Include a tree hash ID in the JSON views for trees and commits.

Sample tree view (note the new top-level "id" property):

$ curl -s 'http://localhost:8080/gitiles/+/master/lib?format=JSON'
)]}'
{
  "id": "35913812a8e851228502cf49de8cc299ec149280",
  "entries": [
    {
      "mode": 33188,
      "type": "blob",
      "id": "abed91637554aa423806eb199958d007a6b72510",
      "name": "BUCK"
    },
    {
      "mode": 16384,
      "type": "tree",
      "id": "1c0b739a3b621f4d004daf16eed83121c69c1ff0",
      "name": "guice"
    },
    {
      "mode": 16384,
      "type": "tree",
      "id": "0337998ca4c09f2956c2f21497d7324027874139",
      "name": "jetty"
    },
    {
      "mode": 16384,
      "type": "tree",
      "id": "5e33423164943cd96f9804e96be1968a29a30b62",
      "name": "jgit"
    },
    {
      "mode": 16384,
      "type": "tree",
      "id": "e238f03c6d6d08426e335c9a30d06e0db28e9db3",
      "name": "slf4j"
    }
  ]
}

Sample commit view (note the new "tree" field):

$ curl 'http://localhost:8080/third_party/gitiles/+/HEAD?format=JSON'
)]}'
{
  "commit": "df50acbf091b678e424b47a2786342c256508df5",
  "tree": "cf62a7dc041f76659efa0cf9fe16c81ddb967b56",
  "parents": [
    "92bb12fac93061d1aeb6c81cd5081e7afd1926a7"
  ],
  "author": {
    "name": "Ken Rockot",
    "email": "[email protected]",
    "time": "Mon May 12 14:42:58 2014 -0700"
  },
  ...
}

Change-Id: Ifb94a3a626392a38aa571090c2784dfe04569f21
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/CommitJsonData.java b/gitiles-servlet/src/main/java/com/google/gitiles/CommitJsonData.java
index 86141c3..39d9be4 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/CommitJsonData.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/CommitJsonData.java
@@ -35,10 +35,11 @@
 
 class CommitJsonData {
   static final ImmutableSet<Field> DEFAULT_FIELDS = Sets.immutableEnumSet(
-      Field.SHA, Field.PARENTS, Field.AUTHOR, Field.COMMITTER, Field.MESSAGE);
+      Field.SHA, Field.TREE, Field.PARENTS, Field.AUTHOR, Field.COMMITTER, Field.MESSAGE);
 
   static class Commit {
     String commit;
+    String tree;
     List<String> parents;
     Ident author;
     Ident committer;
@@ -86,6 +87,9 @@
     if (cd.sha != null) {
       result.commit = cd.sha.name();
     }
+    if (cd.tree != null) {
+      result.tree = cd.tree.name();
+    }
     if (cd.parents != null) {
       result.parents = Lists.newArrayListWithCapacity(cd.parents.size());
       for (RevCommit parent : cd.parents) {
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
index 118e4e0..ff660b8 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/PathServlet.java
@@ -250,7 +250,7 @@
       }
       switch (wr.type) {
         case TREE:
-          renderJson(req, res, TreeJsonData.toJsonData(wr.tw), TreeJsonData.Tree.class);
+          renderJson(req, res, TreeJsonData.toJsonData(wr.id, wr.tw), TreeJsonData.Tree.class);
           break;
         default:
           res.setStatus(SC_NOT_FOUND);
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java b/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
index be4ba4f..4ad6562 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/TreeJsonData.java
@@ -18,6 +18,7 @@
 
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.FileMode;
+import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.treewalk.TreeWalk;
 
 import java.io.IOException;
@@ -25,6 +26,7 @@
 
 class TreeJsonData {
   static class Tree {
+    String id;
     List<Entry> entries;
   }
 
@@ -35,8 +37,9 @@
     String name;
   }
 
-  static Tree toJsonData(TreeWalk tw) throws IOException {
+  static Tree toJsonData(ObjectId id, TreeWalk tw) throws IOException {
     Tree tree = new Tree();
+    tree.id = id.name();
     tree.entries = Lists.newArrayList();
     while (tw.next()) {
       Entry e = new Entry();
diff --git a/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java b/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
index fbd0792..1eecaff 100644
--- a/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
+++ b/gitiles-servlet/src/test/java/com/google/gitiles/PathServletTest.java
@@ -235,6 +235,7 @@
         .create());
 
     Tree tree = buildJson("/repo/+/master/?format=JSON", Tree.class);
+    assertEquals(c.getTree().name(), tree.id);
     assertEquals(2, tree.entries.size());
     assertEquals(0100644, tree.entries.get(0).mode);
     assertEquals("blob", tree.entries.get(0).type);
@@ -246,6 +247,7 @@
     assertEquals("foo", tree.entries.get(1).name);
 
     tree = buildJson("/repo/+/master/foo?format=JSON", Tree.class);
+    assertEquals(repo.get(c.getTree(), "foo").name(), tree.id);
     assertEquals(1, tree.entries.size());
     assertEquals(0100644, tree.entries.get(0).mode);
     assertEquals("blob", tree.entries.get(0).type);
@@ -253,6 +255,7 @@
     assertEquals("bar", tree.entries.get(0).name);
 
     tree = buildJson("/repo/+/master/foo/?format=JSON", Tree.class);
+    assertEquals(repo.get(c.getTree(), "foo").name(), tree.id);
     assertEquals(1, tree.entries.size());
     assertEquals(0100644, tree.entries.get(0).mode);
     assertEquals("blob", tree.entries.get(0).type);