slow, stupid, and safe index updating
Always merge the git-annex branch into .git/annex/index before making a commit from the index. This ensures that, when the branch has been changed in any way (by a push being received, or changes pulled directly into it, or even by the user checking it out, and committing a change), the index reflects those changes. This is much too slow; it needs to be optimised to only update the index when the branch has really changed, not every time. Also, there is an unhandled race, when a change is made to the branch right after the index gets updated. I left it in for now because it's unlikely and I didn't want to complicate things with additional locking yet.
This commit is contained in:
parent
59971c9230
commit
8680c415de
4 changed files with 34 additions and 25 deletions
|
@ -45,14 +45,26 @@ originname = Git.Ref $ "origin/" ++ show name
|
||||||
|
|
||||||
{- Populates the branch's index file with the current branch contents.
|
{- Populates the branch's index file with the current branch contents.
|
||||||
-
|
-
|
||||||
- Usually, this is only done when the index doesn't yet exist, and
|
- This is only done when the index doesn't yet exist, and the index
|
||||||
- the index is used to build up changes to be commited to the branch,
|
- is used to build up changes to be commited to the branch, and merge
|
||||||
- and merge in changes from other branches.
|
- in changes from other branches.
|
||||||
-}
|
-}
|
||||||
genIndex :: Git.Repo -> IO ()
|
genIndex :: Git.Repo -> IO ()
|
||||||
genIndex g = Git.UnionMerge.stream_update_index g
|
genIndex g = Git.UnionMerge.stream_update_index g
|
||||||
[Git.UnionMerge.ls_tree fullname g]
|
[Git.UnionMerge.ls_tree fullname g]
|
||||||
|
|
||||||
|
{- Merges the specified branches into the index.
|
||||||
|
- Any changes staged in the index will be preserved. -}
|
||||||
|
mergeIndex :: [Git.Ref] -> Annex ()
|
||||||
|
mergeIndex branches = do
|
||||||
|
h <- catFileHandle
|
||||||
|
inRepo $ \g -> Git.UnionMerge.merge_index h g branches
|
||||||
|
|
||||||
|
{- Updates the branch's index to reflect the current contents of the branch.
|
||||||
|
- Any changes staged in the index will be preserved. -}
|
||||||
|
updateIndex :: Annex ()
|
||||||
|
updateIndex = withIndex $ mergeIndex [fullname]
|
||||||
|
|
||||||
{- Runs an action using the branch's index file. -}
|
{- Runs an action using the branch's index file. -}
|
||||||
withIndex :: Annex a -> Annex a
|
withIndex :: Annex a -> Annex a
|
||||||
withIndex = withIndex' False
|
withIndex = withIndex' False
|
||||||
|
@ -66,6 +78,8 @@ withIndex' bootstrapping a = do
|
||||||
unless bootstrapping $ inRepo genIndex
|
unless bootstrapping $ inRepo genIndex
|
||||||
a
|
a
|
||||||
|
|
||||||
|
{- Runs an action using the branch's index file, first making sure that
|
||||||
|
- the branch and index are up-to-date. -}
|
||||||
withIndexUpdate :: Annex a -> Annex a
|
withIndexUpdate :: Annex a -> Annex a
|
||||||
withIndexUpdate a = update >> withIndex a
|
withIndexUpdate a = update >> withIndex a
|
||||||
|
|
||||||
|
@ -106,11 +120,12 @@ create = unlessM hasBranch $ do
|
||||||
{- Stages the journal, and commits staged changes to the branch. -}
|
{- Stages the journal, and commits staged changes to the branch. -}
|
||||||
commit :: String -> Annex ()
|
commit :: String -> Annex ()
|
||||||
commit message = whenM journalDirty $ lockJournal $ do
|
commit message = whenM journalDirty $ lockJournal $ do
|
||||||
|
updateIndex
|
||||||
stageJournalFiles
|
stageJournalFiles
|
||||||
withIndex $ inRepo $ Git.commit message fullname [fullname]
|
withIndex $ inRepo $ Git.commit message fullname [fullname]
|
||||||
|
|
||||||
{- Ensures that the branch is up-to-date; should be called before data is
|
{- Ensures that the branch and index are is up-to-date; should be
|
||||||
- read from it. Runs only once per git-annex run.
|
- called before data is read from it. Runs only once per git-annex run.
|
||||||
-
|
-
|
||||||
- Before refs are merged into the index, it's important to first stage the
|
- Before refs are merged into the index, it's important to first stage the
|
||||||
- journal into the index. Otherwise, any changes in the journal would
|
- journal into the index. Otherwise, any changes in the journal would
|
||||||
|
@ -126,8 +141,9 @@ commit message = whenM journalDirty $ lockJournal $ do
|
||||||
-}
|
-}
|
||||||
update :: Annex ()
|
update :: Annex ()
|
||||||
update = onceonly $ do
|
update = onceonly $ do
|
||||||
-- ensure branch exists
|
-- ensure branch exists, and index is up-to-date
|
||||||
create
|
create
|
||||||
|
updateIndex
|
||||||
-- check what needs updating before taking the lock
|
-- check what needs updating before taking the lock
|
||||||
dirty <- journalDirty
|
dirty <- journalDirty
|
||||||
c <- filterM (changedBranch name . snd) =<< siblingBranches
|
c <- filterM (changedBranch name . snd) =<< siblingBranches
|
||||||
|
@ -141,14 +157,7 @@ update = onceonly $ do
|
||||||
" into " ++ show name
|
" into " ++ show name
|
||||||
unless (null branches) $ do
|
unless (null branches) $ do
|
||||||
showSideAction merge_desc
|
showSideAction merge_desc
|
||||||
{- Note: This merges the branches into the index.
|
mergeIndex branches
|
||||||
- Any unstaged changes in the git-annex branch
|
|
||||||
- (if it's checked out) will be removed. So,
|
|
||||||
- documentation advises users not to directly
|
|
||||||
- modify the branch.
|
|
||||||
-}
|
|
||||||
h <- catFileHandle
|
|
||||||
inRepo $ \g -> Git.UnionMerge.merge_index h g branches
|
|
||||||
ff <- if dirty then return False else tryFastForwardTo refs
|
ff <- if dirty then return False else tryFastForwardTo refs
|
||||||
unless ff $ inRepo $
|
unless ff $ inRepo $
|
||||||
Git.commit merge_desc fullname (nub $ fullname:refs)
|
Git.commit merge_desc fullname (nub $ fullname:refs)
|
||||||
|
|
5
debian/changelog
vendored
5
debian/changelog
vendored
|
@ -13,6 +13,11 @@ git-annex (3.20111204) UNRELEASED; urgency=low
|
||||||
remote, by running git commit, pull, and push for you.
|
remote, by running git commit, pull, and push for you.
|
||||||
* Version monad-control dependency in cabal file.
|
* Version monad-control dependency in cabal file.
|
||||||
* Fix bug in last version in getting contents from bare repositories.
|
* Fix bug in last version in getting contents from bare repositories.
|
||||||
|
* Ensure that git-annex branch changes are merged into git-annex's index,
|
||||||
|
which fixes a bug that could cause changes that were pushed to the
|
||||||
|
git-annex branch to get reverted. As a side effect, it's now safe
|
||||||
|
for users to check out and commit changes directly to the git-annex
|
||||||
|
branch.
|
||||||
|
|
||||||
-- Joey Hess <joeyh@debian.org> Sun, 04 Dec 2011 12:22:37 -0400
|
-- Joey Hess <joeyh@debian.org> Sun, 04 Dec 2011 12:22:37 -0400
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,9 @@ corresponds to its index, and if the branch is at a different ref,
|
||||||
merge it into the index. I am still considering how to do that atomically;
|
merge it into the index. I am still considering how to do that atomically;
|
||||||
what if a push comes in while git-annex is updating its index?
|
what if a push comes in while git-annex is updating its index?
|
||||||
|
|
||||||
|
> Now git-annex always updates the index with the git-annex branch, which
|
||||||
|
> is a slow, but safe way to avoid this problem. [[done]] --[[Joey]]
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Workaround
|
## Workaround
|
||||||
|
|
|
@ -22,17 +22,9 @@ deleting or changing the file contents.
|
||||||
This branch is managed by git-annex, with the contents listed below.
|
This branch is managed by git-annex, with the contents listed below.
|
||||||
|
|
||||||
The file `.git/annex/index` is a separate git index file it uses
|
The file `.git/annex/index` is a separate git index file it uses
|
||||||
to accumulate changes for the git-annex. Also, `.git/annex/journal/` is used
|
to accumulate changes for the git-annex branch.
|
||||||
to record changes before they are added to git.
|
Also, `.git/annex/journal/` is used to record changes before they
|
||||||
|
are added to git.
|
||||||
Note that for speed reasons, git-annex assumes only it will modify this
|
|
||||||
branch. If you go in and make changes directly, it will probably revert
|
|
||||||
your changes in its next commit to the branch.
|
|
||||||
|
|
||||||
The best way to make changes to the git-annex branch is instead
|
|
||||||
to create a branch of it, with a name like "my/git-annex", and then
|
|
||||||
use "git annex merge" to automerge your branch into the main git-annex
|
|
||||||
branch.
|
|
||||||
|
|
||||||
### `uuid.log`
|
### `uuid.log`
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue