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 &&