From 914ce405af975a6bf65cedd279e1bf75ca1671d5 Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Mon, 17 Mar 2014 18:56:22 +0800
Subject: [PATCH] bug fixed

---
 models/repo2.go | 115 +++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 94 insertions(+), 21 deletions(-)

diff --git a/models/repo2.go b/models/repo2.go
index e3fdc2784b..ccdda5bdb3 100644
--- a/models/repo2.go
+++ b/models/repo2.go
@@ -6,6 +6,7 @@ package models
 
 import (
 	"path"
+	"strings"
 	"time"
 
 	git "github.com/gogits/git"
@@ -13,10 +14,33 @@ import (
 
 type RepoFile struct {
 	*git.TreeEntry
-	Path    string
-	Message string
-	Created time.Time
-	Size    int64
+	Path       string
+	Message    string
+	Created    time.Time
+	Size       int64
+	LastCommit string
+}
+
+func findTree(repo *git.Repository, tree *git.Tree, rpath string) *git.Tree {
+	if rpath == "" {
+		return tree
+	}
+	paths := strings.Split(rpath, "/")
+	var g = tree
+	for _, p := range paths {
+		s := g.EntryByName(p)
+		if s == nil {
+			return nil
+		}
+		g, err := repo.LookupTree(s.Id)
+		if err != nil {
+			return nil
+		}
+		if g == nil {
+			return nil
+		}
+	}
+	return g
 }
 
 func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile, error) {
@@ -45,23 +69,72 @@ func GetReposFiles(userName, reposName, branchName, rpath string) ([]*RepoFile,
 			if err != nil {
 				return 0
 			}
-			switch entry.Filemode {
-			case git.FileModeBlob, git.FileModeBlobExec:
-				repofiles = append(repofiles, &RepoFile{
-					entry,
-					path.Join(dirname, entry.Name),
-					lastCommit.Message(),
-					lastCommit.Committer.When,
-					size,
-				})
-			case git.FileModeTree:
-				repodirs = append(repodirs, &RepoFile{
-					entry,
-					path.Join(dirname, entry.Name),
-					lastCommit.Message(),
-					lastCommit.Committer.When,
-					size,
-				})
+
+			var cm = lastCommit
+
+			for {
+				if cm.ParentCount() == 0 {
+					break
+				} else if cm.ParentCount() == 1 {
+					pt := findTree(repo, cm.Parent(0).Tree, dirname)
+					if pt == nil {
+						break
+					}
+					pEntry := pt.EntryByName(entry.Name)
+					if pEntry == nil || !pEntry.Id.Equal(entry.Id) {
+						break
+					} else {
+						cm = cm.Parent(0)
+					}
+				} else {
+					var emptyCnt = 0
+					var sameIdcnt = 0
+					for i := 0; i < cm.ParentCount(); i++ {
+						p := cm.Parent(i)
+						pt := findTree(repo, p.Tree, dirname)
+						var pEntry *git.TreeEntry
+						if pt != nil {
+							pEntry = pt.EntryByName(entry.Name)
+						}
+
+						if pEntry == nil {
+							if emptyCnt == cm.ParentCount()-1 {
+								goto loop
+							} else {
+								emptyCnt = emptyCnt + 1
+								continue
+							}
+						} else {
+							if !pEntry.Id.Equal(entry.Id) {
+								goto loop
+							} else {
+								if sameIdcnt == cm.ParentCount()-1 {
+									// TODO: now follow the first parent commit?
+									cm = cm.Parent(0)
+									break
+								}
+								sameIdcnt = sameIdcnt + 1
+							}
+						}
+					}
+				}
+			}
+
+		loop:
+
+			rp := &RepoFile{
+				entry,
+				path.Join(dirname, entry.Name),
+				cm.Message(),
+				cm.Committer.When,
+				size,
+				cm.Id().String(),
+			}
+
+			if entry.IsFile() {
+				repofiles = append(repofiles, rp)
+			} else if entry.IsDir() {
+				repodirs = append(repodirs, rp)
 			}
 		}
 		return 0