summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Sohn <matthias.sohn@sap.com>2011-12-16 08:49:59 +0100
committerMatthias Sohn <matthias.sohn@sap.com>2011-12-16 08:50:49 +0100
commitf1019b9738089650ed24ae24a41e1567f28ea269 (patch)
tree332f582bff1d0854f8c5f9e5ec8a03dbd3f0e263
parent84c80be1dc45885969e2d0fa0421f709b8706453 (diff)
parent78ebffd5f4a65a098a2a41b241747c54905be63d (diff)
downloadjgit-f1019b9738089650ed24ae24a41e1567f28ea269.tar.gz
jgit-f1019b9738089650ed24ae24a41e1567f28ea269.zip
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>
-rw-r--r--org.eclipse.jgit.ant/pom.xml19
-rw-r--r--org.eclipse.jgit.console/pom.xml19
-rw-r--r--org.eclipse.jgit.http.server/pom.xml19
-rw-r--r--org.eclipse.jgit.storage.dht/pom.xml19
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java83
-rw-r--r--org.eclipse.jgit/pom.xml20
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java82
-rw-r--r--pom.xml19
8 files changed, 273 insertions, 7 deletions
diff --git a/org.eclipse.jgit.ant/pom.xml b/org.eclipse.jgit.ant/pom.xml
index fcd6f8918a..9a55466f4a 100644
--- a/org.eclipse.jgit.ant/pom.xml
+++ b/org.eclipse.jgit.ant/pom.xml
@@ -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>
diff --git a/org.eclipse.jgit.console/pom.xml b/org.eclipse.jgit.console/pom.xml
index c5573c54de..bd99d39cdb 100644
--- a/org.eclipse.jgit.console/pom.xml
+++ b/org.eclipse.jgit.console/pom.xml
@@ -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>
diff --git a/org.eclipse.jgit.http.server/pom.xml b/org.eclipse.jgit.http.server/pom.xml
index 94479ccf64..d4fc39eff7 100644
--- a/org.eclipse.jgit.http.server/pom.xml
+++ b/org.eclipse.jgit.http.server/pom.xml
@@ -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>
diff --git a/org.eclipse.jgit.storage.dht/pom.xml b/org.eclipse.jgit.storage.dht/pom.xml
index 83c1b857c2..06ca61d95b 100644
--- a/org.eclipse.jgit.storage.dht/pom.xml
+++ b/org.eclipse.jgit.storage.dht/pom.xml
@@ -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>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
index bb90588918..30a94520d1 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/MergeCommandTest.java
@@ -60,6 +60,7 @@ import org.eclipse.jgit.lib.RepositoryTestCase;
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 class MergeCommandTest extends RepositoryTestCase {
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();
diff --git a/org.eclipse.jgit/pom.xml b/org.eclipse.jgit/pom.xml
index b77a17a7a1..92f39acbe2 100644
--- a/org.eclipse.jgit/pom.xml
+++ b/org.eclipse.jgit/pom.xml
@@ -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>
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index b763568951..8211780ca1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -51,6 +51,7 @@ import java.io.IOException;
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 @@ public class ResolveMerger extends ThreeWayMerger {
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 @@ public class ResolveMerger extends ThreeWayMerger {
// 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 @@ public class ResolveMerger extends ThreeWayMerger {
}
}
+ /**
+ * 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()))
diff --git a/pom.xml b/pom.xml
index 15365b0977..b74db9ddc0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -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>