74

我想要做的是签出一个文件或一组具有像这样的通用名称部分的文件

git checkout myBranch */myFile.md

git checkout myBranch -- */*Test*(不确定'--'部分)

代替

git checkout myBranch src/main/java/a/deep/package/structure/myFile.md

git checkout myBranch src/test/java/a/deep/package/structure/TestOne.java
git checkout myBranch src/test/java/a/deep/package/structure/TestTwo.java
git checkout myBranch src/test/java/a/deep/package/structure/resources/TestData.sql

我知道某些 git 命令有一些有限的通配符功能diffadd但没有找到checkout. 有办法吗?

编辑:我在 Linux 上使用 git 1.7.9.5。git 和 shell 命令的工作组合也是可以接受的。

4

9 回答 9

81

Git确实使用fnmatch(3)处理通配符。请参阅Git 词汇表中的pathspec条目。

但是为了确保 git 可以看到通配符,它​​们必须被转义,否则你的shell将首先扩展它们。通常,我在单引号之间使用通配符:

git checkout myBranch -- '*/myFile.md'

通配符应用于整个名称,包括目录。

正如您在文档中看到的那样,pathspec 还允许改变如何解释 pathspec 的魔术签名。例如,您可以使用icase设置不区分大小写的路径(您可以键入':(icase)*readme*'以查找所有自述文件)。

我在这里引用@bambams 的评论,以防您在 Windows 中遇到问题:

这不适用于我在 Windows 中使用 2.8.1.windows.1 并且我正在使用 cmd.exe shell 中的 Git,因此没有内置 globbing。但是,如果您处于如此糟糕的状态,有一个解决方案。结合git diff --name-onlyxargs实现您的目标:

git diff --name-only <COMMIT> -- <GLOB>... | xargs git checkout <COMMIT> 
于 2015-10-23T15:24:47.360 回答
23

Git 不处理通配符,但你的 shell 可以。

尝试这个 :

git checkout myBranch **/myFile.md

git checkout myBranch  **/*Test*

使用**,您的 shell 将从当前工作目录开始在所有子目录中查找文件。

于 2013-03-01T15:44:45.733 回答
2

电源外壳

@(gci -Recurse *test* | Resolve-Path -Relative) | %{git checkout mybranch -- $_)

gci 生成与条件 ( *test*) 匹配的所有文件的列表,然后将其通过管道传输到 Resolve-Path 以获取相对路径。最后,文件名的扁平 (@) 列表通过管道传输到 git 调用中(每个找到的文件执行一次)。

于 2019-08-08T14:46:25.880 回答
1

带有 xargs 的 Windows git bash

git difftool myBranch --name-only *.java | xargs git checkout myBranch
于 2020-03-23T05:48:14.547 回答
0

如果您有 gitignore 或未跟踪的文件,并且您想在 git checkout 中使用通配符,那么它可能会给您带来问题,解决方案可能是:

git ls-files '*/myFile.md' | tr '\n' '\0' | xargs -0 -L1 -I '$' git checkout -- '$'
于 2020-04-20T13:51:33.383 回答
0

对我来说,任务是检查几个以一种模式命名的文件:

  • ./a/b/c/FirstTest.java
  • .d/e/f/SecondTest.java
  • ./g/h/i/ThirdTest.java

我用过这个 bash 命令:

# 1. Find files named after "*Test.java" pattern.
# 2. Execute checkout command on every found file.

find . -name "*Test.java" -exec git checkout master {} \;

同样首先您可以find使用 simple 测试命令,echo它只打印给定的文本({}在我们的例子中,它将被 shell 替换为当前找到的文件名):

find . -name "*Test.java" -exec echo {} \;
于 2020-06-17T17:40:17.543 回答
0

其他答案都不适合我,但 bambams 评论有效。我把它变成了一个接受两个参数的 bash 函数。用法:

gitcheckout myBranch '*文件*'

gitcheckout()
{
    GIT_DIR=$(git rev-parse --git-dir 2>/dev/null); 
    pushd .;
    cd $GIT_DIR/../;
    git diff --name-only $1 -- $2 | xargs git checkout $1 --;
    popd;
}
于 2017-02-10T21:55:12.777 回答
0

如果您需要从提交中获取文件,无论它们是否在该提交中被更改,您可以使用以下命令:

git ls-tree --name-only -r myBranch | grep myFilePattern | xargs git checkout myBranch
于 2022-02-28T22:51:07.193 回答
0

知道 git 从第三个字符返回分支列表名称,可以切换到通过 [mask] 定义的所需分支:

BRANCH_NAME=$(git branch --list | grep [mask] | cut -c3-)
git checkout ${BRANCH_NAME}
于 2020-05-26T14:16:45.297 回答