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