Browse Source
Rebase must honor the upstream configuration branch.<branchname>.rebase Change-Id: Ic94f263d3f47b630ad75bd5412cb4741bb1109ca Signed-off-by: Mathias Kinzler <mathias.kinzler@sap.com>stable-0.11
Mathias Kinzler
14 years ago
4 changed files with 359 additions and 51 deletions
@ -0,0 +1,254 @@
|
||||
/* |
||||
* Copyright (C) 2011, Mathias Kinzler <mathias.kinzler@sap.com> |
||||
* and other copyright owners as documented in the project's IP log. |
||||
* |
||||
* This program and the accompanying materials are made available |
||||
* under the terms of the Eclipse Distribution License v1.0 which |
||||
* accompanies this distribution, is reproduced below, and is |
||||
* available at http://www.eclipse.org/org/documents/edl-v10.php
|
||||
* |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or |
||||
* without modification, are permitted provided that the following |
||||
* conditions are met: |
||||
* |
||||
* - Redistributions of source code must retain the above copyright |
||||
* notice, this list of conditions and the following disclaimer. |
||||
* |
||||
* - Redistributions in binary form must reproduce the above |
||||
* copyright notice, this list of conditions and the following |
||||
* disclaimer in the documentation and/or other materials provided |
||||
* with the distribution. |
||||
* |
||||
* - Neither the name of the Eclipse Foundation, Inc. nor the |
||||
* names of its contributors may be used to endorse or promote |
||||
* products derived from this software without specific prior |
||||
* written permission. |
||||
* |
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, |
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR |
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
*/ |
||||
package org.eclipse.jgit.api; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertFalse; |
||||
import static org.junit.Assert.assertNull; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import java.io.ByteArrayOutputStream; |
||||
import java.io.File; |
||||
import java.io.FileInputStream; |
||||
import java.io.FileOutputStream; |
||||
import java.io.IOException; |
||||
|
||||
import org.eclipse.jgit.api.CreateBranchCommand.SetupUpstreamMode; |
||||
import org.eclipse.jgit.api.RebaseResult.Status; |
||||
import org.eclipse.jgit.lib.Constants; |
||||
import org.eclipse.jgit.lib.RepositoryState; |
||||
import org.eclipse.jgit.lib.RepositoryTestCase; |
||||
import org.eclipse.jgit.lib.StoredConfig; |
||||
import org.eclipse.jgit.storage.file.FileRepository; |
||||
import org.eclipse.jgit.transport.RefSpec; |
||||
import org.eclipse.jgit.transport.RemoteConfig; |
||||
import org.eclipse.jgit.transport.URIish; |
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
|
||||
public class PullCommandWithRebaseTest extends RepositoryTestCase { |
||||
/** Second Test repository */ |
||||
protected FileRepository dbTarget; |
||||
|
||||
private Git source; |
||||
|
||||
private Git target; |
||||
|
||||
private File sourceFile; |
||||
|
||||
private File targetFile; |
||||
|
||||
@Test |
||||
public void testPullFastForward() throws Exception { |
||||
PullResult res = target.pull().call(); |
||||
// nothing to update since we don't have different data yet
|
||||
assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty()); |
||||
assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus()); |
||||
|
||||
assertFileContentsEqual(targetFile, "Hello world"); |
||||
|
||||
// change the source file
|
||||
writeToFile(sourceFile, "Another change"); |
||||
source.add().addFilepattern("SomeFile.txt").call(); |
||||
source.commit().setMessage("Some change in remote").call(); |
||||
|
||||
res = target.pull().call(); |
||||
|
||||
assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty()); |
||||
assertEquals(Status.FAST_FORWARD, res.getRebaseResult().getStatus()); |
||||
assertFileContentsEqual(targetFile, "Another change"); |
||||
assertEquals(RepositoryState.SAFE, target.getRepository() |
||||
.getRepositoryState()); |
||||
|
||||
res = target.pull().call(); |
||||
assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus()); |
||||
} |
||||
|
||||
@Test |
||||
public void testPullConflict() throws Exception { |
||||
PullResult res = target.pull().call(); |
||||
// nothing to update since we don't have different data yet
|
||||
assertTrue(res.getFetchResult().getTrackingRefUpdates().isEmpty()); |
||||
assertTrue(res.getRebaseResult().getStatus().equals(Status.UP_TO_DATE)); |
||||
|
||||
assertFileContentsEqual(targetFile, "Hello world"); |
||||
|
||||
// change the source file
|
||||
writeToFile(sourceFile, "Source change"); |
||||
source.add().addFilepattern("SomeFile.txt").call(); |
||||
source.commit().setMessage("Source change in remote").call(); |
||||
|
||||
// change the target file
|
||||
writeToFile(targetFile, "Target change"); |
||||
target.add().addFilepattern("SomeFile.txt").call(); |
||||
target.commit().setMessage("Target change in local").call(); |
||||
|
||||
res = target.pull().call(); |
||||
|
||||
assertFalse(res.getFetchResult().getTrackingRefUpdates().isEmpty()); |
||||
assertTrue(res.getRebaseResult().getStatus().equals(Status.STOPPED)); |
||||
String result = "<<<<<<< OURS\nSource change\n=======\nTarget change\n>>>>>>> THEIRS\n"; |
||||
assertFileContentsEqual(targetFile, result); |
||||
assertEquals(RepositoryState.REBASING_INTERACTIVE, target |
||||
.getRepository().getRepositoryState()); |
||||
} |
||||
|
||||
@Test |
||||
public void testPullLocalConflict() throws Exception { |
||||
target.branchCreate().setName("basedOnMaster").setStartPoint( |
||||
"refs/heads/master").setUpstreamMode(SetupUpstreamMode.NOTRACK) |
||||
.call(); |
||||
StoredConfig config = target.getRepository().getConfig(); |
||||
config.setString("branch", "basedOnMaster", "remote", "."); |
||||
config.setString("branch", "basedOnMaster", "rebase", |
||||
"refs/heads/master"); |
||||
config.save(); |
||||
target.getRepository().updateRef(Constants.HEAD).link( |
||||
"refs/heads/basedOnMaster"); |
||||
PullResult res = target.pull().call(); |
||||
// nothing to update since we don't have different data yet
|
||||
assertNull(res.getFetchResult()); |
||||
assertEquals(Status.UP_TO_DATE, res.getRebaseResult().getStatus()); |
||||
|
||||
assertFileContentsEqual(targetFile, "Hello world"); |
||||
|
||||
// change the file in master
|
||||
target.getRepository().updateRef(Constants.HEAD).link( |
||||
"refs/heads/master"); |
||||
writeToFile(targetFile, "Master change"); |
||||
target.add().addFilepattern("SomeFile.txt").call(); |
||||
target.commit().setMessage("Source change in master").call(); |
||||
|
||||
// change the file in slave
|
||||
target.getRepository().updateRef(Constants.HEAD).link( |
||||
"refs/heads/basedOnMaster"); |
||||
writeToFile(targetFile, "Slave change"); |
||||
target.add().addFilepattern("SomeFile.txt").call(); |
||||
target.commit().setMessage("Source change in based on master").call(); |
||||
|
||||
res = target.pull().call(); |
||||
|
||||
assertNull(res.getFetchResult()); |
||||
assertEquals(Status.STOPPED, res.getRebaseResult().getStatus()); |
||||
String result = "<<<<<<< OURS\nMaster change\n=======\nSlave change\n>>>>>>> THEIRS\n"; |
||||
assertFileContentsEqual(targetFile, result); |
||||
assertEquals(RepositoryState.REBASING_INTERACTIVE, target |
||||
.getRepository().getRepositoryState()); |
||||
} |
||||
|
||||
@Override |
||||
@Before |
||||
public void setUp() throws Exception { |
||||
super.setUp(); |
||||
dbTarget = createWorkRepository(); |
||||
source = new Git(db); |
||||
target = new Git(dbTarget); |
||||
|
||||
// put some file in the source repo
|
||||
sourceFile = new File(db.getWorkTree(), "SomeFile.txt"); |
||||
writeToFile(sourceFile, "Hello world"); |
||||
// and commit it
|
||||
source.add().addFilepattern("SomeFile.txt").call(); |
||||
source.commit().setMessage("Initial commit for source").call(); |
||||
|
||||
// configure the target repo to connect to the source via "origin"
|
||||
StoredConfig targetConfig = dbTarget.getConfig(); |
||||
targetConfig.setString("branch", "master", "remote", "origin"); |
||||
targetConfig |
||||
.setString("branch", "master", "merge", "refs/heads/master"); |
||||
RemoteConfig config = new RemoteConfig(targetConfig, "origin"); |
||||
|
||||
config |
||||
.addURI(new URIish(source.getRepository().getWorkTree() |
||||
.getPath())); |
||||
config.addFetchRefSpec(new RefSpec( |
||||
"+refs/heads/*:refs/remotes/origin/*")); |
||||
config.update(targetConfig); |
||||
targetConfig.save(); |
||||
|
||||
targetFile = new File(dbTarget.getWorkTree(), "SomeFile.txt"); |
||||
// make sure we have the same content
|
||||
target.pull().call(); |
||||
target.checkout().setStartPoint("refs/remotes/origin/master").setName( |
||||
"master").call(); |
||||
|
||||
targetConfig.setString("branch", "master", "rebase", |
||||
"refs/remotes/origin/master"); |
||||
targetConfig.unset("branch", "master", "merge"); |
||||
targetConfig.save(); |
||||
|
||||
assertFileContentsEqual(targetFile, "Hello world"); |
||||
} |
||||
|
||||
private void writeToFile(File actFile, String string) throws IOException { |
||||
FileOutputStream fos = null; |
||||
try { |
||||
fos = new FileOutputStream(actFile); |
||||
fos.write(string.getBytes("UTF-8")); |
||||
fos.close(); |
||||
} finally { |
||||
if (fos != null) |
||||
fos.close(); |
||||
} |
||||
} |
||||
|
||||
private void assertFileContentsEqual(File actFile, String string) |
||||
throws IOException { |
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream(); |
||||
FileInputStream fis = null; |
||||
byte[] buffer = new byte[100]; |
||||
try { |
||||
fis = new FileInputStream(actFile); |
||||
int read = fis.read(buffer); |
||||
while (read > 0) { |
||||
bos.write(buffer, 0, read); |
||||
read = fis.read(buffer); |
||||
} |
||||
String content = new String(bos.toByteArray(), "UTF-8"); |
||||
assertEquals(string, content); |
||||
} finally { |
||||
if (fis != null) |
||||
fis.close(); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue