@matheusbsbs / matheus-bagliano / commits / 13e7ed6a3a
Fork 0

builtin/checkout: compute checkout metadata for checkouts

Provide commit metadata for checkout code paths that use unpack_trees and friends. When we're checking out a commit, use the commit information, but don't provide commit information if we're checking out from the index, since there need not be any particular commit associated with the index, and even if there is one, we can't know what it is. Signed-off-by: brian m. carlson <bk2204@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

brian m. carlson committed Mar 16, 2020 at 18:05 UTC 13e7ed6a3a0ecd5d50b7bba2d86ce9d88494fa9b
6 files changed +68 -33
builtin/checkout.c
+14 -4
@@ -604,7 +604,8 @@ static void describe_detached_head(const char *msg, struct commit *commit)
604 }
605
606 static int reset_tree(struct tree *tree, const struct checkout_opts *o,
607 - int worktree, int *writeout_error)
607 + int worktree, int *writeout_error,
608 + struct branch_info *info)
609 {
610 struct unpack_trees_options opts;
611 struct tree_desc tree_desc;
@@ -619,6 +620,11 @@ static int reset_tree(struct tree *tree, const struct checkout_opts *o,
620 opts.verbose_update = o->show_progress;
621 opts.src_index = &the_index;
622 opts.dst_index = &the_index;
623 + init_checkout_metadata(&opts.meta, info->refname,
624 + info->commit ? &info->commit->object.oid :
625 + is_null_oid(&info->oid) ? &tree->object.oid :
626 + &info->oid,
627 + NULL);
628 parse_tree(tree);
629 init_tree_desc(&tree_desc, tree->buffer, tree->size);
630 switch (unpack_trees(1, &tree_desc, &opts)) {
@@ -677,7 +683,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
683 } else
684 new_tree = get_commit_tree(new_branch_info->commit);
685 if (opts->discard_changes) {
680 - ret = reset_tree(new_tree, opts, 1, writeout_error);
686 + ret = reset_tree(new_tree, opts, 1, writeout_error, new_branch_info);
687 if (ret)
688 return ret;
689 } else {
@@ -706,6 +712,10 @@ static int merge_working_tree(const struct checkout_opts *opts,
712 topts.quiet = opts->merge && old_branch_info->commit;
713 topts.verbose_update = opts->show_progress;
714 topts.fn = twoway_merge;
715 + init_checkout_metadata(&topts.meta, new_branch_info->refname,
716 + new_branch_info->commit ?
717 + &new_branch_info->commit->object.oid :
718 + &new_branch_info->oid, NULL);
719 if (opts->overwrite_ignore) {
720 topts.dir = xcalloc(1, sizeof(*topts.dir));
721 topts.dir->flags |= DIR_SHOW_IGNORED;
@@ -776,7 +786,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
786
787 ret = reset_tree(new_tree,
788 opts, 1,
779 - writeout_error);
789 + writeout_error, new_branch_info);
790 if (ret)
791 return ret;
792 o.ancestor = old_branch_info->name;
@@ -796,7 +806,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
806 exit(128);
807 ret = reset_tree(new_tree,
808 opts, 0,
799 - writeout_error);
809 + writeout_error, new_branch_info);
810 strbuf_release(&o.obuf);
811 strbuf_release(&old_commit_shortname);
812 if (ret)
merge.c
+1
@@ -94,6 +94,7 @@ int checkout_fast_forward(struct repository *r,
94 opts.verbose_update = 1;
95 opts.merge = 1;
96 opts.fn = twoway_merge;
97 + init_checkout_metadata(&opts.meta, NULL, remote, NULL);
98 setup_unpack_trees_porcelain(&opts, "merge");
99
100 if (unpack_trees(nr_trees, t, &opts)) {
t/t0021-conversion.sh
+50 -28
@@ -364,6 +364,10 @@ test_expect_success PERL 'required process filter should filter data' '
364 S=$(file_size test.r) &&
365 S2=$(file_size test2.r) &&
366 S3=$(file_size "testsubdir/test3 '\''sq'\'',\$x=.r") &&
367 + M=$(git hash-object test.r) &&
368 + M2=$(git hash-object test2.r) &&
369 + M3=$(git hash-object "testsubdir/test3 '\''sq'\'',\$x=.r") &&
370 + EMPTY=$(git hash-object /dev/null) &&
371
372 filter_git add . &&
373 cat >expected.log <<-EOF &&
@@ -378,14 +382,15 @@ test_expect_success PERL 'required process filter should filter data' '
382 test_cmp_count expected.log debug.log &&
383
384 git commit -m "test commit 2" &&
385 + META="ref=refs/heads/master treeish=$(git rev-parse --verify master)" &&
386 rm -f test2.r "testsubdir/test3 '\''sq'\'',\$x=.r" &&
387
388 filter_git checkout --quiet --no-progress . &&
389 cat >expected.log <<-EOF &&
390 START
391 init handshake complete
387 - IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
388 - IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $S3 [OK] -- OUT: $S3 . [OK]
392 + IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
393 + IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
394 STOP
395 EOF
396 test_cmp_exclude_clean expected.log debug.log &&
@@ -406,10 +411,10 @@ test_expect_success PERL 'required process filter should filter data' '
411 cat >expected.log <<-EOF &&
412 START
413 init handshake complete
409 - IN: smudge test.r $S [OK] -- OUT: $S . [OK]
410 - IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
411 - IN: smudge test4-empty.r 0 [OK] -- OUT: 0 [OK]
412 - IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $S3 [OK] -- OUT: $S3 . [OK]
414 + IN: smudge test.r $META blob=$M $S [OK] -- OUT: $S . [OK]
415 + IN: smudge test2.r $META blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
416 + IN: smudge test4-empty.r $META blob=$EMPTY 0 [OK] -- OUT: 0 [OK]
417 + IN: smudge testsubdir/test3 '\''sq'\'',\$x=.r $META blob=$M3 $S3 [OK] -- OUT: $S3 . [OK]
418 STOP
419 EOF
420 test_cmp_exclude_clean expected.log debug.log &&
@@ -519,17 +524,22 @@ test_expect_success PERL 'required process filter should process multiple packet
524 EOF
525 test_cmp_count expected.log debug.log &&
526
522 - rm -f *.file &&
527 + M1="blob=$(git hash-object 1pkt_1__.file)" &&
528 + M2="blob=$(git hash-object 2pkt_1+1.file)" &&
529 + M3="blob=$(git hash-object 2pkt_2-1.file)" &&
530 + M4="blob=$(git hash-object 2pkt_2__.file)" &&
531 + M5="blob=$(git hash-object 3pkt_2+1.file)" &&
532 + rm -f *.file debug.log &&
533
534 filter_git checkout --quiet --no-progress -- *.file &&
535 cat >expected.log <<-EOF &&
536 START
537 init handshake complete
528 - IN: smudge 1pkt_1__.file $(($S )) [OK] -- OUT: $(($S )) . [OK]
529 - IN: smudge 2pkt_1+1.file $(($S +1)) [OK] -- OUT: $(($S +1)) .. [OK]
530 - IN: smudge 2pkt_2-1.file $(($S*2-1)) [OK] -- OUT: $(($S*2-1)) .. [OK]
531 - IN: smudge 2pkt_2__.file $(($S*2 )) [OK] -- OUT: $(($S*2 )) .. [OK]
532 - IN: smudge 3pkt_2+1.file $(($S*2+1)) [OK] -- OUT: $(($S*2+1)) ... [OK]
538 + IN: smudge 1pkt_1__.file $M1 $(($S )) [OK] -- OUT: $(($S )) . [OK]
539 + IN: smudge 2pkt_1+1.file $M2 $(($S +1)) [OK] -- OUT: $(($S +1)) .. [OK]
540 + IN: smudge 2pkt_2-1.file $M3 $(($S*2-1)) [OK] -- OUT: $(($S*2-1)) .. [OK]
541 + IN: smudge 2pkt_2__.file $M4 $(($S*2 )) [OK] -- OUT: $(($S*2 )) .. [OK]
542 + IN: smudge 3pkt_2+1.file $M5 $(($S*2+1)) [OK] -- OUT: $(($S*2+1)) ... [OK]
543 STOP
544 EOF
545 test_cmp_exclude_clean expected.log debug.log &&
@@ -578,6 +588,10 @@ test_expect_success PERL 'process filter should restart after unexpected write f
588 S=$(file_size test.r) &&
589 S2=$(file_size test2.r) &&
590 SF=$(file_size smudge-write-fail.r) &&
591 + M=$(git hash-object test.r) &&
592 + M2=$(git hash-object test2.r) &&
593 + MF=$(git hash-object smudge-write-fail.r) &&
594 + rm -f debug.log &&
595
596 git add . &&
597 rm -f *.r &&
@@ -591,11 +605,11 @@ test_expect_success PERL 'process filter should restart after unexpected write f
605 cat >expected.log <<-EOF &&
606 START
607 init handshake complete
594 - IN: smudge smudge-write-fail.r $SF [OK] -- [WRITE FAIL]
608 + IN: smudge smudge-write-fail.r blob=$MF $SF [OK] -- [WRITE FAIL]
609 START
610 init handshake complete
597 - IN: smudge test.r $S [OK] -- OUT: $S . [OK]
598 - IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
611 + IN: smudge test.r blob=$M $S [OK] -- OUT: $S . [OK]
612 + IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
613 STOP
614 EOF
615 test_cmp_exclude_clean expected.log debug.log &&
@@ -629,6 +643,10 @@ test_expect_success PERL 'process filter should not be restarted if it signals a
643 S=$(file_size test.r) &&
644 S2=$(file_size test2.r) &&
645 SE=$(file_size error.r) &&
646 + M=$(git hash-object test.r) &&
647 + M2=$(git hash-object test2.r) &&
648 + ME=$(git hash-object error.r) &&
649 + rm -f debug.log &&
650
651 git add . &&
652 rm -f *.r &&
@@ -637,9 +655,9 @@ test_expect_success PERL 'process filter should not be restarted if it signals a
655 cat >expected.log <<-EOF &&
656 START
657 init handshake complete
640 - IN: smudge error.r $SE [OK] -- [ERROR]
641 - IN: smudge test.r $S [OK] -- OUT: $S . [OK]
642 - IN: smudge test2.r $S2 [OK] -- OUT: $S2 . [OK]
658 + IN: smudge error.r blob=$ME $SE [OK] -- [ERROR]
659 + IN: smudge test.r blob=$M $S [OK] -- OUT: $S . [OK]
660 + IN: smudge test2.r blob=$M2 $S2 [OK] -- OUT: $S2 . [OK]
661 STOP
662 EOF
663 test_cmp_exclude_clean expected.log debug.log &&
@@ -665,18 +683,21 @@ test_expect_success PERL 'process filter abort stops processing of all further f
683 echo "error this blob and all future blobs" >abort.o &&
684 cp abort.o abort.r &&
685
686 + M="blob=$(git hash-object abort.r)" &&
687 + rm -f debug.log &&
688 SA=$(file_size abort.r) &&
689
690 git add . &&
691 rm -f *.r &&
692
693 +
694 # Note: This test assumes that Git filters files in alphabetical
695 # order ("abort.r" before "test.r").
696 filter_git checkout --quiet --no-progress . &&
697 cat >expected.log <<-EOF &&
698 START
699 init handshake complete
679 - IN: smudge abort.r $SA [OK] -- [ABORT]
700 + IN: smudge abort.r $M $SA [OK] -- [ABORT]
701 STOP
702 EOF
703 test_cmp_exclude_clean expected.log debug.log &&
@@ -727,27 +748,28 @@ test_expect_success PERL 'delayed checkout in process filter' '
748 ) &&
749
750 S=$(file_size "$TEST_ROOT/test.o") &&
751 + M="blob=$(git -C repo rev-parse --verify master:test.a)" &&
752 cat >a.exp <<-EOF &&
753 START
754 init handshake complete
733 - IN: smudge test.a $S [OK] -- OUT: $S . [OK]
734 - IN: smudge test-delay10.a $S [OK] -- [DELAYED]
735 - IN: smudge test-delay11.a $S [OK] -- [DELAYED]
736 - IN: smudge test-delay20.a $S [OK] -- [DELAYED]
755 + IN: smudge test.a $M $S [OK] -- OUT: $S . [OK]
756 + IN: smudge test-delay10.a $M $S [OK] -- [DELAYED]
757 + IN: smudge test-delay11.a $M $S [OK] -- [DELAYED]
758 + IN: smudge test-delay20.a $M $S [OK] -- [DELAYED]
759 IN: list_available_blobs test-delay10.a test-delay11.a [OK]
738 - IN: smudge test-delay10.a 0 [OK] -- OUT: $S . [OK]
739 - IN: smudge test-delay11.a 0 [OK] -- OUT: $S . [OK]
760 + IN: smudge test-delay10.a $M 0 [OK] -- OUT: $S . [OK]
761 + IN: smudge test-delay11.a $M 0 [OK] -- OUT: $S . [OK]
762 IN: list_available_blobs test-delay20.a [OK]
741 - IN: smudge test-delay20.a 0 [OK] -- OUT: $S . [OK]
763 + IN: smudge test-delay20.a $M 0 [OK] -- OUT: $S . [OK]
764 IN: list_available_blobs [OK]
765 STOP
766 EOF
767 cat >b.exp <<-EOF &&
768 START
769 init handshake complete
748 - IN: smudge test-delay10.b $S [OK] -- [DELAYED]
770 + IN: smudge test-delay10.b $M $S [OK] -- [DELAYED]
771 IN: list_available_blobs test-delay10.b [OK]
750 - IN: smudge test-delay10.b 0 [OK] -- OUT: $S . [OK]
772 + IN: smudge test-delay10.b $M 0 [OK] -- OUT: $S . [OK]
773 IN: list_available_blobs [OK]
774 STOP
775 EOF
t/t0021/rot13-filter.pl
+1 -1
@@ -136,7 +136,7 @@ while (1) {
136 $DELAY{$pathname}{"requested"} = 1;
137 }
138 } elsif ($buffer =~ /^(ref|treeish|blob)=/) {
139 - # Do nothing.
139 + print $debug " $buffer";
140 } else {
141 # In general, filters need to be graceful about
142 # new metadata, since it's documented that we
unpack-trees.c
+1
@@ -371,6 +371,7 @@ static int check_updates(struct unpack_trees_options *o)
371 state.quiet = 1;
372 state.refresh_cache = 1;
373 state.istate = index;
374 + clone_checkout_metadata(&state.meta, &o->meta, NULL);
375
376 if (!o->update || o->dry_run) {
377 remove_marked_cache_entries(index, 0);
unpack-trees.h
+1
@@ -85,6 +85,7 @@ struct unpack_trees_options {
85 struct index_state result;
86
87 struct pattern_list *pl; /* for internal use */
88 + struct checkout_metadata meta;
89 };
90
91 int unpack_trees(unsigned n, struct tree_desc *t,