remote: fix "update [group...]"
The rewrite in C inadvertently broke updating with remote groups: when you pass parameters to "git remote update", it used to look up "remotes.<group>" for every parameter, and interpret the value as a list of remotes to update. Also, no parameter, or a single parameter "default" should update all remotes that have not been marked with "skipDefaultUpdate". Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Johannes Schindelin committed
Mar 4, 2008 at 11:23 UTC
84521ed6f2ccfd8dfe001806f83bb28e6a8934be
2 files changed
+142
-9
builtin-remote.c
+50
-9
@@ -474,24 +474,65 @@ cleanup_states:
474
return result;
475
}
476
477
-static int update_one(struct remote *remote, void *priv)
477
+static int get_one_remote_for_update(struct remote *remote, void *priv)
478
{
479
+ struct path_list *list = priv;
480
if (!remote->skip_default_update)
480
- return fetch_remote(remote->name);
481
+ path_list_append(xstrdup(remote->name), list);
482
+ return 0;
483
+}
484
+
485
+struct remote_group {
486
+ const char *name;
487
+ struct path_list *list;
488
+} remote_group;
489
+
490
+static int get_remote_group(const char *key, const char *value)
491
+{
492
+ if (!prefixcmp(key, "remotes.") &&
493
+ !strcmp(key + 8, remote_group.name)) {
494
+ /* split list by white space */
495
+ int space = strcspn(value, " \t\n");
496
+ while (*value) {
497
+ if (space > 1)
498
+ path_list_append(xstrndup(value, space),
499
+ remote_group.list);
500
+ value += space + (value[space] != '\0');
501
+ space = strcspn(value, " \t\n");
502
+ }
503
+ }
504
+
505
return 0;
506
}
507
508
static int update(int argc, const char **argv)
509
{
486
- int i;
510
+ int i, result = 0;
511
+ struct path_list list = { NULL, 0, 0, 0 };
512
+ static const char *default_argv[] = { NULL, "default", NULL };
513
488
- if (argc < 2)
489
- return for_each_remote(update_one, NULL);
514
+ if (argc < 2) {
515
+ argc = 2;
516
+ argv = default_argv;
517
+ }
518
491
- for (i = 1; i < argc; i++)
492
- if (fetch_remote(argv[i]))
493
- return 1;
494
- return 0;
519
+ remote_group.list = &list;
520
+ for (i = 1; i < argc; i++) {
521
+ remote_group.name = argv[i];
522
+ result = git_config(get_remote_group);
523
+ }
524
+
525
+ if (!result && !list.nr && argc == 2 && !strcmp(argv[1], "default"))
526
+ result = for_each_remote(get_one_remote_for_update, &list);
527
+
528
+ for (i = 0; i < list.nr; i++)
529
+ result |= fetch_remote(list.items[i].path);
530
+
531
+ /* all names were strdup()ed or strndup()ed */
532
+ list.strdup_paths = 1;
533
+ path_list_clear(&list, 0);
534
+
535
+ return result;
536
}
537
538
static int get_one_entry(struct remote *remote, void *priv)
t/t5505-remote.sh
+92
@@ -10,10 +10,12 @@ setup_repository () {
10
git init &&
11
>file &&
12
git add file &&
13
+ test_tick &&
14
git commit -m "Initial" &&
15
git checkout -b side &&
16
>elif &&
17
git add elif &&
18
+ test_tick &&
19
git commit -m "Second" &&
20
git checkout master
21
)
@@ -113,6 +115,7 @@ test_expect_success 'show' '
115
git branch -d -r origin/master &&
116
(cd ../one &&
117
echo 1 > file &&
118
+ test_tick &&
119
git commit -m update file) &&
120
git remote show origin > output &&
121
git diff expect output)
@@ -144,4 +147,93 @@ test_expect_success 'add --mirror && prune' '
147
git rev-parse --verify refs/heads/side)
148
'
149
150
+cat > one/expect << EOF
151
+ apis/master
152
+ apis/side
153
+ drosophila/another
154
+ drosophila/master
155
+ drosophila/side
156
+EOF
157
+
158
+test_expect_success 'update' '
159
+
160
+ (cd one &&
161
+ git remote add drosophila ../two &&
162
+ git remote add apis ../mirror &&
163
+ git remote update &&
164
+ git branch -r > output &&
165
+ git diff expect output)
166
+
167
+'
168
+
169
+cat > one/expect << EOF
170
+ drosophila/another
171
+ drosophila/master
172
+ drosophila/side
173
+ manduca/master
174
+ manduca/side
175
+ megaloprepus/master
176
+ megaloprepus/side
177
+EOF
178
+
179
+test_expect_success 'update with arguments' '
180
+
181
+ (cd one &&
182
+ for b in $(git branch -r)
183
+ do
184
+ git branch -r -d $b || break
185
+ done &&
186
+ git remote add manduca ../mirror &&
187
+ git remote add megaloprepus ../mirror &&
188
+ git config remotes.phobaeticus "drosophila megaloprepus" &&
189
+ git config remotes.titanus manduca &&
190
+ git remote update phobaeticus titanus &&
191
+ git branch -r > output &&
192
+ git diff expect output)
193
+
194
+'
195
+
196
+cat > one/expect << EOF
197
+ apis/master
198
+ apis/side
199
+ manduca/master
200
+ manduca/side
201
+ megaloprepus/master
202
+ megaloprepus/side
203
+EOF
204
+
205
+test_expect_success 'update default' '
206
+
207
+ (cd one &&
208
+ for b in $(git branch -r)
209
+ do
210
+ git branch -r -d $b || break
211
+ done &&
212
+ git config remote.drosophila.skipDefaultUpdate true &&
213
+ git remote update default &&
214
+ git branch -r > output &&
215
+ git diff expect output)
216
+
217
+'
218
+
219
+cat > one/expect << EOF
220
+ drosophila/another
221
+ drosophila/master
222
+ drosophila/side
223
+EOF
224
+
225
+test_expect_success 'update default (overridden, with funny whitespace)' '
226
+
227
+ (cd one &&
228
+ for b in $(git branch -r)
229
+ do
230
+ git branch -r -d $b || break
231
+ done &&
232
+ git config remotes.default "$(printf "\t drosophila \n")" &&
233
+ git remote update default &&
234
+ git branch -r > output &&
235
+ git diff expect output)
236
+
237
+'
238
+
239
test_done