error out when another branch has been manually merged into the adjusted branch

This avoids losing the merge commit when re-running git-annex adjust in the
adjusted branch.

It also makes git-annex sync error out, rather than displaying a warning
and exiting successfully.

Sponsored-by: Leon Schuermann on Patreon
This commit is contained in:
Joey Hess 2025-08-20 13:28:03 -04:00
commit fd89e611b2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
4 changed files with 59 additions and 22 deletions

View file

@ -524,15 +524,12 @@ propigateAdjustedCommits'
propigateAdjustedCommits' warnwhendiverged origbranch adj _commitsprevented =
inRepo (Git.Ref.sha basis) >>= \case
Just origsha -> catCommit currbranch >>= \case
Just currcommit ->
newcommits >>= go origsha origsha False >>= \case
Left e -> do
warning (UnquotedString e)
return (Nothing, return ())
Right newparent -> return
( Just newparent
, rebase currcommit newparent
)
Just currcommit -> do
newparent <- newcommits >>= go origsha origsha False
return
( Just newparent
, rebase currcommit newparent
)
Nothing -> return (Nothing, return ())
Nothing -> do
warning $ UnquotedString $
@ -553,16 +550,14 @@ propigateAdjustedCommits' warnwhendiverged origbranch adj _commitsprevented =
warning $ UnquotedString $
"Original branch " ++ fromRef origbranch ++ " has diverged from current adjusted branch " ++ fromRef currbranch
_ -> inRepo $ Git.Branch.update' origbranch parent
return (Right parent)
return parent
go origsha parent pastadjcommit (sha:l) = catCommit sha >>= \case
Just c
| hasAdjustedBranchCommitMessage c ->
go origsha parent True l
| pastadjcommit ->
reverseAdjustedCommit parent adj (sha, c) origbranch
>>= \case
Left e -> return (Left e)
Right commit -> go origsha commit pastadjcommit l
| pastadjcommit -> do
commit <- reverseAdjustedCommit parent adj (sha, c) origbranch
go origsha commit pastadjcommit l
_ -> go origsha parent pastadjcommit l
rebase currcommit newparent = do
-- Reuse the current adjusted tree, and reparent it
@ -582,10 +577,10 @@ rebaseOnTopMsg = "rebasing adjusted branch on top of updated original branch"
- The commit message, and the author and committer metadata are
- copied over from the basiscommit. However, any gpg signature
- 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 Sha
reverseAdjustedCommit commitparent adj (csha, basiscommit) origbranch
| length (commitParent basiscommit) > 1 = return $
Left $ "unable to propagate merge commit " ++ show csha ++ " back to " ++ show origbranch
| length (commitParent basiscommit) > 1 = giveup $
"unable to propagate merge commit " ++ show csha ++ " back to " ++ show origbranch
| otherwise = do
cmode <- annexCommitMode <$> Annex.getGitConfig
treesha <- reverseAdjustedTree commitparent adj csha
@ -595,7 +590,7 @@ reverseAdjustedCommit commitparent adj (csha, basiscommit) origbranch
Git.Branch.commitTree cmode
[commitMessage basiscommit]
[commitparent] treesha
return (Right revadjcommit)
return revadjcommit
{- Adjusts the tree of the basis, changing only the files that the
- commit changed, and reverse adjusting those changes.

View file

@ -16,6 +16,10 @@ git-annex (10.20250722) UNRELEASED; urgency=medium
and display.
* Improve behavior when there are special remotes configured with
autoenable=yes with names that conflict with other remotes.
* adjust: When another branch has been manually merged into the adjusted
branch, re-adjusting errors out, rather than losing that merge commit.
* sync: When another branch has been manually merged into an adjusted
branch, error out rather than only displaying a warning.
* Bump aws build dependency to 0.24.1.
* stack.yaml: Update to lts-24.2.

View file

@ -0,0 +1,37 @@
[[!comment format=mdwn
username="joey"
subject="""comment 2"""
date="2025-08-20T16:34:25Z"
content="""
Thanks for bumping this. It was in my backlog. I've taken a look at it now.
Note that you can use the reflog to get back to the missing commits.
The [[git-annex-adjust]] warns about merging into an adjusted branch. And
suggests to use `git-annex merge` to merge a branch into an adjusted
branch. Which avoids this problem.
Probably the best thing for it to do in this situation is to fail in a way
that leaves the adjusted branch as-is. The user can then address the
problem, eg by resetting the adjusted branch to a point before the merge
and doing the merge some other way.
It would be difficult to handle propagating a merge commit back to the
original branch. Usually when on an adjusted branch, any commit of annexed
files can be assumed to have the adjustment (eg unlocking) applied to the
files. And so reversing the adjustment will yield the desired state (eg
locked files). But a merge commit may not be of another adjusted branch,
it could be a non-adjusted branch. Or it could be a branch with a different
adjustment applied to it. Reversing the adjustment would then do the wrong
thing.
Consider for example, if the --unlock adjustment were used. But then a
branch adjusted with --hide-missing were merged in. This is basically
indistingushable from merging in a branch where some unwanted annexed file
is removed.
Also, it looks at the diff of changes made in a commit to know which
annexed files were changed and reverse adjusts those files. In a merge
commit, it's not clear which of the multiple parents it should diff
against.
"""]]

View file

@ -21,7 +21,7 @@ to a public branch with commands like `git-annex unlock`.
While in the adjusted branch, you can use git-annex and git commands as
usual. Any commits that you make will initially only be made to the
adjusted branch.
adjusted branch.
To propagate commits from the adjusted branch back to the original branch,
and to other repositories, as well as to merge in changes from other
@ -31,8 +31,9 @@ made by this command.
When in an adjusted branch, using `git merge otherbranch` is often not
ideal, because merging a non-adjusted branch may lead to unnecessary
merge conflicts, or add files in non-adjusted form. To avoid those
problems, use `git annex merge otherbranch`.
merge conflicts, or add files in non-adjusted form. And such merges
cannot be propagated from the adjusted branch back to the original branch.
To avoid those problems, use `git annex merge otherbranch`.
Re-running this command with the same options
while inside the adjusted branch will update the adjusted branch