- Git Version Control Cookbook
- Aske Olsson Rasmus Voss
- 885字
- 2021-12-08 12:33:51
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/*
- 數(shù)據(jù)科學(xué)實(shí)戰(zhàn)手冊(cè)(R+Python)
- Java程序設(shè)計(jì)與開發(fā)
- R語(yǔ)言經(jīng)典實(shí)例(原書第2版)
- Cocos2d-x游戲開發(fā):手把手教你Lua語(yǔ)言的編程方法
- Spring Boot+Spring Cloud+Vue+Element項(xiàng)目實(shí)戰(zhàn):手把手教你開發(fā)權(quán)限管理系統(tǒng)
- 微信小程序入門指南
- Visual Foxpro 9.0數(shù)據(jù)庫(kù)程序設(shè)計(jì)教程
- Solr Cookbook(Third Edition)
- Mastering Git
- Mastering Elasticsearch(Second Edition)
- .NET 4.5 Parallel Extensions Cookbook
- jQuery技術(shù)內(nèi)幕:深入解析jQuery架構(gòu)設(shè)計(jì)與實(shí)現(xiàn)原理
- Instant Automapper
- 基于GPU加速的計(jì)算機(jī)視覺編程:使用OpenCV和CUDA實(shí)時(shí)處理復(fù)雜圖像數(shù)據(jù)
- R語(yǔ)言實(shí)戰(zhàn)(第2版)