Skip to content

Commit dc484f2

Browse files
committed
Merge branch 'pb/remote-mirror-config'
* pb/remote-mirror-config: Add a remote.*.mirror configuration option
2 parents 2b3e60c + 84bb2df commit dc484f2

File tree

8 files changed

+104
-36
lines changed

8 files changed

+104
-36
lines changed

Documentation/config.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -921,6 +921,10 @@ remote.<name>.push::
921921
The default set of "refspec" for linkgit:git-push[1]. See
922922
linkgit:git-push[1].
923923

924+
remote.<name>.mirror::
925+
If true, pushing to this remote will automatically behave
926+
as if the `\--mirror` option was given on the command line.
927+
924928
remote.<name>.skipDefaultUpdate::
925929
If true, this remote will be skipped by default when updating
926930
using the update subcommand of linkgit:git-remote[1].

Documentation/git-push.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ the remote repository.
7070
be mirrored to the remote repository. Newly created local
7171
refs will be pushed to the remote end, locally updated refs
7272
will be force updated on the remote end, and deleted refs
73-
will be removed from the remote end.
73+
will be removed from the remote end. This is the default
74+
if the configuration option `remote.<remote>.mirror` is
75+
set.
7476

7577
\--dry-run::
7678
Do everything except actually send the updates.

Documentation/git-remote.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,11 @@ With `-m <master>` option, `$GIT_DIR/remotes/<name>/HEAD` is set
4747
up to point at remote's `<master>` branch instead of whatever
4848
branch the `HEAD` at the remote repository actually points at.
4949
+
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
5151
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.
5355

5456
'rm'::
5557

builtin-push.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,17 @@ static int do_push(const char *repo, int flags)
5656
if (!remote)
5757
die("bad repository '%s'", repo);
5858

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+
5970
if (!refspec
6071
&& !(flags & TRANSPORT_PUSH_ALL)
6172
&& remote->push_refspec_nr) {
@@ -95,6 +106,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
95106
int dry_run = 0;
96107
int force = 0;
97108
int tags = 0;
109+
int rc;
98110
const char *repo = NULL; /* default repository */
99111

100112
struct option options[] = {
@@ -130,14 +142,10 @@ int cmd_push(int argc, const char **argv, const char *prefix)
130142
repo = argv[0];
131143
set_refspecs(argv + 1, argc - 1);
132144
}
133-
if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
134-
usage_with_options(push_usage, options);
135145

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)
139148
usage_with_options(push_usage, options);
140-
}
141-
142-
return do_push(repo, flags);
149+
else
150+
return rc;
143151
}

builtin-remote.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,13 @@ static int add(int argc, const char **argv)
118118
return 1;
119119
}
120120

121+
if (mirror) {
122+
strbuf_reset(&buf);
123+
strbuf_addf(&buf, "remote.%s.mirror", name);
124+
if (git_config_set(buf.buf, "yes"))
125+
return 1;
126+
}
127+
121128
if (fetch && fetch_remote(name))
122129
return 1;
123130

remote.c

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -337,44 +337,49 @@ static int handle_config(const char *key, const char *value)
337337
return 0;
338338
}
339339
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);
357350
} 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);
359355
} 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);
361360
} else if (!strcmp(subkey, ".receivepack")) {
361+
const char *v;
362+
if (git_config_string(&v, key, value))
363+
return -1;
362364
if (!remote->receivepack)
363-
remote->receivepack = xstrdup(value);
365+
remote->receivepack = v;
364366
else
365367
error("more than one receivepack given, using the first");
366368
} else if (!strcmp(subkey, ".uploadpack")) {
369+
const char *v;
370+
if (git_config_string(&v, key, value))
371+
return -1;
367372
if (!remote->uploadpack)
368-
remote->uploadpack = xstrdup(value);
373+
remote->uploadpack = v;
369374
else
370375
error("more than one uploadpack given, using the first");
371376
} else if (!strcmp(subkey, ".tagopt")) {
372377
if (!strcmp(value, "--no-tags"))
373378
remote->fetch_tags = -1;
374379
} 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+
}
378383
return 0;
379384
}
380385

remote.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct remote {
2626
*/
2727
int fetch_tags;
2828
int skip_default_update;
29+
int mirror;
2930

3031
const char *receivepack;
3132
const char *uploadpack;

t/t5517-push-mirror.sh

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ mk_repo_pair () {
2525
(
2626
cd master &&
2727
git init &&
28-
git config remote.up.url ../mirror
28+
git remote add $1 up ../mirror
2929
)
3030
}
3131

@@ -225,4 +225,43 @@ test_expect_success 'push mirror adds, updates and removes tags together' '
225225
226226
'
227227

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+
228267
test_done

0 commit comments

Comments
 (0)