Use real default branch in gclient

Currently, gclient sync assumes the default branch is master, and
it doesn't work at all if such branch doesn't exist. This change queries
local git copy to get remote HEAD. If local git version is not
available, it queries remote git server using ls-remote.

This change requires git version 2.28 (depot_tools comes with 2.29).

R=ehmaldonado@chromium.org

Bug: 1156318
Change-Id: Id348e0f1004093f395139e8f4d62adb66b94ca9c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2628359
Commit-Queue: Josip Sokcevic <sokcevic@google.com>
Reviewed-by: Edward Lesmes <ehmaldonado@chromium.org>
diff --git a/scm.py b/scm.py
index 42f566b..812454b 100644
--- a/scm.py
+++ b/scm.py
@@ -111,7 +111,7 @@
     return env
 
   @staticmethod
-  def Capture(args, cwd, strip_out=True, **kwargs):
+  def Capture(args, cwd=None, strip_out=True, **kwargs):
     env = GIT.ApplyEnvVars(kwargs)
     output = subprocess2.check_output(
         ['git'] + args, cwd=cwd, stderr=subprocess2.PIPE, env=env, **kwargs)
@@ -194,6 +194,31 @@
       return None
 
   @staticmethod
+  def GetRemoteHeadRef(cwd, url, remote):
+    """Returns the full default remote branch reference, e.g.
+    'refs/remotes/origin/main'."""
+    if os.path.exists(cwd):
+      try:
+        # Try using local git copy first
+        ref = 'refs/remotes/%s/HEAD' % remote
+        return GIT.Capture(['symbolic-ref', ref], cwd=cwd)
+      except subprocess2.CalledProcessError:
+        pass
+
+    try:
+      # Fetch information from git server
+      resp = GIT.Capture(['ls-remote', '--symref', url, 'HEAD'])
+      regex = r'^ref: (.*)\tHEAD$'
+      for line in resp.split('\n'):
+        m = re.match(regex, line)
+        if m:
+          return ''.join(GIT.RefToRemoteRef(m.group(1), remote))
+    except subprocess2.CalledProcessError:
+      pass
+    # Return default branch
+    return 'refs/remotes/%s/master' % remote
+
+  @staticmethod
   def GetBranch(cwd):
     """Returns the short branch name, e.g. 'main'."""
     branchref = GIT.GetBranchRef(cwd)