mirror of
https://github.com/facebook/sapling.git
synced 2024-10-07 07:17:55 +03:00
make pushes faster in our reverse sync case
Summary: Our reverse sync job is too slow when pushing to svn. It seems like the slowness comes keep doing push-pull-rebase which doesn't seem necessary in our case. From my understanding, we need to do push-pull-rebase because we have multiple writers. In our sync job, we only have one writer and therefore can we skip the pulls and rebases? Reviewed By: DurhamG Differential Revision: D16442559 fbshipit-source-id: 926d1c516e8e6d59298d310fc67927ace37f72c9
This commit is contained in:
parent
83b1186e2a
commit
86bdaeb464
@ -22,6 +22,9 @@ Config::
|
||||
# Append 'REVERSE_SYNC_ONLY_HG_NODE: {hghash}' to the commit message when
|
||||
# committing to SVN. The hghash here is the original hash, before any rebase.
|
||||
rewritesvncommitwithhghash = False
|
||||
# Skip the post-push pull and rebase. This only works in single-writer
|
||||
# scenario and should only be used in HG -> SVN reverse sync.
|
||||
skippostpushpulls = False
|
||||
"""
|
||||
|
||||
from __future__ import absolute_import
|
||||
@ -429,6 +432,10 @@ configitem("hgsubversion", "repouuid", default="")
|
||||
# write the hg hash in the svn commit message when pushing to svn.
|
||||
# only used for HG -> SVN reverse sync.
|
||||
configitem("hgsubversion", "rewritesvncommitwithhghash", default=False)
|
||||
# skip the pulls and potential rebases after pushing each commits.
|
||||
# this significantly speed up the push but is not usable in multi-writer case.
|
||||
# only used for HG -> SVN reverse sync.
|
||||
configitem("hgsubversion", "skippostpushpulls", default=False)
|
||||
|
||||
|
||||
@templatekeyword("svnrev")
|
||||
|
@ -253,6 +253,7 @@ def push(repo, dest, force, revs):
|
||||
tip_ctx = repo[outgoing[-1]].p1()
|
||||
svnbranch = tip_ctx.branch()
|
||||
modified_files = {}
|
||||
pushedrev = None
|
||||
for i in range(len(outgoing) - 1, -1, -1):
|
||||
# 2. Pick the oldest changeset that needs to be pushed
|
||||
current_ctx = repo[outgoing[i]]
|
||||
@ -266,46 +267,51 @@ def push(repo, dest, force, revs):
|
||||
# results in nonzero exit status, see hg's commands.py
|
||||
return 0
|
||||
|
||||
# 3. Move the changeset to the tip of the branch if necessary
|
||||
conflicts = False
|
||||
for file in current_ctx.files():
|
||||
if file in modified_files:
|
||||
conflicts = True
|
||||
break
|
||||
|
||||
if conflicts or current_ctx.branch() != svnbranch:
|
||||
util.swap_out_encoding(old_encoding)
|
||||
try:
|
||||
|
||||
def extrafn(ctx, extra):
|
||||
extra["branch"] = ctx.branch()
|
||||
|
||||
ui.note("rebasing %s onto %s \n" % (current_ctx, tip_ctx))
|
||||
hgrebase.rebase(
|
||||
ui,
|
||||
repo,
|
||||
dest=node.hex(tip_ctx.node()),
|
||||
rev=[node.hex(current_ctx.node())],
|
||||
extrafn=extrafn,
|
||||
keep=True,
|
||||
)
|
||||
finally:
|
||||
util.swap_out_encoding()
|
||||
|
||||
# Don't trust the pre-rebase repo and context.
|
||||
repo = getlocalpeer(ui, {}, meta.path)
|
||||
meta = repo.svnmeta(svn.uuid, svn.subdir)
|
||||
hashes = meta.revmap.hashes()
|
||||
tip_ctx = repo[tip_ctx.node()]
|
||||
for c in tip_ctx.descendants():
|
||||
rebasesrc = c.extra().get("rebase_source")
|
||||
if rebasesrc and node.bin(rebasesrc) == current_ctx.node():
|
||||
current_ctx = c
|
||||
temporary_commits.append(c.node())
|
||||
if ui.configbool("hgsubversion", "skippostpushpulls"):
|
||||
# We use the revmap for the first commit.
|
||||
# After that, we use what we received from svn.
|
||||
tip_hash = pushedrev.revnum if pushedrev else hashes[tip_ctx.node()][0]
|
||||
else:
|
||||
# 3. Move the changeset to the tip of the branch if necessary
|
||||
conflicts = False
|
||||
for file in current_ctx.files():
|
||||
if file in modified_files:
|
||||
conflicts = True
|
||||
break
|
||||
|
||||
if conflicts or current_ctx.branch() != svnbranch:
|
||||
util.swap_out_encoding(old_encoding)
|
||||
try:
|
||||
|
||||
def extrafn(ctx, extra):
|
||||
extra["branch"] = ctx.branch()
|
||||
|
||||
ui.note("rebasing %s onto %s \n" % (current_ctx, tip_ctx))
|
||||
hgrebase.rebase(
|
||||
ui,
|
||||
repo,
|
||||
dest=node.hex(tip_ctx.node()),
|
||||
rev=[node.hex(current_ctx.node())],
|
||||
extrafn=extrafn,
|
||||
keep=True,
|
||||
)
|
||||
finally:
|
||||
util.swap_out_encoding()
|
||||
|
||||
# Don't trust the pre-rebase repo and context.
|
||||
repo = getlocalpeer(ui, {}, meta.path)
|
||||
meta = repo.svnmeta(svn.uuid, svn.subdir)
|
||||
hashes = meta.revmap.hashes()
|
||||
tip_ctx = repo[tip_ctx.node()]
|
||||
for c in tip_ctx.descendants():
|
||||
rebasesrc = c.extra().get("rebase_source")
|
||||
if rebasesrc and node.bin(rebasesrc) == current_ctx.node():
|
||||
current_ctx = c
|
||||
temporary_commits.append(c.node())
|
||||
break
|
||||
tip_hash = hashes[tip_ctx.node()][0]
|
||||
|
||||
# 4. Push the changeset to subversion
|
||||
tip_hash = hashes[tip_ctx.node()][0]
|
||||
try:
|
||||
ui.status("committing %s\n" % current_ctx)
|
||||
pushedrev = pushmod.commit(
|
||||
@ -325,6 +331,9 @@ def push(repo, dest, force, revs):
|
||||
# push a revision and pull it back.
|
||||
repo.hook("debug-hgsubversion-between-push-and-pull-for-tests")
|
||||
|
||||
if ui.configbool("hgsubversion", "skippostpushpulls"):
|
||||
continue
|
||||
|
||||
# 5. Pull the latest changesets from subversion, which will
|
||||
# include the one we just committed (and possibly others).
|
||||
r = pull(repo, dest, force=force, meta=meta)
|
||||
|
@ -854,6 +854,29 @@ class PushTests(test_hgsubversion_util.TestBase):
|
||||
"automated test\nREVERSE_SYNC_ONLY_HG_NODE: " + old_tip_hex,
|
||||
)
|
||||
|
||||
def test_push_with_skip_postpush_pull_config(self):
|
||||
"""
|
||||
Push performs a pull after each push. With a config, that is disabled.
|
||||
Lets ensure that code path works
|
||||
"""
|
||||
|
||||
changes = [("gamma", "gamma", "sometext")]
|
||||
self.commitchanges(changes)
|
||||
changes = [("gamma", "gamma", "someothertext")]
|
||||
newhash = self.commitchanges(changes)
|
||||
|
||||
repo = self.repo
|
||||
old_tip = self.repo["tip"].hex()
|
||||
hg.update(repo, newhash)
|
||||
self.pushrevisionswithconfigs(
|
||||
configs=[("hgsubversion", "skippostpushpulls", True)]
|
||||
)
|
||||
|
||||
# verify that we didn't pull new commits
|
||||
new_tip = self.repo["tip"].hex()
|
||||
self.assertEqual(old_tip, new_tip)
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import silenttestrunner
|
||||
|
Loading…
Reference in New Issue
Block a user