error out when another branch has been manually merged into the adjusted branch
authorJoey Hess <joeyh@joeyh.name>
Wed, 20 Aug 2025 17:28:03 +0000 (13:28 -0400)
committerJoey Hess <joeyh@joeyh.name>
Wed, 20 Aug 2025 17:28:03 +0000 (13:28 -0400)
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
Annex/AdjustedBranch.hs
CHANGELOG
doc/bugs/Re-Adjust_Loses_Commits/comment_2_5b9c6c1966f967ff417c2acc39cfada4._comment [new file with mode: 0644]
doc/git-annex-adjust.mdwn

index 95bd8cfc3424cb27dba56774c8a4434692ea8d5e..4f72cbd979d90d3c49087f92df0836cdde005762 100644 (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.
index adba28c4d43d925239b033bca1d1581ce5a49f36..a43bae3fd4f231f366e21e97c6ec3cdd9e0bfd0f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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.
 
diff --git a/doc/bugs/Re-Adjust_Loses_Commits/comment_2_5b9c6c1966f967ff417c2acc39cfada4._comment b/doc/bugs/Re-Adjust_Loses_Commits/comment_2_5b9c6c1966f967ff417c2acc39cfada4._comment
new file mode 100644 (file)
index 0000000..b3ff29c
--- /dev/null
@@ -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.
+"""]]
index fd573ec904568dceda6a77c02e5c0faac715c194..55f7f646e7dc5516fce08642a612de286e1de0a1 100644 (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