-
Notifications
You must be signed in to change notification settings - Fork 3
/
README
216 lines (163 loc) · 7.84 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
######################################################################
GitMeta 0.05
######################################################################
NAME
GitMeta - Clone/update many Git repositories using Meta repos
SYNOPSIS
# use the command line interface
gitmeta-update gitmeta-repo-loc meta.gmf /local/git/repo/dir
DESCRIPTION
GetMeta allows you to work on dozens of git repositories hosted on
different servers, and update all of your local copies with a single
command. It defines a new syntax, called GMF (git meta format), to
configure many different remote git repository locations and provides a
script, "gitmeta-update", to create local copies of all of these repos
or updates them if they already exist. This is useful to
* periodically update your local clones while you have an Internet
connection going so they're up-to-date later when you're offline.
* move to a new system and create clones of all of your favorite git
repos with a single command.
SIMPLE EXAMPLE
For example, if you want to follow the Perl core developers on
perl5.git.perl.org and also the Log4perl project on Github, simply put
these lines into a new file "myrepos.gmf":
# myrepos.gmf
# Log4perl project
- git://github.com/mschilli/log4perl.git
# Perl core development
- git://perl5.git.perl.org/perl.git
Then, if you run
gitmeta-update myrepos.gmf ~/my-git-repos
the script will create clones of theses repos in the directory
"~/my-git-repos" (it will ask to create it if it doesn't exist yet) or
update them if they're already cloned but out-of-date:
Updating git://perl5.git.perl.org/perl.git
...
Updating git://github.com/mschilli/log4perl.git
...
If you look your local "~/my-git-repos" directory, you now have clones
of both projects, ready to use:
$ ls ~/my-git-repos
log4perl
perl
REMOTE GITMETA REPOS
Having the meta configuration "myrepos.gmf" local on your box is nice
for testing, but it's much more powerful to store it in a new repo
somewhere on the Net, e.g. "github.com/mschilli/gitmeta-test" (this
actually exists for your testing pleasure). Now, wherever you are,
simply call
gitmeta-update git://github.com/mschilli/gitmeta-test \
myrepos.gmf ~/my-git-repos
and the script will go out and fetch the git meta configuration from
github, process each entry, and create or update the corresponding
repositories in your local git repo directory ("~/my-git-repos").
ADVANCED EXAMPLE
If you want to follow all repositories of a given user (like yourself)
on Github, or you want to clone all repositories in a given directory on
your hosting service, it would be tiresome to constantly update your
.gmf file when you create new repositories or remove retired ones.
This is why GitMeta offers additional modules to automate this:
"GitMeta::Github"
Expands to all git repos of a given user on Github. Put
# All github projects of user 'mschilli'
-
type: Github
user: mschilli
in your .gmf file (note the peculiar YAML syntax requiring
indentation and an empty - line to define an array entry referencing
a hash) then "gitmeta-update" will fetch a list of all Github
projects of user "user" and add them to the processing list, before
it starts cloning/updating those repos.
"GitMeta::SshDir"
Expands to all git repos in the given directory on a server via ssh.
If you put
# All projects in directory 'projects'
# on some host via git/SSH
-
type: SshDir
host: [email protected]
dir: projects
in your .gmf, then "gitmeta-update" will fetch a list of all
repositories in the given directory on the given host and add them
to the processing list. Requires ssh keys to be set up or you'll be
prompted for your password.
"GitMeta::GMF"
You guessed it: You can refer to other .gmf files in other gitmeta
repos, which "gitmeta-update" will dutifully follow. If you put
-
type: GMF
repo: [email protected]:git/gitmeta
gmf_path: privdev.gmf
in your .gmf file, "gitmeta-update" will fetch the .gmf file
"privdev.gmf" from [email protected]:git/gitmeta, process its
directives and add the results to the processing list.
This mechanism allows you to group repos into several meta repos and
retrieve them separately or combined. For example, if you have your
private repositories in "[email protected]:git/gitmeta/priv.gmf" and
your public repos in "[email protected]:git/gitmeta/pub.gmf", you can
write a .gmf file that fetches them all at once:
# all.gmf
-
type: GMF
repo: [email protected]:git/gitmeta
gmf_path: priv.gmf
-
type: GMF
repo: [email protected]:git/gitmeta
gmf_path: pub.gmf
If you put that file in [email protected]:git/gitmeta as well, all
you need to do is run
gitmeta-update [email protected]:git gitmeta/all.gmf ~/local-dir
to get all repos created/updated.
To combine all of the above, let's say that you're following several
projects on Github.com, another set of git repositories located on a
private hosting service, the perl core development on
"perl5.git.perl.org", and another git meta definition in another gitmeta
repo. You define the following .gmf file (in YAML format):
# gitmeta.gmf
# Perl core development
- git://perl5.git.perl.org/perl.git
# All github projects of user 'mschilli'
-
type: Github
user: mschilli
# All projects in directory 'projects'
# on some host via git/SSH
-
type: SshDir
host: [email protected]
dir: projects
# Private Project via git/SSH
- [email protected]:git/private-project.git
# Another .gmf file somewhere in another gitmeta repo
-
type: GMF
repo: [email protected]:git/gitmeta
gmf_path: privdev.gmf
Note that in order to update a local repository, gitsync will fetch the
remote changes, but won't merge them into the local clone. This is
because there might be merge conflicts and when updating dozens of repos
in one quick run, you don't want to be interrupted to resolve a
conflicted merge.
So, in git parlance, "gitsync" performs a "git fetch", not a "git pull".
The updates will therefore be available in your locally defined remote
branches, and if you want to merge them into the local branches, you
need to run a "git merge" (you don't need an Internet connection for
that, so you can do this later), e.g. use
git merge origin/master
to merge the changes in the 'master' branch of the 'origin' remote into
the local branch you're currently on (presumably 'master' as well).
TROUBLESHOOTING
Make sure that 'git' is in your PATH.
FIRST PUBLICATION
This module was first published in the German edition of Linux Magazin
in August 2010:
http://www.linux-magazin.de/Heft-Abo/Ausgaben/2010/08/Ueberall-Projekte
An English translation is available here:
http://www.linux-magazine.com/w3/issue/118/050-055_perl.pdf
LEGALESE
Copyright 2010-2011 by Mike Schilli, all rights reserved. This program
is free software, you can redistribute it and/or modify it under the
same terms as Perl itself.
AUTHOR
2010, Mike Schilli <[email protected]>