run out of tree merge with --no-ff

This is how direct mode does it too, and somehow, for reasons that
currently escape me, this makes git merge not care if it's run with an
empty work tree.
This commit is contained in:
Joey Hess 2016-04-06 18:40:28 -04:00
parent 60bdffe43e
commit 887ef93a7f
Failed to extract signature
5 changed files with 20 additions and 12 deletions

View file

@ -32,6 +32,7 @@ import qualified Git.Ref
import qualified Git.Command import qualified Git.Command
import qualified Git.Tree import qualified Git.Tree
import qualified Git.DiffTree import qualified Git.DiffTree
import qualified Git.Merge
import Git.Tree (TreeItem(..)) import Git.Tree (TreeItem(..))
import Git.Sha import Git.Sha
import Git.Env import Git.Env
@ -272,13 +273,16 @@ updateAdjustedBranch tomerge (origbranch, adj) commitmode = catchBoolIO $
withemptydir tmpwt $ withWorkTree tmpwt $ do withemptydir tmpwt $ withWorkTree tmpwt $ do
liftIO $ writeFile (tmpgit </> "HEAD") (fromRef updatedorig) liftIO $ writeFile (tmpgit </> "HEAD") (fromRef updatedorig)
showAction $ "Merging into " ++ fromRef (Git.Ref.base origbranch) showAction $ "Merging into " ++ fromRef (Git.Ref.base origbranch)
ifM (autoMergeFrom tomerge (Just origbranch) True commitmode) -- The --no-ff is important; it makes git
( do -- merge not care that the work tree is empty.
merged <- inRepo (Git.Merge.mergeNonInteractive' [Param "--no-ff"] tomerge commitmode)
<||> (resolveMerge (Just updatedorig) tomerge True <&&> commitResolvedMerge commitmode)
if merged
then do
!mergecommit <- liftIO $ extractSha <$> readFile (tmpgit </> "HEAD") !mergecommit <- liftIO $ extractSha <$> readFile (tmpgit </> "HEAD")
-- This is run after the commit lock is dropped. -- This is run after the commit lock is dropped.
return $ postmerge currbranch mergecommit return $ postmerge currbranch mergecommit
, return $ return False else return $ return False
)
changestomerge Nothing _ = return $ return False changestomerge Nothing _ = return $ return False
withemptydir d a = bracketIO setup cleanup (const a) withemptydir d a = bracketIO setup cleanup (const a)
@ -305,7 +309,7 @@ updateAdjustedBranch tomerge (origbranch, adj) commitmode = catchBoolIO $
adjmergecommit <- commitAdjustedTree' adjtree mergecommit adjmergecommit <- commitAdjustedTree' adjtree mergecommit
[mergecommit, currbranch] [mergecommit, currbranch]
showAction "Merging into adjusted branch" showAction "Merging into adjusted branch"
ifM (autoMergeFrom adjmergecommit (Just currbranch) False commitmode) ifM (autoMergeFrom adjmergecommit (Just currbranch) commitmode)
-- The adjusted branch has a merge commit on top; -- The adjusted branch has a merge commit on top;
-- clean that up and propigate any changes made -- clean that up and propigate any changes made
-- in that merge to the origbranch. -- in that merge to the origbranch.

View file

@ -42,8 +42,8 @@ import qualified Data.ByteString.Lazy as L
- Callers should use Git.Branch.changed first, to make sure that - Callers should use Git.Branch.changed first, to make sure that
- there are changes from the current branch to the branch being merged in. - there are changes from the current branch to the branch being merged in.
-} -}
autoMergeFrom :: Git.Ref -> Maybe Git.Ref -> Bool -> Git.Branch.CommitMode -> Annex Bool autoMergeFrom :: Git.Ref -> Maybe Git.Ref -> Git.Branch.CommitMode -> Annex Bool
autoMergeFrom branch currbranch inoverlay commitmode = do autoMergeFrom branch currbranch commitmode = do
showOutput showOutput
case currbranch of case currbranch of
Nothing -> go Nothing Nothing -> go Nothing
@ -52,7 +52,7 @@ autoMergeFrom branch currbranch inoverlay commitmode = do
go old = ifM isDirect go old = ifM isDirect
( mergeDirect currbranch old branch (resolveMerge old branch False) commitmode ( mergeDirect currbranch old branch (resolveMerge old branch False) commitmode
, inRepo (Git.Merge.mergeNonInteractive branch commitmode) , inRepo (Git.Merge.mergeNonInteractive branch commitmode)
<||> (resolveMerge old branch inoverlay <&&> commitResolvedMerge commitmode) <||> (resolveMerge old branch False <&&> commitResolvedMerge commitmode)
) )
{- Resolves a conflicted merge. It's important that any conflicts be {- Resolves a conflicted merge. It's important that any conflicts be

View file

@ -204,6 +204,7 @@ stageMerge d branch commitmode = do
-- has been updated, which would leave things in an inconsistent -- has been updated, which would leave things in an inconsistent
-- state if mergeDirectCleanup is interrupted. -- state if mergeDirectCleanup is interrupted.
-- <http://marc.info/?l=git&m=140262402204212&w=2> -- <http://marc.info/?l=git&m=140262402204212&w=2>
liftIO $ print ("stagemerge in", d)
merger <- ifM (coreSymlinks <$> Annex.getGitConfig) merger <- ifM (coreSymlinks <$> Annex.getGitConfig)
( return Git.Merge.stageMerge ( return Git.Merge.stageMerge
, return $ \ref -> Git.Merge.mergeNonInteractive ref commitmode , return $ \ref -> Git.Merge.mergeNonInteractive ref commitmode

View file

@ -170,7 +170,7 @@ merge :: CurrBranch -> Git.Branch.CommitMode -> Git.Branch -> Annex Bool
merge (Just b, Just adj) commitmode tomerge = merge (Just b, Just adj) commitmode tomerge =
updateAdjustedBranch tomerge (b, adj) commitmode updateAdjustedBranch tomerge (b, adj) commitmode
merge (b, _) commitmode tomerge = merge (b, _) commitmode tomerge =
autoMergeFrom tomerge b False commitmode autoMergeFrom tomerge b commitmode
syncBranch :: Git.Branch -> Git.Branch syncBranch :: Git.Branch -> Git.Branch
syncBranch = Git.Ref.under "refs/heads/synced" . fromDirectBranch . fromAdjustedBranch syncBranch = Git.Ref.under "refs/heads/synced" . fromDirectBranch . fromAdjustedBranch

View file

@ -15,12 +15,15 @@ import Git.Branch (CommitMode(..))
{- Avoids recent git's interactive merge. -} {- Avoids recent git's interactive merge. -}
mergeNonInteractive :: Ref -> CommitMode -> Repo -> IO Bool mergeNonInteractive :: Ref -> CommitMode -> Repo -> IO Bool
mergeNonInteractive branch commitmode mergeNonInteractive = mergeNonInteractive' []
mergeNonInteractive' :: [CommandParam] -> Ref -> CommitMode -> Repo -> IO Bool
mergeNonInteractive' extraparams branch commitmode
| older "1.7.7.6" = merge [Param $ fromRef branch] | older "1.7.7.6" = merge [Param $ fromRef branch]
| otherwise = merge $ [Param "--no-edit", Param $ fromRef branch] | otherwise = merge $ [Param "--no-edit", Param $ fromRef branch]
where where
merge ps = runBool $ cp ++ [Param "merge"] ++ ps merge ps = runBool $ sp ++ [Param "merge"] ++ ps ++ extraparams
cp sp
| commitmode == AutomaticCommit = | commitmode == AutomaticCommit =
[Param "-c", Param "commit.gpgsign=false"] [Param "-c", Param "commit.gpgsign=false"]
| otherwise = [] | otherwise = []