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