propigateAdjustedCommits: avoid overwriting diverged original branch
Bug fix: Re-running git-annex adjust or sync when in an adjusted branch would overwrite the original branch, losing any commits that had been made to it since the adjusted branch was created. When git-annex adjust is run in this situation, it will display a warning about the diverged branches. When git-annex sync is run in this situation, mergeToAdjustedBranch will merge the changes from the original branch to the adjusted branch. So it does not need to display the divergence warning. Note that for some reason, I'm needing to run sync twice for that to happen. The first run does not do the merge and the second does. I'm unsure why and so am not fully done with this bug. Sponsored-By: the NIH-funded NICEMAN (ReproNim TR&D3) project
This commit is contained in:
parent
fc1fcc7491
commit
adb09117f1
5 changed files with 66 additions and 13 deletions
|
@ -258,7 +258,7 @@ updateAdjustedBranch adj (AdjBranch currbranch) origbranch
|
|||
-- Avoid losing any commits that the adjusted branch
|
||||
-- has that have not yet been propigated back to the
|
||||
-- origbranch.
|
||||
_ <- propigateAdjustedCommits' origbranch adj commitlck
|
||||
_ <- propigateAdjustedCommits' True origbranch adj commitlck
|
||||
|
||||
origheadfile <- inRepo $ readFileStrict . Git.Ref.headFile
|
||||
origheadsha <- inRepo (Git.Ref.sha currbranch)
|
||||
|
@ -294,7 +294,7 @@ updateAdjustedBranch adj (AdjBranch currbranch) origbranch
|
|||
return ok
|
||||
| otherwise = preventCommits $ \commitlck -> do
|
||||
-- Done for consistency.
|
||||
_ <- propigateAdjustedCommits' origbranch adj commitlck
|
||||
_ <- propigateAdjustedCommits' True origbranch adj commitlck
|
||||
-- No need to actually update the branch because the
|
||||
-- adjustment is stable.
|
||||
return True
|
||||
|
@ -495,20 +495,21 @@ findAdjustingCommit (AdjBranch b) = go =<< catCommit b
|
|||
propigateAdjustedCommits :: OrigBranch -> Adjustment -> Annex ()
|
||||
propigateAdjustedCommits origbranch adj =
|
||||
preventCommits $ \commitsprevented ->
|
||||
join $ snd <$> propigateAdjustedCommits' origbranch adj commitsprevented
|
||||
join $ snd <$> propigateAdjustedCommits' True origbranch adj commitsprevented
|
||||
|
||||
{- Returns sha of updated basis branch, and action which will rebase
|
||||
- the adjusted branch on top of the updated basis branch. -}
|
||||
propigateAdjustedCommits'
|
||||
:: OrigBranch
|
||||
:: Bool
|
||||
-> OrigBranch
|
||||
-> Adjustment
|
||||
-> CommitsPrevented
|
||||
-> Annex (Maybe Sha, Annex ())
|
||||
propigateAdjustedCommits' origbranch adj _commitsprevented =
|
||||
propigateAdjustedCommits' warnwhendiverged origbranch adj _commitsprevented =
|
||||
inRepo (Git.Ref.sha basis) >>= \case
|
||||
Just origsha -> catCommit currbranch >>= \case
|
||||
Just currcommit ->
|
||||
newcommits >>= go origsha False >>= \case
|
||||
newcommits >>= go origsha origsha False >>= \case
|
||||
Left e -> do
|
||||
warning (UnquotedString e)
|
||||
return (Nothing, return ())
|
||||
|
@ -528,20 +529,25 @@ propigateAdjustedCommits' origbranch adj _commitsprevented =
|
|||
-- Get commits oldest first, so they can be processed
|
||||
-- in order made.
|
||||
[Param "--reverse"]
|
||||
go parent _ [] = do
|
||||
go origsha parent _ [] = do
|
||||
setBasisBranch (BasisBranch basis) parent
|
||||
inRepo $ Git.Branch.update' origbranch parent
|
||||
inRepo (Git.Ref.sha origbranch) >>= \case
|
||||
Just origbranchsha | origbranchsha /= origsha ->
|
||||
when warnwhendiverged $
|
||||
warning $ UnquotedString $
|
||||
"Original branch " ++ fromRef origbranch ++ " has diverged from current adjusted branch " ++ fromRef currbranch
|
||||
_ -> inRepo $ Git.Branch.update' origbranch parent
|
||||
return (Right parent)
|
||||
go parent pastadjcommit (sha:l) = catCommit sha >>= \case
|
||||
go origsha parent pastadjcommit (sha:l) = catCommit sha >>= \case
|
||||
Just c
|
||||
| commitMessage c == adjustedBranchCommitMessage ->
|
||||
go parent True l
|
||||
go origsha parent True l
|
||||
| pastadjcommit ->
|
||||
reverseAdjustedCommit parent adj (sha, c) origbranch
|
||||
>>= \case
|
||||
Left e -> return (Left e)
|
||||
Right commit -> go commit pastadjcommit l
|
||||
_ -> go parent pastadjcommit l
|
||||
Right commit -> go origsha commit pastadjcommit l
|
||||
_ -> go origsha parent pastadjcommit l
|
||||
rebase currcommit newparent = do
|
||||
-- Reuse the current adjusted tree, and reparent it
|
||||
-- on top of the newparent.
|
||||
|
|
|
@ -46,7 +46,7 @@ mergeToAdjustedBranch tomerge (origbranch, adj) mergeconfig canresolvemerge comm
|
|||
ifM (inRepo $ Git.Branch.changed currbranch tomerge)
|
||||
( do
|
||||
(updatedorig, _) <- propigateAdjustedCommits'
|
||||
origbranch adj commitsprevented
|
||||
False origbranch adj commitsprevented
|
||||
changestomerge updatedorig
|
||||
, nochangestomerge
|
||||
)
|
||||
|
|
|
@ -8,6 +8,9 @@ git-annex (10.20230627) UNRELEASED; urgency=medium
|
|||
annexed text files.
|
||||
* assist: With --jobs, parallelize transferring content to/from remotes.
|
||||
* Fix breakage when git is configured with safe.bareRepository = explicit.
|
||||
* Bug fix: Re-running git-annex adjust or sync when in an adjusted branch
|
||||
would overwrite the original branch, losing any commits that had been
|
||||
made to it since the adjusted branch was created.
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Mon, 26 Jun 2023 13:10:40 -0400
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 1"""
|
||||
date="2023-07-05T19:49:19Z"
|
||||
content="""
|
||||
Simplified test case:
|
||||
|
||||
git init tc
|
||||
cd tc
|
||||
git-annex init
|
||||
echo 1 > foo
|
||||
git-annex add
|
||||
git commit -m add
|
||||
git annex adjust --unlock
|
||||
git checkout master
|
||||
rm foo
|
||||
echo 2 > foo
|
||||
git-annex add
|
||||
git commit -m "this commit will be lost"
|
||||
git checkout 'adjusted/master(unlocked)'
|
||||
git annex adjust --unlock # or git-annex sync
|
||||
git log master
|
||||
|
||||
What an unfortunate oversight! And it's not a reversion, it's been there
|
||||
since the beginning of adjusted branches.
|
||||
|
||||
git-annex adjust should display a warning message in that situation,
|
||||
since the original branch has diverged from the adjusted branch.
|
||||
|
||||
And git-annex sync should be able to resolve the divergence by
|
||||
auto-merging the changes from the original branch into the adjusted
|
||||
branch.
|
||||
"""]]
|
|
@ -0,0 +1,11 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 2"""
|
||||
date="2023-07-05T21:01:53Z"
|
||||
content="""
|
||||
I've fixed the data loss part of this bug.
|
||||
|
||||
`git-annex sync` is able to resolve the divergence too. But for some
|
||||
reason, the first time it's run after the divergence, it leaves it
|
||||
diverged, and the second time it resolves it. That needs to be fixed.
|
||||
"""]]
|
Loading…
Reference in a new issue