Merge pull request #1226 from asynts/patch-1

typo
diff --git a/plumbing/format/diff/unified_encoder.go b/plumbing/format/diff/unified_encoder.go
index 169242d..ce3bc7c 100644
--- a/plumbing/format/diff/unified_encoder.go
+++ b/plumbing/format/diff/unified_encoder.go
@@ -4,6 +4,7 @@
 	"bytes"
 	"fmt"
 	"io"
+	"regexp"
 	"strings"
 
 	"gopkg.in/src-d/go-git.v4/plumbing"
@@ -25,9 +26,10 @@
 	tPath  = "+++ %s\n"
 	binary = "Binary files %s and %s differ\n"
 
-	addLine    = "+%s\n"
-	deleteLine = "-%s\n"
-	equalLine  = " %s\n"
+	addLine    = "+%s%s"
+	deleteLine = "-%s%s"
+	equalLine  = " %s%s"
+	noNewLine  = "\n\\ No newline at end of file\n"
 
 	oldMode         = "old mode %o\n"
 	newMode         = "new mode %o\n"
@@ -216,7 +218,7 @@
 		linesBefore = c.ctxLines
 	}
 
-	c.current = &hunk{ctxPrefix: ctxPrefix}
+	c.current = &hunk{ctxPrefix: strings.TrimSuffix(ctxPrefix, "\n")}
 	c.current.AddOp(Equal, c.beforeContext...)
 
 	switch op {
@@ -279,12 +281,13 @@
 	}
 }
 
+var splitLinesRE = regexp.MustCompile(`[^\n]*(\n|$)`)
+
 func splitLines(s string) []string {
-	out := strings.Split(s, "\n")
+	out := splitLinesRE.FindAllString(s, -1)
 	if out[len(out)-1] == "" {
 		out = out[:len(out)-1]
 	}
-
 	return out
 }
 
@@ -346,7 +349,7 @@
 }
 
 func (o *op) String() string {
-	var prefix string
+	var prefix, suffix string
 	switch o.t {
 	case Add:
 		prefix = addLine
@@ -355,6 +358,10 @@
 	case Equal:
 		prefix = equalLine
 	}
+	n := len(o.text)
+	if n > 0 && o.text[n-1] != '\n' {
+		suffix = noNewLine
+	}
 
-	return fmt.Sprintf(prefix, o.text)
+	return fmt.Sprintf(prefix, o.text, suffix)
 }
diff --git a/plumbing/format/diff/unified_encoder_test.go b/plumbing/format/diff/unified_encoder_test.go
index 7736af1..091a96a 100644
--- a/plumbing/format/diff/unified_encoder_test.go
+++ b/plumbing/format/diff/unified_encoder_test.go
@@ -83,7 +83,7 @@
 			content: "A\n",
 			op:      Delete,
 		}, {
-			content: "B\nC\nD\nE\nF\nG",
+			content: "B\nC\nD\nE\nF\nG\n",
 			op:      Equal,
 		}, {
 			content: "H\n",
@@ -125,7 +125,7 @@
 			content: "A\n",
 			op:      Add,
 		}, {
-			content: "B\nC\nD\nE\nF\nG",
+			content: "B\nC\nD\nE\nF\nG\n",
 			op:      Equal,
 		}, {
 			content: "H\n",
@@ -164,13 +164,13 @@
 				seed: "hello\nbug\n",
 			},
 			chunks: []testChunk{{
-				content: "hello",
+				content: "hello\n",
 				op:      Equal,
 			}, {
-				content: "world",
+				content: "world\n",
 				op:      Delete,
 			}, {
-				content: "bug",
+				content: "bug\n",
 				op:      Add,
 			}},
 		}},
@@ -239,18 +239,18 @@
 			from: &testFile{
 				mode: filemode.Regular,
 				path: "test.txt",
-				seed: "test",
+				seed: "test\n",
 			},
 			to: &testFile{
 				mode: filemode.Regular,
 				path: "test1.txt",
-				seed: "test1",
+				seed: "test1\n",
 			},
 			chunks: []testChunk{{
-				content: "test",
+				content: "test\n",
 				op:      Delete,
 			}, {
-				content: "test1",
+				content: "test1\n",
 				op:      Add,
 			}},
 		}},
@@ -260,7 +260,7 @@
 	diff: `diff --git a/test.txt b/test1.txt
 rename from test.txt
 rename to test1.txt
-index 30d74d258442c7c65512eafab474568dd706c430..f079749c42ffdcc5f52ed2d3a6f15b09307e975e 100644
+index 9daeafb9864cf43055ae93beb0afd6c7d144bfa4..a5bce3fd2565d8f458555a0c6f42d0504a848bd5 100644
 --- a/test.txt
 +++ b/test1.txt
 @@ -1 +1 @@
@@ -299,19 +299,19 @@
 			from: &testFile{
 				mode: filemode.Regular,
 				path: "test.txt",
-				seed: "test",
+				seed: "test\n",
 			},
 			to: &testFile{
 				mode: filemode.Regular,
 				path: "test.txt",
-				seed: "test2",
+				seed: "test2\n",
 			},
 
 			chunks: []testChunk{{
-				content: "test",
+				content: "test\n",
 				op:      Delete,
 			}, {
-				content: "test2",
+				content: "test2\n",
 				op:      Add,
 			}},
 		}},
@@ -320,7 +320,7 @@
 	desc:    "one line change",
 	context: 1,
 	diff: `diff --git a/test.txt b/test.txt
-index 30d74d258442c7c65512eafab474568dd706c430..d606037cb232bfda7788a8322492312d55b2ae9d 100644
+index 9daeafb9864cf43055ae93beb0afd6c7d144bfa4..180cf8328022becee9aaa2577a8f84ea2b9f3827 100644
 --- a/test.txt
 +++ b/test.txt
 @@ -1 +1 @@
@@ -334,19 +334,19 @@
 			from: &testFile{
 				mode: filemode.Regular,
 				path: "test.txt",
-				seed: "test",
+				seed: "test\n",
 			},
 			to: &testFile{
 				mode: filemode.Regular,
 				path: "test.txt",
-				seed: "test2",
+				seed: "test2\n",
 			},
 
 			chunks: []testChunk{{
-				content: "test",
+				content: "test\n",
 				op:      Delete,
 			}, {
-				content: "test2",
+				content: "test2\n",
 				op:      Add,
 			}},
 		}},
@@ -356,7 +356,7 @@
 	context: 1,
 	diff: `this is the message
 diff --git a/test.txt b/test.txt
-index 30d74d258442c7c65512eafab474568dd706c430..d606037cb232bfda7788a8322492312d55b2ae9d 100644
+index 9daeafb9864cf43055ae93beb0afd6c7d144bfa4..180cf8328022becee9aaa2577a8f84ea2b9f3827 100644
 --- a/test.txt
 +++ b/test.txt
 @@ -1 +1 @@
@@ -397,7 +397,9 @@
 +++ b/test.txt
 @@ -1 +1 @@
 -test
+\ No newline at end of file
 +test2
+\ No newline at end of file
 `,
 }, {
 	patch: testPatch{
@@ -407,7 +409,7 @@
 			to: &testFile{
 				mode: filemode.Regular,
 				path: "new.txt",
-				seed: "test\ntest2\test3",
+				seed: "test\ntest2\ntest3",
 			},
 
 			chunks: []testChunk{{
@@ -421,13 +423,14 @@
 	context: 1,
 	diff: `diff --git a/new.txt b/new.txt
 new file mode 100644
-index 0000000000000000000000000000000000000000..65c8dd02a42273038658a22b1cb29c8d9457ca12
+index 0000000000000000000000000000000000000000..3ceaab5442b64a0c2b33dd25fae67ccdb4fd1ea8
 --- /dev/null
 +++ b/new.txt
 @@ -0,0 +1,3 @@
 +test
 +test2
 +test3
+\ No newline at end of file
 `,
 }, {
 	patch: testPatch{
@@ -456,6 +459,7 @@
 +++ /dev/null
 @@ -1 +0,0 @@
 -test
+\ No newline at end of file
 `,
 }, {
 	patch:   oneChunkPatch,
@@ -548,6 +552,7 @@
  X
  Y
  Z
+\ No newline at end of file
 `,
 }, {
 	patch: oneChunkPatch,
@@ -813,6 +818,47 @@
 +++ b/onechunk.txt
 @@ -23 +22,0 @@ Y
 -Z
+\ No newline at end of file
+`,
+}, {
+	patch: testPatch{
+		message: "",
+		filePatches: []testFilePatch{{
+			from: &testFile{
+				mode: filemode.Regular,
+				path: "onechunk.txt",
+				seed: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY\nZ",
+			},
+			to: &testFile{
+				mode: filemode.Regular,
+				path: "onechunk.txt",
+				seed: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY",
+			},
+
+			chunks: []testChunk{{
+				content: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\n",
+				op:      Equal,
+			}, {
+				content: "Y\nZ",
+				op:      Delete,
+			}, {
+				content: "Y",
+				op:      Add,
+			}},
+		}},
+	},
+	desc:    "remove last letter and no newline at end of file",
+	context: 0,
+	diff: `diff --git a/onechunk.txt b/onechunk.txt
+index 0adddcde4fd38042c354518351820eb06c417c82..d39ae38aad7ba9447b5e7998b2e4714f26c9218d 100644
+--- a/onechunk.txt
++++ b/onechunk.txt
+@@ -22,2 +21 @@ X
+-Y
+-Z
+\ No newline at end of file
++Y
+\ No newline at end of file
 `,
 }}
 
diff --git a/utils/diff/diff_ext_test.go b/utils/diff/diff_ext_test.go
index adda276..c6c7e90 100644
--- a/utils/diff/diff_ext_test.go
+++ b/utils/diff/diff_ext_test.go
@@ -99,6 +99,37 @@
 			{Type: 1, Text: "111\nBCD\n"},
 		},
 	},
+	{
+		src: "A\nB\nC\nD\nE\nF\nG\nH\nI\nJ\nK\nL\nM\nN\nÑ\nO\nP\nQ\nR\nS\nT\nU\nV\nW\nX\nY\nZ",
+		dst: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY\nZ",
+		exp: []diffmatchpatch.Diff{
+			{Type: -1, Text: "A\n"},
+			{Type: 0, Text: "B\nC\nD\nE\nF\nG\n"},
+			{Type: -1, Text: "H\n"},
+			{Type: 0, Text: "I\nJ\nK\nL\nM\nN\n"},
+			{Type: -1, Text: "Ñ\n"},
+			{Type: 0, Text: "O\nP\nQ\nR\nS\nT\n"},
+			{Type: -1, Text: "U\n"},
+			{Type: 0, Text: "V\nW\nX\nY\nZ"},
+		},
+	},
+	{
+		src: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY\nZ",
+		dst: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY\n",
+		exp: []diffmatchpatch.Diff{
+			{Type: 0, Text: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY\n"},
+			{Type: -1, Text: "Z"},
+		},
+	},
+	{
+		src: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY\nZ",
+		dst: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\nY",
+		exp: []diffmatchpatch.Diff{
+			{Type: 0, Text: "B\nC\nD\nE\nF\nG\nI\nJ\nK\nL\nM\nN\nO\nP\nQ\nR\nS\nT\nV\nW\nX\n"},
+			{Type: -1, Text: "Y\nZ"},
+			{Type: 1, Text: "Y"},
+		},
+	},
 }
 
 func (s *suiteCommon) TestDo(c *C) {