Reland "git-cache: Add option to fetch commits."

This is a reland of 4c67f856f06693b39eecaa0efb86b2856c3532bb
Issues should have been fixed by crrev.com/c/2838026

Original change's description:
> git-cache: Add option to fetch commits.
>
> Add option to git cache to fetch commits.
> And use it in bot_update and gclient sync to make sure
> the needed commits are present on the checkout.
>
> Change-Id: I9e90da9e3be6e7bacf714b22bf0b735463e655b6
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2829942
> Reviewed-by: Gavin Mak <gavinmak@google.com>
> Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>

Change-Id: Ie5a29737f5a75d28bc7c5c2f6cb99ec7f87cd9e8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2841046
Reviewed-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
diff --git a/gclient_scm.py b/gclient_scm.py
index 4407ea9..ea8f773 100644
--- a/gclient_scm.py
+++ b/gclient_scm.py
@@ -399,7 +399,7 @@
     elif not scm.GIT.IsValidRevision(self.checkout_path, target_rev):
       # Fetch |target_rev| if it's not already available.
       url, _ = gclient_utils.SplitUrlRevision(self.url)
-      mirror = self._GetMirror(url, options, target_rev)
+      mirror = self._GetMirror(url, options, target_rev, target_rev)
       if mirror:
         rev_type = 'branch' if target_rev.startswith('refs/') else 'hash'
         self._UpdateMirrorIfNotContains(mirror, options, rev_type, target_rev)
@@ -508,7 +508,7 @@
     if revision_ref.startswith('refs/branch-heads'):
       options.with_branch_heads = True
 
-    mirror = self._GetMirror(url, options, revision_ref)
+    mirror = self._GetMirror(url, options, revision, revision_ref)
     if mirror:
       url = mirror.mirror_path
 
@@ -948,13 +948,14 @@
     return os.path.join(self._root_dir,
                         'old_' + self.relpath.replace(os.sep, '_')) + '.git'
 
-  def _GetMirror(self, url, options, revision_ref=None):
+  def _GetMirror(self, url, options, revision=None, revision_ref=None):
     """Get a git_cache.Mirror object for the argument url."""
     if not self.cache_dir:
       return None
     mirror_kwargs = {
         'print_func': self.filter,
-        'refs': []
+        'refs': [],
+        'commits': [],
     }
     if hasattr(options, 'with_branch_heads') and options.with_branch_heads:
       mirror_kwargs['refs'].append('refs/branch-heads/*')
@@ -964,6 +965,8 @@
       mirror_kwargs['refs'].append('refs/tags/*')
     elif revision_ref and revision_ref.startswith('refs/tags/'):
       mirror_kwargs['refs'].append(revision_ref)
+    if revision and not revision.startswith('refs/'):
+      mirror_kwargs['commits'].append(revision)
     return git_cache.Mirror(url, **mirror_kwargs)
 
   def _UpdateMirrorIfNotContains(self, mirror, options, rev_type, revision):