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