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

[PATCH 2/2] send-pack: don't update tracking refs on error

From
Jeff King <peff@peff.net>
Date
Oct 18, 2007, 06:19 UTC
Message-ID
<20071018061915.GB29531@coredump.intra.peff.net>
In-Reply-To
<20071018045358.GB14735@spearce.org>

Previously, we updated the tracking refs (which match refs we are pushing) while generating the list of refs to send. However, at that point we don't know whether the refs were accepted.

Instead, we now wait until we get a response code from the server. If an error was indicated, we don't update any local tracking refs. Technically some refs could have been updated on the remote, but since the local ref update is just an optimization to avoid an extra fetch, we are better off erring on the side of correctness.

The user-visible message is now generated much later in the program, and has been tweaked to make more sense.

Signed-off-by: Jeff King <peff@peff.net>
---
 send-pack.c |   50 ++++++++++++++++++++++++++++++++++----------------
 1 files changed, 34 insertions(+), 16 deletions(-)
diff --git a/send-pack.c b/send-pack.c
index f74e66a..25d5c25 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -177,6 +177,35 @@ static int receive_status(int in)
 	return ret;
 }
 
+static void update_tracking_ref(struct remote *remote, struct ref *ref)
+{
+	struct refspec rs;
+	int will_delete_ref;
+
+	rs.src = ref->name;
+	rs.dst = NULL;
+
+	if (!ref->peer_ref)
+		return;
+
+	will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
+
+	if (!will_delete_ref &&
+			!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1))
+		return;
+
+	if (!remote_find_tracking(remote, &rs)) {
+		fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
+		if (is_null_sha1(ref->peer_ref->new_sha1)) {
+			if (delete_ref(rs.dst, NULL))
+				error("Failed to delete");
+		} else
+			update_ref("update by push", rs.dst,
+					ref->new_sha1, NULL, 0, 0);
+		free(rs.dst);
+	}
+}
+
 static int send_pack(int in, int out, struct remote *remote, int nr_refspec, char **refspec)
 {
 	struct ref *ref;
@@ -302,22 +331,6 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
 			fprintf(stderr, "\n  from %s\n  to   %s\n",
 				old_hex, new_hex);
 		}
-		if (remote) {
-			struct refspec rs;
-			rs.src = ref->name;
-			rs.dst = NULL;
-			if (!remote_find_tracking(remote, &rs)) {
-				fprintf(stderr, " Also local %s\n", rs.dst);
-				if (will_delete_ref) {
-					if (delete_ref(rs.dst, NULL)) {
-						error("Failed to delete");
-					}
-				} else
-					update_ref("update by push", rs.dst,
-						ref->new_sha1, NULL, 0, 0);
-				free(rs.dst);
-			}
-		}
 	}
 
 	packet_flush(out);
@@ -330,6 +343,11 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
 			ret = -4;
 	}
 
+	if (remote && ret == 0) {
+		for (ref = remote_refs; ref; ref = ref->next)
+			update_tracking_ref(remote, ref);
+	}
+
 	if (!new_refs && ret == 0)
 		fprintf(stderr, "Everything up-to-date\n");
 	return ret;
-- 
1.5.3.4.1162.gc3e8e-dirty
Previous: Shawn O. Pearce
Message 8 of 8 in “bug: origin refs updated too soon locally”
  1. Perry WagleOct 18, 2007
  2. Perry WagleOct 18, 2007
  3. Shawn O. PearceOct 18, 2007
  4. Jeff KingOct 18, 2007
  5. t5516: test update of local refs on pushJeff King, Oct 18, 2007
  6. Jeff KingOct 18, 2007
  7. Shawn O. PearceOct 18, 2007
  8. 2/2 send-pack: don't update tracking refs on errorJeff King, Oct 18, 2007

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.