remove direct mode remnant of merging unrelated histories
authorJoey Hess <joeyh@joeyh.name>
Mon, 19 Jul 2021 15:40:48 +0000 (11:40 -0400)
committerJoey Hess <joeyh@joeyh.name>
Mon, 19 Jul 2021 15:41:26 +0000 (11:41 -0400)
sync, merge, post-receive: Avoid merging unrelated histories, which used to
be allowed only to support direct mode repositories.

(However, sync does still merge unrelated histories when importing trees
from special remotes, and the assistant still merges unrelated histories
always.)

See 556b2ded2ba8270846fa207255b4c2def6ef5d8a for why this was added
back in 2016, for direct mode.

This is a behavior change, which might break something that was relying
on sync merging unrelated histories, but git had a good reason to
prevent it, since it's easy to foot shoot with it, and git-annex should
follow suit.

Sponsored-by: Noam Kremen on Patreon
Assistant/Sync.hs
Assistant/Threads/Merger.hs
CHANGELOG
Command/Merge.hs
Command/PostReceive.hs
Command/Sync.hs

index 487cf5be55ee57a5acfde716fc317a5f999073df..df51a1c5ed6d47d74667e5309a0ad2c78651b21f 100644 (file)
@@ -213,7 +213,8 @@ syncAction rs a
 manualPull :: Command.Sync.CurrBranch -> [Remote] -> Assistant ([Remote], Bool)
 manualPull currentbranch remotes = do
        g <- liftAnnex gitRepo
-       mc <- liftAnnex Command.Sync.mergeConfig
+       -- Allow merging unrelated histories.
+       mc <- liftAnnex $ Command.Sync.mergeConfig True
        failed <- forM remotes $ \r -> if wantpull $ Remote.gitconfig r
                then do
                        g' <- liftAnnex $ do
index 19b5ceca04558a79858743d8d162b05961a93c3c..04d1a135b2a24039b8a8199143b89891843d4bd9 100644 (file)
@@ -90,7 +90,8 @@ onChange file
                                        ]
                                void $ liftAnnex $ do
                                        cmode <- annexCommitMode <$> Annex.getGitConfig
-                                       mc <- Command.Sync.mergeConfig
+                                       -- Allow merging unrelated histories.
+                                       mc <- Command.Sync.mergeConfig True
                                        Command.Sync.merge
                                                currbranch
                                                mc
index 1a916aaf4c89ef4ccd20a2b89e52bc49f20991ae..a4f8eeb5a50f4ee30aac07bcf84834399b582b97 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -9,6 +9,11 @@ git-annex (8.20210715) UNRELEASED; urgency=medium
   * sync: When --quiet is used, run git commit, push, and pull without
     their ususual output.
   * merge: When --quiet is used, run git merge without its usual output.
+  * sync, merge, post-receive: Avoid merging unrelated histories,
+    which used to be allowed only to support direct mode repositories.
+    (However, sync does still merge unrelated histories when importing
+    trees from special remotes, and the assistant still merges unrelated
+    histories.)
 
  -- Joey Hess <id@joeyh.name>  Wed, 14 Jul 2021 14:26:36 -0400
 
index 2a964d07697bdf3224915f654c7fdf5516a30508..aa8b0ddeb8a15f767cdb249aa075c691f686d239 100644 (file)
@@ -41,14 +41,14 @@ mergeAnnexBranch = starting "merge" ai si $ do
 
 mergeSyncedBranch :: CommandStart
 mergeSyncedBranch = do
-       mc <- mergeConfig
+       mc <- mergeConfig False
        mergeLocal mc def =<< getCurrentBranch
 
 mergeBranch :: Git.Ref -> CommandStart
 mergeBranch r = starting "merge" ai si $ do
        currbranch <- getCurrentBranch
        let o = def { notOnlyAnnexOption = True }
-       mc <- mergeConfig
+       mc <- mergeConfig False
        next $ merge currbranch mc o Git.Branch.ManualCommit r
   where
        ai = ActionItemOther (Just (Git.fromRef r))
index fab6181b029d051dfb68dfef273d34f12eada411..ec0678383fe4f4f50a79c0922ec9badf8f7eb20d 100644 (file)
@@ -52,5 +52,5 @@ updateInsteadEmulation :: CommandStart
 updateInsteadEmulation = do
        prepMerge
        let o = def { notOnlyAnnexOption = True }
-       mc <- mergeConfig
+       mc <- mergeConfig False
        mergeLocal mc o =<< getCurrentBranch
index c0e469c9ebdfb60d0532f9b9513eea3ea19feda9..f6c53c9514733c2ecfeafc1996c3ede027b46d62 100644 (file)
@@ -218,7 +218,7 @@ seek' o = do
                        commandAction (withbranch cleanupLocal)
                        mapM_ (commandAction . withbranch . cleanupRemote) gitremotes
                else do
-                       mc <- mergeConfig
+                       mc <- mergeConfig False
 
                        -- Syncing involves many actions, any of which
                        -- can independently fail, without preventing
@@ -234,7 +234,7 @@ seek' o = do
                        content <- shouldSyncContent o
 
                        forM_ (filter isImport contentremotes) $
-                               withbranch . importRemote content o mc
+                               withbranch . importRemote content o
                        forM_ (filter isThirdPartyPopulated contentremotes) $
                                pullThirdPartyPopulated o
                        
@@ -275,20 +275,17 @@ seek' o = do
 prepMerge :: Annex ()
 prepMerge = Annex.changeDirectory . fromRawFilePath =<< fromRepo Git.repoPath
 
-mergeConfig :: Annex [Git.Merge.MergeConfig]
-mergeConfig = do
+mergeConfig :: Bool -> Annex [Git.Merge.MergeConfig]
+mergeConfig mergeunrelated = do
        quiet <- commandProgressDisabled
        return $ catMaybes
                [ Just Git.Merge.MergeNonInteractive
-               -- In several situations, unrelated histories should be
-               -- merged together. This includes pairing in the assistant,
-               -- merging from a remote into a newly created direct mode
-               -- repo, and an initial merge from an import from a special
-               -- remote. (Once direct mode is removed, this could be
-               -- changed, so only the assistant and import from special
-               -- remotes use it.)
-               , Just Git.Merge.MergeUnrelatedHistories
-               , if quiet then Just Git.Merge.MergeQuiet else Nothing
+               , if mergeunrelated 
+                       then Just Git.Merge.MergeUnrelatedHistories
+                       else Nothing
+               , if quiet
+                       then Just Git.Merge.MergeQuiet
+                       else Nothing
                ]
 
 merge :: CurrBranch -> [Git.Merge.MergeConfig] -> SyncOptions -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool
@@ -483,8 +480,8 @@ pullRemote o mergeconfig remote branch = stopUnless (pure $ pullOption o && want
        ai = ActionItemOther (Just (Remote.name remote))
        si = SeekInput []
 
-importRemote :: Bool -> SyncOptions -> [Git.Merge.MergeConfig] -> Remote -> CurrBranch -> CommandSeek
-importRemote importcontent o mergeconfig remote currbranch
+importRemote :: Bool -> SyncOptions -> Remote -> CurrBranch -> CommandSeek
+importRemote importcontent o remote currbranch
        | not (pullOption o) || not wantpull = noop
        | otherwise = case remoteAnnexTrackingBranch (Remote.gitconfig remote) of
                Nothing -> noop
@@ -497,7 +494,13 @@ importRemote importcontent o mergeconfig remote currbranch
                        if canImportKeys remote importcontent
                                then do
                                        Command.Import.seekRemote remote branch subdir importcontent (CheckGitIgnore True)
-                                       void $ mergeRemote remote currbranch mergeconfig o
+                                       -- Importing generates a branch
+                                       -- that is not initially connected
+                                       -- to the current branch, so allow
+                                       -- merging unrelated histories when
+                                       -- mergeing it.
+                                       mc <- mergeConfig True
+                                       void $ mergeRemote remote currbranch mc o
                                else warning $ "Cannot import from " ++ Remote.name remote ++ " when not syncing content."
   where
        wantpull = remoteAnnexPull (Remote.gitconfig remote)