[PATCH 1/2] Teach send-pack & push to --send-up-to-date refs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Provide an option that forces the local Git transport to transmit a local
ref even when the receiving ref would not change (i.e. the local & remote
refs point to the same object).  This is not done normally, as no changes
would take place on the server in a vanilla Git setup.  However, some Git
servers support push options and those push options decide which branches
to operate on based on the refs that are transmitted alongside the option.

This option ensures the refs listed on the command line are always sent.

Signed-off-by: Christopher Lindee <christopher.lindee@xxxxxxxxxxx>
---
 Documentation/git-push.txt      | 8 +++++++-
 Documentation/git-send-pack.txt | 7 +++++++
 builtin/push.c                  | 1 +
 builtin/send-pack.c             | 4 ++++
 send-pack.c                     | 2 +-
 send-pack.h                     | 3 ++-
 transport-helper.c              | 7 ++++++-
 transport.c                     | 1 +
 transport.h                     | 1 +
 9 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt
index 9b7cfbc5c1..44d1e04931 100644
--- a/Documentation/git-push.txt
+++ b/Documentation/git-push.txt
@@ -11,7 +11,7 @@ SYNOPSIS
 [verse]
 'git push' [--all | --branches | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=<git-receive-pack>]
 	   [--repo=<repository>] [-f | --force] [-d | --delete] [--prune] [-q | --quiet] [-v | --verbose]
-	   [-u | --set-upstream] [-o <string> | --push-option=<string>]
+	   [-u | --set-upstream] [-o <string> | --push-option=<string>] [--send-up-to-date]
 	   [--[no-]signed|--signed=(true|false|if-asked)]
 	   [--force-with-lease[=<refname>[:<expect>]] [--force-if-includes]]
 	   [--no-verify] [<repository> [<refspec>...]]
@@ -225,6 +225,12 @@ already exists on the remote side.
 	line, the values of configuration variable `push.pushOption`
 	are used instead.
 
+--send-up-to-date::
+	Usually, the command will not send a local ref when the remote ref
+	already matches, as no change would occur if it did.  This flag
+	disables that check.  This allows push options to be sent alongside
+	up-to-date references on the remote.
+
 --receive-pack=<git-receive-pack>::
 --exec=<git-receive-pack>::
 	Path to the 'git-receive-pack' program on the remote
diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt
index b9e73f2e77..2517d226d0 100644
--- a/Documentation/git-send-pack.txt
+++ b/Documentation/git-send-pack.txt
@@ -13,6 +13,7 @@ SYNOPSIS
 		[--receive-pack=<git-receive-pack>]
 		[--verbose] [--thin] [--atomic]
 		[--[no-]signed | --signed=(true|false|if-asked)]
+		[--send-up-to-date]
 		[<host>:]<directory> (--all | <ref>...)
 
 DESCRIPTION
@@ -88,6 +89,12 @@ be in a separate packet, and the list must end with a flush packet.
 	options, error out.  See linkgit:git-push[1] and
 	linkgit:githooks[5] for details.
 
+--send-up-to-date::
+	Usually, the command will not send a local ref when the remote ref
+	already matches, as no change would occur if it did.  This flag
+	disables that check.  This allows push options to be sent alongside
+	up-to-date references on the remote.
+
 <host>::
 	A remote host to house the repository.  When this
 	part is specified, 'git-receive-pack' is invoked via
diff --git a/builtin/push.c b/builtin/push.c
index 2fbb31c3ad..555e8b53fe 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -617,6 +617,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 		OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK),
 		OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"),
 			TRANSPORT_PUSH_FOLLOW_TAGS),
+		OPT_BIT(0, "send-up-to-date", &flags, N_("send refs when there is no change"), TRANSPORT_PUSH_SEND_UPTODATE),
 		OPT_CALLBACK_F(0, "signed", &push_cert, "(yes|no|if-asked)", N_("GPG sign the push"),
 				PARSE_OPT_OPTARG, option_parse_push_signed),
 		OPT_BIT(0, "atomic", &flags, N_("request atomic transaction on remote side"), TRANSPORT_PUSH_ATOMIC),
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 3df9eaad09..da6630fa12 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -19,6 +19,7 @@ static const char * const send_pack_usage[] = {
 	   "              [--receive-pack=<git-receive-pack>]\n"
 	   "              [--verbose] [--thin] [--atomic]\n"
 	   "              [--[no-]signed | --signed=(true|false|if-asked)]\n"
+	   "              [--send-up-to-date]\n"
 	   "              [<host>:]<directory> (--all | <ref>...)"),
 	NULL,
 };
@@ -165,6 +166,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	const char *receivepack = "git-receive-pack";
 	unsigned dry_run = 0;
 	unsigned send_mirror = 0;
+	unsigned send_uptodate = 0;
 	unsigned force_update = 0;
 	unsigned quiet = 0;
 	int push_cert = 0;
@@ -200,6 +202,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 		OPT_BOOL(0, "stateless-rpc", &stateless_rpc, N_("use stateless RPC protocol")),
 		OPT_BOOL(0, "stdin", &from_stdin, N_("read refs from stdin")),
 		OPT_BOOL(0, "helper-status", &helper_status, N_("print status from remote helper")),
+		OPT_BOOL(0, "send-up-to-date", &send_uptodate, N_("send refs when there is no change")),
 		OPT_CALLBACK_F(0, "force-with-lease", &cas, N_("<refname>:<expect>"),
 		  N_("require old value of ref to be at this value"),
 		  PARSE_OPT_OPTARG, parseopt_push_cas_option),
@@ -221,6 +224,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	args.verbose = verbose;
 	args.dry_run = dry_run;
 	args.send_mirror = send_mirror;
+	args.send_uptodate = send_uptodate;
 	args.force_update = force_update;
 	args.quiet = quiet;
 	args.push_cert = push_cert;
diff --git a/send-pack.c b/send-pack.c
index 37f59d4f66..30b0f2f276 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -313,7 +313,7 @@ static int check_to_send_update(const struct ref *ref, const struct send_pack_ar
 	case REF_STATUS_REJECT_NODELETE:
 		return CHECK_REF_STATUS_REJECTED;
 	case REF_STATUS_UPTODATE:
-		return CHECK_REF_UPTODATE;
+		return args->send_uptodate ? 0 : CHECK_REF_UPTODATE;
 
 	default:
 	case REF_STATUS_EXPECTING_REPORT:
diff --git a/send-pack.h b/send-pack.h
index 7edb80596c..241b4278bc 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -27,7 +27,8 @@ struct send_pack_args {
 		push_cert:2,
 		stateless_rpc:1,
 		atomic:1,
-		disable_bitmaps:1;
+		disable_bitmaps:1,
+		send_uptodate:1;
 	const struct string_list *push_options;
 };
 
diff --git a/transport-helper.c b/transport-helper.c
index dd6002b393..115f46f6b8 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -983,6 +983,7 @@ static int push_refs_with_push(struct transport *transport,
 	int force_all = flags & TRANSPORT_PUSH_FORCE;
 	int mirror = flags & TRANSPORT_PUSH_MIRROR;
 	int atomic = flags & TRANSPORT_PUSH_ATOMIC;
+	int do_nop = flags & TRANSPORT_PUSH_SEND_UPTODATE;
 	struct helper_data *data = transport->data;
 	struct strbuf buf = STRBUF_INIT;
 	struct ref *ref;
@@ -1010,7 +1011,11 @@ static int push_refs_with_push(struct transport *transport,
 			} else
 				continue;
 		case REF_STATUS_UPTODATE:
-			continue;
+			if (do_nop) {
+				; /* do nothing */
+			}
+			else
+				continue;
 		default:
 			; /* do nothing */
 		}
diff --git a/transport.c b/transport.c
index df518ead70..84deadd2b6 100644
--- a/transport.c
+++ b/transport.c
@@ -867,6 +867,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
 
 	memset(&args, 0, sizeof(args));
 	args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
+	args.send_uptodate = !!(flags & TRANSPORT_PUSH_SEND_UPTODATE);
 	args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
 	args.use_thin_pack = data->options.thin;
 	args.verbose = (transport->verbose > 0);
diff --git a/transport.h b/transport.h
index 6393cd9823..61a20e84f0 100644
--- a/transport.h
+++ b/transport.h
@@ -158,6 +158,7 @@ struct transport {
 #define TRANSPORT_RECURSE_SUBMODULES_ONLY	(1<<15)
 #define TRANSPORT_PUSH_FORCE_IF_INCLUDES	(1<<16)
 #define TRANSPORT_PUSH_AUTO_UPSTREAM		(1<<17)
+#define TRANSPORT_PUSH_SEND_UPTODATE		(1<<18)
 
 int transport_summary_width(const struct ref *refs);
 
-- 
2.38.1





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux