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
44
45
46
47 package org.eclipse.jgit.junit;
48
49 import static org.junit.Assert.assertEquals;
50
51 import java.io.File;
52 import java.io.FileInputStream;
53 import java.io.FileNotFoundException;
54 import java.io.FileOutputStream;
55 import java.io.IOException;
56 import java.io.InputStreamReader;
57 import java.io.Reader;
58 import java.util.Map;
59 import java.util.TreeSet;
60
61 import org.eclipse.jgit.api.Git;
62 import org.eclipse.jgit.api.errors.GitAPIException;
63 import org.eclipse.jgit.dircache.DirCache;
64 import org.eclipse.jgit.dircache.DirCacheBuilder;
65 import org.eclipse.jgit.dircache.DirCacheCheckout;
66 import org.eclipse.jgit.dircache.DirCacheEntry;
67 import org.eclipse.jgit.internal.storage.file.FileRepository;
68 import org.eclipse.jgit.lib.Constants;
69 import org.eclipse.jgit.lib.FileMode;
70 import org.eclipse.jgit.lib.ObjectId;
71 import org.eclipse.jgit.lib.ObjectInserter;
72 import org.eclipse.jgit.lib.RefUpdate;
73 import org.eclipse.jgit.lib.Repository;
74 import org.eclipse.jgit.revwalk.RevCommit;
75 import org.eclipse.jgit.revwalk.RevWalk;
76 import org.eclipse.jgit.treewalk.FileTreeIterator;
77 import org.eclipse.jgit.util.FS;
78 import org.eclipse.jgit.util.FileUtils;
79 import org.junit.Before;
80
81
82
83
84
85
86
87 public abstract class RepositoryTestCase extends LocalDiskRepositoryTestCase {
88 protected static void copyFile(final File src, final File dst)
89 throws IOException {
90 final FileInputStream fis = new FileInputStream(src);
91 try {
92 final FileOutputStream fos = new FileOutputStream(dst);
93 try {
94 final byte[] buf = new byte[4096];
95 int r;
96 while ((r = fis.read(buf)) > 0) {
97 fos.write(buf, 0, r);
98 }
99 } finally {
100 fos.close();
101 }
102 } finally {
103 fis.close();
104 }
105 }
106
107 protected File writeTrashFile(final String name, final String data)
108 throws IOException {
109 return JGitTestUtil.writeTrashFile(db, name, data);
110 }
111
112 protected File writeTrashFile(final String subdir, final String name,
113 final String data)
114 throws IOException {
115 return JGitTestUtil.writeTrashFile(db, subdir, name, data);
116 }
117
118 protected String read(final String name) throws IOException {
119 return JGitTestUtil.read(db, name);
120 }
121
122 protected boolean check(final String name) {
123 return JGitTestUtil.check(db, name);
124 }
125
126 protected void deleteTrashFile(final String name) throws IOException {
127 JGitTestUtil.deleteTrashFile(db, name);
128 }
129
130 protected static void checkFile(File f, final String checkData)
131 throws IOException {
132 Reader r = new InputStreamReader(new FileInputStream(f), "ISO-8859-1");
133 try {
134 char[] data = new char[(int) f.length()];
135 if (f.length() != r.read(data))
136 throw new IOException("Internal error reading file data from "+f);
137 assertEquals(checkData, new String(data));
138 } finally {
139 r.close();
140 }
141 }
142
143
144 protected FileRepository db;
145
146
147 protected File trash;
148
149 @Override
150 @Before
151 public void setUp() throws Exception {
152 super.setUp();
153 db = createWorkRepository();
154 trash = db.getWorkTree();
155 }
156
157 public static final int MOD_TIME = 1;
158
159 public static final int SMUDGE = 2;
160
161 public static final int LENGTH = 4;
162
163 public static final int CONTENT_ID = 8;
164
165 public static final int CONTENT = 16;
166
167 public static final int ASSUME_UNCHANGED = 32;
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207 public String indexState(Repository repo, int includedOptions)
208 throws IllegalStateException, IOException {
209 DirCache dc = repo.readDirCache();
210 StringBuilder sb = new StringBuilder();
211 TreeSet<Long> timeStamps = null;
212
213
214 if (0 != (includedOptions & MOD_TIME)) {
215 timeStamps = new TreeSet<Long>();
216 for (int i=0; i<dc.getEntryCount(); ++i)
217 timeStamps.add(Long.valueOf(dc.getEntry(i).getLastModified()));
218 }
219
220
221 for (int i=0; i<dc.getEntryCount(); ++i) {
222 DirCacheEntry entry = dc.getEntry(i);
223 sb.append("["+entry.getPathString()+", mode:" + entry.getFileMode());
224 int stage = entry.getStage();
225 if (stage != 0)
226 sb.append(", stage:" + stage);
227 if (0 != (includedOptions & MOD_TIME)) {
228 sb.append(", time:t"+
229 timeStamps.headSet(Long.valueOf(entry.getLastModified())).size());
230 }
231 if (0 != (includedOptions & SMUDGE))
232 if (entry.isSmudged())
233 sb.append(", smudged");
234 if (0 != (includedOptions & LENGTH))
235 sb.append(", length:"
236 + Integer.toString(entry.getLength()));
237 if (0 != (includedOptions & CONTENT_ID))
238 sb.append(", sha1:" + ObjectId.toString(entry.getObjectId()));
239 if (0 != (includedOptions & CONTENT)) {
240 sb.append(", content:"
241 + new String(db.open(entry.getObjectId(),
242 Constants.OBJ_BLOB).getCachedBytes(), "UTF-8"));
243 }
244 if (0 != (includedOptions & ASSUME_UNCHANGED))
245 sb.append(", assume-unchanged:"
246 + Boolean.toString(entry.isAssumeValid()));
247 sb.append("]");
248 }
249 return sb.toString();
250 }
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287 public String indexState(int includedOptions)
288 throws IllegalStateException, IOException {
289 return indexState(db, includedOptions);
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308 protected void resetIndex(FileTreeIterator treeItr)
309 throws FileNotFoundException, IOException {
310 try (ObjectInserter inserter = db.newObjectInserter()) {
311 DirCacheBuilder builder = db.lockDirCache().builder();
312 DirCacheEntry dce;
313
314 while (!treeItr.eof()) {
315 long len = treeItr.getEntryLength();
316
317 dce = new DirCacheEntry(treeItr.getEntryPathString());
318 dce.setFileMode(treeItr.getEntryFileMode());
319 dce.setLastModified(treeItr.getEntryLastModified());
320 dce.setLength((int) len);
321 FileInputStream in = new FileInputStream(
322 treeItr.getEntryFile());
323 dce.setObjectId(inserter.insert(Constants.OBJ_BLOB, len, in));
324 in.close();
325 builder.add(dce);
326 treeItr.next(1);
327 }
328 builder.commit();
329 inserter.flush();
330 }
331 }
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354 public static String lookup(Object l, String nameTemplate,
355 Map<Object, String> lookupTable) {
356 String name = lookupTable.get(l);
357 if (name == null) {
358 name = nameTemplate.replaceAll("%n",
359 Integer.toString(lookupTable.size()));
360 lookupTable.put(l, name);
361 }
362 return name;
363 }
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381 public static long fsTick(File lastFile) throws InterruptedException,
382 IOException {
383 long sleepTime = 64;
384 FS fs = FS.DETECTED;
385 if (lastFile != null && !fs.exists(lastFile))
386 throw new FileNotFoundException(lastFile.getPath());
387 File tmp = File.createTempFile("FileTreeIteratorWithTimeControl", null);
388 try {
389 long startTime = (lastFile == null) ? fs.lastModified(tmp) : fs
390 .lastModified(lastFile);
391 long actTime = fs.lastModified(tmp);
392 while (actTime <= startTime) {
393 Thread.sleep(sleepTime);
394 sleepTime *= 2;
395 FileOutputStream fos = new FileOutputStream(tmp);
396 fos.close();
397 actTime = fs.lastModified(tmp);
398 }
399 return actTime;
400 } finally {
401 FileUtils.delete(tmp);
402 }
403 }
404
405 protected void createBranch(ObjectId objectId, String branchName)
406 throws IOException {
407 RefUpdate updateRef = db.updateRef(branchName);
408 updateRef.setNewObjectId(objectId);
409 updateRef.update();
410 }
411
412 protected void checkoutBranch(String branchName)
413 throws IllegalStateException, IOException {
414 try (RevWalk walk = new RevWalk(db)) {
415 RevCommit head = walk.parseCommit(db.resolve(Constants.HEAD));
416 RevCommit branch = walk.parseCommit(db.resolve(branchName));
417 DirCacheCheckout dco = new DirCacheCheckout(db,
418 head.getTree().getId(), db.lockDirCache(),
419 branch.getTree().getId());
420 dco.setFailOnConflict(true);
421 dco.checkout();
422 }
423
424 RefUpdate refUpdate = db.updateRef(Constants.HEAD);
425 refUpdate.setRefLogMessage("checkout: moving to " + branchName, false);
426 refUpdate.link(branchName);
427 }
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445 protected File writeTrashFiles(boolean ensureDistinctTimestamps,
446 String... contents)
447 throws IOException, InterruptedException {
448 File f = null;
449 for (int i = 0; i < contents.length; i++)
450 if (contents[i] != null) {
451 if (ensureDistinctTimestamps && (f != null))
452 fsTick(f);
453 f = writeTrashFile(Integer.toString(i), contents[i]);
454 }
455 return f;
456 }
457
458
459
460
461
462
463
464
465
466
467
468
469
470 protected RevCommit commitFile(String filename, String contents, String branch) {
471 try {
472 Git git = new Git(db);
473 Repository repo = git.getRepository();
474 String originalBranch = repo.getFullBranch();
475 boolean empty = repo.resolve(Constants.HEAD) == null;
476 if (!empty) {
477 if (repo.getRef(branch) == null)
478 git.branchCreate().setName(branch).call();
479 git.checkout().setName(branch).call();
480 }
481
482 writeTrashFile(filename, contents);
483 git.add().addFilepattern(filename).call();
484 RevCommit commit = git.commit()
485 .setMessage(branch + ": " + filename).call();
486
487 if (originalBranch != null)
488 git.checkout().setName(originalBranch).call();
489 else if (empty)
490 git.branchCreate().setName(branch).setStartPoint(commit).call();
491
492 return commit;
493 } catch (IOException e) {
494 throw new RuntimeException(e);
495 } catch (GitAPIException e) {
496 throw new RuntimeException(e);
497 }
498 }
499
500 protected DirCacheEntry createEntry(final String path, final FileMode mode) {
501 return createEntry(path, mode, DirCacheEntry.STAGE_0, path);
502 }
503
504 protected DirCacheEntry createEntry(final String path, final FileMode mode,
505 final String content) {
506 return createEntry(path, mode, DirCacheEntry.STAGE_0, content);
507 }
508
509 protected DirCacheEntry createEntry(final String path, final FileMode mode,
510 final int stage, final String content) {
511 final DirCacheEntry entry = new DirCacheEntry(path, stage);
512 entry.setFileMode(mode);
513 entry.setObjectId(new ObjectInserter.Formatter().idFor(
514 Constants.OBJ_BLOB, Constants.encode(content)));
515 return entry;
516 }
517
518 public static void assertEqualsFile(File expected, File actual)
519 throws IOException {
520 assertEquals(expected.getCanonicalFile(), actual.getCanonicalFile());
521 }
522 }