官术网_书友最值得收藏!

The refspec exemplified

Though the refspec isn't the first thing that comes to mind when thinking about the Git configuration, it is actually quite close. In a lot of the Git commands the refspec is used, but often implicitly, that is, the refspec is taken from the configuration file. If you don't remember setting a refspec configuration, you are probably right, but if you cloned the repository or added a remote, you'll have a section in .git/config, which looks something like the following (this is for the Jgit repository):

[remote "origin"]
 url = https://git.eclipse.org/r/jgit/jgit
 fetch = +refs/heads/*:refs/remotes/origin/*

The fetch line contains the configured refspec to fetch for this repository.

Getting ready

In this example, we'll be using the jgit repository as our server repository, but we have to make a clone of it to a bare repository so we can push it. You can't push to the checked out branch on a non-bare repository as this can overwrite the work area and index.

Create a bare repository from the jgit repository and create a new Git repository where we can play with the refspec as follows:

$ git clone --bare https://git.eclipse.org/r/jgit/jgit jgit-bare.git
$ git init refspec-tests
$ cd refspec-tests
$ git remote add origin ../jgit-bare.git

We also need to change the branch names on some of the branches to match the example for name spacing; the following will rename the stable-xxx branches to stable/xxx:

$ for br in $(git branch -a | grep "stable-"); do new=$(echo $br| sed 's/-/\//'); git branch $new $br; done

In the previous shell scripting, the $new and $br variables aren't placed in double quotes (") as good practice for shell scripting would otherwise suggest. This is okay as the variables reflect the names of the branches in the repository and branch names cannot contain spaces.

How to do it...

Let us set up our new repository to only fetch the master branch. We do this by changing the fetch line under [remote "origin"] in the configuration file (.git/config), as follows:

[remote "origin"]
 url = ../jgit-bare.git
 fetch = +refs/heads/master:refs/remotes/origin/master

Now, we will only fetch the master branch and not all the other branches when executing a git fetch, git pull, or a git remote update origin, as follows:

$ git pull
remote: Counting objects: 44033, done.
remote: Compressing objects: 100% (6927/6927), done.
remote: Total 44033 (delta 24063), reused 44033 (delta 24063)
Receiving objects: 100% (44033/44033), 9.45 MiB | 5.70 MiB/s, done.
Resolving deltas: 100% (24063/24063), done.
From ../jgit-bare
 * [new branch] master -> origin/master
From ../jgit-bare
 * [new tag] v0.10.1 -> v0.10.1
 * [new tag] v0.11.1 -> v0.11.1
 * [new tag] v0.11.3 -> v0.11.3
...
$ git branch –a
* master
 remotes/origin/master

Let's also set up a separate refspec to fetch all the stable/* branches to the local repository as follows:

[remote "origin"]
 url = ../jgit-bare.git
 fetch = +refs/heads/master:refs/remotes/origin/master
 fetch = +refs/heads/stable/*:refs/remotes/origin/stable/*

Now, fetch the branches locally, as shown in the following command:

$ git fetch
From ../jgit-bare
 * [new branch] stable/0.10 -> origin/stable/0.10
 * [new branch] stable/0.11 -> origin/stable/0.11
 * [new branch] stable/0.12 -> origin/stable/0.12
 * [new branch] stable/0.7 -> origin/stable/0.7
 * [new branch] stable/0.8 -> origin/stable/0.8
 * [new branch] stable/0.9 -> origin/stable/0.9
 * [new branch] stable/1.0 -> origin/stable/1.0
 * [new branch] stable/1.1 -> origin/stable/1.1
 * [new branch] stable/1.2 -> origin/stable/1.2
 * [new branch] stable/1.3 -> origin/stable/1.3
 * [new branch] stable/2.0 -> origin/stable/2.0
 * [new branch] stable/2.1 -> origin/stable/2.1
 * [new branch] stable/2.2 -> origin/stable/2.2
 * [new branch] stable/2.3 -> origin/stable/2.3
 * [new branch] stable/3.0 -> origin/stable/3.0
 * [new branch] stable/3.1 -> origin/stable/3.1
 * [new branch] stable/3.2 -> origin/stable/3.2

We can also set up push refspecs that specify where branches are pushed to by default. Let's create a branch called develop and create one commit, as shown in the following commands:

$ git checkout -b develop
Switched to a new branch 'develop'
$ echo "This is the developer setup, read carefully" > readme-dev.txt
$ git add readme-dev.txt
$ git commit -m "adds readme file for developers"
[develop ccb2f08] adds readme file for developers
1 file changed, 1 insertion(+)
 create mode 100644 readme-dev.txt

Now, let's create a push refspec that will send the contents of the develop branch to integration/master on origin:

[remote "origin"]
 url = ../jgit-bare.git
 fetch = +refs/heads/master:refs/remotes/origin/master
 fetch = +refs/heads/stable/*:refs/remotes/origin/stable/*
 push = refs/heads/develop:refs/remotes/origin/integration/master

Let us push our commit on develop as follows:

$ git push
Counting objects: 4, done.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 345 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To ../jgit-bare.git
 * [new branch] develop -> origin/integration/master

As the integration/master branch didn't exist on the remote side, it was created for us.

How it works...

The format of the refspec is in the form of <source>:<destination>. For a fetch refspec, this means that <source> is the source on the remote side and <destination> is local. For a push refspec, <source> is local and <destination> is remote. The refspec can be prefixed by a + to indicate that the ref pattern can be updated even though it isn't a fast-forward update. It is not possible to use partial globs in the refspec pattern, as shown in the following line:

fetch = +refs/heads/stable*:refs/remotes/origin/stable*

But it is possible to use namespacing. That's why we had to rewrite the stable-xxx branches to stable/xxx to fit as a namespace pattern:

fetch = +refs/heads/stable/*:refs/remotes/origin/stable/*
主站蜘蛛池模板: 永顺县| 邵阳县| 民和| 时尚| 雷山县| 资源县| 和龙市| 石河子市| 教育| 台江县| 明溪县| 五家渠市| 保康县| 长海县| 营山县| 蛟河市| 崇左市| 晋城| 青神县| 泾阳县| 盐亭县| 玛多县| 寿宁县| 长葛市| 确山县| 綦江县| 吴旗县| 彰化县| 卓资县| 寿宁县| 天长市| 鹰潭市| 阿鲁科尔沁旗| 聂拉木县| 西昌市| 焉耆| 英德市| 邵阳县| 阿城市| 日土县| 揭阳市|