Git分支和切换回主分支是什么意思?

4

我有一段代码,工作得非常好,现在我要在工作电脑上创建一个分支进行一些重要的更改,使用命令 git checkout -b messaging。我提交了部分完成的工作,并使用命令 git push origin messaging 将其推送到远程存储库中。现在我回到家里,运行命令 git pull origin messaging 并切换到了这个分支,但我想切换回 master 分支,但是运行 git checkout master 命令后收到以下信息:

$ git checkout master
Switched to branch 'master'
Your branch is ahead of 'origin/master' by 1 commit.

我的 messaging 分支的所有文件都在那里。 git status 告诉我我目前在 master 分支,但是我的分支比 origin/master 提交多1次。 我已经想出了两种方法来获取到我的真正的主分支:

git checkout origin/master
git checkout master~1

但是我对这种情况感到困惑,我想确保我对 master 的更改不会影响 messaging 分支,反之亦然。 我想做的是将 origin/master 作为我的本地 master,并将 messaging 保持在其单独的分支中。 我在家里电脑上做了什么让 master 指向 messaging 提交? 目前,我想要有两个完全隔离的分支。

再考虑一下,当我执行 git pull origin messaging 时,我正在我的 master 分支上,这实际上会将 messaging 分支合并到我的本地 master 中吗? 如果是这样,我应该怎么做(创建本地的 messaging 分支并将其拉入其中?)并且如何将我的本地 master 指向没有 messaging 更改的提交?


我刚执行了'git reset --hard origin/master',我认为这可能已经解决了我的问题。 我仍然希望了解我所犯错误的详细信息,以避免将来出现类似的情况,并确认此操作是否正确。 - Jason Goemaat
3个回答

6

哦,git pull……我不喜欢git pull;它只会让人混乱。那么发生了什么?

在你回家并运行git pull origin messaging之前,一切都很好。如果你运行git branch -av,你会看到origin/masterorigin/messaging指向你想要的提交。

那么,pull做了什么?

git pull实际上只是一个git fetch后跟着一个git merge的包装器。 git fetch很容易理解;它只收集了远程(由origin指定)拥有但你本地没有的任何快照的信息。在这种情况下,一个提交和名为origin/messaging的分支。然后,pull运行了git merge origin/messaging,将origin/messaging分支合并到你当前所选的分支(master)中。因此,您无意中将更改从origin/messaging拉入了master中。

让我们来修正一下。首先,将主分支恢复到应该的位置:

git checkout master
git reset --hard origin/master

现在,基于你的远程分支,请检出本地分支 messaging
git checkout -b --track messaging origin/messaging

你现在可以继续在 messaging 分支上工作。

未来建议避免使用 git pull。我认为它的语义很容易让人混淆。相反,先运行 git fetch,然后通过合并或变基更新你感兴趣的每个分支。


谢谢,我之前没有意识到 'git fetch' 实际上会从远程获取所有分支中的所有更改。 我现在明白了,它只是一堆提交记录,每个提交记录都指向它创建时的那个提交记录。此外,有些分支基本上只是指向一个提交记录(因此是该提交记录的历史记录)。 我以为最初的克隆是在查看主分支,但我猜它会拉取所有提交记录和分支指针,但之后我需要特别跟踪任何新的远程分支。 - Jason Goemaat
听起来你已经搞定了! - Peter Lundgren

5
我认为你已经自己回答了这个问题。根据 git pull 的手册:
“将远程仓库中的更改合并到当前分支中。在默认模式下, git pull 等同于 git fetch 加上 git merge FETCH_HEAD。”
换句话说,你将远程的 'messaging' 分支拉到了本地的主分支。
这是在不真正理解其功能的情况下进行git pull时普遍存在的危险。实际上,它是一个git fetch加上一个git merge,这显然不是你在这种情况下想要的。你可能想要做的是 git fetch 加上 git checkout --track origin/messaging。这将创建一个本地的 messaging 分支来跟踪远程仓库 - 这可能是你期望的行为。
Mark Longair 在 这篇博客文章 中很好地解释了 git pull 的使用以及为什么你通常最好明确地获取和合并。

谢谢你的出色答案,我已经点了个赞,但我认为Peter的略微好一些。 - Jason Goemaat

0

是的,您的拉取操作已经将分支获取并合并到了主分支中。而且,您是正确的,应该创建一个本地消息分支并将其拉取到其中。

考虑将其拆分为两个命令git fetch 然后 git merge origin/XX,以便您可以100%清楚地知道正在发生什么。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接