Reflogs, Digests, and Dashboards

Renamed pushlog to reflog to better match it's current and future purpose.
Split PushesPanel into ReflogPanel and DigestsPanel.
Overhauled project pages and gave them a coherent purpose from the dashboard.
diff --git a/src/main/distrib/data/gitblit.properties b/src/main/distrib/data/gitblit.properties
index 9f7eb77..7936bc2 100644
--- a/src/main/distrib/data/gitblit.properties
+++ b/src/main/distrib/data/gitblit.properties
@@ -853,17 +853,17 @@
 # SINCE 0.5.0

 web.itemsPerPage = 50

 

-# The number of pushes to display on the overview page

+# The number of reflog changes to display on the overview page

 # Value must exceed 0 else default of 5 is used

 #

 # SINCE 1.3.0

-web.overviewPushCount = 5

+web.overviewReflogCount = 5

 

-# The number of pushes to show on a push page before show the first, prev, next

-# pagination links.  A default of 10 is used for any invalid value.

+# The number of reflog changes to show on a reflog page before show the first,

+#  prev, next pagination links.  A default of 10 is used for any invalid value.

 #

 # SINCE 1.3.0

-web.pushesPerPage = 10

+web.reflogChangesPerPage = 10

 

 # Registered file extensions to ignore during Lucene indexing

 #

diff --git a/src/main/java/com/gitblit/git/ReceiveHook.java b/src/main/java/com/gitblit/git/ReceiveHook.java
index 3e00b38..e3435ff 100644
--- a/src/main/java/com/gitblit/git/ReceiveHook.java
+++ b/src/main/java/com/gitblit/git/ReceiveHook.java
@@ -45,7 +45,7 @@
 import com.gitblit.utils.ArrayUtils;

 import com.gitblit.utils.ClientLogger;

 import com.gitblit.utils.JGitUtils;

-import com.gitblit.utils.PushLogUtils;

+import com.gitblit.utils.RefLogUtils;

 import com.gitblit.utils.StringUtils;

 

 /**

@@ -256,7 +256,7 @@
 

 		// update push log

 		try {

-			PushLogUtils.updatePushLog(user, rp.getRepository(), commands);

+			RefLogUtils.updateRefLog(user, rp.getRepository(), commands);

 			logger.debug(MessageFormat.format("{0} push log updated", repository.name));

 		} catch (Exception e) {

 			logger.error(MessageFormat.format("Failed to update {0} pushlog", repository.name), e);

diff --git a/src/main/java/com/gitblit/models/DailyLogEntry.java b/src/main/java/com/gitblit/models/DailyLogEntry.java
index a459d76..41f1381 100644
--- a/src/main/java/com/gitblit/models/DailyLogEntry.java
+++ b/src/main/java/com/gitblit/models/DailyLogEntry.java
@@ -28,7 +28,7 @@
  * 
  * @author James Moger
  */
-public class DailyLogEntry extends PushLogEntry implements Serializable {
+public class DailyLogEntry extends RefLogEntry implements Serializable {
 
 	private static final long serialVersionUID = 1L;
 
diff --git a/src/main/java/com/gitblit/models/PushLogEntry.java b/src/main/java/com/gitblit/models/RefLogEntry.java
similarity index 97%
rename from src/main/java/com/gitblit/models/PushLogEntry.java
rename to src/main/java/com/gitblit/models/RefLogEntry.java
index 77bed38..54d1777 100644
--- a/src/main/java/com/gitblit/models/PushLogEntry.java
+++ b/src/main/java/com/gitblit/models/RefLogEntry.java
@@ -39,7 +39,7 @@
  * 

  * @author James Moger

  */

-public class PushLogEntry implements Serializable, Comparable<PushLogEntry> {

+public class RefLogEntry implements Serializable, Comparable<RefLogEntry> {

 

 	private static final long serialVersionUID = 1L;

 

@@ -67,7 +67,7 @@
 	 * @param user

 	 *            the user who pushed

 	 */

-	public PushLogEntry(String repository, Date date, UserModel user) {

+	public RefLogEntry(String repository, Date date, UserModel user) {

 		this.repository = repository;

 		this.date = date;

 		this.user = user;

@@ -317,7 +317,7 @@
 	}

 

 	@Override

-	public int compareTo(PushLogEntry o) {

+	public int compareTo(RefLogEntry o) {

 		// reverse chronological order

 		return o.date.compareTo(date);

 	}

diff --git a/src/main/java/com/gitblit/utils/PushLogUtils.java b/src/main/java/com/gitblit/utils/RefLogUtils.java
similarity index 77%
rename from src/main/java/com/gitblit/utils/PushLogUtils.java
rename to src/main/java/com/gitblit/utils/RefLogUtils.java
index fed5b19..ce03a16 100644
--- a/src/main/java/com/gitblit/utils/PushLogUtils.java
+++ b/src/main/java/com/gitblit/utils/RefLogUtils.java
@@ -41,6 +41,7 @@
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.PersonIdent;
+import org.eclipse.jgit.lib.RefRename;
 import org.eclipse.jgit.lib.RefUpdate;
 import org.eclipse.jgit.lib.RefUpdate.Result;
 import org.eclipse.jgit.lib.Repository;
@@ -55,23 +56,23 @@
 import com.gitblit.Constants;
 import com.gitblit.models.DailyLogEntry;
 import com.gitblit.models.PathModel.PathChangeModel;
-import com.gitblit.models.PushLogEntry;
+import com.gitblit.models.RefLogEntry;
 import com.gitblit.models.RefModel;
 import com.gitblit.models.RepositoryCommit;
 import com.gitblit.models.UserModel;
 
 /**
- * Utility class for maintaining a pushlog within a git repository on an
+ * Utility class for maintaining a reflog within a git repository on an
  * orphan branch.
  * 
  * @author James Moger
  *
  */
-public class PushLogUtils {
+public class RefLogUtils {
 	
-	public static final String GB_PUSHES = "refs/gitblit/pushes";
+	private static final String GB_REFLOG = "refs/gitblit/reflog";
 
-	static final Logger LOGGER = LoggerFactory.getLogger(PushLogUtils.class);
+	private static final Logger LOGGER = LoggerFactory.getLogger(RefLogUtils.class);
 
 	/**
 	 * Log an error message and exception.
@@ -97,17 +98,39 @@
 	}
 
 	/**
-	 * Returns a RefModel for the gb-pushes branch in the repository. If the
+	 * Returns a RefModel for the reflog branch in the repository. If the
 	 * branch can not be found, null is returned.
 	 * 
 	 * @param repository
-	 * @return a refmodel for the gb-pushes branch or null
+	 * @return a refmodel for the reflog branch or null
 	 */
-	public static RefModel getPushLogBranch(Repository repository) {
+	public static RefModel getRefLogBranch(Repository repository) {
 		List<RefModel> refs = JGitUtils.getRefs(repository, com.gitblit.Constants.R_GITBLIT);
+		RefModel pushLog = null;
+		final String GB_PUSHES = "refs/gitblit/pushes";
 		for (RefModel ref : refs) {
-			if (ref.reference.getName().equals(GB_PUSHES)) {
+			if (ref.reference.getName().equals(GB_REFLOG)) {
 				return ref;
+			} else if (ref.reference.getName().equals(GB_PUSHES)) {
+				pushLog = ref;
+			}
+		}
+		if (pushLog != null) {
+			// rename refs/gitblit/pushes to refs/gitblit/reflog
+			RefRename cmd;
+			try {
+				cmd = repository.renameRef(GB_PUSHES, GB_REFLOG);
+				cmd.setRefLogIdent(new PersonIdent("Gitblit", "gitblit@localhost"));
+				cmd.setRefLogMessage("renamed " + GB_PUSHES + " => " + GB_REFLOG);
+				Result res = cmd.rename();
+				switch (res) {
+				case RENAMED:
+					return getRefLogBranch(repository);
+				default:
+					LOGGER.error("failed to rename " + GB_PUSHES + " => " + GB_REFLOG + " (" + res.name() + ")");
+				}
+			} catch (IOException e) {
+				LOGGER.error("failed to rename pushlog", e);
 			}
 		}
 		return null;
@@ -133,25 +156,25 @@
 	}
 	
 	/**
-	 * Updates a push log.
+	 * Updates the reflog with the received commands.
 	 * 
 	 * @param user
 	 * @param repository
 	 * @param commands
 	 * @return true, if the update was successful
 	 */
-	public static boolean updatePushLog(UserModel user, Repository repository,
+	public static boolean updateRefLog(UserModel user, Repository repository,
 			Collection<ReceiveCommand> commands) {
-		RefModel pushlogBranch = getPushLogBranch(repository);
-		if (pushlogBranch == null) {
-			JGitUtils.createOrphanBranch(repository, GB_PUSHES, null);
+		RefModel reflogBranch = getRefLogBranch(repository);
+		if (reflogBranch == null) {
+			JGitUtils.createOrphanBranch(repository, GB_REFLOG, null);
 		}
 		
 		boolean success = false;
 		String message = "push";
 		
 		try {
-			ObjectId headId = repository.resolve(GB_PUSHES + "^{commit}");
+			ObjectId headId = repository.resolve(GB_REFLOG + "^{commit}");
 			ObjectInserter odi = repository.newObjectInserter();
 			try {
 				// Create the in-memory index of the push log entry
@@ -184,7 +207,7 @@
 				RevWalk revWalk = new RevWalk(repository);
 				try {
 					RevCommit revCommit = revWalk.parseCommit(commitId);
-					RefUpdate ru = repository.updateRef(GB_PUSHES);
+					RefUpdate ru = repository.updateRef(GB_REFLOG);
 					ru.setNewObjectId(commitId);
 					ru.setExpectedOldObjectId(headId);
 					ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
@@ -201,7 +224,7 @@
 								ru.getRef(), rc);
 					default:
 						throw new JGitInternalException(MessageFormat.format(
-								JGitText.get().updatingRefFailed, GB_PUSHES, commitId.toString(),
+								JGitText.get().updatingRefFailed, GB_REFLOG, commitId.toString(),
 								rc));
 					}
 				} finally {
@@ -211,7 +234,7 @@
 				odi.release();
 			}
 		} catch (Throwable t) {
-			error(t, repository, "Failed to commit pushlog entry to {0}");
+			error(t, repository, "Failed to commit reflog entry to {0}");
 		}
 		return success;
 	}
@@ -316,25 +339,25 @@
 		return inCoreIndex;
 	}
 	
-	public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository) {
-		return getPushLog(repositoryName, repository, null, 0, -1);
+	public static List<RefLogEntry> getRefLog(String repositoryName, Repository repository) {
+		return getRefLog(repositoryName, repository, null, 0, -1);
 	}
 
-	public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository, int maxCount) {
-		return getPushLog(repositoryName, repository, null, 0, maxCount);
+	public static List<RefLogEntry> getRefLog(String repositoryName, Repository repository, int maxCount) {
+		return getRefLog(repositoryName, repository, null, 0, maxCount);
 	}
 
-	public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository, int offset, int maxCount) {
-		return getPushLog(repositoryName, repository, null, offset, maxCount);
+	public static List<RefLogEntry> getRefLog(String repositoryName, Repository repository, int offset, int maxCount) {
+		return getRefLog(repositoryName, repository, null, offset, maxCount);
 	}
 
-	public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository, Date minimumDate) {
-		return getPushLog(repositoryName, repository, minimumDate, 0, -1);
+	public static List<RefLogEntry> getRefLog(String repositoryName, Repository repository, Date minimumDate) {
+		return getRefLog(repositoryName, repository, minimumDate, 0, -1);
 	}
 	
 	/**
-	 * Returns the list of push log entries as they were recorded by Gitblit.
-	 * Each PushLogEntry may represent multiple ref updates.
+	 * Returns the list of reflog entries as they were recorded by Gitblit.
+	 * Each RefLogEntry may represent multiple ref updates.
 	 * 
 	 * @param repositoryName
 	 * @param repository
@@ -344,10 +367,10 @@
 	 * 			if < 0, all pushes are returned.
 	 * @return a list of push log entries
 	 */
-	public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository,
+	public static List<RefLogEntry> getRefLog(String repositoryName, Repository repository,
 			Date minimumDate, int offset, int maxCount) {
-		List<PushLogEntry> list = new ArrayList<PushLogEntry>();
-		RefModel ref = getPushLogBranch(repository);
+		List<RefLogEntry> list = new ArrayList<RefLogEntry>();
+		RefModel ref = getRefLogBranch(repository);
 		if (ref == null) {
 			return list;
 		}
@@ -358,9 +381,9 @@
 		Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);
 		List<RevCommit> pushes;
 		if (minimumDate == null) {
-			pushes = JGitUtils.getRevLog(repository, GB_PUSHES, offset, maxCount);
+			pushes = JGitUtils.getRevLog(repository, GB_REFLOG, offset, maxCount);
 		} else {
-			pushes = JGitUtils.getRevLog(repository, GB_PUSHES, minimumDate);
+			pushes = JGitUtils.getRevLog(repository, GB_REFLOG, minimumDate);
 		}
 		for (RevCommit push : pushes) {
 			if (push.getAuthorIdent().getName().equalsIgnoreCase("gitblit")) {
@@ -371,7 +394,7 @@
 			UserModel user = newUserModelFrom(push.getAuthorIdent());
 			Date date = push.getAuthorIdent().getWhen();
 			
-			PushLogEntry log = new PushLogEntry(repositoryName, date, user);
+			RefLogEntry log = new RefLogEntry(repositoryName, date, user);
 			list.add(log);
 			List<PathChangeModel> changedRefs = JGitUtils.getFilesInCommit(repository, push);
 			for (PathChangeModel change : changedRefs) {
@@ -410,8 +433,8 @@
 	 * @param maxCount
 	 * @return a list of push log entries separated by ref
 	 */
-	public static List<PushLogEntry> getPushLogByRef(String repositoryName, Repository repository, int maxCount) {
-		return getPushLogByRef(repositoryName, repository, 0, maxCount);
+	public static List<RefLogEntry> getLogByRef(String repositoryName, Repository repository, int maxCount) {
+		return getLogByRef(repositoryName, repository, 0, maxCount);
 	}
 	
 	/**
@@ -424,65 +447,65 @@
 	 * @param maxCount
 	 * @return a list of push log entries separated by ref
 	 */
-	public static List<PushLogEntry> getPushLogByRef(String repositoryName, Repository repository,  int offset,
+	public static List<RefLogEntry> getLogByRef(String repositoryName, Repository repository,  int offset,
 			int maxCount) {
 		// break the push log into ref push logs and then merge them back into a list
-		Map<String, List<PushLogEntry>> refMap = new HashMap<String, List<PushLogEntry>>();
-        List<PushLogEntry> pushes = getPushLog(repositoryName, repository, offset, maxCount);
-		for (PushLogEntry push : pushes) {
-			for (String ref : push.getChangedRefs()) {
+		Map<String, List<RefLogEntry>> refMap = new HashMap<String, List<RefLogEntry>>();
+        List<RefLogEntry> refLog = getRefLog(repositoryName, repository, offset, maxCount);
+		for (RefLogEntry entry : refLog) {
+			for (String ref : entry.getChangedRefs()) {
 				if (!refMap.containsKey(ref)) {
-					refMap.put(ref, new ArrayList<PushLogEntry>());
+					refMap.put(ref, new ArrayList<RefLogEntry>());
 				}
 				
-				// construct new ref-specific push log entry
-				PushLogEntry refPush;
-				if (push instanceof DailyLogEntry) {
+				// construct new ref-specific ref change entry
+				RefLogEntry refChange;
+				if (entry instanceof DailyLogEntry) {
 					// simulated push log from commits grouped by date
-					refPush = new DailyLogEntry(push.repository, push.date);
+					refChange = new DailyLogEntry(entry.repository, entry.date);
 				} else {
 					// real push log entry
-					refPush = new PushLogEntry(push.repository, push.date, push.user);
+					refChange = new RefLogEntry(entry.repository, entry.date, entry.user);
 				}
-				refPush.updateRef(ref, push.getChangeType(ref), push.getOldId(ref), push.getNewId(ref));
-				refPush.addCommits(push.getCommits(ref));
-				refMap.get(ref).add(refPush);
+				refChange.updateRef(ref, entry.getChangeType(ref), entry.getOldId(ref), entry.getNewId(ref));
+				refChange.addCommits(entry.getCommits(ref));
+				refMap.get(ref).add(refChange);
 			}
 		}
 		
-		// merge individual ref pushes into master list
-		List<PushLogEntry> refPushLog = new ArrayList<PushLogEntry>();
-		for (List<PushLogEntry> refPush : refMap.values()) {
-			refPushLog.addAll(refPush);
+		// merge individual ref changes into master list
+		List<RefLogEntry> mergedRefLog = new ArrayList<RefLogEntry>();
+		for (List<RefLogEntry> refPush : refMap.values()) {
+			mergedRefLog.addAll(refPush);
 		}
 		
-		// sort ref push log
-		Collections.sort(refPushLog);
+		// sort ref log
+		Collections.sort(mergedRefLog);
 		
-		return refPushLog;
+		return mergedRefLog;
 	}
 	
 	/**
-	 * Returns the list of pushes separated by ref (e.g. each ref has it's own
-	 * PushLogEntry object).
+	 * Returns the list of ref changes separated by ref (e.g. each ref has it's own
+	 * RefLogEntry object).
 	 *  
 	 * @param repositoryName
 	 * @param repository
 	 * @param minimumDate
-	 * @return a list of push log entries separated by ref
+	 * @return a list of ref log entries separated by ref
 	 */
-	public static List<PushLogEntry> getPushLogByRef(String repositoryName, Repository repository,  Date minimumDate) {
+	public static List<RefLogEntry> getLogByRef(String repositoryName, Repository repository,  Date minimumDate) {
 		// break the push log into ref push logs and then merge them back into a list
-		Map<String, List<PushLogEntry>> refMap = new HashMap<String, List<PushLogEntry>>();
-		List<PushLogEntry> pushes = getPushLog(repositoryName, repository, minimumDate);
-		for (PushLogEntry push : pushes) {
+		Map<String, List<RefLogEntry>> refMap = new HashMap<String, List<RefLogEntry>>();
+		List<RefLogEntry> pushes = getRefLog(repositoryName, repository, minimumDate);
+		for (RefLogEntry push : pushes) {
 			for (String ref : push.getChangedRefs()) {
 				if (!refMap.containsKey(ref)) {
-					refMap.put(ref, new ArrayList<PushLogEntry>());
+					refMap.put(ref, new ArrayList<RefLogEntry>());
 				}
 
                 // construct new ref-specific push log entry
-                PushLogEntry refPush = new PushLogEntry(push.repository, push.date, push.user);
+                RefLogEntry refPush = new RefLogEntry(push.repository, push.date, push.user);
                 refPush.updateRef(ref, push.getChangeType(ref), push.getOldId(ref), push.getNewId(ref));
 				refPush.addCommits(push.getCommits(ref));
 				refMap.get(ref).add(refPush);
@@ -490,8 +513,8 @@
 		}
 		
 		// merge individual ref pushes into master list
-		List<PushLogEntry> refPushLog = new ArrayList<PushLogEntry>();
-		for (List<PushLogEntry> refPush : refMap.values()) {
+		List<RefLogEntry> refPushLog = new ArrayList<RefLogEntry>();
+		for (List<RefLogEntry> refPush : refMap.values()) {
 			refPushLog.addAll(refPush);
 		}
 		
@@ -562,7 +585,7 @@
                         			Date tagDate = commit.getAuthorIdent().getWhen();
                         			tags.put(dateStr, new DailyLogEntry(repositoryName, tagDate, tagUser));
                                 }
-                                PushLogEntry tagEntry = tags.get(dateStr);
+                                RefLogEntry tagEntry = tags.get(dateStr);
                                 tagEntry.updateRef(ref.getName(), ReceiveCommand.Type.CREATE);
                                 tagEntry.addCommit(ref.getName(), commit);
                             } else if (ref.getName().startsWith(Constants.R_PULL)) {
@@ -572,7 +595,7 @@
                         			Date commitDate = commit.getAuthorIdent().getWhen();
                         			pulls.put(dateStr, new DailyLogEntry(repositoryName, commitDate, commitUser));
                                 }
-                                PushLogEntry pullEntry = pulls.get(dateStr);
+                                RefLogEntry pullEntry = pulls.get(dateStr);
                                 pullEntry.updateRef(ref.getName(), ReceiveCommand.Type.CREATE);
                                 pullEntry.addCommit(ref.getName(), commit);
                             }
diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
index f4180fa..cdae093 100644
--- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
+++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.java
@@ -44,18 +44,18 @@
 import com.gitblit.wicket.pages.GitSearchPage;

 import com.gitblit.wicket.pages.GravatarProfilePage;

 import com.gitblit.wicket.pages.HistoryPage;

-import com.gitblit.wicket.pages.DashboardPage;

 import com.gitblit.wicket.pages.LogPage;

 import com.gitblit.wicket.pages.LogoutPage;

 import com.gitblit.wicket.pages.LuceneSearchPage;

 import com.gitblit.wicket.pages.MarkdownPage;

 import com.gitblit.wicket.pages.MetricsPage;

+import com.gitblit.wicket.pages.MyDashboardPage;

 import com.gitblit.wicket.pages.OverviewPage;

 import com.gitblit.wicket.pages.PatchPage;

 import com.gitblit.wicket.pages.ProjectPage;

 import com.gitblit.wicket.pages.ProjectsPage;

-import com.gitblit.wicket.pages.PushesPage;

 import com.gitblit.wicket.pages.RawPage;

+import com.gitblit.wicket.pages.ReflogPage;

 import com.gitblit.wicket.pages.RepositoriesPage;

 import com.gitblit.wicket.pages.ReviewProposalPage;

 import com.gitblit.wicket.pages.SummaryPage;

@@ -69,7 +69,7 @@
 

 public class GitBlitWebApp extends WebApplication {

 

-	public final static Class<? extends BasePage> HOME_PAGE_CLASS = DashboardPage.class;

+	public final static Class<? extends BasePage> HOME_PAGE_CLASS = MyDashboardPage.class;

 	

 	@Override

 	public void init() {

@@ -98,7 +98,7 @@
 		mount("/repositories", RepositoriesPage.class);

 		mount("/overview", OverviewPage.class, "r", "h");

 		mount("/summary", SummaryPage.class, "r");

-		mount("/pushes", PushesPage.class, "r", "h");

+		mount("/reflog", ReflogPage.class, "r", "h");

 		mount("/commits", LogPage.class, "r", "h");

 		mount("/log", LogPage.class, "r", "h");

 		mount("/tags", TagsPage.class, "r");

diff --git a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
index 2e17e60..f7e72ca 100644
--- a/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
+++ b/src/main/java/com/gitblit/wicket/GitBlitWebApp.properties
@@ -462,8 +462,7 @@
 gb.at = at
 gb.of = of
 gb.in = in
-gb.morePushes = all pushes...
-gb.pushes = pushes
+gb.moreChanges = all changes...
 gb.pushedNCommitsTo = pushed {0} commits to
 gb.pushedOneCommitTo = pushed 1 commit to
 gb.commitsTo = {0} commits to
@@ -488,8 +487,12 @@
 gb.starredRepositories = starred repositories
 gb.failedToUpdateUser = Failed to update user account!
 gb.myRepositories = my repositories
-gb.noActivity = there has been no recent commit activity
+gb.noActivity = there has been no activity in the last {0} days
 gb.findSomeRepositories = find some repositories
 gb.metricAuthorExclusions = author metric exclusions
 gb.myDashboard = my dashboard
-gb.failedToFindAccount = failed to find user account ''{0}''
\ No newline at end of file
+gb.failedToFindAccount = failed to find user account ''{0}''
+gb.reflog = reflog
+gb.active = active
+gb.starred = starred
+gb.owned = owned
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/DashboardPage.html b/src/main/java/com/gitblit/wicket/pages/DashboardPage.html
deleted file mode 100644
index 1da7ef4..0000000
--- a/src/main/java/com/gitblit/wicket/pages/DashboardPage.html
+++ /dev/null
@@ -1,100 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

-<html xmlns="http://www.w3.org/1999/xhtml"  

-      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  

-      xml:lang="en"  

-      lang="en"> 

-

-<body>

-<wicket:extend>

-<div class="container">

-	<div class="hidden-phone markdown" style="padding-bottom:5px;" wicket:id="repositoriesMessage">[repositories message]</div>

-	

-	<div class="row">

-		<div class="span7">

-			<div style="color:#888;font-size:1.75em;padding-bottom:5px;" wicket:id="feedheader"></div>

-			<div class="hidden-phone hidden-tablet"  style="text-align:center;">

-				<table>

-					<tr>

-						<td><div id="chartRepositories" style="display:inline-block;width: 175px; height:175px"></div></td>

-						<td><div id="chartAuthors" style="display:inline-block;width: 175px; height: 175px;"></div></td>

-					</tr>

-				</table>

-			</div>

-			<div wicket:id="digests"></div>

-		</div>

-		<div class="span5">

-			<div wicket:id="active">[active]</div>

-			<div wicket:id="starred">[starred]</div>

-			<div wicket:id="owned">[owned]</div>

-		</div>

-		

-	</div>

-</div>

-

-<wicket:fragment wicket:id="starredListFragment">

-	<div ng-controller="starredCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">

-		<div class="header" style="padding: 5px;border: none;"><i class="icon-star"></i> <wicket:message key="gb.starredRepositories"></wicket:message> ({{starred.length}})

-			<div class="pull-right">

-				<a class="btn btn-mini">more</a>

-			</div>

-			<div style="padding: 5px 0px 0px;">

-				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

-			</div>

-		</div>

-		

-		<div ng-repeat="item in starred | limitTo: 20 | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

-			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

-			<a href="summary/?r={{item.r}}">{{item.p}}<b>{{item.n}}</b></a>

-			<span class="link hidden-tablet hidden-phone" style="color: #aaa;" title="{{item.d}}">{{item.t}}</span>

-			<span ng-show="item.s" class="pull-right">

-				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

-			</span>

-		</div>

-		

-	</div>

-</wicket:fragment>

-

-<wicket:fragment wicket:id="ownedListFragment">

-	<div ng-controller="ownedCtrl" style="border: 1px solid #ddd;border-radius: 4px;">

-		<div class="header" style="padding: 5px;border: none;"><i class="icon-user"></i> <wicket:message key="gb.myRepositories"></wicket:message> ({{owned.length}})

-			<div class="hidden-phone pull-right">

-				<span wicket:id="create"></span>

-			</div>

-			<div style="padding: 5px 0px 0px;">

-				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

-			</div>

-		</div>

-		

-		<div ng-repeat="item in owned | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

-			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

-			<a href="summary/?r={{item.r}}">{{item.p}}<b>{{item.n}}</b></a>

-			<span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>

-			<span ng-show="item.s" class="pull-right">

-				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

-			</span>

-		</div>		

-	</div>

-</wicket:fragment>

-

-<wicket:fragment wicket:id="activeListFragment">

-	<div ng-controller="activeCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">

-		<div class="header" style="padding: 5px;border: none;"><i class="icon-user"></i> <wicket:message key="gb.activeRepositories"></wicket:message> ({{active.length}})

-			<div style="padding: 5px 0px 0px;">

-				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

-			</div>

-		</div>

-		

-		<div ng-repeat="item in active | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

-			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

-			<a href="summary/?r={{item.r}}">{{item.p}}<b>{{item.n}}</b></a>

-			<span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>

-			<span ng-show="item.s" class="pull-right">

-				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

-			</span>

-		</div>		

-	</div>

-</wicket:fragment>

-

-</wicket:extend>

-</body>

-</html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java
index 6c328b1..1c45b64 100644
--- a/src/main/java/com/gitblit/wicket/pages/DashboardPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/DashboardPage.java
@@ -15,49 +15,40 @@
  */

 package com.gitblit.wicket.pages;

 

-import java.io.File;

-import java.io.FileInputStream;

-import java.io.InputStream;

-import java.io.InputStreamReader;

 import java.io.Serializable;

 import java.text.DateFormat;

 import java.text.MessageFormat;

 import java.text.SimpleDateFormat;

 import java.util.ArrayList;

 import java.util.Calendar;

+import java.util.Collection;

 import java.util.Collections;

-import java.util.Comparator;

 import java.util.Date;

 import java.util.HashMap;

-import java.util.HashSet;

 import java.util.List;

 import java.util.Map;

 import java.util.Set;

 import java.util.TimeZone;

 import java.util.TreeSet;

 

-import org.apache.wicket.Component;

 import org.apache.wicket.PageParameters;

 import org.apache.wicket.behavior.HeaderContributor;

 import org.apache.wicket.markup.html.basic.Label;

 import org.apache.wicket.markup.html.panel.Fragment;

-import org.eclipse.jgit.lib.Constants;

 import org.eclipse.jgit.lib.Repository;

 

 import com.gitblit.GitBlit;

 import com.gitblit.Keys;

 import com.gitblit.models.DailyLogEntry;

 import com.gitblit.models.Metric;

-import com.gitblit.models.PushLogEntry;

+import com.gitblit.models.RefLogEntry;

 import com.gitblit.models.RepositoryCommit;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.ArrayUtils;

-import com.gitblit.utils.MarkdownUtils;

-import com.gitblit.utils.PushLogUtils;

+import com.gitblit.utils.RefLogUtils;

 import com.gitblit.utils.StringUtils;

 import com.gitblit.wicket.GitBlitWebApp;

-import com.gitblit.wicket.GitBlitWebSession;

 import com.gitblit.wicket.PageRegistration;

 import com.gitblit.wicket.PageRegistration.DropDownMenuItem;

 import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;

@@ -66,19 +57,17 @@
 import com.gitblit.wicket.charting.GoogleCharts;

 import com.gitblit.wicket.charting.GooglePieChart;

 import com.gitblit.wicket.ng.NgController;

+import com.gitblit.wicket.panels.DigestsPanel;

 import com.gitblit.wicket.panels.LinkPanel;

-import com.gitblit.wicket.panels.PushesPanel;

 

-public class DashboardPage extends RootPage {

+public abstract class DashboardPage extends RootPage {

 

 	public DashboardPage() {

 		super();

-		setup(null);

 	}

 

 	public DashboardPage(PageParameters params) {

 		super(params);

-		setup(params);

 	}

 

 	@Override

@@ -86,115 +75,50 @@
 		return true;

 	}

 

-	private void setup(PageParameters params) {

-		setupPage("", "");

-		// check to see if we should display a login message

-		boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);

-		if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {

-			String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit");

-			String message = readMarkdown(messageSource, "login.mkd");

-			Component repositoriesMessage = new Label("repositoriesMessage", message);

-			add(repositoriesMessage.setEscapeModelStrings(false));

-			add(new Label("digests"));

-			add(new Label("active").setVisible(false));

-			add(new Label("starred").setVisible(false));

-			add(new Label("owned").setVisible(false));

-			add(new Label("feedheader").setVisible(false));

-			return;

-		}

-

-		// Load the markdown welcome message

-		String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit");

-		String message = readMarkdown(messageSource, "welcome.mkd");

-		Component repositoriesMessage = new Label("repositoriesMessage", message)

-				.setEscapeModelStrings(false).setVisible(message.length() > 0);

-		add(repositoriesMessage);

-

-		UserModel user = GitBlitWebSession.get().getUser();

-		if (user == null) {

-			user = UserModel.ANONYMOUS;

-		}

-

-		Comparator<RepositoryModel> lastUpdateSort = new Comparator<RepositoryModel>() {

-			@Override

-			public int compare(RepositoryModel o1, RepositoryModel o2) {

-				return o2.lastChange.compareTo(o1.lastChange);

-			}

-		};

-		

-		// parameters

-		int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params);

-		if (daysBack < 1) {

-			daysBack = 7;

-		}

+	protected void addActivity(UserModel user, Collection<RepositoryModel> repositories, int daysBack) {

 		Calendar c = Calendar.getInstance();

 		c.add(Calendar.DATE, -1*daysBack);

 		Date minimumDate = c.getTime();

 		TimeZone timezone = getTimeZone();

 		

-		// build repo lists 

-		List<RepositoryModel> starred = new ArrayList<RepositoryModel>();

-		List<RepositoryModel> owned = new ArrayList<RepositoryModel>();

-		List<RepositoryModel> active = new ArrayList<RepositoryModel>();

-

-		for (RepositoryModel model : getRepositoryModels()) {

-			if (model.isUsersPersonalRepository(user.username) || model.isOwner(user.username)) {

-				owned.add(model);

-			}

-			

-			if (user.getPreferences().isStarredRepository(model.name)) {

-				starred.add(model);

-			}

-			

-			if (model.isShowActivity() && model.lastChange.after(minimumDate)) {

-				active.add(model);

-			}

-		}

-		

-		Collections.sort(owned, lastUpdateSort);

-		Collections.sort(starred, lastUpdateSort);

-		Collections.sort(active, lastUpdateSort);

-		

-		Set<RepositoryModel> feedSources = new HashSet<RepositoryModel>();

-		feedSources.addAll(starred);

-		if (feedSources.isEmpty()) {

-			feedSources.addAll(active);

-		}

-		

 		// create daily commit digest feed

-		List<PushLogEntry> pushes = new ArrayList<PushLogEntry>();

-		for (RepositoryModel model : feedSources) {

+		List<DailyLogEntry> digests = new ArrayList<DailyLogEntry>();

+		for (RepositoryModel model : repositories) {

 			Repository repository = GitBlit.self().getRepository(model.name);

-			List<DailyLogEntry> entries = PushLogUtils.getDailyLogByRef(model.name, repository, minimumDate, timezone);

-			pushes.addAll(entries);

+			List<DailyLogEntry> entries = RefLogUtils.getDailyLogByRef(model.name, repository, minimumDate, timezone);

+			digests.addAll(entries);

 			repository.close();

 		}

 		

-		if (pushes.size() == 0) {

+		Fragment activityFragment = new Fragment("activity", "activityFragment", this);

+		add(activityFragment);

+		if (digests.size() == 0) {

 			// quiet or no starred repositories

-			if (feedSources.size() == 0) {

+			if (repositories.size() == 0) {

 				if (UserModel.ANONYMOUS.equals(user)) {

-					add(new Label("digests", getString("gb.noActivity")));	

+					activityFragment.add(new Label("digests", MessageFormat.format(getString("gb.noActivity"), daysBack)));	

 				} else {

-					add(new LinkPanel("digests", null, getString("gb.findSomeRepositories"), RepositoriesPage.class));

+					activityFragment.add(new LinkPanel("digests", null, getString("gb.findSomeRepositories"), RepositoriesPage.class));

 				}

 			} else {

-				add(new Label("digests", getString("gb.noActivity")));

+				activityFragment.add(new Label("digests", MessageFormat.format(getString("gb.noActivity"), daysBack)));

 			}

 		} else {

 			// show daily commit digest feed

-			Collections.sort(pushes);

-			add(new PushesPanel("digests", pushes));

+			Collections.sort(digests);

+			DigestsPanel digestsPanel = new DigestsPanel("digests", digests);

+			WicketUtils.setCssStyle(digestsPanel,  "margin-top:-20px");

+			activityFragment.add(digestsPanel);

 		}

 		

 		// add the nifty charts

-		if (!ArrayUtils.isEmpty(pushes)) {

+		if (!ArrayUtils.isEmpty(digests)) {

 			// aggregate author exclusions

 			Set<String> authorExclusions = new TreeSet<String>();

 			for (String author : GitBlit.getStrings(Keys.web.metricAuthorExclusions)) {

 				authorExclusions.add(author.toLowerCase());

 			}

-			for (RepositoryModel model : feedSources) {

+			for (RepositoryModel model : repositories) {

 				if (!ArrayUtils.isEmpty(model.metricAuthorExclusions)) {

 					for (String author : model.metricAuthorExclusions) {

 						authorExclusions.add(author.toLowerCase());

@@ -202,40 +126,10 @@
 				}

 			}

 

-			addCharts(pushes, authorExclusions, daysBack);

+			addCharts(activityFragment, digests, authorExclusions, daysBack);

 		} else {

-			add(new Label("feedheader").setVisible(false));

-		}

-		

-		// active repository list

-		if (starred.isEmpty()) {

-			Fragment activeView = createNgList("active", "activeListFragment", "activeCtrl", active);

-			add(activeView);

-		} else {

-			add(new Label("active").setVisible(false));

-		}

-		

-		// starred repository list

-		if (ArrayUtils.isEmpty(starred)) {

-			add(new Label("starred").setVisible(false));

-		} else {

-			Fragment starredView = createNgList("starred", "starredListFragment", "starredCtrl", starred);

-			add(starredView);

-		}

-		

-		// owned repository list

-		if (ArrayUtils.isEmpty(owned)) {

-			add(new Label("owned").setVisible(false));

-		} else {

-			Fragment ownedView = createNgList("owned", "ownedListFragment", "ownedCtrl", owned);

-			if (user.canCreate) {

-				// create button

-				ownedView.add(new LinkPanel("create", "btn btn-mini", getString("gb.newRepository"), EditRepositoryPage.class));

-			} else {

-				// no button

-				ownedView.add(new Label("create").setVisible(false));

-			}

-			add(ownedView);

+			activityFragment.add(new Label("charts").setVisible(false));

+			activityFragment.add(new Label("feedheader").setVisible(false));

 		}

 	}

 	

@@ -259,6 +153,7 @@
 			item.n = name;

 			item.p = path;

 			item.r = repo.name;

+			item.i = repo.description;

 			item.s = GitBlit.self().getStarCount(repo);

 			item.t = getTimeUtils().timeAgo(repo.lastChange);

 			item.d = df.format(repo.lastChange);

@@ -295,104 +190,32 @@
 		pages.add(menu);

 	}

 

-	private String readMarkdown(String messageSource, String resource) {

-		String message = "";

-		if (messageSource.equalsIgnoreCase("gitblit")) {

-			// Read default message

-			message = readDefaultMarkdown(resource);

-		} else {

-			// Read user-supplied message

-			if (!StringUtils.isEmpty(messageSource)) {

-				File file = GitBlit.getFileOrFolder(messageSource);

-				if (file.exists()) {

-					try {

-						FileInputStream fis = new FileInputStream(file);

-						InputStreamReader reader = new InputStreamReader(fis,

-								Constants.CHARACTER_ENCODING);

-						message = MarkdownUtils.transformMarkdown(reader);

-						reader.close();

-					} catch (Throwable t) {

-						message = getString("gb.failedToRead") + " " + file;

-						warn(message, t);

-					}

-				} else {

-					message = messageSource + " " + getString("gb.isNotValidFile");

-				}

-			}

-		}

-		return message;

-	}

 

-	private String readDefaultMarkdown(String file) {

-		String base = file.substring(0, file.lastIndexOf('.'));

-		String ext = file.substring(file.lastIndexOf('.'));

-		String lc = getLanguageCode();

-		String cc = getCountryCode();

-

-		// try to read file_en-us.ext, file_en.ext, file.ext

-		List<String> files = new ArrayList<String>();

-		if (!StringUtils.isEmpty(lc)) {

-			if (!StringUtils.isEmpty(cc)) {

-				files.add(base + "_" + lc + "-" + cc + ext);

-				files.add(base + "_" + lc + "_" + cc + ext);

-			}

-			files.add(base + "_" + lc + ext);

-		}

-		files.add(file);

-

-		for (String name : files) {

-			String message;

-			InputStreamReader reader = null;

-			try {

-				InputStream is = getClass().getResourceAsStream("/" + name);

-				if (is == null) {

-					continue;

-				}

-				reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING);

-				message = MarkdownUtils.transformMarkdown(reader);

-				reader.close();

-				return message;

-			} catch (Throwable t) {

-				message = MessageFormat.format(getString("gb.failedToReadMessage"), file);

-				error(message, t, false);

-				return message;

-			} finally {

-				if (reader != null) {

-					try {

-						reader.close();

-					} catch (Exception e) {

-					}

-				}

-			}			

-		}

-		return MessageFormat.format(getString("gb.failedToReadMessage"), file);

-	}

-	

 	/**

 	 * Creates the daily activity line chart, the active repositories pie chart,

 	 * and the active authors pie chart

 	 * 

-	 * @param recentPushes

+	 * @param recentChanges

 	 * @param authorExclusions

 	 * @param daysBack

 	 */

-	private void addCharts(List<PushLogEntry> recentPushes, Set<String> authorExclusions, int daysBack) {

+	protected void addCharts(Fragment frag, List<DailyLogEntry> recentChanges, Set<String> authorExclusions, int daysBack) {

 		// activity metrics

 		Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();

 		Map<String, Metric> authorMetrics = new HashMap<String, Metric>();

 

 		// aggregate repository and author metrics

 		int totalCommits = 0;

-		for (PushLogEntry push : recentPushes) {

+		for (RefLogEntry change : recentChanges) {

 

 			// aggregate repository metrics

-			String repository = StringUtils.stripDotGit(push.repository);

+			String repository = StringUtils.stripDotGit(change.repository);

 			if (!repositoryMetrics.containsKey(repository)) {

 				repositoryMetrics.put(repository, new Metric(repository));

 			}

 			repositoryMetrics.get(repository).count += 1;

 			

-			for (RepositoryCommit commit : push.getCommits()) {

+			for (RepositoryCommit commit : change.getCommits()) {

 				totalCommits++;

 				String author = StringUtils.removeNewlines(commit.getAuthorIdent().getName());

 				String authorName = author.toLowerCase();

@@ -406,7 +229,7 @@
 			}

 		}

 		

-		add(new Label("feedheader", MessageFormat.format(getString("gb.recentActivityStats"),

+		frag.add(new Label("feedheader", MessageFormat.format(getString("gb.recentActivityStats"),

 				daysBack, totalCommits, authorMetrics.size())));

 

 		// build google charts

@@ -430,10 +253,11 @@
 		chart.setShowLegend(false);

 		charts.addChart(chart);

 

-		add(new HeaderContributor(charts));

+		add(new HeaderContributor(charts));		

+		frag.add(new Fragment("charts", "chartsFragment", this));

 	}

 	

-	class RepoListItem implements Serializable {

+	protected class RepoListItem implements Serializable {

 

 		private static final long serialVersionUID = 1L;

 		

@@ -442,6 +266,7 @@
 		String p; // project/path

 		String t; // time ago

 		String d; // last updated

+		String i; // information/description

 		long s; // stars

 		String c; // html color

 		int wc; // working copy, 1 = true

diff --git a/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html
new file mode 100644
index 0000000..6b78b14
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.html
@@ -0,0 +1,158 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

+<html xmlns="http://www.w3.org/1999/xhtml"  

+      xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.3-strict.dtd"  

+      xml:lang="en"  

+      lang="en"> 

+

+<body>

+<wicket:extend>

+<div class="container">

+

+	<div class="row" style="padding-top:5px;">

+		<div class="span7">

+			<div class="hidden-phone markdown" style="padding-bottom: 30px;" wicket:id="repositoriesMessage">[repositories message]</div>

+			<div wicket:id="activity"></div>

+		</div>

+		<div class="span5">

+			<div wicket:id="repositoryTabs"></div>

+		</div>		

+	</div>

+</div>

+

+<wicket:fragment wicket:id="anonymousTabsFragment">

+	<ul class="nav nav-pills">

+		<li class="active"><a href="#recent" data-toggle="tab"><wicket:message key="gb.active">[active]</wicket:message></a></li>

+		<li><a href="#projects" data-toggle="tab"><wicket:message key="gb.projects">[projects]</wicket:message></a></li>

+	</ul>

+	<div class="tab-content">

+		<div class="tab-pane active" id="recent">

+			<div wicket:id="active">[recently active]</div>

+		</div>

+		<div class="tab-pane" id="projects">

+			<div wicket:id="projectList">[all projects]</div>

+		</div>

+	</div>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="authenticatedTabsFragment">

+	<ul class="nav nav-pills">

+		<li class="active"><a href="#starred" data-toggle="tab"><wicket:message key="gb.starred">[starred]</wicket:message></a></li>

+		<li><a href="#owned" data-toggle="tab"><wicket:message key="gb.owned">[owned]</wicket:message></a></li>

+		<li><a href="#recent" data-toggle="tab"><wicket:message key="gb.active">[active]</wicket:message></a></li>

+		<li><a href="#projects" data-toggle="tab"><wicket:message key="gb.projects">[projects]</wicket:message></a></li>

+	</ul>

+	<div class="tab-content">

+		<div class="tab-pane active" id="starred">

+			<div wicket:id="starred">[starred repositories]</div>

+		</div>

+		<div class="tab-pane" id="owned">

+			<div wicket:id="owned">[my repositories]</div>

+		</div>

+		<div class="tab-pane" id="recent">

+			<div wicket:id="active">[recently active]</div>

+		</div>

+		<div class="tab-pane" id="projects">

+			<div wicket:id="projectList">[all projects]</div>

+		</div>

+	</div>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="activityFragment">

+	<div class="dashboardTitle"><wicket:message key="gb.recentActivity"></wicket:message> <small><span wicket:id="feedheader"></span></small></div>

+	<div class="hidden-phone hidden-tablet"  style="text-align:center;">

+		<div wicket:id="charts"></div>

+	</div>

+	<div wicket:id="digests"></div>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="chartsFragment">

+	<table>

+		<tr>

+			<td><div id="chartRepositories" style="display:inline-block;width: 175px; height:175px"></div></td>

+			<td><div id="chartAuthors" style="display:inline-block;width: 175px; height: 175px;"></div></td>

+		</tr>

+	</table>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="starredListFragment">

+	<div ng-controller="starredCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">

+		<div class="header" style="padding: 5px;border: none;"><i class="icon-star"></i> <wicket:message key="gb.starredRepositories"></wicket:message> ({{starred.length}})

+			<div style="padding: 5px 0px 0px;">

+				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

+			</div>

+		</div>

+		

+		<div ng-repeat="item in starred | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

+			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

+			<a href="summary/?r={{item.r}}" title="{{item.i}}">{{item.p}}<b>{{item.n}}</b></a>

+			<span class="link hidden-tablet hidden-phone" style="color: #aaa;" title="{{item.d}}">{{item.t}}</span>

+			<span ng-show="item.s" class="pull-right">

+				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

+			</span>

+		</div>

+		

+	</div>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="ownedListFragment">

+	<div ng-controller="ownedCtrl" style="border: 1px solid #ddd;border-radius: 4px;">

+		<div class="header" style="padding: 5px;border: none;"><i class="icon-user"></i> <wicket:message key="gb.myRepositories"></wicket:message> ({{owned.length}})

+			<div class="hidden-phone pull-right">

+				<span wicket:id="create"></span>

+			</div>

+			<div style="padding: 5px 0px 0px;">

+				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

+			</div>

+		</div>

+		

+		<div ng-repeat="item in owned | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

+			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

+			<a href="summary/?r={{item.r}}" title="{{item.i}}">{{item.p}}<b>{{item.n}}</b></a>

+			<span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>

+			<span ng-show="item.s" class="pull-right">

+				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

+			</span>

+		</div>		

+	</div>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="activeListFragment">

+	<div ng-controller="activeCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">

+		<div class="header" style="padding: 5px;border: none;"><i class="icon-user"></i> <wicket:message key="gb.activeRepositories"></wicket:message> ({{active.length}})

+			<div style="padding: 5px 0px 0px;">

+				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

+			</div>

+		</div>

+		

+		<div ng-repeat="item in active | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

+			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

+			<a href="summary/?r={{item.r}}" title="{{item.i}}">{{item.p}}<b>{{item.n}}</b></a>

+			<span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>

+			<span ng-show="item.s" class="pull-right">

+				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

+			</span>

+		</div>		

+	</div>

+</wicket:fragment>

+

+<wicket:fragment wicket:id="projectListFragment">

+	<div ng-controller="projectListCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">

+		<div class="header" style="padding: 5px;border: none;"><i class="icon-folder-close"></i> <wicket:message key="gb.projects"></wicket:message> ({{projectList.length}})

+			<div style="padding: 5px 0px 0px;">

+				<input type="text" ng-model="query.n" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

+			</div>

+		</div>

+		

+		<div ng-repeat="item in projectList | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

+			<a href="project/{{item.p}}" title="{{item.i}}"><b>{{item.n}}</b></a>

+			<span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>

+			<span class="pull-right">

+				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;" wicket:message="title:gb.repositories">{{item.c | number}}</span>

+			</span>

+		</div>

+	</div>

+</wicket:fragment>

+

+</wicket:extend>

+</body>

+</html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java
new file mode 100644
index 0000000..b0c89b7
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/pages/MyDashboardPage.java
@@ -0,0 +1,311 @@
+/*

+ * Copyright 2013 gitblit.com.

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+package com.gitblit.wicket.pages;

+

+import java.io.File;

+import java.io.FileInputStream;

+import java.io.InputStream;

+import java.io.InputStreamReader;

+import java.io.Serializable;

+import java.text.DateFormat;

+import java.text.MessageFormat;

+import java.text.SimpleDateFormat;

+import java.util.ArrayList;

+import java.util.Calendar;

+import java.util.Collections;

+import java.util.Comparator;

+import java.util.Date;

+import java.util.HashSet;

+import java.util.List;

+import java.util.Set;

+

+import org.apache.wicket.Component;

+import org.apache.wicket.PageParameters;

+import org.apache.wicket.behavior.HeaderContributor;

+import org.apache.wicket.markup.html.basic.Label;

+import org.apache.wicket.markup.html.panel.Fragment;

+import org.eclipse.jgit.lib.Constants;

+

+import com.gitblit.GitBlit;

+import com.gitblit.Keys;

+import com.gitblit.models.ProjectModel;

+import com.gitblit.models.RepositoryModel;

+import com.gitblit.models.UserModel;

+import com.gitblit.utils.ArrayUtils;

+import com.gitblit.utils.MarkdownUtils;

+import com.gitblit.utils.StringUtils;

+import com.gitblit.wicket.GitBlitWebSession;

+import com.gitblit.wicket.WicketUtils;

+import com.gitblit.wicket.ng.NgController;

+import com.gitblit.wicket.panels.LinkPanel;

+

+public class MyDashboardPage extends DashboardPage {

+

+	public MyDashboardPage() {

+		super();

+		setup(null);

+	}

+

+	public MyDashboardPage(PageParameters params) {

+		super(params);

+		setup(params);

+	}

+

+	@Override

+	protected boolean reusePageParameters() {

+		return true;

+	}

+

+	private void setup(PageParameters params) {

+		setupPage("", "");

+		// check to see if we should display a login message

+		boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);

+		if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {

+			String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit");

+			String message = readMarkdown(messageSource, "login.mkd");

+			Component repositoriesMessage = new Label("repositoriesMessage", message);

+			add(repositoriesMessage.setEscapeModelStrings(false));

+			add(new Label("activity").setVisible(false));

+			add(new Label("repositoryTabs").setVisible(false));

+			return;

+		}

+

+		// Load the markdown welcome message

+		String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit");

+		String message = readMarkdown(messageSource, "welcome.mkd");

+		Component repositoriesMessage = new Label("repositoriesMessage", message)

+				.setEscapeModelStrings(false).setVisible(message.length() > 0);

+		add(repositoriesMessage);

+

+		UserModel user = GitBlitWebSession.get().getUser();

+		if (user == null) {

+			user = UserModel.ANONYMOUS;

+		}

+

+		// parameters

+		int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params);

+		if (daysBack < 1) {

+			daysBack = 7;

+		}

+		Calendar c = Calendar.getInstance();

+		c.add(Calendar.DATE, -1*daysBack);

+		Date minimumDate = c.getTime();

+		

+		// build repo lists 

+		List<RepositoryModel> starred = new ArrayList<RepositoryModel>();

+		List<RepositoryModel> owned = new ArrayList<RepositoryModel>();

+		List<RepositoryModel> active = new ArrayList<RepositoryModel>();

+

+		for (RepositoryModel model : getRepositoryModels()) {

+			if (model.isUsersPersonalRepository(user.username) || model.isOwner(user.username)) {

+				owned.add(model);

+			}

+			

+			if (user.getPreferences().isStarredRepository(model.name)) {

+				starred.add(model);

+			}

+			

+			if (model.isShowActivity() && model.lastChange.after(minimumDate)) {

+				active.add(model);

+			}

+		}

+		

+		Comparator<RepositoryModel> lastUpdateSort = new Comparator<RepositoryModel>() {

+			@Override

+			public int compare(RepositoryModel o1, RepositoryModel o2) {

+				return o2.lastChange.compareTo(o1.lastChange);

+			}

+		};

+		

+		Collections.sort(owned, lastUpdateSort);

+		Collections.sort(starred, lastUpdateSort);

+		Collections.sort(active, lastUpdateSort);

+		

+		Set<RepositoryModel> feed = new HashSet<RepositoryModel>();

+		feed.addAll(starred);

+		feed.addAll(owned);

+		if (feed.isEmpty()) {

+			feed.addAll(active);

+		}

+		

+		addActivity(user, feed, daysBack);

+		

+		Fragment repositoryTabs;

+		if (UserModel.ANONYMOUS.equals(user)) {

+			repositoryTabs = new Fragment("repositoryTabs", "anonymousTabsFragment", this);

+		} else {

+			repositoryTabs = new Fragment("repositoryTabs", "authenticatedTabsFragment", this);

+		}

+		

+		add(repositoryTabs);

+		

+		Fragment projectList = createProjectList();

+		repositoryTabs.add(projectList);

+		

+		// active repository list

+		if (active.isEmpty()) {

+			repositoryTabs.add(new Label("active").setVisible(false));

+		} else {

+			Fragment activeView = createNgList("active", "activeListFragment", "activeCtrl", active);

+			repositoryTabs.add(activeView);

+		}

+		

+		// starred repository list

+		if (ArrayUtils.isEmpty(starred)) {

+			repositoryTabs.add(new Label("starred").setVisible(false));

+		} else {

+			Fragment starredView = createNgList("starred", "starredListFragment", "starredCtrl", starred);

+			repositoryTabs.add(starredView);

+		}

+		

+		// owned repository list

+		if (ArrayUtils.isEmpty(owned)) {

+			repositoryTabs.add(new Label("owned").setVisible(false));

+		} else {

+			Fragment ownedView = createNgList("owned", "ownedListFragment", "ownedCtrl", owned);

+			if (user.canCreate) {

+				// create button

+				ownedView.add(new LinkPanel("create", "btn btn-mini", getString("gb.newRepository"), EditRepositoryPage.class));

+			} else {

+				// no button

+				ownedView.add(new Label("create").setVisible(false));

+			}

+			repositoryTabs.add(ownedView);

+		}

+	}

+	

+	private String readMarkdown(String messageSource, String resource) {

+		String message = "";

+		if (messageSource.equalsIgnoreCase("gitblit")) {

+			// Read default message

+			message = readDefaultMarkdown(resource);

+		} else {

+			// Read user-supplied message

+			if (!StringUtils.isEmpty(messageSource)) {

+				File file = GitBlit.getFileOrFolder(messageSource);

+				if (file.exists()) {

+					try {

+						FileInputStream fis = new FileInputStream(file);

+						InputStreamReader reader = new InputStreamReader(fis,

+								Constants.CHARACTER_ENCODING);

+						message = MarkdownUtils.transformMarkdown(reader);

+						reader.close();

+					} catch (Throwable t) {

+						message = getString("gb.failedToRead") + " " + file;

+						warn(message, t);

+					}

+				} else {

+					message = messageSource + " " + getString("gb.isNotValidFile");

+				}

+			}

+		}

+		return message;

+	}

+

+	private String readDefaultMarkdown(String file) {

+		String base = file.substring(0, file.lastIndexOf('.'));

+		String ext = file.substring(file.lastIndexOf('.'));

+		String lc = getLanguageCode();

+		String cc = getCountryCode();

+

+		// try to read file_en-us.ext, file_en.ext, file.ext

+		List<String> files = new ArrayList<String>();

+		if (!StringUtils.isEmpty(lc)) {

+			if (!StringUtils.isEmpty(cc)) {

+				files.add(base + "_" + lc + "-" + cc + ext);

+				files.add(base + "_" + lc + "_" + cc + ext);

+			}

+			files.add(base + "_" + lc + ext);

+		}

+		files.add(file);

+

+		for (String name : files) {

+			String message;

+			InputStreamReader reader = null;

+			try {

+				InputStream is = getClass().getResourceAsStream("/" + name);

+				if (is == null) {

+					continue;

+				}

+				reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING);

+				message = MarkdownUtils.transformMarkdown(reader);

+				reader.close();

+				return message;

+			} catch (Throwable t) {

+				message = MessageFormat.format(getString("gb.failedToReadMessage"), file);

+				error(message, t, false);

+				return message;

+			} finally {

+				if (reader != null) {

+					try {

+						reader.close();

+					} catch (Exception e) {

+					}

+				}

+			}			

+		}

+		return MessageFormat.format(getString("gb.failedToReadMessage"), file);

+	}

+	

+	protected Fragment createProjectList() {

+		String format = GitBlit.getString(Keys.web.datestampShortFormat, "MM/dd/yy");

+		final DateFormat df = new SimpleDateFormat(format);

+		df.setTimeZone(getTimeZone());

+		List<ProjectModel> projects = GitBlit.self().getProjectModels(getRepositoryModels(), false);

+		Collections.sort(projects, new Comparator<ProjectModel>() {

+			@Override

+			public int compare(ProjectModel o1, ProjectModel o2) {

+				return o2.lastChange.compareTo(o1.lastChange);

+			}

+		});

+

+		List<ProjectListItem> list = new ArrayList<ProjectListItem>();

+		for (ProjectModel proj : projects) {

+			if (proj.isUserProject() || proj.repositories.isEmpty()) {

+				// exclude user projects from list

+				continue;

+			}

+			ProjectListItem item = new ProjectListItem();

+			item.p = proj.name;

+			item.n = StringUtils.isEmpty(proj.title) ? proj.name : proj.title;

+			item.i = proj.description;

+			item.t = getTimeUtils().timeAgo(proj.lastChange);

+			item.d = df.format(proj.lastChange);

+			item.c = proj.repositories.size();

+			list.add(item);

+		}

+		

+		// inject an AngularJS controller with static data

+		NgController ctrl = new NgController("projectListCtrl");

+		ctrl.addVariable("projectList", list);

+		add(new HeaderContributor(ctrl));

+		

+		Fragment fragment = new Fragment("projectList", "projectListFragment", this);

+		return fragment;

+	}

+	

+	protected class ProjectListItem implements Serializable {

+

+		private static final long serialVersionUID = 1L;

+		

+		String p; // path

+		String n; // name

+		String t; // time ago

+		String d; // last updated

+		String i; // information/description

+		long c;   // repository count

+	}

+}

diff --git a/src/main/java/com/gitblit/wicket/pages/OverviewPage.html b/src/main/java/com/gitblit/wicket/pages/OverviewPage.html
index 3340e31..995f8df 100644
--- a/src/main/java/com/gitblit/wicket/pages/OverviewPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/OverviewPage.html
@@ -48,7 +48,7 @@
 		<div class="span6">

 			<div class="hidden-tablet" style="padding-bottom: 10px; margin-bottom: 10px; border-bottom: 1px solid #ddd;" wicket:id="repositoryUrlPanel">[repository url panel]</div>

 		

-			<div wicket:id="pushesPanel">[pushes panel]</div>	

+			<div wicket:id="reflogPanel">[reflog panel]</div>	

 		</div>

 	</div>

 

diff --git a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java
index 42d20c5..8848767 100644
--- a/src/main/java/com/gitblit/wicket/pages/OverviewPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/OverviewPage.java
@@ -41,7 +41,7 @@
 import com.gitblit.wicket.charting.GoogleLineChart;

 import com.gitblit.wicket.panels.BranchesPanel;

 import com.gitblit.wicket.panels.LinkPanel;

-import com.gitblit.wicket.panels.PushesPanel;

+import com.gitblit.wicket.panels.ReflogPanel;

 import com.gitblit.wicket.panels.RepositoryUrlPanel;

 import com.gitblit.wicket.panels.TagsPanel;

 

@@ -113,9 +113,9 @@
 

 		add(new RepositoryUrlPanel("repositoryUrlPanel", false, user, model));

 

-		int pushCount = GitBlit.getInteger(Keys.web.overviewPushCount, 5);

-		PushesPanel pushes = new PushesPanel("pushesPanel", getRepositoryModel(), r, pushCount, 0, false);

-		add(pushes);

+		int reflogCount = GitBlit.getInteger(Keys.web.overviewReflogCount, 5);

+		ReflogPanel reflog = new ReflogPanel("reflogPanel", getRepositoryModel(), r, reflogCount, 0);

+		add(reflog);

 		add(new TagsPanel("tagsPanel", repositoryName, r, numberRefs).hideIfEmpty());

 		add(new BranchesPanel("branchesPanel", getRepositoryModel(), r, numberRefs, false).hideIfEmpty());

 

diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectPage.html b/src/main/java/com/gitblit/wicket/pages/ProjectPage.html
index 3b5d4e6..9fbe1b2 100644
--- a/src/main/java/com/gitblit/wicket/pages/ProjectPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/ProjectPage.html
@@ -6,66 +6,70 @@
 

 <body>

 <wicket:extend>

-

-<div class="container">

-	<div class="row">

-		<div class="span12">

-			<h2><span wicket:id="projectTitle"></span> <small><span wicket:id="projectDescription"></span></small>

-				<a class="hidden-phone hidden-tablet brand" style="text-decoration: none;" wicket:id="syndication" wicket:message="title:gb.feed">

-					<img style="border:0px;vertical-align:middle;" src="feed_16x16.png"></img>

-				</a>

-			</h2>

-			<div class="markdown" wicket:id="projectMessage">[project message]</div>

+		<div class="container">

+			<div class="row" style="padding-top:5px;">

+				<div class="span12">

+					<div class="dashboardTitle">

+						<span wicket:id="projectTitle"></span>

+						<small><span wicket:id="projectDescription"></span></small>

+						

+						<a

+							class="hidden-phone hidden-tablet brand"

+							style="text-decoration: none;" wicket:id="syndication"

+							wicket:message="title:gb.feed"> <img

+							style="border: 0px; vertical-align: middle;" src="feed_16x16.png"></img>

+						</a>

+					</div>

+				</div>

+			</div>

+			

+			<div class="row">

+				<div class="span7">					

+					<div class="markdown" style="padding-bottom: 30px;" wicket:id="projectMessage">[project message]</div>

+					<div wicket:id="activity">[activity panel]</div>

+				</div>

+				<div class="span5">

+					<div class="markdown" wicket:id="repositoriesMessage">[repositories message]</div>

+					<div wicket:id="repositoryList">[repository list]</div>

+				</div>

+			</div>

 		</div>

+

+<wicket:fragment wicket:id="activityFragment">

+	<div class="dashboardTitle"><wicket:message key="gb.recentActivity"></wicket:message> <small><span wicket:id="feedheader"></span></small></div>

+	<div class="hidden-phone hidden-tablet"  style="text-align:center;">

+		<div wicket:id="charts"></div>

 	</div>

+	<div wicket:id="digests"></div>

+</wicket:fragment>

 

-	<div class="tabbable">

-		<!-- tab titles -->

-		<ul class="nav nav-tabs">

-			<li class="active"><a href="#repositories" data-toggle="tab"><wicket:message key="gb.repositories"></wicket:message></a></li>

-			<li ><a href="#activity" data-toggle="tab"><wicket:message key="gb.activity"></wicket:message></a></li>

-		</ul>

-	

-		<!-- tab content -->

-		<div class="tab-content">

-

-			<!-- repositories tab -->

-			<div class="tab-pane active" id="repositories">

-				<!-- markdown -->

-				<div class="row">

-					<div class="span12">

-						<div class="markdown" wicket:id="repositoriesMessage">[repositories message]</div>

-					</div>

-				</div>

-				<div class="row">

-					<div class="span6" wicket:id="repositoryList">

-						<span wicket:id="repository"></span>

-					</div>

-				</div>				

-			</div>

-			

-			<!-- activity tab -->

-			<div class="tab-pane" id="activity">

-				<div class="pageTitle">

-					<h2><wicket:message key="gb.recentActivity"></wicket:message><small> <span class="hidden-phone">/ <span wicket:id="subheader">[days back]</span></span></small></h2>

-				</div>

-			

-				<div class="hidden-phone" style="height: 155px;text-align: center;">

-					<table>

-					<tr>

-						<td><span class="hidden-tablet" id="chartDaily"></span></td>

-						<td><span id="chartRepositories"></span></td>

-						<td><span id="chartAuthors"></span></td>

-					</tr>

-					</table>

-				</div>

-			

-				<div wicket:id="activityPanel">[activity panel]</div>

-			</div>

+<wicket:fragment wicket:id="chartsFragment">

+	<table>

+		<tr>

+			<td><div id="chartRepositories" style="display:inline-block;width: 175px; height:175px"></div></td>

+			<td><div id="chartAuthors" style="display:inline-block;width: 175px; height: 175px;"></div></td>

+		</tr>

+	</table>

+</wicket:fragment>

 		

+<wicket:fragment wicket:id="repositoryListFragment">

+	<div ng-controller="repositoryListCtrl" style="border: 1px solid #ddd;border-radius: 4px;margin-bottom: 20px;">

+		<div class="header" style="padding: 5px;border: none;"><img style="vertical-align: middle;" src="git-black-16x16.png"/> <wicket:message key="gb.repositories"></wicket:message> ({{repositoryList.length}})

+			<div style="padding: 5px 0px 0px;">

+				<input type="text" ng-model="query.r" class="input-large" wicket:message="placeholder:gb.filter" style="border-radius: 14px; padding: 3px 14px;margin: 0px;"></input>

+			</div>

 		</div>

+		

+		<div ng-repeat="item in repositoryList | filter:query" style="padding: 3px;border-top: 1px solid #ddd;">

+			<b><span class="repositorySwatch" style="background-color:{{item.c}};"><span ng-show="item.wc">!</span><span ng-show="!item.wc">&nbsp;</span></span></b>

+			<a href="summary/?r={{item.r}}" title="{{item.i}}">{{item.p}}<b>{{item.n}}</b></a>

+			<span class="link hidden-tablet hidden-phone" style="color: #bbb;" title="{{item.d}}">{{item.t}}</span>

+			<span ng-show="item.s" class="pull-right">

+				<span style="padding: 0px 5px;color: #888;font-weight:bold;vertical-align:middle;">{{item.s | number}} <i style="vertical-align:baseline;" class="iconic-star"></i></span>

+			</span>

+		</div>		

 	</div>

-	</div>

-</wicket:extend>

+</wicket:fragment>		

+	</wicket:extend>

 </body>

 </html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectPage.java b/src/main/java/com/gitblit/wicket/pages/ProjectPage.java
index 7eba033..c64e900 100644
--- a/src/main/java/com/gitblit/wicket/pages/ProjectPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/ProjectPage.java
@@ -15,34 +15,23 @@
  */

 package com.gitblit.wicket.pages;

 

-import java.text.MessageFormat;

-import java.text.SimpleDateFormat;

 import java.util.ArrayList;

 import java.util.Collections;

 import java.util.Comparator;

-import java.util.HashMap;

-import java.util.HashSet;

 import java.util.List;

-import java.util.Map;

-import java.util.Set;

 

 import org.apache.wicket.Component;

 import org.apache.wicket.PageParameters;

-import org.apache.wicket.behavior.HeaderContributor;

 import org.apache.wicket.markup.html.basic.Label;

 import org.apache.wicket.markup.html.link.ExternalLink;

-import org.apache.wicket.markup.repeater.Item;

-import org.apache.wicket.markup.repeater.data.DataView;

-import org.apache.wicket.markup.repeater.data.ListDataProvider;

+import org.apache.wicket.markup.html.panel.Fragment;

 

 import com.gitblit.GitBlit;

 import com.gitblit.Keys;

 import com.gitblit.SyndicationServlet;

-import com.gitblit.models.Activity;

-import com.gitblit.models.Metric;

 import com.gitblit.models.ProjectModel;

 import com.gitblit.models.RepositoryModel;

-import com.gitblit.utils.ActivityUtils;

+import com.gitblit.models.UserModel;

 import com.gitblit.utils.MarkdownUtils;

 import com.gitblit.utils.StringUtils;

 import com.gitblit.wicket.GitBlitWebApp;

@@ -52,14 +41,8 @@
 import com.gitblit.wicket.PageRegistration.DropDownMenuItem;

 import com.gitblit.wicket.PageRegistration.DropDownMenuRegistration;

 import com.gitblit.wicket.WicketUtils;

-import com.gitblit.wicket.charting.GoogleChart;

-import com.gitblit.wicket.charting.GoogleCharts;

-import com.gitblit.wicket.charting.GoogleLineChart;

-import com.gitblit.wicket.charting.GooglePieChart;

-import com.gitblit.wicket.panels.ActivityPanel;

-import com.gitblit.wicket.panels.ProjectRepositoryPanel;

 

-public class ProjectPage extends RootPage {

+public class ProjectPage extends DashboardPage {

 	

 	List<ProjectModel> projectModels = new ArrayList<ProjectModel>();

 

@@ -72,10 +55,9 @@
 		super(params);

 		setup(params);

 	}

-

-	@Override

-	protected boolean reusePageParameters() {

-		return true;

+	

+	protected Class<? extends BasePage> getRootNavPageClass() {

+		return RepositoriesPage.class;

 	}

 

 	private void setup(PageParameters params) {

@@ -118,8 +100,20 @@
 				.setEscapeModelStrings(false).setVisible(rmessage.length() > 0);

 		add(repositoriesMessage);

 

-		List<RepositoryModel> repositories = getRepositories(params);

+		UserModel user = GitBlitWebSession.get().getUser();

+		if (user == null) {

+			user = UserModel.ANONYMOUS;

+		}

+		int daysBack = params == null ? 0 : WicketUtils.getDaysBack(params);

+		if (daysBack < 1) {

+			daysBack = 7;

+		}

+		// reset the daysback parameter so that we have a complete project

+		// repository list.  the recent activity will be built up by the

+		// reflog utils.

+		params.put("db", 0);

 		

+		List<RepositoryModel> repositories = getRepositories(params);

 		Collections.sort(repositories, new Comparator<RepositoryModel>() {

 			@Override

 			public int compare(RepositoryModel o1, RepositoryModel o2) {

@@ -128,145 +122,21 @@
 			}

 		});

 

-		final ListDataProvider<RepositoryModel> dp = new ListDataProvider<RepositoryModel>(repositories);

-		DataView<RepositoryModel> dataView = new DataView<RepositoryModel>("repositoryList", dp) {

-			private static final long serialVersionUID = 1L;

-

-			public void populateItem(final Item<RepositoryModel> item) {

-				final RepositoryModel entry = item.getModelObject();

-				

-				ProjectRepositoryPanel row = new ProjectRepositoryPanel("repository", 

-						getLocalizer(), this, showAdmin, entry, getAccessRestrictions());

-				item.add(row);

-			}

-		};

-		add(dataView);

-

-		// project activity

-		// parameters

-		int daysBack = WicketUtils.getDaysBack(params);

-		if (daysBack < 1) {

-			daysBack = 14;

-		}

-		String objectId = WicketUtils.getObject(params);

-

-		List<Activity> recentActivity = ActivityUtils.getRecentActivity(repositories, 

-				daysBack, objectId, getTimeZone());

-		if (recentActivity.size() == 0) {

-			// no activity, skip graphs and activity panel

-			add(new Label("subheader", MessageFormat.format(getString("gb.recentActivityNone"),

-					daysBack)));

-			add(new Label("activityPanel"));

+		

+		addActivity(user, repositories, daysBack);

+		

+		if (repositories.isEmpty()) {

+			add(new Label("repositoryList").setVisible(false));

 		} else {

-			// calculate total commits and total authors

-			int totalCommits = 0;

-			Set<String> uniqueAuthors = new HashSet<String>();

-			for (Activity activity : recentActivity) {

-				totalCommits += activity.getCommitCount();

-				uniqueAuthors.addAll(activity.getAuthorMetrics().keySet());

-			}

-			int totalAuthors = uniqueAuthors.size();

-

-			// add the subheader with stat numbers

-			add(new Label("subheader", MessageFormat.format(getString("gb.recentActivityStats"),

-					daysBack, totalCommits, totalAuthors)));

-

-			// create the activity charts

-			GoogleCharts charts = createCharts(recentActivity);

-			add(new HeaderContributor(charts));

-

-			// add activity panel

-			add(new ActivityPanel("activityPanel", recentActivity));

+			Fragment activeView = createNgList("repositoryList", "repositoryListFragment", "repositoryListCtrl", repositories);

+			add(activeView);

 		}

 	}

 	

-	/**

-	 * Creates the daily activity line chart, the active repositories pie chart,

-	 * and the active authors pie chart

-	 * 

-	 * @param recentActivity

-	 * @return

-	 */

-	private GoogleCharts createCharts(List<Activity> recentActivity) {

-		// activity metrics

-		Map<String, Metric> repositoryMetrics = new HashMap<String, Metric>();

-		Map<String, Metric> authorMetrics = new HashMap<String, Metric>();

-

-		// aggregate repository and author metrics

-		for (Activity activity : recentActivity) {

-

-			// aggregate author metrics

-			for (Map.Entry<String, Metric> entry : activity.getAuthorMetrics().entrySet()) {

-				String author = entry.getKey();

-				if (!authorMetrics.containsKey(author)) {

-					authorMetrics.put(author, new Metric(author));

-				}

-				authorMetrics.get(author).count += entry.getValue().count;

-			}

-

-			// aggregate repository metrics

-			for (Map.Entry<String, Metric> entry : activity.getRepositoryMetrics().entrySet()) {

-				String repository = StringUtils.stripDotGit(entry.getKey());

-				if (!repositoryMetrics.containsKey(repository)) {

-					repositoryMetrics.put(repository, new Metric(repository));

-				}

-				repositoryMetrics.get(repository).count += entry.getValue().count;

-			}

-		}

-

-		// build google charts

-		int w = 310;

-		int h = 150;

-		GoogleCharts charts = new GoogleCharts();

-

-		// sort in reverse-chronological order and then reverse that

-		Collections.sort(recentActivity);

-		Collections.reverse(recentActivity);

-

-		// daily line chart

-		GoogleChart chart = new GoogleLineChart("chartDaily", getString("gb.dailyActivity"), "day",

-				getString("gb.commits"));

-		SimpleDateFormat df = new SimpleDateFormat("MMM dd");

-		df.setTimeZone(getTimeZone());

-		for (Activity metric : recentActivity) {

-			chart.addValue(df.format(metric.startDate), metric.getCommitCount());

-		}

-		chart.setWidth(w);

-		chart.setHeight(h);

-		charts.addChart(chart);

-

-		// active repositories pie chart

-		chart = new GooglePieChart("chartRepositories", getString("gb.activeRepositories"),

-				getString("gb.repository"), getString("gb.commits"));

-		for (Metric metric : repositoryMetrics.values()) {

-			chart.addValue(metric.name, metric.count);

-		}

-		chart.setWidth(w);

-		chart.setHeight(h);

-		charts.addChart(chart);

-

-		// active authors pie chart

-		chart = new GooglePieChart("chartAuthors", getString("gb.activeAuthors"),

-				getString("gb.author"), getString("gb.commits"));

-		for (Metric metric : authorMetrics.values()) {

-			chart.addValue(metric.name, metric.count);

-		}

-		chart.setWidth(w);

-		chart.setHeight(h);

-		charts.addChart(chart);

-

-		return charts;

-	}

-

 	@Override

 	protected void addDropDownMenus(List<PageRegistration> pages) {

 		PageParameters params = getPageParameters();

 

-		DropDownMenuRegistration projects = new DropDownMenuRegistration("gb.projects",

-				ProjectPage.class);

-		projects.menuItems.addAll(getProjectsMenu());

-		pages.add(0, projects);

-

 		DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",

 				ProjectPage.class);

 		// preserve time filter option on repository choices

@@ -277,10 +147,15 @@
 

 		if (menu.menuItems.size() > 0) {

 			// Reset Filter

-			menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), null, null));

+			menu.menuItems.add(new DropDownMenuItem(getString("gb.reset"), "p", WicketUtils.getProjectName(params)));

 		}

 

 		pages.add(menu);

+		

+		DropDownMenuRegistration projects = new DropDownMenuRegistration("gb.projects",

+				ProjectPage.class);

+		projects.menuItems.addAll(getProjectsMenu());

+		pages.add(projects);

 	}

 	

 	@Override

diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectsPage.html b/src/main/java/com/gitblit/wicket/pages/ProjectsPage.html
index caa0f81..2d446ec 100644
--- a/src/main/java/com/gitblit/wicket/pages/ProjectsPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/ProjectsPage.html
@@ -7,7 +7,6 @@
 <body>

 <wicket:extend>

 <div class="container">

-	<div class="markdown" style="padding-bottom:5px;" wicket:id="projectsMessage">[projects message]</div>

 	

 	<table class="repositories">

 		<thead>

diff --git a/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java b/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java
index 7f0b002..d0001ec 100644
--- a/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/ProjectsPage.java
@@ -15,29 +15,17 @@
  */

 package com.gitblit.wicket.pages;

 

-import java.io.File;

-import java.io.FileInputStream;

-import java.io.InputStream;

-import java.io.InputStreamReader;

-import java.text.MessageFormat;

-import java.util.ArrayList;

 import java.util.List;

 

-import org.apache.wicket.Component;

 import org.apache.wicket.PageParameters;

 import org.apache.wicket.markup.html.basic.Label;

 import org.apache.wicket.markup.repeater.Item;

 import org.apache.wicket.markup.repeater.data.DataView;

 import org.apache.wicket.markup.repeater.data.ListDataProvider;

-import org.apache.wicket.resource.ContextRelativeResource;

-import org.apache.wicket.util.resource.ResourceStreamNotFoundException;

-import org.eclipse.jgit.lib.Constants;

 

 import com.gitblit.GitBlit;

 import com.gitblit.Keys;

 import com.gitblit.models.ProjectModel;

-import com.gitblit.utils.MarkdownUtils;

-import com.gitblit.utils.StringUtils;

 import com.gitblit.wicket.GitBlitWebSession;

 import com.gitblit.wicket.PageRegistration;

 import com.gitblit.wicket.PageRegistration.DropDownMenuItem;

@@ -63,6 +51,11 @@
 	}

 	

 	@Override

+	protected Class<? extends BasePage> getRootNavPageClass() {

+		return RepositoriesPage.class;

+	}

+

+	@Override

 	protected List<ProjectModel> getProjectModels() {

 		return GitBlit.self().getProjectModels(getRepositoryModels(), false);

 	}

@@ -72,21 +65,10 @@
 		// check to see if we should display a login message

 		boolean authenticateView = GitBlit.getBoolean(Keys.web.authenticateViewPages, true);

 		if (authenticateView && !GitBlitWebSession.get().isLoggedIn()) {

-			String messageSource = GitBlit.getString(Keys.web.loginMessage, "gitblit");

-			String message = readMarkdown(messageSource, "login.mkd");

-			Component repositoriesMessage = new Label("projectsMessage", message);

-			add(repositoriesMessage.setEscapeModelStrings(false));

 			add(new Label("projectsPanel"));

 			return;

 		}

 

-		// Load the markdown welcome message

-		String messageSource = GitBlit.getString(Keys.web.repositoriesMessage, "gitblit");

-		String message = readMarkdown(messageSource, "welcome.mkd");

-		Component projectsMessage = new Label("projectsMessage", message).setEscapeModelStrings(

-				false).setVisible(message.length() > 0);

-		add(projectsMessage);

-

 		List<ProjectModel> projects = getProjects(params);

 

 		ListDataProvider<ProjectModel> dp = new ListDataProvider<ProjectModel>(projects);

@@ -130,20 +112,12 @@
 			}

 		};

 		add(dataView);

-

-		// push the panel down if we are hiding the admin controls and the

-		// welcome message

-		if (!showAdmin && !projectsMessage.isVisible()) {

-			WicketUtils.setCssStyle(dataView, "padding-top:5px;");

-		}

 	}

 

 	@Override

 	protected void addDropDownMenus(List<PageRegistration> pages) {

 		PageParameters params = getPageParameters();

 		

-		pages.add(0, new PageRegistration("gb.projects", ProjectsPage.class, params));

-

 		DropDownMenuRegistration menu = new DropDownMenuRegistration("gb.filters",

 				ProjectsPage.class);

 		// preserve time filter option on repository choices

@@ -159,77 +133,4 @@
 

 		pages.add(menu);

 	}

-

-	private String readMarkdown(String messageSource, String resource) {

-		String message = "";

-		if (messageSource.equalsIgnoreCase("gitblit")) {

-			// Read default message

-			message = readDefaultMarkdown(resource);

-		} else {

-			// Read user-supplied message

-			if (!StringUtils.isEmpty(messageSource)) {

-				File file = new File(messageSource);

-				if (file.exists()) {

-					try {

-						FileInputStream fis = new FileInputStream(file);

-						InputStreamReader reader = new InputStreamReader(fis,

-								Constants.CHARACTER_ENCODING);

-						message = MarkdownUtils.transformMarkdown(reader);

-						reader.close();

-					} catch (Throwable t) {

-						message = getString("gb.failedToRead") + " " + file;

-						warn(message, t);

-					}

-				} else {

-					message = messageSource + " " + getString("gb.isNotValidFile");

-				}

-			}

-		}

-		return message;

-	}

-

-	private String readDefaultMarkdown(String file) {

-		String base = file.substring(0, file.lastIndexOf('.'));

-		String ext = file.substring(file.lastIndexOf('.'));

-		String lc = getLanguageCode();

-		String cc = getCountryCode();

-

-		// try to read file_en-us.ext, file_en.ext, file.ext

-		List<String> files = new ArrayList<String>();

-		if (!StringUtils.isEmpty(lc)) {

-			if (!StringUtils.isEmpty(cc)) {

-				files.add(base + "_" + lc + "-" + cc + ext);

-				files.add(base + "_" + lc + "_" + cc + ext);

-			}

-			files.add(base + "_" + lc + ext);

-		}

-		files.add(file);

-		

-		for (String name : files) {

-			String message;

-			InputStreamReader reader = null;

-			try {

-				ContextRelativeResource res = WicketUtils.getResource(name);

-				InputStream is = res.getResourceStream().getInputStream();

-				reader = new InputStreamReader(is, Constants.CHARACTER_ENCODING);

-				message = MarkdownUtils.transformMarkdown(reader);

-				reader.close();

-				return message;

-			} catch (ResourceStreamNotFoundException t) {

-				continue;

-			} catch (Throwable t) {

-				message = MessageFormat.format(getString("gb.failedToReadMessage"), file);

-				error(message, t, false);

-				return message;

-			} finally {

-				if (reader != null) {

-					try {

-						reader.close();

-					} catch (Exception e) {

-					}

-				}

-			}			

-		}

-		return MessageFormat.format(getString("gb.failedToReadMessage"), file);

-	}

 }

diff --git a/src/main/java/com/gitblit/wicket/pages/PushesPage.html b/src/main/java/com/gitblit/wicket/pages/ReflogPage.html
similarity index 91%
rename from src/main/java/com/gitblit/wicket/pages/PushesPage.html
rename to src/main/java/com/gitblit/wicket/pages/ReflogPage.html
index 145db6f..c0ac7eb 100644
--- a/src/main/java/com/gitblit/wicket/pages/PushesPage.html
+++ b/src/main/java/com/gitblit/wicket/pages/ReflogPage.html
@@ -12,8 +12,8 @@
 		<a wicket:id="firstPage"><wicket:message key="gb.pageFirst"></wicket:message></a> | <a wicket:id="prevPage">&laquo; <wicket:message key="gb.pagePrevious"></wicket:message></a> | <a wicket:id="nextPage"><wicket:message key="gb.pageNext"></wicket:message> &raquo;</a> 

 	</div>

 	

-	<!-- push log -->

-	<div style="margin-top:5px;" wicket:id="pushesPanel">[push log panel]</div>

+	<!-- ref log -->

+	<div style="margin-top:5px;" wicket:id="reflogPanel">[reflog panel]</div>

 

 	<!-- pager links -->

 	<div style="padding-bottom:5px;">

diff --git a/src/main/java/com/gitblit/wicket/pages/PushesPage.java b/src/main/java/com/gitblit/wicket/pages/ReflogPage.java
similarity index 72%
rename from src/main/java/com/gitblit/wicket/pages/PushesPage.java
rename to src/main/java/com/gitblit/wicket/pages/ReflogPage.java
index 866964a..884f616 100644
--- a/src/main/java/com/gitblit/wicket/pages/PushesPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/ReflogPage.java
@@ -19,11 +19,11 @@
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;

 

 import com.gitblit.wicket.WicketUtils;

-import com.gitblit.wicket.panels.PushesPanel;

+import com.gitblit.wicket.panels.ReflogPanel;

 

-public class PushesPage extends RepositoryPage {

+public class ReflogPage extends RepositoryPage {

 

-	public PushesPage(PageParameters params) {

+	public ReflogPage(PageParameters params) {

 		super(params);

 

 		addSyndicationDiscoveryLink();

@@ -32,24 +32,24 @@
 		int prevPage = Math.max(0, pageNumber - 1);

 		int nextPage = pageNumber + 1;

 

-		PushesPanel pushesPanel = new PushesPanel("pushesPanel", getRepositoryModel(), getRepository(), -1,

-				pageNumber - 1, false);

-		boolean hasMore = pushesPanel.hasMore();

-		add(pushesPanel);

+		ReflogPanel reflogPanel = new ReflogPanel("reflogPanel", getRepositoryModel(), getRepository(), -1,

+				pageNumber - 1);

+		boolean hasMore = reflogPanel.hasMore();

+		add(reflogPanel);

 

-		add(new BookmarkablePageLink<Void>("firstPage", PushesPage.class,

+		add(new BookmarkablePageLink<Void>("firstPage", ReflogPage.class,

 				WicketUtils.newObjectParameter(repositoryName, objectId))

 				.setEnabled(pageNumber > 1));

-		add(new BookmarkablePageLink<Void>("prevPage", PushesPage.class,

+		add(new BookmarkablePageLink<Void>("prevPage", ReflogPage.class,

 				WicketUtils.newLogPageParameter(repositoryName, objectId, prevPage))

 				.setEnabled(pageNumber > 1));

-		add(new BookmarkablePageLink<Void>("nextPage", PushesPage.class,

+		add(new BookmarkablePageLink<Void>("nextPage", ReflogPage.class,

 				WicketUtils.newLogPageParameter(repositoryName, objectId, nextPage))

 				.setEnabled(hasMore));

 	}

 

 	@Override

 	protected String getPageName() {

-		return getString("gb.pushes");

+		return getString("gb.reflog");

 	}

 }

diff --git a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
index a15dd91..9657301 100644
--- a/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/RepositoryPage.java
@@ -60,7 +60,7 @@
 import com.gitblit.utils.ArrayUtils;

 import com.gitblit.utils.DeepCopier;

 import com.gitblit.utils.JGitUtils;

-import com.gitblit.utils.PushLogUtils;

+import com.gitblit.utils.RefLogUtils;

 import com.gitblit.utils.StringUtils;

 import com.gitblit.utils.TicgitUtils;

 import com.gitblit.wicket.GitBlitWebSession;

@@ -187,12 +187,12 @@
 		RepositoryModel model = getRepositoryModel();

 

 		// standard links

-		if (PushLogUtils.getPushLogBranch(r) == null) {

+		if (RefLogUtils.getRefLogBranch(r) == null) {

 			pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));

 		} else {

 			pages.put("summary", new PageRegistration("gb.summary", SummaryPage.class, params));

 //			pages.put("overview", new PageRegistration("gb.overview", OverviewPage.class, params));

-			pages.put("pushes", new PageRegistration("gb.pushes", PushesPage.class, params));

+			pages.put("reflog", new PageRegistration("gb.reflog", ReflogPage.class, params));

 		}		

 		pages.put("commits", new PageRegistration("gb.commits", LogPage.class, params));

 		pages.put("tree", new PageRegistration("gb.tree", TreePage.class, params));

diff --git a/src/main/java/com/gitblit/wicket/pages/RootPage.java b/src/main/java/com/gitblit/wicket/pages/RootPage.java
index d21be36..8c1a568 100644
--- a/src/main/java/com/gitblit/wicket/pages/RootPage.java
+++ b/src/main/java/com/gitblit/wicket/pages/RootPage.java
@@ -119,7 +119,7 @@
 		// navigation links

 		List<PageRegistration> pages = new ArrayList<PageRegistration>();

 		if (!authenticateView || (authenticateView && GitBlitWebSession.get().isLoggedIn())) {

-			pages.add(new PageRegistration(GitBlitWebSession.get().isLoggedIn() ? "gb.myDashboard" : "gb.dashboard", DashboardPage.class,

+			pages.add(new PageRegistration(GitBlitWebSession.get().isLoggedIn() ? "gb.myDashboard" : "gb.dashboard", MyDashboardPage.class,

 					getRootPageParameters()));

 			pages.add(new PageRegistration("gb.repositories", RepositoriesPage.class,

 					getRootPageParameters()));

diff --git a/src/main/java/com/gitblit/wicket/panels/PushesPanel.html b/src/main/java/com/gitblit/wicket/panels/DigestsPanel.html
similarity index 65%
copy from src/main/java/com/gitblit/wicket/panels/PushesPanel.html
copy to src/main/java/com/gitblit/wicket/panels/DigestsPanel.html
index fb67cfc..53a8104 100644
--- a/src/main/java/com/gitblit/wicket/panels/PushesPanel.html
+++ b/src/main/java/com/gitblit/wicket/panels/DigestsPanel.html
@@ -6,15 +6,15 @@
 

 <body>

 <wicket:panel>

-<div wicket:id="push" class="push">

+<div wicket:id="change" class="reflog">

 	<table style="padding: 3px 0px;">

 	<tr>

-		<td class="icon hidden-phone"><i wicket:id="pushIcon"></i></td>

+		<td class="icon hidden-phone"><i wicket:id="changeIcon"></i></td>

 		<td style="padding-left: 7px;vertical-align:middle;">

 			<div>

-				<span style="color:#aaa;" wicket:id="whenPushed"></span> <span wicket:id="refRewind" class="alert alert-error" style="padding: 1px 5px;font-size: 10px;font-weight: bold;margin-left: 10px;">[rewind]</span>

+				<span class="when" wicket:id="whenChanged"></span>

 			</div>

-			<div style="font-weight:bold;"><span wicket:id="whoPushed">[pusher]</span> <span wicket:id="whatPushed"></span><span wicket:id="refPushed"></span> <span wicket:id="repoPreposition"></span> <span wicket:id="repoPushed"></span> <span wicket:id="byAuthors"></span></div>

+			<div style="font-weight:bold;"><span wicket:id="whoChanged">[who changed]</span> <span wicket:id="whatChanged"></span><span wicket:id="refChanged"></span> <span wicket:id="repoPreposition"></span> <span wicket:id="repoChanged"></span> <span wicket:id="byAuthors"></span></div>

 		</td>

 	</tr>

 	<tr>

@@ -37,7 +37,6 @@
 	</tr>	

 	</table>

 </div>

-<div wicket:id="morePushes">[more...]</div>

 </wicket:panel>

 </body>

 </html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/panels/DigestsPanel.java b/src/main/java/com/gitblit/wicket/panels/DigestsPanel.java
new file mode 100644
index 0000000..0f380a4
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/panels/DigestsPanel.java
@@ -0,0 +1,273 @@
+/*

+ * Copyright 2013 gitblit.com.

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+package com.gitblit.wicket.panels;

+

+import java.text.DateFormat;

+import java.text.MessageFormat;

+import java.text.SimpleDateFormat;

+import java.util.ArrayList;

+import java.util.Calendar;

+import java.util.Date;

+import java.util.List;

+import java.util.TimeZone;

+

+import org.apache.wicket.markup.html.basic.Label;

+import org.apache.wicket.markup.repeater.Item;

+import org.apache.wicket.markup.repeater.data.DataView;

+import org.apache.wicket.markup.repeater.data.ListDataProvider;

+

+import com.gitblit.Constants;

+import com.gitblit.GitBlit;

+import com.gitblit.Keys;

+import com.gitblit.models.DailyLogEntry;

+import com.gitblit.models.RepositoryCommit;

+import com.gitblit.utils.StringUtils;

+import com.gitblit.utils.TimeUtils;

+import com.gitblit.wicket.WicketUtils;

+import com.gitblit.wicket.pages.CommitPage;

+import com.gitblit.wicket.pages.ComparePage;

+import com.gitblit.wicket.pages.SummaryPage;

+import com.gitblit.wicket.pages.TagPage;

+import com.gitblit.wicket.pages.TreePage;

+import com.gitblit.wicket.pages.UserPage;

+

+public class DigestsPanel extends BasePanel {

+

+	private static final long serialVersionUID = 1L;

+

+	private final boolean hasChanges;

+	

+	private boolean hasMore;

+

+	public DigestsPanel(String wicketId, List<DailyLogEntry> digests) {

+		super(wicketId);

+		hasChanges = digests.size() > 0;

+

+		final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6);

+

+		String dateFormat = GitBlit.getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");

+		final TimeZone timezone = getTimeZone();

+		final DateFormat df = new SimpleDateFormat(dateFormat);

+		df.setTimeZone(timezone);

+		final Calendar cal = Calendar.getInstance(timezone);

+		

+		ListDataProvider<DailyLogEntry> dp = new ListDataProvider<DailyLogEntry>(digests);

+		DataView<DailyLogEntry> pushView = new DataView<DailyLogEntry>("change", dp) {

+			private static final long serialVersionUID = 1L;

+

+			public void populateItem(final Item<DailyLogEntry> logItem) {

+				final DailyLogEntry change = logItem.getModelObject();

+				String fullRefName = change.getChangedRefs().get(0);

+				String shortRefName = fullRefName;

+				boolean isTag = false;

+				if (shortRefName.startsWith(Constants.R_HEADS)) {

+					shortRefName = shortRefName.substring(Constants.R_HEADS.length());

+				} else if (shortRefName.startsWith(Constants.R_TAGS)) {

+					shortRefName = shortRefName.substring(Constants.R_TAGS.length());

+					isTag = true;

+				}

+				

+				String fuzzydate;

+				TimeUtils tu = getTimeUtils();

+				Date pushDate = change.date;

+				if (TimeUtils.isToday(pushDate, timezone)) {

+					fuzzydate = tu.today();

+				} else if (TimeUtils.isYesterday(pushDate, timezone)) {

+					fuzzydate = tu.yesterday();

+				} else {

+					// calculate a fuzzy time ago date

+                	cal.setTime(pushDate);

+                	cal.set(Calendar.HOUR_OF_DAY, 0);

+                	cal.set(Calendar.MINUTE, 0);

+                	cal.set(Calendar.SECOND, 0);

+                	cal.set(Calendar.MILLISECOND, 0);

+                	pushDate = cal.getTime();

+					fuzzydate = getTimeUtils().timeAgo(pushDate);

+				}

+				logItem.add(new Label("whenChanged", fuzzydate + ", " + df.format(pushDate)));

+

+				Label changeIcon = new Label("changeIcon");

+				// use the repository hash color to differentiate the icon.

+                String color = StringUtils.getColor(StringUtils.stripDotGit(change.repository));

+                WicketUtils.setCssStyle(changeIcon, "color: " + color);

+

+				if (isTag) {

+					WicketUtils.setCssClass(changeIcon, "iconic-tag");

+				} else {

+					WicketUtils.setCssClass(changeIcon, "iconic-loop");

+				}

+				logItem.add(changeIcon);

+

+                if (!isTag) {

+                	logItem.add(new Label("whoChanged").setVisible(false));

+                } else {

+                	if (change.user.username.equals(change.user.emailAddress) && change.user.emailAddress.indexOf('@') > -1) {

+                		// username is an email address can not link - 1.2.1 push log bug

+                		logItem.add(new Label("whoChanged", change.user.getDisplayName()));

+                	} else {

+                		// link to user account page

+                		logItem.add(new LinkPanel("whoChanged", null, change.user.getDisplayName(),

+                				UserPage.class, WicketUtils.newUsernameParameter(change.user.username)));

+                	}

+                }

+				

+				String preposition = "gb.of";

+				boolean isDelete = false;

+				String what;

+				String by = null;

+				switch(change.getChangeType(fullRefName)) {

+				case CREATE:

+					if (isTag) {

+						// new tag

+						what = getString("gb.createdNewTag");

+						preposition = "gb.in";

+					} else {

+						// new branch

+						what = getString("gb.createdNewBranch");

+						preposition = "gb.in";

+					}

+					break;

+				case DELETE:

+					isDelete = true;

+					if (isTag) {

+						what = getString("gb.deletedTag");

+					} else {

+						what = getString("gb.deletedBranch");

+					}

+					preposition = "gb.from";

+					break;

+				default:

+					what = MessageFormat.format(change.getCommitCount() > 1 ? getString("gb.commitsTo") : getString("gb.oneCommitTo"), change.getCommitCount());

+					

+					if (change.getAuthorCount() == 1) {

+						by = MessageFormat.format(getString("gb.byOneAuthor"), change.getAuthorIdent().getName());

+					} else {

+						by = MessageFormat.format(getString("gb.byNAuthors"), change.getAuthorCount());	

+					}

+					break;

+				}

+				logItem.add(new Label("whatChanged", what));

+				logItem.add(new Label("byAuthors", by).setVisible(!StringUtils.isEmpty(by)));

+				

+				if (isDelete) {

+					// can't link to deleted ref

+					logItem.add(new Label("refChanged", shortRefName));

+				} else if (isTag) {

+					// link to tag

+					logItem.add(new LinkPanel("refChanged", null, shortRefName,

+							TagPage.class, WicketUtils.newObjectParameter(change.repository, fullRefName)));

+				} else {

+					// link to tree

+					logItem.add(new LinkPanel("refChanged", null, shortRefName,

+						TreePage.class, WicketUtils.newObjectParameter(change.repository, fullRefName)));

+				}

+				

+				// to/from/etc

+				logItem.add(new Label("repoPreposition", getString(preposition)));

+				String repoName = StringUtils.stripDotGit(change.repository);

+				logItem.add(new LinkPanel("repoChanged", null, repoName,

+						SummaryPage.class, WicketUtils.newRepositoryParameter(change.repository)));

+				

+				int maxCommitCount = 5;

+				List<RepositoryCommit> commits = change.getCommits();

+				if (commits.size() > maxCommitCount) {

+					commits = new ArrayList<RepositoryCommit>(commits.subList(0,  maxCommitCount));					

+				}

+				

+				// compare link

+				String compareLinkText = null;

+				if ((change.getCommitCount() <= maxCommitCount) && (change.getCommitCount() > 1)) {

+					compareLinkText = MessageFormat.format(getString("gb.viewComparison"), commits.size());

+				} else if (change.getCommitCount() > maxCommitCount) {

+					int diff = change.getCommitCount() - maxCommitCount;

+					compareLinkText = MessageFormat.format(diff > 1 ? getString("gb.nMoreCommits") : getString("gb.oneMoreCommit"), diff);

+				}

+				if (StringUtils.isEmpty(compareLinkText)) {

+					logItem.add(new Label("compareLink").setVisible(false));

+				} else {

+					String endRangeId = change.getNewId(fullRefName);

+					String startRangeId = change.getOldId(fullRefName);

+					logItem.add(new LinkPanel("compareLink", null, compareLinkText, ComparePage.class, WicketUtils.newRangeParameter(change.repository, startRangeId, endRangeId)));

+				}

+				

+				final boolean showSwatch = GitBlit.getBoolean(Keys.web.repositoryListSwatches, true);

+				

+				ListDataProvider<RepositoryCommit> cdp = new ListDataProvider<RepositoryCommit>(commits);

+				DataView<RepositoryCommit> commitsView = new DataView<RepositoryCommit>("commit", cdp) {

+					private static final long serialVersionUID = 1L;

+

+					public void populateItem(final Item<RepositoryCommit> commitItem) {

+						final RepositoryCommit commit = commitItem.getModelObject();

+

+						// author gravatar

+						commitItem.add(new GravatarImage("commitAuthor", commit.getAuthorIdent().getName(),

+								commit.getAuthorIdent().getEmailAddress(), null, 16, false, false));

+						

+						// merge icon

+						if (commit.getParentCount() > 1) {

+							commitItem.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));

+						} else {

+							commitItem.add(WicketUtils.newBlankImage("commitIcon"));

+						}

+

+						// short message

+						String shortMessage = commit.getShortMessage();

+						String trimmedMessage = shortMessage;

+						if (commit.getRefs() != null && commit.getRefs().size() > 0) {

+							trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);

+						} else {

+							trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);

+						}

+						LinkPanel shortlog = new LinkPanel("commitShortMessage", "list",

+								trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(

+										change.repository, commit.getName()));

+						if (!shortMessage.equals(trimmedMessage)) {

+							WicketUtils.setHtmlTooltip(shortlog, shortMessage);

+						}

+						commitItem.add(shortlog);

+

+						// commit hash link

+						LinkPanel commitHash = new LinkPanel("hashLink", null, commit.getName().substring(0, hashLen),

+								CommitPage.class, WicketUtils.newObjectParameter(

+										change.repository, commit.getName()));

+						WicketUtils.setCssClass(commitHash, "shortsha1");

+						WicketUtils.setHtmlTooltip(commitHash, commit.getName());

+						commitItem.add(commitHash);

+						

+						if (showSwatch) {

+							// set repository color

+							String color = StringUtils.getColor(StringUtils.stripDotGit(change.repository));

+							WicketUtils.setCssStyle(commitItem, MessageFormat.format("border-left: 2px solid {0};", color));

+						}

+					}

+				};

+

+				logItem.add(commitsView);

+			}

+		};

+		

+		add(pushView);

+	}

+

+	public boolean hasMore() {

+		return hasMore;

+	}

+	

+	public boolean hideIfEmpty() {

+		setVisible(hasChanges);

+		return hasChanges;

+	}

+}

diff --git a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
index e9196cd..02d67e3 100644
--- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
+++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.html
@@ -70,8 +70,6 @@
 					<wicket:message key="gb.lastChange">[last change]</wicket:message> <span wicket:id="repositoryLastChange">[last change]</span>,

 					<span style="font-size:0.8em;" wicket:id="repositorySize">[repository size]</span>

 				</div>

-        

-				<div class="hidden-phone hidden-tablet" style="padding-top: 5px;" wicket:id="repositoryPrimaryUrl">[repository primary url]</div>

 			</div>

 		</div>

 	</div>

diff --git a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
index e7fe017..37641d3 100644
--- a/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
+++ b/src/main/java/com/gitblit/wicket/panels/ProjectRepositoryPanel.java
@@ -192,7 +192,5 @@
 		}

 

 		add(new ExternalLink("syndication", SyndicationServlet.asLink("", entry.name, null, 0)));

-

-		add(new RepositoryUrlPanel("repositoryPrimaryUrl", true, user, entry));

 	}

 }

diff --git a/src/main/java/com/gitblit/wicket/panels/PushesPanel.java b/src/main/java/com/gitblit/wicket/panels/PushesPanel.java
deleted file mode 100644
index 5c473f7..0000000
--- a/src/main/java/com/gitblit/wicket/panels/PushesPanel.java
+++ /dev/null
@@ -1,381 +0,0 @@
-/*

- * Copyright 2013 gitblit.com.

- *

- * Licensed under the Apache License, Version 2.0 (the "License");

- * you may not use this file except in compliance with the License.

- * You may obtain a copy of the License at

- *

- *     http://www.apache.org/licenses/LICENSE-2.0

- *

- * Unless required by applicable law or agreed to in writing, software

- * distributed under the License is distributed on an "AS IS" BASIS,

- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

- * See the License for the specific language governing permissions and

- * limitations under the License.

- */

-package com.gitblit.wicket.panels;

-

-import java.text.DateFormat;

-import java.text.MessageFormat;

-import java.text.SimpleDateFormat;

-import java.util.ArrayList;

-import java.util.Calendar;

-import java.util.Date;

-import java.util.List;

-import java.util.TimeZone;

-

-import org.apache.wicket.markup.html.basic.Label;

-import org.apache.wicket.markup.repeater.Item;

-import org.apache.wicket.markup.repeater.data.DataView;

-import org.apache.wicket.markup.repeater.data.ListDataProvider;

-import org.apache.wicket.model.StringResourceModel;

-import org.eclipse.jgit.lib.Repository;

-

-import com.gitblit.Constants;

-import com.gitblit.GitBlit;

-import com.gitblit.Keys;

-import com.gitblit.models.DailyLogEntry;

-import com.gitblit.models.PushLogEntry;

-import com.gitblit.models.RepositoryCommit;

-import com.gitblit.models.RepositoryModel;

-import com.gitblit.utils.PushLogUtils;

-import com.gitblit.utils.StringUtils;

-import com.gitblit.utils.TimeUtils;

-import com.gitblit.wicket.WicketUtils;

-import com.gitblit.wicket.pages.CommitPage;

-import com.gitblit.wicket.pages.ComparePage;

-import com.gitblit.wicket.pages.PushesPage;

-import com.gitblit.wicket.pages.SummaryPage;

-import com.gitblit.wicket.pages.TagPage;

-import com.gitblit.wicket.pages.TreePage;

-import com.gitblit.wicket.pages.UserPage;

-

-public class PushesPanel extends BasePanel {

-

-	private static final long serialVersionUID = 1L;

-

-	private final boolean hasPushes;

-	

-	private boolean hasMore;

-

-	public PushesPanel(String wicketId, final RepositoryModel model, Repository r, int limit, int pageOffset, boolean showRepo) {

-		super(wicketId);

-		boolean pageResults = limit <= 0;

-		int pushesPerPage = GitBlit.getInteger(Keys.web.pushesPerPage, 10);

-		if (pushesPerPage <= 1) {

-			pushesPerPage = 10;

-		}

-

-		List<PushLogEntry> pushes;

-		if (pageResults) {

-			pushes = PushLogUtils.getPushLogByRef(model.name, r, pageOffset * pushesPerPage, pushesPerPage);

-		} else {

-			pushes = PushLogUtils.getPushLogByRef(model.name, r, limit);

-		}

-

-		// inaccurate way to determine if there are more commits.

-		// works unless commits.size() represents the exact end.

-		hasMore = pushes.size() >= pushesPerPage;

-		hasPushes = pushes.size() > 0;

-		

-		setup(pushes, showRepo);

-		

-		// determine to show pager, more, or neither

-		if (limit <= 0) {

-			// no display limit

-			add(new Label("morePushes").setVisible(false));

-		} else {

-			if (pageResults) {

-				// paging

-				add(new Label("morePushes").setVisible(false));

-			} else {

-				// more

-				if (pushes.size() == limit) {

-					// show more

-					add(new LinkPanel("morePushes", "link", new StringResourceModel("gb.morePushes",

-							this, null), PushesPage.class,

-							WicketUtils.newRepositoryParameter(model.name)));

-				} else {

-					// no more

-					add(new Label("morePushes").setVisible(false));

-				}

-			}

-		}

-	}

-	

-	public PushesPanel(String wicketId, List<PushLogEntry> pushes) {

-		super(wicketId);

-		hasPushes = pushes.size() > 0;

-		setup(pushes, true);

-		add(new Label("morePushes").setVisible(false));

-	}

-	

-	protected void setup(List<PushLogEntry> pushes, final boolean showRepo) {

-		final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6);

-

-		String dateFormat = GitBlit.getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");

-		final TimeZone timezone = getTimeZone();

-		final DateFormat df = new SimpleDateFormat(dateFormat);

-		df.setTimeZone(timezone);

-		final Calendar cal = Calendar.getInstance(timezone);

-		

-		ListDataProvider<PushLogEntry> dp = new ListDataProvider<PushLogEntry>(pushes);

-		DataView<PushLogEntry> pushView = new DataView<PushLogEntry>("push", dp) {

-			private static final long serialVersionUID = 1L;

-

-			public void populateItem(final Item<PushLogEntry> pushItem) {

-				final PushLogEntry push = pushItem.getModelObject();

-				String fullRefName = push.getChangedRefs().get(0);

-				String shortRefName = fullRefName;

-				boolean isTag = false;

-				boolean isPull = false;

-				if (shortRefName.startsWith(Constants.R_HEADS)) {

-					shortRefName = shortRefName.substring(Constants.R_HEADS.length());

-				} else if (shortRefName.startsWith(Constants.R_TAGS)) {

-					shortRefName = shortRefName.substring(Constants.R_TAGS.length());

-					isTag = true;

-				} else if (shortRefName.startsWith(Constants.R_PULL)) {

-					shortRefName = "#" + shortRefName.substring(Constants.R_PULL.length());

-					if (shortRefName.endsWith("/head")) {

-						// strip pull request head from name 

-						shortRefName = shortRefName.substring(0, shortRefName.length() - "/head".length());

-					}					

-					isPull = true;

-				}

-				boolean isDigest = push instanceof DailyLogEntry;

-				

-				String fuzzydate;

-				TimeUtils tu = getTimeUtils();

-				Date pushDate = push.date;

-				if (TimeUtils.isToday(pushDate, timezone)) {

-					fuzzydate = tu.today();

-				} else if (TimeUtils.isYesterday(pushDate, timezone)) {

-					fuzzydate = tu.yesterday();

-				} else {

-					// calculate a fuzzy time ago date

-                	cal.setTime(pushDate);

-                	cal.set(Calendar.HOUR_OF_DAY, 0);

-                	cal.set(Calendar.MINUTE, 0);

-                	cal.set(Calendar.SECOND, 0);

-                	cal.set(Calendar.MILLISECOND, 0);

-                	pushDate = cal.getTime();

-					fuzzydate = getTimeUtils().timeAgo(pushDate);

-				}

-				pushItem.add(new Label("whenPushed", fuzzydate + ", " + df.format(pushDate)));

-

-				Label pushIcon = new Label("pushIcon");

-				if (showRepo) {

-					// if we are showing the repo, we are showing multiple

-					// repos.  use the repository hash color to differentiate

-					// the icon.

-	                String color = StringUtils.getColor(StringUtils.stripDotGit(push.repository));

-	                WicketUtils.setCssStyle(pushIcon, "color: " + color);

-				}

-				if (isTag) {

-					WicketUtils.setCssClass(pushIcon, "iconic-tag");

-				} else if (isPull) {

-					WicketUtils.setCssClass(pushIcon, "iconic-share");

-				} else if (isDigest) {

-					WicketUtils.setCssClass(pushIcon, "iconic-loop");

-				} else {

-					WicketUtils.setCssClass(pushIcon, "iconic-upload");

-				}

-				pushItem.add(pushIcon);

-

-                if (isDigest && !isTag) {

-                	pushItem.add(new Label("whoPushed").setVisible(false));

-                } else {

-                	if (push.user.username.equals(push.user.emailAddress) && push.user.emailAddress.indexOf('@') > -1) {

-                		// username is an email address - 1.2.1 push log bug

-                		pushItem.add(new Label("whoPushed", push.user.getDisplayName()));

-                	} else {

-                		// link to user account page

-                		pushItem.add(new LinkPanel("whoPushed", null, push.user.getDisplayName(),

-                				UserPage.class, WicketUtils.newUsernameParameter(push.user.username)));

-                	}

-                }

-				

-				String preposition = "gb.of";

-				boolean isDelete = false;

-				boolean isRewind = false;

-				String what;

-				String by = null;

-				switch(push.getChangeType(fullRefName)) {

-				case CREATE:

-					if (isTag) {

-						// new tag

-						if (isDigest) {

-							what = getString("gb.createdNewTag");

-							preposition = "gb.in";

-						} else {

-							what = getString("gb.pushedNewTag");

-							preposition = "gb.to";

-						}

-					} else if (isPull) {

-						// merged pull request

-						what = getString("gb.mergedPullRequest");

-						preposition = "gb.in";

-					} else {

-						// new branch

-						if (isDigest) {

-							what = getString("gb.createdNewBranch");

-							preposition = "gb.in";

-						} else {

-							what = getString("gb.pushedNewBranch");

-							preposition = "gb.to";

-						}

-					}

-					break;

-				case DELETE:

-					isDelete = true;

-					if (isTag) {

-						what = getString("gb.deletedTag");

-					} if (isPull) {

-						what = getString("gb.deletedTag");

-					} else {

-						what = getString("gb.deletedBranch");

-					}

-					preposition = "gb.from";

-					break;

-				case UPDATE_NONFASTFORWARD:

-					isRewind = true;

-				default:

-					if (isDigest) {

-						what = MessageFormat.format(push.getCommitCount() > 1 ? getString("gb.commitsTo") : getString("gb.oneCommitTo"), push.getCommitCount());

-					} else {

-						what = MessageFormat.format(push.getCommitCount() > 1 ? getString("gb.pushedNCommitsTo") : getString("gb.pushedOneCommitTo") , push.getCommitCount());

-					}

-					

-					if (push.getAuthorCount() == 1) {

-						by = MessageFormat.format(getString("gb.byOneAuthor"), push.getAuthorIdent().getName());

-					} else {

-						by = MessageFormat.format(getString("gb.byNAuthors"), push.getAuthorCount());	

-					}

-					break;

-				}

-				pushItem.add(new Label("whatPushed", what));

-				pushItem.add(new Label("byAuthors", by).setVisible(!StringUtils.isEmpty(by)));

-				

-				pushItem.add(new Label("refRewind", getString("gb.rewind")).setVisible(isRewind));

-				

-				if (isDelete) {

-					// can't link to deleted ref

-					pushItem.add(new Label("refPushed", shortRefName));

-				} else if (isTag) {

-					// link to tag

-					pushItem.add(new LinkPanel("refPushed", null, shortRefName,

-							TagPage.class, WicketUtils.newObjectParameter(push.repository, fullRefName)));

-				} else if (isPull) {

-					// link to pull request

-					pushItem.add(new LinkPanel("refPushed", null, shortRefName,

-							TagPage.class, WicketUtils.newObjectParameter(push.repository, fullRefName)));

-				} else {

-					// link to tree

-					pushItem.add(new LinkPanel("refPushed", null, shortRefName,

-						TreePage.class, WicketUtils.newObjectParameter(push.repository, fullRefName)));

-				}

-				

-				if (showRepo) {

-					// to/from/etc

-					pushItem.add(new Label("repoPreposition", getString(preposition)));

-

-					String repoName = StringUtils.stripDotGit(push.repository);

-					pushItem.add(new LinkPanel("repoPushed", null, repoName,

-							SummaryPage.class, WicketUtils.newRepositoryParameter(push.repository)));

-				} else {

-					// do not display repository name if we are viewing the push

-					// log of a repository.

-					pushItem.add(new Label("repoPreposition").setVisible(false));

-					pushItem.add(new Label("repoPushed").setVisible(false));

-				}

-				

-				int maxCommitCount = 5;

-				List<RepositoryCommit> commits = push.getCommits();

-				if (commits.size() > maxCommitCount) {

-					commits = new ArrayList<RepositoryCommit>(commits.subList(0,  maxCommitCount));					

-				}

-				

-				// compare link

-				String compareLinkText = null;

-				if ((push.getCommitCount() <= maxCommitCount) && (push.getCommitCount() > 1)) {

-					compareLinkText = MessageFormat.format(getString("gb.viewComparison"), commits.size());

-				} else if (push.getCommitCount() > maxCommitCount) {

-					int diff = push.getCommitCount() - maxCommitCount;

-					compareLinkText = MessageFormat.format(diff > 1 ? getString("gb.nMoreCommits") : getString("gb.oneMoreCommit"), diff);

-				}

-				if (StringUtils.isEmpty(compareLinkText)) {

-					pushItem.add(new Label("compareLink").setVisible(false));

-				} else {

-					String endRangeId = push.getNewId(fullRefName);

-					String startRangeId = push.getOldId(fullRefName);

-					pushItem.add(new LinkPanel("compareLink", null, compareLinkText, ComparePage.class, WicketUtils.newRangeParameter(push.repository, startRangeId, endRangeId)));

-				}

-				

-				final boolean showSwatch = showRepo && GitBlit.getBoolean(Keys.web.repositoryListSwatches, true);

-				

-				ListDataProvider<RepositoryCommit> cdp = new ListDataProvider<RepositoryCommit>(commits);

-				DataView<RepositoryCommit> commitsView = new DataView<RepositoryCommit>("commit", cdp) {

-					private static final long serialVersionUID = 1L;

-

-					public void populateItem(final Item<RepositoryCommit> commitItem) {

-						final RepositoryCommit commit = commitItem.getModelObject();

-

-						// author gravatar

-						commitItem.add(new GravatarImage("commitAuthor", commit.getAuthorIdent().getName(),

-								commit.getAuthorIdent().getEmailAddress(), null, 16, false, false));

-						

-						// merge icon

-						if (commit.getParentCount() > 1) {

-							commitItem.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));

-						} else {

-							commitItem.add(WicketUtils.newBlankImage("commitIcon"));

-						}

-

-						// short message

-						String shortMessage = commit.getShortMessage();

-						String trimmedMessage = shortMessage;

-						if (commit.getRefs() != null && commit.getRefs().size() > 0) {

-							trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);

-						} else {

-							trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);

-						}

-						LinkPanel shortlog = new LinkPanel("commitShortMessage", "list",

-								trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(

-										push.repository, commit.getName()));

-						if (!shortMessage.equals(trimmedMessage)) {

-							WicketUtils.setHtmlTooltip(shortlog, shortMessage);

-						}

-						commitItem.add(shortlog);

-

-						// commit hash link

-						LinkPanel commitHash = new LinkPanel("hashLink", null, commit.getName().substring(0, hashLen),

-								CommitPage.class, WicketUtils.newObjectParameter(

-										push.repository, commit.getName()));

-						WicketUtils.setCssClass(commitHash, "shortsha1");

-						WicketUtils.setHtmlTooltip(commitHash, commit.getName());

-						commitItem.add(commitHash);

-						

-						if (showSwatch) {

-							// set repository color

-							String color = StringUtils.getColor(StringUtils.stripDotGit(push.repository));

-							WicketUtils.setCssStyle(commitItem, MessageFormat.format("border-left: 2px solid {0};", color));

-						}

-					}

-				};

-

-				pushItem.add(commitsView);

-			}

-		};

-		

-		add(pushView);

-	}

-

-	public boolean hasMore() {

-		return hasMore;

-	}

-	

-	public boolean hideIfEmpty() {

-		setVisible(hasPushes);

-		return hasPushes;

-	}

-}

diff --git a/src/main/java/com/gitblit/wicket/panels/PushesPanel.html b/src/main/java/com/gitblit/wicket/panels/ReflogPanel.html
similarity index 65%
rename from src/main/java/com/gitblit/wicket/panels/PushesPanel.html
rename to src/main/java/com/gitblit/wicket/panels/ReflogPanel.html
index fb67cfc..0148d89 100644
--- a/src/main/java/com/gitblit/wicket/panels/PushesPanel.html
+++ b/src/main/java/com/gitblit/wicket/panels/ReflogPanel.html
@@ -6,15 +6,15 @@
 

 <body>

 <wicket:panel>

-<div wicket:id="push" class="push">

+<div wicket:id="change" class="reflog">

 	<table style="padding: 3px 0px;">

 	<tr>

-		<td class="icon hidden-phone"><i wicket:id="pushIcon"></i></td>

+		<td class="icon hidden-phone"><i wicket:id="changeIcon"></i></td>

 		<td style="padding-left: 7px;vertical-align:middle;">

 			<div>

-				<span style="color:#aaa;" wicket:id="whenPushed"></span> <span wicket:id="refRewind" class="alert alert-error" style="padding: 1px 5px;font-size: 10px;font-weight: bold;margin-left: 10px;">[rewind]</span>

+				<span class="when" wicket:id="whenChanged"></span> <span wicket:id="refRewind" class="alert alert-error" style="padding: 1px 5px;font-size: 10px;font-weight: bold;margin-left: 10px;">[rewind]</span>

 			</div>

-			<div style="font-weight:bold;"><span wicket:id="whoPushed">[pusher]</span> <span wicket:id="whatPushed"></span><span wicket:id="refPushed"></span> <span wicket:id="repoPreposition"></span> <span wicket:id="repoPushed"></span> <span wicket:id="byAuthors"></span></div>

+			<div style="font-weight:bold;"><span wicket:id="whoChanged">[change author]</span> <span wicket:id="whatChanged"></span><span wicket:id="refChanged"></span> <span wicket:id="byAuthors"></span></div>

 		</td>

 	</tr>

 	<tr>

@@ -37,7 +37,7 @@
 	</tr>	

 	</table>

 </div>

-<div wicket:id="morePushes">[more...]</div>

+<div wicket:id="moreChanges">[more...]</div>

 </wicket:panel>

 </body>

 </html>
\ No newline at end of file
diff --git a/src/main/java/com/gitblit/wicket/panels/ReflogPanel.java b/src/main/java/com/gitblit/wicket/panels/ReflogPanel.java
new file mode 100644
index 0000000..048ce1b
--- /dev/null
+++ b/src/main/java/com/gitblit/wicket/panels/ReflogPanel.java
@@ -0,0 +1,305 @@
+/*

+ * Copyright 2013 gitblit.com.

+ *

+ * Licensed under the Apache License, Version 2.0 (the "License");

+ * you may not use this file except in compliance with the License.

+ * You may obtain a copy of the License at

+ *

+ *     http://www.apache.org/licenses/LICENSE-2.0

+ *

+ * Unless required by applicable law or agreed to in writing, software

+ * distributed under the License is distributed on an "AS IS" BASIS,

+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+ * See the License for the specific language governing permissions and

+ * limitations under the License.

+ */

+package com.gitblit.wicket.panels;

+

+import java.text.DateFormat;

+import java.text.MessageFormat;

+import java.text.SimpleDateFormat;

+import java.util.ArrayList;

+import java.util.Calendar;

+import java.util.Date;

+import java.util.List;

+import java.util.TimeZone;

+

+import org.apache.wicket.markup.html.basic.Label;

+import org.apache.wicket.markup.repeater.Item;

+import org.apache.wicket.markup.repeater.data.DataView;

+import org.apache.wicket.markup.repeater.data.ListDataProvider;

+import org.apache.wicket.model.StringResourceModel;

+import org.eclipse.jgit.lib.Repository;

+

+import com.gitblit.Constants;

+import com.gitblit.GitBlit;

+import com.gitblit.Keys;

+import com.gitblit.models.RefLogEntry;

+import com.gitblit.models.RepositoryCommit;

+import com.gitblit.models.RepositoryModel;

+import com.gitblit.utils.RefLogUtils;

+import com.gitblit.utils.StringUtils;

+import com.gitblit.utils.TimeUtils;

+import com.gitblit.wicket.WicketUtils;

+import com.gitblit.wicket.pages.CommitPage;

+import com.gitblit.wicket.pages.ComparePage;

+import com.gitblit.wicket.pages.ReflogPage;

+import com.gitblit.wicket.pages.TagPage;

+import com.gitblit.wicket.pages.TreePage;

+import com.gitblit.wicket.pages.UserPage;

+

+public class ReflogPanel extends BasePanel {

+

+	private static final long serialVersionUID = 1L;

+

+	private final boolean hasChanges;

+	

+	private boolean hasMore;

+

+	public ReflogPanel(String wicketId, final RepositoryModel model, Repository r, int limit, int pageOffset) {

+		super(wicketId);

+		boolean pageResults = limit <= 0;

+		int changesPerPage = GitBlit.getInteger(Keys.web.reflogChangesPerPage, 10);

+		if (changesPerPage <= 1) {

+			changesPerPage = 10;

+		}

+

+		List<RefLogEntry> changes;

+		if (pageResults) {

+			changes = RefLogUtils.getLogByRef(model.name, r, pageOffset * changesPerPage, changesPerPage);

+		} else {

+			changes = RefLogUtils.getLogByRef(model.name, r, limit);

+		}

+

+		// inaccurate way to determine if there are more commits.

+		// works unless commits.size() represents the exact end.

+		hasMore = changes.size() >= changesPerPage;

+		hasChanges = changes.size() > 0;

+		

+		setup(changes);

+		

+		// determine to show pager, more, or neither

+		if (limit <= 0) {

+			// no display limit

+			add(new Label("moreChanges").setVisible(false));

+		} else {

+			if (pageResults) {

+				// paging

+				add(new Label("moreChanges").setVisible(false));

+			} else {

+				// more

+				if (changes.size() == limit) {

+					// show more

+					add(new LinkPanel("moreChanges", "link", new StringResourceModel("gb.moreChanges",

+							this, null), ReflogPage.class,

+							WicketUtils.newRepositoryParameter(model.name)));

+				} else {

+					// no more

+					add(new Label("moreChanges").setVisible(false));

+				}

+			}

+		}

+	}

+	

+	public ReflogPanel(String wicketId, List<RefLogEntry> changes) {

+		super(wicketId);

+		hasChanges = changes.size() > 0;

+		setup(changes);

+		add(new Label("moreChanges").setVisible(false));

+	}

+	

+	protected void setup(List<RefLogEntry> changes) {

+		final int hashLen = GitBlit.getInteger(Keys.web.shortCommitIdLength, 6);

+

+		String dateFormat = GitBlit.getString(Keys.web.datestampLongFormat, "EEEE, MMMM d, yyyy");

+		final TimeZone timezone = getTimeZone();

+		final DateFormat df = new SimpleDateFormat(dateFormat);

+		df.setTimeZone(timezone);

+		final Calendar cal = Calendar.getInstance(timezone);

+		

+		ListDataProvider<RefLogEntry> dp = new ListDataProvider<RefLogEntry>(changes);

+		DataView<RefLogEntry> changeView = new DataView<RefLogEntry>("change", dp) {

+			private static final long serialVersionUID = 1L;

+

+			public void populateItem(final Item<RefLogEntry> changeItem) {

+				final RefLogEntry change = changeItem.getModelObject();

+				String fullRefName = change.getChangedRefs().get(0);

+				String shortRefName = fullRefName;

+				boolean isTag = false;

+				if (shortRefName.startsWith(Constants.R_HEADS)) {

+					shortRefName = shortRefName.substring(Constants.R_HEADS.length());

+				} else if (shortRefName.startsWith(Constants.R_TAGS)) {

+					shortRefName = shortRefName.substring(Constants.R_TAGS.length());

+					isTag = true;

+				}

+				

+				String fuzzydate;

+				TimeUtils tu = getTimeUtils();

+				Date changeDate = change.date;

+				if (TimeUtils.isToday(changeDate, timezone)) {

+					fuzzydate = tu.today();

+				} else if (TimeUtils.isYesterday(changeDate, timezone)) {

+					fuzzydate = tu.yesterday();

+				} else {

+					// calculate a fuzzy time ago date

+                	cal.setTime(changeDate);

+                	cal.set(Calendar.HOUR_OF_DAY, 0);

+                	cal.set(Calendar.MINUTE, 0);

+                	cal.set(Calendar.SECOND, 0);

+                	cal.set(Calendar.MILLISECOND, 0);

+                	changeDate = cal.getTime();

+					fuzzydate = getTimeUtils().timeAgo(changeDate);

+				}

+				changeItem.add(new Label("whenChanged", fuzzydate + ", " + df.format(changeDate)));

+

+				Label changeIcon = new Label("changeIcon");

+				if (isTag) {

+					WicketUtils.setCssClass(changeIcon, "iconic-tag");

+				} else {

+					WicketUtils.setCssClass(changeIcon, "iconic-upload");

+				}

+				changeItem.add(changeIcon);

+

+				if (change.user.username.equals(change.user.emailAddress) && change.user.emailAddress.indexOf('@') > -1) {

+					// username is an email address - 1.2.1 push log bug

+					changeItem.add(new Label("whoChanged", change.user.getDisplayName()));

+				} else {

+					// link to user account page

+					changeItem.add(new LinkPanel("whoChanged", null, change.user.getDisplayName(),

+							UserPage.class, WicketUtils.newUsernameParameter(change.user.username)));

+				}

+				

+				boolean isDelete = false;

+				boolean isRewind = false;

+				String what;

+				String by = null;

+				switch(change.getChangeType(fullRefName)) {

+				case CREATE:

+					if (isTag) {

+						// new tag

+						what = getString("gb.pushedNewTag");

+					} else {

+						// new branch

+						what = getString("gb.pushedNewBranch");

+					}

+					break;

+				case DELETE:

+					isDelete = true;

+					if (isTag) {

+						what = getString("gb.deletedTag");

+					} else {

+						what = getString("gb.deletedBranch");

+					}

+					break;

+				case UPDATE_NONFASTFORWARD:

+					isRewind = true;

+				default:

+					what = MessageFormat.format(change.getCommitCount() > 1 ? getString("gb.pushedNCommitsTo") : getString("gb.pushedOneCommitTo") , change.getCommitCount());

+					

+					if (change.getAuthorCount() == 1) {

+						by = MessageFormat.format(getString("gb.byOneAuthor"), change.getAuthorIdent().getName());

+					} else {

+						by = MessageFormat.format(getString("gb.byNAuthors"), change.getAuthorCount());	

+					}

+					break;

+				}

+				changeItem.add(new Label("whatChanged", what));

+				changeItem.add(new Label("byAuthors", by).setVisible(!StringUtils.isEmpty(by)));

+				

+				changeItem.add(new Label("refRewind", getString("gb.rewind")).setVisible(isRewind));

+				

+				if (isDelete) {

+					// can't link to deleted ref

+					changeItem.add(new Label("refChanged", shortRefName));

+				} else if (isTag) {

+					// link to tag

+					changeItem.add(new LinkPanel("refChanged", null, shortRefName,

+							TagPage.class, WicketUtils.newObjectParameter(change.repository, fullRefName)));

+				} else {

+					// link to tree

+					changeItem.add(new LinkPanel("refChanged", null, shortRefName,

+						TreePage.class, WicketUtils.newObjectParameter(change.repository, fullRefName)));

+				}

+				

+				int maxCommitCount = 5;

+				List<RepositoryCommit> commits = change.getCommits();

+				if (commits.size() > maxCommitCount) {

+					commits = new ArrayList<RepositoryCommit>(commits.subList(0,  maxCommitCount));					

+				}

+				

+				// compare link

+				String compareLinkText = null;

+				if ((change.getCommitCount() <= maxCommitCount) && (change.getCommitCount() > 1)) {

+					compareLinkText = MessageFormat.format(getString("gb.viewComparison"), commits.size());

+				} else if (change.getCommitCount() > maxCommitCount) {

+					int diff = change.getCommitCount() - maxCommitCount;

+					compareLinkText = MessageFormat.format(diff > 1 ? getString("gb.nMoreCommits") : getString("gb.oneMoreCommit"), diff);

+				}

+				if (StringUtils.isEmpty(compareLinkText)) {

+					changeItem.add(new Label("compareLink").setVisible(false));

+				} else {

+					String endRangeId = change.getNewId(fullRefName);

+					String startRangeId = change.getOldId(fullRefName);

+					changeItem.add(new LinkPanel("compareLink", null, compareLinkText, ComparePage.class, WicketUtils.newRangeParameter(change.repository, startRangeId, endRangeId)));

+				}

+				

+				ListDataProvider<RepositoryCommit> cdp = new ListDataProvider<RepositoryCommit>(commits);

+				DataView<RepositoryCommit> commitsView = new DataView<RepositoryCommit>("commit", cdp) {

+					private static final long serialVersionUID = 1L;

+

+					public void populateItem(final Item<RepositoryCommit> commitItem) {

+						final RepositoryCommit commit = commitItem.getModelObject();

+

+						// author gravatar

+						commitItem.add(new GravatarImage("commitAuthor", commit.getAuthorIdent().getName(),

+								commit.getAuthorIdent().getEmailAddress(), null, 16, false, false));

+						

+						// merge icon

+						if (commit.getParentCount() > 1) {

+							commitItem.add(WicketUtils.newImage("commitIcon", "commit_merge_16x16.png"));

+						} else {

+							commitItem.add(WicketUtils.newBlankImage("commitIcon"));

+						}

+

+						// short message

+						String shortMessage = commit.getShortMessage();

+						String trimmedMessage = shortMessage;

+						if (commit.getRefs() != null && commit.getRefs().size() > 0) {

+							trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG_REFS);

+						} else {

+							trimmedMessage = StringUtils.trimString(shortMessage, Constants.LEN_SHORTLOG);

+						}

+						LinkPanel shortlog = new LinkPanel("commitShortMessage", "list",

+								trimmedMessage, CommitPage.class, WicketUtils.newObjectParameter(

+										change.repository, commit.getName()));

+						if (!shortMessage.equals(trimmedMessage)) {

+							WicketUtils.setHtmlTooltip(shortlog, shortMessage);

+						}

+						commitItem.add(shortlog);

+

+						// commit hash link

+						LinkPanel commitHash = new LinkPanel("hashLink", null, commit.getName().substring(0, hashLen),

+								CommitPage.class, WicketUtils.newObjectParameter(

+										change.repository, commit.getName()));

+						WicketUtils.setCssClass(commitHash, "shortsha1");

+						WicketUtils.setHtmlTooltip(commitHash, commit.getName());

+						commitItem.add(commitHash);

+					}

+				};

+

+				changeItem.add(commitsView);

+			}

+		};

+		

+		add(changeView);

+	}

+

+	public boolean hasMore() {

+		return hasMore;

+	}

+	

+	public boolean hideIfEmpty() {

+		setVisible(hasChanges);

+		return hasChanges;

+	}

+}

diff --git a/src/main/resources/gitblit.css b/src/main/resources/gitblit.css
index 351d43f..6074b36 100644
--- a/src/main/resources/gitblit.css
+++ b/src/main/resources/gitblit.css
@@ -129,23 +129,39 @@
     background-color: #002060;

 }

 

-div.push {

+div.reflog {

     border-bottom: 1px solid #ddd;

 	margin-bottom: 5px;

 	padding-bottom: 5px;

 }

 

-div.push .icon {

+div.reflog .icon {

     font-size: 42px;

     line-height: 42px;

 }

 

-div.push i {

+div.reflog .when {

+	color: #aaa;

+}

+

+div.reflog i {

     font-size: 42px;

     color: #bbb;

     vertical-align: middle;

 }

 

+div.dashboardTitle {

+	font-size: 1.75em;

+	padding-bottom: 5px;

+	margin-bottom: 10px;

+	border-bottom: 1px solid #ccc;

+}

+

+div.dashboardTitle small {

+	color: #888;

+	font-size: 0.7em;

+}

+

 .repositorynavbar {

 	background-color: #fbfbfb;

 	border-bottom: 1px solid #ccc;

diff --git a/src/test/java/com/gitblit/tests/GitServletTest.java b/src/test/java/com/gitblit/tests/GitServletTest.java
index c1aaf1a..7607fbf 100644
--- a/src/test/java/com/gitblit/tests/GitServletTest.java
+++ b/src/test/java/com/gitblit/tests/GitServletTest.java
@@ -38,12 +38,12 @@
 import com.gitblit.Constants.AuthorizationControl;

 import com.gitblit.GitBlit;

 import com.gitblit.Keys;

-import com.gitblit.models.PushLogEntry;

+import com.gitblit.models.RefLogEntry;

 import com.gitblit.models.RepositoryModel;

 import com.gitblit.models.UserModel;

 import com.gitblit.utils.ArrayUtils;

 import com.gitblit.utils.JGitUtils;

-import com.gitblit.utils.PushLogUtils;

+import com.gitblit.utils.RefLogUtils;

 

 public class GitServletTest {

 

@@ -788,7 +788,7 @@
 		String name = "refchecks/ticgit.git";

 		File refChecks = new File(GitBlitSuite.REPOSITORIES, name);

 		Repository repository = new FileRepositoryBuilder().setGitDir(refChecks).build();

-		List<PushLogEntry> pushes = PushLogUtils.getPushLog(name, repository);

+		List<RefLogEntry> pushes = RefLogUtils.getRefLog(name, repository);

 		GitBlitSuite.close(repository);

 		assertTrue("Repository has an empty push log!", pushes.size() > 0);

 	}

diff --git a/src/test/java/com/gitblit/tests/PushLogTest.java b/src/test/java/com/gitblit/tests/PushLogTest.java
index 0f46b53..f5d5965 100644
--- a/src/test/java/com/gitblit/tests/PushLogTest.java
+++ b/src/test/java/com/gitblit/tests/PushLogTest.java
@@ -25,8 +25,8 @@
 import org.eclipse.jgit.util.FS;

 import org.junit.Test;

 

-import com.gitblit.models.PushLogEntry;

-import com.gitblit.utils.PushLogUtils;

+import com.gitblit.models.RefLogEntry;

+import com.gitblit.utils.RefLogUtils;

 

 public class PushLogTest {

 

@@ -35,7 +35,7 @@
 		String name = "~james/helloworld.git";

 		File gitDir = FileKey.resolve(new File(GitBlitSuite.REPOSITORIES, name), FS.DETECTED);

 		Repository repository = new FileRepositoryBuilder().setGitDir(gitDir).build();

-		List<PushLogEntry> pushes = PushLogUtils.getPushLog(name, repository);

+		List<RefLogEntry> pushes = RefLogUtils.getRefLog(name, repository);

 		GitBlitSuite.close(repository);

 	}

 }
\ No newline at end of file