Support building gn without a .git directory.

This is relevant both for jj non-colocated repos, and for performant mutagen-based syncing, which allows for you to sync the code without syncing the .git directory.

Change-Id: I6e4b5edcc260077c73a3447b19f8d1a46a6a6964
Reviewed-on: https://gn-review.googlesource.com/c/gn/+/21760
Reviewed-by: Takuto Ikuta <tikuta@google.com>
Commit-Queue: Matt Stark <msta@google.com>
diff --git a/build/gen.py b/build/gen.py
index ccf8cbf..6ccd5fe 100755
--- a/build/gen.py
+++ b/build/gen.py
@@ -246,13 +246,19 @@
 
 def GenerateLastCommitPosition(host, header):
   ROOT_TAG = 'initial-commit'
-  describe_output = subprocess.check_output(
-      ['git', 'describe', 'HEAD', '--abbrev=12', '--match', ROOT_TAG],
-      shell=host.is_windows(), cwd=REPO_ROOT)
-  mo = re.match(ROOT_TAG + r'-(\d+)-g([0-9a-f]+)', describe_output.decode())
-  if not mo:
-    raise ValueError(
-        'Unexpected output from git describe when generating version header')
+  if os.path.isdir(os.path.join(REPO_ROOT, '.git')):
+    describe_output = subprocess.check_output(
+        ['git', 'describe', 'HEAD', '--abbrev=12', '--match', ROOT_TAG],
+        shell=host.is_windows(), cwd=REPO_ROOT)
+    mo = re.match(ROOT_TAG + r'-(\d+)-g([0-9a-f]+)', describe_output.decode())
+    if not mo:
+      raise ValueError(
+          'Unexpected output from git describe when generating version header')
+    num = mo.group(1)
+    commit_id = mo.group(2)
+  else:
+    num = 0
+    commit_id = "UNKNOWN"
 
   contents = '''// Generated by build/gen.py.
 
@@ -263,7 +269,7 @@
 #define LAST_COMMIT_POSITION "%s (%s)"
 
 #endif  // OUT_LAST_COMMIT_POSITION_H_
-''' % (mo.group(1), mo.group(1), mo.group(2))
+''' % (num, num, commit_id)
 
   # Only write/touch this file if the commit position has changed.
   old_contents = ''