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.junit;
45
46 import static java.nio.charset.StandardCharsets.UTF_8;
47 import static org.junit.Assert.assertEquals;
48 import static org.junit.Assert.assertFalse;
49 import static org.junit.Assert.assertNotEquals;
50 import static org.junit.Assert.assertNull;
51 import static org.junit.Assert.assertSame;
52 import static org.junit.Assert.assertTrue;
53
54 import java.util.Date;
55 import java.util.regex.Pattern;
56
57 import org.eclipse.jgit.internal.storage.dfs.DfsRepositoryDescription;
58 import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
59 import org.eclipse.jgit.lib.AnyObjectId;
60 import org.eclipse.jgit.lib.Constants;
61 import org.eclipse.jgit.lib.ObjectId;
62 import org.eclipse.jgit.lib.ObjectLoader;
63 import org.eclipse.jgit.lib.PersonIdent;
64 import org.eclipse.jgit.lib.Ref;
65 import org.eclipse.jgit.revwalk.RevBlob;
66 import org.eclipse.jgit.revwalk.RevCommit;
67 import org.eclipse.jgit.revwalk.RevObject;
68 import org.eclipse.jgit.revwalk.RevWalk;
69 import org.eclipse.jgit.treewalk.TreeWalk;
70 import org.junit.After;
71 import org.junit.Before;
72 import org.junit.Test;
73
74 public class TestRepositoryTest {
75 private TestRepository<InMemoryRepository> tr;
76 private InMemoryRepository repo;
77 private RevWalk rw;
78
79 @Before
80 public void setUp() throws Exception {
81 tr = new TestRepository<>(new InMemoryRepository(
82 new DfsRepositoryDescription("test")));
83 repo = tr.getRepository();
84 rw = tr.getRevWalk();
85 }
86
87 @After
88 public void tearDown() {
89 rw.close();
90 repo.close();
91 }
92
93 @Test
94 public void insertChangeId() throws Exception {
95 RevCommit c1 = tr.commit().message("message").insertChangeId().create();
96 rw.parseBody(c1);
97 assertTrue(Pattern.matches(
98 "^message\n\nChange-Id: I[0-9a-f]{40}\n$", c1.getFullMessage()));
99
100 RevCommit c2 = tr.commit().message("").insertChangeId().create();
101 rw.parseBody(c2);
102 assertEquals("\n\nChange-Id: I0000000000000000000000000000000000000000\n",
103 c2.getFullMessage());
104 }
105
106 @Test
107 public void insertChangeIdIgnoresExisting() throws Exception {
108 String msg = "message\n"
109 + "\n"
110 + "Change-Id: Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef\n";
111 RevCommit c = tr.commit().message(msg).insertChangeId().create();
112 rw.parseBody(c);
113 assertEquals(msg, c.getFullMessage());
114 }
115
116 @Test
117 public void insertExplicitChangeId() throws Exception {
118 RevCommit c = tr.commit().message("message")
119 .insertChangeId("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
120 .create();
121 rw.parseBody(c);
122 assertEquals("message\n\n"
123 + "Change-Id: Ideadbeefdeadbeefdeadbeefdeadbeefdeadbeef\n"
124 , c.getFullMessage());
125 }
126
127 @Test
128 public void resetFromSymref() throws Exception {
129 repo.updateRef("HEAD").link("refs/heads/master");
130 Ref head = repo.getRef("HEAD");
131 RevCommit master = tr.branch("master").commit().create();
132 RevCommit branch = tr.branch("branch").commit().create();
133 RevCommit detached = tr.commit().create();
134
135 assertTrue(head.isSymbolic());
136 assertEquals("refs/heads/master", head.getTarget().getName());
137 assertEquals(master, repo.getRef("refs/heads/master").getObjectId());
138 assertEquals(branch, repo.getRef("refs/heads/branch").getObjectId());
139
140
141 tr.reset("master");
142 head = repo.getRef("HEAD");
143 assertEquals(master, head.getObjectId());
144 assertTrue(head.isSymbolic());
145 assertEquals("refs/heads/master", head.getTarget().getName());
146
147 tr.reset("branch");
148 head = repo.getRef("HEAD");
149 assertEquals(branch, head.getObjectId());
150 assertTrue(head.isSymbolic());
151 assertEquals("refs/heads/master", head.getTarget().getName());
152 ObjectId lastHeadBeforeDetach = head.getObjectId().copy();
153
154
155 tr.reset(detached);
156 head = repo.getRef("HEAD");
157 assertEquals(detached, head.getObjectId());
158 assertFalse(head.isSymbolic());
159
160 tr.reset(detached.name());
161 head = repo.getRef("HEAD");
162 assertEquals(detached, head.getObjectId());
163 assertFalse(head.isSymbolic());
164
165
166 tr.reset("master");
167 head = repo.getRef("HEAD");
168 assertEquals(lastHeadBeforeDetach, head.getObjectId());
169 assertFalse(head.isSymbolic());
170 }
171
172 @Test
173 public void resetFromDetachedHead() throws Exception {
174 Ref head = repo.getRef("HEAD");
175 RevCommit master = tr.branch("master").commit().create();
176 RevCommit branch = tr.branch("branch").commit().create();
177 RevCommit detached = tr.commit().create();
178
179 assertNull(head);
180 assertEquals(master, repo.getRef("refs/heads/master").getObjectId());
181 assertEquals(branch, repo.getRef("refs/heads/branch").getObjectId());
182
183 tr.reset("master");
184 head = repo.getRef("HEAD");
185 assertEquals(master, head.getObjectId());
186 assertFalse(head.isSymbolic());
187
188 tr.reset("branch");
189 head = repo.getRef("HEAD");
190 assertEquals(branch, head.getObjectId());
191 assertFalse(head.isSymbolic());
192
193 tr.reset(detached);
194 head = repo.getRef("HEAD");
195 assertEquals(detached, head.getObjectId());
196 assertFalse(head.isSymbolic());
197
198 tr.reset(detached.name());
199 head = repo.getRef("HEAD");
200 assertEquals(detached, head.getObjectId());
201 assertFalse(head.isSymbolic());
202 }
203
204 @Test
205 public void amendRef() throws Exception {
206 RevCommit root = tr.commit()
207 .add("todelete", "to be deleted")
208 .create();
209 RevCommit orig = tr.commit().parent(root)
210 .rm("todelete")
211 .add("foo", "foo contents")
212 .add("bar", "bar contents")
213 .add("dir/baz", "baz contents")
214 .create();
215 rw.parseBody(orig);
216 tr.branch("master").update(orig);
217 assertEquals("foo contents", blobAsString(orig, "foo"));
218 assertEquals("bar contents", blobAsString(orig, "bar"));
219 assertEquals("baz contents", blobAsString(orig, "dir/baz"));
220
221 RevCommit amended = tr.amendRef("master")
222 .tick(3)
223 .add("bar", "fixed bar contents")
224 .create();
225 assertEquals(amended, repo.getRef("refs/heads/master").getObjectId());
226 rw.parseBody(amended);
227
228 assertEquals(1, amended.getParentCount());
229 assertEquals(root, amended.getParent(0));
230 assertEquals(orig.getFullMessage(), amended.getFullMessage());
231 assertEquals(orig.getAuthorIdent(), amended.getAuthorIdent());
232
233
234 assertEquals(new PersonIdent(orig.getCommitterIdent(), new Date(0)),
235 new PersonIdent(amended.getCommitterIdent(), new Date(0)));
236 assertTrue(orig.getCommitTime() < amended.getCommitTime());
237
238 assertEquals("foo contents", blobAsString(amended, "foo"));
239 assertEquals("fixed bar contents", blobAsString(amended, "bar"));
240 assertEquals("baz contents", blobAsString(amended, "dir/baz"));
241 assertNull(TreeWalk.forPath(repo, "todelete", amended.getTree()));
242 }
243
244 @Test
245 public void amendHead() throws Exception {
246 repo.updateRef("HEAD").link("refs/heads/master");
247 RevCommit root = tr.commit()
248 .add("foo", "foo contents")
249 .create();
250 RevCommit orig = tr.commit().parent(root)
251 .message("original message")
252 .add("bar", "bar contents")
253 .create();
254 tr.branch("master").update(orig);
255
256 RevCommit amended = tr.amendRef("HEAD")
257 .add("foo", "fixed foo contents")
258 .create();
259
260 Ref head = repo.getRef(Constants.HEAD);
261 assertEquals(amended, head.getObjectId());
262 assertTrue(head.isSymbolic());
263 assertEquals("refs/heads/master", head.getTarget().getName());
264
265 rw.parseBody(amended);
266 assertEquals("original message", amended.getFullMessage());
267 assertEquals("fixed foo contents", blobAsString(amended, "foo"));
268 assertEquals("bar contents", blobAsString(amended, "bar"));
269 }
270
271 @Test
272 public void amendCommit() throws Exception {
273 RevCommit root = tr.commit()
274 .add("foo", "foo contents")
275 .create();
276 RevCommit orig = tr.commit().parent(root)
277 .message("original message")
278 .add("bar", "bar contents")
279 .create();
280 RevCommit amended = tr.amend(orig.copy())
281 .add("foo", "fixed foo contents")
282 .create();
283
284 rw.parseBody(amended);
285 assertEquals("original message", amended.getFullMessage());
286 assertEquals("fixed foo contents", blobAsString(amended, "foo"));
287 assertEquals("bar contents", blobAsString(amended, "bar"));
288 }
289
290 @Test
291 public void commitToUnbornHead() throws Exception {
292 repo.updateRef("HEAD").link("refs/heads/master");
293 RevCommit root = tr.branch("HEAD").commit().create();
294 Ref ref = repo.getRef(Constants.HEAD);
295 assertEquals(root, ref.getObjectId());
296 assertTrue(ref.isSymbolic());
297 assertEquals("refs/heads/master", ref.getTarget().getName());
298 }
299
300 @Test
301 public void cherryPick() throws Exception {
302 repo.updateRef("HEAD").link("refs/heads/master");
303 RevCommit head = tr.branch("master").commit()
304 .add("foo", "foo contents\n")
305 .create();
306 rw.parseBody(head);
307 RevCommit toPick = tr.commit()
308 .parent(tr.commit().create())
309 .author(new PersonIdent("Cherrypick Author", "cpa@example.com",
310 tr.getClock(), tr.getTimeZone()))
311 .author(new PersonIdent("Cherrypick Committer", "cpc@example.com",
312 tr.getClock(), tr.getTimeZone()))
313 .message("message to cherry-pick")
314 .add("bar", "bar contents\n")
315 .create();
316 RevCommit result = tr.cherryPick(toPick);
317 rw.parseBody(result);
318
319 Ref headRef = tr.getRepository().getRef("HEAD");
320 assertEquals(result, headRef.getObjectId());
321 assertTrue(headRef.isSymbolic());
322 assertEquals("refs/heads/master", headRef.getLeaf().getName());
323
324 assertEquals(1, result.getParentCount());
325 assertEquals(head, result.getParent(0));
326 assertEquals(toPick.getAuthorIdent(), result.getAuthorIdent());
327
328
329 assertEquals(new PersonIdent(head.getCommitterIdent(), new Date(0)),
330 new PersonIdent(result.getCommitterIdent(), new Date(0)));
331 assertTrue(toPick.getCommitTime() < result.getCommitTime());
332
333 assertEquals("message to cherry-pick", result.getFullMessage());
334 assertEquals("foo contents\n", blobAsString(result, "foo"));
335 assertEquals("bar contents\n", blobAsString(result, "bar"));
336 }
337
338 @Test
339 public void cherryPickWithContentMerge() throws Exception {
340 RevCommit base = tr.branch("HEAD").commit()
341 .add("foo", "foo contents\n\n")
342 .create();
343 tr.branch("HEAD").commit()
344 .add("foo", "foo contents\n\nlast line\n")
345 .create();
346 RevCommit toPick = tr.commit()
347 .message("message to cherry-pick")
348 .parent(base)
349 .add("foo", "changed foo contents\n\n")
350 .create();
351 RevCommit result = tr.cherryPick(toPick);
352 rw.parseBody(result);
353
354 assertEquals("message to cherry-pick", result.getFullMessage());
355 assertEquals("changed foo contents\n\nlast line\n",
356 blobAsString(result, "foo"));
357 }
358
359 @Test
360 public void cherryPickWithIdenticalContents() throws Exception {
361 RevCommit base = tr.branch("HEAD").commit().add("foo", "foo contents\n")
362 .create();
363 RevCommit head = tr.branch("HEAD").commit()
364 .parent(base)
365 .add("bar", "bar contents\n")
366 .create();
367 RevCommit toPick = tr.commit()
368 .parent(base)
369 .message("message to cherry-pick")
370 .add("bar", "bar contents\n")
371 .create();
372 assertNotEquals(head, toPick);
373 assertNull(tr.cherryPick(toPick));
374 assertEquals(head, repo.getRef("HEAD").getObjectId());
375 }
376
377 private String blobAsString(AnyObjectId treeish, String path)
378 throws Exception {
379 RevObject obj = tr.get(rw.parseTree(treeish), path);
380 assertSame(RevBlob.class, obj.getClass());
381 ObjectLoader loader = rw.getObjectReader().open(obj);
382 return new String(loader.getCachedBytes(), UTF_8);
383 }
384 }