diff --git a/CHANGELOG b/CHANGELOG index fe00907ccf..877f7ddd5a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ git-annex (8.20210331) UNRELEASED; urgency=medium * Avoid excess commits to the git-annex branch when stall detection is enabled. * Added --debugfilter (and annex.debugfilter) + * diffdriver: Support unlocked files. -- Joey Hess Thu, 01 Apr 2021 12:17:26 -0400 diff --git a/Command/DiffDriver.hs b/Command/DiffDriver.hs index e0cef22234..9dc8c5b26b 100644 --- a/Command/DiffDriver.hs +++ b/Command/DiffDriver.hs @@ -1,6 +1,6 @@ {- git-annex command - - - Copyright 2014 Joey Hess + - Copyright 2014-2021 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} @@ -77,8 +77,12 @@ parseReq opts = case separate (== "--") opts of {- Check if either file is a symlink to a git-annex object, - which git-diff will leave as a normal file containing the link text. - - Adjust the Req to instead point to the actual location of the annexed - - object (which may or may not exist). -} + - + - Also check if either file is a pointer file, as used for unlocked files. + - + - In either case, adjust the Req to instead point to the actual + - location of the annexed object (which may or may not be present). + -} fixupReq :: Req -> Annex Req fixupReq req@(UnmergedReq {}) = return req fixupReq req@(Req {}) = @@ -87,12 +91,13 @@ fixupReq req@(Req {}) = where check getfile getmode setfile r = case readTreeItemType (encodeBS' (getmode r)) of Just TreeSymlink -> do - v <- getAnnexLinkTarget' (toRawFilePath (getfile r)) False - case parseLinkTargetOrPointer =<< v of - Nothing -> return r - Just k -> withObjectLoc k $ - pure . setfile r . fromRawFilePath - _ -> return r + v <- getAnnexLinkTarget' f False + maybe (return r) repoint (parseLinkTargetOrPointer =<< v) + _ -> maybe (return r) repoint =<< liftIO (isPointerFile f) + where + repoint k = withObjectLoc k $ + pure . setfile r . fromRawFilePath + f = toRawFilePath (getfile r) externalDiffer :: String -> [String] -> Differ externalDiffer c ps = \req -> boolSystem c (map Param ps ++ serializeReq req ) diff --git a/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__.mdwn b/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__.mdwn index c810a05a6d..f0a221c448 100644 --- a/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__.mdwn +++ b/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__.mdwn @@ -117,3 +117,5 @@ git status [[!meta author=yoh]] [[!tag projects/datalad]] + +> [[fixed|done]] --[[Joey]] diff --git a/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__/comment_1_f5f0bb494672fb6b959c2a72a042467d._comment b/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__/comment_1_f5f0bb494672fb6b959c2a72a042467d._comment new file mode 100644 index 0000000000..3fec3b29ea --- /dev/null +++ b/doc/bugs/diffdriver_does_not_workout_on_unlocked_file__63__/comment_1_f5f0bb494672fb6b959c2a72a042467d._comment @@ -0,0 +1,29 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 1""" + date="2021-04-08T18:09:25Z" + content=""" +Let's see, I have a file foo that was added, locked, and committed. +I then unlock foo, and modify it. Then I run + + GIT_EXTERNAL_DIFF='git-annex diffdriver -- my-diff --' git diff HEAD + +And my-diff is a shell script that prints "$@". So I see: + + foo .git/annex/objects/W8/Zw/SHA256E-s30--9e179ece66f95419f996974c1e478294d6d6e8ea3eee2e6694d1d2fba5d82704/SHA256E-s30--9e179ece66f95419f996974c1e478294d6d6e8ea3eee2e6694d1d2fba5d82704 ebf7004afbf3838eaad7db6af8b77eb21eb1f810 120000 foo 0000000000000000000000000000000000000000 100644 + +$2 is the old content of the file, which git-annex diffdriver has correctly +fixed up to be the annex object file. $5 is the new version of the file +which git-annex has not touched, but it's "foo" in the working tree, which is right. + +So that's ok, what about the other way around. Start with foo being unlocked, +commit that, then modify it, and add it locked. Now I see: + + foo /home/joey/tmp/5klQtl_foo 1a822e679e46982e0119f0ea725aaaffc6954f4b 100644 .git/annex/objects/wm/ZV/SHA256E-s8--ca7eb6f8a60a1abaddc1df52662184d6e7b33feca3cb5165343321dc35aeda17/SHA256E-s8--ca7eb6f8a60a1abaddc1df52662184d6e7b33feca3cb5165343321dc35aeda17 3ba78f367ca1a5b5bf6a4054a117d5d9a013073a 120000 + +Here git-annex diffdriver has correctly fixed up $5, but $2 is left as-is, +and if I have it cat that tmp file, it's "/annex/objects/SHA..."; the git-annex +link used for the locked file. + +Ok, now I understand. :) +"""]] diff --git a/doc/git-annex-diffdriver.mdwn b/doc/git-annex-diffdriver.mdwn index 3df61154e1..f787c69fdd 100644 --- a/doc/git-annex-diffdriver.mdwn +++ b/doc/git-annex-diffdriver.mdwn @@ -9,10 +9,10 @@ git annex diffdriver `-- cmd --opts --` # DESCRIPTION This is an external git diff driver shim. Normally, when using `git diff` -with an external diff driver, the symlinks to annexed files are not set up -right, so the external diff driver cannot read them in order to perform -smart diffing of their contents. This command works around the problem, -by passing the fixed up files to the real external diff driver. +with an external diff driver, it will not see the contents of annexed +files, since git passes to it the git-annex symlinks or pointer files. +This command works around the problem, by running the +real external diff driver, and passing it the paths to the annexed content. To use this, you will need to have installed some git external diff driver command. This is not the regular diff command; it takes a git-specific