Skip to content

Commit 142e014

Browse files
author
Bernard `Guyzmo` Pratz
committed
🔖 Added article on git remote add set-url
1 parent 16c57d8 commit 142e014

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
type: post
3+
categories: code
4+
tags: [ code, python, tip, git ]
5+
title: "A tip for git, discover multiple URL remote"
6+
date: 2016-12-30T20:28:42+02:00
7+
summary: "While I was developing git-repo I stumbled upon a little known feature that
8+
has been introduced in git 2.7: the possibility to have a remote with multiple
9+
URLs. After the break I'll tell you what this is about…"
10+
lang: english
11+
logo: /img/gitlogo-black.png
12+
header_background: /img/gitdark-bg.png
13+
tweet: 814917694436868097
14+
aliases: /code/on/git:_how_to_setup_one_url_with_multiple_remotes
15+
---
16+
17+
While I was developing [git-repo] I stumbled upon a little known feature that
18+
has been introduced in git 2.7: the possibility to have a remote with multiple
19+
URLs.
20+
21+
# Why would I need that?
22+
23+
What's great with git is that it's a decentralized version control system. What that
24+
means is that, even if most of the time you'll work with only one remote repository (in a
25+
very centralised way), sometimes you'll be happy to be able to have many remotes to
26+
work with.
27+
28+
An use case I had in a former work setup was to have an internal repository (that will
29+
feature the open code, as well as some custom features in branches for our paying customers),
30+
an external repository (because opensource is ♥), a production repository (for deployment
31+
purposes, but it's not anymore a use case thanks to CI integrations that [does automatic
32+
deployment](https://about.gitlab.com/gitlab-ci/)).
33+
34+
Another use case, which was the one I ran into when developing [git-repo], is working
35+
with several repository services at once. You've got gitlab, github, bitbucket, gogs…
36+
And when you're working with all of them you got to create a remote for each, and
37+
push your changesets to each of them everytime:
38+
39+
``` bash
40+
git remote add github https://github.com/guyzmo/git-repo
41+
git remote add gitlab https://gitlab.com/guyzmo/git-repo
42+
git remote add bitbucket https://bitbucket.org/guyzmo/git-repo
43+
git remote add home https://gitlab.myserver.com/guyzmo/git-repo
44+
git remote add gogs https://gogs.myserver.com/guyzmo/git-repo
45+
```
46+
47+
it's a bit boring and redundant to do so, but at least that's a task you do only
48+
once (and you can do it faster with [a great editor](http://vim.org) on the `.git/config` file).
49+
50+
But each time you want to push to your projects, you got to push to each of them:
51+
52+
``` bash
53+
git push github master
54+
git push gitlab master
55+
git push bitbucket master
56+
git push home master
57+
git push gogs master
58+
```
59+
60+
And as you're as lazy as anybody, you'll end up only pushing to one, maybe two
61+
of the remotes, usually `github` and `home`…
62+
63+
# The multiple URL remote comes to help
64+
65+
…But you don't really have to! You can work with multiple remotes nicely, by creating
66+
a new remote that contains all the other remotes URLs:
67+
68+
``` bash
69+
git remote add all https://github.com/guyzmo/git-repo
70+
git remote add all set-url --add https://gitlab.com/guyzmo/git-repo
71+
git remote add all set-url --add https://bitbucket.org/guyzmo/git-repo
72+
git remote add all set-url --add https://gitlab.myserver.com/guyzmo/git-repo
73+
git remote add all set-url --add https://gogs.myserver.com/guyzmo/git-repo
74+
```
75+
76+
then, when it's time to push your code, you just need to run:
77+
78+
``` bash
79+
git push all master
80+
```
81+
82+
The only drawback is that it makes little sense to pull from a remote with multiple URL,
83+
and when looking at your index, you'll see that the `all/master` ref is updated, but
84+
not the other refs (`github/master`, `gitlab/master`…). So if you want to keep all the
85+
remotes updated you've got to run:
86+
87+
``` bash
88+
git fetch --all
89+
```
90+
91+
which will sync back all the refs that have been updated when you pushed through the all
92+
remote. So instead of 4/5 or more commands to repeat, you end up with only two commands.
93+
94+
And you can make it simpler using an alias such as:
95+
96+
``` bash
97+
git config alias.pushall "!pushall() { git push all $* && git fetch --all ; }; pushall"
98+
```
99+
100+
# And how is it being used in [git-repo]?
101+
102+
When I worked on [git-repo], I figured that's a great feature to take advantage of. So
103+
I've implemented a customized version of the `git remote add`, that's being used under
104+
the hood by `git <target> create`, `git <target> clone`, git <target> fork`…
105+
106+
This is the `git <target> add` command, and it works as follows:
107+
108+
``` bash
109+
git hub add <user>/<repo> [<name>] [--tracking=<branch>] [-a]
110+
```
111+
112+
there you can add to the list of remotes the repository as identified by the repo slug
113+
(`<user>/<repo>`, a full URL to the repo works as well, as long as it matches the targetted
114+
service provider). Then you can give a custom name to the repo and specify the branch you
115+
want to track (with `--tracking`). The `-a/--alone` parameter is to prevent from adding
116+
the URL to the `all` remote.
117+
118+
``` bash
119+
% git hub add foobar/project foobar --tracking=devel
120+
Successfully added `foobar/project` as remote named `foobar`
121+
% git remote
122+
all
123+
foobar
124+
github
125+
% git remote get-url --all all
126+
git@github.com:guyzmo/clait
127+
git@github.com:foobar/project
128+
```
129+
130+
As a nice to have idea I'd like to implement would be to make the `add` command so it is possible
131+
to handle `remote add` with just any repository, something that's like:
132+
133+
``` bash
134+
% git <target> add user@10.0.0.1:./repository.git local_machine --tracking=devel
135+
Successfully added `user@10.0.0.1:./repository.git` as remote named `local_machine`
136+
```
137+
138+
At the time of writing this article, the feature [has been implemented](https://github.com/guyzmo/git-repo/compare/devel...features/repo_add_cmd?expand=1),
139+
and will be merged to one of the future versions of [git-repo].
140+
141+
[git-repo]:https://github.com/guyzmo/git-repo

0 commit comments

Comments
 (0)