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 package org.eclipse.jgit.submodule;
44
45 import java.io.File;
46 import java.io.IOException;
47 import java.util.Collection;
48
49 import org.eclipse.jgit.api.Git;
50 import org.eclipse.jgit.api.SubmoduleDeinitCommand;
51 import org.eclipse.jgit.api.SubmoduleDeinitResult;
52 import org.eclipse.jgit.api.SubmoduleUpdateCommand;
53 import org.eclipse.jgit.api.errors.GitAPIException;
54 import org.eclipse.jgit.dircache.DirCache;
55 import org.eclipse.jgit.dircache.DirCacheEditor;
56 import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
57 import org.eclipse.jgit.dircache.DirCacheEntry;
58 import org.eclipse.jgit.junit.JGitTestUtil;
59 import org.eclipse.jgit.junit.RepositoryTestCase;
60 import org.eclipse.jgit.lib.ConfigConstants;
61 import org.eclipse.jgit.lib.Constants;
62 import org.eclipse.jgit.lib.FileMode;
63 import org.eclipse.jgit.lib.Repository;
64 import org.eclipse.jgit.lib.StoredConfig;
65 import org.eclipse.jgit.revwalk.RevCommit;
66 import org.eclipse.jgit.storage.file.FileBasedConfig;
67 import org.junit.Test;
68
69 import static org.junit.Assert.assertEquals;
70 import static org.junit.Assert.assertNotEquals;
71 import static org.junit.Assert.assertNotNull;
72 import static org.junit.Assert.assertTrue;
73
74
75
76
77 public class SubmoduleDeinitTest extends RepositoryTestCase {
78
79 @Test
80 public void repositoryWithNoSubmodules() throws GitAPIException {
81 SubmoduleDeinitCommand command = new SubmoduleDeinitCommand(db);
82 Collection<SubmoduleDeinitResult> modules = command.call();
83 assertNotNull(modules);
84 assertTrue(modules.isEmpty());
85 }
86
87 @Test
88 public void alreadyClosedSubmodule() throws Exception {
89 final String path = "sub";
90 Git git = Git.wrap(db);
91
92 commitSubmoduleCreation(path, git);
93
94 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
95 assertEquals(path, result.getPath());
96 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.ALREADY_DEINITIALIZED, result.getStatus());
97 }
98
99 @Test
100 public void dirtySubmoduleBecauseUntracked() throws Exception {
101 final String path = "sub";
102 Git git = Git.wrap(db);
103
104 commitSubmoduleCreation(path, git);
105
106 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
107 assertEquals(1, updated.size());
108
109 File submoduleDir = assertSubmoduleIsInitialized();
110 SubmoduleWalk generator;
111
112 write(new File(submoduleDir, "untracked"), "untracked");
113
114 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
115 assertEquals(path, result.getPath());
116 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus());
117
118 generator = SubmoduleWalk.forIndex(db);
119 assertTrue(generator.next());
120 assertTrue(submoduleDir.isDirectory());
121 assertNotEquals(0, submoduleDir.list().length);
122 }
123
124 @Test
125 public void dirtySubmoduleBecauseNewCommit() throws Exception {
126 final String path = "sub";
127 Git git = Git.wrap(db);
128
129 commitSubmoduleCreation(path, git);
130
131 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
132 assertEquals(1, updated.size());
133
134 File submoduleDir = assertSubmoduleIsInitialized();
135 SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
136 generator.next();
137
138
139 Repository submoduleLocalRepo = generator.getRepository();
140 JGitTestUtil.writeTrashFile(submoduleLocalRepo, "file.txt", "new data");
141 Git.wrap(submoduleLocalRepo).commit().setAll(true).setMessage("local commit").call();
142
143 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
144 assertEquals(path, result.getPath());
145 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.DIRTY, result.getStatus());
146
147 generator = SubmoduleWalk.forIndex(db);
148 assertTrue(generator.next());
149 assertTrue(submoduleDir.isDirectory());
150 assertNotEquals(0, submoduleDir.list().length);
151 }
152
153 private File assertSubmoduleIsInitialized() throws IOException {
154 SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
155 assertTrue(generator.next());
156 File submoduleDir = new File(db.getWorkTree(), generator.getPath());
157 assertTrue(submoduleDir.isDirectory());
158 assertNotEquals(0, submoduleDir.list().length);
159 return submoduleDir;
160 }
161
162 @Test
163 public void dirtySubmoduleWithForce() throws Exception {
164 final String path = "sub";
165 Git git = Git.wrap(db);
166
167 commitSubmoduleCreation(path, git);
168
169 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
170 assertEquals(1, updated.size());
171
172 File submoduleDir = assertSubmoduleIsInitialized();
173
174 write(new File(submoduleDir, "untracked"), "untracked");
175
176 SubmoduleDeinitCommand command = new SubmoduleDeinitCommand(db).addPath("sub").setForce(true);
177 SubmoduleDeinitResult result = runDeinit(command);
178 assertEquals(path, result.getPath());
179 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.FORCED, result.getStatus());
180
181 SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
182 assertTrue(generator.next());
183 assertTrue(submoduleDir.isDirectory());
184 assertEquals(0, submoduleDir.list().length);
185 }
186
187 @Test
188 public void cleanSubmodule() throws Exception {
189 final String path = "sub";
190 Git git = Git.wrap(db);
191
192 commitSubmoduleCreation(path, git);
193
194 Collection<String> updated = new SubmoduleUpdateCommand(db).addPath(path).setFetch(false).call();
195 assertEquals(1, updated.size());
196
197 File submoduleDir = assertSubmoduleIsInitialized();
198
199 SubmoduleDeinitResult result = runDeinit(new SubmoduleDeinitCommand(db).addPath("sub"));
200 assertEquals(path, result.getPath());
201 assertEquals(SubmoduleDeinitCommand.SubmoduleDeinitStatus.SUCCESS, result.getStatus());
202
203 SubmoduleWalk generator = SubmoduleWalk.forIndex(db);
204 assertTrue(generator.next());
205 assertTrue(submoduleDir.isDirectory());
206 assertEquals(0, submoduleDir.list().length);
207 }
208
209 private SubmoduleDeinitResult runDeinit(SubmoduleDeinitCommand command) throws GitAPIException {
210 Collection<SubmoduleDeinitResult> deinitialized = command.call();
211 assertNotNull(deinitialized);
212 assertEquals(1, deinitialized.size());
213 return deinitialized.iterator().next();
214 }
215
216
217 private RevCommit commitSubmoduleCreation(String path, Git git) throws IOException, GitAPIException {
218 writeTrashFile("file.txt", "content");
219 git.add().addFilepattern("file.txt").call();
220 final RevCommit commit = git.commit().setMessage("create file").call();
221
222 DirCache cache = db.lockDirCache();
223 DirCacheEditor editor = cache.editor();
224 editor.add(new PathEdit(path) {
225
226 @Override
227 public void apply(DirCacheEntry ent) {
228 ent.setFileMode(FileMode.GITLINK);
229 ent.setObjectId(commit);
230 }
231 });
232 editor.commit();
233
234 StoredConfig config = db.getConfig();
235 config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
236 ConfigConstants.CONFIG_KEY_URL, db.getDirectory().toURI()
237 .toString());
238 config.save();
239
240 FileBasedConfig modulesConfig = new FileBasedConfig(new File(
241 db.getWorkTree(), Constants.DOT_GIT_MODULES), db.getFS());
242 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
243 ConfigConstants.CONFIG_KEY_PATH, path);
244 modulesConfig.save();
245
246 new File(db.getWorkTree(), "sub").mkdir();
247 git.add().addFilepattern(Constants.DOT_GIT_MODULES).call();
248 git.commit().setMessage("create submodule").call();
249 return commit;
250 }
251 }