我试图在GitHub上审查一个拉请求到一个不是主的分支。目标分支在master后面,拉请求显示了来自master的提交,所以我合并了master并将其推送到GitHub,但刷新后,他们的提交和差异仍然出现在拉请求中。我已经再次检查了GitHub上的分支是否有来自master的提交。为什么它们仍然出现在拉请求中?

我还检查了本地拉请求,它只显示未合并的提交。


看起来Pull Request没有跟踪目标分支的变化(我联系了GitHub支持,并在2014年11月18日收到了回复,说这是故意的)。

但是,你可以通过以下方法让它显示更新后的更改:

http://githuburl/org/repo/compare/targetbranch...currentbranch

根据需要替换githuburl, org, repo, targetbranch和currentbranch。

或者正如hexsprite在他的回答中所指出的,你也可以通过点击PR上的Edit来强制它进行更新,并临时将基础更改为不同的分支,然后再返回。这会产生警告:

你确定要改变底色吗? 类中的旧基本分支中的一些提交可能会被删除 时间轴,旧的评论可能会过时。

并将在PR中留下两个日志条目:


对于遇到这种情况并对GitHub Pull Request行为感到困惑的其他人来说,根本原因是PR是源分支尖端与源分支和目标分支的共同祖先之间的差异。因此,它将显示源分支上直到公共祖先的所有更改,而不会考虑目标分支上可能发生的任何更改。

更多信息请访问:https://developer.atlassian.com/blog/2015/01/a-better-pull-request/

基于共同祖先的差异似乎很危险。我希望GitHub能够提供一个更标准的基于3方合并的PR。

编辑-我从来没有提到我总是使用明显的变通办法来避免由此产生的任何问题。只要定期将你的目标分支合并到你的PR分支中,你就不会遇到任何令人不快的意外。


解决这个问题的一种方法是git在PR中rebase targetbranch。然后git push -force targetbranch,然后Github会显示正确的提交和diff。如果你不知道你在做什么,请小心使用这个。也许先签出一个测试分支来做rebase,然后git diff targetbranch以确保它仍然是你想要的。


我不太确定这背后的理论。但我得到了这个几次,并能够通过做下面的事情来解决这个问题。

git pull --rebase

这将从您的原始回购主分支获取并合并更改(如果您有指向)

然后你把你的更改强行推到你的github克隆库(目标)

git push -f origin master

这将确保你的github克隆和你的父repo在相同的github提交级别,你不会看到跨分支的任何不必要的更改。


您需要在~/中添加以下内容。gitconfig文件:

[rebase]
    autosquash = true

这将自动实现与此答案所显示的相同的结果。

接下来我来处理。


综上所述,GitHub不会在拉请求中自动调整提交历史。最简单的解决方案是:

解决方案1:调整基数

假设你想从feature-01合并到master:

git fetch origin
git checkout feature-01
git rebase origin/master
git push --force-with-lease

如果你在一个分叉上工作,那么你可能需要用上游替换上面的原点。参见如何更新GitHub分叉存储库?了解有关跟踪原始存储库的远程分支的更多信息。

解决方案2:创建一个新的拉请求

假设你想从feature-01中合并介绍master:

git checkout feature-01
git checkout -b feature-01-rebased
git push -u origin feature-01-rebased

现在打开一个基于feature-01-re - based的拉请求,并关闭feature-01的拉请求。


这里有一个很好的变通办法。在GitHub中查看PR时,使用Edit按钮将基本分支更改为master以外的内容。然后切换回master,现在它将正确地显示最近提交的更改。


如果你太担心会把事情搞砸,可以采用故障安全方法: 转到文件并手动删除更改,然后使用最后一次提交压缩

git add .  && git commit -a --allow-empty-message -m '' && git reset --soft HEAD~2 &&
git commit --edit -m"$(git log --format=%B --reverse HEAD..HEAD@{1})"

我没有矛盾,你就好走了!


这发生在GitHub中,当你压缩从目标分支合并的提交时。

I had been using squash and merge with Github as the default merge strategy, including merges from the target branch. This introduces a new commit and GitHub doesn't recognize that this squashed commit is the same as the ones already in master (but with different hashes). Git handles it properly but you see all the changes again in GitHub, making it annoying to review. The solution is to do a regular merge of these pulled in upstream commits instead of a squash and merge. When you want to merge in another branch into yours as a dependency, git merge --squash and revert that single commit before pulling from master once that other branch has actually made it to master.

编辑:另一种解决方案是重新基底和强制推。干净但被改写的历史


我找到了一种方法来获得正确的行为(在2020年11月测试)。

git合并和解决冲突后,需要使用git merge——continue而不是git commit ....


用2点url代替3点url来比较

而不是

http://githuburl/org/repo/compare/targetbranch...currentbranch

Use

http://githuburl/org/repo/compare/targetbranch..currentbranch

我做了什么,为什么会这样?

没有一个解决方案对我有效。当我用两个点,即。。而不是……GH的差异更接近我所改变的。但这还不是我全部的改变。

这是因为GitHub显示压缩合并更改的方式存在问题。最好的解释在这里

它基本上发生在以下情况:

推送featureBranch的变化 挤压合并到主 在本地,当我仍然在featureBranch上时,我将它与main合并。做更多的修改,再把它推上去。 但后来在GitHub上,我看到了比我预期的更多的变化。

值得注意的是,这不是git的问题。相反,这是一个GitHub问题。GitHub无法判断压缩提交与非压缩提交的总和相同,从而导致额外的差异。


解决方案

在本地main上,撤消并保存所有未与main合并的更改。我做到了。例如,如果我有4个提交,不在我的PR得到壁球合并,那么我会这样做:

git重置头~4 Git保存“最近4次提交”

然后用刚才存储的内容创建一个新分支。步骤:

Git checkout main git checkout -b newBranch Git stash应用 Git add—all Git commit -m "some message" git推


一旦我在开始新的改变或创建PR之前开始做以下事情,这个问题就不会发生在我身上。

git pull --rebase origin <target-branch>

这基本上确保了从本地添加的任何新更改都堆叠在当前远程分支中的内容之上。因此,我们的本地分支总是在当前远程头的顶部,只有新的提交在PR中。


解决这个问题的偷懒方式: 手动编辑分支中已经在目标分支中的文件,使用从目标分支的文件复制的相同代码,并保存它。它被提交。现在,PR将自动更新您所做的新提交,从而解决问题。


使用git的精选

如果重基过程对您来说像对我一样混乱,另一个选择是使用git精选。以下是步骤:

Update your local target branch using git pull. checkout the branch where you made changes and copy the commit IDs of the commits you want. if the branch name is tangled, do git checkout tangled and then git log. You can scroll through the git log output using the up/down arrows on the keyboard. The commit IDs are the long numbers that each commit contains. Create a new branch from your target branch (e.g main) using git checkout -b new-branch-name when you are on the target branch. On the new branch, do git cherry-pick commit-id where commit-id is the long number that you copied from git log which identifies the commit you want to push. You can do this multiple times, changing the id each time to get another commit. If you run git log on this new branch which you created, you can see that only the changes you have added exist after your target branch's head, as expected. Lastly, push the changes to remote using git push origin new-branch-name and create a pull request.


在我回答之前先说说我的问题

我将考虑3个分支,主控、测试和特性。

测试分支已经有了主要的变化。

当我将master合并到我的特性分支中,然后工作并提交到我的特性分支中,当我提出一个针对测试的PR时,它会再次显示已经在测试中的更改。这令人沮丧,我的同事没有遇到这个问题,因为他们使用命令提示符。我不希望使用命令提示符。

我使用GitHub桌面应用程序,这种情况经常发生在我身上,直到今天我才对此无能为力。

如果你在你的特性分支上有无数次提交(最多4-5次),只有 那么这个程序就有用了。如果有的话,你可能会感到困惑 大量的提交。

现在围绕GitHub桌面用户的工作:

从测试创建一个分支,命名为“feature-merge-to-testing” 选择那些提交到“特性合并到测试”。 解决冲突。 现在针对测试分支提出一个PR。 一旦完成,删除“特性-合并-测试”分支。

直到GitHub修复桌面应用程序中PRs的问题。我想我要按这个程序来,这似乎对我很管用。如果有什么有效的工作,请告诉我。

改变底数(这个问题的第一个答案)对我没用。


这发生在PRs被压缩和合并选项合并时。如果您希望旧的提交不显示在下面的pr中,那么只需使用创建合并提交选项合并这些pr。

创建合并提交 压缩和合并 重组和合并

注意:一旦完成,下一个pr总是显示他们自己的提交,而不是旧的,因为旧的已经通过创建合并提交选项添加到基础分支。

技术解释:merge -squash和rebase之间的区别是什么?