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