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 package org.eclipse.jgit.symlinks;
39
40 import static org.junit.Assert.assertEquals;
41
42 import java.io.File;
43 import java.util.List;
44
45 import org.eclipse.jgit.api.Git;
46 import org.eclipse.jgit.diff.DiffEntry;
47 import org.eclipse.jgit.junit.RepositoryTestCase;
48 import org.eclipse.jgit.lib.FileMode;
49 import org.eclipse.jgit.lib.Ref;
50 import org.eclipse.jgit.revwalk.RevCommit;
51 import org.eclipse.jgit.treewalk.FileTreeIterator;
52 import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry;
53 import org.eclipse.jgit.treewalk.TreeWalk;
54 import org.eclipse.jgit.util.FS;
55 import org.eclipse.jgit.util.FileUtils;
56 import org.junit.Before;
57 import org.junit.Test;
58
59 public class SymlinksTest extends RepositoryTestCase {
60 @Before
61 public void beforeMethod() {
62
63
64 org.junit.Assume.assumeTrue(FS.DETECTED.supportsSymlinks());
65 }
66
67
68
69
70
71
72
73
74
75
76 @Test
77 public void fileModeTestFileThenSymlink() throws Exception {
78 try (Git git = new Git(db)) {
79 writeTrashFile("a", "Hello world a");
80 writeTrashFile("b", "Hello world b");
81 git.add().addFilepattern(".").call();
82 git.commit().setMessage("add files a & b").call();
83 Ref branch_1 = git.branchCreate().setName("branch_1").call();
84 git.rm().addFilepattern("a").call();
85 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
86 git.add().addFilepattern("a").call();
87 git.commit().setMessage("add symlink a").call();
88
89 FileEntry entry = new FileTreeIterator.FileEntry(new File(
90 db.getWorkTree(), "a"), db.getFS());
91 assertEquals(FileMode.SYMLINK, entry.getMode());
92
93 git.checkout().setName(branch_1.getName()).call();
94
95 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
96 db.getFS());
97 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
98 }
99 }
100
101
102
103
104
105
106
107
108
109
110 @Test
111 public void fileModeTestSymlinkThenFile() throws Exception {
112 try (Git git = new Git(db)) {
113 writeTrashFile("b", "Hello world b");
114 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
115 git.add().addFilepattern(".").call();
116 git.commit().setMessage("add file b & symlink a").call();
117 Ref branch_1 = git.branchCreate().setName("branch_1").call();
118 git.rm().addFilepattern("a").call();
119 writeTrashFile("a", "Hello world a");
120 git.add().addFilepattern("a").call();
121 git.commit().setMessage("add file a").call();
122
123 FileEntry entry = new FileTreeIterator.FileEntry(new File(
124 db.getWorkTree(), "a"), db.getFS());
125 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
126
127 git.checkout().setName(branch_1.getName()).call();
128
129 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
130 db.getFS());
131 assertEquals(FileMode.SYMLINK, entry.getMode());
132 }
133 }
134
135
136
137
138
139
140
141
142
143
144 @Test
145 public void fileModeTestFolderThenSymlink() throws Exception {
146 try (Git git = new Git(db)) {
147 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
148 writeTrashFile("a/b", "Hello world b");
149 writeTrashFile("c", "Hello world c");
150 git.add().addFilepattern(".").call();
151 git.commit().setMessage("add folder a").call();
152 Ref branch_1 = git.branchCreate().setName("branch_1").call();
153 git.rm().addFilepattern("a").call();
154 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
155 git.add().addFilepattern("a").call();
156 git.commit().setMessage("add symlink a").call();
157
158 FileEntry entry = new FileTreeIterator.FileEntry(new File(
159 db.getWorkTree(), "a"), db.getFS());
160 assertEquals(FileMode.SYMLINK, entry.getMode());
161
162 git.checkout().setName(branch_1.getName()).call();
163
164 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
165 db.getFS());
166 assertEquals(FileMode.TREE, entry.getMode());
167 }
168 }
169
170
171
172
173
174
175
176
177
178
179 @Test
180 public void fileModeTestSymlinkThenFolder() throws Exception {
181 try (Git git = new Git(db)) {
182 writeTrashFile("c", "Hello world c");
183 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
184 git.add().addFilepattern(".").call();
185 git.commit().setMessage("add symlink a").call();
186 Ref branch_1 = git.branchCreate().setName("branch_1").call();
187 git.rm().addFilepattern("a").call();
188 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
189 writeTrashFile("a/b", "Hello world b");
190 git.add().addFilepattern("a").call();
191 git.commit().setMessage("add folder a").call();
192
193 FileEntry entry = new FileTreeIterator.FileEntry(new File(
194 db.getWorkTree(), "a"), db.getFS());
195 assertEquals(FileMode.TREE, entry.getMode());
196
197 git.checkout().setName(branch_1.getName()).call();
198
199 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
200 db.getFS());
201 assertEquals(FileMode.SYMLINK, entry.getMode());
202 }
203 }
204
205
206
207
208
209
210
211
212
213
214 @Test
215 public void fileModeTestMissingThenSymlink() throws Exception {
216 try (Git git = new Git(db);
217 TreeWalk tw = new TreeWalk(db);) {
218 writeTrashFile("b", "Hello world b");
219 git.add().addFilepattern(".").call();
220 RevCommit commit1 = git.commit().setMessage("add file b").call();
221 Ref branch_1 = git.branchCreate().setName("branch_1").call();
222 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
223 git.add().addFilepattern("a").call();
224 RevCommit commit2 = git.commit().setMessage("add symlink a").call();
225
226 git.checkout().setName(branch_1.getName()).call();
227
228 tw.addTree(commit1.getTree());
229 tw.addTree(commit2.getTree());
230 List<DiffEntry> scan = DiffEntry.scan(tw);
231 assertEquals(1, scan.size());
232 assertEquals(FileMode.SYMLINK, scan.get(0).getNewMode());
233 assertEquals(FileMode.MISSING, scan.get(0).getOldMode());
234 }
235 }
236
237
238
239
240
241
242
243
244
245
246 @Test
247 public void fileModeTestSymlinkThenMissing() throws Exception {
248 try (Git git = new Git(db);
249 TreeWalk tw = new TreeWalk(db);) {
250 writeTrashFile("b", "Hello world b");
251 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
252 git.add().addFilepattern(".").call();
253 RevCommit commit1 = git.commit().setMessage("add file b & symlink a")
254 .call();
255 Ref branch_1 = git.branchCreate().setName("branch_1").call();
256 git.rm().addFilepattern("a").call();
257 RevCommit commit2 = git.commit().setMessage("delete symlink a").call();
258
259 git.checkout().setName(branch_1.getName()).call();
260
261 tw.addTree(commit1.getTree());
262 tw.addTree(commit2.getTree());
263 List<DiffEntry> scan = DiffEntry.scan(tw);
264 assertEquals(1, scan.size());
265 assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
266 assertEquals(FileMode.SYMLINK, scan.get(0).getOldMode());
267 }
268 }
269
270 @Test
271 public void createSymlinkAfterTarget() throws Exception {
272 try (Git git = new Git(db)) {
273 writeTrashFile("a", "start");
274 git.add().addFilepattern("a").call();
275 RevCommit base = git.commit().setMessage("init").call();
276 writeTrashFile("target", "someData");
277 FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
278 git.add().addFilepattern("target").addFilepattern("link").call();
279 git.commit().setMessage("add target").call();
280 assertEquals(4, db.getWorkTree().list().length);
281 git.checkout().setName(base.name()).call();
282 assertEquals(2, db.getWorkTree().list().length);
283 git.checkout().setName("master").call();
284 assertEquals(4, db.getWorkTree().list().length);
285 String data = read(new File(db.getWorkTree(), "target"));
286 assertEquals(8, new File(db.getWorkTree(), "target").length());
287 assertEquals("someData", data);
288 data = read(new File(db.getWorkTree(), "link"));
289 assertEquals("target",
290 FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
291 assertEquals("someData", data);
292 }
293 }
294
295 @Test
296 public void createFileSymlinkBeforeTarget() throws Exception {
297 try (Git git = new Git(db)) {
298 writeTrashFile("a", "start");
299 git.add().addFilepattern("a").call();
300 RevCommit base = git.commit().setMessage("init").call();
301 writeTrashFile("target", "someData");
302 FileUtils.createSymLink(new File(db.getWorkTree(), "tlink"), "target");
303 git.add().addFilepattern("target").addFilepattern("tlink").call();
304 git.commit().setMessage("add target").call();
305 assertEquals(4, db.getWorkTree().list().length);
306 git.checkout().setName(base.name()).call();
307 assertEquals(2, db.getWorkTree().list().length);
308 git.checkout().setName("master").call();
309 assertEquals(4, db.getWorkTree().list().length);
310 String data = read(new File(db.getWorkTree(), "target"));
311 assertEquals(8, new File(db.getWorkTree(), "target").length());
312 assertEquals("someData", data);
313 data = read(new File(db.getWorkTree(), "tlink"));
314 assertEquals("target",
315 FileUtils.readSymLink(new File(db.getWorkTree(), "tlink")));
316 assertEquals("someData", data);
317 }
318 }
319
320 @Test
321 public void createDirSymlinkBeforeTarget() throws Exception {
322 try (Git git = new Git(db)) {
323 writeTrashFile("a", "start");
324 git.add().addFilepattern("a").call();
325 RevCommit base = git.commit().setMessage("init").call();
326 FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
327 FileUtils.mkdir(new File(db.getWorkTree(), "target"));
328 writeTrashFile("target/file", "someData");
329 git.add().addFilepattern("target").addFilepattern("link").call();
330 git.commit().setMessage("add target").call();
331 assertEquals(4, db.getWorkTree().list().length);
332 git.checkout().setName(base.name()).call();
333 assertEquals(2, db.getWorkTree().list().length);
334 git.checkout().setName("master").call();
335 assertEquals(4, db.getWorkTree().list().length);
336 String data = read(new File(db.getWorkTree(), "target/file"));
337 assertEquals(8, new File(db.getWorkTree(), "target/file").length());
338 assertEquals("someData", data);
339 data = read(new File(db.getWorkTree(), "link/file"));
340 assertEquals("target",
341 FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
342 assertEquals("someData", data);
343 }
344 }
345 }