Browse Source

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>
maint
Ilari Liusvaara 15 years ago committed by Junio C Hamano
parent
commit
4fc5006676
  1. 8
      Documentation/git-branch.txt
  2. 31
      branch.c
  3. 2
      builtin-branch.c
  4. 1
      cache.h
  5. 21
      t/t6040-tracking-info.sh

8
Documentation/git-branch.txt

@ -11,7 +11,7 @@ SYNOPSIS @@ -11,7 +11,7 @@ SYNOPSIS
'git branch' [--color | --no-color] [-r | -a]
[-v [--abbrev=<length> | --no-abbrev]]
[(--merged | --no-merged | --contains) [<commit>]]
'git branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git branch' [--set-upstream | --track | --no-track] [-l] [-f] <branchname> [<start-point>]
'git branch' (-m | -M) [<oldbranch>] <newbranch>
'git branch' (-d | -D) [-r] <branchname>...

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

--set-upstream::
If specified branch does not exist yet or if '--force' has been
given, acts exactly like '--track'. Otherwise sets up configuration
like '--track' would when creating the branch, except that where
branch points to is not changed.

--contains <commit>::
Only list branches which contain the specified commit.


31
branch.c

@ -108,6 +108,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref, @@ -108,6 +108,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref,
switch (track) {
case BRANCH_TRACK_ALWAYS:
case BRANCH_TRACK_EXPLICIT:
case BRANCH_TRACK_OVERRIDE:
break;
default:
return 1;
@ -128,18 +129,25 @@ void create_branch(const char *head, @@ -128,18 +129,25 @@ void create_branch(const char *head,
const char *name, const char *start_name,
int force, int reflog, enum branch_track track)
{
struct ref_lock *lock;
struct ref_lock *lock = NULL;
struct commit *commit;
unsigned char sha1[20];
char *real_ref, msg[PATH_MAX + 20];
struct strbuf ref = STRBUF_INIT;
int forcing = 0;
int dont_change_ref = 0;
int explicit_tracking = 0;

if (track == BRANCH_TRACK_EXPLICIT || track == BRANCH_TRACK_OVERRIDE)
explicit_tracking = 1;

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

if (resolve_ref(ref.buf, sha1, 1, NULL)) {
if (!force)
if (!force && track == BRANCH_TRACK_OVERRIDE)
dont_change_ref = 1;
else if (!force)
die("A branch named '%s' already exists.", name);
else if (!is_bare_repository() && !strcmp(head, name))
die("Cannot force update the current branch.");
@ -153,12 +161,12 @@ void create_branch(const char *head, @@ -153,12 +161,12 @@ void create_branch(const char *head,
switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) {
case 0:
/* Not branching from any existing branch */
if (track == BRANCH_TRACK_EXPLICIT)
if (explicit_tracking)
die("Cannot setup tracking information; starting point is not a branch.");
break;
case 1:
/* Unique completion -- good, only if it is a real ref */
if (track == BRANCH_TRACK_EXPLICIT && !strcmp(real_ref, "HEAD"))
if (explicit_tracking && !strcmp(real_ref, "HEAD"))
die("Cannot setup tracking information; starting point is not a branch.");
break;
default:
@ -170,9 +178,11 @@ void create_branch(const char *head, @@ -170,9 +178,11 @@ void create_branch(const char *head,
die("Not a valid branch point: '%s'.", start_name);
hashcpy(sha1, commit->object.sha1);

lock = lock_any_ref_for_update(ref.buf, NULL, 0);
if (!lock)
die_errno("Failed to lock ref for update");
if (!dont_change_ref) {
lock = lock_any_ref_for_update(ref.buf, NULL, 0);
if (!lock)
die_errno("Failed to lock ref for update");
}

if (reflog)
log_all_ref_updates = 1;
@ -180,15 +190,16 @@ void create_branch(const char *head, @@ -180,15 +190,16 @@ void create_branch(const char *head,
if (forcing)
snprintf(msg, sizeof msg, "branch: Reset from %s",
start_name);
else
else if (!dont_change_ref)
snprintf(msg, sizeof msg, "branch: Created from %s",
start_name);

if (real_ref && track)
setup_tracking(name, real_ref, track);

if (write_ref_sha1(lock, sha1, msg) < 0)
die_errno("Failed to write ref");
if (!dont_change_ref)
if (write_ref_sha1(lock, sha1, msg) < 0)
die_errno("Failed to write ref");

strbuf_release(&ref);
free(real_ref);

2
builtin-branch.c

@ -564,6 +564,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) @@ -564,6 +564,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
OPT__VERBOSE(&verbose),
OPT_SET_INT('t', "track", &track, "set up tracking mode (see git-pull(1))",
BRANCH_TRACK_EXPLICIT),
OPT_SET_INT( 0, "set-upstream", &track, "change upstream info",
BRANCH_TRACK_OVERRIDE),
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
REF_REMOTE_BRANCH),

1
cache.h

@ -553,6 +553,7 @@ enum branch_track { @@ -553,6 +553,7 @@ enum branch_track {
BRANCH_TRACK_REMOTE,
BRANCH_TRACK_ALWAYS,
BRANCH_TRACK_EXPLICIT,
BRANCH_TRACK_OVERRIDE,
};

enum rebase_setup_type {

21
t/t6040-tracking-info.sh

@ -89,4 +89,25 @@ test_expect_success 'status when tracking annotated tags' ' @@ -89,4 +89,25 @@ test_expect_success 'status when tracking annotated tags' '
grep "set up to track" actual &&
git checkout heavytrack
'

test_expect_success 'setup tracking with branch --set-upstream on existing branch' '
git branch from-master master &&
test_must_fail git config branch.from-master.merge > actual &&
git branch --set-upstream from-master master &&
git config branch.from-master.merge > actual &&
grep -q "^refs/heads/master$" actual
'

test_expect_success '--set-upstream does not change branch' '
git branch from-master2 master &&
test_must_fail git config branch.from-master2.merge > actual &&
git rev-list from-master2 &&
git update-ref refs/heads/from-master2 from-master2^ &&
git rev-parse from-master2 >expect2 &&
git branch --set-upstream from-master2 master &&
git config branch.from-master.merge > actual &&
git rev-parse from-master2 >actual2 &&
grep -q "^refs/heads/master$" actual &&
cmp expect2 actual2
'
test_done

Loading…
Cancel
Save