Skip to content

Commit 01e9378

Browse files
remote: add --set-head option to 'git remote add'
Mirror the behavior 'git clone' applies to its first remote: after fetching, set refs/remotes/<name>/HEAD to the remote's default branch. Equivalent to running: git remote add -f <name> <url> git remote set-head <name> -a The new option implies --fetch. Signed-off-by: Harald Nordgren <haraldnordgren@gmail.com>
1 parent 94f0577 commit 01e9378

3 files changed

Lines changed: 40 additions & 3 deletions

File tree

Documentation/git-remote.adoc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ SYNOPSIS
1010
--------
1111
[synopsis]
1212
git remote [-v | --verbose]
13-
git remote add [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=(fetch|push)] <name> <URL>
13+
git remote add [-t <branch>] [-m <master>] [-f] [--set-head] [--[no-]tags] [--mirror=(fetch|push)] <name> <URL>
1414
git remote rename [--[no-]progress] <old> <new>
1515
git remote remove <name>
1616
git remote set-head <name> (-a | --auto | -d | --delete | <branch>)
@@ -73,6 +73,13 @@ multiple branches without grabbing all branches.
7373
With `-m <master>` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
7474
up to point at remote's _<master>_ branch. See also the set-head command.
7575
+
76+
With `--set-head` option, a symbolic-ref `refs/remotes/<name>/HEAD` is set
77+
up to point at the remote's default branch, mirroring the behavior of
78+
`git clone`. This is equivalent to running `git remote set-head <name> -a`
79+
after the remote is added, and implies `-f` so that the remote's refs are
80+
available locally. It cannot be combined with `-m <master>` or with a push
81+
mirror.
82+
+
7683
When a fetch mirror is created with `--mirror=fetch`, the refs will not
7784
be stored in the `refs/remotes/` namespace, but rather everything in
7885
`refs/` on the remote will be directly mirrored into `refs/` in the

builtin/remote.c

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
static const char * const builtin_remote_usage[] = {
2525
"git remote [-v | --verbose]",
26-
N_("git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--mirror=<fetch|push>] <name> <url>"),
26+
N_("git remote add [-t <branch>] [-m <master>] [-f] [--set-head] [--tags | --no-tags] [--mirror=<fetch|push>] <name> <url>"),
2727
N_("git remote rename [--[no-]progress] <old> <new>"),
2828
N_("git remote remove <name>"),
2929
N_("git remote set-head <name> (-a | --auto | -d | --delete | <branch>)"),
@@ -174,10 +174,21 @@ static int check_remote_collision(struct remote *remote, void *data)
174174
return 0;
175175
}
176176

177+
static int set_head_auto_for_remote(const char *name)
178+
{
179+
struct child_process cmd = CHILD_PROCESS_INIT;
180+
181+
strvec_pushl(&cmd.args, "remote", "set-head", "--auto", name, NULL);
182+
cmd.git_cmd = 1;
183+
if (run_command(&cmd))
184+
return error(_("Could not set up HEAD for %s"), name);
185+
return 0;
186+
}
187+
177188
static int add(int argc, const char **argv, const char *prefix,
178189
struct repository *repo UNUSED)
179190
{
180-
int fetch = 0, fetch_tags = TAGS_DEFAULT;
191+
int fetch = 0, fetch_tags = TAGS_DEFAULT, set_head_auto = 0;
181192
unsigned mirror = MIRROR_NONE;
182193
struct string_list track = STRING_LIST_INIT_NODUP;
183194
const char *master = NULL;
@@ -195,6 +206,8 @@ static int add(int argc, const char **argv, const char *prefix,
195206
OPT_STRING_LIST('t', "track", &track, N_("branch"),
196207
N_("branch(es) to track")),
197208
OPT_STRING('m', "master", &master, N_("branch"), N_("master branch")),
209+
OPT_BOOL(0, "set-head", &set_head_auto,
210+
N_("set refs/remotes/<name>/HEAD according to remote (implies --fetch)")),
198211
OPT_CALLBACK_F(0, "mirror", &mirror, "(push|fetch)",
199212
N_("set up remote as a mirror to push to or fetch from"),
200213
PARSE_OPT_OPTARG | PARSE_OPT_COMP_ARG, parse_mirror_opt),
@@ -211,6 +224,12 @@ static int add(int argc, const char **argv, const char *prefix,
211224
die(_("specifying a master branch makes no sense with --mirror"));
212225
if (mirror && !(mirror & MIRROR_FETCH) && track.nr)
213226
die(_("specifying branches to track makes sense only with fetch mirrors"));
227+
if (set_head_auto && master)
228+
die(_("--set-head and --master are mutually exclusive"));
229+
if (set_head_auto && mirror && !(mirror & MIRROR_FETCH))
230+
die(_("--set-head makes no sense with a push mirror"));
231+
if (set_head_auto)
232+
fetch = 1;
214233

215234
name = argv[0];
216235
url = argv[1];
@@ -269,6 +288,9 @@ static int add(int argc, const char **argv, const char *prefix,
269288
result = error(_("Could not setup master '%s'"), master);
270289
}
271290

291+
if (set_head_auto && set_head_auto_for_remote(name))
292+
result = 1;
293+
272294
out:
273295
strbuf_release(&buf);
274296
strbuf_release(&buf2);

t/t5505-remote.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,14 @@ test_expect_success 'add another remote' '
8181
)
8282
'
8383

84+
test_expect_success 'add remote with --set-head implies --fetch and sets HEAD' '
85+
test_when_finished "git -C test remote remove third" &&
86+
git -C test remote add --set-head third ../two &&
87+
echo refs/remotes/third/main >expect &&
88+
git -C test symbolic-ref refs/remotes/third/HEAD >actual &&
89+
test_cmp expect actual
90+
'
91+
8492
test_expect_success 'setup bare clone for server' '
8593
git clone --bare "file://$(pwd)/one" srv.bare &&
8694
git -C srv.bare config --local uploadpack.allowfilter 1 &&

0 commit comments

Comments
 (0)