如何在Git中获取分支上的更改

290

如何获得自当前分支创建以来在一个分支上的提交记录? 我目前的解决方案是:

git log $(git merge-base HEAD branch)..branch

git-diff 的文档表明 git diff A...B 等同于 git diff $(git-merge-base A B) B。另一方面,git-rev-parse 的文档表明 r1...r2 被定义为 r1 r2 --not $(git merge-base --all r1 r2)

为什么它们不同?请注意,git diff HEAD...branch 给出了我想要的差异,但是相应的 git log 命令给出了更多的结果。

假设有这样的图片:

         x---y---z---branch
        /
---a---b---c---d---e---HEAD

我想得到包含提交 x、y、z 的日志记录。

  • git diff HEAD...branch 给出了这些提交
  • 然而,git log HEAD...branch 给出了 x、y、z、c、d、e。


从我所看到的情况来看,你在使用“git log”时并不正确。我已经在下面添加了我的答案。 - Debajit
10个回答

202
在修订列表的上下文中,A...B 是由 git-rev-parse 定义的。git-log 取一个修订列表。 git-diff 不取修订列表 - 它取一个或两个修订版本,并将 A...B 语法定义为在 git-diff manpage 中的定义。如果 git-diff 没有明确定义 A...B,则该语法将是无效的。请注意,git-rev-parse manpage 在“Specifying Ranges”部分描述了 A...B,并且该部分中的所有内容仅在需要修订范围时有效(即当需要修订列表时)。
要获取仅包含 x、y 和 z 的日志,请尝试 git log HEAD..branch(两个点而不是三个)。这与 git log branch --not HEAD 相同,并意味着所有在 branch 上的提交但不在 HEAD 上的提交。

34
哇,这真是令人困惑。原来使用"git diff HEAD..branch"会显示所有的提交记录(x, y, z, c, d, e),但是"git log HEAD..branch"却完全符合我的需求,只显示了x、y、z!这完全是和“...”相反的结果。 - Greg Hewgill
23
git diff HEAD..branchgit diff HEAD branch 完全相同。这里需要记住的关键是,log 命令需要一系列/范围的版本,而 diff 命令则不需要。这就是它们处理参数的方式不同的原因。 - Lily Ballard
4
似乎 git diff HEAD...branch (三个点)对应于 git log HEAD..branch 的输出。 - jchook
热门提示:如果您想查看自创建以来当前分支中的所有差异,请使用 git difftool --dir-diff main(或 master)。所有所做的更改都将在定义的可视化差异和合并工具中显示。 - Eduardo Lucio

74
git cherry branch [newbranch]

这正好做到了你在 master 分支下所要求的内容。

我也非常喜欢:

git diff --name-status branch [newbranch]

虽然不完全符合您的问题,但在相同的上下文中仍然非常有用。


8
'git cherry' 命令会输出一系列提交记录的 ID。我能否将它们转换成一个单一的 diff,将每个提交记录中所有的更改合并在一起呢? - Jonathan Hartley
2
@JonathanHartley 取出提交 ID 的第一行和最后一行,并将它们传递到 gif-diff: git diff x..z,或者对于我的示例,它是 git diff 13bc4d..8eda3a - towi
4
很难理解在你的命令中应该替换哪个代码,即 branch 或 newbranch 中的哪一个是关键字,哪一个应该用自定义分支名称来替换。 - pal4life

39
您想查看的是外发提交列表。您可以使用以下方法实现。
git log master..branchName 
git log master..branchName --oneline

我假设"branchName"是作为"master"的一个跟踪分支创建的。

同样,要查看传入的更改,您可以使用:

git log branchName..master

1
@A-B-B,如果省略branchName,则默认为“head”,这在上面的示例中实际上就是branchName。 - Debajit

25

这与我在Preview a Git push中发布的答案类似。

把以下函数添加到您的Bash配置文件中:

  • gbout - 显示Git分支差异(出站)
  • gbin - 显示Git分支差异(入站)

您可以像这样使用它:

  • 如果在主分支上:gbin branch1 <-- 这将显示branch1中存在但master中不存在的内容
  • 如果在主分支上:gbout branch1 <-- 这将显示master中存在但branch1中不存在的内容

这适用于任何分支。

function parse_git_branch {
  git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/'
}

function gbin {
    echo branch \($1\) has these commits and \($(parse_git_branch)\) does not
    git log ..$1 --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}

function gbout {
    echo branch \($(parse_git_branch)\) has these commits and \($1\) does not
    git log $1.. --no-merges --format='%h | Author:%an | Date:%ad | %s' --date=local
}

25

当已经在相关的分支中时,请使用

git diff master...

这个功能结合了几个特点:

  • 非常简短
  • 显示实际变化
  • 允许主分支向前移动

1
或者明确指定分支:git diff <branch1>...<branch2> 将显示由 branch2 引入的更改。 - Alex
这些评论已经过时,需要更新回答。 - Michael Durrant

10

在那里加上一个 -p 以查看一些文件更改

git log -p master..branch

创建一些别名:

alias gbc="git branch --no-color | sed -e '/^[^\*]/d' -e 's/* \\(.*\\)/\1/'"

alias gbl='git log -p master..\`gbc\`'

查看分支的独有提交记录:

gbl

7

查看自从分支出master后的当前分支日志:

git log master...

如果你目前在master分支上,查看其他分支自从它分出master后的日志:

git log ...other-branch


4
git log --cherry-mark --oneline from_branch...to_branch

(3个点) 但有时会显示'+'而不是'='。

三个点在分支上显示第一次提交两次,而两个点则不会。 - TJ Biddle

2

我发现

git diff <branch_with_changes> <branch_to_compare_to>

更有用的是,你不仅可以获得提交信息,还可以获得整个差异。如果您已经在要查看更改的分支上,并且(例如)想要查看与主分支的变更,您可以使用:

git diff HEAD master

0

在 Git 2.30(2021 年第一季度)中,“git diff A...B(man)” 学会了 “git diff --merge-base A B(man)”,这是一个更长的简写,表示相同的意思。

因此,您可以使用 git diff --merge-base <branch> HEAD 来执行此操作。这应该等同于 git diff <branch>...HEAD,但不需要在差异中使用范围符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接