Subject: Re: [RFC PATCH v2 2/2] push: support pushing to a remote group

From: Junio C Hamano <[email-masked]>
Date: Wed, 18 Mar 2026 13:57:48 -0700

Usman Akinyemi <[email-masked]> writes:

> A known interaction: push.default = simple will die when the current
> branch has no upstream configured, because setup_default_push_refspecs()
> requires an upstream for that mode. Users pushing to a group should set
> push.default = current or supply explicit refspecs. This is consistent
> with how fetch handles default refspec resolution per remote.

Even if you are not pushing to a group but to a single remote,
default=simple would die when the current branch has no upstream
configured, so I do not know what the point of singling
"default=simple" out is in the above paragraph.  For that matter, is
"default=current" so special and would it be the only way, other
than giving an explicit refspec, to make the push succeed?  Wouldn't
default=matching, for example, work equally well?

> +When a group name is given as the `<repository>` argument, the push is
> +performed to each member remote in turn.  The defining principle is:
> +
> +	git push <options> all-remotes <args>
> +
> +is exactly equivalent to:
> +
> +	git push <options> r1 <args>
> +	git push <options> r2 <args>
> +	...
> +	git push <options> rN <args>
> +
> +where r1, r2, ..., rN are the members of `all-remotes`.  No special
> +behaviour is added or removed — the group is purely a shorthand for
> +running the same push command against each member remote individually.

One thing this does not make it clear is if we abort upon the first
failure, or even after some fail we still attempt to push to the
rest of the remotes in the group.

> +Similarly, if `--force-with-lease` is given without an explicit expected
> +commit, Git will guess the expected commit for each remote independently
> +from that remote's own remote-tracking branch, the same way it would if
> +each push were run separately.

Understandable (even though it would be obvious from the "exactly
equivalent to" above).

> If an explicit commit is given with
> +`--force-with-lease=<refname>:<expect>`, that same value is forwarded
> +to every member remote, as if each of
> +`git push --force-with-lease=<refname>:<expect> r1`,
> +`git push --force-with-lease=<refname>:<expect> r2`, ...,
> +`git push --force-with-lease=<refname>:<expect> rN` had been invoked.

Understandable (ditto).

> diff --git a/builtin/push.c b/builtin/push.c
> index 5b6cebbb85..33de769a33 100644
> --- a/builtin/push.c
> +++ b/builtin/push.c
> @@ -542,7 +542,6 @@ static int git_push_config(const char *k, const char *v,
>  
>  	return git_default_config(k, v, ctx, NULL);
>  }
> -
>  int cmd_push(int argc,
>  	     const char **argv,
>  	     const char *prefix,

You didn't want to include this hunk, I presume?

Thanks.