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