fixed merging of changes from adjusted branch + a remote
This commit is contained in:
parent
f08149207c
commit
12ddb6e8b2
3 changed files with 222 additions and 108 deletions
|
@ -205,15 +205,18 @@ preventCommits = bracket setup cleanup
|
||||||
- metadata is based on the parent.
|
- metadata is based on the parent.
|
||||||
-}
|
-}
|
||||||
commitAdjustedTree :: Sha -> Ref -> Annex Sha
|
commitAdjustedTree :: Sha -> Ref -> Annex Sha
|
||||||
commitAdjustedTree treesha parent = go =<< catCommit parent
|
commitAdjustedTree treesha parent = commitAdjustedTree' treesha parent [parent]
|
||||||
|
|
||||||
|
commitAdjustedTree' :: Sha -> Ref -> [Ref] -> Annex Sha
|
||||||
|
commitAdjustedTree' treesha basis parents = go =<< catCommit basis
|
||||||
where
|
where
|
||||||
go Nothing = inRepo mkcommit
|
go Nothing = inRepo mkcommit
|
||||||
go (Just parentcommit) = inRepo $ commitWithMetaData
|
go (Just basiscommit) = inRepo $ commitWithMetaData
|
||||||
(commitAuthorMetaData parentcommit)
|
(commitAuthorMetaData basiscommit)
|
||||||
(commitCommitterMetaData parentcommit)
|
(commitCommitterMetaData basiscommit)
|
||||||
mkcommit
|
mkcommit
|
||||||
mkcommit = Git.Branch.commitTree Git.Branch.AutomaticCommit
|
mkcommit = Git.Branch.commitTree Git.Branch.AutomaticCommit
|
||||||
adjustedBranchCommitMessage [parent] treesha
|
adjustedBranchCommitMessage parents treesha
|
||||||
|
|
||||||
adjustedBranchCommitMessage :: String
|
adjustedBranchCommitMessage :: String
|
||||||
adjustedBranchCommitMessage = "git-annex adjusted branch"
|
adjustedBranchCommitMessage = "git-annex adjusted branch"
|
||||||
|
@ -222,13 +225,14 @@ adjustedBranchCommitMessage = "git-annex adjusted branch"
|
||||||
- branch into it. -}
|
- branch into it. -}
|
||||||
updateAdjustedBranch :: Branch -> (OrigBranch, Adjustment) -> Git.Branch.CommitMode -> Annex Bool
|
updateAdjustedBranch :: Branch -> (OrigBranch, Adjustment) -> Git.Branch.CommitMode -> Annex Bool
|
||||||
updateAdjustedBranch tomerge (origbranch, adj) commitmode = catchBoolIO $
|
updateAdjustedBranch tomerge (origbranch, adj) commitmode = catchBoolIO $
|
||||||
join $ preventCommits $ \_ -> go =<< (,)
|
join $ preventCommits $ \commitsprevented -> go commitsprevented =<< (,)
|
||||||
<$> inRepo (Git.Ref.sha tomerge)
|
<$> inRepo (Git.Ref.sha tomerge)
|
||||||
<*> inRepo Git.Branch.current
|
<*> inRepo Git.Branch.current
|
||||||
where
|
where
|
||||||
go (Just mergesha, Just currbranch) =
|
go commitsprevented (Just mergesha, Just currbranch) =
|
||||||
ifM (inRepo $ Git.Branch.changed currbranch mergesha)
|
ifM (inRepo $ Git.Branch.changed currbranch mergesha)
|
||||||
( do
|
( do
|
||||||
|
void $ propigateAdjustedCommits' origbranch (adj, currbranch) commitsprevented
|
||||||
adjustedtomerge <- adjust adj mergesha
|
adjustedtomerge <- adjust adj mergesha
|
||||||
ifM (inRepo $ Git.Branch.changed currbranch adjustedtomerge)
|
ifM (inRepo $ Git.Branch.changed currbranch adjustedtomerge)
|
||||||
( return $
|
( return $
|
||||||
|
@ -242,24 +246,56 @@ updateAdjustedBranch tomerge (origbranch, adj) commitmode = catchBoolIO $
|
||||||
)
|
)
|
||||||
, nochangestomerge
|
, nochangestomerge
|
||||||
)
|
)
|
||||||
go _ = return $ return False
|
go _ _ = return $ return False
|
||||||
nochangestomerge = return $ return True
|
nochangestomerge = return $ return True
|
||||||
{- Once a merge commit has been made, re-do it, removing
|
|
||||||
- the old version of the adjusted branch as a parent, and
|
{- A merge commit has been made on the adjusted branch.
|
||||||
- making the only parent be the branch that was merged in.
|
- Now, re-do it, removing the old version of the adjusted branch
|
||||||
|
- from its history.
|
||||||
-
|
-
|
||||||
- Doing this ensures that the same commit Sha is
|
- There are two possible scenarios; either some commits
|
||||||
- always arrived at for a given commit from the merged in branch.
|
- were made on top of the adjusted branch's adjusting commit,
|
||||||
|
- or not. Those commits have already been propigated to the
|
||||||
- Also, update the origbranch.
|
- orig branch, so we can just check if there are commits in the
|
||||||
|
- orig branch that are not present in tomerge.
|
||||||
-}
|
-}
|
||||||
recommit currbranch parent (Just commit) = do
|
recommit currbranch mergedsha (Just mergecommit) =
|
||||||
commitsha <- commitAdjustedTree (commitTree commit) parent
|
ifM (inRepo $ Git.Branch.changed tomerge origbranch)
|
||||||
inRepo $ Git.Branch.update "updating original branch" origbranch parent
|
( remerge currbranch mergedsha mergecommit
|
||||||
inRepo $ Git.Branch.update "rebasing adjusted branch on top of updated original branch after merge" currbranch commitsha
|
=<< inRepo (Git.Ref.sha origbranch)
|
||||||
return True
|
, fastforward currbranch mergedsha mergecommit
|
||||||
|
)
|
||||||
recommit _ _ Nothing = return False
|
recommit _ _ Nothing = return False
|
||||||
|
|
||||||
|
{- Fast-forward scenario. The mergecommit is changed to a non-merge
|
||||||
|
- commit, with its parent being the mergedsha.
|
||||||
|
- The orig branch can simply be pointed at the mergedsha.
|
||||||
|
-}
|
||||||
|
fastforward currbranch mergedsha mergecommit = do
|
||||||
|
commitsha <- commitAdjustedTree (commitTree mergecommit) mergedsha
|
||||||
|
inRepo $ Git.Branch.update "fast-forward update of adjusted branch" currbranch commitsha
|
||||||
|
inRepo $ Git.Branch.update "updating original branch" origbranch mergedsha
|
||||||
|
return True
|
||||||
|
|
||||||
|
{- True merge scenario. -}
|
||||||
|
remerge currbranch mergedsha mergecommit (Just origsha) = do
|
||||||
|
-- Update origbranch by reverse adjusting the mergecommit,
|
||||||
|
-- yielding a merge between orig and tomerge.
|
||||||
|
treesha <- reverseAdjustedTree origsha adj
|
||||||
|
-- get 1-parent commit because
|
||||||
|
-- reverseAdjustedTree does not support merges
|
||||||
|
=<< commitAdjustedTree (commitTree mergecommit) origsha
|
||||||
|
revadjcommit <- inRepo $
|
||||||
|
Git.Branch.commitTree Git.Branch.AutomaticCommit
|
||||||
|
("Merge branch " ++ fromRef tomerge) [origsha, mergedsha] treesha
|
||||||
|
inRepo $ Git.Branch.update "updating original branch" origbranch revadjcommit
|
||||||
|
-- Update currbranch, reusing mergedsha, but making its
|
||||||
|
-- parent be the updated origbranch.
|
||||||
|
adjcommit <- commitAdjustedTree' (commitTree mergecommit) revadjcommit [revadjcommit]
|
||||||
|
inRepo $ Git.Branch.update rebaseOnTopMsg currbranch adjcommit
|
||||||
|
return True
|
||||||
|
remerge _ _ _ Nothing = return False
|
||||||
|
|
||||||
{- Check for any commits present on the adjusted branch that have not yet
|
{- Check for any commits present on the adjusted branch that have not yet
|
||||||
- been propigated to the orig branch, and propigate them.
|
- been propigated to the orig branch, and propigate them.
|
||||||
-
|
-
|
||||||
|
@ -268,9 +304,16 @@ updateAdjustedBranch tomerge (origbranch, adj) commitmode = catchBoolIO $
|
||||||
-}
|
-}
|
||||||
propigateAdjustedCommits :: OrigBranch -> (Adjustment, AdjBranch) -> Annex ()
|
propigateAdjustedCommits :: OrigBranch -> (Adjustment, AdjBranch) -> Annex ()
|
||||||
propigateAdjustedCommits origbranch (adj, currbranch) =
|
propigateAdjustedCommits origbranch (adj, currbranch) =
|
||||||
preventCommits $ propigateAdjustedCommits' origbranch (adj, currbranch)
|
preventCommits $ \commitsprevented -> do
|
||||||
|
join $ propigateAdjustedCommits' origbranch (adj, currbranch) commitsprevented
|
||||||
propigateAdjustedCommits' :: OrigBranch -> (Adjustment, AdjBranch) -> CommitsPrevented -> Annex ()
|
|
||||||
|
{- Returns action which will rebase the adjusted branch on top of the
|
||||||
|
- updated orig branch. -}
|
||||||
|
propigateAdjustedCommits'
|
||||||
|
:: OrigBranch
|
||||||
|
-> (Adjustment, AdjBranch)
|
||||||
|
-> CommitsPrevented
|
||||||
|
-> Annex (Annex ())
|
||||||
propigateAdjustedCommits' origbranch (adj, currbranch) _commitsprevented = do
|
propigateAdjustedCommits' origbranch (adj, currbranch) _commitsprevented = do
|
||||||
ov <- inRepo $ Git.Ref.sha (Git.Ref.under "refs/heads" origbranch)
|
ov <- inRepo $ Git.Ref.sha (Git.Ref.under "refs/heads" origbranch)
|
||||||
case ov of
|
case ov of
|
||||||
|
@ -282,11 +325,11 @@ propigateAdjustedCommits' origbranch (adj, currbranch) _commitsprevented = do
|
||||||
case v of
|
case v of
|
||||||
Left e -> do
|
Left e -> do
|
||||||
warning e
|
warning e
|
||||||
return ()
|
return $ return ()
|
||||||
Right newparent ->
|
Right newparent -> return $
|
||||||
rebase currcommit newparent
|
rebase currcommit newparent
|
||||||
Nothing -> return ()
|
Nothing -> return $ return ()
|
||||||
Nothing -> return ()
|
Nothing -> return $ return ()
|
||||||
where
|
where
|
||||||
newcommits = inRepo $ Git.Branch.changedCommits origbranch currbranch
|
newcommits = inRepo $ Git.Branch.changedCommits origbranch currbranch
|
||||||
-- Get commits oldest first, so they can be processed
|
-- Get commits oldest first, so they can be processed
|
||||||
|
@ -312,41 +355,53 @@ propigateAdjustedCommits' origbranch (adj, currbranch) _commitsprevented = do
|
||||||
-- and reparent it on top of the new
|
-- and reparent it on top of the new
|
||||||
-- version of the origbranch.
|
-- version of the origbranch.
|
||||||
commitAdjustedTree (commitTree currcommit) newparent
|
commitAdjustedTree (commitTree currcommit) newparent
|
||||||
>>= inRepo . Git.Branch.update "rebasing adjusted branch on top of updated original branch" currbranch
|
>>= inRepo . Git.Branch.update rebaseOnTopMsg currbranch
|
||||||
|
|
||||||
{- Reverses an adjusted commit, and commit on top of the provided newparent,
|
rebaseOnTopMsg :: String
|
||||||
|
rebaseOnTopMsg = "rebasing adjusted branch on top of updated original branch"
|
||||||
|
|
||||||
|
{- Reverses an adjusted commit, and commit with provided commitparent,
|
||||||
- yielding a commit sha.
|
- yielding a commit sha.
|
||||||
-
|
-
|
||||||
- Adjust the tree of the newparent, changing only the files that the
|
- Adjusts the tree of the commitparent, changing only the files that the
|
||||||
- commit changed, and reverse adjusting those changes.
|
- commit changed, and reverse adjusting those changes.
|
||||||
-
|
-
|
||||||
- Note that the commit message, and the author and committer metadata are
|
- The commit message, and the author and committer metadata are
|
||||||
- copied over. However, any gpg signature will be lost, and any other
|
- copied over from the basiscommit. However, any gpg signature
|
||||||
- headers are not copied either. -}
|
- will be lost, and any other headers are not copied either. -}
|
||||||
reverseAdjustedCommit :: Sha -> Adjustment -> (Sha, Commit) -> OrigBranch -> Annex (Either String Sha)
|
reverseAdjustedCommit :: Sha -> Adjustment -> (Sha, Commit) -> OrigBranch -> Annex (Either String Sha)
|
||||||
reverseAdjustedCommit newparent adj (csha, c) origbranch
|
reverseAdjustedCommit commitparent adj (csha, basiscommit) origbranch
|
||||||
-- commitDiff does not support merge commits
|
| length (commitParent basiscommit) > 1 = return $
|
||||||
| length (commitParent c) > 1 = return $
|
|
||||||
Left $ "unable to propigate merge commit " ++ show csha ++ " back to " ++ show origbranch
|
Left $ "unable to propigate merge commit " ++ show csha ++ " back to " ++ show origbranch
|
||||||
| otherwise = do
|
| otherwise = do
|
||||||
(diff, cleanup) <- inRepo (Git.DiffTree.commitDiff csha)
|
treesha <- reverseAdjustedTree commitparent adj csha
|
||||||
let (adds, others) = partition (\dti -> Git.DiffTree.srcsha dti == nullSha) diff
|
|
||||||
let (removes, changes) = partition (\dti -> Git.DiffTree.dstsha dti == nullSha) others
|
|
||||||
adds' <- catMaybes <$>
|
|
||||||
mapM (adjustTreeItem reverseadj) (map diffTreeToTreeItem adds)
|
|
||||||
treesha <- Git.Tree.adjustTree
|
|
||||||
(propchanges changes)
|
|
||||||
adds'
|
|
||||||
(map Git.DiffTree.file removes)
|
|
||||||
newparent
|
|
||||||
=<< Annex.gitRepo
|
|
||||||
void $ liftIO cleanup
|
|
||||||
revadjcommit <- inRepo $ commitWithMetaData
|
revadjcommit <- inRepo $ commitWithMetaData
|
||||||
(commitAuthorMetaData c)
|
(commitAuthorMetaData basiscommit)
|
||||||
(commitCommitterMetaData c) $
|
(commitCommitterMetaData basiscommit) $
|
||||||
Git.Branch.commitTree Git.Branch.AutomaticCommit
|
Git.Branch.commitTree Git.Branch.AutomaticCommit
|
||||||
(commitMessage c) [newparent] treesha
|
(commitMessage basiscommit) [commitparent] treesha
|
||||||
return (Right revadjcommit)
|
return (Right revadjcommit)
|
||||||
|
|
||||||
|
{- Adjusts the tree of the basis, changing only the files that the
|
||||||
|
- commit changed, and reverse adjusting those changes.
|
||||||
|
-
|
||||||
|
- commitDiff does not support merge commits, so the csha must not be a
|
||||||
|
- merge commit. -}
|
||||||
|
reverseAdjustedTree :: Sha -> Adjustment -> Sha -> Annex Sha
|
||||||
|
reverseAdjustedTree basis adj csha = do
|
||||||
|
(diff, cleanup) <- inRepo (Git.DiffTree.commitDiff csha)
|
||||||
|
let (adds, others) = partition (\dti -> Git.DiffTree.srcsha dti == nullSha) diff
|
||||||
|
let (removes, changes) = partition (\dti -> Git.DiffTree.dstsha dti == nullSha) others
|
||||||
|
adds' <- catMaybes <$>
|
||||||
|
mapM (adjustTreeItem reverseadj) (map diffTreeToTreeItem adds)
|
||||||
|
treesha <- Git.Tree.adjustTree
|
||||||
|
(propchanges changes)
|
||||||
|
adds'
|
||||||
|
(map Git.DiffTree.file removes)
|
||||||
|
basis
|
||||||
|
=<< Annex.gitRepo
|
||||||
|
void $ liftIO cleanup
|
||||||
|
return treesha
|
||||||
where
|
where
|
||||||
reverseadj = reverseAdjustment adj
|
reverseadj = reverseAdjustment adj
|
||||||
propchanges changes ti@(TreeItem f _ _) =
|
propchanges changes ti@(TreeItem f _ _) =
|
||||||
|
|
|
@ -243,9 +243,7 @@ commitStaged commitmode commitmessage = do
|
||||||
return True
|
return True
|
||||||
|
|
||||||
mergeLocal :: CurrBranch -> CommandStart
|
mergeLocal :: CurrBranch -> CommandStart
|
||||||
mergeLocal currbranch@(Just branch, madj) = do
|
mergeLocal currbranch@(Just branch, madj) = go =<< needmerge
|
||||||
proptoorig
|
|
||||||
go =<< needmerge
|
|
||||||
where
|
where
|
||||||
syncbranch = syncBranch branch
|
syncbranch = syncBranch branch
|
||||||
needmerge = ifM isBareRepo
|
needmerge = ifM isBareRepo
|
||||||
|
@ -260,11 +258,6 @@ mergeLocal currbranch@(Just branch, madj) = do
|
||||||
showStart "merge" $ Git.Ref.describe syncbranch
|
showStart "merge" $ Git.Ref.describe syncbranch
|
||||||
next $ next $ merge currbranch Git.Branch.ManualCommit syncbranch
|
next $ next $ merge currbranch Git.Branch.ManualCommit syncbranch
|
||||||
branch' = maybe branch (originalToAdjusted branch) madj
|
branch' = maybe branch (originalToAdjusted branch) madj
|
||||||
-- When in an adjusted branch, propigate any changes made to it
|
|
||||||
-- back to the original branch.
|
|
||||||
proptoorig = case madj of
|
|
||||||
Just adj -> propigateAdjustedCommits branch (adj, branch')
|
|
||||||
Nothing -> return ()
|
|
||||||
mergeLocal (Nothing, _) = stop
|
mergeLocal (Nothing, _) = stop
|
||||||
|
|
||||||
pushLocal :: CurrBranch -> CommandStart
|
pushLocal :: CurrBranch -> CommandStart
|
||||||
|
@ -274,7 +267,13 @@ pushLocal b = do
|
||||||
|
|
||||||
updateSyncBranch :: CurrBranch -> Annex ()
|
updateSyncBranch :: CurrBranch -> Annex ()
|
||||||
updateSyncBranch (Nothing, _) = noop
|
updateSyncBranch (Nothing, _) = noop
|
||||||
updateSyncBranch (Just branch, _) = do
|
updateSyncBranch (Just branch, madj) = do
|
||||||
|
-- When in an adjusted branch, propigate any changes made to it
|
||||||
|
-- back to the original branch.
|
||||||
|
case madj of
|
||||||
|
Just adj -> propigateAdjustedCommits branch
|
||||||
|
(adj, originalToAdjusted branch adj)
|
||||||
|
Nothing -> return ()
|
||||||
-- Update the sync branch to match the new state of the branch
|
-- Update the sync branch to match the new state of the branch
|
||||||
inRepo $ updateBranch (syncBranch branch) branch
|
inRepo $ updateBranch (syncBranch branch) branch
|
||||||
-- In direct mode, we're operating on some special direct mode
|
-- In direct mode, we're operating on some special direct mode
|
||||||
|
|
|
@ -109,10 +109,10 @@ beginning the merge. There may be staged changes, or changes in the work tree.
|
||||||
|
|
||||||
First filter the new commit:
|
First filter the new commit:
|
||||||
|
|
||||||
origin/master adjusted/master
|
origin/master adjusted/master master
|
||||||
A
|
A A
|
||||||
|--------------->A'
|
|--------------->A' |
|
||||||
| |
|
| | |
|
||||||
| |
|
| |
|
||||||
B
|
B
|
||||||
|
|
|
|
||||||
|
@ -120,10 +120,10 @@ First filter the new commit:
|
||||||
|
|
||||||
Then, merge that into adjusted/master:
|
Then, merge that into adjusted/master:
|
||||||
|
|
||||||
origin/master adjusted/master
|
origin/master adjusted/master master
|
||||||
A
|
A A
|
||||||
|--------------->A'
|
|--------------->A' |
|
||||||
| |
|
| | |
|
||||||
| |
|
| |
|
||||||
B |
|
B |
|
||||||
| |
|
| |
|
||||||
|
@ -136,35 +136,13 @@ conflict should only affect the work tree/index, so can be resolved without
|
||||||
making a commit, but B'' may end up being made to resolve a merge
|
making a commit, but B'' may end up being made to resolve a merge
|
||||||
conflict.)
|
conflict.)
|
||||||
|
|
||||||
------
|
Once the merge is done, we have a merge commit B'' on adjusted/master.
|
||||||
|
To finish, redo that commit so it does not have A' as its parent.
|
||||||
|
|
||||||
TODO FIXME: When an adjusted unlocked branch has gotten a file, and a new
|
origin/master adjusted/master master
|
||||||
commit is merged in, that does not touch that file, there is a false merge
|
A A
|
||||||
conflict on the file. It's auto-resolved by creating a .variant file.
|
|--------------->A' |
|
||||||
This is probably a bug in the auto-resolve code for v6 files.
|
| | |
|
||||||
|
|
||||||
Test case:
|
|
||||||
|
|
||||||
git clone ~/lib/tmp
|
|
||||||
cd tmp
|
|
||||||
git annex upgrade
|
|
||||||
git annex adjust
|
|
||||||
git annex get t/foo
|
|
||||||
# make change in ~/lib/tmp and commit
|
|
||||||
git annex sync
|
|
||||||
# t/foo.variant-* is there
|
|
||||||
|
|
||||||
------
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Once the merge is done, we have a commit B'' on adjusted/master. To finish,
|
|
||||||
adjust that commit so it does not have adjusted/master as its parent.
|
|
||||||
|
|
||||||
origin/master adjusted/master
|
|
||||||
A
|
|
||||||
|--------------->A'
|
|
||||||
| |
|
|
||||||
| |
|
| |
|
||||||
B
|
B
|
||||||
|
|
|
|
||||||
|
@ -172,6 +150,16 @@ adjust that commit so it does not have adjusted/master as its parent.
|
||||||
| |
|
| |
|
||||||
|
|
||||||
Finally, update master, by reverse filtering B''.
|
Finally, update master, by reverse filtering B''.
|
||||||
|
|
||||||
|
origin/master adjusted/master master
|
||||||
|
A A
|
||||||
|
|--------------->A' |
|
||||||
|
| | |
|
||||||
|
| | |
|
||||||
|
B |
|
||||||
|
| |
|
||||||
|
|--------------->B'' - - - - - - -> B
|
||||||
|
| |
|
||||||
|
|
||||||
Notice how similar this is to the commit graph. So, "fast-forward"
|
Notice how similar this is to the commit graph. So, "fast-forward"
|
||||||
merging the same B commit from origin/master will lead to an identical
|
merging the same B commit from origin/master will lead to an identical
|
||||||
|
@ -191,6 +179,66 @@ between the adjusted work tree and pulled changes. A post-merge hook would
|
||||||
be needed to re-adjust the work tree, and there would be a window where eg,
|
be needed to re-adjust the work tree, and there would be a window where eg,
|
||||||
not present files would appear in the work tree.]
|
not present files would appear in the work tree.]
|
||||||
|
|
||||||
|
## another merge scenario
|
||||||
|
|
||||||
|
Another merge scenario is when there's a new commit C on adjusted/master,
|
||||||
|
and also a new commit B on origin/master.
|
||||||
|
|
||||||
|
Start by adjusting B':
|
||||||
|
|
||||||
|
origin/master adjusted/master master
|
||||||
|
A A
|
||||||
|
|--------------->A' |
|
||||||
|
| | |
|
||||||
|
| C'
|
||||||
|
B
|
||||||
|
|
|
||||||
|
|---------->B'
|
||||||
|
|
||||||
|
Then, merge B' into adjusted/master:
|
||||||
|
|
||||||
|
origin/master adjusted/master master
|
||||||
|
A A
|
||||||
|
|--------------->A' |
|
||||||
|
| | |
|
||||||
|
| C'
|
||||||
|
B |
|
||||||
|
| |
|
||||||
|
|----------->B'->M'
|
||||||
|
|
||||||
|
Here M' is the correct tree, but it has A' as its grandparent,
|
||||||
|
which is the adjusted branch commit, so needs to be dropped in order to
|
||||||
|
get a commit that can be put on master.
|
||||||
|
|
||||||
|
We don't want to lose commit C', but it's an adjusted
|
||||||
|
commit, so needs to be de-adjusted.
|
||||||
|
|
||||||
|
origin/master adjusted/master master
|
||||||
|
A A
|
||||||
|
|--------------->A' |
|
||||||
|
| | |
|
||||||
|
| C'- - - - - - - - > C
|
||||||
|
B |
|
||||||
|
| |
|
||||||
|
|----------->B'->M'
|
||||||
|
|
|
||||||
|
|
||||||
|
Now, we generate a merge commit, between B and C, with known result M'
|
||||||
|
(so no actual merging done here).
|
||||||
|
|
||||||
|
origin/master adjusted/master master
|
||||||
|
A A
|
||||||
|
|--------------->A' |
|
||||||
|
| | |
|
||||||
|
| C'- - - - - - - - > C
|
||||||
|
B |
|
||||||
|
| |
|
||||||
|
|--------------->M'<-----------------|
|
||||||
|
|
|
||||||
|
|
||||||
|
Finally, update master, by reverse filtering M'. The resulting commit
|
||||||
|
on master will also be a merge between B and C.
|
||||||
|
|
||||||
## annex object add/remove
|
## annex object add/remove
|
||||||
|
|
||||||
When objects are added/removed from the annex, the associated file has to
|
When objects are added/removed from the annex, the associated file has to
|
||||||
|
@ -303,20 +351,32 @@ into adjusted view worktrees.]
|
||||||
* Honor annex.thin when entering an adjusted branch.
|
* Honor annex.thin when entering an adjusted branch.
|
||||||
* Cloning a repo that has an adjusted branch checked out gets into an ugly
|
* Cloning a repo that has an adjusted branch checked out gets into an ugly
|
||||||
state.
|
state.
|
||||||
|
* There are potentially races in code that assumes a branch like
|
||||||
|
master is not being changed by someone else. In particular,
|
||||||
|
propigateAdjustedCommits rebases the adjusted branch on top of master.
|
||||||
|
That is called by sync. The assumption is that any changes in master
|
||||||
|
have already been handled by updateAdjustedBranch. But, if another remote
|
||||||
|
pushed a new master at just the right time, the adjusted branch could be
|
||||||
|
rebased on top of a master that it doesn't incorporate, which is wrong.
|
||||||
|
|
||||||
Bug running git-annex sync in adjusted branch when there is a local change
|
------
|
||||||
that gets committed (or already has been), and remote changes available.
|
|
||||||
Both propigateAdjustedCommits and updateAdjustedBranch
|
|
||||||
get called in this scenario. Neither order of calling the two works entirely.
|
|
||||||
|
|
||||||
The reflog has:
|
TODO FIXME: When an adjusted unlocked branch has gotten a file, and a new
|
||||||
|
commit is merged in, that does not touch that file, there is a false merge
|
||||||
|
conflict on the file. It's auto-resolved by creating a .variant file.
|
||||||
|
This is probably a bug in the auto-resolve code for v6 files.
|
||||||
|
|
||||||
d585d7f HEAD@{1}: rebasing adjusted branch on top of updated original branch
|
Test case:
|
||||||
e51daec HEAD@{2}: merge f7f2b9f3b1d1c97a1ab24f4a94d4a27d84898992: Merge made by the 'recursive' strategy.
|
|
||||||
9504e7b HEAD@{3}: rebasing adjusted branch on top of updated original branch
|
git clone ~/lib/tmp
|
||||||
6c6fd41 HEAD@{4}: commit: add
|
cd tmp
|
||||||
|
git annex upgrade
|
||||||
|
git annex adjust
|
||||||
|
git annex get t/foo
|
||||||
|
# make change in ~/lib/tmp and commit
|
||||||
|
git annex sync
|
||||||
|
# t/foo.variant-* is there
|
||||||
|
|
||||||
|
------
|
||||||
|
|
||||||
e51daec has ok correct history; it gets messed up in d585d7f
|
|
||||||
|
|
||||||
Problem is just, that the commit made to the adjusted branch
|
|
||||||
is left out of the history.
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue