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 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 @Test
110 public void fileModeTestSymlinkThenFile() throws Exception {
111 Git git = new Git(db);
112 writeTrashFile("b", "Hello world b");
113 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
114 git.add().addFilepattern(".").call();
115 git.commit().setMessage("add file b & symlink a").call();
116 Ref branch_1 = git.branchCreate().setName("branch_1").call();
117 git.rm().addFilepattern("a").call();
118 writeTrashFile("a", "Hello world a");
119 git.add().addFilepattern("a").call();
120 git.commit().setMessage("add file a").call();
121
122 FileEntry entry = new FileTreeIterator.FileEntry(new File(
123 db.getWorkTree(), "a"), db.getFS());
124 assertEquals(FileMode.REGULAR_FILE, entry.getMode());
125
126 git.checkout().setName(branch_1.getName()).call();
127
128 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
129 db.getFS());
130 assertEquals(FileMode.SYMLINK, entry.getMode());
131 }
132
133
134
135
136
137
138
139
140
141
142 @Test
143 public void fileModeTestFolderThenSymlink() throws Exception {
144 Git git = new Git(db);
145 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
146 writeTrashFile("a/b", "Hello world b");
147 writeTrashFile("c", "Hello world c");
148 git.add().addFilepattern(".").call();
149 git.commit().setMessage("add folder a").call();
150 Ref branch_1 = git.branchCreate().setName("branch_1").call();
151 git.rm().addFilepattern("a").call();
152 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
153 git.add().addFilepattern("a").call();
154 git.commit().setMessage("add symlink a").call();
155
156 FileEntry entry = new FileTreeIterator.FileEntry(new File(
157 db.getWorkTree(), "a"), db.getFS());
158 assertEquals(FileMode.SYMLINK, entry.getMode());
159
160 git.checkout().setName(branch_1.getName()).call();
161
162 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
163 db.getFS());
164 assertEquals(FileMode.TREE, entry.getMode());
165 }
166
167
168
169
170
171
172
173
174
175
176 @Test
177 public void fileModeTestSymlinkThenFolder() throws Exception {
178 Git git = new Git(db);
179 writeTrashFile("c", "Hello world c");
180 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "c");
181 git.add().addFilepattern(".").call();
182 git.commit().setMessage("add symlink a").call();
183 Ref branch_1 = git.branchCreate().setName("branch_1").call();
184 git.rm().addFilepattern("a").call();
185 FileUtils.mkdirs(new File(db.getWorkTree(), "a"));
186 writeTrashFile("a/b", "Hello world b");
187 git.add().addFilepattern("a").call();
188 git.commit().setMessage("add folder a").call();
189
190 FileEntry entry = new FileTreeIterator.FileEntry(new File(
191 db.getWorkTree(), "a"), db.getFS());
192 assertEquals(FileMode.TREE, entry.getMode());
193
194 git.checkout().setName(branch_1.getName()).call();
195
196 entry = new FileTreeIterator.FileEntry(new File(db.getWorkTree(), "a"),
197 db.getFS());
198 assertEquals(FileMode.SYMLINK, entry.getMode());
199 }
200
201
202
203
204
205
206
207
208
209
210 @Test
211 public void fileModeTestMissingThenSymlink() throws Exception {
212 Git git = new Git(db);
213 writeTrashFile("b", "Hello world b");
214 git.add().addFilepattern(".").call();
215 RevCommit commit1 = git.commit().setMessage("add file b").call();
216 Ref branch_1 = git.branchCreate().setName("branch_1").call();
217 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
218 git.add().addFilepattern("a").call();
219 RevCommit commit2 = git.commit().setMessage("add symlink a").call();
220
221 git.checkout().setName(branch_1.getName()).call();
222
223 TreeWalk tw = new TreeWalk(db);
224 tw.addTree(commit1.getTree());
225 tw.addTree(commit2.getTree());
226 List<DiffEntry> scan = DiffEntry.scan(tw);
227 assertEquals(1, scan.size());
228 assertEquals(FileMode.SYMLINK, scan.get(0).getNewMode());
229 assertEquals(FileMode.MISSING, scan.get(0).getOldMode());
230 }
231
232
233
234
235
236
237
238
239
240
241 @Test
242 public void fileModeTestSymlinkThenMissing() throws Exception {
243 Git git = new Git(db);
244 writeTrashFile("b", "Hello world b");
245 FileUtils.createSymLink(new File(db.getWorkTree(), "a"), "b");
246 git.add().addFilepattern(".").call();
247 RevCommit commit1 = git.commit().setMessage("add file b & symlink a")
248 .call();
249 Ref branch_1 = git.branchCreate().setName("branch_1").call();
250 git.rm().addFilepattern("a").call();
251 RevCommit commit2 = git.commit().setMessage("delete symlink a").call();
252
253 git.checkout().setName(branch_1.getName()).call();
254
255 TreeWalk tw = new TreeWalk(db);
256 tw.addTree(commit1.getTree());
257 tw.addTree(commit2.getTree());
258 List<DiffEntry> scan = DiffEntry.scan(tw);
259 assertEquals(1, scan.size());
260 assertEquals(FileMode.MISSING, scan.get(0).getNewMode());
261 assertEquals(FileMode.SYMLINK, scan.get(0).getOldMode());
262 }
263
264 @Test
265 public void createSymlinkAfterTarget() throws Exception {
266 Git git = new Git(db);
267 writeTrashFile("a", "start");
268 git.add().addFilepattern("a").call();
269 RevCommit base = git.commit().setMessage("init").call();
270 writeTrashFile("target", "someData");
271 FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
272 git.add().addFilepattern("target").addFilepattern("link").call();
273 git.commit().setMessage("add target").call();
274 assertEquals(4, db.getWorkTree().list().length);
275 git.checkout().setName(base.name()).call();
276 assertEquals(2, db.getWorkTree().list().length);
277 git.checkout().setName("master").call();
278 assertEquals(4, db.getWorkTree().list().length);
279 String data = read(new File(db.getWorkTree(), "target"));
280 assertEquals(8, new File(db.getWorkTree(), "target").length());
281 assertEquals("someData", data);
282 data = read(new File(db.getWorkTree(), "link"));
283 assertEquals("target",
284 FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
285 assertEquals("someData", data);
286 }
287
288 @Test
289 public void createFileSymlinkBeforeTarget() throws Exception {
290 Git git = new Git(db);
291 writeTrashFile("a", "start");
292 git.add().addFilepattern("a").call();
293 RevCommit base = git.commit().setMessage("init").call();
294 writeTrashFile("target", "someData");
295 FileUtils.createSymLink(new File(db.getWorkTree(), "tlink"), "target");
296 git.add().addFilepattern("target").addFilepattern("tlink").call();
297 git.commit().setMessage("add target").call();
298 assertEquals(4, db.getWorkTree().list().length);
299 git.checkout().setName(base.name()).call();
300 assertEquals(2, db.getWorkTree().list().length);
301 git.checkout().setName("master").call();
302 assertEquals(4, db.getWorkTree().list().length);
303 String data = read(new File(db.getWorkTree(), "target"));
304 assertEquals(8, new File(db.getWorkTree(), "target").length());
305 assertEquals("someData", data);
306 data = read(new File(db.getWorkTree(), "tlink"));
307 assertEquals("target",
308 FileUtils.readSymLink(new File(db.getWorkTree(), "tlink")));
309 assertEquals("someData", data);
310 }
311
312 @Test
313 public void createDirSymlinkBeforeTarget() throws Exception {
314 Git git = new Git(db);
315 writeTrashFile("a", "start");
316 git.add().addFilepattern("a").call();
317 RevCommit base = git.commit().setMessage("init").call();
318 FileUtils.createSymLink(new File(db.getWorkTree(), "link"), "target");
319 FileUtils.mkdir(new File(db.getWorkTree(), "target"));
320 writeTrashFile("target/file", "someData");
321 git.add().addFilepattern("target").addFilepattern("link").call();
322 git.commit().setMessage("add target").call();
323 assertEquals(4, db.getWorkTree().list().length);
324 git.checkout().setName(base.name()).call();
325 assertEquals(2, db.getWorkTree().list().length);
326 git.checkout().setName("master").call();
327 assertEquals(4, db.getWorkTree().list().length);
328 String data = read(new File(db.getWorkTree(), "target/file"));
329 assertEquals(8, new File(db.getWorkTree(), "target/file").length());
330 assertEquals("someData", data);
331 data = read(new File(db.getWorkTree(), "link/file"));
332 assertEquals("target",
333 FileUtils.readSymLink(new File(db.getWorkTree(), "link")));
334 assertEquals("someData", data);
335 }
336 }