Merge branch 'ds/check-connected-reprepare-packed-git'
[git] / t / t6046-merge-skip-unneeded-updates.sh
1 #!/bin/sh
2
3 test_description="merge cases"
4
5 # The setup for all of them, pictorially, is:
6 #
7 #      A
8 #      o
9 #     / \
10 #  O o   ?
11 #     \ /
12 #      o
13 #      B
14 #
15 # To help make it easier to follow the flow of tests, they have been
16 # divided into sections and each test will start with a quick explanation
17 # of what commits O, A, and B contain.
18 #
19 # Notation:
20 #    z/{b,c}   means  files z/b and z/c both exist
21 #    x/d_1     means  file x/d exists with content d1.  (Purpose of the
22 #                     underscore notation is to differentiate different
23 #                     files that might be renamed into each other's paths.)
24
25 . ./test-lib.sh
26
27
28 ###########################################################################
29 # SECTION 1: Cases involving no renames (one side has subset of changes of
30 #            the other side)
31 ###########################################################################
32
33 # Testcase 1a, Changes on A, subset of changes on B
34 #   Commit O: b_1
35 #   Commit A: b_2
36 #   Commit B: b_3
37 #   Expected: b_2
38
39 test_setup_1a () {
40         test_create_repo 1a_$1 &&
41         (
42                 cd 1a_$1 &&
43
44                 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
45                 git add b &&
46                 test_tick &&
47                 git commit -m "O" &&
48
49                 git branch O &&
50                 git branch A &&
51                 git branch B &&
52
53                 git checkout A &&
54                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
55                 git add b &&
56                 test_tick &&
57                 git commit -m "A" &&
58
59                 git checkout B &&
60                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
61                 git add b &&
62                 test_tick &&
63                 git commit -m "B"
64         )
65 }
66
67 test_expect_success '1a-L: Modify(A)/Modify(B), change on B subset of A' '
68         test_setup_1a L &&
69         (
70                 cd 1a_L &&
71
72                 git checkout A^0 &&
73
74                 test-tool chmtime --get -3600 b >old-mtime &&
75
76                 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
77
78                 test_must_be_empty err &&
79
80                 # Make sure b was NOT updated
81                 test-tool chmtime --get b >new-mtime &&
82                 test_cmp old-mtime new-mtime &&
83
84                 git ls-files -s >index_files &&
85                 test_line_count = 1 index_files &&
86
87                 git rev-parse >actual HEAD:b &&
88                 git rev-parse >expect A:b &&
89                 test_cmp expect actual &&
90
91                 git hash-object b   >actual &&
92                 git rev-parse   A:b >expect &&
93                 test_cmp expect actual
94         )
95 '
96
97 test_expect_success '1a-R: Modify(A)/Modify(B), change on B subset of A' '
98         test_setup_1a R &&
99         (
100                 cd 1a_R &&
101
102                 git checkout B^0 &&
103
104                 test-tool chmtime --get -3600 b >old-mtime &&
105                 GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
106
107                 # Make sure b WAS updated
108                 test-tool chmtime --get b >new-mtime &&
109                 test $(cat old-mtime) -lt $(cat new-mtime) &&
110
111                 test_must_be_empty err &&
112
113                 git ls-files -s >index_files &&
114                 test_line_count = 1 index_files &&
115
116                 git rev-parse >actual HEAD:b &&
117                 git rev-parse >expect A:b &&
118                 test_cmp expect actual &&
119
120                 git hash-object b   >actual &&
121                 git rev-parse   A:b >expect &&
122                 test_cmp expect actual
123         )
124 '
125
126
127 ###########################################################################
128 # SECTION 2: Cases involving basic renames
129 ###########################################################################
130
131 # Testcase 2a, Changes on A, rename on B
132 #   Commit O: b_1
133 #   Commit A: b_2
134 #   Commit B: c_1
135 #   Expected: c_2
136
137 test_setup_2a () {
138         test_create_repo 2a_$1 &&
139         (
140                 cd 2a_$1 &&
141
142                 test_seq 1 10 >b &&
143                 git add b &&
144                 test_tick &&
145                 git commit -m "O" &&
146
147                 git branch O &&
148                 git branch A &&
149                 git branch B &&
150
151                 git checkout A &&
152                 test_seq 1 11 >b &&
153                 git add b &&
154                 test_tick &&
155                 git commit -m "A" &&
156
157                 git checkout B &&
158                 git mv b c &&
159                 test_tick &&
160                 git commit -m "B"
161         )
162 }
163
164 test_expect_success '2a-L: Modify/rename, merge into modify side' '
165         test_setup_2a L &&
166         (
167                 cd 2a_L &&
168
169                 git checkout A^0 &&
170
171                 test_path_is_missing c &&
172                 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
173
174                 test_path_is_file c &&
175
176                 git ls-files -s >index_files &&
177                 test_line_count = 1 index_files &&
178
179                 git rev-parse >actual HEAD:c &&
180                 git rev-parse >expect A:b &&
181                 test_cmp expect actual &&
182
183                 git hash-object c   >actual &&
184                 git rev-parse   A:b >expect &&
185                 test_cmp expect actual &&
186
187                 test_must_fail git rev-parse HEAD:b &&
188                 test_path_is_missing b
189         )
190 '
191
192 test_expect_success '2a-R: Modify/rename, merge into rename side' '
193         test_setup_2a R &&
194         (
195                 cd 2a_R &&
196
197                 git checkout B^0 &&
198
199                 test-tool chmtime --get -3600 c >old-mtime &&
200                 GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
201
202                 # Make sure c WAS updated
203                 test-tool chmtime --get c >new-mtime &&
204                 test $(cat old-mtime) -lt $(cat new-mtime) &&
205
206                 test_must_be_empty err &&
207
208                 git ls-files -s >index_files &&
209                 test_line_count = 1 index_files &&
210
211                 git rev-parse >actual HEAD:c &&
212                 git rev-parse >expect A:b &&
213                 test_cmp expect actual &&
214
215                 git hash-object c   >actual &&
216                 git rev-parse   A:b >expect &&
217                 test_cmp expect actual &&
218
219                 test_must_fail git rev-parse HEAD:b &&
220                 test_path_is_missing b
221         )
222 '
223
224 # Testcase 2b, Changed and renamed on A, subset of changes on B
225 #   Commit O: b_1
226 #   Commit A: c_2
227 #   Commit B: b_3
228 #   Expected: c_2
229
230 test_setup_2b () {
231         test_create_repo 2b_$1 &&
232         (
233                 cd 2b_$1 &&
234
235                 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
236                 git add b &&
237                 test_tick &&
238                 git commit -m "O" &&
239
240                 git branch O &&
241                 git branch A &&
242                 git branch B &&
243
244                 git checkout A &&
245                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
246                 git add b &&
247                 git mv b c &&
248                 test_tick &&
249                 git commit -m "A" &&
250
251                 git checkout B &&
252                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
253                 git add b &&
254                 test_tick &&
255                 git commit -m "B"
256         )
257 }
258
259 test_expect_success '2b-L: Rename+Mod(A)/Mod(B), B mods subset of A' '
260         test_setup_2b L &&
261         (
262                 cd 2b_L &&
263
264                 git checkout A^0 &&
265
266                 test-tool chmtime --get -3600 c >old-mtime &&
267                 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
268
269                 test_must_be_empty err &&
270
271                 # Make sure c WAS updated
272                 test-tool chmtime --get c >new-mtime &&
273                 test_cmp old-mtime new-mtime &&
274
275                 git ls-files -s >index_files &&
276                 test_line_count = 1 index_files &&
277
278                 git rev-parse >actual HEAD:c &&
279                 git rev-parse >expect A:c &&
280                 test_cmp expect actual &&
281
282                 git hash-object c   >actual &&
283                 git rev-parse   A:c >expect &&
284                 test_cmp expect actual &&
285
286                 test_must_fail git rev-parse HEAD:b &&
287                 test_path_is_missing b
288         )
289 '
290
291 test_expect_success '2b-R: Rename+Mod(A)/Mod(B), B mods subset of A' '
292         test_setup_2b R &&
293         (
294                 cd 2b_R &&
295
296                 git checkout B^0 &&
297
298                 test_path_is_missing c &&
299                 GIT_MERGE_VERBOSITY=3 git merge -s recursive A^0 >out 2>err &&
300
301                 # Make sure c now present (and thus was updated)
302                 test_path_is_file c &&
303
304                 test_must_be_empty err &&
305
306                 git ls-files -s >index_files &&
307                 test_line_count = 1 index_files &&
308
309                 git rev-parse >actual HEAD:c &&
310                 git rev-parse >expect A:c &&
311                 test_cmp expect actual &&
312
313                 git hash-object c   >actual &&
314                 git rev-parse   A:c >expect &&
315                 test_cmp expect actual &&
316
317                 test_must_fail git rev-parse HEAD:b &&
318                 test_path_is_missing b
319         )
320 '
321
322 # Testcase 2c, Changes on A, rename on B
323 #   Commit O: b_1
324 #   Commit A: b_2, c_3
325 #   Commit B: c_1
326 #   Expected: rename/add conflict c_2 vs c_3
327 #
328 #   NOTE: Since A modified b_1->b_2, and B renamed b_1->c_1, the threeway
329 #         merge of those files should result in c_2.  We then should have a
330 #         rename/add conflict between c_2 and c_3.  However, if we note in
331 #         merge_content() that A had the right contents (b_2 has same
332 #         contents as c_2, just at a different name), and that A had the
333 #         right path present (c_3 existed) and thus decides that it can
334 #         skip the update, then we're in trouble.  This test verifies we do
335 #         not make that particular mistake.
336
337 test_setup_2c () {
338         test_create_repo 2c &&
339         (
340                 cd 2c &&
341
342                 test_seq 1 10 >b &&
343                 git add b &&
344                 test_tick &&
345                 git commit -m "O" &&
346
347                 git branch O &&
348                 git branch A &&
349                 git branch B &&
350
351                 git checkout A &&
352                 test_seq 1 11 >b &&
353                 echo whatever >c &&
354                 git add b c &&
355                 test_tick &&
356                 git commit -m "A" &&
357
358                 git checkout B &&
359                 git mv b c &&
360                 test_tick &&
361                 git commit -m "B"
362         )
363 }
364
365 test_expect_success '2c: Modify b & add c VS rename b->c' '
366         test_setup_2c &&
367         (
368                 cd 2c &&
369
370                 git checkout A^0 &&
371
372                 test-tool chmtime --get -3600 c >old-mtime &&
373                 GIT_MERGE_VERBOSITY=3 &&
374                 export GIT_MERGE_VERBOSITY &&
375                 test_must_fail git merge -s recursive B^0 >out 2>err &&
376
377                 test_i18ngrep "CONFLICT (rename/add): Rename b->c" out &&
378                 test_must_be_empty err &&
379
380                 # Make sure c WAS updated
381                 test-tool chmtime --get c >new-mtime &&
382                 test $(cat old-mtime) -lt $(cat new-mtime)
383
384                 # FIXME: rename/add conflicts are horribly broken right now;
385                 # when I get back to my patch series fixing it and
386                 # rename/rename(2to1) conflicts to bring them in line with
387                 # how add/add conflicts behave, then checks like the below
388                 # could be added.  But that patch series is waiting until
389                 # the rename-directory-detection series lands, which this
390                 # is part of.  And in the mean time, I do not want to further
391                 # enforce broken behavior.  So for now, the main test is the
392                 # one above that err is an empty file.
393
394                 #git ls-files -s >index_files &&
395                 #test_line_count = 2 index_files &&
396
397                 #git rev-parse >actual :2:c :3:c &&
398                 #git rev-parse >expect A:b  A:c  &&
399                 #test_cmp expect actual &&
400
401                 #git cat-file -p A:b >>merged &&
402                 #git cat-file -p A:c >>merge-me &&
403                 #>empty &&
404                 #test_must_fail git merge-file \
405                 #       -L "Temporary merge branch 1" \
406                 #       -L "" \
407                 #       -L "Temporary merge branch 2" \
408                 #       merged empty merge-me &&
409                 #sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal &&
410
411                 #git hash-object c               >actual &&
412                 #git hash-object merged-internal >expect &&
413                 #test_cmp expect actual &&
414
415                 #test_path_is_missing b
416         )
417 '
418
419
420 ###########################################################################
421 # SECTION 3: Cases involving directory renames
422 #
423 # NOTE:
424 #   Directory renames only apply when one side renames a directory, and the
425 #   other side adds or renames a path into that directory.  Applying the
426 #   directory rename to that new path creates a new pathname that didn't
427 #   exist on either side of history.  Thus, it is impossible for the
428 #   merge contents to already be at the right path, so all of these checks
429 #   exist just to make sure that updates are not skipped.
430 ###########################################################################
431
432 # Testcase 3a, Change + rename into dir foo on A, dir rename foo->bar on B
433 #   Commit O: bq_1, foo/whatever
434 #   Commit A: foo/{bq_2, whatever}
435 #   Commit B: bq_1, bar/whatever
436 #   Expected: bar/{bq_2, whatever}
437
438 test_setup_3a () {
439         test_create_repo 3a_$1 &&
440         (
441                 cd 3a_$1 &&
442
443                 mkdir foo &&
444                 test_seq 1 10 >bq &&
445                 test_write_lines a b c d e f g h i j k >foo/whatever &&
446                 git add bq foo/whatever &&
447                 test_tick &&
448                 git commit -m "O" &&
449
450                 git branch O &&
451                 git branch A &&
452                 git branch B &&
453
454                 git checkout A &&
455                 test_seq 1 11 >bq &&
456                 git add bq &&
457                 git mv bq foo/ &&
458                 test_tick &&
459                 git commit -m "A" &&
460
461                 git checkout B &&
462                 git mv foo/ bar/ &&
463                 test_tick &&
464                 git commit -m "B"
465         )
466 }
467
468 test_expect_success '3a-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
469         test_setup_3a L &&
470         (
471                 cd 3a_L &&
472
473                 git checkout A^0 &&
474
475                 test_path_is_missing bar/bq &&
476                 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
477
478                 test_must_be_empty err &&
479
480                 test_path_is_file bar/bq &&
481
482                 git ls-files -s >index_files &&
483                 test_line_count = 2 index_files &&
484
485                 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
486                 git rev-parse >expect A:foo/bq    A:foo/whatever &&
487                 test_cmp expect actual &&
488
489                 git hash-object bar/bq   bar/whatever   >actual &&
490                 git rev-parse   A:foo/bq A:foo/whatever >expect &&
491                 test_cmp expect actual &&
492
493                 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
494                 test_path_is_missing bq foo/bq foo/whatever
495         )
496 '
497
498 test_expect_success '3a-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
499         test_setup_3a R &&
500         (
501                 cd 3a_R &&
502
503                 git checkout B^0 &&
504
505                 test_path_is_missing bar/bq &&
506                 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
507
508                 test_must_be_empty err &&
509
510                 test_path_is_file bar/bq &&
511
512                 git ls-files -s >index_files &&
513                 test_line_count = 2 index_files &&
514
515                 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
516                 git rev-parse >expect A:foo/bq    A:foo/whatever &&
517                 test_cmp expect actual &&
518
519                 git hash-object bar/bq   bar/whatever   >actual &&
520                 git rev-parse   A:foo/bq A:foo/whatever >expect &&
521                 test_cmp expect actual &&
522
523                 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
524                 test_path_is_missing bq foo/bq foo/whatever
525         )
526 '
527
528 # Testcase 3b, rename into dir foo on A, dir rename foo->bar + change on B
529 #   Commit O: bq_1, foo/whatever
530 #   Commit A: foo/{bq_1, whatever}
531 #   Commit B: bq_2, bar/whatever
532 #   Expected: bar/{bq_2, whatever}
533
534 test_setup_3b () {
535         test_create_repo 3b_$1 &&
536         (
537                 cd 3b_$1 &&
538
539                 mkdir foo &&
540                 test_seq 1 10 >bq &&
541                 test_write_lines a b c d e f g h i j k >foo/whatever &&
542                 git add bq foo/whatever &&
543                 test_tick &&
544                 git commit -m "O" &&
545
546                 git branch O &&
547                 git branch A &&
548                 git branch B &&
549
550                 git checkout A &&
551                 git mv bq foo/ &&
552                 test_tick &&
553                 git commit -m "A" &&
554
555                 git checkout B &&
556                 test_seq 1 11 >bq &&
557                 git add bq &&
558                 git mv foo/ bar/ &&
559                 test_tick &&
560                 git commit -m "B"
561         )
562 }
563
564 test_expect_success '3b-L: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
565         test_setup_3b L &&
566         (
567                 cd 3b_L &&
568
569                 git checkout A^0 &&
570
571                 test_path_is_missing bar/bq &&
572                 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
573
574                 test_must_be_empty err &&
575
576                 test_path_is_file bar/bq &&
577
578                 git ls-files -s >index_files &&
579                 test_line_count = 2 index_files &&
580
581                 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
582                 git rev-parse >expect B:bq        A:foo/whatever &&
583                 test_cmp expect actual &&
584
585                 git hash-object bar/bq bar/whatever   >actual &&
586                 git rev-parse   B:bq   A:foo/whatever >expect &&
587                 test_cmp expect actual &&
588
589                 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
590                 test_path_is_missing bq foo/bq foo/whatever
591         )
592 '
593
594 test_expect_success '3b-R: bq_1->foo/bq_2 on A, foo/->bar/ on B' '
595         test_setup_3b R &&
596         (
597                 cd 3b_R &&
598
599                 git checkout B^0 &&
600
601                 test_path_is_missing bar/bq &&
602                 GIT_MERGE_VERBOSITY=3 git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
603
604                 test_must_be_empty err &&
605
606                 test_path_is_file bar/bq &&
607
608                 git ls-files -s >index_files &&
609                 test_line_count = 2 index_files &&
610
611                 git rev-parse >actual HEAD:bar/bq HEAD:bar/whatever &&
612                 git rev-parse >expect B:bq        A:foo/whatever &&
613                 test_cmp expect actual &&
614
615                 git hash-object bar/bq bar/whatever   >actual &&
616                 git rev-parse   B:bq   A:foo/whatever >expect &&
617                 test_cmp expect actual &&
618
619                 test_must_fail git rev-parse HEAD:bq HEAD:foo/bq &&
620                 test_path_is_missing bq foo/bq foo/whatever
621         )
622 '
623
624 ###########################################################################
625 # SECTION 4: Cases involving dirty changes
626 ###########################################################################
627
628 # Testcase 4a, Changed on A, subset of changes on B, locally modified
629 #   Commit O: b_1
630 #   Commit A: b_2
631 #   Commit B: b_3
632 #   Working copy: b_4
633 #   Expected: b_2 for merge, b_4 in working copy
634
635 test_setup_4a () {
636         test_create_repo 4a &&
637         (
638                 cd 4a &&
639
640                 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
641                 git add b &&
642                 test_tick &&
643                 git commit -m "O" &&
644
645                 git branch O &&
646                 git branch A &&
647                 git branch B &&
648
649                 git checkout A &&
650                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
651                 git add b &&
652                 test_tick &&
653                 git commit -m "A" &&
654
655                 git checkout B &&
656                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
657                 git add b &&
658                 test_tick &&
659                 git commit -m "B"
660         )
661 }
662
663 # NOTE: For as long as we continue using unpack_trees() without index_only
664 #   set to true, it will error out on a case like this claiming the the locally
665 #   modified file would be overwritten by the merge.  Getting this testcase
666 #   correct requires doing the merge in-memory first, then realizing that no
667 #   updates to the file are necessary, and thus that we can just leave the path
668 #   alone.
669 test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '
670         test_setup_4a &&
671         (
672                 cd 4a &&
673
674                 git checkout A^0 &&
675                 echo "File rewritten" >b &&
676
677                 test-tool chmtime --get -3600 b >old-mtime &&
678
679                 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
680
681                 test_must_be_empty err &&
682
683                 # Make sure b was NOT updated
684                 test-tool chmtime --get b >new-mtime &&
685                 test_cmp old-mtime new-mtime &&
686
687                 git ls-files -s >index_files &&
688                 test_line_count = 1 index_files &&
689
690                 git rev-parse >actual :0:b &&
691                 git rev-parse >expect A:b &&
692                 test_cmp expect actual &&
693
694                 git hash-object b >actual &&
695                 echo "File rewritten" | git hash-object --stdin >expect &&
696                 test_cmp expect actual
697         )
698 '
699
700 # Testcase 4b, Changed+renamed on A, subset of changes on B, locally modified
701 #   Commit O: b_1
702 #   Commit A: c_2
703 #   Commit B: b_3
704 #   Working copy: c_4
705 #   Expected: c_2
706
707 test_setup_4b () {
708         test_create_repo 4b &&
709         (
710                 cd 4b &&
711
712                 test_write_lines 1 2 3 4 5 6 7 8 9 10 >b &&
713                 git add b &&
714                 test_tick &&
715                 git commit -m "O" &&
716
717                 git branch O &&
718                 git branch A &&
719                 git branch B &&
720
721                 git checkout A &&
722                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 10.5 >b &&
723                 git add b &&
724                 git mv b c &&
725                 test_tick &&
726                 git commit -m "A" &&
727
728                 git checkout B &&
729                 test_write_lines 1 2 3 4 5 5.5 6 7 8 9 10 >b &&
730                 git add b &&
731                 test_tick &&
732                 git commit -m "B"
733         )
734 }
735
736 test_expect_success '4b: Rename+Mod(A)/Mod(B), change on B subset of A, dirty mods present' '
737         test_setup_4b &&
738         (
739                 cd 4b &&
740
741                 git checkout A^0 &&
742                 echo "File rewritten" >c &&
743
744                 test-tool chmtime --get -3600 c >old-mtime &&
745
746                 GIT_MERGE_VERBOSITY=3 git merge -s recursive B^0 >out 2>err &&
747
748                 test_must_be_empty err &&
749
750                 # Make sure c was NOT updated
751                 test-tool chmtime --get c >new-mtime &&
752                 test_cmp old-mtime new-mtime &&
753
754                 git ls-files -s >index_files &&
755                 test_line_count = 1 index_files &&
756
757                 git rev-parse >actual :0:c &&
758                 git rev-parse >expect A:c &&
759                 test_cmp expect actual &&
760
761                 git hash-object c >actual &&
762                 echo "File rewritten" | git hash-object --stdin >expect &&
763                 test_cmp expect actual &&
764
765                 test_must_fail git rev-parse HEAD:b &&
766                 test_path_is_missing b
767         )
768 '
769
770 test_done