如何使用通配符搜索来执行git diff?

68de4m5k  于 2022-12-17  发布在  Git
关注(0)|答案(2)|浏览(159)

当我执行git status时,我会得到这样的结果:

modified   a/mega/super/duper/long/path/to/the/file/foo.php
modified   a/mega/super/duper/long/path/to/the/file/another/folder/bar.php
modified   a/mega/super/duper/long/path/to/the/file/someotherfolder/blahblah.php

如果我想看看bar.php文件(第2行)有什么变化,我该怎么做?
我希望能做这样的事情:

git diff */bar.php
git diff bar.php

而且那个小东西还能用Tab键完成我的游戏或者读我的想法。

想法一:写出来:

这是相当广泛的不得不写:

git diff a/mega/super/duper/long/path/to/the/file/another/folder/bar.php

方法二:使用鼠标+复制/粘贴

我可以使用鼠标和复制粘贴,但这似乎也是一个糟糕的解决方案。把手指从键盘上移开通常不是解决方案。而且我必须做很多事情。

想法3:Git添加补丁

通过运行git add -p,我自动进入了交互模式,能够执行a bunch of stuff,但这并不是我想要的。
想法4:使用sed
我发现了这样一个问题:git diff just the first file,这意味着:

git diff $(git diff --name-only | sed -n '1 p')

然后我可以设置一个Alfred-snippet或者bash-script来打印它,然后我可以将1更改为我想要查看的文件号。
这就快好了。

想法5:将nth文件的文件名复制到剪贴板的Bash脚本

另一种方法是创建一个bashscript,将nth-文件复制到剪贴板,然后我可以用两个swift命令来完成,如下所示:

./copy-file-name-for-first-file-in-git-status.sh     # Named to make easy to understand.
git diff [PASTE]

这实际上也解决了下面的奖金问题。

附加问题-git addgit log的问题相同

如果我不想使用git add .,但是想在嵌套的文件夹中单独添加文件,也会出现同样的问题,然后我还必须为每个文件输入完整的路径。

xqkwcwgp

xqkwcwgp1#

为了方便使用,使用Git别名而不是外部函数如何?你可以把它放在全局配置中,这样你就不必费力记住新函数或把它添加到路径中。
正如你所看到的,它将运行diff,只使用一个(可能)非常短的子字符串来识别文件。这是一个正则表达式搜索,当你指定的正则表达式不匹配文件或匹配多个文件时,它将优雅地处理这些情况。
把这个添加到你的git配置中:

[alias]
        diffr = "!a() { myfile=$(git status | awk '/modified:/ {print $2}' |grep "$1") ; cnt=$(git status |awk '/modified:/ {print $2}'|grep "$1" |wc -l) ;if [ $cnt -eq 1 ] ; then git diff $myfile;else printf '%s Matched %s files\n' $1 $cnt;fi; if ! [ $cnt -eq 0 ] ; then git status |grep "$1"; fi; }; a"

使用git diffr "<regex>"运行它
以下是测试报告库的状态:

me@mypc MINGW64 /c/repos/aliastest (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   mega/super/duper/long/path/to/the/file/another/folder/bar.php
        modified:   mega/super/duper/long/path/to/the/file/foo.php
        modified:   mega/super/duper/long/path/to/the/file/someotherfolder/blahblah.php

no changes added to commit (use "git add" and/or "git commit -a")

下面是一个成功的diff,它的文件名中包含'foo'(当它是唯一匹配的文件时):

me@mypc MINGW64 /c/repos/aliastest (master)
$ git diffr foo
warning: LF will be replaced by CRLF in mega/super/duper/long/path/to/the/file/foo.php.
The file will have its original line endings in your working directory
diff --git a/mega/super/duper/long/path/to/the/file/foo.php b/mega/super/duper/long/path/to/the/file/foo.php
index 90be1f3..294186e 100644
--- a/mega/super/duper/long/path/to/the/file/foo.php
+++ b/mega/super/duper/long/path/to/the/file/foo.php
@@ -1 +1 @@
-before
+after

下面是它如何处理正则表达式匹配多个文件的无效情况:

me@mypc MINGW64 /c/repos/aliastest (master)
$ git diffr "folder/b[al]"
folder/b[al] Matched 2 files
        modified:   mega/super/duper/long/path/to/the/file/another/folder/bar.php
        modified:   mega/super/duper/long/path/to/the/file/someotherfolder/blahblah.php

下面是处理一个不匹配任何文件的正则表达式:

me@mypc MINGW64 /c/repos/aliastest (master)
$ git diffr "sirnotappearinginthisfilm"
sirnotappearinginthisfilm Matched 0 files

除了所有的转义之外,它只是一个普通的Bash函数,所以你可以随意编辑它。你可以调用一个单独的可执行文件来代替Bash函数,但是这样你就有了外部依赖。对脚本的小调整也可以满足你的git add请求。如果我有时间写它,我会在这里发布它。与git log类似的功能似乎完全不同,因为您可能获得的结果可能是巨大的。
我也有过同样的愿望,想把我的手放在键盘上,也有过同样的问题,但直到现在我还没有真正想到如何解决这个问题。从现在开始,无论其他人是否使用这个解决方案,我都会使用这个解决方案,所以谢谢你的建议。

8gsdolmq

8gsdolmq2#

这对我很有效:

git diff **/bar.php

您可能需要先运行shopt -s globstar,但我没有在我的系统上运行。

相关问题