@matheusbsbs / matheus-bagliano / commits / 4fc5006676
Fork 0

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 <Matthieu.Moy@imag.fr> Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr> Signed-off-by: Ilari Liusvaara <ilari.liusvaara@elisanet.fi> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ilari Liusvaara committed Jan 18, 2010 at 22:44 UTC 4fc500667636c4ada592a40c4d11ce0560c43c0d
5 files changed +52 -11
Documentation/git-branch.txt
+7 -1
@@ -11,7 +11,7 @@ SYNOPSIS
11 'git branch' [--color | --no-color] [-r | -a]
12 [-v [--abbrev=<length> | --no-abbrev]]
13 [(--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>]
15 'git branch' (-m | -M) [<oldbranch>] <newbranch>
16 'git branch' (-d | -D) [-r] <branchname>...
17
@@ -129,6 +129,12 @@ start-point is either a local or remote branch.
129 Do not set up "upstream" configuration, even if the
130 branch.autosetupmerge configuration variable is true.
131
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 +
138 --contains <commit>::
139 Only list branches which contain the specified commit.
140
branch.c
+21 -10
@@ -108,6 +108,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
108 switch (track) {
109 case BRANCH_TRACK_ALWAYS:
110 case BRANCH_TRACK_EXPLICIT:
111 + case BRANCH_TRACK_OVERRIDE:
112 break;
113 default:
114 return 1;
@@ -128,18 +129,25 @@ void create_branch(const char *head,
129 const char *name, const char *start_name,
130 int force, int reflog, enum branch_track track)
131 {
131 - struct ref_lock *lock;
132 + struct ref_lock *lock = NULL;
133 struct commit *commit;
134 unsigned char sha1[20];
135 char *real_ref, msg[PATH_MAX + 20];
136 struct strbuf ref = STRBUF_INIT;
137 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;
143
144 if (strbuf_check_branch_ref(&ref, name))
145 die("'%s' is not a valid branch name.", name);
146
147 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)
151 die("A branch named '%s' already exists.", name);
152 else if (!is_bare_repository() && !strcmp(head, name))
153 die("Cannot force update the current branch.");
@@ -153,12 +161,12 @@ void create_branch(const char *head,
161 switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
162 case 0:
163 /* Not branching from any existing branch */
156 - if (track == BRANCH_TRACK_EXPLICIT)
164 + if (explicit_tracking)
165 die("Cannot setup tracking information; starting point is not a branch.");
166 break;
167 case 1:
168 /* 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"))
170 die("Cannot setup tracking information; starting point is not a branch.");
171 break;
172 default:
@@ -170,9 +178,11 @@ void create_branch(const char *head,
178 die("Not a valid branch point: '%s'.", start_name);
179 hashcpy(sha1, commit->object.sha1);
180
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 + }
186
187 if (reflog)
188 log_all_ref_updates = 1;
@@ -180,15 +190,16 @@ void create_branch(const char *head,
190 if (forcing)
191 snprintf(msg, sizeof msg, "branch: Reset from %s",
192 start_name);
183 - else
193 + else if (!dont_change_ref)
194 snprintf(msg, sizeof msg, "branch: Created from %s",
195 start_name);
196
197 if (real_ref && track)
198 setup_tracking(name, real_ref, track);
199
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");
203
204 strbuf_release(&ref);
205 free(real_ref);
builtin-branch.c
+2
@@ -564,6 +564,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
564 OPT__VERBOSE(&verbose),
565 OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))",
566 BRANCH_TRACK_EXPLICIT),
567 + OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
568 + BRANCH_TRACK_OVERRIDE),
569 OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
570 OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
571 REF_REMOTE_BRANCH),
cache.h
+1
@@ -553,6 +553,7 @@ enum branch_track {
553 BRANCH_TRACK_REMOTE,
554 BRANCH_TRACK_ALWAYS,
555 BRANCH_TRACK_EXPLICIT,
556 + BRANCH_TRACK_OVERRIDE,
557 };
558
559 enum rebase_setup_type {
t/t6040-tracking-info.sh
+21
@@ -89,4 +89,25 @@ test_expect_success 'status when tracking annotated tags' '
89 grep "set up to track" actual &&
90 git checkout heavytrack
91 '
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 +'
113 test_done