TL;博士
(你可能会误解这一点,所以最好跳到下一节;)
我想找到(以前的)提交一个补丁(提交或分阶段/非分阶段工作区更改)会改变。
TL;DR:继续阅读,但跳过“背景” ...
背景
我将在这里描述我的工作流程,以便您了解我的需要。
在我的开发分支上,我经常在许多 WIP 提交中提交小的更改。当我对我的整体更改感到满意时,我会以交互方式重新设置所有这些 WIP 提交以构成一个干净的历史记录。我将提交压缩到其他提交中并编写详细的提交消息。
在三种情况下,我想指出之前的提交应该被压缩到另一个提交中。
- 当我注意到我在以前的 WIP 提交之一中引入了一个错误时
- 当我想明确地将最近的更改合并到某个 WIP 提交中时
- 提及在错误修复的提交消息中引入错误的提交 ID
然后我进行提交,注意必须将更改(错误修复)压缩到该提交中。
历史可能如下所示:
[WIP] Fixed some bug [SQUASH with '[WIP] Made some sloppy change'] (A)
...
[WIP] Made some sloppy change (B)
...
(有时我会在 4 小时内提交超过 15 个提交)
因为我经常做这样的小补丁,所以我想到了一个自动化的解决方案。
我想知道的
当一个补丁...
- 删除和添加行(更改),我想获取已引入或最近更改该行的提交
- 添加行,我想在最近更改或引入的插入之前和之后获取行的提交
- 仅删除行,我想获取添加或最近修改这些行的提交
我如何以手动方式执行此操作
TL;DR:跳过本节并继续阅读“示例...”部分...
在准备提交(A)
时,我以这种方式搜索提交(B)
:
- 通过发出检查本地更改并记住受影响的行号
git diff
如果尚未提交更改git log -1 -p
如果更改已经提交
- 在补丁发布之前找到影响记忆行的提交
git blame HEAD -- path/to/file
如果尚未提交更改git blame HEAD~1 -- path/to/file
如果更改已经提交
之后,在这两种情况下,我都会使用这些提交 ID 获得提交消息git log <COMMIT ID>
添加和更改示例(尚未提交更改):
这是补丁 ( git diff
)
diff --git a/Gruntfile.js b/Gruntfile.js
index 9af9384..380726c 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -82,6 +82,7 @@ module.exports = function(grunt) {
less: {
build: {
options: {
+ dumpLineNumbers: "comments",
paths: ["target/"]
},
@@ -141,7 +142,7 @@ module.exports = function(grunt) {
src: {
files: 'src/**',
- tasks: ['copy:source-tree', 'copy:devel-source-tree']
+ tasks: ['copy:source-tree', 'copy:devel-source-tree', 'less']
}
}
});
这是 git blame -L82,+8 HEAD -- Gruntfile.js
和 git blame -L142,+8 HEAD -- Gruntfile.js
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 82) less: {
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 83) build: {
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 84) options: {
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 85) paths: ["target/"]
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 86) },
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 87)
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 88) files: {
f39f25c0 (Nobody 2014-05-17 16:08:20 +0200 89) "target/styles.css": "src/less/styles.less"
e2e46b59 (Nobody 2014-05-03 10:30:34 +0200 142) src: {
e2e46b59 (Nobody 2014-05-03 10:30:34 +0200 143) files: 'src/**',
e2e46b59 (Nobody 2014-05-03 10:30:34 +0200 144) tasks: ['copy:source-tree', 'copy:devel-source-tree']
f9a635c0 (Nobody 2014-04-21 16:03:38 +0200 145) }
f9a635c0 (Nobody 2014-04-21 16:03:38 +0200 146) }
f9a635c0 (Nobody 2014-04-21 16:03:38 +0200 147) });
5128dcdc (Nobody 2014-04-20 12:56:05 +0200 148)
f9a635c0 (Nobody 2014-04-21 16:03:38 +0200 149) grunt.task.loadTasks("tasks/");
这些是提交消息( git log --oneline -1 f39f25c0
和 git log --oneline -1 e2e46b59
)
f39f25c [WIP] * Changed to less (left .css file)
e2e46b5 [WIP] * Changed watch configuration
现在我知道,我必须单独提交两个大块,并提到单独的提交。
解决方案
是的,我阅读了git-blame
手册页,但我没有找到一个合适的选项来做到这一点(我确信我可能错过了一些东西)。
是的,我也试过在互联网上搜索这个。但是,嗯,我花了一页来描述它——我应该如何制定黄金谷歌搜索表达式来找到这个?
是的,正如您将在下一节中看到的,我有自己的想法。
我的方法
我将创建一个脚本来解析由git log -p
or生成的补丁git diff
。它将使用“我想知道的”部分中的规则输出补丁影响的所有行号。然后一个 bash 脚本通过检查输出来查找提交 ID git blame HEAD[~1]
,提取提交 ID。最后一步是获取提交消息。另一个步骤可能是用刚刚找到的提交消息装饰整个补丁输出(多个块和文件)。
(实际上目前我正在编写一个 Python 脚本来进行补丁解析)
替代方法
也许这可以通过从git blame -- <FILE>
and中提取提交列git blame HEAD -- <FILE>
并将两个输出输入diff
,然后grep -C <N>
ing for00000000
等来找到受影响的提交 ID 来完成。
但我认为这很脆弱,不如上述方法可靠。而且我也需要解析责备差异的补丁。
(我已经尝试过了。最难的部分是 diff 输出解析。)
尝试将其简化为一个问题。
是否有一个标准的 Git 工具,通过显示通过应用提交更改的提交,将 git blame 的功能与 git log 提供的数据相结合?
我希望我的问题足够清楚。:)
要具体。
我确定,我是。