]> source.dussan.org Git - jgit.git/commitdiff
Fix index blob for merges with CRLF translations 74/116574/1
authorThomas Wolf <thomas.wolf@paranor.ch>
Fri, 2 Feb 2018 07:16:13 +0000 (08:16 +0100)
committerThomas Wolf <thomas.wolf@paranor.ch>
Fri, 2 Feb 2018 07:16:13 +0000 (08:16 +0100)
Commit fc7d407 corrected line endings for working tree files resulting
from merges when CRLF translations are to be done. However, that also
resulted in the file content being put as-is into the index, which is
wrong. The index must contain the file content with reverse CRLF
translations applied.

With core.autocrlf=true, the working tree file should have CR-LF, but
the index blob must still contain only LF.

Fix this oversight and apply the inverse translation when updating the
index, similar to what is done in AddCommand.

Bug: 499615
Change-Id: I3a33931318bdb580b2390f3450f91ea8f258a6a4
Signed-off-by: Thomas Wolf <thomas.wolf@paranor.ch>
org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java

index a88efd17555fc75f560d25b840b8c7f1b248bdc1..ab998ebfb8248b676b26610d9d60dc2eb44296cc 100644 (file)
@@ -414,6 +414,9 @@ public class ResolveMergerTest extends RepositoryTestCase {
                assertEquals(MergeResult.MergeStatus.MERGED,
                                mergeResult.getMergeStatus());
                checkFile(testFile, "a first line\r\na crlf file\r\na second line\r\n");
+               assertEquals(
+                               "[crlf.txt, mode:100644, content:a first line\na crlf file\na second line\n]",
+                               indexState(CONTENT));
        }
 
        /**
index b40c192783acc3b99e655768771a30b53cb84171..837528e8736d66f042d4bec8039be17b046b1c76 100644 (file)
@@ -51,6 +51,7 @@ import static org.eclipse.jgit.lib.ConfigConstants.CONFIG_KEY_ALGORITHM;
 import static org.eclipse.jgit.lib.Constants.CHARACTER_ENCODING;
 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
 
+import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -903,17 +904,54 @@ public class ResolveMerger extends ThreeWayMerger {
                        long len = mergedFile.length();
                        dce.setLastModified(FS.DETECTED.lastModified(mergedFile));
                        dce.setLength((int) len);
-                       InputStream is = new FileInputStream(mergedFile);
-                       try {
-                               dce.setObjectId(getObjectInserter().insert(OBJ_BLOB, len, is));
-                       } finally {
-                               is.close();
+                       EolStreamType streamType = EolStreamTypeUtil.detectStreamType(
+                                       OperationType.CHECKIN_OP, workingTreeOptions,
+                                       tw.getAttributes());
+                       long blobLen = len == 0 ? 0
+                                       : getEntryContentLength(mergedFile, streamType);
+                       // TODO: we read the file twice because insert() needs the blob
+                       // length up front. C.f. AddCommand.
+                       try (InputStream is = EolStreamTypeUtil.wrapInputStream(
+                                       new FileInputStream(mergedFile), streamType)) {
+                               dce.setObjectId(
+                                               getObjectInserter().insert(OBJ_BLOB, blobLen, is));
                        }
                } else
                        dce.setObjectId(insertMergeResult(result));
                builder.add(dce);
        }
 
+       /**
+        * Computes the length of the index blob for a given file.
+        *
+        * @param file
+        *            on disk
+        * @param streamType
+        *            specifying CRLF translation
+        * @return the number of bytes after CRLF translations have been done.
+        * @throws IOException
+        *             if the file cannot be read
+        */
+       private long getEntryContentLength(File file, EolStreamType streamType)
+                       throws IOException {
+               if (streamType == EolStreamType.DIRECT) {
+                       return file.length();
+               }
+               long length = 0;
+               try (InputStream is = EolStreamTypeUtil.wrapInputStream(
+                               new BufferedInputStream(new FileInputStream(file)),
+                               streamType)) {
+                       for (;;) {
+                               long n = is.skip(1 << 20);
+                               if (n <= 0) {
+                                       break;
+                               }
+                               length += n;
+                       }
+                       return length;
+               }
+       }
+
        /**
         * Writes merged file content to the working tree.
         *