Merge branch 'jk/fast-import-use-hashmap'
[git] / t / t6012-rev-list-simplify.sh
1 #!/bin/sh
2
3 test_description='merge simplification'
4
5 . ./test-lib.sh
6
7 note () {
8         git tag "$1"
9 }
10
11 unnote () {
12         git name-rev --tags --stdin | sed -e "s|$OID_REGEX (tags/\([^)]*\)) |\1 |g"
13 }
14
15 #
16 # Create a test repo with interesting commit graph:
17 #
18 # A--B----------G--H--I--K--L
19 #  \  \           /     /
20 #   \  \         /     /
21 #    C------E---F     J
22 #        \_/
23 #
24 # The commits are laid out from left-to-right starting with
25 # the root commit A and terminating at the tip commit L.
26 #
27 # There are a few places where we adjust the commit date or
28 # author date to make the --topo-order, --date-order, and
29 # --author-date-order flags produce different output.
30
31 test_expect_success setup '
32         echo "Hi there" >file &&
33         echo "initial" >lost &&
34         git add file lost &&
35         test_tick && git commit -m "Initial file and lost" &&
36         note A &&
37
38         git branch other-branch &&
39
40         git symbolic-ref HEAD refs/heads/unrelated &&
41         git rm -f "*" &&
42         echo "Unrelated branch" >side &&
43         git add side &&
44         test_tick && git commit -m "Side root" &&
45         note J &&
46         git checkout master &&
47
48         echo "Hello" >file &&
49         echo "second" >lost &&
50         git add file lost &&
51         test_tick && GIT_AUTHOR_DATE=$(($test_tick + 120)) git commit -m "Modified file and lost" &&
52         note B &&
53
54         git checkout other-branch &&
55
56         echo "Hello" >file &&
57         >lost &&
58         git add file lost &&
59         test_tick && git commit -m "Modified the file identically" &&
60         note C &&
61
62         echo "This is a stupid example" >another-file &&
63         git add another-file &&
64         test_tick && git commit -m "Add another file" &&
65         note D &&
66
67         test_tick &&
68         test_must_fail git merge -m "merge" master &&
69         >lost && git commit -a -m "merge" &&
70         note E &&
71
72         echo "Yet another" >elif &&
73         git add elif &&
74         test_tick && git commit -m "Irrelevant change" &&
75         note F &&
76
77         git checkout master &&
78         echo "Yet another" >elif &&
79         git add elif &&
80         test_tick && git commit -m "Another irrelevant change" &&
81         note G &&
82
83         test_tick && git merge -m "merge" other-branch &&
84         note H &&
85
86         echo "Final change" >file &&
87         test_tick && git commit -a -m "Final change" &&
88         note I &&
89
90         git checkout master &&
91         test_tick && git merge --allow-unrelated-histories -m "Coolest" unrelated &&
92         note K &&
93
94         echo "Immaterial" >elif &&
95         git add elif &&
96         test_tick && git commit -m "Last" &&
97         note L
98 '
99
100 FMT='tformat:%P         %H | %s'
101
102 check_outcome () {
103         outcome=$1
104         shift
105         for c in $1
106         do
107                 echo "$c"
108         done >expect &&
109         shift &&
110         param="$*" &&
111         test_expect_$outcome "log $param" '
112                 git log --pretty="$FMT" --parents $param |
113                 unnote >actual &&
114                 sed -e "s/^.*   \([^ ]*\) .*/\1/" >check <actual &&
115                 test_cmp expect check
116         '
117 }
118
119 check_result () {
120         check_outcome success "$@"
121 }
122
123 check_result 'L K J I H F E D C G B A' --full-history --topo-order
124 check_result 'L K I H G F E D C B J A' --full-history
125 check_result 'L K I H G F E D C B J A' --full-history --date-order
126 check_result 'L K I H G F E D B C J A' --full-history --author-date-order
127 check_result 'K I H E C B A' --full-history -- file
128 check_result 'K I H E C B A' --full-history --topo-order -- file
129 check_result 'K I H E C B A' --full-history --date-order -- file
130 check_result 'K I H E B C A' --full-history --author-date-order -- file
131 check_result 'I E C B A' --simplify-merges -- file
132 check_result 'I E C B A' --simplify-merges --topo-order -- file
133 check_result 'I E C B A' --simplify-merges --date-order -- file
134 check_result 'I E B C A' --simplify-merges --author-date-order -- file
135 check_result 'I B A' -- file
136 check_result 'I B A' --topo-order -- file
137 check_result 'I B A' --date-order -- file
138 check_result 'I B A' --author-date-order -- file
139 check_result 'H' --first-parent -- another-file
140 check_result 'H' --first-parent --topo-order -- another-file
141
142 check_result 'E C B A' --full-history E -- lost
143 test_expect_success 'full history simplification without parent' '
144         printf "%s\n" E C B A >expect &&
145         git log --pretty="$FMT" --full-history E -- lost |
146         unnote >actual &&
147         sed -e "s/^.*   \([^ ]*\) .*/\1/" >check <actual &&
148         test_cmp expect check
149 '
150
151 test_expect_success '--full-diff is not affected by --parents' '
152         git log -p --pretty="%H" --full-diff -- file >expected &&
153         git log -p --pretty="%H" --full-diff --parents -- file >actual &&
154         test_cmp expected actual
155 '
156
157 #
158 # Create a new history to demonstrate the value of --show-pulls
159 # with respect to the subtleties of simplified history, --full-history,
160 # and --simplify-merges.
161 #
162 #   .-A---M-----C--N---O---P
163 #  /     / \  \  \/   /   /
164 # I     B   \  R-'`-Z'   /
165 #  \   /     \/         /
166 #   \ /      /\        /
167 #    `---X--'  `---Y--'
168 #
169 # This example is explained in Documentation/rev-list-options.txt
170
171 test_expect_success 'rebuild repo' '
172         rm -rf .git * &&
173         git init &&
174         git switch -c main &&
175
176         echo base >file &&
177         git add file &&
178         test_commit I &&
179
180         echo A >file &&
181         git add file &&
182         test_commit A &&
183
184         git switch -c branchB I &&
185         echo B >file &&
186         git add file &&
187         test_commit B &&
188
189         git switch main &&
190         test_must_fail git merge -m "M" B &&
191         echo A >file &&
192         echo B >>file &&
193         git add file &&
194         git merge --continue &&
195         note M &&
196
197         echo C >other &&
198         git add other &&
199         test_commit C &&
200
201         git switch -c branchX I &&
202         echo X >file &&
203         git add file &&
204         test_commit X &&
205
206         git switch -c branchR M &&
207         git merge -m R -Xtheirs X &&
208         note R &&
209
210         git switch main &&
211         git merge -m N R &&
212         note N &&
213
214         git switch -c branchY M &&
215         echo Y >y &&
216         git add y &&
217         test_commit Y &&
218
219         git switch -c branchZ C &&
220         echo Z >z &&
221         git add z &&
222         test_commit Z &&
223
224         git switch main &&
225         git merge -m O Z &&
226         note O &&
227
228         git merge -m P Y &&
229         note P
230 '
231
232 check_result 'X I' -- file
233 check_result 'N R X I' --show-pulls -- file
234
235 check_result 'P O N R X M B A I' --full-history --topo-order -- file
236 check_result 'N R X M B A I' --simplify-merges --topo-order --show-pulls -- file
237 check_result 'R X M B A I' --simplify-merges --topo-order -- file
238 check_result 'N M A I' --first-parent -- file
239 check_result 'N M A I' --first-parent --show-pulls -- file
240
241 # --ancestry-path implies --full-history
242 check_result 'P O N R M' --topo-order \
243         --ancestry-path A..HEAD -- file
244 check_result 'P O N R M' --topo-order \
245         --show-pulls \
246         --ancestry-path A..HEAD -- file
247 check_result 'P O N R M' --topo-order \
248         --full-history \
249         --ancestry-path A..HEAD -- file
250 check_result 'R M' --topo-order \
251         --simplify-merges \
252         --ancestry-path A..HEAD -- file
253 check_result 'N R M' --topo-order \
254         --simplify-merges --show-pulls \
255         --ancestry-path A..HEAD -- file
256
257 test_expect_success 'log --graph --simplify-merges --show-pulls' '
258         cat >expect <<-\EOF &&
259         * N
260         *   R
261         |\  
262         | * X
263         * |   M
264         |\ \  
265         | * | B
266         | |/  
267         * / A
268         |/  
269         * I
270         EOF
271         git log --graph --pretty="%s" \
272                 --simplify-merges --show-pulls \
273                 -- file >actual &&
274         test_cmp expect actual
275 '
276
277 test_done