Fixes #136: Fixed infinite recursion in list and tree commands
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 961103e..bd4c6e0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
 # Release 0.7.1 (xxxx-xx-xx)
 
+- Fixed #136: Fixed infinite recursion in list and tree commands.
 - Fixed issue where glide guess listed a null parent.
 - Fixed #135: Hard failure when home directory not found for cache.
 - Fixed #137: Some messages not ending in "\n".
diff --git a/cmd/tree.go b/cmd/tree.go
index 0a0297b..b521641 100644
--- a/cmd/tree.go
+++ b/cmd/tree.go
@@ -1,6 +1,7 @@
 package cmd
 
 import (
+	"container/list"
 	"fmt"
 	"os"
 	"path/filepath"
@@ -30,7 +31,9 @@
 	}
 
 	fmt.Println(myName)
-	displayTree(buildContext, basedir, myName, 1, showcore)
+	l := list.New()
+	l.PushBack(myName)
+	displayTree(buildContext, basedir, myName, 1, showcore, l)
 	return nil, nil
 }
 
@@ -87,12 +90,16 @@
 	default:
 		info[name] = found
 		for _, i := range walkDeps(b, found.Path, found.Name) {
-			listDeps(b, info, i, found.Path)
+			// Only walk the deps that are not already found to avoid
+			// infinite recursion.
+			if _, f := info[found.Name]; f == false {
+				listDeps(b, info, i, found.Path)
+			}
 		}
 	}
 }
 
-func displayTree(b *BuildCtxt, basedir, myName string, level int, core bool) {
+func displayTree(b *BuildCtxt, basedir, myName string, level int, core bool, l *list.List) {
 	deps := walkDeps(b, basedir, myName)
 	for _, name := range deps {
 		found := findPkg(b, name, basedir)
@@ -105,8 +112,17 @@
 			continue
 		}
 		fmt.Print(strings.Repeat("\t", level))
-		fmt.Printf("%s   (%s)\n", found.Name, found.Path)
-		displayTree(b, found.Path, found.Name, level+1, core)
+
+		f := findInList(found.Name, l)
+		if f == true {
+			fmt.Printf("(Recursion) %s   (%s)\n", found.Name, found.Path)
+		} else {
+			// Every branch in the tree is a copy to handle all the branches
+			cl := copyList(l)
+			cl.PushBack(found.Name)
+			fmt.Printf("%s   (%s)\n", found.Name, found.Path)
+			displayTree(b, found.Path, found.Name, level+1, core, cl)
+		}
 	}
 }
 
@@ -249,3 +265,21 @@
 	}
 	return false
 }
+
+func copyList(l *list.List) *list.List {
+	n := list.New()
+	for e := l.Front(); e != nil; e = e.Next() {
+		n.PushBack(e.Value.(string))
+	}
+	return n
+}
+
+func findInList(n string, l *list.List) bool {
+	for e := l.Front(); e != nil; e = e.Next() {
+		if e.Value.(string) == n {
+			return true
+		}
+	}
+
+	return false
+}
diff --git a/cmd/tree_test.go b/cmd/tree_test.go
new file mode 100644
index 0000000..afa6667
--- /dev/null
+++ b/cmd/tree_test.go
@@ -0,0 +1,23 @@
+package cmd
+
+import (
+	"container/list"
+	"testing"
+)
+
+func TestFindInTree(t *testing.T) {
+	l := list.New()
+	l.PushBack("github.com/Masterminds/glide")
+	l.PushBack("github.com/Masterminds/vcs")
+	l.PushBack("github.com/Masterminds/semver")
+
+	f := findInList("foo", l)
+	if f != false {
+		t.Error("findInList found true instead of false")
+	}
+
+	f = findInList("github.com/Masterminds/vcs", l)
+	if f != true {
+		t.Error("findInList found false instead of true")
+	}
+}