检查由一组提交引起的差异

发布于 2024-12-11 13:32:41 字数 453 浏览 0 评论 0原文

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

例如,

$ 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 相关的提交,即提交 0ff45671ff45675ff4567

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

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

更新:我知道相关提交的列表。给定这个列表,我想获得一个更容易检查的差异。

I want to view the diff of only two commits.

For instance

$ 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

I want to view only the commits relevant to bug #1, that is, commits 0ff4567,1ff4567,5ff4567.

I don't care about the diffs of the rest of the commits.

Is there an easy way to do that?

Update: I know the list of relevant commits. Given this list, I want to get a single diff, which is easier to review.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

长发绾君心 2024-12-18 13:32:41

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

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

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

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

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

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

为了对后一个选项进行一些扩展,此脚本基于 ("super-kludgy") 示例 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

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

You can use the --grep option to git log, which only outputs commits with log messages that match a particular regular expression. In your case you could do:

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

... if you want to see the patches introduced by each of those commits, of course, you should do:

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

In the comments below, you explain that you really want one patch as output, which represents the cumulative effect of the patches introduce by those three commits. In that case, you could try one of the following:

  • Using the combinediff tool from patchutils to combine the diffs. (This may not work, depending on what the intermediate commits have changed.)
  • Create a temporary new branch, and use interactive rebase (possibly with a cunningly constructed command in the GIT_EDITOR environment variable) to reorder and squash the commits.

To expand a bit on the latter option, this script is based on a ("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}^

... which you might invoke as:

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

... which will then create the branch tmp-branch, rebase back to the parent of the first commit that matches bug #1, only picking commits that match bug #1 and squash all but the first one. (You may have to fix some conflicts, and provide a commit message for the squashed commits.) If that succeeds, then you can just do:

git show

... to see the combined patch. I don't seriously recommend anyone use this script, but it's a fun and hacky way of doing what you want, I think :)

吃颗糖壮壮胆 2024-12-18 13:32:41

您可以使用 git log --grep=fix1 (如 Git 参考 所示) )以便隔离相关提交,然后对每个提交执行 git show

请参阅“git commit 与其父级的 diff 的简写?”。

将这些补丁合并为一个差异并不简单,正如 Jefromi 在“带有作者过滤器的 git diff"。

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

在您的情况下,可能的(相当麻烦)的解决方案应该类似于“提取相关更改代码审查”:

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

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

You could use git log --grep=fix1 (as show in Git reference) in order to isolate the relevant commit, and then perform a git show <commit> for each commit.

See "Shorthand for diff of git commit with its parent?".

Combining those patches as a single diff isn't trivial, as Jefromi explains in "git diff with author filter".

The problem here is that you can't do this in the general case.
Suppose Alice changes a particular file, then Bob changes it - including parts that Alice changed - and finally Alice changes it again.
How do you combine Alice's two diffs into a single diff?
If you take them as two patches, the second simply won't apply without Bob's patch being applied first!
But you also can't simply diff the final state against the original, because that will include Bob's changes.

In your case, a possible (quite cumbersome) solution should be similar to "Extract relevant changes for code review":

Check out a working copy at a revision just before the first changes. Then merge all related commits into your working copy.
Now you have a working copy which differs from its base just by the relevant changes. You can review this directly, or create a patch from it for review.

So: a dedicated fix1_review branch is possible, but that remains a semi-automated setup (as you have to solve possible conflicts).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文