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:
globGit treats the pattern as a shell glob suitable for consumption by
fnmatch(3)with theFNM_PATHNAMEflag: wildcards in the pattern will not match a/in the pathname. For example,Documentation/*.htmlmatchesDocumentation/git.htmlbut notDocumentation/ppc/ppc.htmlortools/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.
