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
44 package org.eclipse.jgit.internal.storage.file;
45
46 import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
47 import static org.eclipse.jgit.lib.Constants.OBJECT_ID_STRING_LENGTH;
48 import static org.junit.Assert.assertEquals;
49 import static org.junit.Assert.assertNotNull;
50 import static org.junit.Assert.assertTrue;
51 import static org.junit.Assert.fail;
52
53 import java.io.BufferedOutputStream;
54 import java.io.ByteArrayOutputStream;
55 import java.io.File;
56 import java.io.FileOutputStream;
57 import java.io.IOException;
58 import java.io.OutputStream;
59 import java.util.ArrayList;
60 import java.util.Collection;
61 import java.util.List;
62
63 import org.eclipse.jgit.errors.AmbiguousObjectException;
64 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
65 import org.eclipse.jgit.junit.TestRepository;
66 import org.eclipse.jgit.lib.AbbreviatedObjectId;
67 import org.eclipse.jgit.lib.ObjectId;
68 import org.eclipse.jgit.lib.ObjectReader;
69 import org.eclipse.jgit.lib.Repository;
70 import org.eclipse.jgit.revwalk.RevBlob;
71 import org.eclipse.jgit.transport.PackedObjectInfo;
72 import org.eclipse.jgit.util.FileUtils;
73 import org.junit.After;
74 import org.junit.Before;
75 import org.junit.Test;
76
77 public class AbbreviationTest extends LocalDiskRepositoryTestCase {
78 private FileRepository db;
79
80 private ObjectReader reader;
81
82 private TestRepository<Repository> test;
83
84 @Override
85 @Before
86 public void setUp() throws Exception {
87 super.setUp();
88 db = createBareRepository();
89 reader = db.newObjectReader();
90 test = new TestRepository<>(db);
91 }
92
93 @Override
94 @After
95 public void tearDown() throws Exception {
96 if (reader != null) {
97 reader.close();
98 }
99 }
100
101 @Test
102 public void testAbbreviateOnEmptyRepository() throws IOException {
103 ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba");
104
105 assertEquals(id.abbreviate(2), reader.abbreviate(id, 2));
106 assertEquals(id.abbreviate(7), reader.abbreviate(id, 7));
107 assertEquals(id.abbreviate(8), reader.abbreviate(id, 8));
108 assertEquals(id.abbreviate(10), reader.abbreviate(id, 10));
109 assertEquals(id.abbreviate(16), reader.abbreviate(id, 16));
110
111 assertEquals(AbbreviatedObjectId.fromObjectId(id),
112 reader.abbreviate(id, OBJECT_ID_STRING_LENGTH));
113
114 Collection<ObjectId> matches;
115
116 matches = reader.resolve(reader.abbreviate(id, 8));
117 assertNotNull(matches);
118 assertEquals(0, matches.size());
119
120 matches = reader.resolve(AbbreviatedObjectId.fromObjectId(id));
121 assertNotNull(matches);
122 assertEquals(1, matches.size());
123 assertEquals(id, matches.iterator().next());
124 }
125
126 @Test
127 public void testAbbreviateLooseBlob() throws Exception {
128 ObjectId id = test.blob("test");
129
130 assertEquals(id.abbreviate(2), reader.abbreviate(id, 2));
131 assertEquals(id.abbreviate(7), reader.abbreviate(id, 7));
132 assertEquals(id.abbreviate(8), reader.abbreviate(id, 8));
133 assertEquals(id.abbreviate(10), reader.abbreviate(id, 10));
134 assertEquals(id.abbreviate(16), reader.abbreviate(id, 16));
135
136 Collection<ObjectId> matches = reader.resolve(reader.abbreviate(id, 8));
137 assertNotNull(matches);
138 assertEquals(1, matches.size());
139 assertEquals(id, matches.iterator().next());
140
141 assertEquals(id, db.resolve(reader.abbreviate(id, 8).name()));
142 }
143
144 @Test
145 public void testAbbreviatePackedBlob() throws Exception {
146 RevBlob id = test.blob("test");
147 test.branch("master").commit().add("test", id).child();
148 test.packAndPrune();
149 assertTrue(reader.has(id));
150
151 assertEquals(id.abbreviate(7), reader.abbreviate(id, 7));
152 assertEquals(id.abbreviate(8), reader.abbreviate(id, 8));
153 assertEquals(id.abbreviate(10), reader.abbreviate(id, 10));
154 assertEquals(id.abbreviate(16), reader.abbreviate(id, 16));
155
156 Collection<ObjectId> matches = reader.resolve(reader.abbreviate(id, 8));
157 assertNotNull(matches);
158 assertEquals(1, matches.size());
159 assertEquals(id, matches.iterator().next());
160
161 assertEquals(id, db.resolve(reader.abbreviate(id, 8).name()));
162 }
163
164 @Test
165 public void testAbbreviateIsActuallyUnique() throws Exception {
166
167
168
169
170
171
172 ObjectId id = id("9d5b926ed164e8ee88d3b8b1e525d699adda01ba");
173 byte[] idBuf = toByteArray(id);
174 List<PackedObjectInfo> objects = new ArrayList<>();
175 for (int i = 0; i < 256; i++) {
176 idBuf[9] = (byte) i;
177 objects.add(new PackedObjectInfo(ObjectId.fromRaw(idBuf)));
178 }
179
180 String packName = "pack-" + id.name();
181 File packDir = db.getObjectDatabase().getPackDirectory();
182 File idxFile = new File(packDir, packName + ".idx");
183 File packFile = new File(packDir, packName + ".pack");
184 FileUtils.mkdir(packDir, true);
185 try (OutputStream dst = new BufferedOutputStream(
186 new FileOutputStream(idxFile))) {
187 PackIndexWriter writer = new PackIndexWriterV2(dst);
188 writer.write(objects, new byte[OBJECT_ID_LENGTH]);
189 }
190
191 try (FileOutputStream unused = new FileOutputStream(packFile)) {
192
193 }
194
195 assertEquals(id.abbreviate(20), reader.abbreviate(id, 2));
196
197 AbbreviatedObjectId abbrev8 = id.abbreviate(8);
198 Collection<ObjectId> matches = reader.resolve(abbrev8);
199 assertNotNull(matches);
200 assertEquals(objects.size(), matches.size());
201 for (PackedObjectInfo info : objects)
202 assertTrue("contains " + info.name(), matches.contains(info));
203
204 try {
205 db.resolve(abbrev8.name());
206 fail("did not throw AmbiguousObjectException");
207 } catch (AmbiguousObjectException err) {
208 assertEquals(abbrev8, err.getAbbreviatedObjectId());
209 matches = err.getCandidates();
210 assertNotNull(matches);
211 assertEquals(objects.size(), matches.size());
212 for (PackedObjectInfo info : objects)
213 assertTrue("contains " + info.name(), matches.contains(info));
214 }
215
216 assertEquals(id, db.resolve(id.abbreviate(20).name()));
217 }
218
219 private static ObjectId id(String name) {
220 return ObjectId.fromString(name);
221 }
222
223 private static byte[] toByteArray(ObjectId id) throws IOException {
224 ByteArrayOutputStream buf = new ByteArrayOutputStream(OBJECT_ID_LENGTH);
225 id.copyRawTo(buf);
226 return buf.toByteArray();
227 }
228 }