1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 package org.eclipse.jgit.api;
44
45 import static java.nio.charset.StandardCharsets.UTF_8;
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertNull;
48 import static org.junit.Assert.assertNotNull;
49 import static org.junit.Assert.assertTrue;
50
51 import java.io.BufferedWriter;
52 import java.io.File;
53 import java.io.IOException;
54 import java.nio.file.Files;
55 import java.util.Arrays;
56 import java.util.Collection;
57
58 import org.eclipse.jgit.api.errors.GitAPIException;
59 import org.eclipse.jgit.api.errors.RefNotFoundException;
60 import org.eclipse.jgit.junit.RepositoryTestCase;
61 import org.eclipse.jgit.lib.ObjectId;
62 import org.junit.Test;
63 import org.junit.runner.RunWith;
64 import org.junit.runners.Parameterized;
65 import org.junit.runners.Parameterized.Parameter;
66 import org.junit.runners.Parameterized.Parameters;
67
68 @RunWith(Parameterized.class)
69 public class DescribeCommandTest extends RepositoryTestCase {
70
71 private Git git;
72
73 @Parameter(0)
74 public boolean useAnnotatedTags;
75
76 @Parameter(1)
77 public boolean describeUseAllTags;
78
79 @Parameters(name = "git tag -a {0}?-a: with git describe {1}?--tags:")
80 public static Collection<Boolean[]> getUseAnnotatedTagsValues() {
81 return Arrays.asList(new Boolean[][] { { Boolean.TRUE, Boolean.FALSE },
82 { Boolean.FALSE, Boolean.FALSE },
83 { Boolean.TRUE, Boolean.TRUE },
84 { Boolean.FALSE, Boolean.TRUE } });
85 }
86
87 @Override
88 public void setUp() throws Exception {
89 super.setUp();
90 git = new Git(db);
91 }
92
93 @Test(expected = RefNotFoundException.class)
94 public void noTargetSet() throws Exception {
95 git.describe().call();
96 }
97
98 @Test
99 public void testDescribe() throws Exception {
100 ObjectId c1 = modify("aaa");
101
102 ObjectId c2 = modify("bbb");
103 tag("alice-t1");
104
105 ObjectId c3 = modify("ccc");
106 tag("bob-t2");
107
108 ObjectId c4 = modify("ddd");
109 assertNameStartsWith(c4, "3e563c5");
110
111 assertNull(describe(c1));
112 assertNull(describe(c1, true, false));
113 assertNull(describe(c1, "a*", "b*", "c*"));
114 assertNull(describe(c2, "bob*"));
115 assertNull(describe(c2, "?ob*"));
116
117 if (useAnnotatedTags || describeUseAllTags) {
118 assertEquals("alice-t1", describe(c2));
119 assertEquals("alice-t1", describe(c2, "alice*"));
120 assertEquals("alice-t1", describe(c2, "a*", "b*", "c*"));
121
122 assertEquals("bob-t2", describe(c3));
123 assertEquals("bob-t2-0-g44579eb", describe(c3, true, false));
124 assertEquals("alice-t1-1-g44579eb", describe(c3, "alice*"));
125 assertEquals("alice-t1-1-g44579eb", describe(c3, "a??c?-t*"));
126 assertEquals("bob-t2", describe(c3, "bob*"));
127 assertEquals("bob-t2", describe(c3, "?ob*"));
128 assertEquals("bob-t2", describe(c3, "a*", "b*", "c*"));
129
130
131 assertEquals("bob-t2-1-g3e563c5", describe(c4));
132 assertEquals("bob-t2-1-g3e563c5", describe(c4, true, false));
133 assertEquals("alice-t1-2-g3e563c5", describe(c4, "alice*"));
134 assertEquals("bob-t2-1-g3e563c5", describe(c4, "bob*"));
135 assertEquals("bob-t2-1-g3e563c5", describe(c4, "a*", "b*", "c*"));
136 } else {
137 assertEquals(null, describe(c2));
138 assertEquals(null, describe(c3));
139 assertEquals(null, describe(c4));
140
141 assertEquals("3747db3", describe(c2, false, true));
142 assertEquals("44579eb", describe(c3, false, true));
143 assertEquals("3e563c5", describe(c4, false, true));
144 }
145
146
147 if (useAnnotatedTags) {
148 assertEquals("bob-t2-1-g3e563c5", git.describe().call());
149 assertEquals("bob-t2-1-g3e563c5",
150 git.describe().setTags(false).call());
151 assertEquals("bob-t2-1-g3e563c5",
152 git.describe().setTags(true).call());
153 } else {
154 assertEquals(null, git.describe().call());
155 assertEquals(null, git.describe().setTags(false).call());
156 assertEquals("bob-t2-1-g3e563c5",
157 git.describe().setTags(true).call());
158 }
159 }
160
161 @Test
162 public void testDescribeMultiMatch() throws Exception {
163 ObjectId c1 = modify("aaa");
164 tag("v1.0.0");
165 tick();
166 tag("v1.0.1");
167 tick();
168 tag("v1.1.0");
169 tick();
170 tag("v1.1.1");
171 ObjectId c2 = modify("bbb");
172
173 if (!useAnnotatedTags && !describeUseAllTags) {
174 assertEquals(null, describe(c1));
175 assertEquals(null, describe(c2));
176
177 assertEquals("fd70040", describe(c1, false, true));
178 assertEquals("b89dead", describe(c2, false, true));
179
180 return;
181 }
182
183
184
185 if (useAnnotatedTags) {
186 assertEquals("v1.1.1", describe(c1));
187 assertEquals("v1.1.1-1-gb89dead", describe(c2));
188
189 assertEquals("v1.0.1", describe(c1, "v1.0*"));
190 assertEquals("v1.1.1", describe(c1, "v1.1*"));
191 assertEquals("v1.0.1-1-gb89dead", describe(c2, "v1.0*"));
192 assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.1*"));
193
194
195 assertEquals("v1.1.1", describe(c1, "v1.0*", "v1.1*"));
196 assertEquals("v1.1.1", describe(c1, "v1.1*", "v1.0*"));
197 assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.0*", "v1.1*"));
198 assertEquals("v1.1.1-1-gb89dead", describe(c2, "v1.1*", "v1.0*"));
199 } else {
200
201 assertNotNull(describe(c1));
202 assertNotNull(describe(c2));
203
204 assertNotNull(describe(c1, "v1.0*"));
205 assertNotNull(describe(c1, "v1.1*"));
206 assertNotNull(describe(c2, "v1.0*"));
207 assertNotNull(describe(c2, "v1.1*"));
208
209
210 assertNotNull(describe(c1, "v1.0*", "v1.1*"));
211 assertNotNull(describe(c1, "v1.1*", "v1.0*"));
212 assertNotNull(describe(c2, "v1.0*", "v1.1*"));
213 assertNotNull(describe(c2, "v1.1*", "v1.0*"));
214 }
215 }
216
217
218
219
220
221
222
223
224
225
226
227
228 @Test
229 public void testDescribeBranch() throws Exception {
230 ObjectId c1 = modify("aaa");
231
232 ObjectId c2 = modify("bbb");
233 tag("t");
234
235 branch("b", c1);
236
237 ObjectId c3 = modify("ccc");
238
239 ObjectId c4 = merge(c2);
240
241 assertNameStartsWith(c4, "119892b");
242 if (useAnnotatedTags || describeUseAllTags) {
243 assertEquals("2 commits: c4 and c3", "t-2-g119892b", describe(c4));
244 } else {
245 assertEquals(null, describe(c4));
246
247 assertEquals("119892b", describe(c4, false, true));
248 }
249 assertNull(describe(c3));
250 assertNull(describe(c3, true, false));
251 }
252
253 private void branch(String name, ObjectId base) throws GitAPIException {
254 git.checkout().setCreateBranch(true).setName(name)
255 .setStartPoint(base.name()).call();
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269 @Test
270 public void t1DominatesT2() throws Exception {
271 ObjectId c1 = modify("aaa");
272 tag("t1");
273
274 ObjectId c2 = modify("bbb");
275 tag("t2");
276
277 branch("b", c1);
278
279 ObjectId c3 = modify("ccc");
280 assertNameStartsWith(c3, "0244e7f");
281
282 ObjectId c4 = merge(c2);
283
284 assertNameStartsWith(c4, "119892b");
285
286 if (useAnnotatedTags || describeUseAllTags) {
287 assertEquals("t2-2-g119892b", describe(c4));
288 assertEquals("t1-1-g0244e7f", describe(c3));
289 } else {
290 assertEquals(null, describe(c4));
291 assertEquals(null, describe(c3));
292
293 assertEquals("119892b", describe(c4, false, true));
294 assertEquals("0244e7f", describe(c3, false, true));
295 }
296 }
297
298
299
300
301
302
303
304
305
306
307
308
309 @Test
310 public void t1AnnotatedDominatesT2lightweight() throws Exception {
311 ObjectId c1 = modify("aaa");
312 tag("t1", useAnnotatedTags);
313
314 ObjectId c2 = modify("bbb");
315 tag("t2", false);
316
317 assertNameStartsWith(c2, "3747db3");
318 if (useAnnotatedTags && !describeUseAllTags) {
319 assertEquals(
320 "only annotated tag t1 expected to be used for describe",
321 "t1-1-g3747db3", describe(c2));
322
323 } else if (!useAnnotatedTags && !describeUseAllTags) {
324 assertEquals("no commits to describe expected", null, describe(c2));
325 } else {
326 assertEquals("lightweight tag t2 expected in describe", "t2",
327 describe(c2));
328 }
329
330 branch("b", c1);
331
332 ObjectId c3 = modify("ccc");
333
334 assertNameStartsWith(c3, "0244e7f");
335 if (useAnnotatedTags || describeUseAllTags) {
336 assertEquals("t1-1-g0244e7f", describe(c3));
337 }
338
339 ObjectId c4 = merge(c2);
340
341 assertNameStartsWith(c4, "119892b");
342 if (describeUseAllTags) {
343 assertEquals(
344 "2 commits for describe commit increment expected since lightweight tag: c4 and c3",
345 "t2-2-g119892b", describe(c4));
346 } else if (!useAnnotatedTags && !describeUseAllTags) {
347 assertEquals("no matching commits expected", null, describe(c4));
348 } else {
349 assertEquals(
350 "3 commits for describe commit increment expected since annotated tag: c4 and c3 and c2",
351 "t1-3-g119892b", describe(c4));
352 }
353 }
354
355
356
357
358
359
360
361
362
363
364
365
366 @Test
367 public void t1nearerT2() throws Exception {
368 ObjectId c1 = modify("aaa");
369 modify("bbb");
370 ObjectId t1 = modify("ccc");
371 tag("t1");
372
373 branch("b", c1);
374 modify("ddd");
375 tag("t2");
376 modify("eee");
377 ObjectId c4 = merge(t1);
378
379 assertNameStartsWith(c4, "bb389a4");
380 if (useAnnotatedTags || describeUseAllTags) {
381 assertEquals("t1-3-gbb389a4", describe(c4));
382 } else {
383 assertEquals(null, describe(c4));
384
385 assertEquals("bb389a4", describe(c4, false, true));
386 }
387 }
388
389
390
391
392
393
394
395
396
397
398
399
400
401 @Test
402 public void t1sameDepthT2() throws Exception {
403 ObjectId c1 = modify("aaa");
404 modify("bbb");
405 tag("t1");
406 ObjectId c2 = modify("ccc");
407
408 branch("b", c1);
409 modify("ddd");
410 tag("t2");
411 modify("eee");
412 ObjectId c4 = merge(c2);
413
414 assertNameStartsWith(c4, "bb389a4");
415 if (useAnnotatedTags || describeUseAllTags) {
416 assertEquals("t2-4-gbb389a4", describe(c4));
417 } else {
418 assertEquals(null, describe(c4));
419
420 assertEquals("bb389a4", describe(c4, false, true));
421 }
422 }
423
424 @Test
425 public void globMatchWithSlashes() throws Exception {
426 ObjectId c1 = modify("aaa");
427 tag("a/b/version");
428 ObjectId c2 = modify("bbb");
429 tag("a/b/version2");
430 if (useAnnotatedTags || describeUseAllTags) {
431 assertEquals("a/b/version", describe(c1, "*/version*"));
432 assertEquals("a/b/version2", describe(c2, "*/version*"));
433 } else {
434 assertNull(describe(c1));
435 assertNull(describe(c1, "*/version*"));
436 assertNull(describe(c2));
437 assertNull(describe(c2, "*/version*"));
438 }
439 }
440
441 private ObjectId merge(ObjectId c2) throws GitAPIException {
442 return git.merge().include(c2).call().getNewHead();
443 }
444
445 private ObjectId modify(String content) throws Exception {
446 File a = new File(db.getWorkTree(), "a.txt");
447 touch(a, content);
448 return git.commit().setAll(true).setMessage(content).call().getId();
449 }
450
451 private void tag(String tag) throws GitAPIException {
452 tag(tag, this.useAnnotatedTags);
453 }
454
455 private void tag(String tag, boolean annotatedTag) throws GitAPIException {
456 TagCommand tagCommand = git.tag().setName(tag)
457 .setAnnotated(annotatedTag);
458 if (annotatedTag) {
459 tagCommand.setMessage(tag);
460 }
461 tagCommand.call();
462 }
463
464 private static void touch(File f, String contents) throws Exception {
465 try (BufferedWriter w = Files.newBufferedWriter(f.toPath(), UTF_8)) {
466 w.write(contents);
467 }
468 }
469
470 private String describe(ObjectId c1, boolean longDesc, boolean always)
471 throws GitAPIException, IOException {
472 return git.describe().setTarget(c1).setTags(describeUseAllTags)
473 .setLong(longDesc).setAlways(always).call();
474 }
475
476 private String describe(ObjectId c1) throws GitAPIException, IOException {
477 return describe(c1, false, false);
478 }
479
480 private String describe(ObjectId c1, String... patterns) throws Exception {
481 return git.describe().setTarget(c1).setTags(describeUseAllTags)
482 .setMatch(patterns).call();
483 }
484
485 private static void assertNameStartsWith(ObjectId c4, String prefix) {
486 assertTrue(c4.name(), c4.name().startsWith(prefix));
487 }
488 }