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: