如何找到在文件重命名和重新排序之间添加了特定Gradle构建依赖关系的Git提交



我在一个多项目Gradle项目中工作,该项目使用Spring Boot和Java实现,并使用Git进行版本控制。其中一个子项目依赖于一个特定的库(我们称之为com.example:mylib),该库在该特定子项目的build.gradle文件中声明。这个库是不久前添加的,我想找到添加它的提交,这样我就可以了解添加它的原因,以及是否仍然需要它。在我的代码中没有该库的导入,但由于Spring Boot的自动配置在一定程度上是基于类路径上的库来工作的,因此我的代码内没有直接使用不足以确定是否使用或如何使用该库。

更糟糕的是,自项目开始以来,已经发生了各种项目重组:子项目被多次重命名、移动到子项目等。构建文件本身也进行了重组和重新排序。此外,Gradle文件已经从Groovy(build.gradle)切换到Kotlin(build.gradle.kts),然后又切换回来。

build.gradle

// ...
dependencies {
// ...
compile 'com.example:mylib'
// ...
}
// ...

build.gradle.kts

// ...
dependencies {
// ...
implementation("com.example:mylib:1.0.5")
// ...
}
// ...

我知道一些手动的方法,我可以追溯并找到变化。例如,我可以使用git blame并通过对行的更改返回,在重命名和重组发生时手动切换文件。但是,当发生了很多变化时,这些方法可能会有点耗时和乏味。

如何快速轻松地找到添加库的提交?

git bisect可用于以自动化方式快速查找更改。

假设develop具有库依赖项,并且abc123是添加库依赖项之前的提交,下面将找到添加依赖项的提交:

git bisect start
git bisect new develop
git bisect old abc123
echo "! grep -rI --include *.gradle* mylib ." > /tmp/bisect.sh 
chmod u+x /tmp/bisect.sh 
git bisect run /tmp/bisect.sh
git bisect reset

CCD_ 9开始新的平分会话。然后,我们需要识别至少一个旧的和一个新的提交——也就是说,一个在更改之前的提交("旧的")和一个在变更之后的提交("新的")。CCD_ 10指定CCD_;新的";commit和CCD_;abc123";作为";旧的";犯罪(请注意,标准术语是坏的/好的,而不是新的/旧的,但由于这更多的是一种改变而不是破坏,我选择使用替代术语"旧的"one_answers"新的"来代替标准术语。)

Git将采用二进制搜索算法,大约在旧&新的提交。

输出:

Bisecting: 818 revisions left to test after this (roughly 10 steps)
[1234567890abcdef1234567890abcdef12345678] Committed some stuff

此时,您可以手动将此提交标识为旧的或新的(git bisect old/git bisect new),Git二进制文件会搜索到引入更改的提交。然而,我们可以通过让Git使用git bisect run <scriptname.sh>用脚本检查每个潜在的提交来自动化这个过程。如果脚本返回退出代码0,则将其标识为"0";旧的";;如果它存在的代码在1和127之间(而不是125);新的";。

对于这种情况,我们可以使用命令grep -rI --include *.gradle* mylib .。这使用grep递归地找到与包含术语"0"的模式CCD_ 17匹配的任何非二进制文件;mylib";。这将匹配build.gradlebuild.gradle.kts,但跳过许多我们不关心的其他文件(从而加快了过程)。

但是,grep命令会返回我们想要的相反的退出代码。它在匹配时返回一个成功的("旧")响应,但我们希望它是一个失败的("新")响应。可以使用!保留字:! grep -rI --include *.gradle* mylib .

该命令存储在/tmp/bisect.sh脚本中,并可执行:

echo "! grep -rI --include *.gradle* mylib ." > /tmp/bisect.sh 
chmod u+x /tmp/bisect.sh 

现在我们有了脚本,我们将其传递给git bisect run以获得添加依赖项的提交:

git bisect run /tmp/bisect.sh

输出:

abcdefg1234567890abcdefg1234567890abcdef is the first new commit
commit abcdefg1234567890abcdefg1234567890abcdef
Author: John Doe <john.doe@example.com>
Date:   Tue May 26 17:37:25 2020 -0400
adding a new library for fun and profit

1. add the library
2. ???
3. profit
subproject1/build.gradle                           |   6 +-
.../nested/subpackage/MyAwesomeClass.java          |  37 -------
.../nested/subpackage/LessAwesomeClass.java        | 118 +++++++++++++++++++++
.../nested/BoilerplateJunk.java                    |  32 ++++--
subproject1/src/main/resources/application.yaml    |  12 +++
.../another/subpackage/Whatever.java               |  28 +++++
6 files changed, 189 insertions(+), 44 deletions(-)

最后,我们调用git bisect reset来结束平分会话,并更改回开始平分会话之前的分支。

git log -S仅显示修订—给定文本字符串出现的次数。列表中的最后一项将是首次添加文本字符串的修订。在库的情况下,这将是它第一次添加的依赖项(假设构建文件是依赖项出现过的唯一位置)。

git log -S myLib

-S<string>

查找更改文件中指定字符串出现次数(即添加/删除)的差异。供编剧使用。

当您正在寻找一个精确的代码块(如结构),并想知道该块自第一次出现以来的历史时,它很有用:迭代地使用该功能将预映像中有趣的块反馈回-S,并继续进行,直到获得该块的第一个版本。

二进制文件也会被搜索。

如果只想输出第一次添加依赖项的修订,可以使用一些命令管道来完成。一种方法是:

git log -S mylib --pretty=format:"%H" | tail -1 | xargs git log -1 --stat

输出:

commit abcdefg1234567890abcdefg1234567890abcdef
Author: John Doe <john.doe@example.com>
Date:   Tue May 26 17:37:25 2020 -0400
adding a new library for fun and profit

1. add the library
2. ???
3. profit
subproject1/build.gradle                           |   6 +-
.../nested/subpackage/MyAwesomeClass.java          |  37 -------
.../nested/subpackage/LessAwesomeClass.java        | 118 +++++++++++++++++++++
.../nested/BoilerplateJunk.java                    |  32 ++++--
subproject1/src/main/resources/application.yaml    |  12 +++
.../another/subpackage/Whatever.java               |  28 +++++
6 files changed, 189 insertions(+), 44 deletions(-)

相关内容

  • 没有找到相关文章

最新更新