remove direct mode remnant of merging unrelated histories

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 556b2ded2b 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
This commit is contained in:
Joey Hess 2021-07-19 11:40:48 -04:00
parent 33a80d083a
commit b6bea0d3f2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
6 changed files with 31 additions and 21 deletions

View file

@ -213,7 +213,8 @@ syncAction rs a
manualPull :: Command.Sync.CurrBranch -> [Remote] -> Assistant ([Remote], Bool) manualPull :: Command.Sync.CurrBranch -> [Remote] -> Assistant ([Remote], Bool)
manualPull currentbranch remotes = do manualPull currentbranch remotes = do
g <- liftAnnex gitRepo 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 failed <- forM remotes $ \r -> if wantpull $ Remote.gitconfig r
then do then do
g' <- liftAnnex $ do g' <- liftAnnex $ do

View file

@ -90,7 +90,8 @@ onChange file
] ]
void $ liftAnnex $ do void $ liftAnnex $ do
cmode <- annexCommitMode <$> Annex.getGitConfig cmode <- annexCommitMode <$> Annex.getGitConfig
mc <- Command.Sync.mergeConfig -- Allow merging unrelated histories.
mc <- Command.Sync.mergeConfig True
Command.Sync.merge Command.Sync.merge
currbranch currbranch
mc mc

View file

@ -9,6 +9,11 @@ git-annex (8.20210715) UNRELEASED; urgency=medium
* sync: When --quiet is used, run git commit, push, and pull without * sync: When --quiet is used, run git commit, push, and pull without
their ususual output. their ususual output.
* merge: When --quiet is used, run git merge without its usual 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 -- Joey Hess <id@joeyh.name> Wed, 14 Jul 2021 14:26:36 -0400

View file

@ -41,14 +41,14 @@ mergeAnnexBranch = starting "merge" ai si $ do
mergeSyncedBranch :: CommandStart mergeSyncedBranch :: CommandStart
mergeSyncedBranch = do mergeSyncedBranch = do
mc <- mergeConfig mc <- mergeConfig False
mergeLocal mc def =<< getCurrentBranch mergeLocal mc def =<< getCurrentBranch
mergeBranch :: Git.Ref -> CommandStart mergeBranch :: Git.Ref -> CommandStart
mergeBranch r = starting "merge" ai si $ do mergeBranch r = starting "merge" ai si $ do
currbranch <- getCurrentBranch currbranch <- getCurrentBranch
let o = def { notOnlyAnnexOption = True } let o = def { notOnlyAnnexOption = True }
mc <- mergeConfig mc <- mergeConfig False
next $ merge currbranch mc o Git.Branch.ManualCommit r next $ merge currbranch mc o Git.Branch.ManualCommit r
where where
ai = ActionItemOther (Just (Git.fromRef r)) ai = ActionItemOther (Just (Git.fromRef r))

View file

@ -52,5 +52,5 @@ updateInsteadEmulation :: CommandStart
updateInsteadEmulation = do updateInsteadEmulation = do
prepMerge prepMerge
let o = def { notOnlyAnnexOption = True } let o = def { notOnlyAnnexOption = True }
mc <- mergeConfig mc <- mergeConfig False
mergeLocal mc o =<< getCurrentBranch mergeLocal mc o =<< getCurrentBranch

View file

@ -218,7 +218,7 @@ seek' o = do
commandAction (withbranch cleanupLocal) commandAction (withbranch cleanupLocal)
mapM_ (commandAction . withbranch . cleanupRemote) gitremotes mapM_ (commandAction . withbranch . cleanupRemote) gitremotes
else do else do
mc <- mergeConfig mc <- mergeConfig False
-- Syncing involves many actions, any of which -- Syncing involves many actions, any of which
-- can independently fail, without preventing -- can independently fail, without preventing
@ -234,7 +234,7 @@ seek' o = do
content <- shouldSyncContent o content <- shouldSyncContent o
forM_ (filter isImport contentremotes) $ forM_ (filter isImport contentremotes) $
withbranch . importRemote content o mc withbranch . importRemote content o
forM_ (filter isThirdPartyPopulated contentremotes) $ forM_ (filter isThirdPartyPopulated contentremotes) $
pullThirdPartyPopulated o pullThirdPartyPopulated o
@ -275,20 +275,17 @@ seek' o = do
prepMerge :: Annex () prepMerge :: Annex ()
prepMerge = Annex.changeDirectory . fromRawFilePath =<< fromRepo Git.repoPath prepMerge = Annex.changeDirectory . fromRawFilePath =<< fromRepo Git.repoPath
mergeConfig :: Annex [Git.Merge.MergeConfig] mergeConfig :: Bool -> Annex [Git.Merge.MergeConfig]
mergeConfig = do mergeConfig mergeunrelated = do
quiet <- commandProgressDisabled quiet <- commandProgressDisabled
return $ catMaybes return $ catMaybes
[ Just Git.Merge.MergeNonInteractive [ Just Git.Merge.MergeNonInteractive
-- In several situations, unrelated histories should be , if mergeunrelated
-- merged together. This includes pairing in the assistant, then Just Git.Merge.MergeUnrelatedHistories
-- merging from a remote into a newly created direct mode else Nothing
-- repo, and an initial merge from an import from a special , if quiet
-- remote. (Once direct mode is removed, this could be then Just Git.Merge.MergeQuiet
-- changed, so only the assistant and import from special else Nothing
-- remotes use it.)
, Just Git.Merge.MergeUnrelatedHistories
, if quiet then Just Git.Merge.MergeQuiet else Nothing
] ]
merge :: CurrBranch -> [Git.Merge.MergeConfig] -> SyncOptions -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool 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)) ai = ActionItemOther (Just (Remote.name remote))
si = SeekInput [] si = SeekInput []
importRemote :: Bool -> SyncOptions -> [Git.Merge.MergeConfig] -> Remote -> CurrBranch -> CommandSeek importRemote :: Bool -> SyncOptions -> Remote -> CurrBranch -> CommandSeek
importRemote importcontent o mergeconfig remote currbranch importRemote importcontent o remote currbranch
| not (pullOption o) || not wantpull = noop | not (pullOption o) || not wantpull = noop
| otherwise = case remoteAnnexTrackingBranch (Remote.gitconfig remote) of | otherwise = case remoteAnnexTrackingBranch (Remote.gitconfig remote) of
Nothing -> noop Nothing -> noop
@ -497,7 +494,13 @@ importRemote importcontent o mergeconfig remote currbranch
if canImportKeys remote importcontent if canImportKeys remote importcontent
then do then do
Command.Import.seekRemote remote branch subdir importcontent (CheckGitIgnore True) 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." else warning $ "Cannot import from " ++ Remote.name remote ++ " when not syncing content."
where where
wantpull = remoteAnnexPull (Remote.gitconfig remote) wantpull = remoteAnnexPull (Remote.gitconfig remote)