Which is the same as the git merge option.
After last commit, this turns out to be needed in the test suite, and when
doing git-annex import from special remote, followed by a git-annex merge.
Sponsored-by: Svenne Krap on Patreon
(However, sync does still merge unrelated histories when importing
trees from special remotes, and the assistant still merges unrelated
histories.)
+ * sync, merge: Added --allow-unrelated-histories option, which
+ is the same as the git merge option.
-- Joey Hess <id@joeyh.name> Wed, 14 Jul 2021 14:26:36 -0400
{- git-annex command
-
- - Copyright 2011-2019 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2021 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
import qualified Git
import qualified Git.Branch
import Annex.CurrentBranch
-import Command.Sync (prepMerge, mergeLocal, mergeConfig, merge, SyncOptions(..))
+import Command.Sync (prepMerge, mergeLocal, mergeConfig, merge, notOnlyAnnexOption, parseUnrelatedHistoriesOption)
import Git.Types
cmd :: Command
cmd = command "merge" SectionMaintenance
"merge changes from remotes"
- (paramOptional paramRef) (withParams seek)
+ (paramOptional paramRef) (seek <$$> optParser)
-seek :: CmdParams -> CommandSeek
-seek [] = do
- prepMerge
- commandAction mergeAnnexBranch
- commandAction mergeSyncedBranch
-seek bs = do
- prepMerge
- forM_ bs (commandAction . mergeBranch . Git.Ref . encodeBS')
+data MergeOptions = MergeOptions
+ { mergeBranches :: [String]
+ , allowUnrelatedHistories :: Bool
+ }
+
+optParser :: CmdParamsDesc -> Parser MergeOptions
+optParser desc = MergeOptions
+ <$> cmdParams desc
+ <*> parseUnrelatedHistoriesOption
+
+seek :: MergeOptions -> CommandSeek
+seek o
+ | mergeBranches o == [] = do
+ prepMerge
+ commandAction mergeAnnexBranch
+ commandAction (mergeSyncedBranch o)
+ | otherwise = do
+ prepMerge
+ forM_ (mergeBranches o) $
+ commandAction . mergeBranch o . Git.Ref . encodeBS'
mergeAnnexBranch :: CommandStart
mergeAnnexBranch = starting "merge" ai si $ do
ai = ActionItemOther (Just (fromRef Annex.Branch.name))
si = SeekInput []
-mergeSyncedBranch :: CommandStart
-mergeSyncedBranch = do
- mc <- mergeConfig False
+mergeSyncedBranch :: MergeOptions -> CommandStart
+mergeSyncedBranch o = do
+ mc <- mergeConfig (allowUnrelatedHistories o)
mergeLocal mc def =<< getCurrentBranch
-mergeBranch :: Git.Ref -> CommandStart
-mergeBranch r = starting "merge" ai si $ do
+mergeBranch :: MergeOptions -> Git.Ref -> CommandStart
+mergeBranch o r = starting "merge" ai si $ do
currbranch <- getCurrentBranch
- let o = def { notOnlyAnnexOption = True }
- mc <- mergeConfig False
- next $ merge currbranch mc o Git.Branch.ManualCommit r
+ mc <- mergeConfig (allowUnrelatedHistories o)
+ let so = def { notOnlyAnnexOption = True }
+ next $ merge currbranch mc so Git.Branch.ManualCommit r
where
ai = ActionItemOther (Just (Git.fromRef r))
si = SeekInput []
{- git-annex command
-
- Copyright 2011 Joachim Breitner <mail@joachim-breitner.de>
- - Copyright 2011-2020 Joey Hess <id@joeyh.name>
+ - Copyright 2011-2021 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
syncBranch,
updateBranches,
seekExportContent,
+ parseUnrelatedHistoriesOption,
SyncOptions(..),
) where
, cleanupOption :: Bool
, keyOptions :: Maybe KeyOptions
, resolveMergeOverride :: Bool
+ , allowUnrelatedHistories :: Bool
}
instance Default SyncOptions where
, cleanupOption = False
, keyOptions = Nothing
, resolveMergeOverride = False
+ , allowUnrelatedHistories = False
}
optParser :: CmdParamsDesc -> Parser SyncOptions
<*> invertableSwitch "resolvemerge" True
( help "do not automatically resolve merge conflicts"
)
+ <*> parseUnrelatedHistoriesOption
+
+parseUnrelatedHistoriesOption :: Parser Bool
+parseUnrelatedHistoriesOption =
+ invertableSwitch "allow-unrelated-histories" False
+ ( help "allow merging unrelated histories"
+ )
-- Since prepMerge changes the working directory, FilePath options
-- have to be adjusted.
<*> pure (cleanupOption v)
<*> pure (keyOptions v)
<*> pure (resolveMergeOverride v)
+ <*> pure (allowUnrelatedHistories v)
seek :: SyncOptions -> CommandSeek
seek o = do
commandAction (withbranch cleanupLocal)
mapM_ (commandAction . withbranch . cleanupRemote) gitremotes
else do
- mc <- mergeConfig False
+ mc <- mergeConfig (allowUnrelatedHistories o)
-- Syncing involves many actions, any of which
-- can independently fail, without preventing
testimport = do
origbranch <- annexeval origBranch
git_annex "import" [origbranch++":"++subdir, "--from", "foo"] "import of subdir"
- git_annex "merge" ["foo/master"] "git annex merge foo/master"
+ git_annex "merge" ["foo/master", "--allow-unrelated-histories"] "git annex merge foo/master"
-- Make sure that import did not import the file to the top
-- of the repo.
For example:
git annex import master --from myremote
- git annex merge myremote/master
-
-You could just as well use `git merge myremote/master` as the second step,
-but using `git-annex merge` avoids a couple of gotchas. When using adjusted
-branches, it adjusts the branch before merging from it. And it avoids
-the merge failing on the first merge from an import due to unrelated
-histories.
-
-If you do use `git merge`, you can pass `--allow-unrelated-histories` the
-first time you `git merge` from an import. Think of this as the remote
-being a separate git repository with its own files. If you first
-`git annex export` files to a remote, and then `git annex import` from it,
-you won't need that option.
+ git annex merge --allow-unrelated-histories myremote/master
+
+You could just as well use `git merge --allow-unrelated-histories myremote/master`
+as the second step, but using `git-annex merge` avoids a couple of gotchas.
+When using adjusted branches, it adjusts the branch before merging from it.
+
+The --allow-unrelated-histories option is needed for at least the first
+merge of an imported remote tracking branch, since the branch's history is
+not connected. Think of this as the remote being a separate git repository
+with its own files. If you first `git annex export` files to a remote, and
+then `git annex import` from it, you won't need that option.
You can import into a subdirectory, using the "branch:subdir" syntax. For
example, if "camera" is a special remote that accesses a camera, and you
# OPTIONS
-* The [[git-annex-common-options]](1) can be used.
+* `--allow-unrelated-histories`, `--no-allow-unrelated-histories`
+
+ Passed on to `git merge`, to control whether or not to merge
+ histories that do not share a common ancestor.
+
+* Also, the [[git-annex-common-options]](1) can be used.
# SEE ALSO
less efficient. When --content is synced, the files are processed
in parallel as well.
+* `--allow-unrelated-histories`, `--no-allow-unrelated-histories`
+
+ Passed on to `git merge`, to control whether or not to merge
+ histories that do not share a common ancestor.
+
* `--resolvemerge`, `--no-resolvemerge`
By default, merge conflicts are automatically handled by sync. When two