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 package org.eclipse.jgit.api;
44
45 import static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertFalse;
47 import static org.junit.Assert.assertTrue;
48 import static org.junit.Assert.fail;
49 import static org.junit.Assume.assumeFalse;
50
51 import java.io.File;
52 import java.io.IOException;
53 import java.io.PrintWriter;
54
55 import org.eclipse.jgit.api.errors.GitAPIException;
56 import org.eclipse.jgit.api.errors.JGitInternalException;
57 import org.eclipse.jgit.api.errors.NoMessageException;
58 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
59 import org.eclipse.jgit.errors.MissingObjectException;
60 import org.eclipse.jgit.junit.RepositoryTestCase;
61 import org.eclipse.jgit.lib.Constants;
62 import org.eclipse.jgit.lib.ObjectId;
63 import org.eclipse.jgit.lib.PersonIdent;
64 import org.eclipse.jgit.lib.RefUpdate;
65 import org.eclipse.jgit.lib.ReflogReader;
66 import org.eclipse.jgit.revwalk.RevCommit;
67 import org.eclipse.jgit.treewalk.TreeWalk;
68 import org.eclipse.jgit.util.FS;
69 import org.eclipse.jgit.util.FileUtils;
70 import org.eclipse.jgit.util.RawParseUtils;
71 import org.junit.Test;
72
73
74
75
76 public class CommitAndLogCommandTest extends RepositoryTestCase {
77 @Test
78 public void testSomeCommits() throws JGitInternalException, IOException,
79 GitAPIException {
80
81
82 try (Git git = new Git(db)) {
83 git.commit().setMessage("initial commit").call();
84 git.commit().setMessage("second commit").setCommitter(committer).call();
85 git.commit().setMessage("third commit").setAuthor(author).call();
86 git.commit().setMessage("fourth commit").setAuthor(author)
87 .setCommitter(committer).call();
88 Iterable<RevCommit> commits = git.log().call();
89
90
91 PersonIdent defaultCommitter = new PersonIdent(db);
92 PersonIdent expectedAuthors[] = new PersonIdent[] { defaultCommitter,
93 committer, author, author };
94 PersonIdent expectedCommitters[] = new PersonIdent[] {
95 defaultCommitter, committer, defaultCommitter, committer };
96 String expectedMessages[] = new String[] { "initial commit",
97 "second commit", "third commit", "fourth commit" };
98 int l = expectedAuthors.length - 1;
99 for (RevCommit c : commits) {
100 assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent()
101 .getName());
102 assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent()
103 .getName());
104 assertEquals(c.getFullMessage(), expectedMessages[l]);
105 l--;
106 }
107 assertEquals(l, -1);
108 ReflogReader reader = db.getReflogReader(Constants.HEAD);
109 assertTrue(reader.getLastEntry().getComment().startsWith("commit:"));
110 reader = db.getReflogReader(db.getBranch());
111 assertTrue(reader.getLastEntry().getComment().startsWith("commit:"));
112 }
113 }
114
115 @Test
116 public void testLogWithFilter() throws IOException, JGitInternalException,
117 GitAPIException {
118
119 try (Git git = new Git(db)) {
120
121 File file = new File(db.getWorkTree(), "a.txt");
122 FileUtils.createNewFile(file);
123 try (PrintWriter writer = new PrintWriter(file)) {
124 writer.print("content1");
125 }
126
127
128 git.add().addFilepattern("a.txt").call();
129 git.commit().setMessage("commit1").setCommitter(committer).call();
130
131
132 file = new File(db.getWorkTree(), "b.txt");
133 FileUtils.createNewFile(file);
134 try (PrintWriter writer = new PrintWriter(file)) {
135 writer.print("content2");
136 }
137
138
139 git.add().addFilepattern("b.txt").call();
140 git.commit().setMessage("commit2").setCommitter(committer).call();
141
142
143 int count = 0;
144 for (RevCommit c : git.log().addPath("a.txt").call()) {
145 assertEquals("commit1", c.getFullMessage());
146 count++;
147 }
148 assertEquals(1, count);
149
150
151 count = 0;
152 for (RevCommit c : git.log().addPath("b.txt").call()) {
153 assertEquals("commit2", c.getFullMessage());
154 count++;
155 }
156 assertEquals(1, count);
157
158
159 count = 0;
160 for (RevCommit c : git.log().call()) {
161 assertEquals(committer, c.getCommitterIdent());
162 count++;
163 }
164 assertEquals(2, count);
165 }
166 }
167
168
169 @Test
170 public void testWrongParams() throws GitAPIException {
171 try (Git git = new Git(db)) {
172 git.commit().setAuthor(author).call();
173 fail("Didn't get the expected exception");
174 } catch (NoMessageException e) {
175
176 }
177 }
178
179
180
181 @Test
182 public void testMultipleInvocations() throws GitAPIException {
183 try (Git git = new Git(db)) {
184 CommitCommand commitCmd = git.commit();
185 commitCmd.setMessage("initial commit").call();
186 try {
187
188 commitCmd.setAuthor(author);
189 fail("didn't catch the expected exception");
190 } catch (IllegalStateException e) {
191
192 }
193 LogCommand logCmd = git.log();
194 logCmd.call();
195 try {
196
197 logCmd.call();
198 fail("didn't catch the expected exception");
199 } catch (IllegalStateException e) {
200
201 }
202 }
203 }
204
205 @Test
206 public void testMergeEmptyBranches() throws IOException,
207 JGitInternalException, GitAPIException {
208 try (Git git = new Git(db)) {
209 git.commit().setMessage("initial commit").call();
210 RefUpdate r = db.updateRef("refs/heads/side");
211 r.setNewObjectId(db.resolve(Constants.HEAD));
212 assertEquals(r.forceUpdate(), RefUpdate.Result.NEW);
213 RevCommit second = git.commit().setMessage("second commit").setCommitter(committer).call();
214 db.updateRef(Constants.HEAD).link("refs/heads/side");
215 RevCommit firstSide = git.commit().setMessage("first side commit").setAuthor(author).call();
216
217 write(new File(db.getDirectory(), Constants.MERGE_HEAD), ObjectId
218 .toString(db.resolve("refs/heads/master")));
219 write(new File(db.getDirectory(), Constants.MERGE_MSG), "merging");
220
221 RevCommit commit = git.commit().call();
222 RevCommit[] parents = commit.getParents();
223 assertEquals(parents[0], firstSide);
224 assertEquals(parents[1], second);
225 assertEquals(2, parents.length);
226 }
227 }
228
229 @Test
230 public void testAddUnstagedChanges() throws IOException,
231 JGitInternalException, GitAPIException {
232 File file = new File(db.getWorkTree(), "a.txt");
233 FileUtils.createNewFile(file);
234 try (PrintWriter writer = new PrintWriter(file)) {
235 writer.print("content");
236 }
237
238 try (Git git = new Git(db)) {
239 git.add().addFilepattern("a.txt").call();
240 RevCommit commit = git.commit().setMessage("initial commit").call();
241 TreeWalk tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
242 assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea",
243 tw.getObjectId(0).getName());
244
245 try (PrintWriter writer = new PrintWriter(file)) {
246 writer.print("content2");
247 }
248 commit = git.commit().setMessage("second commit").call();
249 tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
250 assertEquals("6b584e8ece562ebffc15d38808cd6b98fc3d97ea",
251 tw.getObjectId(0).getName());
252
253 commit = git.commit().setAll(true).setMessage("third commit")
254 .setAll(true).call();
255 tw = TreeWalk.forPath(db, "a.txt", commit.getTree());
256 assertEquals("db00fd65b218578127ea51f3dffac701f12f486a",
257 tw.getObjectId(0).getName());
258 }
259 }
260
261 @Test
262 public void testModeChange() throws IOException, GitAPIException {
263 assumeFalse(System.getProperty("os.name").startsWith("Windows"));
264 try (Git git = new Git(db)) {
265
266 File file = new File(db.getWorkTree(), "a.txt");
267 FileUtils.createNewFile(file);
268 try (PrintWriter writer = new PrintWriter(file)) {
269 writer.print("content1");
270 }
271
272
273 git.add().addFilepattern("a.txt").call();
274 git.commit().setMessage("commit1").setCommitter(committer).call();
275
276
277 FS fs = db.getFS();
278 fs.setExecute(file, true);
279 git.add().addFilepattern("a.txt").call();
280 git.commit().setMessage("mode change").setCommitter(committer).call();
281
282
283 fs.setExecute(file, false);
284 git.add().addFilepattern("a.txt").call();
285 git.commit().setMessage("mode change").setCommitter(committer)
286 .setOnly("a.txt").call();
287 }
288 }
289
290 @Test
291 public void testCommitRange() throws GitAPIException,
292 JGitInternalException, MissingObjectException,
293 IncorrectObjectTypeException {
294
295 try (Git git = new Git(db)) {
296 git.commit().setMessage("first commit").call();
297 RevCommit second = git.commit().setMessage("second commit")
298 .setCommitter(committer).call();
299 git.commit().setMessage("third commit").setAuthor(author).call();
300 RevCommit last = git.commit().setMessage("fourth commit").setAuthor(
301 author)
302 .setCommitter(committer).call();
303 Iterable<RevCommit> commits = git.log().addRange(second.getId(),
304 last.getId()).call();
305
306
307 PersonIdent defaultCommitter = new PersonIdent(db);
308 PersonIdent expectedAuthors[] = new PersonIdent[] { author, author };
309 PersonIdent expectedCommitters[] = new PersonIdent[] {
310 defaultCommitter, committer };
311 String expectedMessages[] = new String[] { "third commit",
312 "fourth commit" };
313 int l = expectedAuthors.length - 1;
314 for (RevCommit c : commits) {
315 assertEquals(expectedAuthors[l].getName(), c.getAuthorIdent()
316 .getName());
317 assertEquals(expectedCommitters[l].getName(), c.getCommitterIdent()
318 .getName());
319 assertEquals(c.getFullMessage(), expectedMessages[l]);
320 l--;
321 }
322 assertEquals(l, -1);
323 }
324 }
325
326 @Test
327 public void testCommitAmend() throws JGitInternalException, IOException,
328 GitAPIException {
329 try (Git git = new Git(db)) {
330 git.commit().setMessage("first comit").call();
331 git.commit().setAmend(true).setMessage("first commit").call();
332
333 Iterable<RevCommit> commits = git.log().call();
334 int c = 0;
335 for (RevCommit commit : commits) {
336 assertEquals("first commit", commit.getFullMessage());
337 c++;
338 }
339 assertEquals(1, c);
340 ReflogReader reader = db.getReflogReader(Constants.HEAD);
341 assertTrue(reader.getLastEntry().getComment()
342 .startsWith("commit (amend):"));
343 reader = db.getReflogReader(db.getBranch());
344 assertTrue(reader.getLastEntry().getComment()
345 .startsWith("commit (amend):"));
346 }
347 }
348
349 @Test
350 public void testInsertChangeId() throws JGitInternalException,
351 GitAPIException {
352 try (Git git = new Git(db)) {
353 String messageHeader = "Some header line\n\nSome detail explanation\n";
354 String changeIdTemplate = "\nChange-Id: I"
355 + ObjectId.zeroId().getName() + "\n";
356 String messageFooter = "Some foooter lines\nAnother footer line\n";
357 RevCommit commit = git.commit().setMessage(
358 messageHeader + messageFooter)
359 .setInsertChangeId(true).call();
360
361 byte[] chars = commit.getFullMessage().getBytes();
362 int lastLineBegin = RawParseUtils.prevLF(chars, chars.length - 2);
363 String lastLine = RawParseUtils.decode(chars, lastLineBegin + 1,
364 chars.length);
365 assertTrue(lastLine.contains("Change-Id:"));
366 assertFalse(lastLine.contains(
367 "Change-Id: I" + ObjectId.zeroId().getName()));
368
369 commit = git.commit().setMessage(
370 messageHeader + changeIdTemplate + messageFooter)
371 .setInsertChangeId(true).call();
372
373
374 chars = commit.getFullMessage().getBytes();
375 int lineStart = 0;
376 int lineEnd = 0;
377 for (int i = 0; i < 4; i++) {
378 lineStart = RawParseUtils.nextLF(chars, lineStart);
379 }
380 lineEnd = RawParseUtils.nextLF(chars, lineStart);
381
382 String line = RawParseUtils.decode(chars, lineStart, lineEnd);
383
384 assertTrue(line.contains("Change-Id:"));
385 assertFalse(line.contains(
386 "Change-Id: I" + ObjectId.zeroId().getName()));
387
388 commit = git.commit().setMessage(
389 messageHeader + changeIdTemplate + messageFooter)
390 .setInsertChangeId(false).call();
391
392 chars = commit.getFullMessage().getBytes();
393 lineStart = 0;
394 lineEnd = 0;
395 for (int i = 0; i < 4; i++) {
396 lineStart = RawParseUtils.nextLF(chars, lineStart);
397 }
398 lineEnd = RawParseUtils.nextLF(chars, lineStart);
399
400 line = RawParseUtils.decode(chars, lineStart, lineEnd);
401
402 assertTrue(commit.getFullMessage().contains(
403 "Change-Id: I" + ObjectId.zeroId().getName()));
404 }
405 }
406 }