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.assertFalse;
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.ByteArrayOutputStream;
52 import java.io.File;
53 import java.io.FileInputStream;
54 import java.io.FileOutputStream;
55 import java.io.IOException;
56
57 import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode;
58 import org.eclipse.jgit.api.MergeResult.MergeStatus;
59 import org.eclipse.jgit.api.RebaseResult.Status;
60 import org.eclipse.jgit.junit.RepositoryTestCase;
61 import org.eclipse.jgit.lib.ConfigConstants;
62 import org.eclipse.jgit.lib.Constants;
63 import org.eclipse.jgit.lib.ObjectId;
64 import org.eclipse.jgit.lib.Repository;
65 import org.eclipse.jgit.lib.RepositoryState;
66 import org.eclipse.jgit.lib.StoredConfig;
67 import org.eclipse.jgit.merge.MergeStrategy;
68 import org.eclipse.jgit.revwalk.RevCommit;
69 import org.eclipse.jgit.revwalk.RevWalk;
70 import org.eclipse.jgit.transport.RefSpec;
71 import org.eclipse.jgit.transport.RemoteConfig;
72 import org.eclipse.jgit.transport.URIish;
73 import org.junit.Before;
74 import org.junit.Test;
75
76 public class PullCommandWithRebaseTest extends RepositoryTestCase {
77
78 protected Repository dbTarget;
79
80 private Git source;
81
82 private Git target;
83
84 private File sourceFile;
85
86 private File targetFile;
87
88 @Test
89 public void testPullFastForward() throws Exception {
90 PullResult res = target.pull().call();
91
92 assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty());
93 assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());
94
95 assertFileContentsEqual(targetFile, "Hello world");
96
97
98 writeToFile(sourceFile, "Another change");
99 source.add().addFilepattern("SomeFile.txt").call();
100 source.commit().setMessage("Some change in remote").call();
101
102 res = target.pull().call();
103
104 assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty());
105 assertEquals(Status.FAST_FORWARD, res.getRebaseResult().getStatus());
106 assertFileContentsEqual(targetFile, "Another change");
107 assertEquals(RepositoryState.SAFE, target.getRepository()
108 .getRepositoryState());
109
110 res = target.pull().call();
111 assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());
112 }
113
114 @Test
115 public void testPullFastForwardWithBranchInSource() throws Exception {
116 PullResult res = target.pull().call();
117
118 assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty());
119 assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());
120
121 assertFileContentsEqual(targetFile, "Hello world");
122
123
124 writeToFile(sourceFile, "Another change\n\n\n\nFoo");
125 source.add().addFilepattern("SomeFile.txt").call();
126 RevCommit initialCommit = source.commit()
127 .setMessage("Some change in remote").call();
128
129
130 createBranch(initialCommit, "refs/heads/side");
131 checkoutBranch("refs/heads/side");
132 writeToFile(sourceFile, "Another change\n\n\n\nBoo");
133 source.add().addFilepattern("SomeFile.txt").call();
134 RevCommit sideCommit = source.commit()
135 .setMessage("Some change in remote").call();
136
137
138 checkoutBranch("refs/heads/master");
139 writeToFile(sourceFile, "More change\n\n\n\nFoo");
140 source.add().addFilepattern("SomeFile.txt").call();
141 source.commit().setMessage("Some change in remote").call();
142
143
144 MergeResult result = source.merge().include(sideCommit.getId())
145 .setStrategy(MergeStrategy.RESOLVE).call();
146 assertEquals(MergeStatus.MERGED, result.getMergeStatus());
147
148 }
149
150 @Test
151 public void testPullConflict() throws Exception {
152 PullResult res = target.pull().call();
153
154 assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty());
155 assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());
156
157 assertFileContentsEqual(targetFile, "Hello world");
158
159
160 writeToFile(sourceFile, "Source change");
161 source.add().addFilepattern("SomeFile.txt").call();
162 source.commit().setMessage("Source change in remote").call();
163
164
165 writeToFile(targetFile, "Target change");
166 target.add().addFilepattern("SomeFile.txt").call();
167 target.commit().setMessage("Target change in local").call();
168
169 res = target.pull().call();
170
171 String remoteUri = target
172 .getRepository()
173 .getConfig()
174 .getString(ConfigConstants.CONFIG_REMOTE_SECTION, "origin",
175 ConfigConstants.CONFIG_KEY_URL);
176
177 assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty());
178 assertEquals(Status.STOPPED, res.getRebaseResult().getStatus());
179 String result = "<<<<<<< Upstream, based on branch 'master' of "
180 + remoteUri
181 + "\nSource change\n=======\nTarget change\n>>>>>>> 42453fd Target change in local\n";
182 assertFileContentsEqual(targetFile, result);
183 assertEquals(RepositoryState.REBASING_MERGE, target
184 .getRepository().getRepositoryState());
185 }
186
187 @Test
188 public void testPullLocalConflict() throws Exception {
189 target.branchCreate().setName("basedOnMaster").setStartPoint(
190 "refs/heads/master").setUpstreamMode(SetupUpstreamMode.NOTRACK)
191 .call();
192 StoredConfig config = target.getRepository().getConfig();
193 config.setString("branch", "basedOnMaster", "remote", ".");
194 config.setString("branch", "basedOnMaster", "merge",
195 "refs/heads/master");
196 config.setBoolean("branch", "basedOnMaster", "rebase", true);
197 config.save();
198 target.getRepository().updateRef(Constants.HEAD).link(
199 "refs/heads/basedOnMaster");
200 PullResult res = target.pull().call();
201
202 assertNull(res.getFetchResult());
203 assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus());
204
205 assertFileContentsEqual(targetFile, "Hello world");
206
207
208 target.getRepository().updateRef(Constants.HEAD).link(
209 "refs/heads/master");
210 writeToFile(targetFile, "Master change");
211 target.add().addFilepattern("SomeFile.txt").call();
212 target.commit().setMessage("Source change in master").call();
213
214
215 target.getRepository().updateRef(Constants.HEAD).link(
216 "refs/heads/basedOnMaster");
217 writeToFile(targetFile, "Slave change");
218 target.add().addFilepattern("SomeFile.txt").call();
219 target.commit().setMessage("Source change in based on master").call();
220
221 res = target.pull().call();
222
223 assertNull(res.getFetchResult());
224 assertEquals(Status.STOPPED, res.getRebaseResult().getStatus());
225 String result = "<<<<<<< Upstream, based on branch 'master' of local repository\n"
226 + "Master change\n=======\nSlave change\n>>>>>>> 4049c9e Source change in based on master\n";
227 assertFileContentsEqual(targetFile, result);
228 assertEquals(RepositoryState.REBASING_MERGE, target
229 .getRepository().getRepositoryState());
230 }
231
232 @Test
233 public void testPullFastForwardWithLocalCommitAndRebaseFlagSet() throws Exception {
234 final String SOURCE_COMMIT_MESSAGE = "Source commit message for rebase flag test";
235 final String TARGET_COMMIT_MESSAGE = "Target commit message for rebase flag test";
236
237 assertFalse(SOURCE_COMMIT_MESSAGE.equals(TARGET_COMMIT_MESSAGE));
238
239 final String SOURCE_FILE_CONTENTS = "Source change";
240 final String NEW_FILE_CONTENTS = "New file from target";
241
242
243
244 StoredConfig targetConfig = dbTarget.getConfig();
245 targetConfig.setBoolean("branch", "master", "rebase", false);
246 targetConfig.save();
247
248
249 writeToFile(sourceFile, SOURCE_FILE_CONTENTS);
250 source.add().addFilepattern(sourceFile.getName()).call();
251 source.commit().setMessage(SOURCE_COMMIT_MESSAGE).call();
252
253
254 File newFile = new File(dbTarget.getWorkTree().getPath() + "/newFile.txt");
255 writeToFile(newFile, NEW_FILE_CONTENTS);
256 target.add().addFilepattern(newFile.getName()).call();
257 target.commit().setMessage(TARGET_COMMIT_MESSAGE).call();
258
259
260 assertFalse(targetConfig.getBoolean("branch", "master", "rebase", true));
261
262
263 PullResult pullResult = target.pull().setRebase(true).call();
264
265
266 assertTrue(pullResult.isSuccessful());
267
268
269 RebaseResult rebaseResult = pullResult.getRebaseResult();
270 assertNotNull(rebaseResult);
271 assertNull(rebaseResult.getFailingPaths());
272 assertEquals(Status.OK, rebaseResult.getStatus());
273
274
275 Repository targetRepo = target.getRepository();
276 RevWalk revWalk = new RevWalk(targetRepo);
277 ObjectId headId = targetRepo.resolve(Constants.HEAD);
278 RevCommit root = revWalk.parseCommit(headId);
279 revWalk.markStart(root);
280
281 RevCommit head = revWalk.next();
282
283 RevCommit beforeHead = revWalk.next();
284
285
286 assertEquals(TARGET_COMMIT_MESSAGE, head.getFullMessage());
287
288 assertEquals(SOURCE_COMMIT_MESSAGE, beforeHead.getFullMessage());
289
290
291 assertFileContentsEqual(sourceFile, SOURCE_FILE_CONTENTS);
292 assertFileContentsEqual(newFile, NEW_FILE_CONTENTS);
293
294 assertEquals(RepositoryState.SAFE, target
295 .getRepository().getRepositoryState());
296 }
297
298 @Override
299 @Before
300 public void setUp() throws Exception {
301 super.setUp();
302 dbTarget = createWorkRepository();
303 source = new Git(db);
304 target = new Git(dbTarget);
305
306
307 sourceFile = new File(db.getWorkTree(), "SomeFile.txt");
308 writeToFile(sourceFile, "Hello world");
309
310 source.add().addFilepattern("SomeFile.txt").call();
311 source.commit().setMessage("Initial commit for source").call();
312
313
314 StoredConfig targetConfig = dbTarget.getConfig();
315 targetConfig.setString("branch", "master", "remote", "origin");
316 targetConfig
317 .setString("branch", "master", "merge", "refs/heads/master");
318 RemoteConfig config = new RemoteConfig(targetConfig, "origin");
319
320 config
321 .addURI(new URIish(source.getRepository().getWorkTree()
322 .getAbsolutePath()));
323 config.addFetchRefSpec(new RefSpec(
324 "+refs/heads/*:refs/remotes/origin/*"));
325 config.update(targetConfig);
326 targetConfig.save();
327
328 targetFile = new File(dbTarget.getWorkTree(), "SomeFile.txt");
329
330 target.pull().call();
331 target.checkout().setStartPoint("refs/remotes/origin/master").setName(
332 "master").call();
333
334 targetConfig
335 .setString("branch", "master", "merge", "refs/heads/master");
336 targetConfig.setBoolean("branch", "master", "rebase", true);
337 targetConfig.save();
338
339 assertFileContentsEqual(targetFile, "Hello world");
340 }
341
342 private static void writeToFile(File actFile, String string)
343 throws IOException {
344 FileOutputStream fos = null;
345 try {
346 fos = new FileOutputStream(actFile);
347 fos.write(string.getBytes("UTF-8"));
348 fos.close();
349 } finally {
350 if (fos != null)
351 fos.close();
352 }
353 }
354
355 private static void assertFileContentsEqual(File actFile, String string)
356 throws IOException {
357 ByteArrayOutputStream bos = new ByteArrayOutputStream();
358 FileInputStream fis = null;
359 byte[] buffer = new byte[100];
360 try {
361 fis = new FileInputStream(actFile);
362 int read = fis.read(buffer);
363 while (read > 0) {
364 bos.write(buffer, 0, read);
365 read = fis.read(buffer);
366 }
367 String content = new String(bos.toByteArray(), "UTF-8");
368 assertEquals(string, content);
369 } finally {
370 if (fis != null)
371 fis.close();
372 }
373 }
374 }