From 3af29b3ba91f2cb9dc8b6b0c1b0607e7d2aa165f Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 26 Oct 2018 13:35:13 -0400 Subject: [PATCH] When annex.thin is set, allow hard links to be made between executable work tree files and annex objects. This is safe, because while the annex object ends up executable, there were already at least two other cases where it ended up executable: 1. git add an an executable file 2. chmod +x of a a non-executable worktree file that was hard linked to the annex object After copy/hard link, it always fixes up the permissions to match the mode of the worktree file, so when an executable annex object gets hard linked to a non-executable worktree file, its execute bit gets removed. Commit b7c8bf5274a64389ac87d6ce0388b8708c261971 already *said* it would do this; I suspect the line of code I've removed was included in that commit accidentially. Also improves annex.thin documentation. This commit was sponsored by Boyd Stephen Smith Jr. on Patreon. --- Annex/Content/LowLevel.hs | 1 - CHANGELOG | 2 ++ ...le_across_lock__47__unlock_or_cloning.mdwn | 2 ++ ..._41478c52765cf09a94c7137437ad8716._comment | 1 + ..._2b36163f3c8cca18ce4b05e381bf1795._comment | 24 +++++++++++++++++++ doc/git-annex.mdwn | 7 ++++-- 6 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_5_2b36163f3c8cca18ce4b05e381bf1795._comment diff --git a/Annex/Content/LowLevel.hs b/Annex/Content/LowLevel.hs index 54fc0a4ed8..47e6a9dee4 100644 --- a/Annex/Content/LowLevel.hs +++ b/Annex/Content/LowLevel.hs @@ -49,7 +49,6 @@ linkOrCopy = linkOrCopy' (annexThin <$> Annex.getGitConfig) linkOrCopy' :: Annex Bool -> Key -> FilePath -> FilePath -> Maybe FileMode -> Annex (Maybe LinkedOrCopied) linkOrCopy' canhardlink key src dest destmode - | maybe False isExecutable destmode = copy =<< getstat | otherwise = catchDefaultIO Nothing $ ifM canhardlink ( hardlink diff --git a/CHANGELOG b/CHANGELOG index ff25b44456..88e22e6714 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -44,6 +44,8 @@ git-annex (7.20181025) UNRELEASED; urgency=medium exporttree remote. * init --version=6 will still work, but the repository is auto-upgraded immediately to v7. + * When annex.thin is set, allow hard links to be made between executable + work tree files and annex objects. -- Joey Hess Sat, 13 Oct 2018 00:52:02 -0400 diff --git a/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning.mdwn b/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning.mdwn index 220c6306ef..c3c0570374 100644 --- a/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning.mdwn +++ b/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning.mdwn @@ -377,3 +377,5 @@ total 12 lil' positive end note mode on: git-annex is the only thing to which I trust my archive of most valuable documents and memories! + +> [[done]]; see comments --[[Joey]] diff --git a/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_4_41478c52765cf09a94c7137437ad8716._comment b/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_4_41478c52765cf09a94c7137437ad8716._comment index c938dc193a..533c94dad4 100644 --- a/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_4_41478c52765cf09a94c7137437ad8716._comment +++ b/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_4_41478c52765cf09a94c7137437ad8716._comment @@ -5,6 +5,7 @@ subject="comment 4" date="2018-10-18T23:34:26Z" content=""" + I am stupid talking about executable files hardlinking. I think I just chmod-ed already hardlinking files, that's how I got it. No surprise. I am ok with this quirk (executable files are not thinned), but just curious: what exactly influenced such design decision? diff --git a/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_5_2b36163f3c8cca18ce4b05e381bf1795._comment b/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_5_2b36163f3c8cca18ce4b05e381bf1795._comment new file mode 100644 index 0000000000..5caf7d5038 --- /dev/null +++ b/doc/bugs/v6_hardlinking_is_not_stable_across_lock__47__unlock_or_cloning/comment_5_2b36163f3c8cca18ce4b05e381bf1795._comment @@ -0,0 +1,24 @@ +[[!comment format=mdwn + username="joey" + subject="""comment 5""" + date="2018-10-26T17:17:35Z" + content=""" +[[!commit b7c8bf5274a64389ac87d6ce0388b8708c261971]] is where that was +implemented. Interestingly, its commit message does say that the annex +object file is made executable when using annex.thin. +And indeed, git add of an executable file with annex.thin set does +make the object executable and hard link to it. + +But that commit contains this line that avoids hard linking: + + | maybe False isExecutable destmode = copy =<< getstat + +Which is what I based my earlier comment on. But without that line, +AFAIK it will behave the way you want, with the annex object and +executable worktree file being hard linked. The code also removes the +execute bit if the annex object file later ends up getting hard linked +instead to a non-executable file. + +So, based on this analysis, I'm going to remove that line. And improve the +annex.thin docs slightly, and I think that's sufficient to close this bug. +"""]] diff --git a/doc/git-annex.mdwn b/doc/git-annex.mdwn index 2ee23d5787..1cb95b8245 100644 --- a/doc/git-annex.mdwn +++ b/doc/git-annex.mdwn @@ -1024,13 +1024,16 @@ Here are all the supported configuration settings. * `annex.thin` Set this to `true` to make unlocked files be a hard link to their content - in the annex, rather than a second copy. (Only when supported by the file - system, and only in repository version 6.) This can save considerable + in the annex, rather than a second copy. This can save considerable disk space, but when a modification is made to a file, you will lose the local (and possibly only) copy of the old version. So, enable with care. After setting (or unsetting) this, you should run `git annex fix` to fix up the annexed files in the work tree to be hard links (or copies). + + Note that this has no effect when the filesystem does not support hard links. + And when multiple files in the work tree have the same content, only + one of them gets hard linked to the annex. * `annex.delayadd`