diffdriver: Support unlocked files

This commit is contained in:
Joey Hess 2021-04-08 14:32:09 -04:00
parent e0dc101179
commit 805d325a8d
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 50 additions and 13 deletions

View file

@ -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 <id@joeyh.name> Thu, 01 Apr 2021 12:17:26 -0400

View file

@ -1,6 +1,6 @@
{- git-annex command
-
- Copyright 2014 Joey Hess <id@joeyh.name>
- Copyright 2014-2021 Joey Hess <id@joeyh.name>
-
- 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 )

View file

@ -117,3 +117,5 @@ git status
[[!meta author=yoh]]
[[!tag projects/datalad]]
> [[fixed|done]] --[[Joey]]

View file

@ -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. :)
"""]]

View file

@ -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