Is it correct that git pull
operates on branches?
In a repository, when running git pull
on different branches, will it do different things?
When not specifying any argument after git pull
,
origin
? Thanks.
Git already only pulls the current branch. If you have branch set up as a tracking branch, you do not need to specify the remote branch. git branch --set-upstream localbranch reponame/remotebranch will set up the tracking relationship. You then issue git pull [--rebase] and only that branch will be updated.
The "pull" command is used to download and integrate remote changes. The target (which branch the data should be integrated into) is always the currently checked out HEAD branch. By default, pull uses a merge operation, but it can also be configured to use rebase instead.
git pull origin master will pull changes from the origin remote, master branch and merge them to the local checked-out branch. git pull origin/master will pull changes from the locally stored branch origin/master and merge that to the local checked-out branch.
Also, git pull --all will update your local tracking branches, but depending on your local commits and how the 'merge' configure option is set it might create a merge commit, fast-forward or fail.
First, don't use git pull
. This command is never needed, and you will be better off if you avoid it until you are a Git-master. But if you insist on using it, because it's convenient—and it is convenient—remember that it just runs git fetch
first, and then, depending on various things, usually runs git merge
second.
Is it correct that
git pull
operates on branches?
Yes—but it's better to think of git pull
as running two Git commands, because that's what git pull
does.
In a repository, when running
git pull
on different branches, will it do different things?
It's not clear what you mean by "on different branches" and "do different things". You might mean:
git checkout branch1; git pull; git checkout branch2; git pull
or:
git checkout branch1; git pull origin branch2 branch3
and the latter is very different. (The short answer to "when to use this form" is never. The long answer is "Not yet: first learn about octopus merges, then re-read the documentation. Then, once you are a Git master, you will realize that you probably should never do an octopus merge directly with git pull
anyway, but at least now you know when it's safe to use git pull
at all.")
The former—running git pull
while on branch1
, then running git pull
again while on branch2
—just goes through the four steps listed below twice, once on branch1
, and then again on branch2
.
When not specifying any argument after
git pull
,
- does it only pull to the current branch from a same-name branch in the remote
origin
?- does it do anything for any other branch?
Let's dispose of the second part first, because that's easy: "no, as long as you are not talking about remote-tracking branches."
Next, we need to note an assumption: that the remote is named origin
. You can have more than one remote, and if you do, obviously at most one of them is named origin
. Even if you have only one remote, you can call it whatever you want. So the idea that the remote is origin
is a bit shaky to start with.
(Usually, though, it is origin
. Most people have just one remote, and it's named origin
, so there's only the remote, not "one of seven different remotes to pick from" or whatever.)
When you run git pull
with no arguments, Git will:
Identify the current branch's upstream. For instance, the upstream of branch1
is probably origin/branch1
. Note that there are two parts to this upstream:
origin
.branch1
.
To make a remote-tracking branch, Git effectively pastes these two parts together, which is why we see it as origin/branch1
. But there are still the two parts.
There is no requirement that the upstream branch name match the local branch name. It's just a good idea.
(There are times when you must violate this "good idea", when you have two or more remotes. Suppose, for instance, that remote fred
has a branch named develop
and different remote susan
has a branch named develop
. You now have both fred/develop
and susan/develop
in your repository. You want to do something with both of those; what branch names will you use? Maybe you can call one fred-develop
and the other susan-develop
. But now the upstream name doesn't match the local name any more: the upstream for fred-develop
is fred/develop
, not fred/fred-develop
.)
Split up this upstream into its two parts: remote, and name-of-branch as seen on the remote.
Run git fetch
with several arguments. The git fetch
step will call up another Git using the URL for the remote. Once your Git has the foreign Git on the Internet-phone, your Git will obtain any new commits they have on their branch, that you do not have anywhere yet.
Let's say the current branch is branch1
and the upstream is origin/branch1
. If your own Git is not too ancient (is at least version 1.8.4), this updates your origin/branch1
. (If your Git is older than that, the arguments that git pull
provides prevent your remote-tracking branch from being updated. This is not such a good situation, and you should update your Git version. It all works, it's just hard to explain. If you avoid git pull
entirely, the weird way that Git 1.8.3 and earlier does this no longer matters, because git fetch origin
updates all your remote-tracking branches, even in these ancient versions of Git.)
Now that git fetch
has those new commits in your repository, under your origin/branch1
remote-tracking branch, you're all set. A later git fetch
will finish very quickly, because you now have those new commits.
Run git merge
, or some other Git command, with several arguments.
It's this last step—usually git merge
—that affects your branch. When git merge
succeeds, it often makes a new commit. As with all normal Git commands, making a new commit adds the commit to your current branch. When git merge
does a fast-forward instead of making a new commit, that also affects your current branch.
Hence, we can say this: When git pull
runs git merge
, the git merge
step affects your current branch in the same way that git merge
always affects your current branch.
You can ask git pull
to run a different second command, though. Specifically, you can set things up so that git pull
runs git rebase
instead of git merge
. To figure out what that does, we must look at what git rebase
does, and that's more complicated—but in the end, it also affects your current branch, just like git merge
.1 Hence we can also say: When git pull
runs git rebase
, the git rebase
step affects your current branch in the same way that git rebase
always1 affects your current branch.
When we put all these facts together, we end up seeing that git pull
's second command is what affects the current branch. And, it only affects the current branch, because git merge
and git rebase
work only on the current branch.
(The first command—the git fetch
step—affects remote-tracking branches. But since those are just your Git's way of remembering what it got from a foreign Git, the last time it got things from that foreign Git, that's not very important.)
Last, don't use git pull
. Use git fetch
, followed by whichever command you choose based on what came in with the fetch
: git merge
or git rebase
.
1There is a way to make git rebase
affect a different branch, but—fortunately—git pull
doesn't use it. (You probably shouldn't either, unless you know what you are doing. It is pretty trivial: it literally just does a git checkout
of another branch-name first, then proceeds as if you had done this yourself, and had not specified the extra branch-name.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With