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:
commit
f1019b9738
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
19
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>
|
||||
|
||||
|
|
Loading…
Reference in New Issue