I'm trying to get the versions of all files in a folder (but not in subfolders) including deletions.
Given a git repo with the following history:
$ git log --oneline
e654806 (HEAD -> master) Adding content to bar files
e43071a 3rd commit
1686e2f 2nd commit
3f21424 Initial commit
Trying to check out a version with a deleted file (added in e43071a) fails with:
git checkout 1686e2f foo/*.txt
error: pathspec 'foo/5.txt' did not match any file(s) known to git
So I delete all files in foo/
and checkout again
rm foo/*.txt
git checkout 1686e2f foo/*.txt
I was surprised to find that this gave me the version of all files both in foo and foo/bar from 1686e2f
$ git st
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: foo/1.txt
modified: foo/2.txt
modified: foo/bar/3.txt
modified: foo/bar/4.txt
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: foo/5.txt
how would I go about only getting the file versions of 1686e2f in foo
but not in foo/bar
?
CodePudding user response:
Read the pathspec
section of the gitglossary(7)
man page, which tells us:
the rest of the pathspec is a pattern for the remainder of the pathname. Paths relative to the directory prefix will be matched against that pattern using fnmatch(3); in particular, * and ?can match directory separators.
So that's why you're getting both foo/*.txt
and foo/bar/*.txt
. If
you keep reading, you'll find that you can add flags to the pathspec
that modify that behavior:
glob
Git treats the pattern as a shell glob suitable for consumption by
fnmatch(3)
with theFNM_PATHNAME
flag: wildcards in the pattern will not match a/
in the pathname. For example,Documentation/*.html
matchesDocumentation/git.html
but notDocumentation/ppc/ppc.html
ortools/perf/Documentation/perf.html
.
That means we can write this:
git checkout 1686e2f ':(glob)foo/*.txt'
And that will match only files in foo/
with a .txt
extension.