Mercurial > hgsubversion
comparison push_cmd.py @ 150:58ae90a65f41
push: Improved the rebasing logic for push so that it doesn't break with
keeping branch names during rebase.
| author | Augie Fackler <durin42@gmail.com> |
|---|---|
| date | Mon, 22 Dec 2008 21:21:11 -0600 |
| parents | 1da7aafdd323 |
| children | 2decec74ad0c |
comparison
equal
deleted
inserted
replaced
| 149:04800fda7af5 | 150:58ae90a65f41 |
|---|---|
| 37 ui.status('Found a branch merge, this needs discussion and ' | 37 ui.status('Found a branch merge, this needs discussion and ' |
| 38 'implementation.') | 38 'implementation.') |
| 39 return 1 | 39 return 1 |
| 40 base_n = old_ctx.parents()[0].node() | 40 base_n = old_ctx.parents()[0].node() |
| 41 old_children = repo[base_n].children() | 41 old_children = repo[base_n].children() |
| 42 svnbranch = repo[base_n].branch() | |
| 43 oldtip = base_n | |
| 44 samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch | |
| 45 and c.node() in svn_commit_hashes] | |
| 46 while samebranchchildren: | |
| 47 oldtip = samebranchchildren[0].node() | |
| 48 samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch | |
| 49 and c.node() in svn_commit_hashes] | |
| 42 # 2. Commit oldest revision that needs to be pushed | 50 # 2. Commit oldest revision that needs to be pushed |
| 43 base_revision = svn_commit_hashes[old_ctx.parents()[0].node()][0] | 51 base_revision = svn_commit_hashes[base_n][0] |
| 44 commit_from_rev(ui, repo, old_ctx, hge, svn_url, base_revision) | 52 commit_from_rev(ui, repo, old_ctx, hge, svn_url, base_revision) |
| 45 # 3. Fetch revisions from svn | 53 # 3. Fetch revisions from svn |
| 46 r = fetch_command.fetch_revisions(ui, svn_url, hg_repo_path, | 54 r = fetch_command.fetch_revisions(ui, svn_url, hg_repo_path, |
| 47 stupid=stupid) | 55 stupid=stupid) |
| 48 assert not r or r == 0 | 56 assert not r or r == 0 |
| 49 # 4. Find the new head of the target branch | 57 # 4. Find the new head of the target branch |
| 50 repo = hg.repository(ui, hge.path) | 58 repo = hg.repository(ui, hge.path) |
| 51 base_c = repo[base_n] | 59 oldtipctx = repo[oldtip] |
| 52 replacement = [c for c in base_c.children() if c not in old_children | 60 replacement = [c for c in oldtipctx.children() if c not in old_children |
| 53 and c.branch() == old_ctx.branch()] | 61 and c.branch() == oldtipctx.branch()] |
| 54 assert len(replacement) == 1 | 62 assert len(replacement) == 1, 'Replacement node came back as: %r' % replacement |
| 55 replacement = replacement[0] | 63 replacement = replacement[0] |
| 56 # 5. Rebase all children of the currently-pushing rev to the new branch | 64 # 5. Rebase all children of the currently-pushing rev to the new branch |
| 57 heads = repo.heads(old_ctx.node()) | 65 heads = repo.heads(old_ctx.node()) |
| 58 for needs_transplant in heads: | 66 for needs_transplant in heads: |
| 67 def extrafn(ctx, extra): | |
| 68 if ctx.node() == oldest: | |
| 69 return | |
| 70 extra['branch'] = ctx.branch() | |
| 59 hg.clean(repo, needs_transplant) | 71 hg.clean(repo, needs_transplant) |
| 60 utility_commands.rebase_commits(ui, repo, hg_repo_path, **opts) | 72 utility_commands.rebase_commits(ui, repo, hg_repo_path, extrafn=extrafn, **opts) |
| 61 repo = hg.repository(ui, hge.path) | 73 repo = hg.repository(ui, hge.path) |
| 62 if needs_transplant in outgoing: | 74 if needs_transplant in outgoing: |
| 63 hg.clean(repo, repo['tip'].node()) | 75 hg.clean(repo, repo['tip'].node()) |
| 64 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) | 76 hge = hg_delta_editor.HgChangeReceiver(hg_repo_path, ui_=ui) |
| 65 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), | 77 svn_commit_hashes = dict(zip(hge.revmap.itervalues(), |
| 124 for d in olddirs: | 136 for d in olddirs: |
| 125 if d not in newdirs and exists(d): | 137 if d not in newdirs and exists(d): |
| 126 deleted.append(d) | 138 deleted.append(d) |
| 127 | 139 |
| 128 return added, deleted | 140 return added, deleted |
| 129 | 141 |
| 130 | 142 |
| 131 def commit_from_rev(ui, repo, rev_ctx, hg_editor, svn_url, base_revision): | 143 def commit_from_rev(ui, repo, rev_ctx, hg_editor, svn_url, base_revision): |
| 132 """Build and send a commit from Mercurial to Subversion. | 144 """Build and send a commit from Mercurial to Subversion. |
| 133 """ | 145 """ |
| 134 file_data = {} | 146 file_data = {} |
| 138 branch_path = 'trunk' | 150 branch_path = 'trunk' |
| 139 | 151 |
| 140 if parent_branch and parent_branch != 'default': | 152 if parent_branch and parent_branch != 'default': |
| 141 branch_path = 'branches/%s' % parent_branch | 153 branch_path = 'branches/%s' % parent_branch |
| 142 | 154 |
| 143 addeddirs, deleteddirs = _getdirchanges(svn, branch_path, parent, | 155 addeddirs, deleteddirs = _getdirchanges(svn, branch_path, parent, |
| 144 rev_ctx, rev_ctx.files()) | 156 rev_ctx, rev_ctx.files()) |
| 145 deleteddirs = set(deleteddirs) | 157 deleteddirs = set(deleteddirs) |
| 146 | 158 |
| 147 props = {} | 159 props = {} |
| 148 copies = {} | 160 copies = {} |
| 219 addeddirs = [svnpath(d) for d in addeddirs] | 231 addeddirs = [svnpath(d) for d in addeddirs] |
| 220 deleteddirs = [svnpath(d) for d in deleteddirs] | 232 deleteddirs = [svnpath(d) for d in deleteddirs] |
| 221 new_target_files += addeddirs + deleteddirs | 233 new_target_files += addeddirs + deleteddirs |
| 222 try: | 234 try: |
| 223 svn.commit(new_target_files, rev_ctx.description(), file_data, | 235 svn.commit(new_target_files, rev_ctx.description(), file_data, |
| 224 base_revision, set(addeddirs), set(deleteddirs), | 236 base_revision, set(addeddirs), set(deleteddirs), |
| 225 props, newcopies) | 237 props, newcopies) |
| 226 except core.SubversionException, e: | 238 except core.SubversionException, e: |
| 227 if hasattr(e, 'apr_err') and e.apr_err == 160028: | 239 if hasattr(e, 'apr_err') and e.apr_err == 160028: |
| 228 raise merc_util.Abort('Base text was out of date, maybe rebase?') | 240 raise merc_util.Abort('Base text was out of date, maybe rebase?') |
| 229 else: | 241 else: |
