@matheusbsbs / matheus-bagliano / commits / 16ed2f48be
Fork 0

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>

Clemens Buchacher committed Nov 5, 2008 at 21:55 UTC 16ed2f48be228918af3d1a6c5a6a4fe9b832cb84
2 files changed +39 -14
builtin-send-pack.c
+8 -14
@@ -222,7 +222,7 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref)
222 {
223 struct refspec rs;
224
225 - if (ref->status != REF_STATUS_OK)
225 + if (ref->status != REF_STATUS_OK && ref->status != REF_STATUS_UPTODATE)
226 return;
227
228 rs.src = ref->name;
@@ -424,24 +424,19 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
424 */
425 new_refs = 0;
426 for (ref = remote_refs; ref; ref = ref->next) {
427 - const unsigned char *new_sha1;
428 -
429 - if (!ref->peer_ref) {
430 - if (!args.send_mirror)
431 - continue;
432 - new_sha1 = null_sha1;
433 - }
434 - else
435 - new_sha1 = ref->peer_ref->new_sha1;
427
428 + if (ref->peer_ref)
429 + hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
430 + else if (!args.send_mirror)
431 + continue;
432
438 - ref->deletion = is_null_sha1(new_sha1);
433 + ref->deletion = is_null_sha1(ref->new_sha1);
434 if (ref->deletion && !allow_deleting_refs) {
435 ref->status = REF_STATUS_REJECT_NODELETE;
436 continue;
437 }
438 if (!ref->deletion &&
444 - !hashcmp(ref->old_sha1, new_sha1)) {
439 + !hashcmp(ref->old_sha1, ref->new_sha1)) {
440 ref->status = REF_STATUS_UPTODATE;
441 continue;
442 }
@@ -469,14 +464,13 @@ static int do_send_pack(int in, int out, struct remote *remote, const char *dest
464 !ref->deletion &&
465 !is_null_sha1(ref->old_sha1) &&
466 (!has_sha1_file(ref->old_sha1)
472 - || !ref_newer(new_sha1, ref->old_sha1));
467 + || !ref_newer(ref->new_sha1, ref->old_sha1));
468
469 if (ref->nonfastforward && !ref->force && !args.force_update) {
470 ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
471 continue;
472 }
473
479 - hashcpy(ref->new_sha1, new_sha1);
474 if (!ref->deletion)
475 new_refs++;
476
t/t5516-fetch-push.sh
+31
@@ -437,6 +437,37 @@ test_expect_success 'push updates local refs' '
437
438 '
439
440 +test_expect_success 'push updates up-to-date local refs' '
441 +
442 + rm -rf parent child &&
443 + mkdir parent &&
444 + (cd parent && git init &&
445 + echo one >foo && git add foo && git commit -m one) &&
446 + git clone parent child1 &&
447 + git clone parent child2 &&
448 + (cd child1 &&
449 + echo two >foo && git commit -a -m two &&
450 + git push) &&
451 + (cd child2 &&
452 + git pull ../child1 master &&
453 + git push &&
454 + test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
455 +
456 +'
457 +
458 +test_expect_success 'push preserves up-to-date packed refs' '
459 +
460 + rm -rf parent child &&
461 + mkdir parent &&
462 + (cd parent && git init &&
463 + echo one >foo && git add foo && git commit -m one) &&
464 + git clone parent child &&
465 + (cd child &&
466 + git push &&
467 + ! test -f .git/refs/remotes/origin/master)
468 +
469 +'
470 +
471 test_expect_success 'push does not update local refs on failure' '
472
473 rm -rf parent child &&