mirror of
https://github.com/facebook/sapling.git
synced 2024-10-10 16:57:49 +03:00
push: Improved the rebasing logic for push so that it doesn't break with
keeping branch names during rebase.
This commit is contained in:
parent
a8a83f58cc
commit
59a1a426b6
24
push_cmd.py
24
push_cmd.py
@ -39,8 +39,16 @@ def push_revisions_to_subversion(ui, repo, hg_repo_path, svn_url,
|
||||
return 1
|
||||
base_n = old_ctx.parents()[0].node()
|
||||
old_children = repo[base_n].children()
|
||||
svnbranch = repo[base_n].branch()
|
||||
oldtip = base_n
|
||||
samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch
|
||||
and c.node() in svn_commit_hashes]
|
||||
while samebranchchildren:
|
||||
oldtip = samebranchchildren[0].node()
|
||||
samebranchchildren = [c for c in repo[oldtip].children() if c.branch() == svnbranch
|
||||
and c.node() in svn_commit_hashes]
|
||||
# 2. Commit oldest revision that needs to be pushed
|
||||
base_revision = svn_commit_hashes[old_ctx.parents()[0].node()][0]
|
||||
base_revision = svn_commit_hashes[base_n][0]
|
||||
commit_from_rev(ui, repo, old_ctx, hge, svn_url, base_revision)
|
||||
# 3. Fetch revisions from svn
|
||||
r = fetch_command.fetch_revisions(ui, svn_url, hg_repo_path,
|
||||
@ -48,16 +56,20 @@ def push_revisions_to_subversion(ui, repo, hg_repo_path, svn_url,
|
||||
assert not r or r == 0
|
||||
# 4. Find the new head of the target branch
|
||||
repo = hg.repository(ui, hge.path)
|
||||
base_c = repo[base_n]
|
||||
replacement = [c for c in base_c.children() if c not in old_children
|
||||
and c.branch() == old_ctx.branch()]
|
||||
assert len(replacement) == 1
|
||||
oldtipctx = repo[oldtip]
|
||||
replacement = [c for c in oldtipctx.children() if c not in old_children
|
||||
and c.branch() == oldtipctx.branch()]
|
||||
assert len(replacement) == 1, 'Replacement node came back as: %r' % replacement
|
||||
replacement = replacement[0]
|
||||
# 5. Rebase all children of the currently-pushing rev to the new branch
|
||||
heads = repo.heads(old_ctx.node())
|
||||
for needs_transplant in heads:
|
||||
def extrafn(ctx, extra):
|
||||
if ctx.node() == oldest:
|
||||
return
|
||||
extra['branch'] = ctx.branch()
|
||||
hg.clean(repo, needs_transplant)
|
||||
utility_commands.rebase_commits(ui, repo, hg_repo_path, **opts)
|
||||
utility_commands.rebase_commits(ui, repo, hg_repo_path, extrafn=extrafn, **opts)
|
||||
repo = hg.repository(ui, hge.path)
|
||||
if needs_transplant in outgoing:
|
||||
hg.clean(repo, repo['tip'].node())
|
||||
|
@ -114,10 +114,48 @@ class PushTests(test_util.TestBase):
|
||||
self.pushrevisions()
|
||||
tip = self.repo['tip']
|
||||
self.assertNotEqual(tip.node(), old_tip)
|
||||
self.assertEqual(tip.parents()[0].node(), expected_parent)
|
||||
self.assertEqual(node.hex(tip.parents()[0].node()),
|
||||
node.hex(expected_parent))
|
||||
self.assertEqual(tip['adding_file'].data(), 'foo')
|
||||
self.assertEqual(tip.branch(), 'default')
|
||||
|
||||
def test_push_two_revs_different_local_branch(self):
|
||||
def filectxfn(repo, memctx, path):
|
||||
return context.memfilectx(path=path,
|
||||
data=path,
|
||||
islink=False,
|
||||
isexec=False,
|
||||
copied=False)
|
||||
oldtiphash = self.repo['default'].node()
|
||||
ctx = context.memctx(self.repo,
|
||||
(self.repo[0].node(), revlog.nullid, ),
|
||||
'automated test',
|
||||
['gamma', ],
|
||||
filectxfn,
|
||||
'testy',
|
||||
'2008-12-21 16:32:00 -0500',
|
||||
{'branch': 'localbranch', })
|
||||
newhash = self.repo.commitctx(ctx)
|
||||
ctx = context.memctx(self.repo,
|
||||
(newhash, revlog.nullid),
|
||||
'automated test2',
|
||||
['delta', ],
|
||||
filectxfn,
|
||||
'testy',
|
||||
'2008-12-21 16:32:00 -0500',
|
||||
{'branch': 'localbranch', })
|
||||
newhash = self.repo.commitctx(ctx)
|
||||
repo = self.repo
|
||||
hg.update(repo, newhash)
|
||||
push_cmd.push_revisions_to_subversion(ui.ui(),
|
||||
repo=repo,
|
||||
svn_url=test_util.fileurl(self.repo_path),
|
||||
hg_repo_path=self.wc_path)
|
||||
self.assertEqual(self.repo['tip'].parents()[0].parents()[0].node(), oldtiphash)
|
||||
self.assertEqual(self.repo['tip'].files(), ['delta', ])
|
||||
self.assertEqual(self.repo['tip'].manifest().keys(),
|
||||
['alpha', 'beta', 'gamma', 'delta'])
|
||||
|
||||
def test_push_two_revs(self):
|
||||
# set up some work for us
|
||||
self.test_push_to_default(commit=False)
|
||||
|
@ -78,7 +78,7 @@ def print_parent_revision(ui, repo, hg_repo_path, **opts):
|
||||
|
||||
|
||||
@util.register_subcommand('rebase')
|
||||
def rebase_commits(ui, repo, hg_repo_path, **opts):
|
||||
def rebase_commits(ui, repo, hg_repo_path, extrafn=None, **opts):
|
||||
"""Rebases current unpushed revisions onto Subversion head
|
||||
|
||||
This moves a line of development from making its own head to the top of
|
||||
@ -86,10 +86,12 @@ def rebase_commits(ui, repo, hg_repo_path, **opts):
|
||||
rebase on top of the current top of Subversion work, you should probably run
|
||||
'hg svn pull' before running this.
|
||||
"""
|
||||
def extrafn(ctx, extra):
|
||||
if extrafn is None:
|
||||
def extrafn2(ctx, extra):
|
||||
"""defined here so we can add things easily.
|
||||
"""
|
||||
extra['branch'] = ctx.branch()
|
||||
extrafn = extrafn2
|
||||
hge = hg_delta_editor.HgChangeReceiver(hg_repo_path,
|
||||
ui_=ui)
|
||||
svn_commit_hashes = dict(zip(hge.revmap.itervalues(),
|
||||
|
Loading…
Reference in New Issue
Block a user