Merge branch 'jc/calloc-fix'
[git] / t / t7611-merge-abort.sh
1 #!/bin/sh
2
3 test_description='test aborting in-progress merges
4
5 Set up repo with conflicting and non-conflicting branches:
6
7 There are three files foo/bar/baz, and the following graph illustrates the
8 content of these files in each commit:
9
10 # foo/bar/baz --- foo/bar/bazz     <-- main
11 #             \
12 #              --- foo/barf/bazf   <-- conflict_branch
13 #               \
14 #                --- foo/bart/baz  <-- clean_branch
15
16 Next, test git merge --abort with the following variables:
17 - before/after successful merge (should fail when not in merge context)
18 - with/without conflicts
19 - clean/dirty index before merge
20 - clean/dirty worktree before merge
21 - dirty index before merge matches contents on remote branch
22 - changed/unchanged worktree after merge
23 - changed/unchanged index after merge
24 '
25 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
26 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
27
28 . ./test-lib.sh
29
30 test_expect_success 'setup' '
31         # Create the above repo
32         echo foo > foo &&
33         echo bar > bar &&
34         echo baz > baz &&
35         git add foo bar baz &&
36         git commit -m initial &&
37         echo bazz > baz &&
38         git commit -a -m "second" &&
39         git checkout -b conflict_branch HEAD^ &&
40         echo barf > bar &&
41         echo bazf > baz &&
42         git commit -a -m "conflict" &&
43         git checkout -b clean_branch HEAD^ &&
44         echo bart > bar &&
45         git commit -a -m "clean" &&
46         git checkout main
47 '
48
49 pre_merge_head="$(git rev-parse HEAD)"
50
51 test_expect_success 'fails without MERGE_HEAD (unstarted merge)' '
52         test_must_fail git merge --abort 2>output &&
53         test_i18ngrep MERGE_HEAD output
54 '
55
56 test_expect_success 'fails without MERGE_HEAD (unstarted merge): .git/MERGE_HEAD sanity' '
57         test ! -f .git/MERGE_HEAD &&
58         test "$pre_merge_head" = "$(git rev-parse HEAD)"
59 '
60
61 test_expect_success 'fails without MERGE_HEAD (completed merge)' '
62         git merge clean_branch &&
63         test ! -f .git/MERGE_HEAD &&
64         # Merge successfully completed
65         post_merge_head="$(git rev-parse HEAD)" &&
66         test_must_fail git merge --abort 2>output &&
67         test_i18ngrep MERGE_HEAD output
68 '
69
70 test_expect_success 'fails without MERGE_HEAD (completed merge): .git/MERGE_HEAD sanity' '
71         test ! -f .git/MERGE_HEAD &&
72         test "$post_merge_head" = "$(git rev-parse HEAD)"
73 '
74
75 test_expect_success 'Forget previous merge' '
76         git reset --hard "$pre_merge_head"
77 '
78
79 test_expect_success 'Abort after --no-commit' '
80         # Redo merge, but stop before creating merge commit
81         git merge --no-commit clean_branch &&
82         test -f .git/MERGE_HEAD &&
83         # Abort non-conflicting merge
84         git merge --abort &&
85         test ! -f .git/MERGE_HEAD &&
86         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
87         test -z "$(git diff)" &&
88         test -z "$(git diff --staged)"
89 '
90
91 test_expect_success 'Abort after conflicts' '
92         # Create conflicting merge
93         test_must_fail git merge conflict_branch &&
94         test -f .git/MERGE_HEAD &&
95         # Abort conflicting merge
96         git merge --abort &&
97         test ! -f .git/MERGE_HEAD &&
98         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
99         test -z "$(git diff)" &&
100         test -z "$(git diff --staged)"
101 '
102
103 test_expect_success 'Clean merge with dirty index fails' '
104         echo xyzzy >> foo &&
105         git add foo &&
106         git diff --staged > expect &&
107         test_must_fail git merge clean_branch &&
108         test ! -f .git/MERGE_HEAD &&
109         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
110         test -z "$(git diff)" &&
111         git diff --staged > actual &&
112         test_cmp expect actual
113 '
114
115 test_expect_success 'Conflicting merge with dirty index fails' '
116         test_must_fail git merge conflict_branch &&
117         test ! -f .git/MERGE_HEAD &&
118         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
119         test -z "$(git diff)" &&
120         git diff --staged > actual &&
121         test_cmp expect actual
122 '
123
124 test_expect_success 'Reset index (but preserve worktree changes)' '
125         git reset "$pre_merge_head" &&
126         git diff > actual &&
127         test_cmp expect actual
128 '
129
130 test_expect_success 'Abort clean merge with non-conflicting dirty worktree' '
131         git merge --no-commit clean_branch &&
132         test -f .git/MERGE_HEAD &&
133         # Abort merge
134         git merge --abort &&
135         test ! -f .git/MERGE_HEAD &&
136         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
137         test -z "$(git diff --staged)" &&
138         git diff > actual &&
139         test_cmp expect actual
140 '
141
142 test_expect_success 'Abort conflicting merge with non-conflicting dirty worktree' '
143         test_must_fail git merge conflict_branch &&
144         test -f .git/MERGE_HEAD &&
145         # Abort merge
146         git merge --abort &&
147         test ! -f .git/MERGE_HEAD &&
148         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
149         test -z "$(git diff --staged)" &&
150         git diff > actual &&
151         test_cmp expect actual
152 '
153
154 test_expect_success 'Reset worktree changes' '
155         git reset --hard "$pre_merge_head"
156 '
157
158 test_expect_success 'Fail clean merge with conflicting dirty worktree' '
159         echo xyzzy >> bar &&
160         git diff > expect &&
161         test_must_fail git merge --no-commit clean_branch &&
162         test ! -f .git/MERGE_HEAD &&
163         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
164         test -z "$(git diff --staged)" &&
165         git diff > actual &&
166         test_cmp expect actual
167 '
168
169 test_expect_success 'Fail conflicting merge with conflicting dirty worktree' '
170         test_must_fail git merge conflict_branch &&
171         test ! -f .git/MERGE_HEAD &&
172         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
173         test -z "$(git diff --staged)" &&
174         git diff > actual &&
175         test_cmp expect actual
176 '
177
178 test_expect_success 'Reset worktree changes' '
179         git reset --hard "$pre_merge_head"
180 '
181
182 test_expect_success 'Fail clean merge with matching dirty worktree' '
183         echo bart > bar &&
184         git diff > expect &&
185         test_must_fail git merge --no-commit clean_branch &&
186         test ! -f .git/MERGE_HEAD &&
187         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
188         test -z "$(git diff --staged)" &&
189         git diff > actual &&
190         test_cmp expect actual
191 '
192
193 test_expect_success 'Fail conflicting merge with matching dirty worktree' '
194         echo barf > bar &&
195         git diff > expect &&
196         test_must_fail git merge conflict_branch &&
197         test ! -f .git/MERGE_HEAD &&
198         test "$pre_merge_head" = "$(git rev-parse HEAD)" &&
199         test -z "$(git diff --staged)" &&
200         git diff > actual &&
201         test_cmp expect actual
202 '
203
204 test_done