简体   繁体   English

在`git pull origin中使用冒号 <remote-branch> : <local-branch> `不拉到正确的分支?

[英]Using colon in `git pull origin <remote-branch> : <local-branch>` does not pull to correct branch?

Let's say I am on a different branch than <local-branch> , called <different-branch> . 比方说,我在不同的分支比<local-branch> ,叫<different-branch>

When I try to pull from a remote branch to a local branch, I do the following: 当我尝试从远程分支拉到本地分支时,我执行以下操作:

git pull origin <remote-branch>:<local-branch>

And, from my understanding this should pull into my <local-branch> , and not pull into <different-branch> . 而且,根据我的理解,这应该进入我的<local-branch> ,而不是拉入<different-branch>

But, then when I check git log while I'm on <different-branch> , I see that those commits are from <remote-branch> ? 但是,当我在<different-branch>上检查git log时,我看到那些提交来自<remote-branch>

How do I pull from a remote branch, into a local branch, when the local branch is different from the one that I cam currently on? 当本地分支与我当前所在的分支不同时,如何从远程分支拉入本地分支? Thank you. 谢谢。

Using git pull with a refspec will not affect the merging part of the pull command. 使用带有refspec的git pull不会影响pull命令的合并部分。 As you maybe know, git pull is essentially just a combination of git fetch and git merge ; 您可能知道, git pull实际上只是git fetchgit merge的组合; first, it will fetch the newest changes from the remote and update the remote-tracking branch, and then it will merge that remote-tracking branch into the current branch . 首先,它将从远程获取最新的更改并更新远程跟踪分支,然后它将该远程跟踪分支合并到当前分支中

Now, as I said, the refspec does not affect the merging part, but it only affects the fetching inside git pull . 现在,正如我所说,refspec的格式不影响合并的一部分,但它不仅影响内 git pull Now to understand what this eventually means, you first have to understand what a refspec is. 现在要了解这最终意味着什么,首先要了解refspec是什么。

A refspec is basically just a configuration which remote branches map to which remote-tracking branch. refspec基本上只是远程分支映射到哪个远程跟踪分支的配置。 The remote branches are here the branches that actually exist on the remote, and the remote-tracking branches are the branches that are created to track the state of the remote branches; 远程分支在这里是实际存在于远程分支上的分支,远程跟踪分支是为跟踪远程分支的状态而创建的分支; for a remote called “origin”, its remote-tracking branches all start with origin/ . 对于名为“origin”的远程,其远程跟踪分支都以origin/开头。

If you don't specify a refspec explicitely, it is taken from the configuration file. 如果未明确指定refspec,则从配置文件中获取。 The default form usually looks like this: 默认表单通常如下所示:

+refs/heads/*:refs/remotes/origin/*

This tells Git to fetch the remote branches located at refs/heads/* and map them to remote-tracking branches located at refs/remotes/origin/* . 这告诉Git获取位于refs/heads/*的远程分支,并将它们映射到位于refs/remotes/origin/*远程跟踪分支。 So for a remote branch master , refs/heads/master will map to refs/remotes/origin/master . 因此对于远程分支masterrefs/heads/master将映射到refs/remotes/origin/master The leading + also tells Git to overwrite the remote-tracking branch regardless of whether the changes could be fast-forwarded or not: After all, you usually want your remote-tracking branches to match exactly the state on the remote, so if the history is rewritten there (which should be avoided) or branches are renamed, you would want the remote-tracking branches to still respect that. 领先+还告诉Git覆盖远程跟踪分支,无论更改是否可以快速转发:毕竟,您通常希望远程跟踪分支完全匹配远程状态,所以如果历史记录在那里重写(应该避免)或重命名分支,你希望远程跟踪分支仍然尊重它。

Now, when you specify the refspec (using git fetch or git pull ), the default mapping is overridden. 现在,当您指定refspec(使用git fetchgit pull )时,将覆盖默认映射。 Instead, your mapping is used. 而是使用您的映射。 For example, when you use git fetch origin master:foo , then a local branch foo is fast-forwarded (if possible) to point to the remote branch master . 例如,当您使用git fetch origin master:foo ,则会快速转发本地分支foo (如果可能)以指向远程分支master So this is actually a fine way to update a local branch, without having to check it out: If you leave out the leading + , then updating the local ref (branch) will fail if it's not a fast-forward merge, so you're also safe against conflicts. 所以这实际上是一个更新本地分支的好方法,而不必检查它:如果你省略了前导+ ,那么更新本地ref(分支)将失败,如果它不是快进合并,那么你'还可以安全地抵御冲突。

But coming back to git pull —what happened when you ran the command? 但回到git pull当你运行命令时发生了什么? As I said, a pull is just a fetch and a merge, so your git pull command first did this: 正如我所说,拉动只是一个提取和合并,所以你的git pull命令首先这样做:

git fetch origin <remote-branch>:<local-branch>

So the remote branch is fetched from the remote, and the local branch is updated—if it's a fast-forward merge. 因此,远程分支从远程获取,本地分支更新 - 如果它是快进合并。 This already does exactly what you wanted: Update <local-branch> . 这已经完全符合您的要求:更新<local-branch>

But then, the merge part of git pull happens; 但是, git pull的合并部分发生了; and Git usually runs git merge FETCH_HEAD for this purpose. 为此,Git通常会运行git merge FETCH_HEAD FETCH_HEAD is a reference to the last fetched branches. FETCH_HEAD是对最后获取的分支的引用。 In this case, it points at <local-branch> . 在这种情况下,它指向<local-branch> So after fetching into <local-branch> , the command that is being executed is git merge <local-branch> . 因此,在获取<local-branch> ,正在执行的命令是git merge <local-branch> And running git merge will merge into the current branch . 并且运行git merge将合并到当前分支中

So when you're on <different-branch> and run git pull origin <remote-branch>:<local-branch> then you will correctly update <local-branch> to match the remote branch, but you will then also merge those changes into the current branch, <different-branch> . 因此,当您在<different-branch>运行git pull origin <remote-branch>:<local-branch>您将正确更新<local-branch>以匹配远程分支,但您还将合并这些更改为当前分支, <different-branch> That's why you see the changes of that branch in the log of the current branch; 这就是为什么你在当前分支的日志中看到该分支的变化; they were simply merged. 他们只是合并。

If you want to avoid that, as per my explanations above, just use git fetch with the refspec. 如果你想避免这种情况,按照我上面的解释,只需使用git fetch和refspec。 It will already update the local branch correctly (if it can) without affecting the current branch. 它将正确更新本地分支(如果可以),而不会影响当前分支。

You can always go low tech: 你总是可以低技术:

git fetch origin #fetches all the remote branches
git checkout <local-branch>
git merge origin/<remote-branch>

or if you practice rebase pulls 或者如果你练习rebase pulls

git rebase -i origin/<remote-branch> <local-branch>

If you want to track the remote branch as well you can use the following: 如果您还想跟踪远程分支,可以使用以下命令:

git checkout --track -b local-branch origin/remote-branch

You might need to run git fetch first if the remote branch was created after you last fetched. 如果在上次提取后创建了远程分支,则可能需要先运行git fetch

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM