Эх сурвалжийг харах

Add a --keep-going flag for people who run rebase-update infrequently.

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@296639 0039d316-1c4b-4281-b951-d872f2087c98
stip@chromium.org 10 жил өмнө
parent
commit
74374f985f

+ 20 - 1
git_rebase_update.py

@@ -196,6 +196,8 @@ def rebase_branch(branch, parent, start_hash):
 def main(args=None):
   parser = argparse.ArgumentParser()
   parser.add_argument('--verbose', '-v', action='store_true')
+  parser.add_argument('--keep-going', '-k', action='store_true',
+                      help='Keep processing past failed rebases.')
   parser.add_argument('--no_fetch', '--no-fetch', '-n',
                       action='store_true',
                       help='Skip fetching remotes.')
@@ -245,6 +247,7 @@ def main(args=None):
   logging.debug('merge_base: %s' % pformat(merge_base))
 
   retcode = 0
+  unrebased_branches = []
   # Rebase each branch starting with the root-most branches and working
   # towards the leaves.
   for branch, parent in git.topo_iter(branch_tree):
@@ -254,7 +257,23 @@ def main(args=None):
       ret = rebase_branch(branch, parent, merge_base[branch])
       if not ret:
         retcode = 1
-        break
+
+        if opts.keep_going:
+          print '--keep-going set, continuing with next branch.'
+          unrebased_branches.append(branch)
+          if git.in_rebase():
+            git.run_with_retcode('rebase', '--abort')
+          if git.in_rebase():  # pragma: no cover
+            print 'Failed to abort rebase. Something is really wrong.'
+            break
+        else:
+          break
+
+  if unrebased_branches:
+    print
+    print 'The following branches could not be cleanly rebased:'
+    for branch in unrebased_branches:
+      print '  %s' % branch
 
   if not retcode:
     remove_empty_branches(branch_tree)

+ 9 - 4
man/html/git-rebase-update.html

@@ -755,7 +755,7 @@ git-rebase-update(1) Manual Page
 <h2 id="_synopsis">SYNOPSIS</h2>
 <div class="sectionbody">
 <div class="verseblock">
-<pre class="content"><em>git rebase-update</em> [-v | --verbose] [-n | --no_fetch]</pre>
+<pre class="content"><em>git rebase-update</em> [-v | --verbose] [-n | --no-fetch] [-k | --keep-going]</pre>
 <div class="attribution">
 </div></div>
 </div>
@@ -786,7 +786,7 @@ Fetching
   of git remotes is determined, and fetched accordingly. Note that if any
   branches have a tag as their upstream, we are forced to pull all remotes.
 </p>
-<div class="paragraph"><p>Pass <code>--no_fetch</code> to skip this phase.</p></div>
+<div class="paragraph"><p>Pass <code>--no-fetch</code> to skip this phase.</p></div>
 </dd>
 <dt class="hdlist1">
 Rebasing
@@ -810,6 +810,11 @@ left in mid-rebase and <code>git rebase-update</code> will exit. You can deal wi
 like any other conflicted rebase. When you&#8217;re done, just <code>git rebase-update</code>
 again to pick up where you left off.</p></div>
 </dd>
+</dl></div>
+<div class="paragraph"><p>If you&#8217;d like to rebase all rebaseable branches in one pass and manually process
+the unrebaseable ones later, use -k or --keep-going. Cleanup will not happen
+until all branches apply cleanly.</p></div>
+<div class="dlist"><dl>
 <dt class="hdlist1">
 Cleanup
 </dt>
@@ -844,7 +849,7 @@ Restoration
 -n
 </dt>
 <dt class="hdlist1">
---no_fetch
+--no-fetch
 </dt>
 <dd>
 <p>
@@ -930,7 +935,7 @@ from <a href="https://chromium.googlesource.com/chromium/tools/depot_tools.git">
 <div id="footnotes"><hr /></div>
 <div id="footer">
 <div id="footer-text">
-Last updated 2014-04-10 14:23:11 PDT
+Last updated 2015-09-10 16:42:50 PDT
 </div>
 </div>
 </body>

+ 8 - 6
man/man1/git-rebase-update.1

@@ -2,12 +2,12 @@
 .\"     Title: git-rebase-update
 .\"    Author: [FIXME: author] [see http://docbook.sf.net/el/author]
 .\" Generator: DocBook XSL Stylesheets v1.78.1 <http://docbook.sf.net/>
-.\"      Date: 04/10/2014
+.\"      Date: 09/10/2015
 .\"    Manual: Chromium depot_tools Manual
-.\"    Source: depot_tools 68b1017
+.\"    Source: depot_tools 805792e
 .\"  Language: English
 .\"
-.TH "GIT\-REBASE\-UPDATE" "1" "04/10/2014" "depot_tools 68b1017" "Chromium depot_tools Manual"
+.TH "GIT\-REBASE\-UPDATE" "1" "09/10/2015" "depot_tools 805792e" "Chromium depot_tools Manual"
 .\" -----------------------------------------------------------------
 .\" * Define some portability stuff
 .\" -----------------------------------------------------------------
@@ -32,7 +32,7 @@ git-rebase-update \- Updates all branches to have the latest changes from their
 .SH "SYNOPSIS"
 .sp
 .nf
-\fIgit rebase\-update\fR [\-v | \-\-verbose] [\-n | \-\-no_fetch]
+\fIgit rebase\-update\fR [\-v | \-\-verbose] [\-n | \-\-no\-fetch] [\-k | \-\-keep\-going]
 .fi
 .sp
 .SH "DESCRIPTION"
@@ -58,7 +58,7 @@ Fetching
 All branches are examined to find their upstream references\&. The correct set of git remotes is determined, and fetched accordingly\&. Note that if any branches have a tag as their upstream, we are forced to pull all remotes\&.
 .sp
 Pass
-\-\-no_fetch
+\-\-no\-fetch
 to skip this phase\&.
 .RE
 .PP
@@ -87,6 +87,8 @@ will exit\&. You can deal with this like any other conflicted rebase\&. When you
 git rebase\-update
 again to pick up where you left off\&.
 .RE
+.sp
+If you\(cqd like to rebase all rebaseable branches in one pass and manually process the unrebaseable ones later, use \-k or \-\-keep\-going\&. Cleanup will not happen until all branches apply cleanly\&.
 .PP
 Cleanup
 .RS 4
@@ -111,7 +113,7 @@ depot\-tools\&.upstream, see
 .RE
 .SH "OPTIONS"
 .PP
-\-n, \-\-no_fetch
+\-n, \-\-no\-fetch
 .RS 4
 Skip the
 git fetch

+ 5 - 1
man/src/git-rebase-update.txt

@@ -9,7 +9,7 @@ include::_git-rebase-update_desc.helper.txt[]
 SYNOPSIS
 --------
 [verse]
-'git rebase-update' [-v | --verbose] [-n | --no-fetch]
+'git rebase-update' [-v | --verbose] [-n | --no-fetch] [-k | --keep-going]
 
 DESCRIPTION
 -----------
@@ -49,6 +49,10 @@ left in mid-rebase and `git rebase-update` will exit. You can deal with this
 like any other conflicted rebase. When you're done, just `git rebase-update`
 again to pick up where you left off.
 
+If you'd like to rebase all rebaseable branches in one pass and manually process
+the unrebaseable ones later, use -k or --keep-going. Cleanup will not happen
+until all branches apply cleanly.
+
 Cleanup::
   Once all the branches have been rebased, any empty branches (i.e. branches
   with no commits on them) are removed. If a branch is removed in this fashion,

+ 36 - 0
tests/git_rebase_update_test.py

@@ -259,6 +259,42 @@ class GitRebaseUpdateTest(git_test_utils.GitRepoReadWriteTestBase):
     self.assertIn('\'branch_G\' was merged', output)
     self.assertIn('checking out \'origin/master\'', output)
 
+  def testRebaseConflictsKeepGoing(self):
+    # Pretend that branch_L landed
+    self.origin.git('checkout', 'master')
+    with self.origin.open('L', 'w') as f:
+      f.write('L')
+    self.origin.git('add', 'L')
+    self.origin.git_commit('L')
+
+    # Add a commit to branch_K so that things fail
+    self.repo.git('checkout', 'branch_K')
+    with self.repo.open('M', 'w') as f:
+      f.write('NOPE')
+    self.repo.git('add', 'M')
+    self.repo.git_commit('K NOPE')
+
+    # Add a commits to branch_L which will work when squashed
+    self.repo.git('checkout', 'branch_L')
+    self.repo.git('reset', 'branch_L~')
+    with self.repo.open('L', 'w') as f:
+      f.write('NOPE')
+    self.repo.git('add', 'L')
+    self.repo.git_commit('L NOPE')
+    with self.repo.open('L', 'w') as f:
+      f.write('L')
+    self.repo.git('add', 'L')
+    self.repo.git_commit('L YUP')
+
+    # start on a branch which will be deleted
+    self.repo.git('checkout', 'branch_G')
+
+    self.repo.git('config', 'branch.branch_K.dormant', 'false')
+    output, _ = self.repo.capture_stdio(self.reup.main, ['-k'])
+    self.assertIn('--keep-going set, continuing with next branch.', output)
+    self.assertIn('could not be cleanly rebased:', output)
+    self.assertIn('  branch_K', output)
+
 
   def testTrackTag(self):
     self.origin.git('tag', 'lkgr', self.origin['M'])