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: |