diff --git a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java index 044f08072..8f44620b8 100644 --- a/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java +++ b/org.eclipse.jgit.junit/src/org/eclipse/jgit/junit/RepositoryTestCase.java @@ -197,14 +197,14 @@ protected void deleteTrashFile(final String name) throws IOException { */ protected static void checkFile(File f, final String checkData) throws IOException { - Reader r = new InputStreamReader(new FileInputStream(f), "UTF-8"); - try { - char[] data = new char[checkData.length()]; - if (checkData.length() != r.read(data)) - throw new IOException("Internal error reading file data from "+f); - assertEquals(checkData, new String(data)); - } finally { - r.close(); + try (Reader r = new InputStreamReader(new FileInputStream(f), + "UTF-8")) { + if (checkData.length() > 0) { + char[] data = new char[checkData.length()]; + assertEquals(data.length, r.read(data)); + assertEquals(checkData, new String(data)); + } + assertEquals(-1, r.read()); } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java index 3272d598b..a88efd175 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java @@ -387,6 +387,35 @@ public void mergeWithCrlfInWT(MergeStrategy strategy) throws IOException, mergeResult.getMergeStatus()); } + @Theory + public void mergeWithCrlfAutoCrlfTrue(MergeStrategy strategy) + throws IOException, GitAPIException { + Git git = Git.wrap(db); + db.getConfig().setString("core", null, "autocrlf", "true"); + db.getConfig().save(); + writeTrashFile("crlf.txt", "a crlf file\r\n"); + git.add().addFilepattern("crlf.txt").call(); + git.commit().setMessage("base").call(); + + git.branchCreate().setName("brancha").call(); + + writeTrashFile("crlf.txt", "a crlf file\r\na second line\r\n"); + git.add().addFilepattern("crlf.txt").call(); + git.commit().setMessage("on master").call(); + + git.checkout().setName("brancha").call(); + File testFile = writeTrashFile("crlf.txt", + "a first line\r\na crlf file\r\n"); + git.add().addFilepattern("crlf.txt").call(); + git.commit().setMessage("on brancha").call(); + + MergeResult mergeResult = git.merge().setStrategy(strategy) + .include(db.resolve("master")).call(); + assertEquals(MergeResult.MergeStatus.MERGED, + mergeResult.getMergeStatus()); + checkFile(testFile, "a first line\r\na crlf file\r\na second line\r\n"); + } + /** * Merging two equal subtrees when the index does not contain any file in * that subtree should lead to a merged state. diff --git a/org.eclipse.jgit/.settings/.api_filters b/org.eclipse.jgit/.settings/.api_filters new file mode 100644 index 000000000..293c60bb0 --- /dev/null +++ b/org.eclipse.jgit/.settings/.api_filters @@ -0,0 +1,11 @@ + + + + + + + + + + + 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 5646529dd..b40c19278 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java @@ -87,6 +87,7 @@ import org.eclipse.jgit.errors.NoWorkTreeException; import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.ConfigConstants; +import org.eclipse.jgit.lib.CoreConfig.EolStreamType; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; @@ -99,10 +100,13 @@ import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.treewalk.NameConflictTreeWalk; import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.TreeWalk.OperationType; import org.eclipse.jgit.treewalk.WorkingTreeIterator; +import org.eclipse.jgit.treewalk.WorkingTreeOptions; import org.eclipse.jgit.treewalk.filter.TreeFilter; import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.TemporaryBuffer; +import org.eclipse.jgit.util.io.EolStreamTypeUtil; /** * A three-way merger performing a content-merge if necessary @@ -277,8 +281,16 @@ public enum MergeFailureReason { protected MergeAlgorithm mergeAlgorithm; /** - * The size limit (bytes) which controls a file to be stored in {@code Heap} or - * {@code LocalFile} during the merge. + * The {@link WorkingTreeOptions} are needed to determine line endings for + * merged files. + * + * @since 4.11 + */ + protected WorkingTreeOptions workingTreeOptions; + + /** + * The size limit (bytes) which controls a file to be stored in {@code Heap} + * or {@code LocalFile} during the merge. */ private int inCoreLimit; @@ -319,6 +331,7 @@ protected ResolveMerger(Repository local, boolean inCore) { dircache = DirCache.newInCore(); } else { implicitDirCache = true; + workingTreeOptions = local.getConfig().get(WorkingTreeOptions.KEY); } } @@ -916,10 +929,15 @@ private File writeMergedFile(MergeResult result) FS fs = nonNullRepo().getFS(); File of = new File(workTree, tw.getPathString()); File parentFolder = of.getParentFile(); - if (!fs.exists(parentFolder)) + if (!fs.exists(parentFolder)) { parentFolder.mkdirs(); - try (OutputStream os = new BufferedOutputStream( - new FileOutputStream(of))) { + } + EolStreamType streamType = EolStreamTypeUtil.detectStreamType( + OperationType.CHECKOUT_OP, workingTreeOptions, + tw.getAttributes()); + try (OutputStream os = EolStreamTypeUtil.wrapOutputStream( + new BufferedOutputStream(new FileOutputStream(of)), + streamType)) { new MergeFormatter().formatMerge(os, result, Arrays.asList(commitNames), CHARACTER_ENCODING); }