Make git-rebase-update a bit more robust

  * When aborting a failed rebase, don't cascade errors if the abort itself
    fails.
  * When starting a rebase-update cycle, cd to the root of the repo. This avoids
    an issue when you run rebase-update from inside of a branch which adds a
    new folder.

R=agable@chromium.org
BUG=499031

Review URL: https://codereview.chromium.org/1180673003

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@295637 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/git_common.py b/git_common.py
index 2df4936..22f14cd 100644
--- a/git_common.py
+++ b/git_common.py
@@ -525,7 +525,7 @@
     return RebaseRet(True, '', '')
   except subprocess2.CalledProcessError as cpe:
     if abort:
-      run('rebase', '--abort')
+      run_with_retcode('rebase', '--abort')  # ignore failure
     return RebaseRet(False, cpe.stdout, cpe.stderr)
 
 
diff --git a/git_rebase_update.py b/git_rebase_update.py
index 10c10d1..63d0503 100755
--- a/git_rebase_update.py
+++ b/git_rebase_update.py
@@ -12,6 +12,7 @@
 import logging
 import sys
 import textwrap
+import os
 
 from fnmatch import fnmatch
 from pprint import pformat
@@ -20,21 +21,26 @@
 
 
 STARTING_BRANCH_KEY = 'depot-tools.rebase-update.starting-branch'
+STARTING_WORKDIR_KEY = 'depot-tools.rebase-update.starting-workdir'
 
 
-def find_return_branch():
-  """Finds the branch which we should return to after rebase-update completes.
+def find_return_branch_workdir():
+  """Finds the branch and working directory which we should return to after
+  rebase-update completes.
 
-  This value may persist across multiple invocations of rebase-update, if
+  These values may persist across multiple invocations of rebase-update, if
   rebase-update runs into a conflict mid-way.
   """
   return_branch = git.config(STARTING_BRANCH_KEY)
+  workdir = git.config(STARTING_WORKDIR_KEY)
   if not return_branch:
+    workdir = os.getcwd()
+    git.set_config(STARTING_WORKDIR_KEY, workdir)
     return_branch = git.current_branch()
     if return_branch != 'HEAD':
       git.set_config(STARTING_BRANCH_KEY, return_branch)
 
-  return return_branch
+  return return_branch, workdir
 
 
 def fetch_remotes(branch_tree):
@@ -214,7 +220,8 @@
     )
     return 1
 
-  return_branch = find_return_branch()
+  return_branch, return_workdir = find_return_branch_workdir()
+  os.chdir(git.run('rev-parse', '--show-toplevel'))
 
   if git.current_branch() == 'HEAD':
     if git.run('status', '--porcelain'):
@@ -264,7 +271,9 @@
           % (return_branch, root_branch)
         )
       git.run('checkout', root_branch)
+    os.chdir(return_workdir)
     git.set_config(STARTING_BRANCH_KEY, '')
+    git.set_config(STARTING_WORKDIR_KEY, '')
 
   return retcode