简体   繁体   English

Git结帐使用通配符到特定修订版

[英]Git checkout using wildcard to a specific revision

I have been seeking it on Google for 2 hours and still can't find the solution. 我一直在谷歌上搜索它2个小时仍然找不到解决方案。

I want to checkout all files with wildcard to a specific revision. 我想将带有通配符的所有文件签出到特定版本。 I used following command: 我使用以下命令:

git checkout 663090b1c 'src/app/**/*.spec.ts'

But it says: 但它说:

error: pathspec 'src/app/**/*.spec.ts' did not match any file(s) known to git.

Can anyone help me? 谁能帮我?

I believe that this should work, but clearly it doesn't. 我相信这应该有效,但显然不行。 Here's the effect of using the most recent Git (which you can get at https://github.com/git/git ) on Documentation/**/*.txt . 这是在Documentation/**/*.txt上使用最新的Git(可以在https://github.com/git/git上获得)的效果。

I built Git, then used the system Git (at 2.21, slightly behind this version which is 2.22.0.545.g9c9b961d7e ) to do this: 我构建了Git,然后使用系统Git(在2.21,稍微落后于这个版本2.22.0.545.g9c9b961d7e )来做到这一点:

$ rm Documentation/*/*.txt
$ git status --short | head
 D Documentation/RelNotes/1.5.0.1.txt
 D Documentation/RelNotes/1.5.0.2.txt
 D Documentation/RelNotes/1.5.0.3.txt
 D Documentation/RelNotes/1.5.0.4.txt
 D Documentation/RelNotes/1.5.0.5.txt
 D Documentation/RelNotes/1.5.0.6.txt
 D Documentation/RelNotes/1.5.0.7.txt
 D Documentation/RelNotes/1.5.0.txt
 D Documentation/RelNotes/1.5.1.1.txt
 D Documentation/RelNotes/1.5.1.2.txt
$ git checkout -- 'Documentation/**/*.txt'
$ git status --short | head
$ 

Now, however: 但是现在:

$ ./git checkout HEAD -- 'Documentation/**/*.txt'
error: pathspec 'Documentation/**/*.txt' did not match any file(s) known to git

It seems that pathspecs work when used with the index, but not when used with a commit hash. 似乎pathspecs在与索引一起使用时有效,但在与提交哈希一起使用时则不行。

As a workaround—note that this workaround is somewhat defective, though you can patch around it further—you can first read the desired commit into a temporary index, then do the git checkout from the temporary index. 作为一种解决方法,请注意这种解决方法有些缺陷,尽管您可以进一步修补它 - 您可以先将所需的提交读入临时索引,然后从临时索引执行git checkout The following script is completely untested. 以下脚本完全未经测试。

#! /bin/sh
# git-co-c-ps: git checkout <commit> <pathspec>
# work around a bug in which combining <commit> and <pathspec> does not work
. git-sh-setup
case $# in
2) ;;
*) die "usage: $0 <commit> <pathspec>";;
esac

hash=$(git rev-parse "$1^{commit}") || exit 1
export GIT_INDEX_FILE=$(mktemp) || exit 1
rm -f $GIT_INDEX_FILE
trap "rm -f $GIT_INDEX_FILE" 0 1 2 3 15
git read-tree "$hash" || exit 1
git checkout -- "$2"

The (untested) idea here is to read the commit specified by "$1" into a temporary index. 这里的(未经测试的)想法是将“$ 1”指定的提交读入临时索引。 (We could relax the ^{commit} to be just ^{tree} as any tree-ish should suffice.) Then, having read that into a temporary index, we use the mode of "git checkout" with a pathspec ($2) that works, using the temporary index. (我们可以放松^{commit}只是^{tree}因为任何树都应该足够了。)然后,将其读入临时索引,我们使用带有pathspec($ 2)的“git checkout”模式这是有效的,使用临时索引。 This writes to the work-tree. 这会写入工作树。

The defect is that the now-updated work-tree files are not also updated in the index. 缺陷是现在更新的工作树文件也未在索引中更新。 A real git checkout would have copied these same files to the index. 真正的git checkout会将这些相同的文件复制到索引中。 It should be possible to unset $GIT_INDEX_FILE and git add the added files to the real index. 应该可以取消设置$GIT_INDEX_FILE并将git add到真实索引中。 This is left as an exercise. 这是一个练习。 Note that it is not as trivial as just git add -- "$2" since some work-tree files may be in the work-tree not because they were read into the temporary index by the git read-tree operation, but rather because they were already in the work-tree. 请注意,它不像git add -- "$2"那样简单git add -- "$2"因为一些工作树文件可能在工作树中, 而不是因为它们被git read-tree操作读入临时索引,而是因为它们已经在工作树上了。 (Some may be tracked and modified-but-not-yet-staged/added, and others may be untracked.) (有些可能会被跟踪和修改 - 但尚未上演/添加,而其他可能未被跟踪。)

Another, perhaps better, workaround is to use git ls-files on the temporary index, to find the files of interest. 另一种可能更好的解决方法是在临时索引上使用git ls-files来查找感兴趣的文件。 Use xargs or similar to pass these file names to a git checkout that is run without the temporary index: 使用xargs或类似方法将这些文件名传递给在没有临时索引的情况下运行的git checkout

files_file=$(mktemp)
trap "rm -f $files_file" 0 1 2 3 15
(
    export GIT_INDEX_FILE=$(mktemp) || exit 125
    rm -f $GIT_INDEX_FILE
    trap "rm -f $GIT_INDEX_FILE" 0 1 2 3 15
    git read-tree $hash
    git ls-files -z -- "$2"
) > $files_file
# if the inner shell exited with an error, exit now
case $? in 125) exit 1;; esac
xargs -0 ...

(Filling in the rest of this to make a usable Git shell command is also left as an exercise.) (在其余部分填写以生成可用的Git shell命令也留作练习。)

It would be easier to check first a find command: 首先检查一个find命令会更容易:

find . src/app/**/*.spec.ts

See if the list is correct. 查看列表是否正确。
As a workaround, you can then do: 作为解决方法,您可以执行以下操作:

find . src/app/**/*.spec.ts | xargs git checkout <sha1> -- 
# or 
find . src/app/**/*.spec.ts -exec git checkout <sha1> -- {} \; 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM