Support git remotes where .git is a file, not a directory
Eg when --separate-git-dir was used, and core.symlinks=false. This commit was sponsored by Brock Spratlen on Patreon.
This commit is contained in:
parent
cde3e5eb0c
commit
41ebed3941
4 changed files with 60 additions and 17 deletions
|
@ -16,6 +16,8 @@ git-annex (8.20200815) UNRELEASED; urgency=medium
|
||||||
held by another process.
|
held by another process.
|
||||||
* test: Stop gpg-agent daemons that are started for the test framework's
|
* test: Stop gpg-agent daemons that are started for the test framework's
|
||||||
gpg key.
|
gpg key.
|
||||||
|
* Support git remotes where .git is a file, not a directory,
|
||||||
|
eg when --separate-git-dir was used.
|
||||||
|
|
||||||
-- Joey Hess <id@joeyh.name> Fri, 14 Aug 2020 14:57:45 -0400
|
-- Joey Hess <id@joeyh.name> Fri, 14 Aug 2020 14:57:45 -0400
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{- Construction of Git Repo objects
|
{- Construction of Git Repo objects
|
||||||
-
|
-
|
||||||
- Copyright 2010-2012 Joey Hess <id@joeyh.name>
|
- Copyright 2010-2020 Joey Hess <id@joeyh.name>
|
||||||
-
|
-
|
||||||
- Licensed under the GNU AGPL version 3 or higher.
|
- Licensed under the GNU AGPL version 3 or higher.
|
||||||
-}
|
-}
|
||||||
|
@ -73,7 +73,7 @@ fromAbsPath dir
|
||||||
, ret (takeDirectory canondir)
|
, ret (takeDirectory canondir)
|
||||||
)
|
)
|
||||||
| otherwise = ifM (doesDirectoryExist dir)
|
| otherwise = ifM (doesDirectoryExist dir)
|
||||||
( ret dir
|
( gitDirFile dir >>= maybe (ret dir) (pure . newFrom)
|
||||||
-- git falls back to dir.git when dir doesn't
|
-- git falls back to dir.git when dir doesn't
|
||||||
-- exist, as long as dir didn't end with a
|
-- exist, as long as dir didn't end with a
|
||||||
-- path separator
|
-- path separator
|
||||||
|
@ -198,7 +198,7 @@ expandTilde = expandt True
|
||||||
checkForRepo :: FilePath -> IO (Maybe RepoLocation)
|
checkForRepo :: FilePath -> IO (Maybe RepoLocation)
|
||||||
checkForRepo dir =
|
checkForRepo dir =
|
||||||
check isRepo $
|
check isRepo $
|
||||||
check gitDirFile $
|
check (gitDirFile dir) $
|
||||||
check isBareRepo $
|
check isBareRepo $
|
||||||
return Nothing
|
return Nothing
|
||||||
where
|
where
|
||||||
|
@ -217,22 +217,26 @@ checkForRepo dir =
|
||||||
gitSignature (".git" </> "gitdir")
|
gitSignature (".git" </> "gitdir")
|
||||||
isBareRepo = checkdir $ gitSignature "config"
|
isBareRepo = checkdir $ gitSignature "config"
|
||||||
<&&> doesDirectoryExist (dir </> "objects")
|
<&&> doesDirectoryExist (dir </> "objects")
|
||||||
gitDirFile = do
|
|
||||||
-- git-submodule, git-worktree, and --separate-git-dir
|
|
||||||
-- make .git be a file pointing to the real git directory.
|
|
||||||
c <- firstLine <$>
|
|
||||||
catchDefaultIO "" (readFile $ dir </> ".git")
|
|
||||||
return $ if gitdirprefix `isPrefixOf` c
|
|
||||||
then Just $ Local
|
|
||||||
{ gitdir = toRawFilePath $ absPathFrom dir $
|
|
||||||
drop (length gitdirprefix) c
|
|
||||||
, worktree = Just (toRawFilePath dir)
|
|
||||||
}
|
|
||||||
else Nothing
|
|
||||||
where
|
|
||||||
gitdirprefix = "gitdir: "
|
|
||||||
gitSignature file = doesFileExist $ dir </> file
|
gitSignature file = doesFileExist $ dir </> file
|
||||||
|
|
||||||
|
-- git-submodule, git-worktree, and --separate-git-dir
|
||||||
|
-- make .git be a file pointing to the real git directory.
|
||||||
|
-- Detect that, and return a RepoLocation with gitdir pointing
|
||||||
|
-- to the real git directory.
|
||||||
|
gitDirFile :: FilePath -> IO (Maybe RepoLocation)
|
||||||
|
gitDirFile dir = do
|
||||||
|
c <- firstLine <$>
|
||||||
|
catchDefaultIO "" (readFile $ dir </> ".git")
|
||||||
|
return $ if gitdirprefix `isPrefixOf` c
|
||||||
|
then Just $ Local
|
||||||
|
{ gitdir = toRawFilePath $ absPathFrom dir $
|
||||||
|
drop (length gitdirprefix) c
|
||||||
|
, worktree = Just (toRawFilePath dir)
|
||||||
|
}
|
||||||
|
else Nothing
|
||||||
|
where
|
||||||
|
gitdirprefix = "gitdir: "
|
||||||
|
|
||||||
newFrom :: RepoLocation -> Repo
|
newFrom :: RepoLocation -> Repo
|
||||||
newFrom l = Repo
|
newFrom l = Repo
|
||||||
{ location = l
|
{ location = l
|
||||||
|
|
|
@ -178,3 +178,5 @@ shaddy@jazz-debian:~/slaveproj$ ls -lL services
|
||||||
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
|
### Have you had any luck using git-annex before? (Sometimes we get tired of reading bug reports all day and a lil' positive end note does wonders)
|
||||||
|
|
||||||
This issue is not a show stopper. I otherwise love the concepts behind git-annex very much.
|
This issue is not a show stopper. I otherwise love the concepts behind git-annex very much.
|
||||||
|
|
||||||
|
> [[fixed|done]] --[[Joey]]
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
[[!comment format=mdwn
|
||||||
|
username="joey"
|
||||||
|
subject="""comment 1"""
|
||||||
|
date="2020-08-28T18:03:46Z"
|
||||||
|
content="""
|
||||||
|
--separate-git-dir makes eg, masterproj/.git be a file that contains the
|
||||||
|
path to the git dir.
|
||||||
|
|
||||||
|
git-annex init converts such a .git file to a symlink. That is necessary
|
||||||
|
for git-annex symlinks to be resolved, since they always link to files
|
||||||
|
inside .git, and if it's a file, the symlinks won't point to the object
|
||||||
|
files.
|
||||||
|
|
||||||
|
On windows, since core.symlinks is false, it does not make that change.
|
||||||
|
|
||||||
|
So, I think the problem might be that, when .git is a file rather
|
||||||
|
than a symlink, git-annex in the clone doesn't read the .git file to determine
|
||||||
|
the real git repo location, and so can't find annexed files in its remote.
|
||||||
|
|
||||||
|
Seem to have found a way to produce the same problem on linux:
|
||||||
|
|
||||||
|
* git init --separate-git-dir masterproj.git masterproj
|
||||||
|
* cd masterproj; git config core.symlinks false
|
||||||
|
* git-annex init
|
||||||
|
* add file, commit, make clone
|
||||||
|
|
||||||
|
git-annex get in the clone then fails
|
||||||
|
|
||||||
|
openat(AT_FDCWD, "../masterproj/.git/annex/objects/3f/3K/SHA256E-s30--32a7ec5a2905bbeda54a699ed797c96c1fea7b5bc31a6cc104b2ddefe65a95bb/SHA256E-s30--32a7ec5a2905bbeda54a699ed797c96c1fea7b5bc31a6cc104b2ddefe65a95bb", O_RDONLY) = -1 ENOTDIR (Not a directory)
|
||||||
|
|
||||||
|
So, I think it would make sense for git-annex to notice when
|
||||||
|
a remote's .git is a file rather than a directory, and adjust the remote
|
||||||
|
accordingly, so it uses its actual git directory. That will solve
|
||||||
|
this situation.
|
||||||
|
"""]]
|
Loading…
Add table
Add a link
Reference in a new issue