summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joeyh@joeyh.name>2017-06-01 12:46:36 -0400
committerGravatar Joey Hess <joeyh@joeyh.name>2017-06-01 12:51:01 -0400
commitde8f6959d3cd4af348e7a72c45e6e1d6d3cd4cfa (patch)
treef63493430204d764d84a44a909f68b778b719716
parent5c058d99a26da3639afcbf855eb7b6ca3d628fb3 (diff)
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.
-rw-r--r--Annex/AdjustedBranch.hs6
-rw-r--r--Annex/AutoMerge.hs13
-rw-r--r--Assistant/Sync.hs3
-rw-r--r--Assistant/Threads/Merger.hs1
-rw-r--r--CHANGELOG4
-rw-r--r--Command/Merge.hs2
-rw-r--r--Command/PostReceive.hs2
-rw-r--r--Command/Sync.hs41
-rw-r--r--Types/GitConfig.hs3
-rw-r--r--doc/forum/controlling_how___34__git_annex_sync__34___resolves_conflicts/comment_2_c091e5a668b15aca7b2faa955beab403._comment8
-rw-r--r--doc/git-annex-config.mdwn6
-rw-r--r--doc/git-annex-merge.mdwn3
-rw-r--r--doc/git-annex-sync.mdwn17
-rw-r--r--doc/git-annex.mdwn9
14 files changed, 89 insertions, 29 deletions
diff --git a/Annex/AdjustedBranch.hs b/Annex/AdjustedBranch.hs
index c0225540a..52f73e638 100644
--- a/Annex/AdjustedBranch.hs
+++ b/Annex/AdjustedBranch.hs
@@ -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
)
diff --git a/Annex/AutoMerge.hs b/Annex/AutoMerge.hs
index 7f982e515..91f8fc99e 100644
--- a/Annex/AutoMerge.hs
+++ b/Annex/AutoMerge.hs
@@ -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
diff --git a/Assistant/Sync.hs b/Assistant/Sync.hs
index 8f30aa4f7..e6a5bc5d5 100644
--- a/Assistant/Sync.hs
+++ b/Assistant/Sync.hs
@@ -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
diff --git a/Assistant/Threads/Merger.hs b/Assistant/Threads/Merger.hs
index 0bb37e664..05341db1e 100644
--- a/Assistant/Threads/Merger.hs
+++ b/Assistant/Threads/Merger.hs
@@ -78,6 +78,7 @@ onChange file
]
void $ liftAnnex $ Command.Sync.merge
currbranch Command.Sync.mergeConfig
+ def
Git.Branch.AutomaticCommit
changedbranch
mergecurrent _ = noop
diff --git a/CHANGELOG b/CHANGELOG
index 3540b937a..d85926d70 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -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
diff --git a/Command/Merge.hs b/Command/Merge.hs
index 80a8227d1..4f99093ab 100644
--- a/Command/Merge.hs
+++ b/Command/Merge.hs
@@ -33,4 +33,4 @@ mergeBranch = do
mergeSynced :: CommandStart
mergeSynced = do
prepMerge
- mergeLocal mergeConfig =<< join getCurrBranch
+ mergeLocal mergeConfig def =<< join getCurrBranch
diff --git a/Command/PostReceive.hs b/Command/PostReceive.hs
index ffb5516a2..4db775214 100644
--- a/Command/PostReceive.hs
+++ b/Command/PostReceive.hs
@@ -48,4 +48,4 @@ fixPostReceiveHookEnv = do
updateInsteadEmulation :: CommandStart
updateInsteadEmulation = do
prepMerge
- mergeLocal mergeConfig =<< join getCurrBranch
+ mergeLocal mergeConfig def =<< join getCurrBranch
diff --git a/Command/Sync.hs b/Command/Sync.hs
index 332daca73..9ecb98620 100644
--- a/Command/Sync.hs
+++ b/Command/Sync.hs
@@ -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]
diff --git a/Types/GitConfig.hs b/Types/GitConfig.hs
index f66136cb1..cec64b57a 100644
--- a/Types/GitConfig.hs
+++ b/Types/GitConfig.hs
@@ -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
diff --git a/doc/forum/controlling_how___34__git_annex_sync__34___resolves_conflicts/comment_2_c091e5a668b15aca7b2faa955beab403._comment b/doc/forum/controlling_how___34__git_annex_sync__34___resolves_conflicts/comment_2_c091e5a668b15aca7b2faa955beab403._comment
new file mode 100644
index 000000000..f254f6e7d
--- /dev/null
+++ b/doc/forum/controlling_how___34__git_annex_sync__34___resolves_conflicts/comment_2_c091e5a668b15aca7b2faa955beab403._comment
@@ -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`
+"""]]
diff --git a/doc/git-annex-config.mdwn b/doc/git-annex-config.mdwn
index 8b505cde3..bf24251d8 100644
--- a/doc/git-annex-config.mdwn
+++ b/doc/git-annex-config.mdwn
@@ -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.
diff --git a/doc/git-annex-merge.mdwn b/doc/git-annex-merge.mdwn
index 3001e9bed..bb204d725 100644
--- a/doc/git-annex-merge.mdwn
+++ b/doc/git-annex-merge.mdwn
@@ -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)
diff --git a/doc/git-annex-sync.mdwn b/doc/git-annex-sync.mdwn
index a27d31565..2aa009cf8 100644
--- a/doc/git-annex-sync.mdwn
+++ b/doc/git-annex-sync.mdwn
@@ -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)
diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn
index 8a841a941..99f6c9076 100644
--- a/doc/git-annex.mdwn
+++ b/doc/git-annex.mdwn
@@ -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.