I saw the command in .git/config
when I learn pull & request from this article.
fetch = +refs/pull/*/head:refs/pull/origin/*
I open my config file which is different as this fetch = +refs/heads/*:refs/remotes/origin/*
.
After I modify fetch
setting line as the article read and run those git commands:
git fetch origin
git checkout -b 1 pull/origin/1
The config
file automatic append this:
[branch "1"]
remote = origin
merge = refs/pull/1/head
Could someone can explain the means and difference settings of the fetch = ...
?
Why [branch "1"]
will be auto appended?
Thanks
There's quite a lot to unpack here. Let's start from the beginning.
The value of the fetch
setting is what's called a refspec, a special Git syntax used to map local branch references with remote ones.
It takes the form:
<source>:<destination>
In the case of fetch
, <source>
is a branch that exists on a remote repository, while <destination>
is the branch it should map to in the local repository. So, for example:
fetch: +refs/heads/master:refs/remotes/origin/master
tells Git to map the master
branch that exists in the remote repository (the source) to the origin/master
branch in the local one (the destination).
The +
character is optional and means that Git should update the destination branch even if it would require a merge commit (which shouldn't happen since you normally don't commit directly to the origin/master
branch).
Now that you know about the refspec syntax, let's talk about mapping the pull request branches from GitHub.
As you know, every pull request gets assigned a unique number within a given repository. What you may not know, however, is that this number ends up becoming the name of the branch associated to the pull request.
For example, a pull request with number 42
will get a branch reference named:
refs/pull/42
Notice how pull request branches are created in a subdirectory called pull
in the repository hosted on GitHub.
If you wanted to map every pull request branch that exists in the remote repository on GitHub to a corresponding local branch with the same name, you would say:
fetch = +refs/pull/*/head:refs/pull/origin/*
where *
is a wildcard character that matches any name. With this setting, next time you do git fetch
in your local repository, Git will download all branch references that exist in the pull
directory on GitHub and create corresponding branches in the local repository under the directory pull/origin
.
This means that for our pull request 42
, for example, the mapping becomes:
GitHub Your Repo
pull/42/head -> pull/origin/42
Note that the pull/origin/*
branches—while they do exist in your local repository—are not meant for you to commit to. They're called remote-tracking branches and are used by Git to literally keep track of a given branch that exist in a remote repository.
The documentation says it best:
Remote-tracking branches are references to the state of remote branches.
More specifically:
Think of them as bookmarks, to remind you where the branches in your remote repositories were the last time you connected to them.
You can't commit to a remote branch directly. If you want to move it forward, you must first create a local branch (i.e. one that exists only in your local repository) and associate it to the remote branch. From that point on, every time you do git pull
or git push
on that local branch, Git is going to update the corresponding remote tracking branch.
You can do that with a single command:
git checkout -b 42 pull/origin/42
This creates a local branch named 42
and associate it to the remote tracking branch pull/origin/42
, which in turn is mapped to the pull/42
branch on GitHub. Here's how it looks like:
Local Remote GitHub
42 -> pull/origin/42 -> pull/42
The relationship between local branch and remote branch is expressed in the local repository's configuration file as:
[branch "42"]
remote = origin
merge = refs/pull/42/head
The relationship between the remote branch and the branch that's physically on another machine (i.e. on GitHub) is expressed by using the refspec syntax that we looked at in the beginning.
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