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
							parent
							
								
									ff6d26a0e1
								
							
						
					
					
						commit
						4fc5006676
					
				|  | @ -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. | |||
| 	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
								
								
								
								
							
							
						
						
									
										31
									
								
								branch.c
								
								
								
								
							|  | @ -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, | |||
| 		   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, | |||
| 	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, | |||
| 		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, | |||
| 	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); | ||||
|  |  | |||
|  | @ -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
								
								
								
								
							
							
						
						
									
										1
									
								
								cache.h
								
								
								
								
							|  | @ -553,6 +553,7 @@ enum branch_track { | |||
| 	BRANCH_TRACK_REMOTE, | ||||
| 	BRANCH_TRACK_ALWAYS, | ||||
| 	BRANCH_TRACK_EXPLICIT, | ||||
| 	BRANCH_TRACK_OVERRIDE, | ||||
| }; | ||||
|  | ||||
| enum rebase_setup_type { | ||||
|  |  | |||
|  | @ -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…
	
		Reference in New Issue
	
	 Ilari Liusvaara
						Ilari Liusvaara