Once WikiPage.save() has written its commit object, it basically does this:
if branch_head = new_commit.parent:
branch_head = new_commit
else:
merge_commit = merge branch_head and new_commit # gross oversimplification
branch_head = merge_commit
There's a small period of time where someone else could move the branch head between the check and the write in the "no merge needed" case, and a much larger period in the "merge is needed" case (during the merge). The window is probably far less than a second, so not really an issue on local installations or even small shared installations but critical on larger ones.
Because Git tracks the history of the project, not files, an edit to any file that is finalised (ie branch head moved) during this time could be left dangling.
To fix this:
Check the branch head again after the merge, to minimise the amount of time the repository is vulnerable to this condition.
Do both, in order to minimise the amount of time the lock is held.
Workaround:
If this happens to you, cd into Giki's repository and run git fsck. Then, in a non-bare clone, merge all the commits that came up as "dangling commit", and push the changes in your clone back in.
Once
WikiPage.save()
has written its commit object, it basically does this:There's a small period of time where someone else could move the branch head between the check and the write in the "no merge needed" case, and a much larger period in the "merge is needed" case (during the merge). The window is probably far less than a second, so not really an issue on local installations or even small shared installations but critical on larger ones.
Because Git tracks the history of the project, not files, an edit to any file that is finalised (ie branch head moved) during this time could be left dangling.
To fix this:
Workaround:
If this happens to you,
cd
into Giki's repository and rungit fsck
. Then, in a non-bare clone, merge all the commits that came up as "dangling commit", and push the changes in your clone back in.