主分支和'起源/主人'有分歧,如何'疏远'分支'?

时间:2010-03-16 05:05:41

标签: git branch

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

16 个答案:

答案 0 :(得分:899)

你可以review the differences使用:

git log HEAD..origin/master

之前的pulling it(获取+合并)(另请参阅"How do you get git to always pull from a specific branch?"


当您收到如下消息时:

  

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

,检查您是否need to update origin。如果origin是最新的,那么当您在本地提交自己的提交时,某些提交已从另一个仓库推送到origin

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \
                    C  master (your work)

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

然而,在你试图回到原点之前,其他人推动了提交B.
发展历史已分化为不同的路径。

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

<强>合并

使用git merge命令:

$ git merge origin/master

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

... o ---- o ---- A ---- B  origin/master (upstream work)
                   \      \
                    C ---- M  master (your work)

新合并提交M有两个父项,每个父项代表一条开发路径,导致存储在该提交中的内容。

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

<强>衍合

使用git rebase命令:

$ git rebase origin/master

这告诉Git重播提交C(你的工作),就好像你把它建立在提交B而不是A.上 CVS和Subversion用户在提交之前更新时,会在上游工作之前定期更改本地更改 Git只是在提交和rebase步骤之间添加了明确的分离。

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

... o ---- o ---- A ---- B  origin/master (upstream work)
                          \
                           C'  master (your work)

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

  1. 它有不同的历史:B而不是A.
  2. 其内容考虑了B和C的变化;它与合并示例中的M相同。
  3. 请注意,C'背后的历史仍然是线性的 我们选择(目前)只允许cmake.org/cmake.git中的线性历史记录 这种方法保留了之前使用的基于CVS的工作流程,可以简化过渡 尝试将C'推送到我们的存储库中将会有效(假设您有权限,并且在您重新定位时没有人推送过)。

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

    $ git pull --rebase
    

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

答案 1 :(得分:597)

即使在阅读了上述回答之后,我也对此产生了疑问,并对其造成了什么感到困惑。我的解决方案是

git reset --hard origin/master

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

  

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

答案 2 :(得分:42)

git pull --rebase origin/master 

是一个可以在大多数时间帮助你的命令。

编辑:从原点/主档中提取提交,并在新拉出的分支历史记录上应用您的更改。

答案 3 :(得分:28)

当我尝试 rebase 一个跟踪远程分支的分支时,我发现自己处于这种情况,我试图在master上对其进行rebase。在这种情况下,如果您尝试重新绑定,您很可能会发现您的分支分歧并且它可能会造成一个不适合git nubees的混乱!

假设你在分支my_remote_tracking_branch,它是从主分支

  

$ git status

     

#On branch my_remote_tracking_branch

     

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

现在你正试图从主人那里改变:

  

git rebase master

立即停止并省去一些麻烦!相反,使用merge as:

  

git merge master

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

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

现在,如果您正在阅读此内容,因为您已经 处于“分歧”场景中,因为这样的rebase,您可以从原点返回到最后一次提交(即处于非分叉状态)使用:

  

git reset --hard origin / my_remote_tracking_branch

答案 4 :(得分:20)

在我的情况下,这是我做的导致分歧的消息:我做git push但后来git commit --amend向提交消息添加了一些东西。然后我也做了另一次提交。

所以在我的情况下,只是意味着origin / master已经过时了。因为我知道没有其他人接触起源/主人,所以修复很简单:git push -f(其中-f表示强制)

答案 5 :(得分:7)

在我的情况下,我已将更改推送到origin/master,然后意识到我不应该这样做:-(由于本地更改属于子树,这很复杂。所以我回到了最后在&#34;糟糕的&#34;本地更改(使用SourceTree)之前做好了提交,然后我得到了&#34;分歧消息&#34;。

在本地修复我的烂摊子后(这里的细节并不重要)我想及时回到过去#34;远程origin/master分支,以便它再次与本地master同步。在我的案例中的解决方案是:

git push origin master -f

请注意-f(强制)开关。这删除了&#34;糟糕的变化&#34;错误地推送到origin/master并且现在本地和远程分支同步。

请记住,这是一种潜在的破坏性操作,所以只有当您100%确定&#34;后退时才会执行此操作。远程主控时间正常。

答案 6 :(得分:4)

查看差异:

git difftool --dir-diff master origin/master

这将显示两个分支之间的更改或差异。在araxis(我最喜欢的)中,它以文件夹diff样式显示。显示每个已更改的文件。然后,我可以单击文件以查看文件中更改的详细信息。

答案 7 :(得分:4)

我知道这里有很多答案,但我认为git reset --soft HEAD~1值得一些关注,因为它可以让你在解决分歧时保留最后本地(未推送)提交的更改州。我认为这是一个比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)。此外,当想要提交到另一个分支时,应该在切换到所需的分支之后执行此步骤。

答案 8 :(得分:3)

在我的情况下,这是因为没有提交我的冲突解决方案。

问题是由运行git pull命令引起的。原产地的变化导致与我当地的回购冲突,我解决了。但是,我没有提交它们。此时的解决方案是提交更改(git commit已解析的文件)

如果您在解决冲突后也修改了一些文件,git status命令会将本地修改显示为未分阶段的本地修改,并将解析合并为分阶段本地修改。这可以通过git commit首先提交合并中的更改,然后像往常一样添加和提交未暂存的更改(例如,通过git commit -a)来正确解决。

答案 9 :(得分:1)

我希望这样做更方便,更安全。

# copying your commit(s) to separate branch
git checkout <last_sync_commit>
git checkout -b temp
git cherry-pick <last_local_commit>

git checkout master
git reset --soft HEAD~1 # or how many commits you have only on local machine
git stash               # safer, can be avoided using hard resetting on the above line
git pull
git cherry-pick <last_local_commit>

# deleting temporary branch
git branch -D temp

答案 10 :(得分:0)

当我尝试使用以下命令编辑上次提交消息时,我有相同的消息:git commit --amend -m "New message" 当我使用git push --force-with-lease repo_name branch_name推送更改时 没有问题。

答案 11 :(得分:0)

当我通过

创建基于分支A的分支时遇到此问题
git checkout -b a

然后我将分支A的上游设置为原始分支B,

git branch -u origin/B

然后我得到了上面的错误消息。

为我解决此问题的一种方法是

  • 删除分支a
  • 创建新的分支b,
git checkout -b b origin/B

答案 12 :(得分:0)

用分支与原始分支的提交次数替换123。

git reset HEAD~123 && git reset && git checkout . && git clean -fd && git pull

答案 13 :(得分:0)

git reset --soft origin / my_remote_tracking_branch

This way you will not loose your local changes

答案 14 :(得分:0)

我已经解决了这一问题,方法是移至最后一次提交给源/主服务器的 commit_sha

  case .string(let msgString):
                                 
        if msgString.contains("Closing Socket for")     {
        self.task?.cancel(with: .normalClosure, reason: nil) } 

...
          

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

答案 15 :(得分:0)

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

git reset --hard origin/master

但它没有,不知何故我收到了相同的消息,一旦我从远程分支中提取更改,冲突就会发生。由于我确定我根本不需要我现有的本地分支并且我只需要远程 master 分支的精确副本,因此我想出了这个解决方案:

  • 结帐到新分支,例如 git checkout -b placeholder-branch。注意:此分支可以稍后删除。
  • git branch -D master,我这样做是因为我确信我的本地分支搞砸了,我实际上不需要这个,我只需要远程实例的一个新副本。
  • git checkout --track origin/master 完成,现在您可以使用 placeholder-branch
  • 删除 git branch -D