Obey core.filemode setting
[egit.git] / org.spearce.jgit / tst / org / spearce / jgit / lib / T0007_Index.java
blob989c8a49fc92a316eaf9c298f3d7b9fd25df7782
1 package org.spearce.jgit.lib;
3 import java.io.File;
4 import java.io.FileInputStream;
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.lang.reflect.InvocationTargetException;
8 import java.lang.reflect.Method;
10 import org.spearce.jgit.lib.GitIndex.Entry;
12 public class T0007_Index extends RepositoryTestCase {
14 static boolean canrungitstatus;
15 static {
16 try {
17 canrungitstatus = system(new File("."),"git --version") == 0;
18 } catch (IOException e) {
19 System.out.println("Warning: cannot invvoke native git to validate index");
20 } catch (InterruptedException e) {
21 e.printStackTrace();
25 private static int system(File dir, String cmd) throws IOException,
26 InterruptedException {
27 final Process process = Runtime.getRuntime().exec(cmd, null, dir);
28 new Thread() {
29 public void run() {
30 try {
31 InputStream s = process.getErrorStream();
32 for (int c = s.read(); c != -1; c = s.read()) {
33 System.err.print((char) c);
35 s.close();
36 } catch (IOException e1) {
37 // TODO Auto-generated catch block
38 e1.printStackTrace();
41 }.start();
42 final Thread t2 = new Thread() {
43 public void run() {
44 synchronized (this) {
45 try {
46 InputStream e = process.getInputStream();
47 for (int c = e.read(); c != -1; c = e.read()) {
48 System.out.print((char) c);
50 e.close();
51 } catch (IOException e1) {
52 // TODO Auto-generated catch block
53 e1.printStackTrace();
58 t2.start();
59 process.getOutputStream().close();
60 int ret = process.waitFor();
61 synchronized (t2) {
62 return ret;
66 public void testCreateEmptyIndex() throws Exception {
67 GitIndex index = new GitIndex(db);
68 index.write();
69 // native git doesn't like an empty index
70 // assertEquals(0,system(trash,"git status"));
72 GitIndex indexr = new GitIndex(db);
73 indexr.read();
74 assertEquals(0, indexr.getMembers().length);
77 public void testCreateSimpleSortTestIndex() throws Exception {
78 GitIndex index = new GitIndex(db);
79 writeTrashFile("a/b", "data:a/b");
80 writeTrashFile("a:b", "data:a:b");
81 writeTrashFile("a.b", "data:a.b");
82 index.add(trash, new File(trash, "a/b"));
83 index.add(trash, new File(trash, "a:b"));
84 index.add(trash, new File(trash, "a.b"));
85 index.write();
87 assertEquals("a/b", index.getEntry("a/b").getName());
88 assertEquals("a:b", index.getEntry("a:b").getName());
89 assertEquals("a.b", index.getEntry("a.b").getName());
90 assertNull(index.getEntry("a*b"));
92 // Repeat test for re-read index
93 GitIndex indexr = new GitIndex(db);
94 indexr.read();
95 assertEquals("a/b", indexr.getEntry("a/b").getName());
96 assertEquals("a:b", indexr.getEntry("a:b").getName());
97 assertEquals("a.b", indexr.getEntry("a.b").getName());
98 assertNull(indexr.getEntry("a*b"));
100 if (canrungitstatus)
101 assertEquals(0, system(trash, "git status"));
104 public void testUpdateSimpleSortTestIndex() throws Exception {
105 GitIndex index = new GitIndex(db);
106 writeTrashFile("a/b", "data:a/b");
107 writeTrashFile("a:b", "data:a:b");
108 writeTrashFile("a.b", "data:a.b");
109 index.add(trash, new File(trash, "a/b"));
110 index.add(trash, new File(trash, "a:b"));
111 index.add(trash, new File(trash, "a.b"));
112 writeTrashFile("a/b", "data:a/b modified");
113 index.add(trash, new File(trash, "a/b"));
114 index.write();
115 if (canrungitstatus)
116 assertEquals(0, system(trash, "git status"));
119 public void testWriteTree() throws Exception {
120 GitIndex index = new GitIndex(db);
121 writeTrashFile("a/b", "data:a/b");
122 writeTrashFile("a:b", "data:a:b");
123 writeTrashFile("a.b", "data:a.b");
124 index.add(trash, new File(trash, "a/b"));
125 index.add(trash, new File(trash, "a:b"));
126 index.add(trash, new File(trash, "a.b"));
127 index.write();
129 ObjectId id = index.writeTree();
130 assertEquals("c696abc3ab8e091c665f49d00eb8919690b3aec3", id.toString());
132 writeTrashFile("a/b", "data:a/b");
133 index.add(trash, new File(trash, "a/b"));
135 if (canrungitstatus)
136 assertEquals(0, system(trash, "git status"));
139 public void testReadTree() throws Exception {
140 // Prepare tree
141 GitIndex index = new GitIndex(db);
142 writeTrashFile("a/b", "data:a/b");
143 writeTrashFile("a:b", "data:a:b");
144 writeTrashFile("a.b", "data:a.b");
145 index.add(trash, new File(trash, "a/b"));
146 index.add(trash, new File(trash, "a:b"));
147 index.add(trash, new File(trash, "a.b"));
148 index.write();
150 ObjectId id = index.writeTree();
151 System.out.println("wrote id " + id);
152 assertEquals("c696abc3ab8e091c665f49d00eb8919690b3aec3", id.toString());
153 GitIndex index2 = new GitIndex(db);
155 index2.readTree(db.mapTree(new ObjectId(
156 "c696abc3ab8e091c665f49d00eb8919690b3aec3")));
157 Entry[] members = index2.getMembers();
158 assertEquals(3, members.length);
159 assertEquals("a.b", members[0].getName());
160 assertEquals("a/b", members[1].getName());
161 assertEquals("a:b", members[2].getName());
162 assertEquals(3, members.length);
164 GitIndex indexr = new GitIndex(db);
165 indexr.read();
166 Entry[] membersr = indexr.getMembers();
167 assertEquals(3, membersr.length);
168 assertEquals("a.b", membersr[0].getName());
169 assertEquals("a/b", membersr[1].getName());
170 assertEquals("a:b", membersr[2].getName());
171 assertEquals(3, membersr.length);
173 if (canrungitstatus)
174 assertEquals(0, system(trash, "git status"));
177 public void testReadTree2() throws Exception {
178 // Prepare a larger tree to test some odd cases in tree writing
179 GitIndex index = new GitIndex(db);
180 File f1 = writeTrashFile("a/a/a/a", "data:a/a/a/a");
181 File f2 = writeTrashFile("a/c/c", "data:a/c/c");
182 File f3 = writeTrashFile("a/b", "data:a/b");
183 File f4 = writeTrashFile("a:b", "data:a:b");
184 File f5 = writeTrashFile("a/d", "data:a/d");
185 File f6 = writeTrashFile("a.b", "data:a.b");
186 index.add(trash, f1);
187 index.add(trash, f2);
188 index.add(trash, f3);
189 index.add(trash, f4);
190 index.add(trash, f5);
191 index.add(trash, f6);
192 index.write();
193 ObjectId id = index.writeTree();
194 System.out.println("wrote id " + id);
195 assertEquals("ba78e065e2c261d4f7b8f42107588051e87e18e9", id.toString());
196 GitIndex index2 = new GitIndex(db);
198 index2.readTree(db.mapTree(new ObjectId(
199 "ba78e065e2c261d4f7b8f42107588051e87e18e9")));
200 Entry[] members = index2.getMembers();
201 assertEquals(6, members.length);
202 assertEquals("a.b", members[0].getName());
203 assertEquals("a/a/a/a", members[1].getName());
204 assertEquals("a/b", members[2].getName());
205 assertEquals("a/c/c", members[3].getName());
206 assertEquals("a/d", members[4].getName());
207 assertEquals("a:b", members[5].getName());
209 // reread and test
210 GitIndex indexr = new GitIndex(db);
211 indexr.read();
212 Entry[] membersr = indexr.getMembers();
213 assertEquals(6, membersr.length);
214 assertEquals("a.b", membersr[0].getName());
215 assertEquals("a/a/a/a", membersr[1].getName());
216 assertEquals("a/b", membersr[2].getName());
217 assertEquals("a/c/c", membersr[3].getName());
218 assertEquals("a/d", membersr[4].getName());
219 assertEquals("a:b", membersr[5].getName());
222 public void testDelete() throws Exception {
223 GitIndex index = new GitIndex(db);
224 writeTrashFile("a/b", "data:a/b");
225 writeTrashFile("a:b", "data:a:b");
226 writeTrashFile("a.b", "data:a.b");
227 index.add(trash, new File(trash, "a/b"));
228 index.add(trash, new File(trash, "a:b"));
229 index.add(trash, new File(trash, "a.b"));
230 index.write();
231 index.writeTree();
232 index.remove(trash, new File(trash, "a:b"));
233 index.write();
234 assertEquals("a.b", index.getMembers()[0].getName());
235 assertEquals("a/b", index.getMembers()[1].getName());
237 GitIndex indexr = new GitIndex(db);
238 indexr.read();
239 assertEquals("a.b", indexr.getMembers()[0].getName());
240 assertEquals("a/b", indexr.getMembers()[1].getName());
242 if (canrungitstatus)
243 assertEquals(0, system(trash, "git status"));
246 public void testCheckout() throws Exception {
247 // Prepare tree, remote it and checkout
248 GitIndex index = new GitIndex(db);
249 File aslashb = writeTrashFile("a/b", "data:a/b");
250 File acolonb = writeTrashFile("a:b", "data:a:b");
251 File adotb = writeTrashFile("a.b", "data:a.b");
252 index.add(trash, aslashb);
253 index.add(trash, acolonb);
254 index.add(trash, adotb);
255 index.write();
256 index.writeTree();
257 delete(aslashb);
258 delete(acolonb);
259 delete(adotb);
260 delete(aslashb.getParentFile());
262 GitIndex index2 = new GitIndex(db);
263 assertEquals(0, index2.getMembers().length);
265 index2.readTree(db.mapTree(new ObjectId(
266 "c696abc3ab8e091c665f49d00eb8919690b3aec3")));
268 index2.checkout(trash);
269 assertEquals("data:a/b", content(aslashb));
270 assertEquals("data:a:b", content(acolonb));
271 assertEquals("data:a.b", content(adotb));
273 if (canrungitstatus)
274 assertEquals(0, system(trash, "git status"));
277 public void test030_executeBit_coreModeTrue() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Error, Exception {
278 try {
279 // coremode true is the default, typically set to false
280 // by git init (but not jgit!)
281 Method canExecute = File.class.getMethod("canExecute", (Class[])null);
282 Method setExecute = File.class.getMethod("setExecutable", new Class[] { Boolean.TYPE });
283 File execFile = writeTrashFile("exec","exec");
284 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.TRUE })).booleanValue())
285 throw new Error("could not set execute bit on "+execFile.getAbsolutePath()+"for test");
286 File nonexecFile = writeTrashFile("nonexec","nonexec");
287 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.FALSE })).booleanValue())
288 throw new Error("could not clear execute bit on "+nonexecFile.getAbsolutePath()+"for test");
290 GitIndex index = new GitIndex(db);
291 index.filemode = Boolean.TRUE; // TODO: we need a way to set this using config
292 index.add(trash, execFile);
293 index.add(trash, nonexecFile);
294 Tree tree = db.mapTree(index.writeTree());
295 assertEquals(FileMode.EXECUTABLE_FILE, tree.findBlobMember(execFile.getName()).getMode());
296 assertEquals(FileMode.REGULAR_FILE, tree.findBlobMember(nonexecFile.getName()).getMode());
298 index.write();
300 if (!execFile.delete())
301 throw new Error("Problem in test, cannot delete test file "+execFile.getAbsolutePath());
302 if (!nonexecFile.delete())
303 throw new Error("Problem in test, cannot delete test file "+nonexecFile.getAbsolutePath());
304 GitIndex index2 = new GitIndex(db);
305 index2.filemode = Boolean.TRUE; // TODO: we need a way to set this using config
306 index2.read();
307 index2.checkout(trash);
308 assertTrue(((Boolean)canExecute.invoke(execFile,(Object[])null)).booleanValue());
309 assertFalse(((Boolean)canExecute.invoke(nonexecFile,(Object[])null)).booleanValue());
311 assertFalse(index2.getEntry(execFile.getName()).isModified(trash));
312 assertFalse(index2.getEntry(nonexecFile.getName()).isModified(trash));
314 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.FALSE })).booleanValue())
315 throw new Error("could not clear set execute bit on "+execFile.getAbsolutePath()+"for test");
316 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.TRUE })).booleanValue())
317 throw new Error("could set execute bit on "+nonexecFile.getAbsolutePath()+"for test");
319 assertTrue(index2.getEntry(execFile.getName()).isModified(trash));
320 assertTrue(index2.getEntry(nonexecFile.getName()).isModified(trash));
322 } catch (NoSuchMethodException e) {
323 System.err.println("Test ignored when running under JDk < 1.6");
324 return;
328 public void test031_executeBit_coreModeFalse() throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, Error, Exception {
329 try {
330 // coremode true is the default, typically set to false
331 // by git init (but not jgit!)
332 Method canExecute = File.class.getMethod("canExecute", (Class[])null);
333 Method setExecute = File.class.getMethod("setExecutable", new Class[] { Boolean.TYPE });
334 File execFile = writeTrashFile("exec","exec");
335 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.TRUE })).booleanValue())
336 throw new Error("could not set execute bit on "+execFile.getAbsolutePath()+"for test");
337 File nonexecFile = writeTrashFile("nonexec","nonexec");
338 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.FALSE })).booleanValue())
339 throw new Error("could not clear execute bit on "+nonexecFile.getAbsolutePath()+"for test");
341 GitIndex index = new GitIndex(db);
342 index.filemode = Boolean.FALSE; // TODO: we need a way to set this using config
343 index.add(trash, execFile);
344 index.add(trash, nonexecFile);
345 Tree tree = db.mapTree(index.writeTree());
346 assertEquals(FileMode.REGULAR_FILE, tree.findBlobMember(execFile.getName()).getMode());
347 assertEquals(FileMode.REGULAR_FILE, tree.findBlobMember(nonexecFile.getName()).getMode());
349 index.write();
351 if (!execFile.delete())
352 throw new Error("Problem in test, cannot delete test file "+execFile.getAbsolutePath());
353 if (!nonexecFile.delete())
354 throw new Error("Problem in test, cannot delete test file "+nonexecFile.getAbsolutePath());
355 GitIndex index2 = new GitIndex(db);
356 index2.filemode = Boolean.FALSE; // TODO: we need a way to set this using config
357 index2.read();
358 index2.checkout(trash);
359 assertFalse(((Boolean)canExecute.invoke(execFile,(Object[])null)).booleanValue());
360 assertFalse(((Boolean)canExecute.invoke(nonexecFile,(Object[])null)).booleanValue());
362 assertFalse(index2.getEntry(execFile.getName()).isModified(trash));
363 assertFalse(index2.getEntry(nonexecFile.getName()).isModified(trash));
365 if (!((Boolean)setExecute.invoke(execFile, new Object[] { Boolean.FALSE })).booleanValue())
366 throw new Error("could not clear set execute bit on "+execFile.getAbsolutePath()+"for test");
367 if (!((Boolean)setExecute.invoke(nonexecFile, new Object[] { Boolean.TRUE })).booleanValue())
368 throw new Error("could set execute bit on "+nonexecFile.getAbsolutePath()+"for test");
370 // no change since we ignore the execute bit
371 assertFalse(index2.getEntry(execFile.getName()).isModified(trash));
372 assertFalse(index2.getEntry(nonexecFile.getName()).isModified(trash));
374 } catch (NoSuchMethodException e) {
375 System.err.println("Test ignored when running under JDk < 1.6");
376 return;
380 private String content(File f) throws IOException {
381 byte[] buf = new byte[(int) f.length()];
382 FileInputStream is = new FileInputStream(f);
383 int read = is.read(buf);
384 assertEquals(f.length(), read);
385 return new String(buf, 0);
388 private void delete(File f) throws IOException {
389 if (!f.delete())
390 throw new IOException("Failed to delete f");