threads / rfc / 58893

RFC patchpush: introduce '--heads' option

Subject: [RFC PATCH 0/1] push: introduce '--heads' option

## tl;dr

18 messages between Dec 5, 2022 and May 7, 2023. Diffs are folded; open one to read it.

replies: 17people: 4as markdown or json

Teng Long· Dec 5, 2022, 13:35 UTC · lore
From: Teng Long <dyroneteng@gmail.com>

This RFC patch try to introduce a new option '--heads' in 'git-push' subcmd. The value of this patch may come from my personal point of view, and the patch might not have enough tests so far. It's pleasure to hear any suggestion, test scenario which need to be covered or any test method which need to be noticed if it's worthy.

Thanks.
Teng Long (1):
  push: introduce '--heads' option
 Documentation/git-push.txt |  1 +
 builtin/push.c             | 13 +++++++------
 t/t5523-push-upstream.sh   | 19 ++++++++++++-------
 3 files changed, 20 insertions(+), 13 deletions(-)
-- 
2.39.0.rc1.5.ge01d593fc21.dirty
Teng Long· Dec 5, 2022, 13:35 UTC · re: Teng Long · lore

[RFC PATCH 1/1] push: introduce '--heads' option

From: Teng Long <dyroneteng@gmail.com>

The '--all' option of git-push built-in cmd support to push all branches (refs under refs/heads) to remote. Under the usage, a user can easlily work in some scenarios, for example, branches synchronization and batch upload.

'--all' was introduced for a long time, meanwhile, git supports to customize the storage location under "refs/". when a new git user see the usage like, 'git push origin --all', we might feel like we're pushing _all_ the refs instead of just branches without looking at the documents until we found the related description of it or '--mirror'.

To ensure compatibility, we cannot rename '--all' to another name directly, one way is, we can try to add a new option '--heads' which be identical with the functionality of '--all' to let the user understand the meaning of representation more clearly. Actually, We've more or less named options this way already, for example, in 'git-show-ref' and 'git ls-remote'.

At the same time, we fix a related issue about the wrong help information of '--all' option in code.

Signed-off-by: Teng Long <dyroneteng@gmail.com>
---
 Documentation/git-push.txt |  1 +
 builtin/push.c             | 13 +++++++------
 t/t5523-push-upstream.sh   | 19 ++++++++++++-------
 3 files changed, 20 insertions(+), 13 deletions(-)
Show changes to 3 files +20 −13

Documentation/git-push.txt, builtin/push.c, t/t5523-push-upstream.sh

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 5bb1d5aae25..a5d18fb90b6 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -147,6 +147,7 @@ already exists on the remote side.
 `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
 
 --all::
+--heads::
 	Push all branches (i.e. refs under `refs/heads/`); cannot be
 	used with other <refspec>.
 
diff --git a/builtin/push.c b/builtin/push.c
index 60ac8017e52..970cabaa78b 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -588,11 +588,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__VERBOSITY(&verbosity),
 		OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
-		OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
+		OPT_BIT( 0 , "all", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
+		OPT_BIT( 0 , "heads", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
 		OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
 			    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
 		OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")),
-		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
+		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --heads or --mirror)")),
 		OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
 		OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
 		OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
@@ -635,7 +636,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	set_push_cert_flags(&flags, push_cert);
 
 	if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
-		die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--mirror/--tags");
+		die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--heads/--mirror/--tags");
 	if (deleterefs && argc < 2)
 		die(_("--delete doesn't make sense without any refs"));
 
@@ -673,9 +674,9 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 
 	if (flags & TRANSPORT_PUSH_ALL) {
 		if (tags)
-			die(_("options '%s' and '%s' cannot be used together"), "--all", "--tags");
+			die(_("options '%s' and '%s' cannot be used together"), "--all/--heads", "--tags");
 		if (argc >= 2)
-			die(_("--all can't be combined with refspecs"));
+			die(_("--all/--heads can't be combined with refspecs"));
 	}
 	if (flags & TRANSPORT_PUSH_MIRROR) {
 		if (tags)
@@ -684,7 +685,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 			die(_("--mirror can't be combined with refspecs"));
 	}
 	if ((flags & TRANSPORT_PUSH_ALL) && (flags & TRANSPORT_PUSH_MIRROR))
-		die(_("options '%s' and '%s' cannot be used together"), "--all", "--mirror");
+		die(_("options '%s' and '%s' cannot be used together"), "--all/--heads", "--mirror");
 
 	if (!is_empty_cas(&cas) && (flags & TRANSPORT_PUSH_FORCE_IF_INCLUDES))
 		cas.use_force_if_includes = 1;
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index fdb42920564..29d03b2f58b 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -60,13 +60,18 @@ test_expect_success 'push -u :topic_2' '
 	check_config topic_2 upstream refs/heads/other2
 '
 
-test_expect_success 'push -u --all' '
-	git branch all1 &&
-	git branch all2 &&
-	git push -u --all &&
-	check_config all1 upstream refs/heads/all1 &&
-	check_config all2 upstream refs/heads/all2
-'
+
+for option in 'all' 'heads'
+do
+
+	test_expect_success "push -u --$option" '
+		git branch "$option"1 &&
+		git branch "$option"2 &&
+		git push -u --"$option" &&
+		check_config "$option"1 upstream refs/heads/"$option"1 &&
+		check_config "$option"2 upstream refs/heads/"$option"2
+	'
+done
 
 test_expect_success 'push -u HEAD' '
 	git checkout -b headbranch &&
-- 
2.39.0.rc1.5.ge01d593fc21.dirty
ZheNing Hu· Dec 5, 2022, 14:23 UTC · re: Teng Long · lore

Re: [RFC PATCH 1/1] push: introduce '--heads' option

Hi,
Teng Long <dyroneteng@gmail.com> 于2022年12月5日周一 21:44写道:
Show 14 quoted lines
>
> From: Teng Long <dyroneteng@gmail.com>
>
> The '--all' option of git-push built-in cmd support to push all branches
> (refs under refs/heads) to remote. Under the usage, a user can easlily
> work in some scenarios, for example, branches synchronization and batch
> upload.
>
> '--all' was introduced for a long time, meanwhile, git supports to
> customize the storage location under "refs/". when a new git user see
> the usage like, 'git push origin --all', we might feel like we're
> pushing _all_ the refs instead of just branches without looking at the
> documents until we found the related description of it or '--mirror'.
>

"--all" sounds like it will include all things: branches, tags, but it only includes branches under ref/heads/, which does cause a little confusion for users.

Show 40 quoted lines
> To ensure compatibility, we cannot rename '--all' to another name
> directly, one way is, we can try to add a new option '--heads' which be
> identical with the functionality of '--all' to let the user understand
> the meaning of representation more clearly. Actually, We've more or less
> named options this way already, for example, in 'git-show-ref' and 'git
> ls-remote'.
>
> At the same time, we fix a related issue about the wrong help
> information of '--all' option in code.
>
> Signed-off-by: Teng Long <dyroneteng@gmail.com>
> ---
>  Documentation/git-push.txt |  1 +
>  builtin/push.c             | 13 +++++++------
>  t/t5523-push-upstream.sh   | 19 ++++++++++++-------
>  3 files changed, 20 insertions(+), 13 deletions(-)
>
> diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
> index 5bb1d5aae25..a5d18fb90b6 100644
> --- a/Documentation/git-push.txt
> +++ b/Documentation/git-push.txt
> @@ -147,6 +147,7 @@ already exists on the remote side.
>  `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
>
>  --all::
> +--heads::
>         Push all branches (i.e. refs under `refs/heads/`); cannot be
>         used with other <refspec>.
>
> diff --git a/builtin/push.c b/builtin/push.c
> index 60ac8017e52..970cabaa78b 100644
> --- a/builtin/push.c
> +++ b/builtin/push.c
> @@ -588,11 +588,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
>         struct option options[] = {
>                 OPT__VERBOSITY(&verbosity),
>                 OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
> -               OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
> +               OPT_BIT( 0 , "all", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
> +               OPT_BIT( 0 , "heads", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
Maybe OPT_ALIAS() will be better?
Teng Long· Dec 6, 2022, 12:18 UTC · re: ZheNing Hu · lore

Re: [RFC PATCH 1/1] push: introduce '--heads' option

Show 10 quoted lines
> > '--all' was introduced for a long time, meanwhile, git supports to
> > customize the storage location under "refs/". when a new git user see
> > the usage like, 'git push origin --all', we might feel like we're
> > pushing _all_ the refs instead of just branches without looking at the
> > documents until we found the related description of it or '--mirror'.
> >
>
> "--all" sounds like it will include all things: branches, tags, but it only
> includes branches under ref/heads/, which does cause a little confusion
> for users.

"under refs/heads", right (^ヮ^)? But The overall is nice to me, I'm sure I will use some to revise.

> Maybe OPT_ALIAS() will be better?

I think it's suitable for this if there is no misunderstanding for 'OPT_ALIAS()'.

Thanks.
Felipe Contreras· Apr 28, 2023, 12:21 UTC · re: Teng Long · lore

Re: [RFC PATCH 1/1] push: introduce '--heads' option

Teng Long wrote:
Show 12 quoted lines
> From: Teng Long <dyroneteng@gmail.com>
> 
> The '--all' option of git-push built-in cmd support to push all branches
> (refs under refs/heads) to remote. Under the usage, a user can easlily
> work in some scenarios, for example, branches synchronization and batch
> upload.
> 
> '--all' was introduced for a long time, meanwhile, git supports to
> customize the storage location under "refs/". when a new git user see
> the usage like, 'git push origin --all', we might feel like we're
> pushing _all_ the refs instead of just branches without looking at the
> documents until we found the related description of it or '--mirror'.
Completely agree.

This is something I spotted a long time ago. Although I would prefer `--branches` over `--heads`.

-- 
Felipe Contreras
Teng Long· Apr 30, 2023, 01:05 UTC · re: Felipe Contreras · lore

Re: [RFC PATCH 1/1] push: introduce '--heads' option

Felipe Contreras <felipe.contreras@gmail.com> writes:
Show 18 quoted lines
> Teng Long wrote:
>> From: Teng Long <dyroneteng@gmail.com>
>> 
>> The '--all' option of git-push built-in cmd support to push all branches
>> (refs under refs/heads) to remote. Under the usage, a user can easlily
>> work in some scenarios, for example, branches synchronization and batch
>> upload.
>> 
>> '--all' was introduced for a long time, meanwhile, git supports to
>> customize the storage location under "refs/". when a new git user see
>> the usage like, 'git push origin --all', we might feel like we're
>> pushing _all_ the refs instead of just branches without looking at the
>> documents until we found the related description of it or '--mirror'.
>
>Completely agree.
>
>This is something I spotted a long time ago. Although I would prefer
>`--branches` over `--heads`.

I will cook this recently, maybe we need some well prepared test cases at first.

Thanks.
Teng Long· May 6, 2023, 11:27 UTC · re: Teng Long · lore

[PATCH 0/1] push: introduce '--branches' option

From: Teng Long <dyroneteng@gmail.com>

Based on the feedback I got from the previous RFC patch, I made a formal patch with some additional test cases, but I don't know if the scenarios covered by the test cases are sufficient, if not, the cases will be improved in a subsequent patch.

Thanks.
Teng Long (1):
  push: introduce '--branches' option
 Documentation/git-push.txt |   3 +-
 builtin/push.c             |   7 ++-
 t/t5523-push-upstream.sh   |  12 +++-
 t/t5543-atomic-push.sh     |   5 +-
 t/t5583-push-branches.sh   | 115 +++++++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+), 7 deletions(-)
 create mode 100755 t/t5583-push-branches.sh

Range-diff: 1: 9c9438c3 < -: -------- push: introduce '--heads' option -: -------- > 1: b16bdfe6 push: introduce '--branches' option

-- 
2.40.1.446.gf331623a.dirty
Teng Long· May 6, 2023, 11:27 UTC · re: Teng Long · lore

[PATCH 1/1] push: introduce '--branches' option

From: Teng Long <dyroneteng@gmail.com>

The '--all' option of git-push built-in cmd support to push all branches (refs under refs/heads) to remote. Under the usage, a user can easlily work in some scenarios, for example, branches synchronization and batch upload.

The '--all' was introduced for a long time, meanwhile, git supports to customize the storage location under "refs/". when a new git user see the usage like, 'git push origin --all', we might feel like we're pushing _all_ the refs instead of just branches without looking at the documents until we found the related description of it or '--mirror'.

To ensure compatibility, we cannot rename '--all' to another name directly, one way is, we can try to add a new option '--heads' which be identical with the functionality of '--all' to let the user understand the meaning of representation more clearly. Actually, We've more or less named options this way already, for example, in 'git-show-ref' and 'git ls-remote'.

At the same time, we fix a related issue about the wrong help information of '--all' option in code and add some test cases in t5523, t5543 and t5583.

Signed-off-by: Teng Long <dyroneteng@gmail.com>
---
 Documentation/git-push.txt |   3 +-
 builtin/push.c             |   7 ++-
 t/t5523-push-upstream.sh   |  12 +++-
 t/t5543-atomic-push.sh     |   5 +-
 t/t5583-push-branches.sh   | 115 +++++++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+), 7 deletions(-)
 create mode 100755 t/t5583-push-branches.sh
Show changes to 5 files +135 −7

Documentation/git-push.txt, builtin/push.c, t/t5523-push-upstream.sh, t/t5543-atomic-push.sh, t/t5583-push-branches.sh

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 5bb1d5aa..297927d8 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects
 SYNOPSIS
 --------
 [verse]
-'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
+'git push' [--all | --branches | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
 	   [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
 	   [-u | --set-upstream] [-o <string> | --push-option=<string>]
 	   [--[no-]signed|--signed=(true|false|if-asked)]
@@ -147,6 +147,7 @@ already exists on the remote side.
 `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
 
 --all::
+--branches::
 	Push all branches (i.e. refs under `refs/heads/`); cannot be
 	used with other <refspec>.
 
diff --git a/builtin/push.c b/builtin/push.c
index 6001e4ae..d616fa83 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -593,11 +593,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__VERBOSITY(&verbosity),
 		OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
-		OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
+		OPT_BIT( 0 , "all", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
+		OPT_ALIAS( 0 , "branches", "all"),
 		OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
 			    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
 		OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")),
-		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
+		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --branches or --mirror)")),
 		OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
 		OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
 		OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
@@ -640,7 +641,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	set_push_cert_flags(&flags, push_cert);
 
 	if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
-		die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--mirror/--tags");
+		die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--branches/--mirror/--tags");
 	if (deleterefs && argc < 2)
 		die(_("--delete doesn't make sense without any refs"));
 
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index c9acc076..1b8d6098 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -61,12 +61,20 @@ test_expect_success 'push -u :topic_2' '
 	check_config topic_2 upstream refs/heads/other2
 '
 
-test_expect_success 'push -u --all' '
+test_expect_success 'push -u --all(the same behavior with--branches)' '
 	git branch all1 &&
 	git branch all2 &&
 	git push -u --all &&
 	check_config all1 upstream refs/heads/all1 &&
-	check_config all2 upstream refs/heads/all2
+	check_config all2 upstream refs/heads/all2 &&
+	git config --get-regexp branch.all* > expect &&
+	git config --remove-section branch.all1 &&
+	git config --remove-section branch.all2 &&
+	git push -u --branches &&
+	check_config all1 upstream refs/heads/all1 &&
+	check_config all2 upstream refs/heads/all2 &&
+	git config --get-regexp branch.all* > actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'push -u HEAD' '
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index 70431122..04b47ad8 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -117,7 +117,10 @@ test_expect_success 'atomic push fails if one branch fails' '
 		test_commit five &&
 		git checkout main &&
 		test_commit six &&
-		test_must_fail git push --atomic --all up
+		test_must_fail git push --atomic --all up >output-all 2>&1 &&
+		# --all and --branches have the same behavior when be combined with --atomic
+		test_must_fail git push --atomic --branches up >output-branches 2>&1 &&
+		test_cmp output-all output-branches
 	) &&
 	test_refs main HEAD@{7} &&
 	test_refs second HEAD@{4}
diff --git a/t/t5583-push-branches.sh b/t/t5583-push-branches.sh
new file mode 100755
index 00000000..29a5c560
--- /dev/null
+++ b/t/t5583-push-branches.sh
@@ -0,0 +1,115 @@
+#!bin/sh
+
+test_description='check the consisitency of behavior of --all and --branches'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+. ./test-lib.sh
+
+delete_refs() {
+	dir=$1
+	shift
+	rm -rf deletes
+	for arg in $*
+	do
+		echo "delete ${arg}" >>deletes
+	done
+	git -C $dir update-ref --stdin < deletes
+}
+
+test_expect_success 'setup bare remote' '
+	git init --bare remote-1 &&
+	git -C remote-1 config gc.auto 0 &&
+	test_commit one &&
+	git push remote-1 HEAD
+'
+
+test_expect_success 'setup different types of references' '
+	cat >refs <<-EOF &&
+	update refs/heads/branch-1 HEAD
+	update refs/heads/branch-2 HEAD
+	EOF
+
+	git tag -a -m "annotated" annotated-1 HEAD &&
+	git tag -a -m "annotated" annotated-2 HEAD &&
+	git update-ref --stdin < refs
+'
+
+test_expect_success '--all and --branches have the same behavior' '
+	test_when_finished "delete_refs remote-1 \
+			   refs/heads/branch-1 \
+			   refs/heads/branch-2" &&
+	git push remote-1 --all &&
+	commit=$(git rev-parse HEAD) &&
+	cat >expect <<-EOF &&
+	$commit refs/heads/branch-1
+	$commit refs/heads/branch-2
+	$commit refs/heads/main
+	EOF
+
+	git -C remote-1 show-ref --heads >actual.all &&
+	delete_refs remote-1 refs/heads/branch-1 refs/heads/branch-2 &&
+	git push remote-1 --branches &&
+	git -C remote-1 show-ref --heads >actual.branches &&
+	test_cmp actual.all actual.branches &&
+	test_cmp expect actual.all
+'
+
+test_expect_success '--all or --branches can not be combined with refspecs' '
+	test_must_fail git push remote-1 --all main >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches main >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "be combined with refspecs" actual.all
+'
+
+test_expect_success '--all or --branches can not be combined with --mirror' '
+	test_must_fail git push remote-1 --all --mirror >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches --mirror >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "cannot be used together" actual.all
+'
+
+test_expect_success '--all or --branches can not be combined with --tags' '
+	test_must_fail git push remote-1 --all --tags >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches --tags >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "cannot be used together" actual.all
+'
+
+
+test_expect_success '--all or --branches can not be combined with --delete' '
+	test_must_fail git push remote-1 --all --delete >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches --delete >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "cannot be used together" actual.all
+'
+
+test_expect_success '--all or --branches combines with --follow-tags have same behavior' '
+	test_when_finished "delete_refs remote-1 \
+			   refs/heads/branch-1 \
+			   refs/heads/branch-2 \
+			   refs/tags/annotated-1 \
+			   refs/tags/annotated-2" &&
+	git push remote-1 --all --follow-tags &&
+	git -C remote-1 show-ref > actual.all &&
+	cat >expect <<-EOF &&
+	$commit refs/heads/branch-1
+	$commit refs/heads/branch-2
+	$commit refs/heads/main
+	$(git rev-parse annotated-1) refs/tags/annotated-1
+	$(git rev-parse annotated-2) refs/tags/annotated-2
+	EOF
+
+	delete_refs remote-1 \
+		    refs/heads/branch-1 \
+		    refs/heads/branch-2 \
+		    refs/tags/annotated-1 \
+		    refs/tags/annotated-2 &&
+	git push remote-1 --branches --follow-tags &&
+	git -C remote-1 show-ref >actual.branches &&
+	test_cmp actual.all actual.branches &&
+	test_cmp expect actual.all
+'
+
+test_done
-- 
2.40.1.446.gf331623a.dirty
Teng Long· May 6, 2023, 11:36 UTC · re: Teng Long · lore

[PATCH 0/1] push: introduce '--branches' option

wrong context, please ignore it, refer to
  https://public-inbox.org/git/20230506113408.61529-1-tenglong.tl@alibaba-inc.com/
Thanks.
Junio C Hamano· Dec 5, 2022, 23:35 UTC · re: Teng Long · lore

Re: [RFC PATCH 0/1] push: introduce '--heads' option

Teng Long <dyroneteng@gmail.com> writes:
Show 7 quoted lines
> From: Teng Long <dyroneteng@gmail.com>
>
> This RFC patch try to introduce a new option '--heads' in 'git-push' subcmd. The
> value of this patch may come from my personal point of view, and the patch might
> not have enough tests so far. It's pleasure to hear any suggestion, test
> scenario which need to be covered or any test method which need to be noticed if
> it's worthy.

My knee-jerk reaction is to avoid "--heads" and instead use "--branches", if this is about pushing all local branches. The option "--heads" may still remain in some commands added to the system in the earliest part of our history, but soon we started to use "branch" over "head", as it is a more commonly used word.

How should it interact with --follow-tags? Just as if you listed all local branch names on the command line? I.e. is

    git push $URL --heads
equivalent to the long-hand
    git push $URL $(git for-each-ref --format='%(refname)' refs/heads/\*)
and because of that, does
    git push $URL --any --other --option --heads
behave identically to the long-hand with these other options added?
Teng Long· Dec 15, 2022, 12:27 UTC · re: Junio C Hamano · lore

Re: [RFC PATCH 0/1] push: introduce '--heads' option

Junio C Hamano <gitster@pobox.com> writes:
Show 5 quoted lines
> My knee-jerk reaction is to avoid "--heads" and instead use
> "--branches", if this is about pushing all local branches.  The
> option "--heads" may still remain in some commands added to the
> system in the earliest part of our history, but soon we started
> to use "branch" over "head", as it is a more commonly used word.

OK, that's true, I just misled by some existing '--heads' in other commands.

> How should it interact with --follow-tags?  Just as if you listed
> all local branch names on the command line?  I.e. is

Actually I didn't try '--follow-tags' before, but the documentation about it is a ittle hard to understand for me on first reading. Then, I think it supports to use as negative '--[no-]follow-tags' but not marked in the git-push.txt documentation.

Show 5 quoted lines
>     git push $URL --heads
>
> equivalent to the long-hand
>
>     git push $URL $(git for-each-ref --format='%(refname)' refs/heads/\*)

git push $URL $(git for-each-ref --format='%(refname)' refs/heads/\*\*) maybe to recursivly subdirectories matching?

Actually I didn't get why you represent this, maybe try to let's us know there is another way we could make it as the same result?

Show 5 quoted lines
> and because of that, does
>
>     git push $URL --any --other --option --heads
>
> behave identically to the long-hand with these other options added?

I think you concerned about the compatibility with the interaction of the options, if so, I think a direct way is to keep --all and --heads both have the some behavior when interact with other options, a little confused why we have to use the long-hand to do that.

By the way, it seems like there are no specify tests for '--all', maybe we can add some tests about '--all' first if this RFC patch is worthy to continue.

Thanks.
Teng Long· Apr 28, 2023, 09:59 UTC · re: Junio C Hamano · lore

Re: [RFC PATCH 0/1] push: introduce '--heads' option

Junio C Hamano <gitster@pobox.com> writes:
Show 20 quoted lines
>My knee-jerk reaction is to avoid "--heads" and instead use
>"--branches", if this is about pushing all local branches.  The
>option "--heads" may still remain in some commands added to the
>system in the earliest part of our history, but soon we started
>to use "branch" over "head", as it is a more commonly used word.
>
>How should it interact with --follow-tags?  Just as if you listed
>all local branch names on the command line?  I.e. is
>
>    git push $URL --heads
>
>equivalent to the long-hand
>
>    git push $URL $(git for-each-ref --format='%(refname)' refs/heads/\*)
>
>and because of that, does
>
>    git push $URL --any --other --option --heads
>
>behave identically to the long-hand with these other options added?

ZheNing Hu mentioned me that could use "OPT_ALIAS" instead, it seems like could be better than OPT_BIT in this scenario. If so, are problems that may arise from interactions shielded? If not, I'm willing to add extra test about it (some relevant advice if possible).

Thanks.
Junio C Hamano· Apr 28, 2023, 18:48 UTC · re: Teng Long · lore

Re: [RFC PATCH 0/1] push: introduce '--heads' option

Teng Long <dyroneteng@gmail.com> writes:
> ZheNing Hu mentioned me that could use "OPT_ALIAS" instead, it seems
> like could be better than OPT_BIT in this scenario. If so, are problems
> that may arise from interactions shielded? If not, I'm willing to add
> extra test about it (some relevant advice if possible).

The intent of ALIAS is to just add an extra option visible at the UI level that behaves exactly the same as the other one at the code level, so the codepath that is prepared to deal with one can handle the other one without any extra effort. In fact, after the option parsing is finished, the rest of the code should not even be able to tell which one, the original or the alias, was used on the command line.

And in this case, you'd want a new "push all branches" option that behaves exactly like existing "--all", and possibly you may over time want to deprecate the latter. All the code to ensure how "--all" should interact with other options should be working fine (or if there is a bug, that needs to be corrected whether we would add this alias or not).

Sounds like a very good plan to me.
Thanks.
Teng Long· Apr 30, 2023, 01:09 UTC · re: Junio C Hamano · lore

Re: [RFC PATCH 0/1] push: introduce '--heads' option

Junio C Hamano <gitster@pobox.com> writes:
Show 21 quoted lines
>Teng Long <dyroneteng@gmail.com> writes:
>
>> ZheNing Hu mentioned me that could use "OPT_ALIAS" instead, it seems
>> like could be better than OPT_BIT in this scenario. If so, are problems
>> that may arise from interactions shielded? If not, I'm willing to add
>> extra test about it (some relevant advice if possible).
>
>The intent of ALIAS is to just add an extra option visible at the UI
>level that behaves exactly the same as the other one at the code
>level, so the codepath that is prepared to deal with one can handle
>the other one without any extra effort.  In fact, after the option
>parsing is finished, the rest of the code should not even be able to
>tell which one, the original or the alias, was used on the command
>line.
>
>And in this case, you'd want a new "push all branches" option that
>behaves exactly like existing "--all", and possibly you may over
>time want to deprecate the latter.  All the code to ensure how
>"--all" should interact with other options should be working fine
>(or if there is a bug, that needs to be corrected whether we would
>add this alias or not).
Make sense.
Thanks.
Teng Long· May 6, 2023, 11:34 UTC · re: Teng Long · lore

[PATCH 0/1] push: introduce '--branches' option

From: Teng Long <dyroneteng@gmail.com>

Based on the feedback I got from the previous RFC patch, I made a formal patch with some additional test cases, but I don't know if the scenarios covered by the test cases are sufficient, if not, the cases will be improved in a subsequent patch.

Thanks.
Teng Long (1):
  push: introduce '--branches' option
 Documentation/git-push.txt |   3 +-
 builtin/push.c             |   7 ++-
 t/t5523-push-upstream.sh   |  12 +++-
 t/t5543-atomic-push.sh     |   5 +-
 t/t5583-push-branches.sh   | 115 +++++++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+), 7 deletions(-)
 create mode 100755 t/t5583-push-branches.sh

Range-diff: 1: 9c9438c3 < -: -------- push: introduce '--heads' option -: -------- > 1: b16bdfe6 push: introduce '--branches' option

-- 
2.40.1.446.gf331623a.dirty
Teng Long· May 6, 2023, 11:34 UTC · re: Teng Long · lore

[PATCH 1/1] push: introduce '--branches' option

From: Teng Long <dyroneteng@gmail.com>

The '--all' option of git-push built-in cmd support to push all branches (refs under refs/heads) to remote. Under the usage, a user can easlily work in some scenarios, for example, branches synchronization and batch upload.

The '--all' was introduced for a long time, meanwhile, git supports to customize the storage location under "refs/". when a new git user see the usage like, 'git push origin --all', we might feel like we're pushing _all_ the refs instead of just branches without looking at the documents until we found the related description of it or '--mirror'.

To ensure compatibility, we cannot rename '--all' to another name directly, one way is, we can try to add a new option '--heads' which be identical with the functionality of '--all' to let the user understand the meaning of representation more clearly. Actually, We've more or less named options this way already, for example, in 'git-show-ref' and 'git ls-remote'.

At the same time, we fix a related issue about the wrong help information of '--all' option in code and add some test cases in t5523, t5543 and t5583.

Signed-off-by: Teng Long <dyroneteng@gmail.com>
---
 Documentation/git-push.txt |   3 +-
 builtin/push.c             |   7 ++-
 t/t5523-push-upstream.sh   |  12 +++-
 t/t5543-atomic-push.sh     |   5 +-
 t/t5583-push-branches.sh   | 115 +++++++++++++++++++++++++++++++++++++
 5 files changed, 135 insertions(+), 7 deletions(-)
 create mode 100755 t/t5583-push-branches.sh
Show changes to 5 files +135 −7

Documentation/git-push.txt, builtin/push.c, t/t5523-push-upstream.sh, t/t5543-atomic-push.sh, t/t5583-push-branches.sh

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 5bb1d5aa..297927d8 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects
 SYNOPSIS
 --------
 [verse]
-'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
+'git push' [--all | --branches | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
 	   [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
 	   [-u | --set-upstream] [-o <string> | --push-option=<string>]
 	   [--[no-]signed|--signed=(true|false|if-asked)]
@@ -147,6 +147,7 @@ already exists on the remote side.
 `tag <tag>` means the same as `refs/tags/<tag>:refs/tags/<tag>`.
 
 --all::
+--branches::
 	Push all branches (i.e. refs under `refs/heads/`); cannot be
 	used with other <refspec>.
 
diff --git a/builtin/push.c b/builtin/push.c
index 6001e4ae..d616fa83 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -593,11 +593,12 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT__VERBOSITY(&verbosity),
 		OPT_STRING( 0 , "repo", &repo, N_("repository"), N_("repository")),
-		OPT_BIT( 0 , "all", &flags, N_("push all refs"), TRANSPORT_PUSH_ALL),
+		OPT_BIT( 0 , "all", &flags, N_("push all branches"), TRANSPORT_PUSH_ALL),
+		OPT_ALIAS( 0 , "branches", "all"),
 		OPT_BIT( 0 , "mirror", &flags, N_("mirror all refs"),
 			    (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE)),
 		OPT_BOOL('d', "delete", &deleterefs, N_("delete refs")),
-		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --mirror)")),
+		OPT_BOOL( 0 , "tags", &tags, N_("push tags (can't be used with --all or --branches or --mirror)")),
 		OPT_BIT('n' , "dry-run", &flags, N_("dry run"), TRANSPORT_PUSH_DRY_RUN),
 		OPT_BIT( 0,  "porcelain", &flags, N_("machine-readable output"), TRANSPORT_PUSH_PORCELAIN),
 		OPT_BIT('f', "force", &flags, N_("force updates"), TRANSPORT_PUSH_FORCE),
@@ -640,7 +641,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 	set_push_cert_flags(&flags, push_cert);
 
 	if (deleterefs && (tags || (flags & (TRANSPORT_PUSH_ALL | TRANSPORT_PUSH_MIRROR))))
-		die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--mirror/--tags");
+		die(_("options '%s' and '%s' cannot be used together"), "--delete", "--all/--branches/--mirror/--tags");
 	if (deleterefs && argc < 2)
 		die(_("--delete doesn't make sense without any refs"));
 
diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh
index c9acc076..1b8d6098 100755
--- a/t/t5523-push-upstream.sh
+++ b/t/t5523-push-upstream.sh
@@ -61,12 +61,20 @@ test_expect_success 'push -u :topic_2' '
 	check_config topic_2 upstream refs/heads/other2
 '
 
-test_expect_success 'push -u --all' '
+test_expect_success 'push -u --all(the same behavior with--branches)' '
 	git branch all1 &&
 	git branch all2 &&
 	git push -u --all &&
 	check_config all1 upstream refs/heads/all1 &&
-	check_config all2 upstream refs/heads/all2
+	check_config all2 upstream refs/heads/all2 &&
+	git config --get-regexp branch.all* > expect &&
+	git config --remove-section branch.all1 &&
+	git config --remove-section branch.all2 &&
+	git push -u --branches &&
+	check_config all1 upstream refs/heads/all1 &&
+	check_config all2 upstream refs/heads/all2 &&
+	git config --get-regexp branch.all* > actual &&
+	test_cmp expect actual
 '
 
 test_expect_success 'push -u HEAD' '
diff --git a/t/t5543-atomic-push.sh b/t/t5543-atomic-push.sh
index 70431122..04b47ad8 100755
--- a/t/t5543-atomic-push.sh
+++ b/t/t5543-atomic-push.sh
@@ -117,7 +117,10 @@ test_expect_success 'atomic push fails if one branch fails' '
 		test_commit five &&
 		git checkout main &&
 		test_commit six &&
-		test_must_fail git push --atomic --all up
+		test_must_fail git push --atomic --all up >output-all 2>&1 &&
+		# --all and --branches have the same behavior when be combined with --atomic
+		test_must_fail git push --atomic --branches up >output-branches 2>&1 &&
+		test_cmp output-all output-branches
 	) &&
 	test_refs main HEAD@{7} &&
 	test_refs second HEAD@{4}
diff --git a/t/t5583-push-branches.sh b/t/t5583-push-branches.sh
new file mode 100755
index 00000000..29a5c560
--- /dev/null
+++ b/t/t5583-push-branches.sh
@@ -0,0 +1,115 @@
+#!bin/sh
+
+test_description='check the consisitency of behavior of --all and --branches'
+
+GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
+export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
+
+. ./test-lib.sh
+
+delete_refs() {
+	dir=$1
+	shift
+	rm -rf deletes
+	for arg in $*
+	do
+		echo "delete ${arg}" >>deletes
+	done
+	git -C $dir update-ref --stdin < deletes
+}
+
+test_expect_success 'setup bare remote' '
+	git init --bare remote-1 &&
+	git -C remote-1 config gc.auto 0 &&
+	test_commit one &&
+	git push remote-1 HEAD
+'
+
+test_expect_success 'setup different types of references' '
+	cat >refs <<-EOF &&
+	update refs/heads/branch-1 HEAD
+	update refs/heads/branch-2 HEAD
+	EOF
+
+	git tag -a -m "annotated" annotated-1 HEAD &&
+	git tag -a -m "annotated" annotated-2 HEAD &&
+	git update-ref --stdin < refs
+'
+
+test_expect_success '--all and --branches have the same behavior' '
+	test_when_finished "delete_refs remote-1 \
+			   refs/heads/branch-1 \
+			   refs/heads/branch-2" &&
+	git push remote-1 --all &&
+	commit=$(git rev-parse HEAD) &&
+	cat >expect <<-EOF &&
+	$commit refs/heads/branch-1
+	$commit refs/heads/branch-2
+	$commit refs/heads/main
+	EOF
+
+	git -C remote-1 show-ref --heads >actual.all &&
+	delete_refs remote-1 refs/heads/branch-1 refs/heads/branch-2 &&
+	git push remote-1 --branches &&
+	git -C remote-1 show-ref --heads >actual.branches &&
+	test_cmp actual.all actual.branches &&
+	test_cmp expect actual.all
+'
+
+test_expect_success '--all or --branches can not be combined with refspecs' '
+	test_must_fail git push remote-1 --all main >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches main >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "be combined with refspecs" actual.all
+'
+
+test_expect_success '--all or --branches can not be combined with --mirror' '
+	test_must_fail git push remote-1 --all --mirror >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches --mirror >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "cannot be used together" actual.all
+'
+
+test_expect_success '--all or --branches can not be combined with --tags' '
+	test_must_fail git push remote-1 --all --tags >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches --tags >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "cannot be used together" actual.all
+'
+
+
+test_expect_success '--all or --branches can not be combined with --delete' '
+	test_must_fail git push remote-1 --all --delete >actual.all 2>&1 &&
+	test_must_fail git push remote-1 --branches --delete >actual.branches 2>&1 &&
+	test_cmp actual.all actual.branches &&
+	grep "cannot be used together" actual.all
+'
+
+test_expect_success '--all or --branches combines with --follow-tags have same behavior' '
+	test_when_finished "delete_refs remote-1 \
+			   refs/heads/branch-1 \
+			   refs/heads/branch-2 \
+			   refs/tags/annotated-1 \
+			   refs/tags/annotated-2" &&
+	git push remote-1 --all --follow-tags &&
+	git -C remote-1 show-ref > actual.all &&
+	cat >expect <<-EOF &&
+	$commit refs/heads/branch-1
+	$commit refs/heads/branch-2
+	$commit refs/heads/main
+	$(git rev-parse annotated-1) refs/tags/annotated-1
+	$(git rev-parse annotated-2) refs/tags/annotated-2
+	EOF
+
+	delete_refs remote-1 \
+		    refs/heads/branch-1 \
+		    refs/heads/branch-2 \
+		    refs/tags/annotated-1 \
+		    refs/tags/annotated-2 &&
+	git push remote-1 --branches --follow-tags &&
+	git -C remote-1 show-ref >actual.branches &&
+	test_cmp actual.all actual.branches &&
+	test_cmp expect actual.all
+'
+
+test_done
-- 
2.40.1.446.gf331623a.dirty
Junio C Hamano· May 6, 2023, 21:39 UTC · re: Teng Long · lore

Re: [PATCH 1/1] push: introduce '--branches' option

Teng Long <dyroneteng@gmail.com> writes:
> -'git push' [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
> +'git push' [--all | --branches | --mirror | --tags] [--follow-tags] ...
Will queue.

By the way, you may want to check and correct your patch sending procedure. Somebody in your toolchain is adding "--cc=" to the first recipient address or something silly like that.

> Cc: --cc=avarab@gmail.com,  git@vger.kernel.org,  me@ttaylorr.com,  tenglong.tl@alibaba-inc.com,  adlternative@gmail.com
Teng Long· May 7, 2023, 06:43 UTC · re: Junio C Hamano · lore

Re: [PATCH 1/1] push: introduce '--branches' option

Junio C Hamano <gitster@pobox.com> writes:
>By the way, you may want to check and correct your patch sending
>procedure.  Somebody in your toolchain is adding "--cc=" to the
>first recipient address or something silly like that.
My fault, thank you for mentioning that.
Thanks.

← back to recent threads