git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Phillip Wood <phillip.wood123@gmail.com>
To: Srinidhi Kaushik <shrinidhi.kaushik@gmail.com>, git@vger.kernel.org
Subject: Re: [PATCH v5 1/3] push: add reflog check for "--force-if-includes"
Date: Wed, 23 Sep 2020 11:18:43 +0100	[thread overview]
Message-ID: <3c254220-de10-8e17-1175-f88e790c17a6@gmail.com> (raw)
In-Reply-To: <20200923073022.61293-2-shrinidhi.kaushik@gmail.com>

Hi Srinidhi

I think this is moving forward in the right direction, I've got a couple 
of comments below. Note I've only looked at the first part of the patch 
as I'm not that familiar with the rest of the code.

On 23/09/2020 08:30, Srinidhi Kaushik wrote:
> Add a check to verify if the remote-tracking ref of the local branch
> is reachable from one of its "reflog" entries.
> 
> When a local branch that is based on a remote ref, has been rewound
> and is to be force pushed on the remote, "--force-if-includes" runs
> a check that ensures any updates to remote-tracking refs that may have

nit pick - there is only one remote tracking ref for each local ref

> happened (by push from another repository) in-between the time of the

s/push/fetch/ ?

> last checkout,

more generally it is the last time we updated the local branch to 
incorporate any fetched changes in the remote tracking branch, this 
includes `pull --rebase` `pull --merge` as well as checking out the 
remote ref

> and right before the time of push, have been integrated
> locally before allowing a forced updated.
> 
> A new field "use_force_if_includes" has been added to "push_cas_option",
> which is set to "1" when "--force-if-includes" is specified as an
> option in the command line or as a configuration setting.
> 
> The struct "ref" has two new bit-fields:
>    - check_reachable:
>      Set when we have to run the new check on the ref, and the remote
>      ref was marked as "use_tracking" or "use_tracking_for_rest" by
>      compare-and-swap (if the "the remote tip must be at the expected
>      commit" condition is not specified); "apply_push_cas()" has been
>      updated to check if this field is set and run the check.
> 
>    - unreachable:
>      Set if the ref is unreachable from any of the "reflog" entries of
>      its local counterpart.
> 
> "REF_STATUS_REJECT_REMOTE_UPDATED" has been added to the "status"
> enum to imply that the ref failed the check; "case" statements in
> "send-pack", "transport" and "transport-helper" have been updated
> accordingly to catch this status when set.

This is quite a long description of the implementation, I think it would 
be more helpful to the reader to concentrate on what the new feature is 
and why it is useful.

> 
> When "--force-is-includes" is used along with "--force-with-lease",

s/-is-/-if-/

> the check runs only for refs marked as "if_includes". If the option
> is passed without specifying "--force-with-lease", or specified along
> with "--force-with-lease=<refname>:<expect>" it is a "no-op".

If I've understood this correctly `--force-if-includes` does nothing on 
its own - I had hoped it would imply --force-with-lease

> 
> Signed-off-by: Srinidhi Kaushik <shrinidhi.kaushik@gmail.com>
> ---
>   builtin/send-pack.c |   5 ++
>   remote.c            | 140 +++++++++++++++++++++++++++++++++++++++++++-
>   remote.h            |   8 ++-
>   send-pack.c         |   1 +
>   transport-helper.c  |   5 ++
>   transport.c         |   6 ++
>   6 files changed, 162 insertions(+), 3 deletions(-)
> 
> diff --git a/builtin/send-pack.c b/builtin/send-pack.c
> index 2b9610f121..4d76727edb 100644
> --- a/builtin/send-pack.c
> +++ b/builtin/send-pack.c
> @@ -69,6 +69,11 @@ static void print_helper_status(struct ref *ref)
>   			msg = "stale info";
>   			break;
>   
> +		case REF_STATUS_REJECT_REMOTE_UPDATED:
> +			res = "error";
> +			msg = "remote ref updated since checkout";
> +			break;
> +
>   		case REF_STATUS_REJECT_ALREADY_EXISTS:
>   			res = "error";
>   			msg = "already exists";
> diff --git a/remote.c b/remote.c
> index eafc14cbe7..0dcac4ab8e 100644
> --- a/remote.c
> +++ b/remote.c
> @@ -1471,12 +1471,23 @@ void set_ref_status_for_push(struct ref *remote_refs, int send_mirror,
>   		 * with the remote-tracking branch to find the value
>   		 * to expect, but we did not have such a tracking
>   		 * branch.
> +		 *
> +		 * If the tip of the remote-tracking ref is unreachable
> +		 * from any reflog entry of its local ref indicating a
> +		 * possible update since checkout; reject the push.
>   		 */
>   		if (ref->expect_old_sha1) {
>   			if (!oideq(&ref->old_oid, &ref->old_oid_expect))
>   				reject_reason = REF_STATUS_REJECT_STALE;
> +			else if (ref->check_reachable && ref->unreachable)
> +				reject_reason =
> +					REF_STATUS_REJECT_REMOTE_UPDATED;
>   			else
> -				/* If the ref isn't stale then force the update. */
> +				/*
> +				 * If the ref isn't stale, and is reachable
> +				 * from from one of the reflog entries of
> +				 * the local branch, force the update.
> +				 */
>   				force_ref_update = 1;
>   		}
>   
> @@ -2268,6 +2279,118 @@ static int remote_tracking(struct remote *remote, const char *refname,
>   	return 0;
>   }
>   
> +/*
> + * The struct "reflog_commit_list" and related helper functions
> + * for list manipulation are used for collecting commits into a
> + * list during reflog traversals in "if_exists_or_grab_until()".
> + */
> +struct reflog_commit_list {
> +	struct commit **items;
> +	size_t nr, alloc;
> +};
> +
> +/* Adds a commit to list. */
> +static void add_commit(struct reflog_commit_list *list, struct commit *commit)
> +{
> +	ALLOC_GROW(list->items, list->nr + 1, list->alloc);
> +	list->items[list->nr++] = commit;
> +}
> +
> +/* Free and reset the list. */
> +static void free_reflog_commit_list(struct reflog_commit_list *list)
> +{
> +	FREE_AND_NULL(list->items);
> +	list->nr = list->alloc = 0;
> +}
> +
> +struct check_and_collect_until_cb_data {
> +	struct commit *remote_commit;
> +	struct reflog_commit_list *local_commits;
> +};
> +
> +
> +static int check_and_collect_until(struct object_id *o_oid,
> +				   struct object_id *n_oid,
> +				   const char *ident, timestamp_t timestamp,
> +				   int tz, const char *message, void *cb_data)
> +{
> +	struct commit *commit;
> +	struct check_and_collect_until_cb_data *cb = cb_data;
> +
> +	/*
> +	 * If the reflog entry timestamp is older than the
> +	 * remote commit date, there is no need to check or
> +	 * collect entries older than this one.
> +	 */
> +	if (timestamp < cb->remote_commit->date)

It's great that you've incorporated a date check, however I think we 
need to check the local reflog timestamp against the last time the 
remote ref was updated (i.e. the remote reflog timestamp), not the 
commit date of the commit that the remote ref points too. We are 
interested in whether the local branch has incorporated the remote 
branch since the last time the remote branch was updated.

> +		return -1;
> +
> +	/* An entry was found. */
> +	if (oideq(n_oid, &cb->remote_commit->object.oid))
> +		return 1;
> +
> +	/* Lookup the commit and append it to the list. */
> +	if ((commit = lookup_commit_reference(the_repository, n_oid)))
> +		add_commit(cb->local_commits, commit);

I think Junio suggested batching the commits for the merge base check 
into small groups, rather than checking them all at once

Best Wishes

Phillip

> +
> +	return 0;
> +}
> +
> +/*
> + * Iterate through the reflog of a local ref to check if there is an entry for
> + * the given remote-tracking ref (i.e., if it was checked out); runs until the
> + * timestamp of an entry is older than the commit date of the remote-tracking
> + * ref. Any commits that seen along the way are collected into a list to check
> + * if the remote-tracking ref is reachable from any of them.
> + */
> +static int is_reachable_in_reflog(const char *local_ref_name,
> +				  const struct object_id *remote_oid)
> +{
> +	struct commit *remote_commit;
> +	struct reflog_commit_list list = { NULL, 0, 0 };
> +	struct check_and_collect_until_cb_data cb;
> +	int ret = 0;
> +
> +	remote_commit = lookup_commit_reference(the_repository, remote_oid);
> +	if (!remote_commit)
> +		goto cleanup_return;
> +
> +	cb.remote_commit = remote_commit;
> +	cb.local_commits = &list;
> +	ret = for_each_reflog_ent_reverse(local_ref_name,
> +					  check_and_collect_until, &cb);
> +
> +	/* We found an entry in the reflog. */
> +	if (ret > 0)
> +		goto cleanup_return;
> +
> +	/*
> +	 * Check if "remote_commit" is reachable from
> +	 * any of the commits in the collected list.
> +	 */
> +	if (list.nr > 0)
> +		ret = in_merge_bases_many(remote_commit, list.nr, list.items);
> +
> +cleanup_return:
> +	free_reflog_commit_list(&list);
> +	return ret;
> +}
> +
> +/*
> + * Check for reachability of a remote-tracking
> + * ref in the reflog entries of its local ref.
> + */
> +static void check_if_includes_upstream(struct ref *remote_ref)
> +{
> +	struct ref *local_ref = get_local_ref(remote_ref->name);
> +
> +	if (!local_ref)
> +		return;
> +
> +	if (!is_reachable_in_reflog(local_ref->name, &remote_ref->old_oid))
> +		remote_ref->unreachable = 1;
> +}
> +
>   static void apply_cas(struct push_cas_option *cas,
>   		      struct remote *remote,
>   		      struct ref *ref)
> @@ -2284,6 +2407,8 @@ static void apply_cas(struct push_cas_option *cas,
>   			oidcpy(&ref->old_oid_expect, &entry->expect);
>   		else if (remote_tracking(remote, ref->name, &ref->old_oid_expect))
>   			oidclr(&ref->old_oid_expect);
> +		else
> +			ref->check_reachable = cas->use_force_if_includes;
>   		return;
>   	}
>   
> @@ -2294,6 +2419,8 @@ static void apply_cas(struct push_cas_option *cas,
>   	ref->expect_old_sha1 = 1;
>   	if (remote_tracking(remote, ref->name, &ref->old_oid_expect))
>   		oidclr(&ref->old_oid_expect);
> +	else
> +		ref->check_reachable = cas->use_force_if_includes;
>   }
>   
>   void apply_push_cas(struct push_cas_option *cas,
> @@ -2301,6 +2428,15 @@ void apply_push_cas(struct push_cas_option *cas,
>   		    struct ref *remote_refs)
>   {
>   	struct ref *ref;
> -	for (ref = remote_refs; ref; ref = ref->next)
> +	for (ref = remote_refs; ref; ref = ref->next) {
>   		apply_cas(cas, remote, ref);
> +
> +		/*
> +		 * If "compare-and-swap" is in "use_tracking[_for_rest]"
> +		 * mode, and if "--force-if-includes" was specified, run
> +		 * the check.
> +		 */
> +		if (ref->check_reachable)
> +			check_if_includes_upstream(ref);
> +	}
>   }
> diff --git a/remote.h b/remote.h
> index 5e3ea5a26d..7c5e59770e 100644
> --- a/remote.h
> +++ b/remote.h
> @@ -104,7 +104,11 @@ struct ref {
>   		forced_update:1,
>   		expect_old_sha1:1,
>   		exact_oid:1,
> -		deletion:1;
> +		deletion:1,
> +		/* Need to check if local reflog reaches the remote tip. */
> +		check_reachable:1,
> +		/* The local reflog does not reach the remote tip. */
> +		unreachable:1;
>   
>   	enum {
>   		REF_NOT_MATCHED = 0, /* initial value */
> @@ -134,6 +138,7 @@ struct ref {
>   		REF_STATUS_REJECT_NEEDS_FORCE,
>   		REF_STATUS_REJECT_STALE,
>   		REF_STATUS_REJECT_SHALLOW,
> +		REF_STATUS_REJECT_REMOTE_UPDATED,
>   		REF_STATUS_UPTODATE,
>   		REF_STATUS_REMOTE_REJECT,
>   		REF_STATUS_EXPECTING_REPORT,
> @@ -332,6 +337,7 @@ struct ref *get_stale_heads(struct refspec *rs, struct ref *fetch_map);
>   
>   struct push_cas_option {
>   	unsigned use_tracking_for_rest:1;
> +	unsigned use_force_if_includes:1;
>   	struct push_cas {
>   		struct object_id expect;
>   		unsigned use_tracking:1;
> diff --git a/send-pack.c b/send-pack.c
> index 632f1580ca..956306e8e8 100644
> --- a/send-pack.c
> +++ b/send-pack.c
> @@ -240,6 +240,7 @@ static int check_to_send_update(const struct ref *ref, const struct send_pack_ar
>   	case REF_STATUS_REJECT_FETCH_FIRST:
>   	case REF_STATUS_REJECT_NEEDS_FORCE:
>   	case REF_STATUS_REJECT_STALE:
> +	case REF_STATUS_REJECT_REMOTE_UPDATED:
>   	case REF_STATUS_REJECT_NODELETE:
>   		return CHECK_REF_STATUS_REJECTED;
>   	case REF_STATUS_UPTODATE:
> diff --git a/transport-helper.c b/transport-helper.c
> index c52c99d829..e547e21199 100644
> --- a/transport-helper.c
> +++ b/transport-helper.c
> @@ -779,6 +779,10 @@ static int push_update_ref_status(struct strbuf *buf,
>   			status = REF_STATUS_REJECT_STALE;
>   			FREE_AND_NULL(msg);
>   		}
> +		else if (!strcmp(msg, "remote ref updated since checkout")) {
> +			status = REF_STATUS_REJECT_REMOTE_UPDATED;
> +			FREE_AND_NULL(msg);
> +		}
>   		else if (!strcmp(msg, "forced update")) {
>   			forced = 1;
>   			FREE_AND_NULL(msg);
> @@ -897,6 +901,7 @@ static int push_refs_with_push(struct transport *transport,
>   		case REF_STATUS_REJECT_NONFASTFORWARD:
>   		case REF_STATUS_REJECT_STALE:
>   		case REF_STATUS_REJECT_ALREADY_EXISTS:
> +		case REF_STATUS_REJECT_REMOTE_UPDATED:
>   			if (atomic) {
>   				reject_atomic_push(remote_refs, mirror);
>   				string_list_clear(&cas_options, 0);
> diff --git a/transport.c b/transport.c
> index 43e24bf1e5..99fe6233a3 100644
> --- a/transport.c
> +++ b/transport.c
> @@ -567,6 +567,11 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count,
>   		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
>   				 "stale info", porcelain, summary_width);
>   		break;
> +	case REF_STATUS_REJECT_REMOTE_UPDATED:
> +		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
> +				 "remote ref updated since checkout",
> +				 porcelain, summary_width);
> +		break;
>   	case REF_STATUS_REJECT_SHALLOW:
>   		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
>   				 "new shallow roots not allowed",
> @@ -1101,6 +1106,7 @@ static int run_pre_push_hook(struct transport *transport,
>   		if (!r->peer_ref) continue;
>   		if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue;
>   		if (r->status == REF_STATUS_REJECT_STALE) continue;
> +		if (r->status == REF_STATUS_REJECT_REMOTE_UPDATED) continue;
>   		if (r->status == REF_STATUS_UPTODATE) continue;
>   
>   		strbuf_reset(&buf);
> 


  reply	other threads:[~2020-09-23 10:18 UTC|newest]

Thread overview: 120+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-04 18:51 [PATCH] push: make `--force-with-lease[=<ref>]` safer Srinidhi Kaushik
2020-09-07 15:23 ` Phillip Wood
2020-09-08 15:48   ` Srinidhi Kaushik
2020-09-07 16:14 ` Junio C Hamano
2020-09-08 16:00   ` Srinidhi Kaushik
2020-09-08 21:00     ` Junio C Hamano
2020-09-07 19:45 ` Johannes Schindelin
2020-09-08 15:58   ` Junio C Hamano
2020-09-09  3:40     ` Johannes Schindelin
2020-09-08 16:59   ` Srinidhi Kaushik
2020-09-16 11:55     ` Johannes Schindelin
2020-09-08 19:34   ` Junio C Hamano
2020-09-09  3:44     ` Johannes Schindelin
2020-09-10 10:22       ` Johannes Schindelin
2020-09-10 14:44         ` Srinidhi Kaushik
2020-09-11 22:16           ` Johannes Schindelin
2020-09-14 11:06             ` Srinidhi Kaushik
2020-09-14 20:08             ` Junio C Hamano
2020-09-16  5:31               ` Srinidhi Kaushik
2020-09-16 10:20                 ` Johannes Schindelin
2020-09-19 17:48                   ` Junio C Hamano
2020-09-10 14:46         ` Junio C Hamano
2020-09-11 22:17           ` Johannes Schindelin
2020-09-14 20:07             ` Junio C Hamano
2020-09-12 15:04 ` [PATCH v2 0/2] push: make "--force-with-lease" safer Srinidhi Kaushik
2020-09-12 15:04   ` [PATCH v2 1/2] push: add "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-12 18:20     ` Junio C Hamano
2020-09-12 21:25       ` Srinidhi Kaushik
2020-09-12 15:04   ` [PATCH v2 2/2] push: enable "forceIfIncludesWithLease" by default Srinidhi Kaushik
2020-09-12 18:22     ` Junio C Hamano
2020-09-12 18:15   ` [PATCH v2 0/2] push: make "--force-with-lease" safer Junio C Hamano
2020-09-12 21:03     ` Srinidhi Kaushik
2020-09-13 14:54   ` [PATCH v3 0/7] push: add "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-13 14:54     ` [PATCH v3 1/7] remote: add reflog check for "force-if-includes" Srinidhi Kaushik
2020-09-14 20:17       ` Junio C Hamano
2020-09-16 10:51         ` Srinidhi Kaushik
2020-09-14 20:31       ` Junio C Hamano
2020-09-14 21:13       ` Junio C Hamano
2020-09-16 12:35       ` Johannes Schindelin
2020-09-19 17:01         ` Srinidhi Kaushik
2020-09-13 14:54     ` [PATCH v3 2/7] transport: add flag for "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-13 14:54     ` [PATCH v3 3/7] send-pack: check ref status for "force-if-includes" Srinidhi Kaushik
2020-09-13 14:54     ` [PATCH v3 4/7] transport-helper: update " Srinidhi Kaushik
2020-09-13 14:54     ` [PATCH v3 5/7] builtin/push: add option "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-16 12:36       ` Johannes Schindelin
2020-09-13 14:54     ` [PATCH v3 6/7] doc: add reference for "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-14 21:01       ` Junio C Hamano
2020-09-16  5:35         ` Srinidhi Kaushik
2020-09-13 14:54     ` [PATCH v3 7/7] t: add tests for "force-if-includes" Srinidhi Kaushik
2020-09-16 12:47     ` [PATCH v3 0/7] push: add "--[no-]force-if-includes" Johannes Schindelin
2020-09-19 17:03   ` [PATCH v4 0/3] " Srinidhi Kaushik
2020-09-19 17:03     ` [PATCH v4 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-09-19 20:03       ` Junio C Hamano
2020-09-21  8:42         ` Srinidhi Kaushik
2020-09-21 18:48           ` Junio C Hamano
2020-09-23 10:22             ` Srinidhi Kaushik
2020-09-23 16:47               ` Junio C Hamano
2020-09-21 13:19         ` Phillip Wood
2020-09-21 16:12           ` Junio C Hamano
2020-09-21 18:11             ` Junio C Hamano
2020-09-23 10:27           ` Srinidhi Kaushik
2020-09-19 17:03     ` [PATCH v4 2/3] push: parse and set flag " Srinidhi Kaushik
2020-09-19 20:26       ` Junio C Hamano
2020-09-19 17:03     ` [PATCH v4 3/3] t, doc: update tests, reference " Srinidhi Kaushik
2020-09-19 20:42       ` Junio C Hamano
2020-09-23  7:30     ` [PATCH v5 0/3] push: add "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-23  7:30       ` [PATCH v5 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-09-23 10:18         ` Phillip Wood [this message]
2020-09-23 11:26           ` Srinidhi Kaushik
2020-09-23 16:24           ` Junio C Hamano
2020-09-23 16:29         ` Junio C Hamano
2020-09-23  7:30       ` [PATCH v5 2/3] push: parse and set flag " Srinidhi Kaushik
2020-09-23  7:30       ` [PATCH v5 3/3] t, doc: update tests, reference " Srinidhi Kaushik
2020-09-23 10:24         ` Phillip Wood
2020-09-26 10:13       ` [PATCH v6 0/3] push: add "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-26 10:13         ` [PATCH v6 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-09-26 10:13         ` [PATCH v6 2/3] push: parse and set flag " Srinidhi Kaushik
2020-09-26 10:13         ` [PATCH v6 3/3] t, doc: update tests, reference " Srinidhi Kaushik
2020-09-26 10:21         ` [PATCH v6 0/3] push: add "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-26 11:46         ` [PATCH v7 " Srinidhi Kaushik
2020-09-26 11:46           ` [PATCH v7 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-09-26 23:42             ` Junio C Hamano
2020-09-27 12:27               ` Srinidhi Kaushik
2020-09-26 11:46           ` [PATCH v7 2/3] push: parse and set flag " Srinidhi Kaushik
2020-09-26 11:46           ` [PATCH v7 3/3] t, doc: update tests, reference " Srinidhi Kaushik
2020-09-27 14:17           ` [PATCH v8 0/3] push: add "--[no-]force-if-includes" Srinidhi Kaushik
2020-09-27 14:17             ` [PATCH v8 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-09-27 14:17             ` [PATCH v8 2/3] push: parse and set flag " Srinidhi Kaushik
2020-09-27 14:17             ` [PATCH v8 3/3] t, doc: update tests, reference " Srinidhi Kaushik
2020-09-30 12:54               ` Philip Oakley
2020-09-30 14:27                 ` Srinidhi Kaushik
2020-09-28 17:31             ` [PATCH v8 0/3] push: add "--[no-]force-if-includes" Junio C Hamano
2020-09-28 17:46               ` SZEDER Gábor
2020-09-28 19:34                 ` Srinidhi Kaushik
2020-09-28 19:51                   ` Junio C Hamano
2020-09-28 20:00                 ` Junio C Hamano
2020-10-01  8:21             ` [PATCH v9 " Srinidhi Kaushik
2020-10-01  8:21               ` [PATCH v9 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-10-02 13:52                 ` Johannes Schindelin
2020-10-02 14:50                   ` Johannes Schindelin
2020-10-02 16:22                     ` Junio C Hamano
2020-10-02 15:07                   ` Srinidhi Kaushik
2020-10-02 16:41                     ` Junio C Hamano
2020-10-02 19:39                       ` Srinidhi Kaushik
2020-10-02 20:14                         ` Junio C Hamano
2020-10-02 20:58                           ` Srinidhi Kaushik
2020-10-02 21:36                             ` Junio C Hamano
2020-10-02 16:26                   ` Junio C Hamano
2020-10-01  8:21               ` [PATCH v9 2/3] push: parse and set flag " Srinidhi Kaushik
2020-10-01  8:21               ` [PATCH v9 3/3] t, doc: update tests, reference " Srinidhi Kaushik
2020-10-01 15:46               ` [PATCH v9 0/3] push: add "--[no-]force-if-includes" Junio C Hamano
2020-10-01 17:12                 ` Junio C Hamano
2020-10-01 17:54                   ` Srinidhi Kaushik
2020-10-01 18:32                     ` Junio C Hamano
2020-10-02 16:50                     ` Junio C Hamano
2020-10-02 19:42                       ` Srinidhi Kaushik
2020-10-03 12:10               ` [PATCH v10 " Srinidhi Kaushik
2020-10-03 12:10                 ` [PATCH v10 1/3] push: add reflog check for "--force-if-includes" Srinidhi Kaushik
2020-10-03 12:10                 ` [PATCH v10 2/3] push: parse and set flag " Srinidhi Kaushik
2020-10-03 12:10                 ` [PATCH v10 3/3] t, doc: update tests, reference " Srinidhi Kaushik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3c254220-de10-8e17-1175-f88e790c17a6@gmail.com \
    --to=phillip.wood123@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=shrinidhi.kaushik@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).