如何让git始终从特定分支拉取代码?

502

虽然我不是Git专家,但我已经在几个不同的项目中使用它一段时间了。在每个项目中,我总是执行git clone [repository],然后可以始终执行git pull,当然前提是我没有未完成的更改。

最近,我不得不回退到以前的一个分支,并使用git checkout 4f82a29进行了回退。当我再次准备进行拉取时,我发现我必须将我的分支设置回主干。现在,我无法直接使用git pull进行拉取,而是必须指定git pull origin master,这很麻烦,并表明我不完全理解发生了什么。

为什么会发生这种情况,不允许我直接使用git pull而必须要指定origin master?我该如何将其改回来?

更新:

-bash-3.1$ cat config
[core]
    repositoryformatversion = 0
    filemode = true
    bare = false
    logallrefupdates = true
[branch "master"]
[remote "origin"]
    url = git@github.com:user/project.git
    fetch = refs/heads/*:refs/remotes/origin/*

更新2:明确一下,我知道我的原始方法可能是错误的,但我需要修复这个仓库,以便我可以再次简单地使用git pull。目前,git pull 的结果是:

-bash-3.1$ git pull
You asked me to pull without telling me which branch you
want to merge with, and 'branch.master.merge' in
your configuration file does not tell me either.  Please
name which branch you want to merge on the command line and
try again (e.g. 'git pull  ').
See git-pull(1) for details on the refspec.

If you often merge with the same branch, you may want to
configure the following variables in your configuration
file:

    branch.master.remote = 
    branch.master.merge = 
    remote..url = 
    remote..fetch = 

See git-config(1) for details.

我可以告诉git pull合并哪个分支,它可以正确工作,但在执行git checkout之后,git pull不像最初那样工作。


你的 .git/config 长什么样子?在检查出那个提交后,你做了什么? - Ryan Graham
你在4f82a29的基础上提交了代码吗? - Pat Notz
Pat,我没有在其之上进行任何提交。这是在服务器上的,我们需要回滚到一个稳定版本以隐藏我们创建的一个错误。该系统不是用于开发目的,所以我只想回滚,等待我们修复错误,然后再拉回到最新版本。 - David Smith
2
Ryan,我已经更新了,包括.git/config。在检出后,我什么也没做。这台电脑是一台服务器,不是用来进行开发的。 - David Smith
9个回答

750

[branch "master"] 下,尝试将以下内容添加到存储库的 Git 配置文件 (.git/config) 中:

[branch "master"]
    remote = origin
    merge = refs/heads/master

这会告诉Git两件事:

  1. 当你在主分支上时,默认的远程分支是origin。
  2. 在主分支上使用git pull,没有指定远程分支时,默认使用远程主分支(origin)并合并远程分支的更改。

我不确定为什么此设置已从您的配置中删除。您可能还需要遵循其他人发布的建议,但这可能起作用(或至少有所帮助)。

如果您不想手动编辑配置文件,则可以使用命令行工具:

$ git config branch.master.remote origin
$ git config branch.master.merge refs/heads/master

2
这对我也起作用了,我已经从Github检出了一个项目。我正在运行OS X 10.4。 - Sam Barnum
1
你是指 [branch "master"] 下面的内容是什么意思? - ianj
3
在Git配置文件中(从仓库根目录下的.git/config文件中)。 - mipadi
1
@ianj:从命令行,您可以始终执行“$ git config branch.master.remote origin; git config branch.master.merge refs/heads/master”来完成。 - mipadi
如果文件中没有[branch "master"]行,请添加该行,然后添加答案中的后续行。 - reor
显示剩余8条评论

142

如果您愿意,可以通过命令行设置这些选项(而不是编辑配置文件),方法如下:

  $ git config branch.master.remote origin
  $ git config branch.master.merge refs/heads/master

或者,如果你像我一样,希望这成为你所有项目的默认设置,包括未来可能要处理的项目,那么可以将其添加为全局配置设置:

  $ git config --global branch.master.remote origin
  $ git config --global branch.master.merge refs/heads/master

12
+1 是因为知道神奇的单词 "refs/heads/master"。我没有问题地想出如何设置变量,但是完全不知道要将其设置为什么,而且手册也没有太多帮助。最终在找到这个答案后,我找到了文档中正确的位置。对于好奇的人:这个神奇的单词指的是 .git 中的文件路径,在其中 Git 似乎保存着 master 当前提交的哈希码。 - mokus

88
git branch --set-upstream master origin/master

这将在你的 config 文件中添加以下信息:

[branch "master"]
    remote = origin
    merge = refs/heads/master
如果你设置了 branch.autosetuprebase = always,它也会添加以下内容:
    rebase = true

1
我发现这是让git按要求运行的最简单方法,特别是如果有更多的分支,不仅仅是远程分支(即使您必须为每个分支执行此操作,也只需每个分支执行一次)。 - s3v3n
2
我刚刚尝试了一下,但是我收到了错误信息fatal: Not a valid object name: 'origin/master'.,尽管origin是有效的远程分支,并且master像往常一样存在于两个仓库中。 - Ken Williams
2
Ken,你需要先执行“git fetch origin”命令来获取远程分支的名称。 - Eric Lee
17
新版git希望您使用git branch --set-upstream-to=origin/master master命令。该命令可以使您的代码库与主干分支保持同步。 - orbeckst

54

我发现很难记住 mipadi 和 Casey 的答案中确切的 git configgit branch 参数,因此我使用这两个命令来添加上游引用:

git pull origin master
git push -u origin master

这将会把相同的信息添加到你的.git/config中,但我发现这样更容易记住。


1
我同意。这应该是最好的、最简单的答案。 - linbianxiaocao
2
你的回答应该包括为什么它有效,并引用文档中解释原因的部分。 - vfclists

24

Git pull是将两个操作结合在一起的 -- 从被跟踪分支的远程仓库中获取新提交,然后将它们合并到你当前的分支中。

当你检出一个特定的提交时,你没有当前分支,只有HEAD指向你最近的提交。因此,git pull没有所有参数都指定。 这就是为什么它没有工作的原因。

根据你提供的更新信息,你想要的是恢复你的远程仓库。如果你知道引入错误的提交,处理这个问题的最简单方法是使用git revert来记录一个新的提交,该提交撤销了指定的错误提交:

$ git checkout master
$ git reflog            #to find the SHA1 of buggy commit, say  b12345
$ git revert b12345
$ git pull
$ git push

既然你想要更改自己的服务器,我假设你不需要重写历史来隐藏有问题的提交。

如果 bug 是在合并提交中引入的,则此过程将无效。请参见如何撤消错误的合并


你给了我很好的教育,我很感激,但是我可能没有很好地描述我的情况,所以这并不完全符合我的工作流程。我可能会发布另一个问题来解决这个问题。谢谢,保罗!向您致敬。 - David Smith
我刚才误读了你的情况。很高兴你得到了所需的答案。 - Paul

17

还有一种配置 Git 的方式,使其始终将相应的远程分支拉取或推送到当前工作副本所检出的分支上。这被称为跟踪分支,git ready 建议默认设置。

对于上面的下一个存储库:

git config branch.autosetupmerge true

对于所有没有进行其他配置的Git存储库:

git config --global branch.autosetupmerge true

个人认为这有点像魔法,但在某些情况下可能会有帮助,例如特定分支始终是当前分支的情况。

当你将branch.autosetupmerge设置为true并首次检出一个分支时,Git会告诉你关于跟踪对应远程分支的信息:

(master)$ git checkout gh-pages
Branch gh-pages set up to track remote branch gh-pages from origin.
Switched to a new branch 'gh-pages'

然后Git会自动推送到对应的分支:

(gh-pages)$ git push
Counting objects: 8, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 1003 bytes, done.
Total 6 (delta 2), reused 0 (delta 0)
To git@github.com:bigben87/webbit.git
   1bf578c..268fb60  gh-pages -> gh-pages

谢谢!这正是我在寻找的。我想知道为什么Git不会自动使用此选项进行初始化,因为99%的情况下,当您检出新分支时,您希望跟踪具有相同名称的远程分支。 - AlexanderD

9

不想编辑我的git配置文件,我按照@mipadi的帖子中提供的信息进行了操作:

$ git pull origin master

14
重点是要自动完成这个过程,而不是手动指定它。 - Eric

4

您想知道如何使其拉取主分支,需要按照指示指定要从中拉取的refspec。

[branch "master"]
    merge = refs/heads/master

这不应该是"refs/heads/master"吗?根据git-pull(1)的说法,这是默认合并的远程站点分支的名称。 - Adam Monsen
是的,你说得对。我参考的那个仓库是一个特殊情况。已经更正了。 - Ryan Graham

0

想要补充一些信息,我们可以检查这个信息是不是自动引用到任何分支了。

如果您运行命令git remote show origin(假设origin是远程的短名称),Git会显示这个信息,无论git pull是否存在默认的引用都会显示。

以下是一个示例输出。(摘自Git文档)。

$ git remote show origin
* remote origin
  Fetch URL: https://github.com/schacon/ticgit
  Push  URL: https://github.com/schacon/ticgit
  HEAD branch: master
  Remote branches:
    master                               tracked
    dev-branch                           tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (up to date)

请注意显示“为git pull配置的本地分支”部分。
在这种情况下,git pull将指向git pull origin master。
最初,如果您已经克隆了存储库,使用git clone,这些事情会自动处理。但是,如果您手动添加了一个远程仓库,使用git remote add,则这些内容将缺失于git config中。如果是这种情况,则在git remote show origin的输出中,“为'git pull'配置的本地分支”部分将缺失。
如果没有为git pull配置任何设置,则其他答案已经解释了接下来要执行的步骤。

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