Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Unified Diff: git_cl.py

Issue 1191473002: [depot_tools] New "git cl upload" flag to traverse dependent branches and re-upload them (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Cleanup Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tests/git_cl_test.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: git_cl.py
diff --git a/git_cl.py b/git_cl.py
index d50b7a37dfe8c596f3b2b6c5c534b086daa7a15a..9af0444d829ae41295b03e29c48e224f4ff8bc65 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -1505,6 +1505,91 @@ def get_cl_statuses(
url = c.GetIssueURL()
yield (b, url, Fore.BLUE if url else Fore.WHITE)
+
+def CMDupload_branch_deps(unused_parser, args):
+ """Uploads CLs of local branches that are dependents of the current branch.
+
+ If the local branch dependency tree looks like:
+ test1 -> test2.1 -> test3.1
+ -> test3.2
+ -> test2.2 -> test3.3
+
+ and you run this command from test1 then "git cl upload" is run on the
+ dependent branches in this order:
+ test2.1, test3.1, test3.2, test2.2, test3.3
+
+ Note: This command does not rebase your local dependent branches. Use it when
+ you make a change to the parent branch that will not conflict with its
+ dependent branches, and you would like their dependencies updated in
+ Rietveld.
nodir 2015/06/15 23:50:22 Rebasing would be very nice, for example if I want
iannucci 2015/06/15 23:55:12 git rebase-update can/does already do this.
nodir 2015/06/15 23:58:43 Acknowledged.
+ """
+
+ branchref = RunGit(['symbolic-ref', 'HEAD'],
+ stderr=subprocess2.VOID, error_ok=True).strip()
+ parent_branch = ShortBranchName(branchref)
nodir 2015/06/15 23:50:21 nit: call it root_branch?
rmistry 2015/06/17 17:58:46 Done.
+ if parent_branch is None:
+ DieWithError('Can\'t find dependent branches from detached HEAD state. '
+ 'Get on a branch!')
+
+ branches = RunGit(['for-each-ref',
+ '--format=%(refname:short) %(upstream:short)',
+ 'refs/heads'])
+ if not branches:
+ print('No local branches found.')
+ return 0
+
+ # Create a dictionary of all local branches to the branches that are dependent
+ # on it.
+ tracked_to_dependents = {}
nodir 2015/06/15 23:50:21 collections.defaultdict([]) lines 1546-1547 can be
rmistry 2015/06/17 17:58:45 Cool. Done.
+ for b in branches.splitlines():
+ branch_name, tracked = b.split()
nodir 2015/06/15 23:50:22 this will crash on a non-tracked branch: b.split()
rmistry 2015/06/17 17:58:45 Done.
+ if tracked not in tracked_to_dependents:
+ tracked_to_dependents[tracked] = []
+ tracked_to_dependents[tracked].append(branch_name)
iannucci 2015/06/15 23:55:12 It would be worth consolidating this branch hierar
rmistry 2015/06/17 17:58:45 I looked at git_rebase_update and tried using some
+
+ print
+ print 'The dependent local branches of %s are:' % parent_branch
+ inorder_dependents = []
nodir 2015/06/15 23:50:22 nit: "inorder" is somewhat confusing because it is
rmistry 2015/06/17 17:58:46 Oops. Yea I meant preorder here.
+ def traverse_dependents_inorder(branch, padding=''):
+ dependents_to_process = tracked_to_dependents.get(branch, [])
+ padding += ' '
+ for dependent in dependents_to_process:
+ print '%s%s' % (padding, dependent)
+ inorder_dependents.append(dependent)
+ traverse_dependents_inorder(dependent, padding)
+ traverse_dependents_inorder(parent_branch)
+ print
+
+ print ('This command will checkout all dependent branches and run '
+ '"git cl upload".')
+ ask_for_data('[Press enter to dcommit or ctrl-C to quit]')
+
+ # Go through all dependents, checkout the branch and upload.
+ if inorder_dependents:
nodir 2015/06/15 23:50:22 inverse the condition, return early and deindent t
rmistry 2015/06/17 17:58:45 Done.
+ try:
+ for dependent_branch in inorder_dependents:
+ print
+ print '--------------------------------------'
+ print 'Running "git cl upload" from %s:' % dependent_branch
+ RunGit(['checkout', '-q', dependent_branch])
nodir 2015/06/15 23:50:22 can CMDupload_branch_deps be called when the work
rmistry 2015/06/17 17:58:45 At this point you have checked out a branch so AFA
+ print
+ if CMDupload(OptionParser(), args) != 0:
nodir 2015/06/15 23:50:22 Will it ask for pathset title every time? I think
rmistry 2015/06/17 17:58:45 I wanted to do this when I started this CL but for
+ print 'Upload failed for %s!' % dependent_branch
nodir 2015/06/15 23:50:21 I think users would thank you if you check that th
rmistry 2015/06/17 17:58:45 Yea I think that is an optimization that can be ma
+ return -1
+ print
+ finally:
+ # Swap back to the original parent branch.
+ RunGit(['checkout', '-q', parent_branch])
+
+ print
+ print 'All dependent branches %s have been updated!' % inorder_dependents
+ print
+ else:
+ print 'There are no dependent local branches for %s' % parent_branch
+
+ return 0
+
+
def CMDstatus(parser, args):
"""Show status of changelists.
« no previous file with comments | « no previous file | tests/git_cl_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698