1
2
3
4
5
6
7
8
9
10
11
12
13 package org.eclipse.jgit.lib;
14
15 import static java.nio.charset.StandardCharsets.UTF_8;
16 import static org.eclipse.jgit.junit.Assert.assertEquals;
17 import static org.junit.Assert.assertEquals;
18 import static org.junit.Assert.assertFalse;
19 import static org.junit.Assert.assertNotNull;
20 import static org.junit.Assert.assertNull;
21 import static org.junit.Assert.assertSame;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
24
25 import java.io.File;
26 import java.io.FileOutputStream;
27 import java.io.IOException;
28 import java.util.Collection;
29 import java.util.HashSet;
30 import java.util.List;
31 import java.util.Optional;
32 import java.util.Set;
33 import java.util.TreeSet;
34
35 import org.eclipse.jgit.lib.Ref.Storage;
36 import org.eclipse.jgit.lib.RefUpdate.Result;
37 import org.eclipse.jgit.storage.file.FileBasedConfig;
38 import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
39 import org.junit.Test;
40
41
42
43
44
45 public class RefTest extends SampleDataRepositoryTestCase {
46
47 private void writeSymref(String src, String dst) throws IOException {
48 RefUpdate u = db.updateRef(src);
49 switch (u.link(dst)) {
50 case NEW:
51 case FORCED:
52 case NO_CHANGE:
53 break;
54 default:
55 fail("link " + src + " to " + dst);
56 }
57 }
58
59 private void writeNewRef(String name, ObjectId value) throws IOException {
60 RefUpdate updateRef = db.updateRef(name);
61 updateRef.setNewObjectId(value);
62 assertEquals(RefUpdate.Result.NEW, updateRef.update());
63 }
64
65 @Test
66 public void testRemoteNames() throws Exception {
67 FileBasedConfig config = db.getConfig();
68 config.setBoolean(ConfigConstants.CONFIG_REMOTE_SECTION,
69 "origin", "dummy", true);
70 config.setBoolean(ConfigConstants.CONFIG_REMOTE_SECTION,
71 "ab/c", "dummy", true);
72 config.save();
73 assertEquals("[ab/c, origin]",
74 new TreeSet<>(db.getRemoteNames()).toString());
75
76
77 assertEquals("master",
78 db.shortenRemoteBranchName("refs/remotes/origin/master"));
79 assertEquals("origin", db.getRemoteName("refs/remotes/origin/master"));
80
81
82 assertEquals("masta/r",
83 db.shortenRemoteBranchName("refs/remotes/origin/masta/r"));
84 assertEquals("origin", db.getRemoteName("refs/remotes/origin/masta/r"));
85
86
87 assertEquals("xmaster",
88 db.shortenRemoteBranchName("refs/remotes/ab/c/xmaster"));
89 assertEquals("ab/c", db.getRemoteName("refs/remotes/ab/c/xmaster"));
90
91
92 assertEquals("xmasta/r",
93 db.shortenRemoteBranchName("refs/remotes/ab/c/xmasta/r"));
94 assertEquals("ab/c", db.getRemoteName("refs/remotes/ab/c/xmasta/r"));
95
96
97 assertNull(db.getRemoteName("refs/remotes/nosuchremote/x"));
98 assertNull(db.shortenRemoteBranchName("refs/remotes/nosuchremote/x"));
99
100
101 assertNull(db.getRemoteName("refs/remotes/abranch"));
102 assertNull(db.shortenRemoteBranchName("refs/remotes/abranch"));
103
104
105 assertNull(db.getRemoteName("refs/heads/abranch"));
106 assertNull(db.shortenRemoteBranchName("refs/heads/abranch"));
107 }
108
109 @Test
110 public void testReadAllIncludingSymrefs() throws Exception {
111 ObjectId masterId = db.resolve("refs/heads/master");
112 RefUpdate updateRef = db.updateRef("refs/remotes/origin/master");
113 updateRef.setNewObjectId(masterId);
114 updateRef.setForceUpdate(true);
115 updateRef.update();
116 writeSymref("refs/remotes/origin/HEAD",
117 "refs/remotes/origin/master");
118
119 ObjectId r = db.resolve("refs/remotes/origin/HEAD");
120 assertEquals(masterId, r);
121
122 List<Ref> allRefs = db.getRefDatabase().getRefs();
123 Optional<Ref> refHEAD = allRefs.stream()
124 .filter(ref -> ref.getName().equals("refs/remotes/origin/HEAD"))
125 .findAny();
126 assertTrue(refHEAD.isPresent());
127 assertEquals(masterId, refHEAD.get().getObjectId());
128 assertFalse(refHEAD.get().isPeeled());
129 assertNull(refHEAD.get().getPeeledObjectId());
130
131 Optional<Ref> refmaster = allRefs.stream().filter(
132 ref -> ref.getName().equals("refs/remotes/origin/master"))
133 .findAny();
134 assertTrue(refmaster.isPresent());
135 assertEquals(masterId, refmaster.get().getObjectId());
136 assertFalse(refmaster.get().isPeeled());
137 assertNull(refmaster.get().getPeeledObjectId());
138 }
139
140 @Test
141 public void testReadSymRefToPacked() throws IOException {
142 writeSymref("HEAD", "refs/heads/b");
143 Ref ref = db.exactRef("HEAD");
144 assertEquals(Ref.Storage.LOOSE, ref.getStorage());
145 assertTrue("is symref", ref.isSymbolic());
146 ref = ref.getTarget();
147 assertEquals("refs/heads/b", ref.getName());
148 assertEquals(Ref.Storage.PACKED, ref.getStorage());
149 }
150
151 @Test
152 public void testReadSymRefToLoosePacked() throws IOException {
153 ObjectId pid = db.resolve("refs/heads/master^");
154 RefUpdate updateRef = db.updateRef("refs/heads/master");
155 updateRef.setNewObjectId(pid);
156 updateRef.setForceUpdate(true);
157 Result update = updateRef.update();
158 assertEquals(Result.FORCED, update);
159
160 writeSymref("HEAD", "refs/heads/master");
161 Ref ref = db.exactRef("HEAD");
162 assertEquals(Ref.Storage.LOOSE, ref.getStorage());
163 ref = ref.getTarget();
164 assertEquals("refs/heads/master", ref.getName());
165 assertEquals(Ref.Storage.LOOSE, ref.getStorage());
166 }
167
168 @Test
169 public void testReadLooseRef() throws IOException {
170 RefUpdate updateRef = db.updateRef("ref/heads/new");
171 updateRef.setNewObjectId(db.resolve("refs/heads/master"));
172 Result update = updateRef.update();
173 assertEquals(Result.NEW, update);
174 Ref ref = db.exactRef("ref/heads/new");
175 assertEquals(Storage.LOOSE, ref.getStorage());
176 }
177
178 @Test
179 public void testGetShortRef() throws IOException {
180 Ref ref = db.exactRef("refs/heads/master");
181 assertEquals("refs/heads/master", ref.getName());
182 assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
183 }
184
185 @Test
186 public void testGetShortExactRef() throws IOException {
187 assertNull(db.getRefDatabase().exactRef("master"));
188
189 Ref ref = db.getRefDatabase().exactRef("HEAD");
190 assertEquals("HEAD", ref.getName());
191 assertEquals("refs/heads/master", ref.getTarget().getName());
192 assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
193 }
194
195 @Test
196 public void testRefsUnderRefs() throws IOException {
197 ObjectId masterId = db.resolve("refs/heads/master");
198 writeNewRef("refs/heads/refs/foo/bar", masterId);
199
200 assertNull(db.getRefDatabase().exactRef("refs/foo/bar"));
201
202 Ref ref = db.findRef("refs/foo/bar");
203 assertEquals("refs/heads/refs/foo/bar", ref.getName());
204 assertEquals(db.resolve("refs/heads/master"), ref.getObjectId());
205 }
206
207 @Test
208 public void testAmbiguousRefsUnderRefs() throws IOException {
209 ObjectId masterId = db.resolve("refs/heads/master");
210 writeNewRef("refs/foo/bar", masterId);
211 writeNewRef("refs/heads/refs/foo/bar", masterId);
212
213 Ref exactRef = db.getRefDatabase().exactRef("refs/foo/bar");
214 assertEquals("refs/foo/bar", exactRef.getName());
215 assertEquals(masterId, exactRef.getObjectId());
216
217 Ref ref = db.findRef("refs/foo/bar");
218 assertEquals("refs/foo/bar", ref.getName());
219 assertEquals(masterId, ref.getObjectId());
220 }
221
222
223
224
225
226
227
228 @Test
229 public void testReadLoosePackedRef() throws IOException,
230 InterruptedException {
231 Ref ref = db.exactRef("refs/heads/master");
232 assertEquals(Storage.PACKED, ref.getStorage());
233 try (FileOutputStream os = new FileOutputStream(
234 new File(db.getDirectory(), "refs/heads/master"))) {
235 os.write(ref.getObjectId().name().getBytes(UTF_8));
236 os.write('\n');
237 }
238
239 ref = db.exactRef("refs/heads/master");
240 assertEquals(Storage.LOOSE, ref.getStorage());
241 }
242
243
244
245
246
247
248
249 @Test
250 public void testReadSimplePackedRefSameRepo() throws IOException {
251 Ref ref = db.exactRef("refs/heads/master");
252 ObjectId pid = db.resolve("refs/heads/master^");
253 assertEquals(Storage.PACKED, ref.getStorage());
254 RefUpdate updateRef = db.updateRef("refs/heads/master");
255 updateRef.setNewObjectId(pid);
256 updateRef.setForceUpdate(true);
257 Result update = updateRef.update();
258 assertEquals(Result.FORCED, update);
259
260 ref = db.exactRef("refs/heads/master");
261 assertEquals(Storage.LOOSE, ref.getStorage());
262 }
263
264 @Test
265 public void testResolvedNamesBranch() throws IOException {
266 Ref ref = db.findRef("a");
267 assertEquals("refs/heads/a", ref.getName());
268 }
269
270 @Test
271 public void testResolvedSymRef() throws IOException {
272 Ref ref = db.exactRef(Constants.HEAD);
273 assertEquals(Constants.HEAD, ref.getName());
274 assertTrue("is symbolic ref", ref.isSymbolic());
275 assertSame(Ref.Storage.LOOSE, ref.getStorage());
276
277 Ref dst = ref.getTarget();
278 assertNotNull("has target", dst);
279 assertEquals("refs/heads/master", dst.getName());
280
281 assertSame(dst.getObjectId(), ref.getObjectId());
282 assertSame(dst.getPeeledObjectId(), ref.getPeeledObjectId());
283 assertEquals(dst.isPeeled(), ref.isPeeled());
284 }
285
286 private static void checkContainsRef(Collection<Ref> haystack, Ref needle) {
287 for (Ref ref : haystack) {
288 if (ref.getName().equals(needle.getName()) &&
289 ref.getObjectId().equals(needle.getObjectId())) {
290 return;
291 }
292 }
293 fail("list " + haystack + " does not contain ref " + needle);
294 }
295
296 @Test
297 public void testGetRefsByPrefix() throws IOException {
298 List<Ref> refs = db.getRefDatabase().getRefsByPrefix("refs/heads/g");
299 assertEquals(2, refs.size());
300 checkContainsRef(refs, db.exactRef("refs/heads/g"));
301 checkContainsRef(refs, db.exactRef("refs/heads/gitlink"));
302
303 refs = db.getRefDatabase().getRefsByPrefix("refs/heads/prefix/");
304 assertEquals(1, refs.size());
305 checkContainsRef(refs, db.exactRef("refs/heads/prefix/a"));
306 }
307
308 @Test
309 public void testGetRefsByPrefixes() throws IOException {
310 List<Ref> refs = db.getRefDatabase().getRefsByPrefix();
311 assertEquals(0, refs.size());
312
313 refs = db.getRefDatabase().getRefsByPrefix("refs/heads/p",
314 "refs/tags/A");
315 assertEquals(3, refs.size());
316 checkContainsRef(refs, db.exactRef("refs/heads/pa"));
317 checkContainsRef(refs, db.exactRef("refs/heads/prefix/a"));
318 checkContainsRef(refs, db.exactRef("refs/tags/A"));
319 }
320
321 @Test
322 public void testGetRefsExcludingPrefix() throws IOException {
323 Set<String> exclude = new HashSet<>();
324 exclude.add("refs/tags");
325
326 List<Ref> refs =
327 db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, exclude);
328 assertEquals(13, refs.size());
329 checkContainsRef(refs, db.exactRef("HEAD"));
330 checkContainsRef(refs, db.exactRef("refs/heads/a"));
331 for (Ref notInResult : db.getRefDatabase().getRefsByPrefix("refs/tags")) {
332 assertFalse(refs.contains(notInResult));
333 }
334 }
335
336 @Test
337 public void testGetRefsExcludingPrefixes() throws IOException {
338 Set<String> exclude = new HashSet<>();
339 exclude.add("refs/tags/");
340 exclude.add("refs/heads/");
341 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, exclude);
342 assertEquals(1, refs.size());
343 checkContainsRef(refs, db.exactRef("HEAD"));
344 }
345
346 @Test
347 public void testGetRefsExcludingNonExistingPrefixes() throws IOException {
348 Set<String> prefixes = new HashSet<>();
349 prefixes.add("refs/tags/");
350 prefixes.add("refs/heads/");
351 prefixes.add("refs/nonexistent/");
352 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, prefixes);
353 assertEquals(1, refs.size());
354 checkContainsRef(refs, db.exactRef("HEAD"));
355 }
356
357 @Test
358 public void testGetRefsWithPrefixExcludingPrefixes() throws IOException {
359 Set<String> exclude = new HashSet<>();
360 exclude.add("refs/heads/pa");
361 String include = "refs/heads/p";
362 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(include, exclude);
363 assertEquals(1, refs.size());
364 checkContainsRef(refs, db.exactRef("refs/heads/prefix/a"));
365 }
366
367 @Test
368 public void testGetRefsWithPrefixExcludingOverlappingPrefixes() throws IOException {
369 Set<String> exclude = new HashSet<>();
370 exclude.add("refs/heads/pa");
371 exclude.add("refs/heads/");
372 exclude.add("refs/heads/p");
373 exclude.add("refs/tags/");
374 List<Ref> refs = db.getRefDatabase().getRefsByPrefixWithExclusions(RefDatabase.ALL, exclude);
375 assertEquals(1, refs.size());
376 checkContainsRef(refs, db.exactRef("HEAD"));
377 }
378
379 @Test
380 public void testResolveTipSha1() throws IOException {
381 ObjectId masterId = db.resolve("refs/heads/master");
382 Set<Ref> resolved = db.getRefDatabase().getTipsWithSha1(masterId);
383
384 assertEquals(2, resolved.size());
385 checkContainsRef(resolved, db.exactRef("refs/heads/master"));
386 checkContainsRef(resolved, db.exactRef("HEAD"));
387
388 assertEquals(db.getRefDatabase()
389 .getTipsWithSha1(ObjectId.zeroId()).size(), 0);
390 }
391 }