1
2
3
4
5
6
7
8
9
10 package org.eclipse.jgit.lib;
11
12 import static java.nio.charset.StandardCharsets.UTF_8;
13 import static org.junit.Assert.assertEquals;
14 import static org.junit.Assert.assertFalse;
15 import static org.junit.Assert.assertTrue;
16
17 import java.io.File;
18 import java.io.FileOutputStream;
19 import java.io.IOException;
20 import java.time.Instant;
21
22 import org.eclipse.jgit.api.Git;
23 import org.eclipse.jgit.dircache.DirCache;
24 import org.eclipse.jgit.junit.RepositoryTestCase;
25 import org.eclipse.jgit.junit.time.TimeUtil;
26 import org.eclipse.jgit.treewalk.FileTreeIterator;
27 import org.eclipse.jgit.treewalk.WorkingTreeOptions;
28 import org.eclipse.jgit.util.FS;
29 import org.junit.Test;
30
31 public class RacyGitTests extends RepositoryTestCase {
32
33 @Test
34 public void testRacyGitDetection() throws Exception {
35
36 try (Git git = new Git(db)) {
37 git.reset().call();
38 }
39
40
41
42 fsTick(db.getIndexFile());
43
44
45 File a = writeToWorkDir("a", "a");
46 File b = writeToWorkDir("b", "b");
47 TimeUtil.setLastModifiedOf(a.toPath(), b.toPath());
48 TimeUtil.setLastModifiedOf(b.toPath(), b.toPath());
49
50
51
52 fsTick(b);
53
54
55 resetIndex(new FileTreeIterator(db));
56
57 assertEquals(
58 "[a, mode:100644, time:t0, length:1, content:a]"
59 + "[b, mode:100644, time:t0, length:1, content:b]",
60 indexState(SMUDGE | MOD_TIME | LENGTH | CONTENT));
61
62
63 fsTick(db.getIndexFile());
64
65
66
67
68
69 File updatedA = writeToWorkDir("a", "a2");
70 Instant newLastModified = TimeUtil
71 .setLastModifiedWithOffset(updatedA.toPath(), 100L);
72 resetIndex(new FileTreeIterator(db));
73 FS.DETECTED.setLastModified(db.getIndexFile().toPath(),
74 newLastModified);
75
76 DirCache dc = db.readDirCache();
77
78
79
80 assertEquals(
81 "[a, mode:100644, time:t1, smudged, length:0, content:a2]"
82 + "[b, mode:100644, time:t0, length:1, content:b]",
83 indexState(SMUDGE | MOD_TIME | LENGTH | CONTENT));
84
85
86
87 FileTreeIterator f = new FileTreeIterator(db.getWorkTree(), db.getFS(),
88 db.getConfig().get(WorkingTreeOptions.KEY));
89 assertTrue(f.findFile("a"));
90 try (ObjectReader reader = db.newObjectReader()) {
91 assertFalse(f.isModified(dc.getEntry("a"), false, reader));
92 }
93 }
94
95 private File writeToWorkDir(String path, String content) throws IOException {
96 File f = new File(db.getWorkTree(), path);
97 try (FileOutputStream fos = new FileOutputStream(f)) {
98 fos.write(content.getBytes(UTF_8));
99 return f;
100 }
101 }
102 }