aboutsummaryrefslogtreecommitdiff
path: root/Annex/VariantFile.hs
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2014-03-03 14:57:16 -0400
committerGravatar Joey Hess <joey@kitenet.net>2014-03-03 14:57:16 -0400
commita9067868a8594577ead2ecbe55f9563bef12f26d (patch)
tree1694cea1754589a7cf0d8ed3096e03d9d430b99d /Annex/VariantFile.hs
parent8d6edac6f48a4bf1522b68a30db579193c097e7a (diff)
sync: Fix bug in direct mode that caused a file not checked into git to be deleted when merging with a remote that added a file by the same name. (Thanks, jkt)
Diffstat (limited to 'Annex/VariantFile.hs')
-rw-r--r--Annex/VariantFile.hs45
1 files changed, 45 insertions, 0 deletions
diff --git a/Annex/VariantFile.hs b/Annex/VariantFile.hs
new file mode 100644
index 000000000..7c849c59f
--- /dev/null
+++ b/Annex/VariantFile.hs
@@ -0,0 +1,45 @@
+{- git-annex .variant files for automatic merge conflict resolution
+ -
+ - Copyright 2014 Joey Hess <joey@kitenet.net>
+ -
+ - Licensed under the GNU GPL version 3 or higher.
+ -}
+
+module Annex.VariantFile where
+
+import Common.Annex
+import Types.Key
+
+import Data.Hash.MD5
+
+variantMarker :: String
+variantMarker = ".variant-"
+
+mkVariant :: FilePath -> String -> FilePath
+mkVariant file variant = takeDirectory file
+ </> dropExtension (takeFileName file)
+ ++ variantMarker ++ variant
+ ++ takeExtension file
+
+{- The filename to use when resolving a conflicted merge of a file,
+ - that points to a key.
+ -
+ - Something derived from the key needs to be included in the filename,
+ - but rather than exposing the whole key to the user, a very weak hash
+ - is used. There is a very real, although still unlikely, chance of
+ - conflicts using this hash.
+ -
+ - In the event that there is a conflict with the filename generated
+ - for some other key, that conflict will itself be handled by the
+ - conflicted merge resolution code. That case is detected, and the full
+ - key is used in the filename.
+ -}
+variantFile :: FilePath -> Key -> FilePath
+variantFile file key
+ | doubleconflict = mkVariant file (key2file key)
+ | otherwise = mkVariant file (shortHash $ key2file key)
+ where
+ doubleconflict = variantMarker `isInfixOf` file
+
+shortHash :: String -> String
+shortHash = take 4 . md5s . md5FilePath