View Javadoc
1   /*
2    * Copyright (C) 2011-2018, Chris Aniszczyk <caniszczyk@gmail.com> and others
3    *
4    * This program and the accompanying materials are made available under the
5    * terms of the Eclipse Distribution License v. 1.0 which is available at
6    * https://www.eclipse.org/org/documents/edl-v10.php.
7    *
8    * SPDX-License-Identifier: BSD-3-Clause
9    */
10  package org.eclipse.jgit.api;
11  
12  import static java.time.Instant.EPOCH;
13  import static org.eclipse.jgit.api.ResetCommand.ResetType.HARD;
14  import static org.junit.Assert.assertEquals;
15  import static org.junit.Assert.assertFalse;
16  import static org.junit.Assert.assertNotNull;
17  import static org.junit.Assert.assertNull;
18  import static org.junit.Assert.assertTrue;
19  import static org.junit.Assert.fail;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.nio.file.Files;
24  import java.nio.file.attribute.FileTime;
25  import java.time.Instant;
26  
27  import org.eclipse.jgit.api.ResetCommand.ResetType;
28  import org.eclipse.jgit.api.errors.GitAPIException;
29  import org.eclipse.jgit.api.errors.JGitInternalException;
30  import org.eclipse.jgit.dircache.DirCache;
31  import org.eclipse.jgit.dircache.DirCacheBuilder;
32  import org.eclipse.jgit.dircache.DirCacheEntry;
33  import org.eclipse.jgit.errors.AmbiguousObjectException;
34  import org.eclipse.jgit.junit.RepositoryTestCase;
35  import org.eclipse.jgit.lib.Constants;
36  import org.eclipse.jgit.lib.FileMode;
37  import org.eclipse.jgit.lib.ObjectId;
38  import org.eclipse.jgit.lib.Ref;
39  import org.eclipse.jgit.revwalk.RevCommit;
40  import org.eclipse.jgit.revwalk.RevWalk;
41  import org.eclipse.jgit.treewalk.TreeWalk;
42  import org.eclipse.jgit.util.FileUtils;
43  import org.junit.Assert;
44  import org.junit.Test;
45  
46  public class ResetCommandTest extends RepositoryTestCase {
47  
48  	private Git git;
49  
50  	private RevCommit initialCommit;
51  
52  	private RevCommit secondCommit;
53  
54  	private File indexFile;
55  
56  	private File indexNestedFile;
57  
58  	private File untrackedFile;
59  
60  	private DirCacheEntry prestage;
61  
62  	public void setupRepository() throws IOException, JGitInternalException,
63  			GitAPIException {
64  
65  		// create initial commit
66  		git = new Git(db);
67  		initialCommit = git.commit().setMessage("initial commit").call();
68  
69  		// create file
70  		indexFile = writeTrashFile("a.txt", "content");
71  
72  		// create nested file
73  		indexNestedFile = writeTrashFile("dir/b.txt", "content");
74  
75  		// add files and commit them
76  		git.add().addFilepattern("a.txt").addFilepattern("dir/b.txt").call();
77  		secondCommit = git.commit().setMessage("adding a.txt and dir/b.txt").call();
78  
79  		prestage = DirCache.read(db.getIndexFile(), db.getFS()).getEntry(indexFile.getName());
80  
81  		// modify files and add to index
82  		writeTrashFile("a.txt", "new content");
83  		writeTrashFile("dir/b.txt", "new content");
84  		git.add().addFilepattern("a.txt").addFilepattern("dir/b.txt").call();
85  
86  		// create a file not added to the index
87  		untrackedFile = writeTrashFile("notAddedToIndex.txt", "content");
88  	}
89  
90  	@Test
91  	public void testHardReset() throws JGitInternalException,
92  			AmbiguousObjectException, IOException, GitAPIException {
93  		setupRepository();
94  		ObjectId prevHead = db.resolve(Constants.HEAD);
95  		ResetCommand reset = git.reset();
96  		assertSameAsHead(reset.setMode(ResetType.HARD)
97  				.setRef(initialCommit.getName()).call());
98  		assertFalse("reflog should be enabled", reset.isReflogDisabled());
99  		// check if HEAD points to initial commit now
100 		ObjectId head = db.resolve(Constants.HEAD);
101 		assertEquals(initialCommit, head);
102 		// check if files were removed
103 		assertFalse(indexFile.exists());
104 		assertFalse(indexNestedFile.exists());
105 		assertTrue(untrackedFile.exists());
106 		// fileInIndex must no longer be in HEAD and in the index
107 		String fileInIndexPath = indexFile.getAbsolutePath();
108 		assertFalse(inHead(fileInIndexPath));
109 		assertFalse(inIndex(indexFile.getName()));
110 		assertReflog(prevHead, head);
111 		assertEquals(prevHead, db.readOrigHead());
112 	}
113 
114 	@Test
115 	public void testHardResetReflogDisabled() throws Exception {
116 		setupRepository();
117 		ObjectId prevHead = db.resolve(Constants.HEAD);
118 		ResetCommand reset = git.reset();
119 		assertSameAsHead(reset.setMode(ResetType.HARD)
120 				.setRef(initialCommit.getName()).disableRefLog(true).call());
121 		assertTrue("reflog should be disabled", reset.isReflogDisabled());
122 		// check if HEAD points to initial commit now
123 		ObjectId head = db.resolve(Constants.HEAD);
124 		assertEquals(initialCommit, head);
125 		// check if files were removed
126 		assertFalse(indexFile.exists());
127 		assertFalse(indexNestedFile.exists());
128 		assertTrue(untrackedFile.exists());
129 		// fileInIndex must no longer be in HEAD and in the index
130 		String fileInIndexPath = indexFile.getAbsolutePath();
131 		assertFalse(inHead(fileInIndexPath));
132 		assertFalse(inIndex(indexFile.getName()));
133 		assertReflogDisabled(head);
134 		assertEquals(prevHead, db.readOrigHead());
135 	}
136 
137 	@Test
138 	public void testHardResetWithConflicts_OverwriteUntrackedFile() throws Exception {
139 		setupRepository();
140 
141 		git.rm().setCached(true).addFilepattern("a.txt").call();
142 		assertTrue(new File(db.getWorkTree(), "a.txt").exists());
143 
144 		git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD).call();
145 		assertTrue(new File(db.getWorkTree(), "a.txt").exists());
146 		assertEquals("content", read(new File(db.getWorkTree(), "a.txt")));
147 	}
148 
149 	@Test
150 	public void testHardResetWithConflicts_DeleteFileFolderConflict() throws Exception {
151 		setupRepository();
152 
153 		writeTrashFile("dir-or-file/c.txt", "content");
154 		git.add().addFilepattern("dir-or-file/c.txt").call();
155 
156 		FileUtils.delete(new File(db.getWorkTree(), "dir-or-file"), FileUtils.RECURSIVE);
157 		writeTrashFile("dir-or-file", "content");
158 
159 		git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD).call();
160 		assertFalse(new File(db.getWorkTree(), "dir-or-file").exists());
161 	}
162 
163 	@Test
164 	public void testHardResetWithConflicts_CreateFolder_UnstagedChanges() throws Exception {
165 		setupRepository();
166 
167 		writeTrashFile("dir-or-file/c.txt", "content");
168 		git.add().addFilepattern("dir-or-file/c.txt").call();
169 		git.commit().setMessage("adding dir-or-file/c.txt").call();
170 
171 		FileUtils.delete(new File(db.getWorkTree(), "dir-or-file"), FileUtils.RECURSIVE);
172 		writeTrashFile("dir-or-file", "content");
173 
174 		// bug 479266: cannot create folder "dir-or-file"
175 		git.reset().setMode(ResetType.HARD).setRef(Constants.HEAD).call();
176 		assertTrue(new File(db.getWorkTree(), "dir-or-file/c.txt").exists());
177 	}
178 
179 	@Test
180 	public void testHardResetWithConflicts_DeleteFolder_UnstagedChanges() throws Exception {
181 		setupRepository();
182 		ObjectId prevHead = db.resolve(Constants.HEAD);
183 
184 		writeTrashFile("dir-or-file/c.txt", "content");
185 		git.add().addFilepattern("dir-or-file/c.txt").call();
186 		git.commit().setMessage("adding dir-or-file/c.txt").call();
187 
188 		writeTrashFile("dir-or-file-2/d.txt", "content");
189 		git.add().addFilepattern("dir-or-file-2/d.txt").call();
190 		FileUtils.delete(new File(db.getWorkTree(), "dir-or-file-2"), FileUtils.RECURSIVE);
191 		writeTrashFile("dir-or-file-2", "content");
192 
193 		// bug 479266: cannot delete folder "dir-or-file"
194 		git.reset().setMode(ResetType.HARD).setRef(prevHead.getName()).call();
195 		assertFalse(new File(db.getWorkTree(), "dir-or-file").exists());
196 		assertFalse(new File(db.getWorkTree(), "dir-or-file-2").exists());
197 	}
198 
199 	@Test
200 	public void testResetToNonexistingHEAD() throws JGitInternalException,
201 			AmbiguousObjectException, IOException, GitAPIException {
202 
203 		// create a file in the working tree of a fresh repo
204 		git = new Git(db);
205 		writeTrashFile("f", "content");
206 
207 		try {
208 			git.reset().setRef(Constants.HEAD).call();
209 			fail("Expected JGitInternalException didn't occur");
210 		} catch (JGitInternalException e) {
211 			// got the expected exception
212 		}
213 	}
214 
215 	@Test
216 	public void testSoftReset() throws JGitInternalException,
217 			AmbiguousObjectException, IOException, GitAPIException {
218 		setupRepository();
219 		ObjectId prevHead = db.resolve(Constants.HEAD);
220 		assertSameAsHead(git.reset().setMode(ResetType.SOFT)
221 				.setRef(initialCommit.getName()).call());
222 		// check if HEAD points to initial commit now
223 		ObjectId head = db.resolve(Constants.HEAD);
224 		assertEquals(initialCommit, head);
225 		// check if files still exist
226 		assertTrue(untrackedFile.exists());
227 		assertTrue(indexFile.exists());
228 		// fileInIndex must no longer be in HEAD but has to be in the index
229 		String fileInIndexPath = indexFile.getAbsolutePath();
230 		assertFalse(inHead(fileInIndexPath));
231 		assertTrue(inIndex(indexFile.getName()));
232 		assertReflog(prevHead, head);
233 		assertEquals(prevHead, db.readOrigHead());
234 	}
235 
236 	@Test
237 	public void testMixedReset() throws JGitInternalException,
238 			AmbiguousObjectException, IOException, GitAPIException {
239 		setupRepository();
240 		ObjectId prevHead = db.resolve(Constants.HEAD);
241 		assertSameAsHead(git.reset().setMode(ResetType.MIXED)
242 				.setRef(initialCommit.getName()).call());
243 		// check if HEAD points to initial commit now
244 		ObjectId head = db.resolve(Constants.HEAD);
245 		assertEquals(initialCommit, head);
246 		// check if files still exist
247 		assertTrue(untrackedFile.exists());
248 		assertTrue(indexFile.exists());
249 		// fileInIndex must no longer be in HEAD and in the index
250 		String fileInIndexPath = indexFile.getAbsolutePath();
251 		assertFalse(inHead(fileInIndexPath));
252 		assertFalse(inIndex(indexFile.getName()));
253 
254 		assertReflog(prevHead, head);
255 		assertEquals(prevHead, db.readOrigHead());
256 	}
257 
258 	@Test
259 	public void testMixedResetRetainsSizeAndModifiedTime() throws Exception {
260 		git = new Git(db);
261 
262 		Files.setLastModifiedTime(writeTrashFile("a.txt", "a").toPath(),
263 				FileTime.from(Instant.now().minusSeconds(60)));
264 		assertNotNull(git.add().addFilepattern("a.txt").call());
265 		assertNotNull(git.commit().setMessage("a commit").call());
266 
267 		Files.setLastModifiedTime(writeTrashFile("b.txt", "b").toPath(),
268 				FileTime.from(Instant.now().minusSeconds(60)));
269 		assertNotNull(git.add().addFilepattern("b.txt").call());
270 		RevCommit commit2 = git.commit().setMessage("b commit").call();
271 		assertNotNull(commit2);
272 
273 		DirCache cache = db.readDirCache();
274 
275 		DirCacheEntry aEntry = cache.getEntry("a.txt");
276 		assertNotNull(aEntry);
277 		assertTrue(aEntry.getLength() > 0);
278 		assertTrue(aEntry.getLastModifiedInstant().compareTo(EPOCH) > 0);
279 
280 		DirCacheEntry bEntry = cache.getEntry("b.txt");
281 		assertNotNull(bEntry);
282 		assertTrue(bEntry.getLength() > 0);
283 		assertTrue(bEntry.getLastModifiedInstant().compareTo(EPOCH) > 0);
284 
285 		assertSameAsHead(git.reset().setMode(ResetType.MIXED)
286 				.setRef(commit2.getName()).call());
287 
288 		cache = db.readDirCache();
289 
290 		DirCacheEntry mixedAEntry = cache.getEntry("a.txt");
291 		assertNotNull(mixedAEntry);
292 		assertEquals(aEntry.getLastModifiedInstant(),
293 				mixedAEntry.getLastModifiedInstant());
294 		assertEquals(aEntry.getLastModifiedInstant(),
295 				mixedAEntry.getLastModifiedInstant());
296 
297 		DirCacheEntry mixedBEntry = cache.getEntry("b.txt");
298 		assertNotNull(mixedBEntry);
299 		assertEquals(bEntry.getLastModifiedInstant(),
300 				mixedBEntry.getLastModifiedInstant());
301 		assertEquals(bEntry.getLastModifiedInstant(),
302 				mixedBEntry.getLastModifiedInstant());
303 	}
304 
305 	@Test
306 	public void testMixedResetWithUnmerged() throws Exception {
307 		git = new Git(db);
308 
309 		String file = "a.txt";
310 		writeTrashFile(file, "data");
311 		String file2 = "b.txt";
312 		writeTrashFile(file2, "data");
313 
314 		git.add().addFilepattern(file).addFilepattern(file2).call();
315 		git.commit().setMessage("commit").call();
316 
317 		DirCache index = db.lockDirCache();
318 		DirCacheBuilder builder = index.builder();
319 		builder.add(createEntry(file, FileMode.REGULAR_FILE, 1, ""));
320 		builder.add(createEntry(file, FileMode.REGULAR_FILE, 2, ""));
321 		builder.add(createEntry(file, FileMode.REGULAR_FILE, 3, ""));
322 		assertTrue(builder.commit());
323 
324 		assertEquals("[a.txt, mode:100644, stage:1]"
325 				+ "[a.txt, mode:100644, stage:2]"
326 				+ "[a.txt, mode:100644, stage:3]",
327 				indexState(0));
328 
329 		assertSameAsHead(git.reset().setMode(ResetType.MIXED).call());
330 
331 		assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]",
332 				indexState(0));
333 	}
334 
335 	@Test
336 	public void testPathsReset() throws Exception {
337 		setupRepository();
338 
339 		DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS())
340 				.getEntry(indexFile.getName());
341 		assertNotNull(preReset);
342 
343 		git.add().addFilepattern(untrackedFile.getName()).call();
344 
345 		// 'a.txt' has already been modified in setupRepository
346 		// 'notAddedToIndex.txt' has been added to repository
347 		assertSameAsHead(git.reset().addPath(indexFile.getName())
348 				.addPath(untrackedFile.getName()).call());
349 
350 		DirCacheEntry postReset = DirCache.read(db.getIndexFile(), db.getFS())
351 				.getEntry(indexFile.getName());
352 		assertNotNull(postReset);
353 		Assert.assertNotSame(preReset.getObjectId(), postReset.getObjectId());
354 		Assert.assertEquals(prestage.getObjectId(), postReset.getObjectId());
355 
356 		// check that HEAD hasn't moved
357 		ObjectId head = db.resolve(Constants.HEAD);
358 		assertEquals(secondCommit, head);
359 		// check if files still exist
360 		assertTrue(untrackedFile.exists());
361 		assertTrue(indexFile.exists());
362 		assertTrue(inHead(indexFile.getName()));
363 		assertTrue(inIndex(indexFile.getName()));
364 		assertFalse(inIndex(untrackedFile.getName()));
365 	}
366 
367 	@Test
368 	public void testPathsResetOnDirs() throws Exception {
369 		setupRepository();
370 
371 		DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS())
372 				.getEntry("dir/b.txt");
373 		assertNotNull(preReset);
374 
375 		git.add().addFilepattern(untrackedFile.getName()).call();
376 
377 		// 'dir/b.txt' has already been modified in setupRepository
378 		assertSameAsHead(git.reset().addPath("dir").call());
379 
380 		DirCacheEntry postReset = DirCache.read(db.getIndexFile(), db.getFS())
381 				.getEntry("dir/b.txt");
382 		assertNotNull(postReset);
383 		Assert.assertNotSame(preReset.getObjectId(), postReset.getObjectId());
384 
385 		// check that HEAD hasn't moved
386 		ObjectId head = db.resolve(Constants.HEAD);
387 		assertEquals(secondCommit, head);
388 		// check if files still exist
389 		assertTrue(untrackedFile.exists());
390 		assertTrue(inHead("dir/b.txt"));
391 		assertTrue(inIndex("dir/b.txt"));
392 	}
393 
394 	@Test
395 	public void testPathsResetWithRef() throws Exception {
396 		setupRepository();
397 
398 		DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS())
399 				.getEntry(indexFile.getName());
400 		assertNotNull(preReset);
401 
402 		git.add().addFilepattern(untrackedFile.getName()).call();
403 
404 		// 'a.txt' has already been modified in setupRepository
405 		// 'notAddedToIndex.txt' has been added to repository
406 		// reset to the inital commit
407 		assertSameAsHead(git.reset().setRef(initialCommit.getName())
408 				.addPath(indexFile.getName()).addPath(untrackedFile.getName())
409 				.call());
410 
411 		// check that HEAD hasn't moved
412 		ObjectId head = db.resolve(Constants.HEAD);
413 		assertEquals(secondCommit, head);
414 		// check if files still exist
415 		assertTrue(untrackedFile.exists());
416 		assertTrue(indexFile.exists());
417 		assertTrue(inHead(indexFile.getName()));
418 		assertFalse(inIndex(indexFile.getName()));
419 		assertFalse(inIndex(untrackedFile.getName()));
420 	}
421 
422 	@Test
423 	public void testPathsResetWithUnmerged() throws Exception {
424 		setupRepository();
425 
426 		String file = "a.txt";
427 		writeTrashFile(file, "data");
428 
429 		git.add().addFilepattern(file).call();
430 		git.commit().setMessage("commit").call();
431 
432 		DirCache index = db.lockDirCache();
433 		DirCacheBuilder builder = index.builder();
434 		builder.add(createEntry(file, FileMode.REGULAR_FILE, 1, ""));
435 		builder.add(createEntry(file, FileMode.REGULAR_FILE, 2, ""));
436 		builder.add(createEntry(file, FileMode.REGULAR_FILE, 3, ""));
437 		builder.add(createEntry("b.txt", FileMode.REGULAR_FILE));
438 		assertTrue(builder.commit());
439 
440 		assertEquals("[a.txt, mode:100644, stage:1]"
441 				+ "[a.txt, mode:100644, stage:2]"
442 				+ "[a.txt, mode:100644, stage:3]"
443 				+ "[b.txt, mode:100644]",
444 				indexState(0));
445 
446 		assertSameAsHead(git.reset().addPath(file).call());
447 
448 		assertEquals("[a.txt, mode:100644]" + "[b.txt, mode:100644]",
449 				indexState(0));
450 	}
451 
452 	@Test
453 	public void testPathsResetOnUnbornBranch() throws Exception {
454 		git = new Git(db);
455 		writeTrashFile("a.txt", "content");
456 		git.add().addFilepattern("a.txt").call();
457 		// Should assume an empty tree, like in C Git 1.8.2
458 		assertSameAsHead(git.reset().addPath("a.txt").call());
459 
460 		DirCache cache = db.readDirCache();
461 		DirCacheEntry aEntry = cache.getEntry("a.txt");
462 		assertNull(aEntry);
463 	}
464 
465 	@Test(expected = JGitInternalException.class)
466 	public void testPathsResetToNonexistingRef() throws Exception {
467 		git = new Git(db);
468 		writeTrashFile("a.txt", "content");
469 		git.add().addFilepattern("a.txt").call();
470 		assertSameAsHead(
471 				git.reset().setRef("doesnotexist").addPath("a.txt").call());
472 	}
473 
474 	@Test
475 	public void testResetDefaultMode() throws Exception {
476 		git = new Git(db);
477 		writeTrashFile("a.txt", "content");
478 		git.add().addFilepattern("a.txt").call();
479 		writeTrashFile("a.txt", "modified");
480 		// should use default mode MIXED
481 		assertSameAsHead(git.reset().call());
482 
483 		DirCache cache = db.readDirCache();
484 		DirCacheEntry aEntry = cache.getEntry("a.txt");
485 		assertNull(aEntry);
486 		assertEquals("modified", read("a.txt"));
487 	}
488 
489 	@Test
490 	public void testHardResetOnTag() throws Exception {
491 		setupRepository();
492 		String tagName = "initialtag";
493 		git.tag().setName(tagName).setObjectId(secondCommit)
494 				.setMessage("message").call();
495 
496 		DirCacheEntry preReset = DirCache.read(db.getIndexFile(), db.getFS())
497 				.getEntry(indexFile.getName());
498 		assertNotNull(preReset);
499 
500 		git.add().addFilepattern(untrackedFile.getName()).call();
501 
502 		assertSameAsHead(git.reset().setRef(tagName).setMode(HARD).call());
503 
504 		ObjectId head = db.resolve(Constants.HEAD);
505 		assertEquals(secondCommit, head);
506 	}
507 
508 	@Test
509 	public void testHardResetAfterSquashMerge() throws Exception {
510 		git = new Git(db);
511 
512 		writeTrashFile("file1", "file1");
513 		git.add().addFilepattern("file1").call();
514 		RevCommit first = git.commit().setMessage("initial commit").call();
515 
516 		assertTrue(new File(db.getWorkTree(), "file1").exists());
517 		createBranch(first, "refs/heads/branch1");
518 		checkoutBranch("refs/heads/branch1");
519 
520 		writeTrashFile("file2", "file2");
521 		git.add().addFilepattern("file2").call();
522 		git.commit().setMessage("second commit").call();
523 		assertTrue(new File(db.getWorkTree(), "file2").exists());
524 
525 		checkoutBranch("refs/heads/master");
526 
527 		MergeResult result = git.merge()
528 				.include(db.exactRef("refs/heads/branch1"))
529 				.setSquash(true)
530 				.call();
531 
532 		assertEquals(MergeResult.MergeStatus.FAST_FORWARD_SQUASHED,
533 				result.getMergeStatus());
534 		assertNotNull(db.readSquashCommitMsg());
535 
536 		assertSameAsHead(git.reset().setMode(ResetType.HARD)
537 				.setRef(first.getName()).call());
538 
539 		assertNull(db.readSquashCommitMsg());
540 	}
541 
542 	@Test
543 	public void testHardResetOnUnbornBranch() throws Exception {
544 		git = new Git(db);
545 		File fileA = writeTrashFile("a.txt", "content");
546 		git.add().addFilepattern("a.txt").call();
547 		// Should assume an empty tree, like in C Git 1.8.2
548 		assertSameAsHead(git.reset().setMode(ResetType.HARD).call());
549 
550 		DirCache cache = db.readDirCache();
551 		DirCacheEntry aEntry = cache.getEntry("a.txt");
552 		assertNull(aEntry);
553 		assertFalse(fileA.exists());
554 		assertNull(db.resolve(Constants.HEAD));
555 	}
556 
557 	private void assertReflog(ObjectId prevHead, ObjectId head)
558 			throws IOException {
559 		// Check the reflog for HEAD
560 		String actualHeadMessage = db.getReflogReader(Constants.HEAD)
561 				.getLastEntry().getComment();
562 		String expectedHeadMessage = head.getName() + ": updating HEAD";
563 		assertEquals(expectedHeadMessage, actualHeadMessage);
564 		assertEquals(head.getName(), db.getReflogReader(Constants.HEAD)
565 				.getLastEntry().getNewId().getName());
566 		assertEquals(prevHead.getName(), db.getReflogReader(Constants.HEAD)
567 				.getLastEntry().getOldId().getName());
568 
569 		// The reflog for master contains the same as the one for HEAD
570 		String actualMasterMessage = db.getReflogReader("refs/heads/master")
571 				.getLastEntry().getComment();
572 		String expectedMasterMessage = head.getName() + ": updating HEAD"; // yes!
573 		assertEquals(expectedMasterMessage, actualMasterMessage);
574 		assertEquals(head.getName(), db.getReflogReader(Constants.HEAD)
575 				.getLastEntry().getNewId().getName());
576 		assertEquals(prevHead.getName(), db
577 				.getReflogReader("refs/heads/master").getLastEntry().getOldId()
578 				.getName());
579 	}
580 
581 	private void assertReflogDisabled(ObjectId head)
582 			throws IOException {
583 		// Check the reflog for HEAD
584 		String actualHeadMessage = db.getReflogReader(Constants.HEAD)
585 				.getLastEntry().getComment();
586 		String expectedHeadMessage = "commit: adding a.txt and dir/b.txt";
587 		assertEquals(expectedHeadMessage, actualHeadMessage);
588 		assertEquals(head.getName(), db.getReflogReader(Constants.HEAD)
589 				.getLastEntry().getOldId().getName());
590 
591 		// The reflog for master contains the same as the one for HEAD
592 		String actualMasterMessage = db.getReflogReader("refs/heads/master")
593 				.getLastEntry().getComment();
594 		String expectedMasterMessage = "commit: adding a.txt and dir/b.txt";
595 		assertEquals(expectedMasterMessage, actualMasterMessage);
596 		assertEquals(head.getName(), db.getReflogReader(Constants.HEAD)
597 				.getLastEntry().getOldId().getName());
598 	}
599 	/**
600 	 * Checks if a file with the given path exists in the HEAD tree
601 	 *
602 	 * @param path
603 	 * @return true if the file exists
604 	 * @throws IOException
605 	 */
606 	private boolean inHead(String path) throws IOException {
607 		ObjectId headId = db.resolve(Constants.HEAD);
608 		try (RevWalk rw = new RevWalk(db);
609 				TreeWalk tw = TreeWalk.forPath(db, path,
610 						rw.parseTree(headId))) {
611 			return tw != null;
612 		}
613 	}
614 
615 	/**
616 	 * Checks if a file with the given path exists in the index
617 	 *
618 	 * @param path
619 	 * @return true if the file exists
620 	 * @throws IOException
621 	 */
622 	private boolean inIndex(String path) throws IOException {
623 		DirCache dc = DirCache.read(db.getIndexFile(), db.getFS());
624 		return dc.getEntry(path) != null;
625 	}
626 
627 	/**
628 	 * Asserts that a certain ref is similar to repos HEAD.
629 	 * @param ref
630 	 * @throws IOException
631 	 */
632 	private void assertSameAsHead(Ref ref) throws IOException {
633 		Ref headRef = db.exactRef(Constants.HEAD);
634 		assertEquals(headRef.getName(), ref.getName());
635 		assertEquals(headRef.getObjectId(), ref.getObjectId());
636 	}
637 }