【发布时间】:2014-05-24 13:51:57
【问题描述】:
TL;DR
(你可能会误解这一点,所以最好跳到下一节;)
我想找出(以前)提交的补丁(提交或暂存/未暂存的工作区更改)会发生变化。
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如果更改已经提交
-
之后,在这两种情况下,我都会使用 git log <COMMIT ID> 获得这些提交 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 手册页,但我没有找到一个合适的选项来执行此操作(我确信我可能遗漏了一些东西)。
是的,我也试过在互联网上搜索这个。但是,嗯,我花了一页来描述它 - 我应该如何制定黄金 Google 搜索表达式来找到它?
是的,正如您将在下一节中看到的,我有自己的想法。
我的方法
我将创建一个脚本来解析git log -p 或git diff 生成的补丁。
它将使用 “我想知道的” 部分中的规则输出补丁影响的所有行号。
然后 bash 脚本通过检查 git blame HEAD[~1] 输出来查找提交 ID,提取提交 ID。
最后一步是获取提交消息。
另一个步骤可能是,用刚刚找到的提交消息装饰整个补丁输出(多个块和文件)。
(其实我现在正在写一个 Python 脚本来做补丁解析)
替代方法
也许这可以通过从git blame -- <FILE>和git blame HEAD -- <FILE>中提取提交列并将两个输出输入diff,然后grep -C <N>ing for 00000000等来找到受影响的提交ID .
但我认为这很脆弱,不如上述方法可靠。而且我也需要解析责任差异的补丁。
(我已经试过了。最难的部分是diff输出解析。)
尽量减少到一个问题。
是否有一个标准的 Git 工具,通过显示应用提交而更改的提交,将 git blame 的功能与 git log 提供的数据相结合?
我希望我的问题足够清楚。 :)
要具体。
我确定,我是。
【问题讨论】:
-
请注意,我已经创建了一个很好的 Python 脚本,它可以解析补丁以找到我将手动查找的行。但它仍然需要一些努力(单元测试,也许是一些控制开关,干净的 CLI),我真的更喜欢一些开箱即用的可能带有一些单线管道的魔术来使用开箱即用的工具获取信息。
标签: git diff history patch blame