sync, merge: Added --allow-unrelated-histories option

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
This commit is contained in:
Joey Hess 2021-07-19 12:08:24 -04:00
parent b6bea0d3f2
commit 3d50b47ded
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
7 changed files with 67 additions and 34 deletions

View file

@ -14,6 +14,8 @@ git-annex (8.20210715) UNRELEASED; urgency=medium
(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

View file

@ -1,6 +1,6 @@
{- 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.
-}
@ -12,22 +12,34 @@ import qualified Annex.Branch
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
@ -39,17 +51,17 @@ 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 []

View file

@ -1,7 +1,7 @@
{- 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.
-}
@ -24,6 +24,7 @@ module Command.Sync (
syncBranch,
updateBranches,
seekExportContent,
parseUnrelatedHistoriesOption,
SyncOptions(..),
) where
@ -102,6 +103,7 @@ data SyncOptions = SyncOptions
, cleanupOption :: Bool
, keyOptions :: Maybe KeyOptions
, resolveMergeOverride :: Bool
, allowUnrelatedHistories :: Bool
}
instance Default SyncOptions where
@ -120,6 +122,7 @@ instance Default SyncOptions where
, cleanupOption = False
, keyOptions = Nothing
, resolveMergeOverride = False
, allowUnrelatedHistories = False
}
optParser :: CmdParamsDesc -> Parser SyncOptions
@ -177,6 +180,13 @@ optParser desc = 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.
@ -196,6 +206,7 @@ instance DeferredParseClass SyncOptions where
<*> pure (cleanupOption v)
<*> pure (keyOptions v)
<*> pure (resolveMergeOverride v)
<*> pure (allowUnrelatedHistories v)
seek :: SyncOptions -> CommandSeek
seek o = do
@ -218,7 +229,7 @@ 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

View file

@ -1983,7 +1983,7 @@ test_export_import_subdir = intmpclonerepo $ do
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.

View file

@ -42,19 +42,17 @@ currently checked out branch.
For example:
git annex import master --from myremote
git annex merge myremote/master
git annex merge --allow-unrelated-histories 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.
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.
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.
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

View file

@ -22,7 +22,12 @@ will not be done.
# 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

View file

@ -150,6 +150,11 @@ have the same value as the currently checked out branch.
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