Add auto-fetch to repo page
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
index 47c534b..a8003cb 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
@@ -240,7 +240,7 @@
 		}
 	};
 
-	exports.gatherSshCredentials = function(serviceRegistry, data, title){
+	exports.gatherSshCredentials = function(serviceRegistry, data, title, noAuth){
 		var def = new Deferred();
 		var repository;
 		
@@ -313,6 +313,11 @@
 		}
 		
 		var failure = function(){
+			if (noAuth) {
+				def.reject();
+				return;
+			}
+			
 			if (!data.parameters && !data.optionsRequested){
 				triggerCallback({gitSshUsername: "", gitSshPassword: "", gitPrivateKey: "", gitPassphrase: ""}); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 				return;
@@ -430,7 +435,13 @@
 
 	exports.createFileCommands = function(serviceRegistry, commandService, explorer, toolbarId) {
 
-		var refresh = function() { explorer.changedItem(); };
+		var refresh = function(data) { 
+			if (data.handler.changedItem) {
+				data.handler.changedItem();
+			} else { 
+				explorer.changedItem(); 
+			}
+		};
 		
 		function displayErrorOnStatus(error) {
 			var display = {};
@@ -839,7 +850,9 @@
 			}
 
 			var item = data.items;
+			var noAuth = false;
 			if (item.LocalBranch && item.RemoteBranch) {
+				noAuth = item.noAuth;
 				item = item.RemoteBranch;
 			}
 			var path = item.Location;
@@ -894,7 +907,7 @@
 					progress.removeOperation(commandInvocation.errorData.failedOperation);
 				}
 				
-				exports.gatherSshCredentials(serviceRegistry, commandInvocation).then(
+				exports.gatherSshCredentials(serviceRegistry, commandInvocation, null, noAuth).then(
 					function(options) {
 						var gitService = serviceRegistry.getService("orion.git.provider"); //$NON-NLS-0$
 						var statusService = serviceRegistry.getService("orion.page.message"); //$NON-NLS-0$
@@ -925,7 +938,8 @@
 								);
 							}
 						);
-					}
+					},
+					d.reject
 				);
 			};
 			
@@ -950,6 +964,9 @@
 			return d;
 		};
 		var fetchVisibleWhen = function(item) {
+			if (item.LocalBranch && item.RemoteBranch) {
+				item = item.RemoteBranch;
+			}
 			if (item.Type === "RemoteTrackingBranch") //$NON-NLS-0$
 				return true;
 			if (item.Type === "Remote") //$NON-NLS-0$
@@ -966,8 +983,8 @@
 			spriteClass: "gitCommandSprite", //$NON-NLS-0$
 			id: "eclipse.orion.git.fetch", //$NON-NLS-0$
 			callback: function(data) {
-				fetchCallback(data, false).then(function() {
-					refresh();
+				return fetchCallback(data, false).then(function() {
+					refresh(data);
 				});
 			},
 			visibleWhen: fetchVisibleWhen
@@ -983,7 +1000,7 @@
 			callback: function(data) {
 				var confirm = messages["You're going to override content of the remote tracking branch. This can cause the branch to lose commits."]+"\n\n"+messages['Are you sure?']; //$NON-NLS-0$
 				fetchCallback(data, true, confirm).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen : fetchVisibleWhen
@@ -1180,7 +1197,7 @@
 			spriteClass: "gitCommandSprite", //$NON-NLS-0$
 			callback: function(data) {
 				rebaseCallback(data).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen : function(item) {
@@ -1227,7 +1244,7 @@
 					return rebaseCallback(data).then(function(jsonData) {
 						if (jsonData.Result === "OK" || jsonData.Result === "FAST_FORWARD" || jsonData.Result === "UP_TO_DATE") { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 							return pushCallbackTags(data).then(function() {
-								refresh();
+								refresh(data);
 							});
 						}
 					});
@@ -1245,7 +1262,7 @@
 			id : "eclipse.orion.git.push", //$NON-NLS-0$
 			callback: function(data) {
 				pushCallbackTags(data).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen: pushVisibleWhen
@@ -1260,7 +1277,7 @@
 			id : "eclipse.orion.git.pushBranch", //$NON-NLS-0$
 			callback:  function(data) {
 				pushCallbackNoTags(data).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen: pushVisibleWhen
@@ -1275,7 +1292,7 @@
 			id : "eclipse.orion.git.pushToGerrit", //$NON-NLS-0$
 			callback:  function(data) {
 				pushCallbackGerrit(data).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen: function(item) {
@@ -1302,7 +1319,7 @@
 			id : "eclipse.orion.git.pushForce", //$NON-NLS-0$
 			callback: function(data) {
 				pushCallbackTagsForce(data).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen: pushVisibleWhen
@@ -1317,7 +1334,7 @@
 			id : "eclipse.orion.git.pushForceBranch", //$NON-NLS-0$
 			callback: function(data) {
 				pushCallbackNoTagsForce(data).then(function() {
-					refresh();
+					refresh(data);
 				});
 			},
 			visibleWhen: pushVisibleWhen
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js
index 835afc0..e55f072 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/gitCommitList.js
@@ -330,6 +330,12 @@
 			var deferred = new Deferred();

 			var that = this;

 			var model = this.model;

+			if (!item) {

+				model.getRoot(function(root) {

+					item = root;

+				});

+			}

+			

 			if (item.Type === "CommitRoot") { //$NON-NLS-0$

 				model.incomingCommits = model.outgoingCommits = null;

 			}

@@ -338,7 +344,13 @@
 			var progress = this.section.createProgressMonitor();

 			progress.begin(messages["Getting git log"]);

 			model.getChildren(item, function(children) {

+				item.removeAll = true;

 				that.myTree.refresh.bind(that.myTree)(item, children, false);

+				that.myTree.expand(that.model.getId(children[0]));

+				that.myTree.expand(that.model.getId(children[1]));

+				if (that.location) {

+					that.myTree.expand(that.model.getId(children[2]));

+				}

 				if (item.Type === "Synchronized") { //$NON-NLS-0$

 					that.updatePageCommands(item);

 				} else {

@@ -355,17 +367,20 @@
 			var model = new GitCommitListModel({root: this.root, registry: this.registry, progressService: this.progressService, statusService: this.statusService, gitClient: this.gitClient, section: this.section, location: this.location, handleError: this.handleError, legacyLog: this.legacyLog});

 			this.createTree(this.parentId, model, {onComplete: function() {

 				that.status = model.status;

-				that.model.getRoot(function(root) {

-					that.model.getChildren(root, function(children) {

-						that.myTree.expand(that.model.getId(children[0]));

-						that.myTree.expand(that.model.getId(children[1]));

-						if (that.location) {

-							that.myTree.expand(that.model.getId(children[2]));

-						}

+				var fetched = function(){

+					that.model.getRoot(function(root) {

+						that.model.getChildren(root, function(children) {

+							that.myTree.expand(that.model.getId(children[0]));

+							that.myTree.expand(that.model.getId(children[1]));

+							if (that.location) {

+								that.myTree.expand(that.model.getId(children[2]));

+							}

+						});

 					});

-				});

-				that.updateCommands();

-				deferred.resolve(model.log);

+					that.updateCommands();

+					deferred.resolve(model.log);

+				};

+				that.fetch().then(fetched, fetched);

 			}});

 			return deferred;

 		},

@@ -435,6 +450,16 @@
 			});

 			commandService.addCommand(chooseBranchCommand);

 		},

+		fetch: function() {

+			var model = this.model;

+			if (model.tracksRemoteBranch() && !this.legacyLog) {

+				var commandService = this.commandService;

+				var remoteBranch = model.getRemoteBranch();

+				var localBranch = model.getLocalBranch();

+				return commandService.runCommand("eclipse.orion.git.fetch", {LocalBranch: localBranch, RemoteBranch: remoteBranch, noAuth: true}, this);

+			}

+			return new Deferred().resolve();

+		},

 		updateCommands: function() {

 			var model = this.model;

 			var currentBranch = model.currentBranch;

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js b/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js
index 9c685f3..dbb4929 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js
@@ -105,14 +105,14 @@
 				if (enabled && command.callback) {
 					var commandInvocation = new Commands.CommandInvocation(handler, item, userData, command, self);
 					commandInvocation.domParent = parent;
-					self._invoke(commandInvocation, parameters);
+					return self._invoke(commandInvocation, parameters);
 				}
 			} else {
 				//TODO should we be keeping invocation context for commands without bindings? 
 				var binding = this._urlBindings[commandId];
 				if (binding && binding.command) {
 					if (binding.command.callback) {
-						self._invoke(binding.invocation, parameters);
+						return self._invoke(binding.invocation, parameters);
 					}
 				}
 			}
@@ -324,11 +324,11 @@
 					}
 					if (!collecting) {
 						// Just call the callback with the information we had.
-						commandInvocation.command.callback.call(commandInvocation.handler || window, commandInvocation);
+						return commandInvocation.command.callback.call(commandInvocation.handler || window, commandInvocation);
 					}
 				} else {
 					// We should not be trying to collect parameters, just call the callback.
-					commandInvocation.command.callback.call(commandInvocation.handler || window, commandInvocation);
+					return commandInvocation.command.callback.call(commandInvocation.handler || window, commandInvocation);
 				}
 			} else {
 				window.console.log("Client attempted to invoke command without an available (rendered) command invocation"); //$NON-NLS-0$