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.api;
44
45 import java.io.File;
46 import java.io.IOException;
47 import java.text.MessageFormat;
48
49 import org.eclipse.jgit.api.errors.GitAPIException;
50 import org.eclipse.jgit.api.errors.JGitInternalException;
51 import org.eclipse.jgit.api.errors.NoFilepatternException;
52 import org.eclipse.jgit.errors.ConfigInvalidException;
53 import org.eclipse.jgit.internal.JGitText;
54 import org.eclipse.jgit.lib.ConfigConstants;
55 import org.eclipse.jgit.lib.Constants;
56 import org.eclipse.jgit.lib.NullProgressMonitor;
57 import org.eclipse.jgit.lib.ProgressMonitor;
58 import org.eclipse.jgit.lib.Repository;
59 import org.eclipse.jgit.lib.StoredConfig;
60 import org.eclipse.jgit.storage.file.FileBasedConfig;
61 import org.eclipse.jgit.submodule.SubmoduleWalk;
62 import org.eclipse.jgit.treewalk.filter.PathFilter;
63 import org.eclipse.jgit.treewalk.filter.TreeFilter;
64
65
66
67
68
69
70
71
72
73
74
75
76 public class SubmoduleAddCommand extends
77 TransportCommand<SubmoduleAddCommand, Repository> {
78
79 private String path;
80
81 private String uri;
82
83 private ProgressMonitor monitor;
84
85
86
87
88
89
90
91 public SubmoduleAddCommand(Repository repo) {
92 super(repo);
93 }
94
95
96
97
98
99
100
101
102 public SubmoduleAddCommand setPath(String path) {
103 this.path = path;
104 return this;
105 }
106
107
108
109
110
111
112
113
114 public SubmoduleAddCommand setURI(String uri) {
115 this.uri = uri;
116 return this;
117 }
118
119
120
121
122
123
124
125
126
127
128 public SubmoduleAddCommand setProgressMonitor(ProgressMonitor monitor) {
129 this.monitor = monitor;
130 return this;
131 }
132
133
134
135
136
137
138
139 protected boolean submoduleExists() throws IOException {
140 TreeFilter filter = PathFilter.create(path);
141 try (SubmoduleWalk w = SubmoduleWalk.forIndex(repo)) {
142 return w.setFilter(filter).next();
143 }
144 }
145
146
147
148
149
150
151
152
153
154
155
156 @Override
157 public Repository call() throws GitAPIException {
158 checkCallable();
159 if (path == null || path.length() == 0)
160 throw new IllegalArgumentException(JGitText.get().pathNotConfigured);
161 if (uri == null || uri.length() == 0)
162 throw new IllegalArgumentException(JGitText.get().uriNotConfigured);
163
164 try {
165 if (submoduleExists())
166 throw new JGitInternalException(MessageFormat.format(
167 JGitText.get().submoduleExists, path));
168 } catch (IOException e) {
169 throw new JGitInternalException(e.getMessage(), e);
170 }
171
172 final String resolvedUri;
173 try {
174 resolvedUri = SubmoduleWalk.getSubmoduleRemoteUrl(repo, uri);
175 } catch (IOException e) {
176 throw new JGitInternalException(e.getMessage(), e);
177 }
178
179 File moduleDirectory = SubmoduleWalk.getSubmoduleDirectory(repo, path);
180 CloneCommand clone = Git.cloneRepository();
181 configure(clone);
182 clone.setDirectory(moduleDirectory);
183 clone.setGitDir(new File(new File(repo.getDirectory(),
184 Constants.MODULES), path));
185 clone.setURI(resolvedUri);
186 if (monitor != null)
187 clone.setProgressMonitor(monitor);
188 Repository subRepo = null;
189 try (Git git = clone.call()) {
190 subRepo = git.getRepository();
191 subRepo.incrementOpen();
192 }
193
194
195 StoredConfig config = repo.getConfig();
196 config.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION, path,
197 ConfigConstants.CONFIG_KEY_URL, resolvedUri);
198 try {
199 config.save();
200 } catch (IOException e) {
201 throw new JGitInternalException(e.getMessage(), e);
202 }
203
204
205 FileBasedConfig modulesConfig = new FileBasedConfig(new File(
206 repo.getWorkTree(), Constants.DOT_GIT_MODULES), repo.getFS());
207 try {
208 modulesConfig.load();
209 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
210 path, ConfigConstants.CONFIG_KEY_PATH, path);
211 modulesConfig.setString(ConfigConstants.CONFIG_SUBMODULE_SECTION,
212 path, ConfigConstants.CONFIG_KEY_URL, uri);
213 modulesConfig.save();
214 } catch (IOException e) {
215 throw new JGitInternalException(e.getMessage(), e);
216 } catch (ConfigInvalidException e) {
217 throw new JGitInternalException(e.getMessage(), e);
218 }
219
220 AddCommand add = new AddCommand(repo);
221
222 add.addFilepattern(Constants.DOT_GIT_MODULES);
223
224 add.addFilepattern(path);
225 try {
226 add.call();
227 } catch (NoFilepatternException e) {
228 throw new JGitInternalException(e.getMessage(), e);
229 }
230
231 return subRepo;
232 }
233 }