The default set of "refspec" for linkgit:git-push[1]. See
linkgit:git-push[1].
+remote.<name>.mirror::
+ If true, pushing to this remote will automatically behave
+ as if the `\--mirror` option was given on the command line.
+
remote.<name>.skipDefaultUpdate::
If true, this remote will be skipped by default when updating
using the update subcommand of linkgit:git-remote[1].
be mirrored to the remote repository. Newly created local
refs will be pushed to the remote end, locally updated refs
will be force updated on the remote end, and deleted refs
- will be removed from the remote end.
+ will be removed from the remote end. This is the default
+ if the configuration option `remote.<remote>.mirror` is
+ set.
\--dry-run::
Do everything except actually send the updates.
up to point at remote's `<master>` branch instead of whatever
branch the `HEAD` at the remote repository actually points at.
+
-In mirror mode, enabled with `--mirror`, the refs will not be stored
+In mirror mode, enabled with `\--mirror`, the refs will not be stored
in the 'refs/remotes/' namespace, but in 'refs/heads/'. This option
-only makes sense in bare repositories.
+only makes sense in bare repositories. If a remote uses mirror
+mode, furthermore, `git push` will always behave as if `\--mirror`
+was passed.
'rm'::
if (!remote)
die("bad repository '%s'", repo);
+ if (remote->mirror)
+ flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
+
+ if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
+ return -1;
+
+ if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
+ (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
+ return error("--all and --mirror are incompatible");
+ }
+
if (!refspec
&& !(flags & TRANSPORT_PUSH_ALL)
&& remote->push_refspec_nr) {
int dry_run = 0;
int force = 0;
int tags = 0;
+ int rc;
const char *repo = NULL; /* default repository */
struct option options[] = {
repo = argv[0];
set_refspecs(argv + 1, argc - 1);
}
- if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
- usage_with_options(push_usage, options);
- if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
- (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
- error("--all and --mirror are incompatible");
+ rc = do_push(repo, flags);
+ if (rc == -1)
usage_with_options(push_usage, options);
- }
-
- return do_push(repo, flags);
+ else
+ return rc;
}
return 1;
}
+ if (mirror) {
+ strbuf_reset(&buf);
+ strbuf_addf(&buf, "remote.%s.mirror", name);
+ if (git_config_set(buf.buf, "yes"))
+ return 1;
+ }
+
if (fetch && fetch_remote(name))
return 1;
return 0;
}
remote = make_remote(name, subkey - name);
- if (!value) {
- /* if we ever have a boolean variable, e.g. "remote.*.disabled"
- * [remote "frotz"]
- * disabled
- * is a valid way to set it to true; we get NULL in value so
- * we need to handle it here.
- *
- * if (!strcmp(subkey, ".disabled")) {
- * val = git_config_bool(key, value);
- * return 0;
- * } else
- *
- */
- return 0; /* ignore unknown booleans */
- }
- if (!strcmp(subkey, ".url")) {
- add_url(remote, xstrdup(value));
+ if (!strcmp(subkey, ".mirror"))
+ remote->mirror = git_config_bool(key, value);
+ else if (!strcmp(subkey, ".skipdefaultupdate"))
+ remote->skip_default_update = git_config_bool(key, value);
+
+ else if (!strcmp(subkey, ".url")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_url(remote, v);
} else if (!strcmp(subkey, ".push")) {
- add_push_refspec(remote, xstrdup(value));
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_push_refspec(remote, v);
} else if (!strcmp(subkey, ".fetch")) {
- add_fetch_refspec(remote, xstrdup(value));
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
+ add_fetch_refspec(remote, v);
} else if (!strcmp(subkey, ".receivepack")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
if (!remote->receivepack)
- remote->receivepack = xstrdup(value);
+ remote->receivepack = v;
else
error("more than one receivepack given, using the first");
} else if (!strcmp(subkey, ".uploadpack")) {
+ const char *v;
+ if (git_config_string(&v, key, value))
+ return -1;
if (!remote->uploadpack)
- remote->uploadpack = xstrdup(value);
+ remote->uploadpack = v;
else
error("more than one uploadpack given, using the first");
} else if (!strcmp(subkey, ".tagopt")) {
if (!strcmp(value, "--no-tags"))
remote->fetch_tags = -1;
} else if (!strcmp(subkey, ".proxy")) {
- remote->http_proxy = xstrdup(value);
- } else if (!strcmp(subkey, ".skipdefaultupdate"))
- remote->skip_default_update = 1;
+ return git_config_string((const char **)&remote->http_proxy,
+ key, value);
+ }
return 0;
}
*/
int fetch_tags;
int skip_default_update;
+ int mirror;
const char *receivepack;
const char *uploadpack;
(
cd master &&
git init &&
- git config remote.up.url ../mirror
+ git remote add $1 up ../mirror
)
}
'
+test_expect_success 'remote.foo.mirror adds and removes branches' '
+
+ mk_repo_pair --mirror &&
+ (
+ cd master &&
+ echo one >foo && git add foo && git commit -m one &&
+ git branch keep master &&
+ git branch remove master &&
+ git push up &&
+ git branch -D remove
+ git push up
+ ) &&
+ (
+ cd mirror &&
+ git show-ref -s --verify refs/heads/keep &&
+ invert git show-ref -s --verify refs/heads/remove
+ )
+
+'
+
+test_expect_success 'remote.foo.mirror=no has no effect' '
+
+ mk_repo_pair &&
+ (
+ cd master &&
+ echo one >foo && git add foo && git commit -m one &&
+ git config --add remote.up.mirror no &&
+ git branch keep master &&
+ git push --mirror up &&
+ git branch -D keep &&
+ git push up
+ ) &&
+ (
+ cd mirror &&
+ git show-ref -s --verify refs/heads/keep
+ )
+
+'
+
test_done