我有两个分支devel
和next
。在开发中,我或多或少都有大量的提交。一些提交是在next
中挑选的。我还添加了一些提交到下一个提交到devel
。
现在,我希望看到next
中缺少的内容,因此我可以在将更改详细检测到next
之前对其进行测试。我现在的问题是,我怎样才能看到devel
中的哪些提交,而下一个提交中没有?
答案 0 :(得分:191)
使用不多的命令git cherry
向您显示尚未采摘的提交。 git cherry
的文档是here,但简而言之,您应该能够做到:
git checkout devel
git cherry next
...并看到输出有点像这样:
+ 492508acab7b454eee8b805f8ba906056eede0ff
- 5ceb5a9077ddb9e78b1e8f24bfc70e674c627949
+ b4459544c000f4d51d1ec23f279d9cdb19c1d32b
+ b6ce3b78e938644a293b2dd2a15b2fecb1b54cd9
以+
开头的提交将是您尚未挑选到next
的提交。在这种情况下,到目前为止我只选择了一个提交。您可能希望将-v
参数添加到git cherry
命令,以便它还输出每个提交的主题行。
答案 1 :(得分:96)
此外,您可以使用
git log --left-right --graph --cherry-pick --oneline devel...next
获取分支之间未共享的实际不同提交的良好列表。
操作词是--cherry-pick
--cherry-pick
当提交集受限于对称差异时,省略任何在“另一方”引入相同更改的提交。例如,如果您有两个分支A和B,通常只在一侧列出所有提交的方法是--left-right,就像上面该选项说明中的示例一样。然而,它显示了从另一个分支中挑选出来的提交(例如,“b上的第3个”可以从分支A中挑选出来)。使用此选项,这些提交对将从输出中排除。
更新正如评论中所述,最新版本的git添加了--cherry-mark
:
--cherry-mark
喜欢--cherry-pick(见下文),但标记等效提交=而不是省略它们,而不等价的提交+。
答案 2 :(得分:46)
您可以尝试使用git log子集:
git log --oneline devel ^next
答案 3 :(得分:24)
怎么样
git log next..devel
结果类似于Byran的答案(不同的提交顺序),但我们的答案都会产生分支之间不同的提交,而只是显示一个分支中的内容而不是另一个分支中的内容。
答案 4 :(得分:1)
要获取未集成到发布分支(下一个)的提交列表,您可以使用:
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
查看git-rev-list了解详情。
答案 5 :(得分:0)
@Mark Longair nailed it in his answer here,但我想补充一些见解。
我的情况:
我用30次提交做了一个大的feature_branch
,并在GitHub上打开了一个Pull Request(PR),将其合并到master
中。分支master
在我下面改变了一吨,并收到了feature_branch
没有的200次提交。为了解决冲突,我做了git checkout feature_branch
和git merge master
来将master
的更改合并到我的feature_branch
中。我选择了merge
而不是rebase
到最新的master上,因此我只需要一次解决冲突,而不是潜在的30次(每次提交一次)。我不想将我的30个提交先压缩为1,然后再基于最新的master
,因为这可能会消除PR中的GitHub评论评论历史记录。因此,我将master合并到我的功能分支中,并且一次解决了冲突。一切都好。但是,我的PR对我的同事来说太大了。我需要将其拆分。我去压缩了30次提交,哦,不!他们在哪?现在,它们都与master
的200次提交相互关联,因为我将master
合并到了feature_branch
中!我该怎么办?
git cherry
的用法,以防您尝试git cherry-pick
单个提交: git cherry
进行营救!(
要查看feature_branch
中所有但master
中没有的提交,我可以这样做:
git checkout feature_branch
git cherry master
或者,我可以通过执行feature_branch
来检查来自ANY分支的提交,而无需确保首先进入git cherry [upstream_branch] [feature_branch]
,就像这样。再次,这检查以查看哪些提交在feature_branch
中,但不在upstream_branch
中(在这种情况下为master
):
git cherry master feature_branch
添加-v
还会显示提交消息主题行:
git cherry -v master
通过“字数统计”“行”(wc -l
)进行计数可统计有多少次提交:
git cherry master | wc -l
您可以将此计数与GithHub PR中显示的提交编号进行比较,以更好地了解git cherry
确实有效。您还可以一一比较git哈希,看看它们在git cherry
和GitHub之间是否匹配。请注意,git cherry
不会计算将master
合并到feature_branch
的任何合并提交,但是GitHub会。因此,如果您发现计数之间的差异很小,请在GitHub PR提交页面上搜索单词“ merge”,您可能会发现这是罪魁祸首,它没有出现在git cherry
中。例如:名为“将分支'master'合并到feature_branch” 中的提交将显示在GitHub PR中,但在您运行git cherry master feature_branch
时不会显示。这很好并且可以预期。
因此,现在,我有了一种方法,可以找出我可能想要选择哪些差异比较到一个新的功能分支来拆分此差异:我可以在本地使用git cherry master feature_branch
或在GitHub公关
但是,分散我的大差异的另一种方法是将我所有的30个提交压缩为一个,将其修补到新的功能分支上,软重置修补程序提交,然后使用git gui
来完成逐个文件,逐个块或逐行添加片段。一旦获得一个子功能,我可以提交添加的内容,然后签出新的分支,添加更多的分支,提交,签出一个新的分支等,直到我将主要功能分解为几个子功能。 问题是由于我的git merge master
到我的feature_branch
中,我的30个提交与其他人的其他200个提交混合在一起,因此重新定基是不切实际的,因为我不得不筛选一下230次提交重新排序并压缩了30次提交。
一种解决方法是简单地obtain a patch file包含我所有30次提交的“压榨”,将其修补到master
的新分支上(新的子功能-branch),然后从那里开始工作,如下所示:
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
现在,我已将30个提交的补丁全部应用在本地,但未暂存且未提交。
git gui
添加文件,块和/或行并破坏您的大PR或“差异”: 请注意,如果您没有git gui
,则可以使用sudo apt install git-gui
在Ubuntu中轻松安装它。
我现在可以运行git gui
并开始添加文件,块和/或行(通过在git GUI程序中单击鼠标右键),并将30个commit功能分支分解为子分支,如上所述。 ,反复添加,提交,然后创建新的功能分支,并重复此循环,直到所有更改都已添加到子功能分支中,并且我的30提交功能被成功分解为3或4个子功能。现在,我可以为这些子功能中的每个子功能打开一个单独的PR,这样我的团队就可以更轻松地对其进行审核。