主分支和'起源/主人'分歧,如何'分散'分支'?

Fra*_*ank 882 git branch

不知何故,我的主人和我的起源/主人分支已经分道扬.. 我实际上不希望它们分歧.如何查看这些差异并"合并"它们?

Von*_*onC 954

您可以通过以下方式查看差异:

git log HEAD..origin/master
Run Code Online (Sandbox Code Playgroud)

拉它之前(fetch + merge)(另请参阅"如何让git始终从特定分支中拉出来?")


如果您有以下消息:

"你的分支和'origin/master'分歧,#并分别有1个和1个不同的提交."

,检查是否需要更新origin.如果origin是最新的,那么origin当你在本地提交自己的提交时,一些提交已被推送到另一个repo.

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \
                    C  master (your work)
Run Code Online (Sandbox Code Playgroud)

您基于提交A提交C,因为这是您当时从上游获取的最新工作.

但是,在您尝试推回原点之前,其他人推送了提交B.
开发历史已分为不同的路径.

然后,您可以合并或变基.有关详细信息,请参阅Pro Git:Git Branching - Rebasing.

合并

使用git merge命令:

$ git merge origin/master
Run Code Online (Sandbox Code Playgroud)

这告诉Git将更改集成origin/master到您的工作中并创建合并提交.
历史图现在看起来像这样:

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \      \
                    C ---- M  master (your work)
Run Code Online (Sandbox Code Playgroud)

新的merge,commit M,有两个父节点,每个父节点代表一条开发路径,导致存储在该提交中的内容.

请注意,M背后的历史现在是非线性的.

变基

使用git rebase命令:

$ git rebase origin/master
Run Code Online (Sandbox Code Playgroud)

这告诉Git重放提交C(你的工作),好像你已经将它基于提交B而不是A.
CVS和Subversion用户在提交之前更新它们时会定期在上游工作之上重新定义它们的本地更改.
Git只是在commit和rebase步骤之间添加了明确的分离.

历史图现在看起来像这样:

... o ---- o ---- A ---- B  origin/master (upstream work)
                          \
                           C'  master (your work)
Run Code Online (Sandbox Code Playgroud)

Commit C'是由git rebase命令创建的新提交.
它在两个方面与C不同:

  1. 它有不同的历史:B而不是A.
  2. 其内容考虑了B和C的变化; 它与合并示例中的M相同.

请注意,C'背后的历史仍然是线性的.
我们选择(现在)仅允许线性历史记录cmake.org/cmake.git.
这种方法保留了之前使用的基于CVS的工作流程,可以简化过渡.
尝试将C'推入我们的存储库将起作用(假设您有权限,并且在您重新定位时没有人推送).

git pull命令提供了一种从源获取并在其上重新定义本地工作的简写方法:

$ git pull --rebase
Run Code Online (Sandbox Code Playgroud)

这将上面的fetch和rebase步骤合并为一个命令.

  • @ CygnusX1将是一个`git reset --hard origin/master`,正如下面的答案所述:http://stackoverflow.com/a/8476004/6309 (20认同)
  • @Neth:因为它不是关于分阶段的修改(即索引中存在但尚未提交的修改),而是关于*local commits*(与远程提交的提交不同).`git reset --hard HEAD`只会删除任何本地索引的非提交修改,并且无法协调本地和远程*提交*之间的差异.只有合并或rebase才能将两组提交(本地提交和远程提交)放在一起. (10认同)
  • 我在查找同样的问题时发现了这个问题,你能解释为什么'git reset --hard HEAD'没有解决问题吗? (3认同)
  • 哇,谢谢这个令人敬畏的回应.我们不小心做了一个没有"--rebase"的"git pull",而"git rebase origin/master"就是修复! (3认同)
  • 怎么样 - 我只是想忽略/转储我的本地更改并与我的本地分支一起使用遥控器?换句话说,我希望`master`在你的例子中指向`B`. (2认同)
  • 这也可能对其他人有帮助;我认为应该以“git”开头的很多命令只是我编辑文本文件。因此,如果您感到困惑,您可能需要使用“nano”、“emacs”、“pico”、“vim”或您使用的任何 GUI 编辑器进行编辑 (2认同)

ski*_*ppy 657

即使在阅读了上述回复之后,我也有了这个并且因为它导致了什么而感到困惑.我的解决方案是做

git reset --hard origin/master
Run Code Online (Sandbox Code Playgroud)

然后,这只是将我的(本地)主副本(我假设被搞砸了)重置到正确的点,由(远程)origin/master表示.

警告:您将丢失尚未推送的所有更改origin/master.

  • 您可能应警告用户,这将使他们失去尚未推送到原点的所有更改 (93认同)
  • 是的,它感觉有点像傻瓜选项,但如果没有真正的危险,你在这里快速解决 - 这是有效的(无论如何我) (17认同)
  • 这需要在主分支之前("git checkout master"). (7认同)
  • @PedroLoureiro提交注意事项真丢失了,您仍然可以使用`git reflog`找到提交,或者在`gitk --all`中查看它们.但是,当然硬重置是另一回事而不是反转. (5认同)

Ris*_*tha 55

我相信这应该对我有帮助:

git reset --hard origin/main
Run Code Online (Sandbox Code Playgroud)

但事实并非如此。不知怎的,我收到了同样的消息,当我从远程分支中提取更改时,冲突就发生了。因为我确信我根本不需要现有的本地分支&我只需要main远程分支的副本,因此我想出了这个解决方案:

  • 结帐到新分支,例如git checkout -b placeholder-branch. 注意:此分支稍后可以删除。
  • git branch -D main,我这样做是因为我确信我当地的分支机构搞砸了并且我不需要这个。我需要来自远程实例的新副本。
  • git checkout --track origin/main& 你完成了; 现在您可以删除placeholder-branch使用git branch -D


asi*_*rna 49

git pull --rebase origin/master 
Run Code Online (Sandbox Code Playgroud)

是一个单一的命令,可以帮助您的大部分时间.

编辑:从原点/主数据中提取提交,并在新提取的分支历史记录上应用更改.

  • 请提一下命令的作用,否则人们可能会运行它并最终搞砸了 (86认同)
  • 除非存在真正的差异,否则会导致您失败. (7认同)
  • 如果没有问题,您最终应该得到包含所有更改 origin/master 的 master 加上所有本地提交将在其之上重播。对我来说似乎不错。 (3认同)

pan*_*kka 30

我发现自己在这种情况下,当我试图变基一个分支,正在跟踪远程分支,我试图重订它的主人.在这种情况下,如果你试图改变,你很可能会发现你的分支分歧,它可以创建一个不适合git nubees的混乱!

假设你在分支my_remote_tracking_branch上,它是从master分支出来的

$ git status

#On branch my_remote_tracking_branch

无需提交(工作目录清理)

而现在你正试图从主人那里退缩:

git rebase master

现在停下来,省去一些麻烦!相反,使用merge作为:

git merge master

是的,你最终会在你的分支上提交额外的提交.但除非你想要"不发散"的分支,否则这将是一个比变基更平滑的工作流程.有关更详细的说明,请参阅此博客.

另一方面,如果你的分支只是一个本地分支(即尚未推送到任何远程),你肯定应该做一个rebase(在这种情况下你的分支不会分歧).

现在,如果您正在阅读此内容,因为您已经处于由于此类rebase而处于"分歧"的情况中,您可以通过使用以下命令返回到源的最后一次提交(即处于非分歧状态):

git reset --hard origin/my_remote_tracking_branch

  • 一个经验法则是,如果您正在变基的分支尚未发布(并由其他人使用),则使用`rebase`.否则,使用`merge`.如果你修改已发布(和使用过)的分支,你必须协调一个阴谋,重写每个使用你的分支的开发人员的历史记录. (5认同)
  • `git reset --hard origin/my_remote_tracking_branch` 才是真正有效的 (4认同)

Dar*_*ook 21

在我的情况下,这就是我所做的导致分歧的消息:我做了git push但后来确实git commit --amend在提交消息中添加了一些内容.然后我也做了另一次提交.

所以在我的情况下,只是意味着origin/master已经过时了.因为我知道没有人触及原点/主人,所以修复很简单:( git push -f-f意味着力量)

  • 用于`git push -f`的+1来覆盖先前提交并推送到原点的更改.我也确信没有其他人触及过存储库. (7认同)
  • 非常危险的命令.请写一份关于命令风险因素的简短信息. (4认同)
  • @Trickster:我已经描述了风险:“因为我知道没有其他人会触及起源/主人”。我相信,在那种情况下,这不是一个冒险的命令。 (2认同)

Lar*_*dua 9

在我的情况下,我已经推动了更改origin/master,然后意识到我不应该这样做:-(这很复杂的事实是本地更改是在一个子树.所以我回到最后一个好的提交之前"坏"本地更改(使用SourceTree)然后我得到了"分歧消息".

在本地修复我的混乱之后(这里的细节并不重要)我想"回到过去"远程origin/master分支,以便它master再次与本地同步.我的解决方案是:

git push origin master -f
Run Code Online (Sandbox Code Playgroud)

注意-f(强制)开关.这删除了origin/master错误推送的"错误更改",现在本地和远程分支同步.

请记住,这是一种潜在的破坏性操作,因此只有在您100%确定及时"移回"远程主站时才能执行此操作.

  • @ThibaultD。即使没有,这正是我正在寻找的。 (2认同)

Bia*_* D. 8

我知道这里有很多答案,但我认为git reset --soft HEAD~1值得关注,因为它可以让您在解决分歧状态的同时保留最后一次本地(未推送)提交中的更改。我认为这是一个比 pull with 更通用的解决方案rebase,因为本地提交可以被审查甚至移动到另一个分支。

关键是用--soft,而不是苛刻--hard。如果提交超过 1 次,则HEAD~x应该使用 的变体。所以这里是解决我的情况的所有步骤(我有 1 个本地提交和 8 个在远程提交):

1) git reset --soft HEAD~1撤销本地提交。在接下来的步骤中,我使用了 SourceTree 中的接口,但我认为以下命令也应该有效:

2) git stash隐藏 1) 中的更改。现在所有的变化都是安全的,不再有分歧了。

3) git pull获取远程更改。

4) git stash popgit stash apply应用上次隐藏的更改,然后根据需要进行新的提交。当想要删除本地提交中的更改时,此步骤与2)一起是可选的。此外,当想要提交到另一个分支时,这一步应该在切换到所需的分支后完成。


Sho*_*hin 6

我已经通过移动到最后提交到 origin/main 的commit_sha来修复它。

git reset --hard commit_sha
Run Code Online (Sandbox Code Playgroud)

警告:您将丢失“commit_sha”提交后提交的所有内容。


归档时间:

查看次数:

655705 次

最近记录:

6 年,4 月 前