From bc8215721627fcdeaa23c6e3bf625e0c4e5c3407 Mon Sep 17 00:00:00 2001
From: Unknwon <u@gogs.io>
Date: Mon, 2 Nov 2015 19:55:24 -0500
Subject: [PATCH] fix #1078

---
 README.md                    |  2 +-
 gogs.go                      |  2 +-
 models/git_diff.go           | 42 +++++++++++++++++++++++++-----------
 templates/.VERSION           |  2 +-
 templates/repo/diff_box.tmpl | 20 ++++++++---------
 5 files changed, 42 insertions(+), 26 deletions(-)

diff --git a/README.md b/README.md
index 3d7f5f5e5d..61f11c66ba 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Gogs - Go Git Service [![Build Status](https://travis-ci.org/gogits/gogs.svg?bra
 
 ![](public/img/gogs-large-resize.png)
 
-##### Current version: 0.6.21 Beta
+##### Current version: 0.6.22 Beta
 
 <table>
     <tr>
diff --git a/gogs.go b/gogs.go
index 1e95e9460e..9f07936922 100644
--- a/gogs.go
+++ b/gogs.go
@@ -17,7 +17,7 @@ import (
 	"github.com/gogits/gogs/modules/setting"
 )
 
-const APP_VER = "0.6.21.1102 Beta"
+const APP_VER = "0.6.22.1102 Beta"
 
 func init() {
 	runtime.GOMAXPROCS(runtime.NumCPU())
diff --git a/models/git_diff.go b/models/git_diff.go
index 2335e46808..3bf938ae40 100644
--- a/models/git_diff.go
+++ b/models/git_diff.go
@@ -37,6 +37,7 @@ const (
 	DIFF_FILE_ADD = iota + 1
 	DIFF_FILE_CHANGE
 	DIFF_FILE_DEL
+	DIFF_FILE_RENAME
 )
 
 type DiffLine struct {
@@ -57,12 +58,14 @@ type DiffSection struct {
 
 type DiffFile struct {
 	Name               string
+	OldName            string
 	Index              int
 	Addition, Deletion int
 	Type               int
 	IsCreated          bool
 	IsDeleted          bool
 	IsBin              bool
+	IsRenamed          bool
 	Sections           []*DiffSection
 }
 
@@ -158,17 +161,29 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
 
 		// Get new file.
 		if strings.HasPrefix(line, DIFF_HEAD) {
-			beg := len(DIFF_HEAD)
-			a := line[beg : (len(line)-beg)/2+beg]
+			middle := -1
 
-			// In case file name is surrounded by double quotes(it happens only in git-shell).
-			if a[0] == '"' {
-				a = a[1 : len(a)-1]
-				a = strings.Replace(a, `\"`, `"`, -1)
+			// Note: In case file name is surrounded by double quotes(it happens only in git-shell).
+			hasQuote := strings.Index(line, `\"`) > -1
+			if hasQuote {
+				line = strings.Replace(line, `\"`, `"`, -1)
+				middle = strings.Index(line, ` "b/`)
+			} else {
+				middle = strings.Index(line, " b/")
 			}
 
+			beg := len(DIFF_HEAD)
+			a := line[beg+2 : middle]
+			b := line[middle+3:]
+			if hasQuote {
+				a = a[1 : len(a)-1]
+				b = b[1 : len(b)-1]
+			}
+
+			fmt.Println(a, b)
+
 			curFile = &DiffFile{
-				Name:     a[strings.Index(a, "/")+1:],
+				Name:     a,
 				Index:    len(diff.Files) + 1,
 				Type:     DIFF_FILE_CHANGE,
 				Sections: make([]*DiffSection, 0, 10),
@@ -180,16 +195,17 @@ func ParsePatch(pid int64, maxlines int, cmd *exec.Cmd, reader io.Reader) (*Diff
 				switch {
 				case strings.HasPrefix(scanner.Text(), "new file"):
 					curFile.Type = DIFF_FILE_ADD
-					curFile.IsDeleted = false
 					curFile.IsCreated = true
 				case strings.HasPrefix(scanner.Text(), "deleted"):
 					curFile.Type = DIFF_FILE_DEL
-					curFile.IsCreated = false
 					curFile.IsDeleted = true
 				case strings.HasPrefix(scanner.Text(), "index"):
 					curFile.Type = DIFF_FILE_CHANGE
-					curFile.IsCreated = false
-					curFile.IsDeleted = false
+				case strings.HasPrefix(scanner.Text(), "similarity index 100%"):
+					curFile.Type = DIFF_FILE_RENAME
+					curFile.IsRenamed = true
+					curFile.OldName = curFile.Name
+					curFile.Name = b
 				}
 				if curFile.Type > 0 {
 					break
@@ -244,10 +260,10 @@ func GetDiffRange(repoPath, beforeCommitId string, afterCommitId string, maxline
 			cmd = exec.Command("git", "show", afterCommitId)
 		} else {
 			c, _ := commit.Parent(0)
-			cmd = exec.Command("git", "diff", c.Id.String(), afterCommitId)
+			cmd = exec.Command("git", "diff", "-M", c.Id.String(), afterCommitId)
 		}
 	} else {
-		cmd = exec.Command("git", "diff", beforeCommitId, afterCommitId)
+		cmd = exec.Command("git", "diff", "-M", beforeCommitId, afterCommitId)
 	}
 	cmd.Dir = repoPath
 	cmd.Stdout = wr
diff --git a/templates/.VERSION b/templates/.VERSION
index 54cbd867fa..2b9408d0cf 100644
--- a/templates/.VERSION
+++ b/templates/.VERSION
@@ -1 +1 @@
-0.6.21.1102 Beta
\ No newline at end of file
+0.6.22.1102 Beta
\ No newline at end of file
diff --git a/templates/repo/diff_box.tmpl b/templates/repo/diff_box.tmpl
index f4509942ec..e531434310 100644
--- a/templates/repo/diff_box.tmpl
+++ b/templates/repo/diff_box.tmpl
@@ -36,18 +36,18 @@
 <div class="diff-file-box diff-box file-content" id="diff-{{.Index}}">
   <h4 class="ui top attached normal header">
     <div class="diff-counter count ui left">
-        {{if not $file.IsBin}}
-        <span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
-        <span class="bar">
-          <span class="pull-left add"></span>
-          <span class="pull-left del"></span>
-        </span>
-        <span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
-        {{else}}
-        {{$.i18n.Tr "repo.diff.bin"}}
+        {{if $file.IsBin}}
+          {{$.i18n.Tr "repo.diff.bin"}}
+        {{else if not $file.IsRenamed}}
+          <span class="add" data-line="{{.Addition}}">+ {{.Addition}}</span>
+          <span class="bar">
+            <span class="pull-left add"></span>
+            <span class="pull-left del"></span>
+          </span>
+          <span class="del" data-line="{{.Deletion}}">- {{.Deletion}}</span>
         {{end}}
     </div>
-    <span class="file">{{$file.Name}}</span>
+    <span class="file">{{if $file.IsRenamed}}{{$file.OldName}} &rarr; {{end}}{{$file.Name}}</span>
     <div class="ui right">
       {{if $file.IsDeleted}}
       <a class="ui basic tiny button" rel="nofollow" href="{{EscapePound $.BeforeSourcePath}}/{{EscapePound .Name}}">{{$.i18n.Tr "repo.diff.view_file"}}</a>