Index: git_cl.py |
=================================================================== |
--- git_cl.py (revision 141621) |
+++ git_cl.py (working copy) |
@@ -69,8 +69,13 @@ |
def RunGitWithCode(args): |
"""Returns return code and stdout.""" |
- out, code = subprocess2.communicate(['git'] + args, stdout=subprocess2.PIPE) |
- return code, out[0] |
+ try: |
+ out, code = subprocess2.communicate(['git'] + args, stdout=subprocess2.PIPE) |
+ return code, out[0] |
+ except ValueError: |
+ # When the subprocess fails, it returns None. That triggers a ValueError |
+ # when trying to unpack the return value into (out, code). |
+ return 1, '' |
def usage(more): |
@@ -1135,6 +1140,14 @@ |
return RietveldUpload(options, args, cl) |
+def IsSubmoduleMergeCommit(ref): |
+ # When submodules are added to the repo, we expect there to be a single |
+ # non-git-svn merge commit at remote HEAD with a signature comment. |
+ pattern = '^SVN changes up to revision [0-9]*$' |
+ cmd = ['rev-list', '--merges', '--grep="%s"' % pattern, '%s^!' % ref] |
+ return RunGit(cmd) != '' |
+ |
+ |
def SendUpstream(parser, args, cmd): |
"""Common code for CmdPush and CmdDCommit |
@@ -1166,6 +1179,7 @@ |
return 1 |
base_branch = args[0] |
+ base_has_submodules = IsSubmoduleMergeCommit(base_branch) |
# Make sure index is up-to-date before running diff-index. |
RunGit(['update-index', '--refresh', '-q'], error_ok=True) |
@@ -1183,11 +1197,18 @@ |
print 'Run "git merge %s" before attempting to %s.' % (base_branch, cmd) |
return 1 |
+ # This is the revision `svn dcommit` will commit on top of. |
+ svn_head = RunGit(['log', '--grep=^git-svn-id:', '-1', |
+ '--pretty=format:%H']) |
+ |
if cmd == 'dcommit': |
- # This is the revision `svn dcommit` will commit on top of. |
- svn_head = RunGit(['log', '--grep=^git-svn-id:', '-1', |
- '--pretty=format:%H']) |
- extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch]) |
+ # If the base_head is a submodule merge commit, the first parent of the |
+ # base_head should be a git-svn commit, which is what we're interested in. |
+ base_svn_head = base_branch |
+ if base_has_submodules: |
+ base_svn_head += '^1' |
+ |
+ extra_commits = RunGit(['rev-list', '^' + svn_head, base_svn_head]) |
if extra_commits: |
print ('This branch has %d additional commits not upstreamed yet.' |
% len(extra_commits.splitlines())) |
@@ -1246,15 +1267,19 @@ |
subprocess2.call(['git', 'diff', '--stat'] + branches) |
ask_for_data('About to commit; enter to confirm.') |
- # We want to squash all this branch's commits into one commit with the |
- # proper description. |
- # We do this by doing a "reset --soft" to the base branch (which keeps |
- # the working copy the same), then dcommitting that. |
+ # We want to squash all this branch's commits into one commit with the proper |
+ # description. We do this by doing a "reset --soft" to the base branch (which |
+ # keeps the working copy the same), then dcommitting that. If origin/master |
+ # has a submodule merge commit, we'll also need to cherry-pick the squashed |
+ # commit onto a branch based on the git-svn head. |
MERGE_BRANCH = 'git-cl-commit' |
- # Delete the merge branch if it already exists. |
- if RunGitWithCode(['show-ref', '--quiet', '--verify', |
- 'refs/heads/' + MERGE_BRANCH])[0] == 0: |
- RunGit(['branch', '-D', MERGE_BRANCH]) |
+ CHERRY_PICK_BRANCH = 'git-cl-cherry-pick' |
+ # Delete the branches if they exist. |
+ for branch in [MERGE_BRANCH, CHERRY_PICK_BRANCH]: |
+ showref_cmd = ['show-ref', '--quiet', '--verify', 'refs/heads/%s' % branch] |
+ result = RunGitWithCode(showref_cmd) |
+ if result[0] == 0: |
+ RunGit(['branch', '-D', branch]) |
# We might be in a directory that's present in this branch but not in the |
# trunk. Move up to the top of the tree so that git commands that expect a |
@@ -1274,6 +1299,11 @@ |
RunGit(['commit', '--author', options.contributor, '-m', description]) |
else: |
RunGit(['commit', '-m', description]) |
+ if base_has_submodules: |
+ cherry_pick_commit = RunGit(['rev-list', 'HEAD^!']).rstrip() |
+ RunGit(['branch', CHERRY_PICK_BRANCH, svn_head]) |
+ RunGit(['checkout', CHERRY_PICK_BRANCH]) |
+ RunGit(['cherry-pick', cherry_pick_commit]) |
if cmd == 'push': |
# push the merge branch. |
remote, branch = cl.FetchUpstreamTuple() |
@@ -1288,6 +1318,8 @@ |
# And then swap back to the original branch and clean up. |
RunGit(['checkout', '-q', cl.GetBranch()]) |
RunGit(['branch', '-D', MERGE_BRANCH]) |
+ if base_has_submodules: |
+ RunGit(['branch', '-D', CHERRY_PICK_BRANCH]) |
if cl.GetIssue(): |
if cmd == 'dcommit' and 'Committed r' in output: |