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 static org.junit.Assert.assertEquals;
46 import static org.junit.Assert.assertNotEquals;
47 import static org.junit.Assert.assertNotNull;
48 import static org.junit.Assert.assertNull;
49 import static org.junit.Assert.assertTrue;
50
51 import java.io.File;
52 import java.util.ArrayList;
53 import java.util.Collection;
54 import java.util.List;
55
56 import org.eclipse.jgit.junit.JGitTestUtil;
57 import org.eclipse.jgit.junit.RepositoryTestCase;
58 import org.eclipse.jgit.lib.Constants;
59 import org.eclipse.jgit.lib.ObjectId;
60 import org.eclipse.jgit.lib.Ref;
61 import org.eclipse.jgit.lib.RefUpdate;
62 import org.eclipse.jgit.lib.Repository;
63 import org.eclipse.jgit.lib.StoredConfig;
64 import org.eclipse.jgit.revwalk.RevCommit;
65 import org.eclipse.jgit.transport.FetchResult;
66 import org.eclipse.jgit.transport.RefSpec;
67 import org.eclipse.jgit.transport.RemoteConfig;
68 import org.eclipse.jgit.transport.TagOpt;
69 import org.eclipse.jgit.transport.TrackingRefUpdate;
70 import org.eclipse.jgit.transport.URIish;
71 import org.junit.Before;
72 import org.junit.Test;
73
74 public class FetchCommandTest extends RepositoryTestCase {
75
76 private Git git;
77 private Git remoteGit;
78
79 @Before
80 public void setupRemoteRepository() throws Exception {
81 git = new Git(db);
82
83
84 Repository remoteRepository = createWorkRepository();
85 remoteGit = new Git(remoteRepository);
86
87
88 final StoredConfig config = db.getConfig();
89 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
90 URIish uri = new URIish(remoteRepository.getDirectory().toURI().toURL());
91 remoteConfig.addURI(uri);
92 remoteConfig.update(config);
93 config.save();
94 }
95
96 @Test
97 public void testFetch() throws Exception {
98
99
100 RevCommit commit = remoteGit.commit().setMessage("initial commit").call();
101 Ref tagRef = remoteGit.tag().setName("tag").call();
102
103 git.fetch().setRemote("test")
104 .setRefSpecs("refs/heads/master:refs/heads/x").call();
105
106 assertEquals(commit.getId(),
107 db.resolve(commit.getId().getName() + "^{commit}"));
108 assertEquals(tagRef.getObjectId(),
109 db.resolve(tagRef.getObjectId().getName()));
110 }
111
112 @Test
113 public void testForcedFetch() throws Exception {
114 remoteGit.commit().setMessage("commit").call();
115 remoteGit.commit().setMessage("commit2").call();
116 git.fetch().setRemote("test")
117 .setRefSpecs("refs/heads/master:refs/heads/master").call();
118
119 remoteGit.commit().setAmend(true).setMessage("amended").call();
120 FetchResult res = git.fetch().setRemote("test")
121 .setRefSpecs("refs/heads/master:refs/heads/master").call();
122 assertEquals(RefUpdate.Result.REJECTED,
123 res.getTrackingRefUpdate("refs/heads/master").getResult());
124 res = git.fetch().setRemote("test")
125 .setRefSpecs("refs/heads/master:refs/heads/master")
126 .setForceUpdate(true).call();
127 assertEquals(RefUpdate.Result.FORCED,
128 res.getTrackingRefUpdate("refs/heads/master").getResult());
129 }
130
131 @Test
132 public void fetchAddsBranches() throws Exception {
133 final String branch1 = "b1";
134 final String branch2 = "b2";
135 final String remoteBranch1 = "test/" + branch1;
136 final String remoteBranch2 = "test/" + branch2;
137 remoteGit.commit().setMessage("commit").call();
138 Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
139 remoteGit.commit().setMessage("commit").call();
140 Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
141
142 String spec = "refs/heads/*:refs/remotes/test/*";
143 git.fetch().setRemote("test").setRefSpecs(spec).call();
144 assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
145 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
146 }
147
148 @Test
149 public void fetchDoesntDeleteBranches() throws Exception {
150 final String branch1 = "b1";
151 final String branch2 = "b2";
152 final String remoteBranch1 = "test/" + branch1;
153 final String remoteBranch2 = "test/" + branch2;
154 remoteGit.commit().setMessage("commit").call();
155 Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
156 remoteGit.commit().setMessage("commit").call();
157 Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
158
159 String spec = "refs/heads/*:refs/remotes/test/*";
160 git.fetch().setRemote("test").setRefSpecs(spec).call();
161 assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
162 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
163
164 remoteGit.branchDelete().setBranchNames(branch1).call();
165 git.fetch().setRemote("test").setRefSpecs(spec).call();
166 assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
167 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
168 }
169
170 @Test
171 public void fetchUpdatesBranches() throws Exception {
172 final String branch1 = "b1";
173 final String branch2 = "b2";
174 final String remoteBranch1 = "test/" + branch1;
175 final String remoteBranch2 = "test/" + branch2;
176 remoteGit.commit().setMessage("commit").call();
177 Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
178 remoteGit.commit().setMessage("commit").call();
179 Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
180
181 String spec = "refs/heads/*:refs/remotes/test/*";
182 git.fetch().setRemote("test").setRefSpecs(spec).call();
183 assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
184 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
185
186 remoteGit.commit().setMessage("commit").call();
187 branchRef2 = remoteGit.branchCreate().setName(branch2).setForce(true).call();
188 git.fetch().setRemote("test").setRefSpecs(spec).call();
189 assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
190 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
191 }
192
193 @Test
194 public void fetchPrunesBranches() throws Exception {
195 final String branch1 = "b1";
196 final String branch2 = "b2";
197 final String remoteBranch1 = "test/" + branch1;
198 final String remoteBranch2 = "test/" + branch2;
199 remoteGit.commit().setMessage("commit").call();
200 Ref branchRef1 = remoteGit.branchCreate().setName(branch1).call();
201 remoteGit.commit().setMessage("commit").call();
202 Ref branchRef2 = remoteGit.branchCreate().setName(branch2).call();
203
204 String spec = "refs/heads/*:refs/remotes/test/*";
205 git.fetch().setRemote("test").setRefSpecs(spec).call();
206 assertEquals(branchRef1.getObjectId(), db.resolve(remoteBranch1));
207 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
208
209 remoteGit.branchDelete().setBranchNames(branch1).call();
210 git.fetch().setRemote("test").setRefSpecs(spec)
211 .setRemoveDeletedRefs(true).call();
212 assertNull(db.resolve(remoteBranch1));
213 assertEquals(branchRef2.getObjectId(), db.resolve(remoteBranch2));
214 }
215
216 @Test
217 public void fetchShouldAutoFollowTag() throws Exception {
218 remoteGit.commit().setMessage("commit").call();
219 Ref tagRef = remoteGit.tag().setName("foo").call();
220
221 git.fetch().setRemote("test")
222 .setRefSpecs("refs/heads/*:refs/remotes/origin/*")
223 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
224
225 assertEquals(tagRef.getObjectId(), db.resolve("foo"));
226 }
227
228 @Test
229 public void fetchShouldAutoFollowTagForFetchedObjects() throws Exception {
230 remoteGit.commit().setMessage("commit").call();
231 Ref tagRef = remoteGit.tag().setName("foo").call();
232 remoteGit.commit().setMessage("commit2").call();
233 git.fetch().setRemote("test")
234 .setRefSpecs("refs/heads/*:refs/remotes/origin/*")
235 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
236 assertEquals(tagRef.getObjectId(), db.resolve("foo"));
237 }
238
239 @Test
240 public void fetchShouldNotFetchTagsFromOtherBranches() throws Exception {
241 remoteGit.commit().setMessage("commit").call();
242 remoteGit.checkout().setName("other").setCreateBranch(true).call();
243 remoteGit.commit().setMessage("commit2").call();
244 remoteGit.tag().setName("foo").call();
245 git.fetch().setRemote("test")
246 .setRefSpecs("refs/heads/master:refs/remotes/origin/master")
247 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
248 assertNull(db.resolve("foo"));
249 }
250
251 @Test
252 public void fetchWithUpdatedTagShouldNotTryToUpdateLocal() throws Exception {
253 final String tagName = "foo";
254 remoteGit.commit().setMessage("commit").call();
255 Ref tagRef = remoteGit.tag().setName(tagName).call();
256 ObjectId originalId = tagRef.getObjectId();
257
258 String spec = "refs/heads/*:refs/remotes/origin/*";
259 git.fetch().setRemote("test").setRefSpecs(spec)
260 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
261 assertEquals(originalId, db.resolve(tagName));
262
263 remoteGit.commit().setMessage("commit 2").call();
264 remoteGit.tag().setName(tagName).setForceUpdate(true).call();
265
266 FetchResult result = git.fetch().setRemote("test").setRefSpecs(spec)
267 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
268
269 Collection<TrackingRefUpdate> refUpdates = result
270 .getTrackingRefUpdates();
271 assertEquals(1, refUpdates.size());
272 TrackingRefUpdate update = refUpdates.iterator().next();
273 assertEquals("refs/heads/master", update.getRemoteName());
274
275 assertEquals(originalId, db.resolve(tagName));
276 }
277
278 @Test
279 public void fetchWithExplicitTagsShouldUpdateLocal() throws Exception {
280 final String tagName = "foo";
281 remoteGit.commit().setMessage("commit").call();
282 Ref tagRef1 = remoteGit.tag().setName(tagName).call();
283
284 String spec = "refs/heads/*:refs/remotes/origin/*";
285 git.fetch().setRemote("test").setRefSpecs(spec)
286 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
287 assertEquals(tagRef1.getObjectId(), db.resolve(tagName));
288
289 remoteGit.commit().setMessage("commit 2").call();
290 Ref tagRef2 = remoteGit.tag().setName(tagName).setForceUpdate(true)
291 .call();
292
293 FetchResult result = git.fetch().setRemote("test").setRefSpecs(spec)
294 .setTagOpt(TagOpt.FETCH_TAGS).call();
295 TrackingRefUpdate update = result.getTrackingRefUpdate(Constants.R_TAGS
296 + tagName);
297 assertEquals(RefUpdate.Result.FORCED, update.getResult());
298 assertEquals(tagRef2.getObjectId(), db.resolve(tagName));
299 }
300
301 @Test
302 public void testFetchWithPruneShouldKeepOriginHead() throws Exception {
303
304 commitFile("foo", "foo", "master");
305
306 Git cloned = Git.cloneRepository()
307 .setDirectory(createTempDirectory("testCloneRepository"))
308 .setURI("file://"
309 + git.getRepository().getWorkTree().getAbsolutePath())
310 .call();
311 assertNotNull(cloned);
312 Repository clonedRepo = cloned.getRepository();
313 addRepoToClose(clonedRepo);
314 ObjectId originMasterId = clonedRepo
315 .resolve("refs/remotes/origin/master");
316 assertNotNull("Should have origin/master", originMasterId);
317 assertNotEquals("origin/master should not be zero ID",
318 ObjectId.zeroId(), originMasterId);
319
320
321 ObjectId originHeadId = clonedRepo.resolve("refs/remotes/origin/HEAD");
322 if (originHeadId == null) {
323 JGitTestUtil.write(
324 new File(clonedRepo.getDirectory(),
325 "refs/remotes/origin/HEAD"),
326 "ref: refs/remotes/origin/master\n");
327 originHeadId = clonedRepo.resolve("refs/remotes/origin/HEAD");
328 }
329 assertEquals("Should have origin/HEAD", originMasterId, originHeadId);
330 FetchResult result = cloned.fetch().setRemote("origin")
331 .setRemoveDeletedRefs(true).call();
332 assertTrue("Fetch after clone should be up-to-date",
333 result.getTrackingRefUpdates().isEmpty());
334 assertEquals("origin/master should still exist", originMasterId,
335 clonedRepo.resolve("refs/remotes/origin/master"));
336 assertEquals("origin/HEAD should be unchanged", originHeadId,
337 clonedRepo.resolve("refs/remotes/origin/HEAD"));
338 }
339
340 @Test
341 public void fetchAddRefsWithDuplicateRefspec() throws Exception {
342 final String branchName = "branch";
343 final String remoteBranchName = "test/" + branchName;
344 remoteGit.commit().setMessage("commit").call();
345 Ref branchRef = remoteGit.branchCreate().setName(branchName).call();
346
347 final String spec1 = "+refs/heads/*:refs/remotes/test/*";
348 final String spec2 = "refs/heads/*:refs/remotes/test/*";
349 final StoredConfig config = db.getConfig();
350 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
351 remoteConfig.addFetchRefSpec(new RefSpec(spec1));
352 remoteConfig.addFetchRefSpec(new RefSpec(spec2));
353 remoteConfig.update(config);
354
355 git.fetch().setRemote("test").setRefSpecs(spec1).call();
356 assertEquals(branchRef.getObjectId(), db.resolve(remoteBranchName));
357 }
358
359 @Test
360 public void fetchPruneRefsWithDuplicateRefspec()
361 throws Exception {
362 final String branchName = "branch";
363 final String remoteBranchName = "test/" + branchName;
364 remoteGit.commit().setMessage("commit").call();
365 Ref branchRef = remoteGit.branchCreate().setName(branchName).call();
366
367 final String spec1 = "+refs/heads/*:refs/remotes/test/*";
368 final String spec2 = "refs/heads/*:refs/remotes/test/*";
369 final StoredConfig config = db.getConfig();
370 RemoteConfig remoteConfig = new RemoteConfig(config, "test");
371 remoteConfig.addFetchRefSpec(new RefSpec(spec1));
372 remoteConfig.addFetchRefSpec(new RefSpec(spec2));
373 remoteConfig.update(config);
374
375 git.fetch().setRemote("test").setRefSpecs(spec1).call();
376 assertEquals(branchRef.getObjectId(), db.resolve(remoteBranchName));
377
378 remoteGit.branchDelete().setBranchNames(branchName).call();
379 git.fetch().setRemote("test").setRefSpecs(spec1)
380 .setRemoveDeletedRefs(true).call();
381 assertNull(db.resolve(remoteBranchName));
382 }
383
384 @Test
385 public void fetchUpdateRefsWithDuplicateRefspec() throws Exception {
386 final String tagName = "foo";
387 remoteGit.commit().setMessage("commit").call();
388 Ref tagRef1 = remoteGit.tag().setName(tagName).call();
389 List<RefSpec> refSpecs = new ArrayList<>();
390 refSpecs.add(new RefSpec("+refs/heads/*:refs/remotes/origin/*"));
391 refSpecs.add(new RefSpec("+refs/tags/*:refs/tags/*"));
392
393
394
395 git.fetch().setRemote("test").setRefSpecs(refSpecs)
396 .setTagOpt(TagOpt.AUTO_FOLLOW).call();
397 assertEquals(tagRef1.getObjectId(), db.resolve(tagName));
398
399 remoteGit.commit().setMessage("commit 2").call();
400 Ref tagRef2 = remoteGit.tag().setName(tagName).setForceUpdate(true)
401 .call();
402 FetchResult result = git.fetch().setRemote("test").setRefSpecs(refSpecs)
403 .setTagOpt(TagOpt.FETCH_TAGS).call();
404 assertEquals(2, result.getTrackingRefUpdates().size());
405 TrackingRefUpdate update = result
406 .getTrackingRefUpdate(Constants.R_TAGS + tagName);
407 assertEquals(RefUpdate.Result.FORCED, update.getResult());
408 assertEquals(tagRef2.getObjectId(), db.resolve(tagName));
409 }
410 }