git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 5/7] push --lockref: implement logic to populate old_sha1_expect[]

From
Junio C Hamano <gitster@pobox.com>
Date
Jul 9, 2013, 19:53 UTC
Message-ID
<1373399610-8588-6-git-send-email-gitster@pobox.com>
In-Reply-To
<1373399610-8588-1-git-send-email-gitster@pobox.com>

This plugs the push_cas_option data collected by the command line option parser to the transport system with a new function apply_push_cas(), which is called after match_push_refs() has already been called. At this point, we know which remote we are talking to, and what remote refs we are going to update, so we can fill in the details that may have been missing from the command line, such as

 (1) what abbreviated refname the user gave us matches the actual
     refname at the remote; and
 (2) which remote tracking branch in our local repository to read the
     value of the object to expect at the remote.
to populate the old_sha1_expect[] field of each of the remote ref.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 builtin/push.c      |  6 ++++++
 builtin/send-pack.c |  3 +++
 remote.c            | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 remote.h            |  3 +++
 transport.c         |  6 ++++++
 transport.h         |  4 ++++
 6 files changed, 83 insertions(+)
diff --git a/builtin/push.c b/builtin/push.c
index 31a5ba0..b0e3691 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -299,6 +299,12 @@ static int push_with_options(struct transport *transport, int flags)
 	if (thin)
 		transport_set_option(transport, TRANS_OPT_THIN, "yes");
 
+	if (!is_empty_cas(&cas)) {
+		if (!transport->smart_options)
+			die("underlying transport does not support --lockref option");
+		transport->smart_options->cas = &cas;
+	}
+
 	if (verbosity > 0)
 		fprintf(stderr, _("Pushing to %s\n"), transport->url);
 	err = transport_push(transport, refspec_nr, refspec, flags,
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 061e2b2..41dc512 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -247,6 +247,9 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix)
 	if (match_push_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
 		return -1;
 
+	if (!is_empty_cas(&cas))
+		apply_push_cas(&cas, remote, remote_refs);
+
 	set_ref_status_for_push(remote_refs, args.send_mirror,
 		args.force_update);
 
diff --git a/remote.c b/remote.c
index e9b423a..db418ff 100644
--- a/remote.c
+++ b/remote.c
@@ -1997,3 +1997,64 @@ int parse_push_cas_option(struct push_cas_option *cas, const char *arg, int unse
 		return error("cannot parse expected object name '%s'", colon + 1);
 	return 0;
 }
+
+int is_empty_cas(const struct push_cas_option *cas)
+{
+	return !cas->use_tracking_for_rest && !cas->nr;
+}
+
+/*
+ * Look at remote.fetch refspec and see if we have a remote
+ * tracking branch for the refname there.  Fill its current
+ * value in sha1[].
+ * If we cannot do so, return negative to signal an error.
+ */
+static int remote_tracking(struct remote *remote, const char *refname,
+			   unsigned char sha1[20])
+{
+	char *dst;
+
+	dst = apply_refspecs(remote->fetch, remote->fetch_refspec_nr, refname);
+	if (!dst)
+		return -1; /* no tracking ref for refname at remote */
+	if (read_ref(dst, sha1))
+		return -1; /* we know what the tracking ref is but we cannot read it */
+	return 0;
+}
+
+static void apply_cas(struct push_cas_option *cas,
+		      struct remote *remote,
+		      struct ref *ref)
+{
+	int i;
+
+	/* Find an explicit --lockref=<name>[:<value>] entry */
+	for (i = 0; i < cas->nr; i++) {
+		struct push_cas *entry = &cas->entry[i];
+		if (!refname_match(entry->refname, ref->name, ref_rev_parse_rules))
+			continue;
+		ref->expect_old_sha1 = 1;
+		if (!entry->use_tracking)
+			hashcpy(ref->old_sha1_expect, cas->entry[i].expect);
+		else if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
+			ref->expect_old_no_trackback = 1;
+		return;
+	}
+
+	/* Are we using "--lockref" to cover all? */
+	if (!cas->use_tracking_for_rest)
+		return;
+
+	ref->expect_old_sha1 = 1;
+	if (remote_tracking(remote, ref->name, ref->old_sha1_expect))
+		ref->expect_old_no_trackback = 1;
+}
+
+void apply_push_cas(struct push_cas_option *cas,
+		    struct remote *remote,
+		    struct ref *remote_refs)
+{
+	struct ref *ref;
+	for (ref = remote_refs; ref; ref = ref->next)
+		apply_cas(cas, remote, ref);
+}
diff --git a/remote.h b/remote.h
index 28eb6a3..baa1c68 100644
--- a/remote.h
+++ b/remote.h
@@ -252,4 +252,7 @@ extern int parseopt_push_cas_option(const struct option *, const char *arg, int
 extern int parse_push_cas_option(struct push_cas_option *, const char *arg, int unset);
 extern void clear_cas_option(struct push_cas_option *);
 
+extern int is_empty_cas(const struct push_cas_option *);
+void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *);
+
 #endif
diff --git a/transport.c b/transport.c
index 98f5270..b321d6a 100644
--- a/transport.c
+++ b/transport.c
@@ -1147,6 +1147,12 @@ int transport_push(struct transport *transport,
 			return -1;
 		}
 
+		if (transport->smart_options &&
+		    transport->smart_options->cas &&
+		    !is_empty_cas(transport->smart_options->cas))
+			apply_push_cas(transport->smart_options->cas,
+				       transport->remote, remote_refs);
+
 		set_ref_status_for_push(remote_refs,
 			flags & TRANSPORT_PUSH_MIRROR,
 			flags & TRANSPORT_PUSH_FORCE);
diff --git a/transport.h b/transport.h
index b551f99..10f7556 100644
--- a/transport.h
+++ b/transport.h
@@ -14,6 +14,7 @@ struct git_transport_options {
 	int depth;
 	const char *uploadpack;
 	const char *receivepack;
+	struct push_cas_option *cas;
 };
 
 struct transport {
@@ -127,6 +128,9 @@ struct transport *transport_get(struct remote *, const char *);
 /* Transfer the data as a thin pack if not null */
 #define TRANS_OPT_THIN "thin"
 
+/* Check the current value of the remote ref */
+#define TRANS_OPT_CAS "cas"
+
 /* Keep the pack that was transferred if not null */
 #define TRANS_OPT_KEEP "keep"
 
-- 
1.8.3.2-875-g76c723c
Previous: Junio C HamanoNext: Junio C Hamano
Message 24 of 62 in “[RFD] Making "git push [--force/--delete]" safer?”
  1. Junio C HamanoJul 2, 2013
  2. Johan HerlandJul 2, 2013
  3. Johan HerlandJul 3, 2013
  4. Junio C HamanoJul 3, 2013
  5. Johan HerlandJul 3, 2013
  6. Jonathan del StrotherJul 3, 2013
  7. Johan HerlandJul 3, 2013
  8. Michael HaggertyJul 3, 2013
  9. Johannes SixtJul 3, 2013
  10. Junio C HamanoJul 3, 2013
  11. Johannes SixtJul 4, 2013
  12. Junio C HamanoJul 4, 2013
  13. Junio C HamanoJul 3, 2013
  14. Junio C HamanoJul 3, 2013
  15. Junio C HamanoJul 3, 2013
  16. 0/7 safer "push --force" with compare-and-swapJunio C Hamano, Jul 9, 2013
  17. 1/7 cache.h: move remote/connect API out of itJunio C Hamano, Jul 9, 2013
  18. 2/7 builtin/push.c: use OPT_BOOL, not OPT_BOOLEANJunio C Hamano, Jul 9, 2013
  19. 3/7 push: beginning of compare-and-swap "force/delete safety"Junio C Hamano, Jul 9, 2013
  20. 4/7 remote.c: add command line option parser for --lockrefJunio C Hamano, Jul 9, 2013
  21. John KeepingJul 16, 2013
  22. Junio C HamanoJul 17, 2013
  23. Junio C HamanoJul 17, 2013
  24. 5/7 push --lockref: implement logic to populate old_sha1_expect[]Junio C Hamano, Jul 9, 2013
  25. 6/7 t5533: test "push --lockref"Junio C Hamano, Jul 9, 2013
  26. 7/7 push: document --lockrefJunio C Hamano, Jul 9, 2013
  27. Aaron SchrabJul 9, 2013
  28. Junio C HamanoJul 9, 2013
  29. Johannes SixtJul 9, 2013
  30. Junio C HamanoJul 9, 2013
  31. Johannes SixtJul 9, 2013
  32. Junio C HamanoJul 9, 2013
  33. Junio C HamanoJul 9, 2013
  34. Johannes SixtJul 11, 2013
  35. Junio C HamanoJul 11, 2013
  36. Junio C HamanoJul 11, 2013
  37. Johannes SixtJul 12, 2013
  38. Junio C HamanoJul 12, 2013
  39. Johannes SixtJul 12, 2013
  40. Junio C HamanoJul 12, 2013
  41. Johannes SixtJul 13, 2013
  42. Junio C HamanoJul 13, 2013
  43. Junio C HamanoJul 13, 2013
  44. Johannes SixtJul 13, 2013
  45. John KeepingJul 14, 2013
  46. Johannes SixtJul 13, 2013
  47. Junio C HamanoJul 14, 2013
  48. Johannes SixtJul 14, 2013
  49. Jonathan NiederJul 14, 2013
  50. Jonathan NiederJul 14, 2013
  51. Johannes SixtJul 14, 2013
  52. Jonathan NiederJul 14, 2013
  53. Junio C HamanoJul 15, 2013
  54. Jonathan NiederJul 15, 2013
  55. Junio C HamanoJul 15, 2013
  56. Johannes SixtJul 15, 2013
  57. Junio C HamanoJul 15, 2013
  58. Default expectation of --lockrefJunio C Hamano, Jul 15, 2013
  59. Johannes SixtJul 15, 2013
  60. Marc BranchaudJul 9, 2013
  61. Michael HaggertyJul 9, 2013
  62. Junio C HamanoJul 9, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.