aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2007-10-30 21:38:04 -0700
committerJunio C Hamano <gitster@pobox.com>2007-10-30 21:38:04 -0700
commit7ae4dd05725e1613375e03f206077959853d6b51 (patch)
tree3f22627155ce51b69fe6a99e3c9340490ec3e98e
parent7e9a4645d1a113d4390f5198a4212721cc9bf3dd (diff)
parent09fba7a59d38d1cafaf33eadaf1d409c4113b30c (diff)
downloadgit-7ae4dd05725e1613375e03f206077959853d6b51.tar.gz
git-7ae4dd05725e1613375e03f206077959853d6b51.tar.xz
Merge branch 'jk/send-pack' into HEAD
* jk/send-pack: t5516: test update of local refs on push send-pack: don't update tracking refs on error
-rw-r--r--send-pack.c50
-rwxr-xr-xt/t5516-fetch-push.sh28
2 files changed, 62 insertions, 16 deletions
diff --git a/send-pack.c b/send-pack.c
index e9b9a39f4..25053d2c2 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -178,6 +178,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;
@@ -306,22 +335,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 && !dry_run) {
- 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);
@@ -334,6 +347,11 @@ static int send_pack(int in, int out, struct remote *remote, int nr_refspec, cha
ret = -4;
}
+ if (!dry_run && 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;
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 4fbd5b1f4..86f9b5346 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -254,4 +254,32 @@ test_expect_success 'push with dry-run' '
check_push_result $old_commit heads/master
'
+test_expect_success 'push updates local refs' '
+
+ rm -rf parent child &&
+ mkdir parent && cd parent && git init &&
+ echo one >foo && git add foo && git commit -m one &&
+ cd .. &&
+ git clone parent child && cd child &&
+ echo two >foo && git commit -a -m two &&
+ git push &&
+ test $(git rev-parse master) = $(git rev-parse remotes/origin/master)
+
+'
+
+test_expect_success 'push does not update local refs on failure' '
+
+ rm -rf parent child &&
+ mkdir parent && cd parent && git init &&
+ echo one >foo && git add foo && git commit -m one &&
+ echo exit 1 >.git/hooks/pre-receive &&
+ chmod +x .git/hooks/pre-receive &&
+ cd .. &&
+ git clone parent child && cd child &&
+ echo two >foo && git commit -a -m two || exit 1
+ git push && exit 1
+ test $(git rev-parse master) != $(git rev-parse remotes/origin/master)
+
+'
+
test_done