sapling/edenscm/hgext/sendunbundlereplay.py
Stanislau Hlebik dee75aa345 pushrebase: support deletion of a bookmark in sendunbundlereplay
Summary:
Previously one couldn't use `sendunbundlereplay` to replay a bundle that just
deletes a bookmark i.e. sends only pushkey part. The problem was in that
`bundleoperation.gettransaction` method wasn't called and so a few hook
arguments weren't set.

In order to fix it this diff just calls this method before calling pushkey. The
solution is not clean, but I don't see much better alternatives.

Another smaller change that this diff is doing is changing sendunbundlereplay
command to require `--deleted` flag. This is just for convenience.

Reviewed By: quark-zju

Differential Revision: D14185380

fbshipit-source-id: f511dc0b9906520b7877501b37639d89ada6fc45
2019-02-25 13:08:00 -08:00

75 lines
2.4 KiB
Python

# sendunbundlereplay.py - send unbundlereplay wireproto command
#
# Copyright 2019-present Facebook, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
from edenscm.mercurial import error, hg, replay, util
from edenscm.mercurial.commands import command
from edenscm.mercurial.i18n import _
@command(
"^sendunbundlereplay",
[
("", "file", "", _("file to read bundle from"), ""),
("", "path", "", _("hg server remotepath (ssh)"), ""),
("r", "rebasedhead", "", _("expected rebased head hash"), ""),
(
"",
"deleted",
False,
_("bookmark was deleted, can't be used with `--rebasedhead`"),
),
("b", "ontobook", "", _("expected onto bookmark for pushrebase"), ""),
],
_("[OPTION]..."),
norepo=True,
)
def sendunbundlereplay(ui, **opts):
"""Send unbundlereplay wireproto command to a given server
Takes `rebasedhook` and `ontobook` arguments on the commmand
line, and commit dates in stdin. The commit date format is:
<commithash>=<hg-parseable-date>
``sendunbundlereplay.respondlightly`` config option instructs the server
to avoid sending large bundle2 parts back.
"""
fname = opts["file"]
path = opts["path"]
rebasedhead = opts["rebasedhead"]
deleted = opts["deleted"]
ontobook = opts["ontobook"]
if rebasedhead and deleted:
raise error.Abort("can't use `--rebasedhead` and `--deleted`")
if not (rebasedhead or deleted):
raise error.Abort("either `--rebasedhead` or `--deleted` should be used")
commitdates = dict(map(lambda s: s.split("="), ui.fin))
with open(fname, "rb") as f:
stream = util.chunkbuffer([f.read()])
remote = hg.peer(ui, {}, path)
reply = remote.unbundlereplay(
stream,
["force"],
remote.url(),
replay.ReplayData(commitdates, rebasedhead, ontobook),
ui.configbool("sendunbundlereplay", "respondlightly", True),
)
returncode = 0
for part in reply.iterparts():
part.read()
if part.type.startswith("error:"):
returncode = 1
ui.warn("%s\n" % part.type)
if "message" in part.params:
ui.warn("%s\n" % (part.params["message"]))
return returncode