【问题标题】:reviewing diff caused by a set of commits审查由一组提交引起的差异
【发布时间】:2011-12-13 11:40:48
【问题描述】:

我只想查看两个提交的差异。

例如

$ git log --oneline
0ff4567 fix bug #1, now really really really
1ff4567 fix bug #1 really
2ff4567 fix bug #2
3ff4567 fix bug #3
4234567 refactor code
5ff4567 fix bug #1
6234567 fix bug #4

我只想查看与 bug #1 相关的提交,即提交 0ff4567,1ff4567,5ff4567

我不关心其余提交的差异。

有没有简单的方法可以做到这一点?

更新:我知道相关提交的列表。鉴于此列表,我想获得一个更易于查看的差异。

【问题讨论】:

  • 重新排序提交是否可以接受?如果它们是你的,而你还没有推动它们,你甚至可以压扁它们。见stackoverflow.com/questions/2740537/reordering-of-commits
  • 不,不。他们已经被推了。否则我不会有问题。
  • 然后我会git clone repo temp_repo 并在临时副本中播放。
  • @Johnsyweb: 没必要 - 你可以创建一个新的分支来变基。
  • @MarkLongair:确实如此,但这是一种既便宜又简单的游戏方式,没有任何风险。

标签: git


【解决方案1】:

您可以将--grep 选项用于git log,它只输出带有与特定正则表达式匹配的日志消息的提交。在你的情况下,你可以这样做:

git log --oneline --grep='bug #1'

...如果您想查看每个提交引入的补丁,当然,您应该这样做:

git log -p --grep='bug #1'

在下面的 cmets 中,您解释说您确实想要一个补丁作为输出,它表示这三个提交引入的补丁的累积效果。在这种情况下,您可以尝试以下方法之一:

  • 使用来自 patchutils 的 combinediff 工具来组合差异。 (这可能不起作用,具体取决于中间提交的更改。)
  • 创建一个临时的新分支,并使用交互式 rebase(可能在 GIT_EDITOR 环境变量中使用巧妙构造的命令)来重新排序和压缩提交。

为了扩展后一个选项,此脚本基于("super-kludgy") example by Jefromi

#!/bin/sh

set -e

if [ $# -ne 2 ]
then
    echo "Usage: $0 REGEX TEMPORARY_BRANCH_NAME"
    exit 1
fi

REGEX="$1"
BRANCH_NAME="$2"

git checkout -b "$BRANCH_NAME"

FIRST_COMMIT=$(git log --grep="$REGEX" --pretty=format:%H | tail -1)
if [ -z "$FIRST_COMMIT" ]
then
    echo "No commits matched '$REGEX'"
    exit 2
fi

export GIT_EDITOR="f() { if [ \"\$(basename \$1)\" = \"git-rebase-todo\" ]; then sed -i -n '/${REGEX}/p' \$1 && sed -i '2,\$s/pick/squash/' \$1; else vim $1; fi }; f"
git rebase -i ${FIRST_COMMIT}^

...你可以调用它:

squash-matching-commits 'bug #1' tmp-branch

... 然后将创建分支tmp-branch,重新定位到匹配bug #1 的第一个提交的父级,只选择匹配bug #1 的提交并压缩除第一个之外的所有提交。 (您可能需要修复一些冲突,并为压缩的提交提供提交消息。)如果成功,那么您可以这样做:

git show

... 查看组合补丁。我不认真推荐任何人使用这个脚本,但我认为这是一种有趣且古怪的方式来做你想做的事:)

【讨论】:

  • 我不想看到补丁列表。我想看一个补丁。
  • 我忘记了-p 选项。 +1
  • 哦,好吧,我添加了另外两个可能的选项。我认为,反对票特别严厉,因为这个问题并没有明确表明 OP 甚至知道--grep 选项。
【解决方案2】:

您可以使用git log --grep=fix1(如Git reference 中所示)来隔离相关提交,然后为每个提交执行git show <commit>

见“Shorthand for diff of git commit with its parent?”。

正如Jefromi 在“git diff with author filter”中解释的那样,将这些补丁组合成一个单独的差异并非易事。

这里的问题是在一般情况下您不能这样做。
假设 Alice 更改了一个特定文件,然后 Bob 更改了它 - 包括 Alice 更改的部分 - 最后 Alice 再次更改了它。
如何将 Alice 的两个 diff 组合成一个 diff?
如果您将它们视为两个补丁,那么如果没有先应用 Bob 的补丁,第二个就不会应用!
但是您也不能简单地将最终状态与原始状态进行比较,因为这将包括 Bob 的更改。

在你的情况下,一个可能的(相当麻烦的)解决方案应该类似于“Extract relevant changes for code review”:

在第一次更改之前查看修订版的工作副本。然后将所有相关的提交合并到您的工作副本中。
现在您有了一个工作副本,它与其基础的不同之处仅在于相关更改。您可以直接查看此内容,或从中创建补丁以供查看。

所以:一个专用的fix1_review 分支是可能的,但这仍然是一个半自动设置(因为您必须解决可能的冲突)。

【讨论】:

  • @Elazar 已经确定了提交。这是一个组合的差异/补丁,这是必需的。
  • @Johnsyweb:我刚刚在最近编辑的答案中解决了这个问题。
  • 我在编辑后阅读了您的答案,但似乎仍然是错误的。我需要使用meld 审查所有内容,并考虑是否存在问题。 greping 无关紧要。我有我感兴趣的提交的确切列表。
  • @Elzar:但你不能总是将这些差异组合在一起,除非它们是连续提交。
  • @ElazarLeibovich:我添加了我能找到的最强大的解决方案:用于审查所有 fix1 更改的专用分支。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-08-02
  • 2021-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多