@matheusbsbs / matheus-bagliano / commits / 84bb2dfd9f
Fork 0

Add a remote.*.mirror configuration option

This patch adds a remote.*.mirror configuration option that, when set, automatically puts git-push in --mirror mode for that remote. Furthermore, the option is set automatically by `git remote add --mirror'. The code in remote.c to parse remote.*.skipdefaultupdate had a subtle problem: a comment in the code indicated that special care was needed for boolean options, but this care was not used in parsing the option. Since I was touching related code, I did this fix too. [jc: and I further fixed up the "ignore boolean" code.] Signed-off-by: Paolo Bonzini <bonzini@gnu.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Paolo Bonzini committed Apr 17, 2008 at 13:17 UTC 84bb2dfd9f4873c9ca19537efe62219b09ec03bf
8 files changed +104 -36
Documentation/config.txt
+4
@@ -910,6 +910,10 @@ remote.<name>.push::
910 The default set of "refspec" for linkgit:git-push[1]. See
911 linkgit:git-push[1].
912
913 +remote.<name>.mirror::
914 + If true, pushing to this remote will automatically behave
915 + as if the `\--mirror` option was given on the command line.
916 +
917 remote.<name>.skipDefaultUpdate::
918 If true, this remote will be skipped by default when updating
919 using the update subcommand of linkgit:git-remote[1].
Documentation/git-push.txt
+3 -1
@@ -69,7 +69,9 @@ the remote repository.
69 be mirrored to the remote repository. Newly created local
70 refs will be pushed to the remote end, locally updated refs
71 will be force updated on the remote end, and deleted refs
72 - will be removed from the remote end.
72 + will be removed from the remote end. This is the default
73 + if the configuration option `remote.<remote>.mirror` is
74 + set.
75
76 \--dry-run::
77 Do everything except actually send the updates.
Documentation/git-remote.txt
+4 -2
@@ -47,9 +47,11 @@ With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
47 up to point at remote's `<master>` branch instead of whatever
48 branch the `HEAD` at the remote repository actually points at.
49 +
50 -In mirror mode, enabled with `--mirror`, the refs will not be stored
50 +In mirror mode, enabled with `\--mirror`, the refs will not be stored
51 in the 'refs/remotes/' namespace, but in 'refs/heads/'. This option
52 -only makes sense in bare repositories.
52 +only makes sense in bare repositories. If a remote uses mirror
53 +mode, furthermore, `git push` will always behave as if `\--mirror`
54 +was passed.
55
56 'rm'::
57
builtin-push.c
+16 -8
@@ -56,6 +56,17 @@ static int do_push(const char *repo, int flags)
56 if (!remote)
57 die("bad repository '%s'", repo);
58
59 + if (remote->mirror)
60 + flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
61 +
62 + if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
63 + return -1;
64 +
65 + if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
66 + (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
67 + return error("--all and --mirror are incompatible");
68 + }
69 +
70 if (!refspec
71 && !(flags & TRANSPORT_PUSH_ALL)
72 && remote->push_refspec_nr) {
@@ -95,6 +106,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
106 int dry_run = 0;
107 int force = 0;
108 int tags = 0;
109 + int rc;
110 const char *repo = NULL; /* default repository */
111
112 struct option options[] = {
@@ -130,14 +142,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
142 repo = argv[0];
143 set_refspecs(argv + 1, argc - 1);
144 }
133 - if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
134 - usage_with_options(push_usage, options);
145
136 - if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
137 - (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
138 - error("--all and --mirror are incompatible");
146 + rc = do_push(repo, flags);
147 + if (rc == -1)
148 usage_with_options(push_usage, options);
140 - }
141 -
142 - return do_push(repo, flags);
149 + else
150 + return rc;
151 }
builtin-remote.c
+7
@@ -117,6 +117,13 @@ static int add(int argc, const char **argv)
117 return 1;
118 }
119
120 + if (mirror) {
121 + strbuf_reset(&buf);
122 + strbuf_addf(&buf, "remote.%s.mirror", name);
123 + if (git_config_set(buf.buf, "yes"))
124 + return 1;
125 + }
126 +
127 if (fetch && fetch_remote(name))
128 return 1;
129
remote.c
+29 -24
@@ -337,44 +337,49 @@ static int handle_config(const char *key, const char *value)
337 return 0;
338 }
339 remote = make_remote(name, subkey - name);
340 - if (!value) {
341 - /* if we ever have a boolean variable, e.g. "remote.*.disabled"
342 - * [remote "frotz"]
343 - * disabled
344 - * is a valid way to set it to true; we get NULL in value so
345 - * we need to handle it here.
346 - *
347 - * if (!strcmp(subkey, ".disabled")) {
348 - * val = git_config_bool(key, value);
349 - * return 0;
350 - * } else
351 - *
352 - */
353 - return 0; /* ignore unknown booleans */
354 - }
355 - if (!strcmp(subkey, ".url")) {
356 - add_url(remote, xstrdup(value));
340 + if (!strcmp(subkey, ".mirror"))
341 + remote->mirror = git_config_bool(key, value);
342 + else if (!strcmp(subkey, ".skipdefaultupdate"))
343 + remote->skip_default_update = git_config_bool(key, value);
344 +
345 + else if (!strcmp(subkey, ".url")) {
346 + const char *v;
347 + if (git_config_string(&v, key, value))
348 + return -1;
349 + add_url(remote, v);
350 } else if (!strcmp(subkey, ".push")) {
358 - add_push_refspec(remote, xstrdup(value));
351 + const char *v;
352 + if (git_config_string(&v, key, value))
353 + return -1;
354 + add_push_refspec(remote, v);
355 } else if (!strcmp(subkey, ".fetch")) {
360 - add_fetch_refspec(remote, xstrdup(value));
356 + const char *v;
357 + if (git_config_string(&v, key, value))
358 + return -1;
359 + add_fetch_refspec(remote, v);
360 } else if (!strcmp(subkey, ".receivepack")) {
361 + const char *v;
362 + if (git_config_string(&v, key, value))
363 + return -1;
364 if (!remote->receivepack)
363 - remote->receivepack = xstrdup(value);
365 + remote->receivepack = v;
366 else
367 error("more than one receivepack given, using the first");
368 } else if (!strcmp(subkey, ".uploadpack")) {
369 + const char *v;
370 + if (git_config_string(&v, key, value))
371 + return -1;
372 if (!remote->uploadpack)
368 - remote->uploadpack = xstrdup(value);
373 + remote->uploadpack = v;
374 else
375 error("more than one uploadpack given, using the first");
376 } else if (!strcmp(subkey, ".tagopt")) {
377 if (!strcmp(value, "--no-tags"))
378 remote->fetch_tags = -1;
379 } else if (!strcmp(subkey, ".proxy")) {
375 - remote->http_proxy = xstrdup(value);
376 - } else if (!strcmp(subkey, ".skipdefaultupdate"))
377 - remote->skip_default_update = 1;
380 + return git_config_string((const char **)&remote->http_proxy,
381 + key, value);
382 + }
383 return 0;
384 }
385
remote.h
+1
@@ -26,6 +26,7 @@ struct remote {
26 */
27 int fetch_tags;
28 int skip_default_update;
29 + int mirror;
30
31 const char *receivepack;
32 const char *uploadpack;
t/t5517-push-mirror.sh
+40 -1
@@ -25,7 +25,7 @@ mk_repo_pair () {
25 (
26 cd master &&
27 git init &&
28 - git config remote.up.url ../mirror
28 + git remote add $1 up ../mirror
29 )
30 }
31
@@ -225,4 +225,43 @@ test_expect_success 'push mirror adds, updates and removes tags together' '
225
226 '
227
228 +test_expect_success 'remote.foo.mirror adds and removes branches' '
229 +
230 + mk_repo_pair --mirror &&
231 + (
232 + cd master &&
233 + echo one >foo && git add foo && git commit -m one &&
234 + git branch keep master &&
235 + git branch remove master &&
236 + git push up &&
237 + git branch -D remove
238 + git push up
239 + ) &&
240 + (
241 + cd mirror &&
242 + git show-ref -s --verify refs/heads/keep &&
243 + invert git show-ref -s --verify refs/heads/remove
244 + )
245 +
246 +'
247 +
248 +test_expect_success 'remote.foo.mirror=no has no effect' '
249 +
250 + mk_repo_pair &&
251 + (
252 + cd master &&
253 + echo one >foo && git add foo && git commit -m one &&
254 + git config --add remote.up.mirror no &&
255 + git branch keep master &&
256 + git push --mirror up &&
257 + git branch -D keep &&
258 + git push up
259 + ) &&
260 + (
261 + cd mirror &&
262 + git show-ref -s --verify refs/heads/keep
263 + )
264 +
265 +'
266 +
267 test_done