summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Joey Hess <joey@kitenet.net>2014-03-04 20:06:55 -0400
committerGravatar Joey Hess <joey@kitenet.net>2014-03-04 20:06:55 -0400
commitd259c769074cc7307a64ddd55f3f309ad6725138 (patch)
tree10c2f923fea3181cee3a4abcae232658db809c95
parent34eb9b2fdc036e1dab4008751e88b312315928d1 (diff)
devblog
-rw-r--r--doc/devblog/day__126-127__merge_fixes.mdwn61
1 files changed, 61 insertions, 0 deletions
diff --git a/doc/devblog/day__126-127__merge_fixes.mdwn b/doc/devblog/day__126-127__merge_fixes.mdwn
new file mode 100644
index 000000000..f46f4b555
--- /dev/null
+++ b/doc/devblog/day__126-127__merge_fixes.mdwn
@@ -0,0 +1,61 @@
+Yesterday I learned of a nasty bug in handling of merges in direct mode. It
+turns out that if the remote repository has added a file, and there is a
+conflicting file in the local work tree, which has not been added to git, the
+local file was overwritten when git-annex did a merge. That's really bad, I'm
+very unhappy this bug lurked undetected for so long.
+
+Understanding the bug was easy. Fixing it turned out to be hard, because
+the automatic merge conflict resolution code was quite a mess. In
+particular, it wrote files to the work tree, which made it difficult for a
+later stage to detect and handle the abovementioned case. Also, the
+automatic merge resolution code had weird asymetric structure that I never
+fully understood, and generally needed to be stared at for an hour to begin
+to understand it.
+
+In the process of cleaning that up, I wrote several more tests,
+to ensure that every case was handled correctly. Coverage was about 50%
+of the cases, and should now be 100%.
+
+To add to the fun, a while ago I had dealt with a bug on FAT/Windows where
+it sometimes lost the symlink bit during automatic merge resolution. Except
+it turned out my test case for it had a heisenbug, and I had not actually
+fixed it (I think). In any case, my old fix for it was a large part
+of the ugliness I was cleaning up, and had to be rewritten.
+Fully tracking down and dealing with that took a large part of today.
+
+Finally this evening, I added support for automatically handling merge
+conflicts where one side is an annexed file, and the other side has the
+same filename committed to git in the normal way. This is not an important
+case, but it's worth it for completeness. There was an unexpected benefit
+to doing it; it turned out that the weird asymetric part of the code went
+away.
+
+The final core of the automatic merge conflict resolver has morphed from
+a mess I'd not want to paste here to a quite consise and easy to follow
+bit of code.
+
+[[!format haskell """
+ case (kus, kthem) of
+ -- Both sides of conflict are annexed files
+ (Just keyUs, Just keyThem) -> resolveby $
+ if keyUs == keyThem
+ then makelink keyUs
+ else do
+ makelink keyUs
+ makelink keyThem
+ -- Our side is annexed file, other side is not.
+ (Just keyUs, Nothing) -> resolveby $ do
+ graftin them file
+ makelink keyUs
+ -- Our side is not annexed file, other side is.
+ (Nothing, Just keyThem) -> resolveby $ do
+ graftin us file
+ makelink keyThem
+ -- Neither side is annexed file; cannot resolve.
+ (Nothing, Nothing) -> return Nothing
+"""]]
+
+Since the bug that started all this is so bad, I want to make a release
+pretty soon.. But I will probably let it soak and whale on the test suite
+a bit more first. (This bug is also probably worth backporting to old
+versions of git-annex in eg Debian stable.)