'How to make git checkout-index strip off prefix
I would like use git checkout-index in way that it strips out the current prefix from the file names.
For example, I am sitting in my repository in the directory
repo/foo/bar/baz
and in this directory are a bunch of files and directories
./file1
./dir1/file2
I would like to do git checkout-index to a directory /tmp/baz so that I end up with
/tmp/baz/file1
/tmp/baz/dir1/file2
If I do
git checkout-index --prefix=/tmp/baz/
then I end up with
/tmp/baz/foo/bar/baz/file1
/tmp/baz/foo/bar/baz/dir1/file2
Solution 1:[1]
May not be the best solution, but if you do a git checkout-index --temp <file> you can get just the file with a .merge_file_XXX name (capture the name from the output of the checkout-index) and then you can mv that to where you want and rename it, but the file is still left in the index (you can git reset it if you want to unstage it). You can wrap this up into a script.
Another approach might be to use git ls-files --stage, which will list all the blobs and you can git show a blob to get the file contents and cat that to a file name created by stripping off the path prefix on the output of that (on the same line as the sha in the output of git ls-files). Again, a scriptable thing.
Solution 2:[2]
If you are using the git checkout-index --temp <file> approach, make sure this is with Git 2.31 (Q1 2021).
The error codepath around the "--temp/--prefix" feature of "git checkout-index"(man) has been improved.
See commit 3f7ba60, commit 9334ea8 (16 Feb 2021) by Matheus Tavares (matheustavares).
(Merged by Junio C Hamano -- gitster -- in commit 3da165c, 25 Feb 2021)
checkout-index: omit entries with no tempname from--tempoutputSigned-off-by: Matheus Tavares
With
--temp(or--stage=all, which implies--temp),checkout-indexwrites a list to stdout associating temporary file names to the entries' names.
But if it fails to write an entry, and the failure happens before even assigning a temporary filename to that entry, we get an odd output line.
This can be seen when trying to check out a symlink whose blob is missing:$ missing_blob=$(git hash-object --stdin </dev/null) $ git update-index --add --cacheinfo 120000,$missing_blob,foo $ git checkout-index --temp foo error: unable to read sha1 file of foo (e69de29bb2d1d6434b8b29ae775ad8c2e48c5391) fooThe '
TAB foo' line is not much useful and it might break scripts that expect the 'tempname TAB foo' output.
So let's omit such entries from the stdout list (but leaving the error message on stderr).We could also consider omitting all failed entries from the output list, but that's probably not a good idea as the associated tempfiles may have been created even when checkout failed, so scripts may want to use the output list for cleanup.
With Git 2.36 (Q2 2022), pick a better random number generator and use it when we prepare temporary filenames (used for instance with git checkout-index --temp <file>).
See commit 47efda9, commit 05cd988 (17 Jan 2022) by brian m. carlson (bk2204).
(Merged by Junio C Hamano -- gitster -- in commit d073bdc, 11 Feb 2022)
wrapper: use aCSPRNGto generate random file namesSigned-off-by: brian m. carlson
The current way we generate random file names is by taking the seconds and microseconds, plus the PID, and mixing them together, then encoding them.
If this fails, we increment the value by 7777, and try again up toTMP_MAXtimes.Unfortunately, this is not the best idea from a security perspective.
If we're writing into TMPDIR, an attacker can guess these values easily and prevent us from creating any temporary files at all by creating them all first.
Even though we setTMP_MAXto 16384, this may be achievable in some contexts, even if unlikely to occur in practice.Fortunately, we can simply solve this by using the system cryptographically secure pseudorandom number generator (
CSPRNG) to generate a random 64-bit value, and use that as before.Note that there is still a small bias here, but because a six-character sequence chosen out of 62 characters provides about 36 bits of entropy, the bias here is less than 2^-28, which is acceptable, especially considering we'll retry several times.
Note that the use of a
CSPRNGin generating temporary file names is also used in manylibcs.glibcrecently changed from an approach similar to ours to using aCSPRNG, and FreeBSD and OpenBSD also use aCSPRNGin this case.
Even if the likelihood of an attack is low, we should still be at least as responsible in creating temporary files aslibcis.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 |
