configuration to disable automatic merge conflict resolution
* Added annex.resolvemerge configuration, which can be set to false to disable the usual automatic merge conflict resolution done by git-annex sync and the assistant. * sync: Added --no-resolvemerge option. Note that disabling merge conflict resolution is probably not a good idea in a direct mode repo or adjusted branch. Since updates to both are done outside the usual work tree, if it fails the tree is not left in a conflicted state, and it would be hard to manually resolve the conflict. Still, made annex.resolvemerge be supported in those cases for consistency. This commit was sponsored by Riku Voipio.
This commit is contained in:
parent
d5cb853dd0
commit
94351daba6
14 changed files with 89 additions and 29 deletions
|
@ -318,8 +318,8 @@ findAdjustingCommit (AdjBranch b) = go =<< catCommit b
|
|||
{- Update the currently checked out adjusted branch, merging the provided
|
||||
- branch into it. Note that the provided branch should be a non-adjusted
|
||||
- branch. -}
|
||||
updateAdjustedBranch :: Branch -> (OrigBranch, Adjustment) -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Annex Bool
|
||||
updateAdjustedBranch tomerge (origbranch, adj) mergeconfig commitmode = catchBoolIO $
|
||||
updateAdjustedBranch :: Branch -> (OrigBranch, Adjustment) -> [Git.Merge.MergeConfig] -> Annex Bool -> Git.Branch.CommitMode -> Annex Bool
|
||||
updateAdjustedBranch tomerge (origbranch, adj) mergeconfig canresolvemerge commitmode = catchBoolIO $
|
||||
join $ preventCommits go
|
||||
where
|
||||
adjbranch@(AdjBranch currbranch) = originalToAdjusted origbranch adj
|
||||
|
@ -417,7 +417,7 @@ updateAdjustedBranch tomerge (origbranch, adj) mergeconfig commitmode = catchBoo
|
|||
-- this commit will be a fast-forward.
|
||||
adjmergecommitff <- commitAdjustedTree' adjtree (BasisBranch mergecommit) [currbranch]
|
||||
showAction "Merging into adjusted branch"
|
||||
ifM (autoMergeFrom adjmergecommitff (Just currbranch) mergeconfig commitmode)
|
||||
ifM (autoMergeFrom adjmergecommitff (Just currbranch) mergeconfig canresolvemerge commitmode)
|
||||
( reparent adjtree adjmergecommit =<< getcurrentcommit
|
||||
, return False
|
||||
)
|
||||
|
|
|
@ -43,18 +43,18 @@ import qualified Data.ByteString.Lazy as L
|
|||
- Callers should use Git.Branch.changed first, to make sure that
|
||||
- there are changes from the current branch to the branch being merged in.
|
||||
-}
|
||||
autoMergeFrom :: Git.Ref -> Maybe Git.Ref -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Annex Bool
|
||||
autoMergeFrom branch currbranch mergeconfig commitmode = do
|
||||
autoMergeFrom :: Git.Ref -> Maybe Git.Ref -> [Git.Merge.MergeConfig] -> Annex Bool -> Git.Branch.CommitMode -> Annex Bool
|
||||
autoMergeFrom branch currbranch mergeconfig canresolvemerge commitmode = do
|
||||
showOutput
|
||||
case currbranch of
|
||||
Nothing -> go Nothing
|
||||
Just b -> go =<< inRepo (Git.Ref.sha b)
|
||||
where
|
||||
go old = ifM isDirect
|
||||
( mergeDirect currbranch old branch (resolveMerge old branch False) mergeconfig commitmode
|
||||
( mergeDirect currbranch old branch resolvemerge mergeconfig commitmode
|
||||
, do
|
||||
r <- inRepo (Git.Merge.merge branch mergeconfig commitmode)
|
||||
<||> (resolveMerge old branch False <&&> commitResolvedMerge commitmode)
|
||||
<||> (resolvemerge <&&> commitResolvedMerge commitmode)
|
||||
-- Merging can cause new associated files to appear
|
||||
-- and the smudge filter will add them to the database.
|
||||
-- To ensure that this process sees those changes,
|
||||
|
@ -62,6 +62,11 @@ autoMergeFrom branch currbranch mergeconfig commitmode = do
|
|||
Database.Keys.closeDb
|
||||
return r
|
||||
)
|
||||
where
|
||||
resolvemerge = ifM canresolvemerge
|
||||
( resolveMerge old branch False
|
||||
, return False
|
||||
)
|
||||
|
||||
{- Resolves a conflicted merge. It's important that any conflicts be
|
||||
- resolved in a way that itself avoids later merge conflicts, since
|
||||
|
|
|
@ -211,7 +211,8 @@ manualPull currentbranch remotes = do
|
|||
else return Nothing
|
||||
haddiverged <- liftAnnex Annex.Branch.forceUpdate
|
||||
forM_ normalremotes $ \r ->
|
||||
liftAnnex $ Command.Sync.mergeRemote r currentbranch Command.Sync.mergeConfig
|
||||
liftAnnex $ Command.Sync.mergeRemote r
|
||||
currentbranch Command.Sync.mergeConfig def
|
||||
return (catMaybes failed, haddiverged)
|
||||
where
|
||||
wantpull gc = remoteAnnexPull gc
|
||||
|
|
|
@ -78,6 +78,7 @@ onChange file
|
|||
]
|
||||
void $ liftAnnex $ Command.Sync.merge
|
||||
currbranch Command.Sync.mergeConfig
|
||||
def
|
||||
Git.Branch.AutomaticCommit
|
||||
changedbranch
|
||||
mergecurrent _ = noop
|
||||
|
|
|
@ -12,6 +12,10 @@ git-annex (6.20170520) UNRELEASED; urgency=medium
|
|||
* metadata: When setting metadata of a file that did not exist,
|
||||
no error message was displayed, unlike getting metadata and most other
|
||||
git-annex commands. Fixed this oversight.
|
||||
* Added annex.resolvemerge configuration, which can be set to false to
|
||||
disable the usual automatic merge conflict resolution done by git-annex
|
||||
sync and the assistant.
|
||||
* sync: Added --no-resolvemerge option.
|
||||
|
||||
-- Joey Hess <id@joeyh.name> Wed, 24 May 2017 14:03:40 -0400
|
||||
|
||||
|
|
|
@ -33,4 +33,4 @@ mergeBranch = do
|
|||
mergeSynced :: CommandStart
|
||||
mergeSynced = do
|
||||
prepMerge
|
||||
mergeLocal mergeConfig =<< join getCurrBranch
|
||||
mergeLocal mergeConfig def =<< join getCurrBranch
|
||||
|
|
|
@ -48,4 +48,4 @@ fixPostReceiveHookEnv = do
|
|||
updateInsteadEmulation :: CommandStart
|
||||
updateInsteadEmulation = do
|
||||
prepMerge
|
||||
mergeLocal mergeConfig =<< join getCurrBranch
|
||||
mergeLocal mergeConfig def =<< join getCurrBranch
|
||||
|
|
|
@ -76,8 +76,14 @@ data SyncOptions = SyncOptions
|
|||
, noContentOption :: Bool
|
||||
, contentOfOption :: [FilePath]
|
||||
, keyOptions :: Maybe KeyOptions
|
||||
, resolveMergeOverride :: ResolveMergeOverride
|
||||
}
|
||||
|
||||
newtype ResolveMergeOverride = ResolveMergeOverride Bool
|
||||
|
||||
instance Default ResolveMergeOverride where
|
||||
def = ResolveMergeOverride False
|
||||
|
||||
optParser :: CmdParamsDesc -> Parser SyncOptions
|
||||
optParser desc = SyncOptions
|
||||
<$> (many $ argument str
|
||||
|
@ -117,6 +123,9 @@ optParser desc = SyncOptions
|
|||
<> metavar paramPath
|
||||
))
|
||||
<*> optional parseAllOption
|
||||
<*> (ResolveMergeOverride <$> invertableSwitch "resolvemerge" True
|
||||
( help "do not automatically resolve merge conflicts"
|
||||
))
|
||||
|
||||
-- Since prepMerge changes the working directory, FilePath options
|
||||
-- have to be adjusted.
|
||||
|
@ -132,6 +141,7 @@ instance DeferredParseClass SyncOptions where
|
|||
<*> pure (noContentOption v)
|
||||
<*> liftIO (mapM absPath (contentOfOption v))
|
||||
<*> pure (keyOptions v)
|
||||
<*> pure (resolveMergeOverride v)
|
||||
|
||||
seek :: SyncOptions -> CommandSeek
|
||||
seek o = allowConcurrentOutput $ do
|
||||
|
@ -150,7 +160,7 @@ seek o = allowConcurrentOutput $ do
|
|||
-- These actions cannot be run concurrently.
|
||||
mapM_ includeCommandAction $ concat
|
||||
[ [ commit o ]
|
||||
, [ withbranch (mergeLocal mergeConfig) ]
|
||||
, [ withbranch (mergeLocal mergeConfig (resolveMergeOverride o)) ]
|
||||
, map (withbranch . pullRemote o mergeConfig) gitremotes
|
||||
, [ mergeAnnex ]
|
||||
]
|
||||
|
@ -219,11 +229,14 @@ mergeConfig =
|
|||
, Git.Merge.MergeUnrelatedHistories
|
||||
]
|
||||
|
||||
merge :: CurrBranch -> [Git.Merge.MergeConfig] -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool
|
||||
merge (Just b, Just adj) mergeconfig commitmode tomerge =
|
||||
updateAdjustedBranch tomerge (b, adj) mergeconfig commitmode
|
||||
merge (b, _) mergeconfig commitmode tomerge =
|
||||
autoMergeFrom tomerge b mergeconfig commitmode
|
||||
merge :: CurrBranch -> [Git.Merge.MergeConfig] -> ResolveMergeOverride -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool
|
||||
merge currbranch mergeconfig resolvemergeoverride commitmode tomerge = case currbranch of
|
||||
(Just b, Just adj) -> updateAdjustedBranch tomerge (b, adj) mergeconfig canresolvemerge commitmode
|
||||
(b, _) -> autoMergeFrom tomerge b mergeconfig canresolvemerge commitmode
|
||||
where
|
||||
canresolvemerge = case resolvemergeoverride of
|
||||
ResolveMergeOverride True -> getGitConfigVal annexResolveMerge
|
||||
ResolveMergeOverride False -> return False
|
||||
|
||||
syncBranch :: Git.Branch -> Git.Branch
|
||||
syncBranch = Git.Ref.underBase "refs/heads/synced" . fromDirectBranch . fromAdjustedBranch
|
||||
|
@ -296,15 +309,15 @@ commitStaged commitmode commitmessage = do
|
|||
void $ inRepo $ Git.Branch.commit commitmode False commitmessage branch parents
|
||||
return True
|
||||
|
||||
mergeLocal :: [Git.Merge.MergeConfig] -> CurrBranch -> CommandStart
|
||||
mergeLocal mergeconfig currbranch@(Just _, _) =
|
||||
mergeLocal :: [Git.Merge.MergeConfig] -> ResolveMergeOverride -> CurrBranch -> CommandStart
|
||||
mergeLocal mergeconfig resolvemergeoverride currbranch@(Just _, _) =
|
||||
go =<< needMerge currbranch
|
||||
where
|
||||
go Nothing = stop
|
||||
go (Just syncbranch) = do
|
||||
showStart "merge" $ Git.Ref.describe syncbranch
|
||||
next $ next $ merge currbranch mergeconfig Git.Branch.ManualCommit syncbranch
|
||||
mergeLocal _ (Nothing, madj) = do
|
||||
next $ next $ merge currbranch mergeconfig resolvemergeoverride Git.Branch.ManualCommit syncbranch
|
||||
mergeLocal _ _ (Nothing, madj) = do
|
||||
b <- inRepo Git.Branch.currentUnsafe
|
||||
ifM (isJust <$> needMerge (b, madj))
|
||||
( do
|
||||
|
@ -365,7 +378,7 @@ pullRemote o mergeconfig remote branch = stopUnless (pure $ pullOption o && want
|
|||
next $ do
|
||||
showOutput
|
||||
stopUnless fetch $
|
||||
next $ mergeRemote remote branch mergeconfig
|
||||
next $ mergeRemote remote branch mergeconfig (resolveMergeOverride o)
|
||||
where
|
||||
fetch = inRepoWithSshOptionsTo (Remote.repo remote) (Remote.gitconfig remote) $
|
||||
Git.Command.runBool
|
||||
|
@ -377,8 +390,8 @@ pullRemote o mergeconfig remote branch = stopUnless (pure $ pullOption o && want
|
|||
- were committed (or pushed changes, if this is a bare remote),
|
||||
- while the synced/master may have changes that some
|
||||
- other remote synced to this remote. So, merge them both. -}
|
||||
mergeRemote :: Remote -> CurrBranch -> [Git.Merge.MergeConfig] -> CommandCleanup
|
||||
mergeRemote remote currbranch mergeconfig = ifM isBareRepo
|
||||
mergeRemote :: Remote -> CurrBranch -> [Git.Merge.MergeConfig] -> ResolveMergeOverride -> CommandCleanup
|
||||
mergeRemote remote currbranch mergeconfig resolvemergeoverride = ifM isBareRepo
|
||||
( return True
|
||||
, case currbranch of
|
||||
(Nothing, _) -> do
|
||||
|
@ -390,7 +403,7 @@ mergeRemote remote currbranch mergeconfig = ifM isBareRepo
|
|||
)
|
||||
where
|
||||
mergelisted getlist = and <$>
|
||||
(mapM (merge currbranch mergeconfig Git.Branch.ManualCommit . remoteBranch remote) =<< getlist)
|
||||
(mapM (merge currbranch mergeconfig resolvemergeoverride Git.Branch.ManualCommit . remoteBranch remote) =<< getlist)
|
||||
tomerge = filterM (changed remote)
|
||||
branchlist Nothing = []
|
||||
branchlist (Just branch) = [branch, syncBranch branch]
|
||||
|
|
|
@ -58,6 +58,7 @@ data GitConfig = GitConfig
|
|||
, annexHttpHeaders :: [String]
|
||||
, annexHttpHeadersCommand :: Maybe String
|
||||
, annexAutoCommit :: Configurable Bool
|
||||
, annexResolveMerge :: Configurable Bool
|
||||
, annexSyncContent :: Configurable Bool
|
||||
, annexDebug :: Bool
|
||||
, annexWebOptions :: [String]
|
||||
|
@ -115,6 +116,8 @@ extractGitConfig r = GitConfig
|
|||
, annexHttpHeadersCommand = getmaybe (annex "http-headers-command")
|
||||
, annexAutoCommit = configurable True $
|
||||
getmaybebool (annex "autocommit")
|
||||
, annexResolveMerge = configurable True $
|
||||
getmaybebool (annex "resolvemerge")
|
||||
, annexSyncContent = configurable False $
|
||||
getmaybebool (annex "synccontent")
|
||||
, annexDebug = getbool (annex "debug") False
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
[[!comment format=mdwn
|
||||
username="joey"
|
||||
subject="""comment 2"""
|
||||
date="2017-06-01T16:16:44Z"
|
||||
content="""
|
||||
I've implemented the annex.automerge configuration setting, for the next
|
||||
release. There's also a `git annex sync --no-resolvemerge`
|
||||
"""]]
|
|
@ -32,6 +32,12 @@ These settings can be overridden on a per-repository basis using
|
|||
Set to false to prevent the git-annex assistant and git-annex sync
|
||||
from automatically committing changes to files in the repository.
|
||||
|
||||
* `annex.resolvemerge`
|
||||
|
||||
Set to false to prevent merge conflicts being automatically resolved
|
||||
by the git-annex assitant, git-annex sync, git-annex merge,
|
||||
and the git-annex post-receive hook.
|
||||
|
||||
* `annex.synccontent`
|
||||
|
||||
Set to true to make git-annex sync default to syncing content.
|
||||
|
|
|
@ -12,6 +12,9 @@ This performs the same merging (and merge conflict resolution)
|
|||
that is done by the sync command, but without pushing or pulling any
|
||||
data.
|
||||
|
||||
When annex.resolvemerge is set to false, merge conflict resolution
|
||||
will not be done.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
[[git-annex]](1)
|
||||
|
|
|
@ -21,11 +21,6 @@ worry about the details, you can use sync.
|
|||
The content of annexed objects is not synced by default, but the --content
|
||||
option (see below) can make that also be synchronized.
|
||||
|
||||
Merge conflicts are automatically handled by sync. When two conflicting
|
||||
versions of a file have been committed, both will be added to the tree,
|
||||
under different filenames. For example, file "foo" would be replaced
|
||||
with "foo.somekey" and "foo.otherkey".
|
||||
|
||||
Note that syncing with a remote will not normally update the remote's working
|
||||
tree with changes made to the local repository. (Unless it's configured
|
||||
with receive.denyCurrentBranch=updateInstead.) However, those changes
|
||||
|
@ -114,6 +109,18 @@ by running "git annex sync" on the remote.
|
|||
less efficient. When --content is synced, the files are processed
|
||||
in parallel as well.
|
||||
|
||||
* `--resolvemerge`, `--no-resolvemerge`
|
||||
|
||||
By default, merge conflicts are automatically handled by sync. When two
|
||||
conflicting versions of a file have been committed, both will be added
|
||||
to the tree, under different filenames. For example, file "foo"
|
||||
would be replaced with "foo.variant-A" and "foo.variant-B". (See
|
||||
[[git-annex-resolvemerge]](1) for details.)
|
||||
|
||||
Use `--no-resolvemerge` to disable this automatic merge conflict
|
||||
resolution. It can also be disabled by setting annex.resolvemerge
|
||||
to false.
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
[[git-annex]](1)
|
||||
|
|
|
@ -1040,6 +1040,15 @@ Here are all the supported configuration settings.
|
|||
To configure the behavior in all clones of the repository,
|
||||
this can be set in [[git-annex-config]].
|
||||
|
||||
* `annex.resolvemerge`
|
||||
|
||||
Set to false to prevent merge conflicts being automatically resolved
|
||||
by the git-annex assitant, git-annex sync, git-annex merge,
|
||||
and the git-annex post-receive hook.
|
||||
|
||||
To configure the behavior in all clones of the repository,
|
||||
this can be set in [[git-annex-config]].
|
||||
|
||||
* `annex.synccontent`
|
||||
|
||||
Set to true to make git-annex sync default to syncing content.
|
||||
|
|
Loading…
Reference in a new issue