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.lib;
44
45 import static java.lang.Long.valueOf;
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertTrue;
48 import static org.junit.Assume.assumeTrue;
49
50 import java.io.File;
51 import java.io.FileOutputStream;
52 import java.io.IOException;
53 import java.util.TreeSet;
54
55 import org.eclipse.jgit.api.Git;
56 import org.eclipse.jgit.junit.RepositoryTestCase;
57 import org.eclipse.jgit.treewalk.FileTreeIterator;
58 import org.eclipse.jgit.treewalk.FileTreeIteratorWithTimeControl;
59 import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
60 import org.eclipse.jgit.util.FileUtils;
61 import org.junit.Test;
62
63 public class RacyGitTests extends RepositoryTestCase {
64 @Test
65 public void testIterator() throws IllegalStateException, IOException,
66 InterruptedException {
67 TreeSet<Long> modTimes = new TreeSet<>();
68 File lastFile = null;
69 for (int i = 0; i < 10; i++) {
70 lastFile = new File(db.getWorkTree(), "0." + i);
71 FileUtils.createNewFile(lastFile);
72 if (i == 5)
73 fsTick(lastFile);
74 }
75 modTimes.add(valueOf(fsTick(lastFile)));
76 for (int i = 0; i < 10; i++) {
77 lastFile = new File(db.getWorkTree(), "1." + i);
78 FileUtils.createNewFile(lastFile);
79 }
80 modTimes.add(valueOf(fsTick(lastFile)));
81 for (int i = 0; i < 10; i++) {
82 lastFile = new File(db.getWorkTree(), "2." + i);
83 FileUtils.createNewFile(lastFile);
84 if (i % 4 == 0)
85 fsTick(lastFile);
86 }
87 FileTreeIteratorWithTimeControl fileIt = new FileTreeIteratorWithTimeControl(
88 db, modTimes);
89 try (NameConflictTreeWalk tw = new NameConflictTreeWalk(db)) {
90 tw.addTree(fileIt);
91 tw.setRecursive(true);
92 FileTreeIterator t;
93 long t0 = 0;
94 for (int i = 0; i < 10; i++) {
95 assertTrue(tw.next());
96 t = tw.getTree(0, FileTreeIterator.class);
97 if (i == 0) {
98 t0 = t.getEntryLastModified();
99 } else {
100 assertEquals(t0, t.getEntryLastModified());
101 }
102 }
103 long t1 = 0;
104 for (int i = 0; i < 10; i++) {
105 assertTrue(tw.next());
106 t = tw.getTree(0, FileTreeIterator.class);
107 if (i == 0) {
108 t1 = t.getEntryLastModified();
109 assertTrue(t1 > t0);
110 } else {
111 assertEquals(t1, t.getEntryLastModified());
112 }
113 }
114 long t2 = 0;
115 for (int i = 0; i < 10; i++) {
116 assertTrue(tw.next());
117 t = tw.getTree(0, FileTreeIterator.class);
118 if (i == 0) {
119 t2 = t.getEntryLastModified();
120 assertTrue(t2 > t1);
121 } else {
122 assertEquals(t2, t.getEntryLastModified());
123 }
124 }
125 }
126 }
127
128 @Test
129 public void testRacyGitDetection() throws Exception {
130 TreeSet<Long> modTimes = new TreeSet<>();
131 File lastFile;
132
133
134 try (Git git = new Git(db)) {
135 git.reset().call();
136 }
137
138
139
140 modTimes.add(valueOf(fsTick(db.getIndexFile())));
141
142
143 addToWorkDir("a", "a");
144 lastFile = addToWorkDir("b", "b");
145
146
147
148 modTimes.add(valueOf(fsTick(lastFile)));
149
150
151 resetIndex(new FileTreeIteratorWithTimeControl(db, modTimes));
152
153 assertEquals(
154 "[a, mode:100644, time:t0, length:1, content:a]" +
155 "[b, mode:100644, time:t0, length:1, content:b]",
156 indexState(SMUDGE | MOD_TIME | LENGTH | CONTENT));
157
158
159
160
161 long indexMod = db.getIndexFile().lastModified();
162 modTimes.add(Long.valueOf(indexMod));
163
164
165 long aMod = addToWorkDir("a", "a2").lastModified();
166 assumeTrue(aMod == indexMod);
167
168
169
170
171 resetIndex(new FileTreeIteratorWithTimeControl(db, modTimes));
172
173 db.readDirCache();
174
175 assertEquals(
176 "[a, mode:100644, time:t1, smudged, length:0, content:a2]" +
177 "[b, mode:100644, time:t0, length:1, content:b]",
178 indexState(SMUDGE|MOD_TIME|LENGTH|CONTENT));
179 }
180
181 private File addToWorkDir(String path, String content) throws IOException {
182 File f = new File(db.getWorkTree(), path);
183 try (FileOutputStream fos = new FileOutputStream(f)) {
184 fos.write(content.getBytes(Constants.CHARACTER_ENCODING));
185 return f;
186 }
187 }
188 }