Re: Minor annoyance with git push

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

 



On Fri, Feb 08, 2008 at 09:46:36PM -0500, Jeff King wrote:

> > The local side has the remote refs if the client has fetched recently,
> > so it might be able to tell in some cases. Not with authority (things
> > may have changed on the server side...) but the client might be able
> > to say something less alarming.
> 
> This is actually not that hard to do in the case that we can. Patch will
> follow in a second, though I am not sure it is a good idea (because it
> silently ignores pushing rewinds).

And here it is. Again, I don't think this is the right default behavior.
I'm not even sure it is a good idea as configurable behavior. But it's
here for comment and for playing with, nonetheless.

-- >8 --
send-pack: treat strict rewinds specially

If you try to push an out-of-date version of a branch, it will generally
be rejected as a non-fastforward. This can clutter up the status output
of git-push if you have many such branches.

Instead, let's check explicitly whether what we are pushing is a strict
subset of what the remote already has. We treat this as a non-error, and
don't even print any status unless "verbose" is given. If the push is
"forced", then we will push as usual.

Note that we cannot always perform this check accurately; it relies on
us having the commit object that the remote claims to have. In the case
that we don't, we treat it like an ordinary non-fastforward and reject.

---
diff --git a/cache.h b/cache.h
index 920e731..78fee0b 100644
--- a/cache.h
+++ b/cache.h
@@ -596,6 +596,7 @@ struct ref {
 		REF_STATUS_UPTODATE,
 		REF_STATUS_REMOTE_REJECT,
 		REF_STATUS_EXPECTING_REPORT,
+		REF_STATUS_REJECT_REWIND,
 	} status;
 	char *remote_status;
 	struct ref *peer_ref; /* when renaming */
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
index 454ad8f..9f82b83 100644
--- a/builtin-send-pack.c
+++ b/builtin-send-pack.c
@@ -315,6 +315,7 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count)
 				ref->peer_ref, NULL);
 		break;
 	case REF_STATUS_REJECT_NONFASTFORWARD:
+	case REF_STATUS_REJECT_REWIND:
 		print_ref_status('!', "[rejected]", ref, ref->peer_ref,
 				"non-fast forward");
 		break;
@@ -343,7 +344,8 @@ static void print_push_status(const char *dest, struct ref *refs)
 
 	if (args.verbose) {
 		for (ref = refs; ref; ref = ref->next)
-			if (ref->status == REF_STATUS_UPTODATE)
+			if (ref->status == REF_STATUS_UPTODATE ||
+			    ref->status == REF_STATUS_REJECT_REWIND)
 				n += print_one_push_status(ref, dest, n);
 	}
 
@@ -354,7 +356,8 @@ static void print_push_status(const char *dest, struct ref *refs)
 	for (ref = refs; ref; ref = ref->next) {
 		if (ref->status != REF_STATUS_NONE &&
 		    ref->status != REF_STATUS_UPTODATE &&
-		    ref->status != REF_STATUS_OK)
+		    ref->status != REF_STATUS_OK &&
+		    ref->status != REF_STATUS_REJECT_REWIND)
 			n += print_one_push_status(ref, dest, n);
 	}
 }
@@ -365,6 +368,7 @@ static int refs_pushed(struct ref *ref)
 		switch(ref->status) {
 		case REF_STATUS_NONE:
 		case REF_STATUS_UPTODATE:
+		case REF_STATUS_REJECT_REWIND:
 			break;
 		default:
 			return 1;
@@ -463,8 +467,12 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 		    (!has_sha1_file(ref->old_sha1)
 		      || !ref_newer(new_sha1, ref->old_sha1));
 
+
 		if (ref->nonfastforward && !ref->force && !args.force_update) {
-			ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
+			if (ref_newer(ref->old_sha1, new_sha1))
+				ref->status = REF_STATUS_REJECT_REWIND;
+			else
+				ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
 			continue;
 		}
 
@@ -522,6 +530,7 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
 		case REF_STATUS_NONE:
 		case REF_STATUS_UPTODATE:
 		case REF_STATUS_OK:
+		case REF_STATUS_REJECT_REWIND:
 			break;
 		default:
 			return -1;
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[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