Merge branch 'stable-1.2'

* stable-1.2:
  Add API checking using clirr
  Fix MergeCommandTest to pass if File.executable is not supported
  Fix ResolveMerger not to add paths with FileMode 0

Change-Id: I86e7194a40acd6dfa3d433f1d17c01bdf5bb0d9c
Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
This commit is contained in:
Matthias Sohn 2011-12-16 08:49:59 +01:00
commit f1019b9738
8 changed files with 273 additions and 7 deletions

View File

@ -110,6 +110,25 @@
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>${clirr-version}</version>
<configuration>
<comparisonVersion>${jgit-last-release-version}</comparisonVersion>
<minSeverity>info</minSeverity>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -108,6 +108,25 @@
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>${clirr-version}</version>
<configuration>
<comparisonVersion>${jgit-last-release-version}</comparisonVersion>
<minSeverity>info</minSeverity>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -125,6 +125,25 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>${clirr-version}</version>
<configuration>
<comparisonVersion>${jgit-last-release-version}</comparisonVersion>
<minSeverity>info</minSeverity>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -157,6 +157,25 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>${clirr-version}</version>
<configuration>
<comparisonVersion>${jgit-last-release-version}</comparisonVersion>
<minSeverity>info</minSeverity>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -60,6 +60,7 @@
import org.eclipse.jgit.merge.MergeStrategy;
import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
import org.junit.Test;
import org.junit.experimental.theories.DataPoints;
@ -1023,6 +1024,88 @@ public void testMergeRemovingFolders() throws Exception {
assertFalse(folder2.exists());
}
@Test
public void testFileModeMerge() throws Exception {
if (!FS.DETECTED.supportsExecute())
return;
// Only Java6
Git git = new Git(db);
writeTrashFile("mergeableMode", "a");
setExecutable(git, "mergeableMode", false);
writeTrashFile("conflictingModeWithBase", "a");
setExecutable(git, "conflictingModeWithBase", false);
RevCommit initialCommit = addAllAndCommit(git);
// switch branch
createBranch(initialCommit, "refs/heads/side");
checkoutBranch("refs/heads/side");
setExecutable(git, "mergeableMode", true);
writeTrashFile("conflictingModeNoBase", "b");
setExecutable(git, "conflictingModeNoBase", true);
RevCommit sideCommit = addAllAndCommit(git);
// switch branch
createBranch(initialCommit, "refs/heads/side2");
checkoutBranch("refs/heads/side2");
setExecutable(git, "mergeableMode", false);
assertFalse(new File(git.getRepository().getWorkTree(),
"conflictingModeNoBase").exists());
writeTrashFile("conflictingModeNoBase", "b");
setExecutable(git, "conflictingModeNoBase", false);
addAllAndCommit(git);
// merge
MergeResult result = git.merge().include(sideCommit.getId())
.setStrategy(MergeStrategy.RESOLVE).call();
assertEquals(MergeStatus.CONFLICTING, result.getMergeStatus());
assertTrue(canExecute(git, "mergeableMode"));
assertFalse(canExecute(git, "conflictingModeNoBase"));
}
@Test
public void testFileModeMergeWithDirtyWorkTree() throws Exception {
if (!FS.DETECTED.supportsExecute())
return;
// Only Java6 (or set x bit in index)
Git git = new Git(db);
writeTrashFile("mergeableButDirty", "a");
setExecutable(git, "mergeableButDirty", false);
RevCommit initialCommit = addAllAndCommit(git);
// switch branch
createBranch(initialCommit, "refs/heads/side");
checkoutBranch("refs/heads/side");
setExecutable(git, "mergeableButDirty", true);
RevCommit sideCommit = addAllAndCommit(git);
// switch branch
createBranch(initialCommit, "refs/heads/side2");
checkoutBranch("refs/heads/side2");
setExecutable(git, "mergeableButDirty", false);
addAllAndCommit(git);
writeTrashFile("mergeableButDirty", "b");
// merge
MergeResult result = git.merge().include(sideCommit.getId())
.setStrategy(MergeStrategy.RESOLVE).call();
assertEquals(MergeStatus.FAILED, result.getMergeStatus());
assertFalse(canExecute(git, "mergeableButDirty"));
}
private void setExecutable(Git git, String path, boolean executable) {
FS.DETECTED.setExecute(
new File(git.getRepository().getWorkTree(), path), executable);
}
private boolean canExecute(Git git, String path) {
return FS.DETECTED.canExecute(new File(git.getRepository()
.getWorkTree(), path));
}
private RevCommit addAllAndCommit(final Git git) throws Exception {
git.add().addFilepattern(".").call();
return git.commit().setMessage("message").call();

View File

@ -142,7 +142,13 @@
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
</plugin>
</plugins>
<pluginManagement>
<plugins>
<plugin>
@ -155,4 +161,18 @@
</plugins>
</pluginManagement>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>${clirr-version}</version>
<configuration>
<comparisonVersion>${jgit-last-release-version}</comparisonVersion>
<minSeverity>info</minSeverity>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

View File

@ -51,6 +51,7 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@ -378,12 +379,46 @@ private boolean processEntry(CanonicalTreeParser base,
if (isIndexDirty())
return false;
if (nonTree(modeO) && modeO == modeT && tw.idEqual(T_OURS, T_THEIRS)) {
// OURS and THEIRS are equal: it doesn't matter which one we choose.
// OURS is chosen.
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0);
// no checkout needed!
return true;
if (nonTree(modeO) && nonTree(modeT) && tw.idEqual(T_OURS, T_THEIRS)) {
// OURS and THEIRS have equal content. Check the file mode
if (modeO == modeT) {
// content and mode of OURS and THEIRS are equal: it doesn't
// matter which one we choose. OURS is chosen.
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0);
// no checkout needed!
return true;
} else {
// same content but different mode on OURS and THEIRS.
// Try to merge the mode and report an error if this is
// not possible.
int newMode = mergeFileModes(modeB, modeO, modeT);
if (newMode != FileMode.MISSING.getBits()) {
if (newMode == modeO)
// ours version is preferred
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0);
else {
// the preferred version THEIRS has a different mode
// than ours. Check it out!
if (isWorktreeDirty())
return false;
DirCacheEntry e = add(tw.getRawPath(), theirs,
DirCacheEntry.STAGE_0);
toBeCheckedOut.put(tw.getPathString(), e);
}
return true;
} else {
// FileModes are not mergeable. We found a conflict on modes
add(tw.getRawPath(), base, DirCacheEntry.STAGE_1);
add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2);
add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3);
unmergedPaths.add(tw.getPathString());
mergeResults.put(
tw.getPathString(),
new MergeResult<RawText>(Collections
.<RawText> emptyList()));
}
return true;
}
}
if (nonTree(modeO) && modeB == modeT && tw.idEqual(T_BASE, T_THEIRS)) {
@ -582,7 +617,12 @@ else if (!result.containsConflicts()) {
// no conflict occurred, the file will contain fully merged content.
// the index will be populated with the new merged version
DirCacheEntry dce = new DirCacheEntry(tw.getPathString());
dce.setFileMode(tw.getFileMode(0));
int newMode = mergeFileModes(tw.getRawMode(0), tw.getRawMode(1),
tw.getRawMode(2));
// set the mode for the new content. Fall back to REGULAR_FILE if
// you can't merge modes of OURS and THEIRS
dce.setFileMode((newMode == FileMode.MISSING.getBits()) ? FileMode.REGULAR_FILE
: FileMode.fromBits(newMode));
dce.setLastModified(of.lastModified());
dce.setLength((int) of.length());
InputStream is = new FileInputStream(of);
@ -599,6 +639,34 @@ else if (!result.containsConflicts()) {
}
}
/**
* Try to merge filemodes. If only ours or theirs have changed the mode
* (compared to base) we choose that one. If ours and theirs have equal
* modes return that one. If also that is not the case the modes are not
* mergeable. Return {@link FileMode#MISSING} int that case.
*
* @param modeB
* filemode found in BASE
* @param modeO
* filemode found in OURS
* @param modeT
* filemode found in THEIRS
*
* @return the merged filemode or {@link FileMode#MISSING} in case of a
* conflict
*/
private int mergeFileModes(int modeB, int modeO, int modeT) {
if (modeO == modeT)
return modeO;
if (modeB == modeO)
// Base equal to Ours -> chooses Theirs if that is not missing
return (modeT == FileMode.MISSING.getBits()) ? modeO : modeT;
if (modeB == modeT)
// Base equal to Theirs -> chooses Ours if that is not missing
return (modeO == FileMode.MISSING.getBits()) ? modeT : modeO;
return FileMode.MISSING.getBits();
}
private static RawText getRawText(ObjectId id, Repository db)
throws IOException {
if (id.equals(ObjectId.zeroId()))

19
pom.xml
View File

@ -130,14 +130,23 @@
<maven.build.timestamp.format>yyyyMMddHHmm</maven.build.timestamp.format>
<bundle-manifest>${project.build.directory}/META-INF/MANIFEST.MF</bundle-manifest>
<jgit-last-release-version>1.1.0.201109151100-r</jgit-last-release-version>
<jsch-version>0.1.44-1</jsch-version>
<junit-version>4.5</junit-version>
<args4j-version>2.0.12</args4j-version>
<servlet-api-version>2.5</servlet-api-version>
<jetty-version>7.1.6.v20100715</jetty-version>
<protobuf-version>2.4.0a</protobuf-version>
<clirr-version>2.3</clirr-version>
</properties>
<repositories>
<repository>
<id>jgit-repository</id>
<url>http://download.eclipse.org/jgit/maven</url>
</repository>
</repositories>
<build>
<pluginManagement>
<plugins>
@ -246,6 +255,16 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>clirr-maven-plugin</artifactId>
<version>${clirr-version}</version>
<configuration>
<comparisonVersion>${jgit-last-release-version}</comparisonVersion>
<minSeverity>info</minSeverity>
</configuration>
</plugin>
</plugins>
</pluginManagement>