def upload_branch_deps(cl, args):
    'Uploads CLs of local branches that are dependents of the current branch.\n\n  If the local branch dependency tree looks like:\n  test1 -> test2.1 -> test3.1\n                   -> test3.2\n        -> test2.2 -> test3.3\n\n  and you run "git cl upload --dependencies" from test1 then "git cl upload" is\n  run on the dependent branches in this order:\n  test2.1, test3.1, test3.2, test2.2, test3.3\n\n  Note: This function does not rebase your local dependent branches. Use it when\n        you make a change to the parent branch that will not conflict with its\n        dependent branches, and you would like their dependencies updated in\n        Rietveld.\n  '
    if git_common.is_dirty_git_tree('upload-branch-deps'):
        return 1
    root_branch = cl.GetBranch()
    if (root_branch is None):
        DieWithError("Can't find dependent branches from detached HEAD state. Get on a branch!")
    if ((not cl.GetIssue()) or (not cl.GetPatchset())):
        DieWithError('Current branch does not have an uploaded CL. We cannot set patchset dependencies without an uploaded CL.')
    branches = RunGit(['for-each-ref', '--format=%(refname:short) %(upstream:short)', 'refs/heads'])
    if (not branches):
        print('No local branches found.')
        return 0
    tracked_to_dependents = collections.defaultdict(list)
    for b in branches.splitlines():
        tokens = b.split()
        if (len(tokens) == 2):
            (branch_name, tracked) = tokens
            tracked_to_dependents[tracked].append(branch_name)
    print()
    print(('The dependent local branches of %s are:' % root_branch))
    dependents = []

    def traverse_dependents_preorder(branch, padding=''):
        dependents_to_process = tracked_to_dependents.get(branch, [])
        padding += '  '
        for dependent in dependents_to_process:
            print(('%s%s' % (padding, dependent)))
            dependents.append(dependent)
            traverse_dependents_preorder(dependent, padding)
    traverse_dependents_preorder(root_branch)
    print()
    if (not dependents):
        print(('There are no dependent local branches for %s' % root_branch))
        return 0
    print('This command will checkout all dependent branches and run "git cl upload".')
    ask_for_data('[Press enter to continue or ctrl-C to quit]')
    if (not cl.IsGerrit()):
        args.extend(['-t', 'Updated patchset dependency'])
    failures = {}
    try:
        for dependent_branch in dependents:
            print()
            print('--------------------------------------')
            print(('Running "git cl upload" from %s:' % dependent_branch))
            RunGit(['checkout', '-q', dependent_branch])
            print()
            try:
                if (CMDupload(OptionParser(), args) != 0):
                    print(('Upload failed for %s!' % dependent_branch))
                    failures[dependent_branch] = 1
            except:
                failures[dependent_branch] = 1
            print()
    finally:
        RunGit(['checkout', '-q', root_branch])
    print()
    print('Upload complete for dependent branches!')
    for dependent_branch in dependents:
        upload_status = ('failed' if failures.get(dependent_branch) else 'succeeded')
        print(('  %s : %s' % (dependent_branch, upload_status)))
    print()
    return 0
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 "git cl upload --dependencies" 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 function 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.
def upload_branch_deps(cl, args):
    'Uploads CLs of local branches that are dependents of the current branch.\n\n  If the local branch dependency tree looks like:\n  test1 -> test2.1 -> test3.1\n                   -> test3.2\n        -> test2.2 -> test3.3\n\n  and you run "git cl upload --dependencies" from test1 then "git cl upload" is\n  run on the dependent branches in this order:\n  test2.1, test3.1, test3.2, test2.2, test3.3\n\n  Note: This function does not rebase your local dependent branches. Use it when\n        you make a change to the parent branch that will not conflict with its\n        dependent branches, and you would like their dependencies updated in\n        Rietveld.\n  '
    if git_common.is_dirty_git_tree('upload-branch-deps'):
        return 1
    root_branch = cl.GetBranch()
    if (root_branch is None):
        DieWithError("Can't find dependent branches from detached HEAD state. Get on a branch!")
    if ((not cl.GetIssue()) or (not cl.GetPatchset())):
        DieWithError('Current branch does not have an uploaded CL. We cannot set patchset dependencies without an uploaded CL.')
    branches = RunGit(['for-each-ref', '--format=%(refname:short) %(upstream:short)', 'refs/heads'])
    if (not branches):
        print('No local branches found.')
        return 0
    tracked_to_dependents = collections.defaultdict(list)
    for b in branches.splitlines():
        tokens = b.split()
        if (len(tokens) == 2):
            (branch_name, tracked) = tokens
            tracked_to_dependents[tracked].append(branch_name)
    print()
    print(('The dependent local branches of %s are:' % root_branch))
    dependents = []

    def traverse_dependents_preorder(branch, padding=):
        dependents_to_process = tracked_to_dependents.get(branch, [])
        padding += '  '
        for dependent in dependents_to_process:
            print(('%s%s' % (padding, dependent)))
            dependents.append(dependent)
            traverse_dependents_preorder(dependent, padding)
    traverse_dependents_preorder(root_branch)
    print()
    if (not dependents):
        print(('There are no dependent local branches for %s' % root_branch))
        return 0
    print('This command will checkout all dependent branches and run "git cl upload".')
    ask_for_data('[Press enter to continue or ctrl-C to quit]')
    if (not cl.IsGerrit()):
        args.extend(['-t', 'Updated patchset dependency'])
    failures = {}
    try:
        for dependent_branch in dependents:
            print()
            print('--------------------------------------')
            print(('Running "git cl upload" from %s:' % dependent_branch))
            RunGit(['checkout', '-q', dependent_branch])
            print()
            try:
                if (CMDupload(OptionParser(), args) != 0):
                    print(('Upload failed for %s!' % dependent_branch))
                    failures[dependent_branch] = 1
            except:
                failures[dependent_branch] = 1
            print()
    finally:
        RunGit(['checkout', '-q', root_branch])
    print()
    print('Upload complete for dependent branches!')
    for dependent_branch in dependents:
        upload_status = ('failed' if failures.get(dependent_branch) else 'succeeded')
        print(('  %s : %s' % (dependent_branch, upload_status)))
    print()
    return 0