git 如何查看一个分支中的哪些提交不在另一个分支中?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7566416/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to see which commits in one branch aren't in the other?
提问by Sascha Effert
I have two branches devel
and next
. In devel I have a more or less huge amount of commits. Some of the commits are cherry picked in next
. Also I added some commits to next which are merged to devel
.
我有两个分支devel
和next
. 在开发中,我或多或少有大量的提交。一些提交是在next
. 我还向 next 添加了一些提交,这些提交合并到devel
.
Now I would like to see what is missing in next
, so I can test the changes in detail before bringing them to next
. My question is now, how can I see which commits are in devel
but not in next?
现在我想看看缺少什么next
,所以我可以在将它们带到next
. 我现在的问题是,我怎样才能看到哪些提交在devel
但不在下一个?
回答by Mark Longair
The little-used command git cherry
shows you the commits which haven't yet been cherry-picked. The documentation for git cherry
is here, but, in short, you should just be able to do:
很少使用的命令git cherry
向您显示尚未被挑选出来的提交。对于文档git cherry
是在这里,但是,总之,你应该能够做到:
git checkout devel
git cherry next
... and see output a bit like this:
...并看到输出有点像这样:
+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9
The commits that begin with +
will be the ones that you haven't yetcherry-picked into next
. In this case, I'd only cherry-picked one commit so far. You might want to add the -v
parameter to the git cherry
command, so that it also outputs the subject line of each commit.
以开头的提交+
将是您尚未挑选的提交next
。在这种情况下,到目前为止我只挑选了一个提交。您可能希望将-v
参数添加到git cherry
命令中,以便它还输出每个提交的主题行。
回答by sehe
Also, you can use
此外,您可以使用
git log --left-right --graph --cherry-pick --oneline devel...next
to get a nice list of actualdifferent commits not shared between the branches.
获得一个很好的列表,列出了分支之间未共享的实际不同提交。
The operative word is --cherry-pick
操作词是 --cherry-pick
--cherry-pick
Omit any commit that introduces the same change as another commit on the "other side" when the set of commits are limited with symmetric difference. For example, if you have two branches, A and B, a usual way to list all commits on only one side of them is with --left-right, like the example above in the description of that option. It however shows the commits that were cherry-picked from the other branch (for example, "3rd on b" may be cherry-picked from branch A). With this option, such pairs of commits are excluded from the output.
--cherry-pick
当提交集受限于对称差异时,省略任何引入与“另一端”的另一个提交相同的更改的提交。例如,如果您有两个分支,A 和 B,通常只列出其中一侧的所有提交的方法是使用 --left-right,就像上面该选项描述中的示例一样。然而,它显示了从另一个分支中挑选出来的提交(例如,“b 上的第三个”可能是从分支 A 中挑选出来的)。使用此选项,此类提交对将从输出中排除。
UpdateAs mentioned in a comment, recent versions of git added --cherry-mark
:
更新正如评论中提到的,最近版本的 git 添加了--cherry-mark
:
--cherry-mark
Like --cherry-pick (see below) but mark equivalent commits with = rather than omitting them, and inequivalent ones with +.
--cherry-mark
像--cherry-pick(见下文),但用= 标记等效提交而不是省略它们,用+ 标记不等效的提交。
回答by Bryan Buckley
You might could try doing git log subsets:
你可以尝试做 git log 子集:
git log --oneline devel ^next
回答by justingordon
How about
怎么样
git log next..devel
Result is similar to Byran's answer (different order of commits) but both of our answers will produce commits that are different between the branches, rather just showing what's in one branch and not in the other.
结果类似于 Byran 的答案(不同的提交顺序),但我们的两个答案都会产生分支之间不同的提交,而只是显示一个分支中的内容而不是另一个分支中的内容。
回答by Mihai
To get the list of commits that were not integrated into the release branch (next) you may use:
要获取未集成到发布分支中的提交列表(下一个),您可以使用:
git rev-list --reverse --pretty="TO_TEST %h (<%ae>) %s" --cherry-pick --right-only origin/release_branch...origin/development_branch | grep "^TO_TEST " > NotIntegratedYet.txt
Check git-rev-listfor more info.
检查git-rev-list以获取更多信息。
回答by Gabriel Staples
@Mark Longair nailed it in his answer here, but I'd like to add some additional insight.
@Mark Longair 在他的回答中指出了这一点,但我想补充一些额外的见解。
Related, and answering the question of how to break up a large Pull Request (PR), especially when squashing your commits is impractical due to one or more merges of master into your feature_branch
相关,并回答有关如何分解大型拉取请求 (PR) 的问题,尤其是当由于一个或多个 master 合并到您的 feature_branch 而压缩您的提交是不切实际的时
My situation:
I made a big feature_branch
with 30 commits and opened a Pull Request (PR) on GitHub to merge it into master
. Branch master
changed a ton underneath me, and received 200 commits my feature_branch
didn't have. To resolve conflicts I did git checkout feature_branch
and git merge master
to merge master
's changes into my feature_branch
. I chose to merge
rather than rebase
onto latest master so I would have to resolve conflicts only one single time instead of potentially 30 times (once for each of my commits). I didn't want to squash my 30 commits into 1 first and then rebase onto the latest master
because that might wipe away GitHub review comment history in the PR. So, I merged master into my feature branch and resolved conflicts 1 single time. All was well. My PR, however, was too big for my colleagues to review. I needed to split it up. I went to squash my 30 commits and OH NO! WHERE ARE THEY? THEY ARE ALL INTERMINGLED WITH master
's 200 recent commits now because I merged master
into my feature_branch
! WHAT DO I DO?
我的情况:
我做了feature_branch
30 次提交,并在 GitHub 上打开了一个拉取请求 (PR) 以将其合并到master
. Branchmaster
在我下面改变了很多,并收到了 200 个我feature_branch
没有的提交。化解矛盾我也git checkout feature_branch
和git merge master
合并master
的变成我的feature_branch
。我选择了merge
而不是rebase
最新的 master,所以我只需要解决一次冲突,而不是可能的 30 次(每次提交一次)。我不想先把我的 30 个提交压缩成 1 个,然后再重新调整到最新的master
因为这可能会清除 PR 中的 GitHub 评论评论历史。因此,我将 master 合并到我的功能分支并解决了 1 次冲突。一切都好。然而,我的 PR 太大了,我的同事们无法。我需要把它分开。我去压缩我的 30 次提交,哦不!他们在哪里?它们现在都与master
200 个最近的提交混合在一起,因为我合并master
到了我的feature_branch
! 我该怎么办?
git cherry
usage in case you want to try to git cherry-pick
individual commits:
git cherry
如果您想尝试git cherry-pick
单独提交,请使用:
git cherry
to the rescue (sort of)!
git cherry
拯救(有点)!
To see all the commits that are in feature_branch
but NOT in master
I can do:
要查看所有在feature_branch
但不在的提交,master
我可以执行以下操作:
git checkout feature_branch
git cherry master
OR, I can check commits from ANY branch withOUT ensuring I'm on feature_branch
first by doing git cherry [upstream_branch] [feature_branch]
, like this. Again, this checks to see which commits ARE in feature_branch
but are NOT in upstream_branch
(master
in this case):
或者,我可以检查来自任何分支的提交,而无需确保我feature_branch
首先通过执行git cherry [upstream_branch] [feature_branch]
,像这样。同样,这会检查哪些提交在feature_branch
但不在upstream_branch
(master
在这种情况下):
git cherry master feature_branch
Adding -v
also shows the commit message subject lines:
添加-v
还显示提交消息主题行:
git cherry -v master
Piping to "word count" "-lines" (wc -l
) counts how many commits there are:
管道到“字数”“-lines”(wc -l
)计算有多少提交:
git cherry master | wc -l
You can compare this count against the commit number shown in your GithHub PR to feel better about knowing git cherry
really is working. You can also compare the git hashes one by one and see they match between git cherry
and GitHub. Note that git cherry
will NOT count any merge commits where you merged master
into feature_branch
, but GitHub WILL. So if you see a small discrepancy in the count, search the GitHub PR commit page for the word "merge" and you'll probably see that's the culprit which is not showing up in git cherry
. Ex: a commit titled "Merge branch 'master' into feature_branch"will show up in the GitHub PR but not when you run git cherry master feature_branch
. This is fine and expected.
您可以将此计数与 GithHub PR 中显示的提交数量进行比较,以便更好地了解git cherry
确实有效。您还可以一一比较 git 哈希,看看它们在git cherry
GitHub之间是否匹配。请注意,git cherry
不会计算您合并master
到 中的任何合并提交feature_branch
,但 GitHub 会。因此,如果您看到计数中的小差异,请在 GitHub PR 提交页面中搜索“合并”一词,您可能会发现这是没有出现在git cherry
. 例如:标题为“Merge branch 'master' into feature_branch”的提交将显示在 GitHub PR 中,但不会在您运行git cherry master feature_branch
. 这很好,也符合预期。
So, now I have a means of finding out which diffs I may want to cherry-pick onto a fresh feature branch to split up this diff: I can use git cherry master feature_branch
locally, or look at the commits in the GitHub PR.
所以,现在我有办法找出哪些差异我可能想要挑选到一个新的功能分支上来拆分这个差异:我可以git cherry master feature_branch
在本地使用,或者查看 GitHub PR 中的提交。
How squashing could help--if only we could squash:
挤压有什么帮助——如果我们能挤压:
An alternative, however, to split up my big diff is to squash all 30 of my commits into one, patch that onto a new feature branch, soft reset the patch commit, then use git gui
to add pieces file by file, chunk by chunk, or line by line.Once I get one sub-feature, I can commit what I've added then check out a new branch, add some more, commit, check out a new branch, etc, until I have my big feature broken out into several sub-features. The problem is that my 30 commits are intermingled with the other 200 commits from other people due to my git merge master
into my feature_branch
, so rebasing is therefore impractical, as I'd have to sift through 230 commits to re-order and squash my 30 commits.
然而,另一种拆分我的大差异的方法是将我的所有 30 个提交压缩为一个,将其修补到新的功能分支上,软重置补丁提交,然后使用git gui
逐个文件、逐块添加片段,或逐行。一旦我获得一个子功能,我就可以提交我添加的内容,然后检查一个新分支,添加更多,提交,检查一个新分支等,直到我将我的大功能分解为几个子功能. 问题是,我的30个提交与其他人等200个提交混由于我git merge master
到我feature_branch
,所以垫底因此不切实际的,因为我有过230个提交筛选一下以重新排序和壁球我30次的提交。
How to use a patch file as a much easier replacement for squashing:
如何使用补丁文件来更轻松地替代压缩:
A work-around is to simply obtain a patch filecontaining a "squash-equivalent" of all 30 of my commits, patch it onto a new fork of master
(a new sub-feature-branch), and work from there, as follows:
一种解决方法是简单地获取一个补丁文件,其中包含我所有 30 个提交的“壁球等效”,将其修补到master
(一个新的子功能分支)的新分支上,然后从那里开始工作,如下所示:
git checkout feature_branch
# ensure I have the latest changes from master merged into feature_branch
git merge master
# Obtain a patch file, which is the equivalent of a squash of my 30 commits into 1 commit:
git diff master..feature_branch > ~/mypatch.patch
git checkout master
# Create a new, sub-feature branch
git checkout -b feature_branch2
# Patch the 30 commit patch file onto it:
git apply ~/mypatch.patch
Now I have my 30-commit patch all applied locally, but unstaged and uncommitted.
现在我的 30-commit 补丁全部应用在本地,但未暂存和未提交。
Now use git gui
to add files, chunks, and/or lines and break up your big PR or "diff":
现在用于git gui
添加文件、块和/或行并分解您的大 PR 或“差异”:
Note that if you don't have git gui
, you can easily install it in Ubuntu with sudo apt install git-gui
.
请注意,如果您没有git gui
,您可以使用sudo apt install git-gui
.
I can now run git gui
and start adding files, chunks, and/or lines (by right-clicking in the git GUI program), and break up the 30 commit feature branch into sub branches as described just above, repeatedly adding, committing, then forking a new feature branch and repeating this cycle until all changes have been added to a sub-feature-branch and my 30-commit feature is successfully broken up into 3 or 4 sub-features. I can open up a separate PR for each of these sub-features now, and they will be easier for my team to review.
我现在可以运行git gui
并开始添加文件、块和/或行(通过在 git GUI 程序中右键单击),并将 30 个提交功能分支分解为如上所述的子分支,重复添加、提交,然后分叉一个新的功能分支并重复这个循环,直到所有更改都添加到子功能分支并且我的 30-commit 功能成功分解为 3 或 4 个子功能。我现在可以为这些子功能中的每一个打开一个单独的 PR,我的团队可以更轻松地查看它们。