Avoid unnecessary git symbolic-ref calls during repo sync

If the m/BRANCH ref is already pointing at the value set in the
manifest there is no reason to set it again.  Leave it alone,
thus saving a full fork+exec call.

Signed-off-by: Shawn O. Pearce <sop@google.com>
diff --git a/git_refs.py b/git_refs.py
index eefa2ab..b91abc2 100644
--- a/git_refs.py
+++ b/git_refs.py
@@ -31,8 +31,7 @@
 
   @property
   def all(self):
-    if self._phyref is None or self._NeedUpdate():
-      self._LoadAll()
+    self._EnsureLoaded()
     return self._phyref
 
   def get(self, name):
@@ -52,6 +51,17 @@
       if name in self._mtime:
         del self._mtime[name]
 
+  def symref(self, name):
+    try:
+      self._EnsureLoaded()
+      return self._symref[name]
+    except KeyError:
+      return ''
+
+  def _EnsureLoaded(self):
+    if self._phyref is None or self._NeedUpdate():
+      self._LoadAll()
+
   def _NeedUpdate(self):
     for name, mtime in self._mtime.iteritems():
       try:
diff --git a/project.py b/project.py
index 9f9cf7b..09a768f 100644
--- a/project.py
+++ b/project.py
@@ -997,14 +997,17 @@
     if self.manifest.branch:
       msg = 'manifest set to %s' % self.revision
       ref = R_M + self.manifest.branch
+      cur = self.bare_ref.symref(ref)
 
       if IsId(self.revision):
-        dst = self.revision + '^0'
-        self.bare_git.UpdateRef(ref, dst, message = msg, detach = True)
+        if cur != '' or self.bare_ref.get(ref) != self.revision:
+          dst = self.revision + '^0'
+          self.bare_git.UpdateRef(ref, dst, message = msg, detach = True)
       else:
         remote = self.GetRemote(self.remote.name)
         dst = remote.ToLocal(self.revision)
-        self.bare_git.symbolic_ref('-m', msg, ref, dst)
+        if cur != dst:
+          self.bare_git.symbolic_ref('-m', msg, ref, dst)
 
   def _InitMirrorHead(self):
     dst = self.GetRemote(self.remote.name).ToLocal(self.revision)