status: add --[no-]ahead-behind to status and commit for V2 format.
Teach "git status" and "git commit" to accept "--no-ahead-behind" and "--ahead-behind" arguments to request quick or full ahead/behind reporting. When "--no-ahead-behind" is given, the existing porcelain V2 line "branch.ab +x -y" is replaced with a new "branch.ab +? -?" line. This indicates that the branch and its upstream are or are not equal without the expense of computing the full ahead/behind values. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									d7d1b496ae
								
							
						
					
					
						commit
						fd9b544a29
					
				|  | @ -130,6 +130,11 @@ ignored, then the directory is not shown, but all contents are shown. | |||
| 	without options are equivalent to 'always' and 'never' | ||||
| 	respectively. | ||||
|  | ||||
| --ahead-behind:: | ||||
| --no-ahead-behind:: | ||||
| 	Display or do not display detailed ahead/behind counts for the | ||||
| 	branch relative to its upstream branch.  Defaults to true. | ||||
|  | ||||
| <pathspec>...:: | ||||
| 	See the 'pathspec' entry in linkgit:gitglossary[7]. | ||||
|  | ||||
|  |  | |||
|  | @ -1151,6 +1151,9 @@ static void finalize_deferred_config(struct wt_status *s) | |||
| 		s->show_branch = status_deferred_config.show_branch; | ||||
| 	if (s->show_branch < 0) | ||||
| 		s->show_branch = 0; | ||||
|  | ||||
| 	if (s->ahead_behind_flags == AHEAD_BEHIND_UNSPECIFIED) | ||||
| 		s->ahead_behind_flags = AHEAD_BEHIND_FULL; | ||||
| } | ||||
|  | ||||
| static int parse_and_validate_options(int argc, const char *argv[], | ||||
|  | @ -1365,6 +1368,8 @@ int cmd_status(int argc, const char **argv, const char *prefix) | |||
| 			 N_("show branch information")), | ||||
| 		OPT_BOOL(0, "show-stash", &s.show_stash, | ||||
| 			 N_("show stash information")), | ||||
| 		OPT_BOOL(0, "ahead-behind", &s.ahead_behind_flags, | ||||
| 			 N_("compute full ahead/behind values")), | ||||
| 		{ OPTION_CALLBACK, 0, "porcelain", &status_format, | ||||
| 		  N_("version"), N_("machine-readable output"), | ||||
| 		  PARSE_OPT_OPTARG, opt_parse_porcelain }, | ||||
|  | @ -1648,6 +1653,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix) | |||
| 		OPT_SET_INT(0, "short", &status_format, N_("show status concisely"), | ||||
| 			    STATUS_FORMAT_SHORT), | ||||
| 		OPT_BOOL(0, "branch", &s.show_branch, N_("show branch information")), | ||||
| 		OPT_BOOL(0, "ahead-behind", &s.ahead_behind_flags, | ||||
| 			 N_("compute full ahead/behind values")), | ||||
| 		OPT_SET_INT(0, "porcelain", &status_format, | ||||
| 			    N_("machine-readable output"), STATUS_FORMAT_PORCELAIN), | ||||
| 		OPT_SET_INT(0, "long", &status_format, | ||||
|  |  | |||
							
								
								
									
										2
									
								
								remote.c
								
								
								
								
							
							
						
						
									
										2
									
								
								remote.c
								
								
								
								
							|  | @ -2058,6 +2058,8 @@ int stat_tracking_info(struct branch *branch, int *num_ours, int *num_theirs, | |||
| 		return 0; | ||||
| 	if (abf == AHEAD_BEHIND_QUICK) | ||||
| 		return 1; | ||||
| 	if (abf != AHEAD_BEHIND_FULL) | ||||
| 		BUG("stat_tracking_info: invalid abf '%d'", abf); | ||||
|  | ||||
| 	/* Run "rev-list --left-right ours...theirs" internally... */ | ||||
| 	argv_array_push(&argv, ""); /* ignored */ | ||||
|  |  | |||
							
								
								
									
										1
									
								
								remote.h
								
								
								
								
							
							
						
						
									
										1
									
								
								remote.h
								
								
								
								
							|  | @ -259,6 +259,7 @@ enum match_refs_flags { | |||
|  | ||||
| /* Flags for --ahead-behind option. */ | ||||
| enum ahead_behind_flags { | ||||
| 	AHEAD_BEHIND_UNSPECIFIED = -1, | ||||
| 	AHEAD_BEHIND_QUICK       =  0,  /* just eq/neq reporting */ | ||||
| 	AHEAD_BEHIND_FULL        =  1,  /* traditional a/b reporting */ | ||||
| }; | ||||
|  |  | |||
|  | @ -390,6 +390,68 @@ test_expect_success 'verify upstream fields in branch header' ' | |||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'verify --[no-]ahead-behind with V2 format' ' | ||||
| 	git checkout master && | ||||
| 	test_when_finished "rm -rf sub_repo" && | ||||
| 	git clone . sub_repo && | ||||
| 	( | ||||
| 		## Confirm local master tracks remote master. | ||||
| 		cd sub_repo && | ||||
| 		HUF=$(git rev-parse HEAD) && | ||||
|  | ||||
| 		# Confirm --no-ahead-behind reports traditional branch.ab with 0/0 for equal branches. | ||||
| 		cat >expect <<-EOF && | ||||
| 		# branch.oid $HUF | ||||
| 		# branch.head master | ||||
| 		# branch.upstream origin/master | ||||
| 		# branch.ab +0 -0 | ||||
| 		EOF | ||||
|  | ||||
| 		git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual && | ||||
| 		test_cmp expect actual && | ||||
|  | ||||
| 		# Confirm --ahead-behind reports traditional branch.ab with 0/0. | ||||
| 		cat >expect <<-EOF && | ||||
| 		# branch.oid $HUF | ||||
| 		# branch.head master | ||||
| 		# branch.upstream origin/master | ||||
| 		# branch.ab +0 -0 | ||||
| 		EOF | ||||
|  | ||||
| 		git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual && | ||||
| 		test_cmp expect actual && | ||||
|  | ||||
| 		## Test non-equal ahead/behind. | ||||
| 		echo xyz >file_xyz && | ||||
| 		git add file_xyz && | ||||
| 		git commit -m xyz && | ||||
|  | ||||
| 		HUF=$(git rev-parse HEAD) && | ||||
|  | ||||
| 		# Confirm --no-ahead-behind reports branch.ab with ?/? for non-equal branches. | ||||
| 		cat >expect <<-EOF && | ||||
| 		# branch.oid $HUF | ||||
| 		# branch.head master | ||||
| 		# branch.upstream origin/master | ||||
| 		# branch.ab +? -? | ||||
| 		EOF | ||||
|  | ||||
| 		git status --no-ahead-behind --porcelain=v2 --branch --untracked-files=all >actual && | ||||
| 		test_cmp expect actual && | ||||
|  | ||||
| 		# Confirm --ahead-behind reports traditional branch.ab with 1/0. | ||||
| 		cat >expect <<-EOF && | ||||
| 		# branch.oid $HUF | ||||
| 		# branch.head master | ||||
| 		# branch.upstream origin/master | ||||
| 		# branch.ab +1 -0 | ||||
| 		EOF | ||||
|  | ||||
| 		git status --ahead-behind --porcelain=v2 --branch --untracked-files=all >actual && | ||||
| 		test_cmp expect actual | ||||
| 	) | ||||
| ' | ||||
|  | ||||
| test_expect_success 'create and add submodule, submodule appears clean (A. S...)' ' | ||||
| 	git checkout master && | ||||
| 	git clone . sub_repo && | ||||
|  |  | |||
							
								
								
									
										30
									
								
								wt-status.c
								
								
								
								
							
							
						
						
									
										30
									
								
								wt-status.c
								
								
								
								
							|  | @ -136,6 +136,7 @@ void wt_status_prepare(struct wt_status *s) | |||
| 	s->ignored.strdup_strings = 1; | ||||
| 	s->show_branch = -1;  /* unspecified */ | ||||
| 	s->show_stash = 0; | ||||
| 	s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED; | ||||
| 	s->display_comment_prefix = 0; | ||||
| } | ||||
|  | ||||
|  | @ -1883,18 +1884,19 @@ static void wt_porcelain_print(struct wt_status *s) | |||
|  * | ||||
|  *    <upstream> ::= the upstream branch name, when set. | ||||
|  * | ||||
|  *       <ahead> ::= integer ahead value, when upstream set | ||||
|  *                   and the commit is present (not gone). | ||||
|  * | ||||
|  *      <behind> ::= integer behind value, when upstream set | ||||
|  *                   and commit is present. | ||||
|  *       <ahead> ::= integer ahead value or '?'. | ||||
|  * | ||||
|  *      <behind> ::= integer behind value or '?'. | ||||
|  * | ||||
|  * The end-of-line is defined by the -z flag. | ||||
|  * | ||||
|  *                 <eol> ::= NUL when -z, | ||||
|  *                           LF when NOT -z. | ||||
|  * | ||||
|  * When an upstream is set and present, the 'branch.ab' line will | ||||
|  * be printed with the ahead/behind counts for the branch and the | ||||
|  * upstream.  When AHEAD_BEHIND_QUICK is requested and the branches | ||||
|  * are different, '?' will be substituted for the actual count. | ||||
|  */ | ||||
| static void wt_porcelain_v2_print_tracking(struct wt_status *s) | ||||
| { | ||||
|  | @ -1934,15 +1936,25 @@ static void wt_porcelain_v2_print_tracking(struct wt_status *s) | |||
| 		/* Lookup stats on the upstream tracking branch, if set. */ | ||||
| 		branch = branch_get(branch_name); | ||||
| 		base = NULL; | ||||
| 		ab_info = (stat_tracking_info(branch, &nr_ahead, &nr_behind, | ||||
| 					      &base, AHEAD_BEHIND_FULL) >= 0); | ||||
| 		ab_info = stat_tracking_info(branch, &nr_ahead, &nr_behind, | ||||
| 					     &base, s->ahead_behind_flags); | ||||
| 		if (base) { | ||||
| 			base = shorten_unambiguous_ref(base, 0); | ||||
| 			fprintf(s->fp, "# branch.upstream %s%c", base, eol); | ||||
| 			free((char *)base); | ||||
|  | ||||
| 			if (ab_info) | ||||
| 				fprintf(s->fp, "# branch.ab +%d -%d%c", nr_ahead, nr_behind, eol); | ||||
| 			if (ab_info > 0) { | ||||
| 				/* different */ | ||||
| 				if (nr_ahead || nr_behind) | ||||
| 					fprintf(s->fp, "# branch.ab +%d -%d%c", | ||||
| 						nr_ahead, nr_behind, eol); | ||||
| 				else | ||||
| 					fprintf(s->fp, "# branch.ab +? -?%c", | ||||
| 						eol); | ||||
| 			} else if (!ab_info) { | ||||
| 				/* same */ | ||||
| 				fprintf(s->fp, "# branch.ab +0 -0%c", eol); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ | |||
| #include "string-list.h" | ||||
| #include "color.h" | ||||
| #include "pathspec.h" | ||||
| #include "remote.h" | ||||
|  | ||||
| struct worktree; | ||||
|  | ||||
|  | @ -86,6 +87,7 @@ struct wt_status { | |||
| 	int show_branch; | ||||
| 	int show_stash; | ||||
| 	int hints; | ||||
| 	enum ahead_behind_flags ahead_behind_flags; | ||||
|  | ||||
| 	enum wt_status_format status_format; | ||||
| 	unsigned char sha1_commit[GIT_MAX_RAWSZ]; /* when not Initial */ | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Jeff Hostetler
						Jeff Hostetler