Skip to content

Commit 4fc5006

Browse files
Ilari Liusvaaragitster
authored andcommitted
Add branch --set-upstream
Add --set-upstream option to branch that works like --track, except that when branch exists already, its upstream info is changed without changing the ref value. Based-on-patch-from: Matthieu Moy <[email protected]> Signed-off-by: Matthieu Moy <[email protected]> Signed-off-by: Ilari Liusvaara <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent ff6d26a commit 4fc5006

File tree

5 files changed

+52
-11
lines changed

5 files changed

+52
-11
lines changed

Documentation/git-branch.txt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ SYNOPSIS
1111
'git branch' [--color | --no-color] [-r | -a]
1212
[-v [--abbrev=<length> | --no-abbrev]]
1313
[(--merged | --no-merged | --contains) [<commit>]]
14-
'git branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
14+
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
1515
'git branch' (-m | -M) [<oldbranch>] <newbranch>
1616
'git branch' (-d | -D) [-r] <branchname>...
1717

@@ -129,6 +129,12 @@ start-point is either a local or remote branch.
129129
Do not set up "upstream" configuration, even if the
130130
branch.autosetupmerge configuration variable is true.
131131

132+
--set-upstream::
133+
If specified branch does not exist yet or if '--force' has been
134+
given, acts exactly like '--track'. Otherwise sets up configuration
135+
like '--track' would when creating the branch, except that where
136+
branch points to is not changed.
137+
132138
--contains <commit>::
133139
Only list branches which contain the specified commit.
134140

branch.c

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
108108
switch (track) {
109109
case BRANCH_TRACK_ALWAYS:
110110
case BRANCH_TRACK_EXPLICIT:
111+
case BRANCH_TRACK_OVERRIDE:
111112
break;
112113
default:
113114
return 1;
@@ -128,18 +129,25 @@ void create_branch(const char *head,
128129
const char *name, const char *start_name,
129130
int force, int reflog, enum branch_track track)
130131
{
131-
struct ref_lock *lock;
132+
struct ref_lock *lock = NULL;
132133
struct commit *commit;
133134
unsigned char sha1[20];
134135
char *real_ref, msg[PATH_MAX + 20];
135136
struct strbuf ref = STRBUF_INIT;
136137
int forcing = 0;
138+
int dont_change_ref = 0;
139+
int explicit_tracking = 0;
140+
141+
if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
142+
explicit_tracking = 1;
137143

138144
if (strbuf_check_branch_ref(&ref, name))
139145
die("'%s' is not a valid branch name.", name);
140146

141147
if (resolve_ref(ref.buf, sha1, 1, NULL)) {
142-
if (!force)
148+
if (!force && track == BRANCH_TRACK_OVERRIDE)
149+
dont_change_ref = 1;
150+
else if (!force)
143151
die("A branch named '%s' already exists.", name);
144152
else if (!is_bare_repository() && !strcmp(head, name))
145153
die("Cannot force update the current branch.");
@@ -153,12 +161,12 @@ void create_branch(const char *head,
153161
switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
154162
case 0:
155163
/* Not branching from any existing branch */
156-
if (track == BRANCH_TRACK_EXPLICIT)
164+
if (explicit_tracking)
157165
die("Cannot setup tracking information; starting point is not a branch.");
158166
break;
159167
case 1:
160168
/* Unique completion -- good, only if it is a real ref */
161-
if (track == BRANCH_TRACK_EXPLICIT && !strcmp(real_ref, "HEAD"))
169+
if (explicit_tracking && !strcmp(real_ref, "HEAD"))
162170
die("Cannot setup tracking information; starting point is not a branch.");
163171
break;
164172
default:
@@ -170,25 +178,28 @@ void create_branch(const char *head,
170178
die("Not a valid branch point: '%s'.", start_name);
171179
hashcpy(sha1, commit->object.sha1);
172180

173-
lock = lock_any_ref_for_update(ref.buf, NULL, 0);
174-
if (!lock)
175-
die_errno("Failed to lock ref for update");
181+
if (!dont_change_ref) {
182+
lock = lock_any_ref_for_update(ref.buf, NULL, 0);
183+
if (!lock)
184+
die_errno("Failed to lock ref for update");
185+
}
176186

177187
if (reflog)
178188
log_all_ref_updates = 1;
179189

180190
if (forcing)
181191
snprintf(msg, sizeof msg, "branch: Reset from %s",
182192
start_name);
183-
else
193+
else if (!dont_change_ref)
184194
snprintf(msg, sizeof msg, "branch: Created from %s",
185195
start_name);
186196

187197
if (real_ref && track)
188198
setup_tracking(name, real_ref, track);
189199

190-
if (write_ref_sha1(lock, sha1, msg) < 0)
191-
die_errno("Failed to write ref");
200+
if (!dont_change_ref)
201+
if (write_ref_sha1(lock, sha1, msg) < 0)
202+
die_errno("Failed to write ref");
192203

193204
strbuf_release(&ref);
194205
free(real_ref);

builtin-branch.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,6 +564,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
564564
OPT__VERBOSE(&verbose),
565565
OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))",
566566
BRANCH_TRACK_EXPLICIT),
567+
OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
568+
BRANCH_TRACK_OVERRIDE),
567569
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
568570
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
569571
REF_REMOTE_BRANCH),

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ enum branch_track {
553553
BRANCH_TRACK_REMOTE,
554554
BRANCH_TRACK_ALWAYS,
555555
BRANCH_TRACK_EXPLICIT,
556+
BRANCH_TRACK_OVERRIDE,
556557
};
557558

558559
enum rebase_setup_type {

t/t6040-tracking-info.sh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,25 @@ test_expect_success 'status when tracking annotated tags' '
8989
grep "set up to track" actual &&
9090
git checkout heavytrack
9191
'
92+
93+
test_expect_success 'setup tracking with branch --set-upstream on existing branch' '
94+
git branch from-master master &&
95+
test_must_fail git config branch.from-master.merge > actual &&
96+
git branch --set-upstream from-master master &&
97+
git config branch.from-master.merge > actual &&
98+
grep -q "^refs/heads/master$" actual
99+
'
100+
101+
test_expect_success '--set-upstream does not change branch' '
102+
git branch from-master2 master &&
103+
test_must_fail git config branch.from-master2.merge > actual &&
104+
git rev-list from-master2 &&
105+
git update-ref refs/heads/from-master2 from-master2^ &&
106+
git rev-parse from-master2 >expect2 &&
107+
git branch --set-upstream from-master2 master &&
108+
git config branch.from-master.merge > actual &&
109+
git rev-parse from-master2 >actual2 &&
110+
grep -q "^refs/heads/master$" actual &&
111+
cmp expect2 actual2
112+
'
92113
test_done

0 commit comments

Comments
 (0)