diff options
author | Clemens Buchacher <drizzd@aon.at> | 2008-11-05 21:55:54 +0100 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2008-11-05 14:22:10 -0800 |
commit | 16ed2f48be228918af3d1a6c5a6a4fe9b832cb84 (patch) | |
tree | 27ac815ad2611de47e90d2d7f14cdff54f6f0c43 | |
parent | 5bdd8d4a3062ac8f29ec511fecb85049f6ff3ecc (diff) | |
download | git-16ed2f48be228918af3d1a6c5a6a4fe9b832cb84.tar.gz git-16ed2f48be228918af3d1a6c5a6a4fe9b832cb84.tar.xz |
push: fix local refs update if already up-to-date
git push normally updates local refs only after a successful push. If the
remote already has the updates -- pushed indirectly through another repository,
for example -- we forget to update local tracking refs.
Signed-off-by: Clemens Buchacher <drizzd@aon.at>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r-- | builtin-send-pack.c | 22 | ||||
-rwxr-xr-x | t/t5516-fetch-push.sh | 31 |
2 files changed, 39 insertions, 14 deletions
diff --git a/builtin-send-pack.c b/builtin-send-pack.c index 301f23043..8fdeaa398 100644 --- a/builtin-send-pack.c +++ b/builtin-send-pack.c @@ -222,7 +222,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref) { struct refspec rs; - if (ref->status != REF_STATUS_OK) + if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE) return; rs.src = ref->name; @@ -424,24 +424,19 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest */ new_refs = 0; for (ref = remote_refs; ref; ref = ref->next) { - const unsigned char *new_sha1; - - if (!ref->peer_ref) { - if (!args.send_mirror) - continue; - new_sha1 = null_sha1; - } - else - new_sha1 = ref->peer_ref->new_sha1; + if (ref->peer_ref) + hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); + else if (!args.send_mirror) + continue; - ref->deletion = is_null_sha1(new_sha1); + ref->deletion = is_null_sha1(ref->new_sha1); if (ref->deletion && !allow_deleting_refs) { ref->status = REF_STATUS_REJECT_NODELETE; continue; } if (!ref->deletion && - !hashcmp(ref->old_sha1, new_sha1)) { + !hashcmp(ref->old_sha1, ref->new_sha1)) { ref->status = REF_STATUS_UPTODATE; continue; } @@ -469,14 +464,13 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest !ref->deletion && !is_null_sha1(ref->old_sha1) && (!has_sha1_file(ref->old_sha1) - || !ref_newer(new_sha1, ref->old_sha1)); + || !ref_newer(ref->new_sha1, ref->old_sha1)); if (ref->nonfastforward && !ref->force && !args.force_update) { ref->status = REF_STATUS_REJECT_NONFASTFORWARD; continue; } - hashcpy(ref->new_sha1, new_sha1); if (!ref->deletion) new_refs++; diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index f0030ad00..598664ce7 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -437,6 +437,37 @@ test_expect_success 'push updates local refs' ' ' +test_expect_success 'push updates up-to-date local refs' ' + + rm -rf parent child && + mkdir parent && + (cd parent && git init && + echo one >foo && git add foo && git commit -m one) && + git clone parent child1 && + git clone parent child2 && + (cd child1 && + echo two >foo && git commit -a -m two && + git push) && + (cd child2 && + git pull ../child1 master && + git push && + test $(git rev-parse master) = $(git rev-parse remotes/origin/master)) + +' + +test_expect_success 'push preserves up-to-date packed refs' ' + + rm -rf parent child && + mkdir parent && + (cd parent && git init && + echo one >foo && git add foo && git commit -m one) && + git clone parent child && + (cd child && + git push && + ! test -f .git/refs/remotes/origin/master) + +' + test_expect_success 'push does not update local refs on failure' ' rm -rf parent child && |