summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2016-06-09 14:11:00 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2016-06-09 14:11:00 -0400
commitacc29b6b9759794a27a0c81315fd0bd5a7f1a052 (patch)
treee0cb7a52a87dc3a69dea522cca731ad16b528634
parenta5681bf82cb2f43c4615529fb5eca3dd1f15268a (diff)
Fix bug in initialization of clone from a repo with an adjusted branch that had not been synced back to master.
This bug caused broken tree objects to get built by a later git annex sync. This is a somewhat unlikely but not impossible situation, and the test suite's union_merge_regression test tickled it when it was run on FAT.
-rw-r--r--Annex/AdjustedBranch.hs42
-rw-r--r--CHANGELOG4
2 files changed, 37 insertions, 9 deletions
diff --git a/Annex/AdjustedBranch.hs b/Annex/AdjustedBranch.hs
index 30cefdec0..5fcb74149 100644
--- a/Annex/AdjustedBranch.hs
+++ b/Annex/AdjustedBranch.hs
@@ -300,9 +300,20 @@ commitAdjustedTree' treesha (BasisBranch basis) parents =
mkcommit = Git.Branch.commitTree Git.Branch.AutomaticCommit
adjustedBranchCommitMessage parents treesha
+{- This message should never be changed. -}
adjustedBranchCommitMessage :: String
adjustedBranchCommitMessage = "git-annex adjusted branch"
+findAdjustingCommit :: AdjBranch -> Annex (Maybe Commit)
+findAdjustingCommit (AdjBranch b) = go =<< catCommit b
+ where
+ go Nothing = return Nothing
+ go (Just c)
+ | commitMessage c == adjustedBranchCommitMessage = return (Just c)
+ | otherwise = case commitParent c of
+ [p] -> go =<< catCommit p
+ _ -> return Nothing
+
{- Update the currently checked out adjusted branch, merging the provided
- branch into it. Note that the provided branch should be a non-adjusted
- branch. -}
@@ -545,12 +556,22 @@ data AdjustedClone = InAdjustedClone | NotInAdjustedClone | NeedUpgradeForAdjust
{- Cloning a repository that has an adjusted branch checked out will
- result in the clone having the same adjusted branch checked out -- but
- - the origbranch won't exist in the clone, nor will the basis.
- - Create them.
+ - the origbranch won't exist in the clone, nor will the basis. So
+ - to properly set up the adjusted branch, the origbranch and basis need
+ - to be set.
+ -
+ - We can't trust that the origin's origbranch matches up with the currently
+ - checked out adjusted branch; the origin could have the two branches
+ - out of sync (eg, due to another branch having been pushed to the origin's
+ - origbranch), or due to a commit on its adjusted branch not having been
+ - propigated back to origbranch.
+ -
+ - So, find the adjusting commit on the currently checked out adjusted
+ - branch, and use the parent of that commit as the basis, and set the
+ - origbranch to it.
-
- The repository may also need to be upgraded to a new version, if the
- - current version is too old to support adjusted branches. Returns True
- - when this is the case. -}
+ - current version is too old to support adjusted branches. -}
checkAdjustedClone :: Annex AdjustedClone
checkAdjustedClone = ifM isBareRepo
( return NotInAdjustedClone
@@ -561,12 +582,15 @@ checkAdjustedClone = ifM isBareRepo
go (Just currbranch) = case adjustedToOriginal currbranch of
Nothing -> return NotInAdjustedClone
Just (adj, origbranch) -> do
- let remotebranch = Git.Ref.underBase "refs/remotes/origin" origbranch
let basis@(BasisBranch bb) = basisBranch (originalToAdjusted origbranch adj)
- unlessM (inRepo $ Git.Ref.exists bb) $
- setBasisBranch basis remotebranch
- unlessM (inRepo $ Git.Ref.exists origbranch) $
- inRepo $ Git.Branch.update' origbranch remotebranch
+ unlessM (inRepo $ Git.Ref.exists bb) $ do
+ unlessM (inRepo $ Git.Ref.exists origbranch) $ do
+ let remotebranch = Git.Ref.underBase "refs/remotes/origin" origbranch
+ inRepo $ Git.Branch.update' origbranch remotebranch
+ aps <- fmap commitParent <$> findAdjustingCommit (AdjBranch currbranch)
+ case aps of
+ Just [p] -> setBasisBranch basis p
+ _ -> error $ "Unable to clean up from clone of adjusted branch; perhaps you should check out " ++ Git.Ref.describe origbranch
ifM versionSupportsUnlockedPointers
( return InAdjustedClone
, return NeedUpgradeForAdjustedClone
diff --git a/CHANGELOG b/CHANGELOG
index b9c7792c0..0db6d1e56 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -24,6 +24,10 @@ git-annex (6.20160528) UNRELEASED; urgency=medium
and a directory with the same name when in an adjusted branch.
* Avoid a crash if getpwuid does not work, when querying the user's full
name.
+ * Fix bug in initialization of clone from a repo with an adjusted branch
+ that had not been synced back to master.
+ (This bug caused broken tree objects to get built by a later git annex
+ sync.)
-- Joey Hess <id@joeyh.name> Fri, 27 May 2016 13:12:48 -0400