support git 2.34.0's handling of merge conflict between annexed and non-annexed file
This version of git -- or its new default "ort" resolver -- handles such a conflict by staging two files, one with the original name and the other named file~ref. Use unmergedSiblingFile when the latter is detected. (It doesn't do that when the conflict is between a directory and a file or symlink though, so see previous commit for how that case is handled.) The sibling file has to be deleted separately, because cleanConflictCruft may not delete it -- that only handles files that are annex links, but the sibling file may be the non-annexed file side of the conflict. The graftin code had assumed that, when the other side of a conclict is a symlink, the file in the work tree will contain the non-annexed content that we want it to contain. But that is not the case with the new git; the file may be the annex link and needs to be replaced with the content, while the annex link will be written as a -variant file. (The weird doesDirectoryExist check in graftin turns out to still be needed, test suite failed when I tried to remove it.) Test suite passes with new git with ort resolver default. Have not tried it with old git or other defaults. Sponsored-by: Noam Kremen on Patreon
This commit is contained in:
parent
c49787824c
commit
5a7f253974
5 changed files with 95 additions and 22 deletions
|
@ -5,6 +5,8 @@
|
|||
- Licensed under the GNU AGPL version 3 or higher.
|
||||
-}
|
||||
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
|
||||
module Git.LsFiles (
|
||||
Options(..),
|
||||
inRepo,
|
||||
|
@ -236,7 +238,14 @@ data Unmerged = Unmerged
|
|||
{ unmergedFile :: RawFilePath
|
||||
, unmergedTreeItemType :: Conflicting TreeItemType
|
||||
, unmergedSha :: Conflicting Sha
|
||||
}
|
||||
, unmergedSiblingFile :: Maybe RawFilePath
|
||||
-- ^ Normally this is Nothing, because a
|
||||
-- merge conflict is represented as a single file with two
|
||||
-- stages. However, git resolvers sometimes choose to stage
|
||||
-- two files, one for each side of the merge conflict. In such a case,
|
||||
-- this is used for the name of the second file, which is related
|
||||
-- to the first file. (Eg, "foo" and "foo~ref")
|
||||
} deriving (Show)
|
||||
|
||||
{- Returns a list of the files in the specified locations that have
|
||||
- unresolved merge conflicts.
|
||||
|
@ -246,7 +255,7 @@ data Unmerged = Unmerged
|
|||
- 1 = old version, can be ignored
|
||||
- 2 = us
|
||||
- 3 = them
|
||||
- If a line is omitted, that side removed the file.
|
||||
- If line 2 or 3 is omitted, that side removed the file.
|
||||
-}
|
||||
unmerged :: [RawFilePath] -> Repo -> IO ([Unmerged], IO Bool)
|
||||
unmerged l repo = guardSafeForLsFiles repo $ do
|
||||
|
@ -265,7 +274,7 @@ data InternalUnmerged = InternalUnmerged
|
|||
, ifile :: RawFilePath
|
||||
, itreeitemtype :: Maybe TreeItemType
|
||||
, isha :: Maybe Sha
|
||||
}
|
||||
} deriving (Show)
|
||||
|
||||
parseUnmerged :: String -> Maybe InternalUnmerged
|
||||
parseUnmerged s
|
||||
|
@ -296,16 +305,25 @@ reduceUnmerged c (i:is) = reduceUnmerged (new:c) rest
|
|||
{ unmergedFile = ifile i
|
||||
, unmergedTreeItemType = Conflicting treeitemtypeA treeitemtypeB
|
||||
, unmergedSha = Conflicting shaA shaB
|
||||
, unmergedSiblingFile = if ifile sibi == ifile i
|
||||
then Nothing
|
||||
else Just (ifile sibi)
|
||||
}
|
||||
findsib templatei [] = ([], removed templatei)
|
||||
findsib templatei (l:ls)
|
||||
| ifile l == ifile templatei = (ls, l)
|
||||
| ifile l == ifile templatei || issibfile templatei l = (ls, l)
|
||||
| otherwise = (l:ls, removed templatei)
|
||||
removed templatei = templatei
|
||||
{ isus = not (isus templatei)
|
||||
, itreeitemtype = Nothing
|
||||
, isha = Nothing
|
||||
}
|
||||
-- foo~<ref> are unmerged sibling files of foo
|
||||
-- Some versions or resolvers of git stage the sibling files,
|
||||
-- other versions or resolvers do not.
|
||||
issibfile x y = (ifile x <> "~") `S.isPrefixOf` ifile y
|
||||
&& isus x || isus y
|
||||
&& not (isus x && isus y)
|
||||
|
||||
{- Gets the InodeCache equivilant information stored in the git index.
|
||||
-
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue