If you do use git archive -o ../subarchive.zip HEAD:subdir
, make sure to do it with Git 2.41 (Q2 2023):
"git archive
"(man) run from a subdirectory mishandled attributes and paths outside the current directory.
See commit 92b1dd1 (24 Mar 2023) by René Scharfe (rscharfe
).
(Merged by Junio C Hamano -- gitster
-- in commit de73a20, 21 Apr 2023)
archive
: improve support for running in subdirectory
Reported-by: Cristian Le
Reported-by: Matthias Görgens
Signed-off-by: René Scharfe
When git archive
(man) is started in a subdirectory, it archives its corresponding tree and its child objects, only.
That is intended.
It does that by effectively cd'ing into that tree and setting "prefix" to the empty string.
This has unfortunate consequences, though: Attributes are anchored at the root of the repository and git archive
still applies them to subtrees, causing mismatches.
And when checking pathspecs it cannot tell the difference between one that doesn't match anthing or one that matches some actual blob outside of the subdirectory, leading to a confusing error message ("current working directory is untracked
").
Fix that by keeping the "prefix" value and passing it to pathspec and attribute functions, and shortening it using relative_path()
for paths written to the archive and (if --verbose
is given) to stdout.
Still reject attempts to archive files outside the current directory, but print a more specific error in that case ("outside the current directory
").
Recognizing it requires a full traversal of the subtree for each pathspec, however.
Allowing them would be easier, but archive entry paths starting with "../
" can be problematic to extract -- e.g. bsdtar
skips them by default.