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