mirror of
https://github.com/facebook/sapling.git
synced 2025-01-06 04:43:19 +03:00
import: add --bypass option
This feature is more a way to test patching without a working directory than something people asked about. Adding a --rev option to specify the parent patch revision would make it a little more useful. What this change introduces is patch.repobackend class which let patches be applied against repository revisions. The caller must supply a filestore object to receive patched content, which can be turned into a memctx with patch.makememctx() helper.
This commit is contained in:
parent
7350aaca49
commit
fd8786d770
@ -3002,6 +3002,8 @@ def identify(ui, repo, source=None, rev=None,
|
||||
('f', 'force', None, _('skip check for outstanding uncommitted changes')),
|
||||
('', 'no-commit', None,
|
||||
_("don't commit, just update the working directory")),
|
||||
('', 'bypass', None,
|
||||
_("apply patch without touching the working directory")),
|
||||
('', 'exact', None,
|
||||
_('apply patch to the nodes from which it was generated')),
|
||||
('', 'import-branch', None,
|
||||
@ -3035,6 +3037,11 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
the patch. This may happen due to character set problems or other
|
||||
deficiencies in the text patch format.
|
||||
|
||||
Use --bypass to apply and commit patches directly to the
|
||||
repository, not touching the working directory. Without --exact,
|
||||
patches will be applied on top of the working directory parent
|
||||
revision.
|
||||
|
||||
With -s/--similarity, hg will attempt to discover renames and
|
||||
copies in the patch in the same way as 'addremove'.
|
||||
|
||||
@ -3050,14 +3057,19 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
if date:
|
||||
opts['date'] = util.parsedate(date)
|
||||
|
||||
update = not opts.get('bypass')
|
||||
if not update and opts.get('no_commit'):
|
||||
raise util.Abort(_('cannot use --no-commit with --bypass'))
|
||||
try:
|
||||
sim = float(opts.get('similarity') or 0)
|
||||
except ValueError:
|
||||
raise util.Abort(_('similarity must be a number'))
|
||||
if sim < 0 or sim > 100:
|
||||
raise util.Abort(_('similarity must be between 0 and 100'))
|
||||
if sim and not update:
|
||||
raise util.Abort(_('cannot use --similarity with --bypass'))
|
||||
|
||||
if opts.get('exact') or not opts.get('force'):
|
||||
if (opts.get('exact') or not opts.get('force')) and update:
|
||||
cmdutil.bailifchanged(repo)
|
||||
|
||||
d = opts["base"]
|
||||
@ -3065,7 +3077,12 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
wlock = lock = None
|
||||
msgs = []
|
||||
|
||||
def tryone(ui, hunk):
|
||||
def checkexact(repo, n, nodeid):
|
||||
if opts.get('exact') and hex(n) != nodeid:
|
||||
repo.rollback()
|
||||
raise util.Abort(_('patch is damaged or loses information'))
|
||||
|
||||
def tryone(ui, hunk, parents):
|
||||
tmpname, message, user, date, branch, nodeid, p1, p2 = \
|
||||
patch.extract(ui, hunk)
|
||||
|
||||
@ -3086,9 +3103,8 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
message = None
|
||||
ui.debug('message:\n%s\n' % message)
|
||||
|
||||
wp = repo.parents()
|
||||
if len(wp) == 1:
|
||||
wp.append(repo[nullid])
|
||||
if len(parents) == 1:
|
||||
parents.append(repo[nullid])
|
||||
if opts.get('exact'):
|
||||
if not nodeid or not p1:
|
||||
raise util.Abort(_('not a Mercurial patch'))
|
||||
@ -3099,44 +3115,65 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
p1 = repo[p1]
|
||||
p2 = repo[p2]
|
||||
except error.RepoError:
|
||||
p1, p2 = wp
|
||||
p1, p2 = parents
|
||||
else:
|
||||
p1, p2 = wp
|
||||
p1, p2 = parents
|
||||
|
||||
if opts.get('exact') and p1 != wp[0]:
|
||||
hg.clean(repo, p1.node())
|
||||
if p1 != wp[0] and p2 != wp[1]:
|
||||
repo.dirstate.setparents(p1.node(), p2.node())
|
||||
n = None
|
||||
if update:
|
||||
if opts.get('exact') and p1 != parents[0]:
|
||||
hg.clean(repo, p1.node())
|
||||
if p1 != parents[0] and p2 != parents[1]:
|
||||
repo.dirstate.setparents(p1.node(), p2.node())
|
||||
|
||||
if opts.get('exact') or opts.get('import_branch'):
|
||||
repo.dirstate.setbranch(branch or 'default')
|
||||
if opts.get('exact') or opts.get('import_branch'):
|
||||
repo.dirstate.setbranch(branch or 'default')
|
||||
|
||||
files = set()
|
||||
patch.patch(ui, repo, tmpname, strip=strip, files=files,
|
||||
eolmode=None, similarity=sim / 100.0)
|
||||
files = list(files)
|
||||
if opts.get('no_commit'):
|
||||
if message:
|
||||
msgs.append(message)
|
||||
else:
|
||||
if opts.get('exact'):
|
||||
m = None
|
||||
files = set()
|
||||
patch.patch(ui, repo, tmpname, strip=strip, files=files,
|
||||
eolmode=None, similarity=sim / 100.0)
|
||||
files = list(files)
|
||||
if opts.get('no_commit'):
|
||||
if message:
|
||||
msgs.append(message)
|
||||
else:
|
||||
m = scmutil.matchfiles(repo, files or [])
|
||||
n = repo.commit(message, opts.get('user') or user,
|
||||
opts.get('date') or date, match=m,
|
||||
editor=cmdutil.commiteditor)
|
||||
if opts.get('exact'):
|
||||
if hex(n) != nodeid:
|
||||
repo.rollback()
|
||||
raise util.Abort(_('patch is damaged'
|
||||
' or loses information'))
|
||||
# Force a dirstate write so that the next transaction
|
||||
# backups an up-do-date file.
|
||||
repo.dirstate.write()
|
||||
if n:
|
||||
commitid = short(n)
|
||||
|
||||
if opts.get('exact'):
|
||||
m = None
|
||||
else:
|
||||
m = scmutil.matchfiles(repo, files or [])
|
||||
n = repo.commit(message, opts.get('user') or user,
|
||||
opts.get('date') or date, match=m,
|
||||
editor=cmdutil.commiteditor)
|
||||
checkexact(repo, n, nodeid)
|
||||
# Force a dirstate write so that the next transaction
|
||||
# backups an up-to-date file.
|
||||
repo.dirstate.write()
|
||||
else:
|
||||
if opts.get('exact') or opts.get('import_branch'):
|
||||
branch = branch or 'default'
|
||||
else:
|
||||
branch = p1.branch()
|
||||
store = patch.filestore()
|
||||
try:
|
||||
files = set()
|
||||
try:
|
||||
patch.patchrepo(ui, repo, p1, store, tmpname, strip,
|
||||
files, eolmode=None)
|
||||
except patch.PatchError, e:
|
||||
raise util.Abort(str(e))
|
||||
memctx = patch.makememctx(repo, (p1.node(), p2.node()),
|
||||
message,
|
||||
opts.get('user') or user,
|
||||
opts.get('date') or date,
|
||||
branch, files, store,
|
||||
editor=cmdutil.commiteditor)
|
||||
repo.savecommitmessage(memctx.description())
|
||||
n = memctx.commit()
|
||||
checkexact(repo, n, nodeid)
|
||||
finally:
|
||||
store.close()
|
||||
if n:
|
||||
commitid = short(n)
|
||||
return commitid
|
||||
finally:
|
||||
os.unlink(tmpname)
|
||||
@ -3144,6 +3181,7 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
try:
|
||||
wlock = repo.wlock()
|
||||
lock = repo.lock()
|
||||
parents = repo.parents()
|
||||
lastcommit = None
|
||||
for p in patches:
|
||||
pf = os.path.join(d, p)
|
||||
@ -3157,12 +3195,16 @@ def import_(ui, repo, patch1, *patches, **opts):
|
||||
|
||||
haspatch = False
|
||||
for hunk in patch.split(pf):
|
||||
commitid = tryone(ui, hunk)
|
||||
commitid = tryone(ui, hunk, parents)
|
||||
if commitid:
|
||||
haspatch = True
|
||||
if lastcommit:
|
||||
ui.status(_('applied %s\n') % lastcommit)
|
||||
lastcommit = commitid
|
||||
if update or opts.get('exact'):
|
||||
parents = repo.parents()
|
||||
else:
|
||||
parents = [repo[commitid]]
|
||||
|
||||
if not haspatch:
|
||||
raise util.Abort(_('no diffs found'))
|
||||
|
@ -11,7 +11,8 @@ import tempfile, zlib, shutil
|
||||
|
||||
from i18n import _
|
||||
from node import hex, nullid, short
|
||||
import base85, mdiff, scmutil, util, diffhelpers, copies, encoding
|
||||
import base85, mdiff, scmutil, util, diffhelpers, copies, encoding, error
|
||||
import context
|
||||
|
||||
gitre = re.compile('diff --git a/(.*) b/(.*)')
|
||||
|
||||
@ -511,6 +512,48 @@ class filestore(object):
|
||||
if self.opener:
|
||||
shutil.rmtree(self.opener.base)
|
||||
|
||||
class repobackend(abstractbackend):
|
||||
def __init__(self, ui, repo, ctx, store):
|
||||
super(repobackend, self).__init__(ui)
|
||||
self.repo = repo
|
||||
self.ctx = ctx
|
||||
self.store = store
|
||||
self.changed = set()
|
||||
self.removed = set()
|
||||
self.copied = {}
|
||||
|
||||
def _checkknown(self, fname):
|
||||
if fname not in self.ctx:
|
||||
raise PatchError(_('cannot patch %s: file is not tracked') % fname)
|
||||
|
||||
def getfile(self, fname):
|
||||
try:
|
||||
fctx = self.ctx[fname]
|
||||
except error.LookupError:
|
||||
raise IOError()
|
||||
flags = fctx.flags()
|
||||
return fctx.data(), ('l' in flags, 'x' in flags)
|
||||
|
||||
def setfile(self, fname, data, mode, copysource):
|
||||
if copysource:
|
||||
self._checkknown(copysource)
|
||||
if data is None:
|
||||
data = self.ctx[fname].data()
|
||||
self.store.setfile(fname, data, mode, copysource)
|
||||
self.changed.add(fname)
|
||||
if copysource:
|
||||
self.copied[fname] = copysource
|
||||
|
||||
def unlink(self, fname):
|
||||
self._checkknown(fname)
|
||||
self.removed.add(fname)
|
||||
|
||||
def exists(self, fname):
|
||||
return fname in self.ctx
|
||||
|
||||
def close(self):
|
||||
return self.changed | self.removed
|
||||
|
||||
# @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
|
||||
unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
|
||||
contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
|
||||
@ -1332,11 +1375,7 @@ def _externalpatch(ui, repo, patcher, patchname, strip, files,
|
||||
util.explainexit(code)[0])
|
||||
return fuzz
|
||||
|
||||
def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict',
|
||||
similarity=0):
|
||||
"""use builtin patch to apply <patchobj> to the working directory.
|
||||
returns whether patch was applied with fuzz factor."""
|
||||
|
||||
def patchbackend(ui, backend, patchobj, strip, files=None, eolmode='strict'):
|
||||
if files is None:
|
||||
files = set()
|
||||
if eolmode is None:
|
||||
@ -1346,7 +1385,6 @@ def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict',
|
||||
eolmode = eolmode.lower()
|
||||
|
||||
store = filestore()
|
||||
backend = workingbackend(ui, repo, similarity)
|
||||
try:
|
||||
fp = open(patchobj, 'rb')
|
||||
except TypeError:
|
||||
@ -1363,6 +1401,33 @@ def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict',
|
||||
raise PatchError(_('patch failed to apply'))
|
||||
return ret > 0
|
||||
|
||||
def internalpatch(ui, repo, patchobj, strip, files=None, eolmode='strict',
|
||||
similarity=0):
|
||||
"""use builtin patch to apply <patchobj> to the working directory.
|
||||
returns whether patch was applied with fuzz factor."""
|
||||
backend = workingbackend(ui, repo, similarity)
|
||||
return patchbackend(ui, backend, patchobj, strip, files, eolmode)
|
||||
|
||||
def patchrepo(ui, repo, ctx, store, patchobj, strip, files=None,
|
||||
eolmode='strict'):
|
||||
backend = repobackend(ui, repo, ctx, store)
|
||||
return patchbackend(ui, backend, patchobj, strip, files, eolmode)
|
||||
|
||||
def makememctx(repo, parents, text, user, date, branch, files, store,
|
||||
editor=None):
|
||||
def getfilectx(repo, memctx, path):
|
||||
data, (islink, isexec), copied = store.getfile(path)
|
||||
return context.memfilectx(path, data, islink=islink, isexec=isexec,
|
||||
copied=copied)
|
||||
extra = {}
|
||||
if branch:
|
||||
extra['branch'] = encoding.fromlocal(branch)
|
||||
ctx = context.memctx(repo, parents, text, files, getfilectx, user,
|
||||
date, extra)
|
||||
if editor:
|
||||
ctx._text = editor(repo, ctx, [])
|
||||
return ctx
|
||||
|
||||
def patch(ui, repo, patchname, strip=1, files=None, eolmode='strict',
|
||||
similarity=0):
|
||||
"""Apply <patchname> to the working directory.
|
||||
|
@ -245,7 +245,7 @@ Show all commands + options
|
||||
heads: rev, topo, active, closed, style, template
|
||||
help: extension, command
|
||||
identify: rev, num, id, branch, tags, bookmarks
|
||||
import: strip, base, force, no-commit, exact, import-branch, message, logfile, date, user, similarity
|
||||
import: strip, base, force, no-commit, bypass, exact, import-branch, message, logfile, date, user, similarity
|
||||
incoming: force, newest-first, bundle, rev, bookmarks, branch, patch, git, limit, no-merges, stat, style, template, ssh, remotecmd, insecure, subrepos
|
||||
locate: rev, print0, fullpath, include, exclude
|
||||
manifest: rev, all
|
||||
|
261
tests/test-import-bypass.t
Normal file
261
tests/test-import-bypass.t
Normal file
@ -0,0 +1,261 @@
|
||||
$ echo "[extensions]" >> $HGRCPATH
|
||||
$ echo "purge=" >> $HGRCPATH
|
||||
$ echo "graphlog=" >> $HGRCPATH
|
||||
|
||||
$ shortlog() {
|
||||
> hg glog --template '{rev}:{node|short} {author} {date|hgdate} - {branch} - {desc|firstline}\n'
|
||||
> }
|
||||
|
||||
Test --bypass with other options
|
||||
|
||||
$ hg init repo-options
|
||||
$ cd repo-options
|
||||
$ echo a > a
|
||||
$ hg ci -Am adda
|
||||
adding a
|
||||
$ echo a >> a
|
||||
$ hg branch foo
|
||||
marked working directory as branch foo
|
||||
$ hg ci -Am changea
|
||||
$ hg export . > ../test.diff
|
||||
$ hg up null
|
||||
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
|
||||
|
||||
Test importing an existing revision
|
||||
|
||||
$ hg import --bypass --exact ../test.diff
|
||||
applying ../test.diff
|
||||
$ shortlog
|
||||
o 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|
|
||||
o 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
|
||||
Test failure without --exact
|
||||
|
||||
$ hg import --bypass ../test.diff
|
||||
applying ../test.diff
|
||||
unable to find 'a' for patching
|
||||
abort: patch failed to apply
|
||||
[255]
|
||||
$ hg st
|
||||
$ shortlog
|
||||
o 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|
|
||||
o 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
|
||||
Test --user, --date and --message
|
||||
|
||||
$ hg up 0
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
$ hg import --bypass --u test2 -d '1 0' -m patch2 ../test.diff
|
||||
applying ../test.diff
|
||||
$ cat .hg/last-message.txt
|
||||
patch2 (no-eol)
|
||||
$ shortlog
|
||||
o 2:2e127d1da504 test2 1 0 - default - patch2
|
||||
|
|
||||
| o 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|/
|
||||
@ 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
$ hg rollback
|
||||
repository tip rolled back to revision 1 (undo commit)
|
||||
working directory now based on revision 0
|
||||
|
||||
Test --import-branch
|
||||
|
||||
$ hg import --bypass --import-branch ../test.diff
|
||||
applying ../test.diff
|
||||
$ shortlog
|
||||
o 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|
|
||||
@ 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
$ hg rollback
|
||||
repository tip rolled back to revision 1 (undo commit)
|
||||
working directory now based on revision 0
|
||||
|
||||
Test --strip
|
||||
|
||||
$ hg import --bypass --strip 0 - <<EOF
|
||||
> # HG changeset patch
|
||||
> # User test
|
||||
> # Date 0 0
|
||||
> # Branch foo
|
||||
> # Node ID 4e322f7ce8e3e4203950eac9ece27bf7e45ffa6c
|
||||
> # Parent 07f4944404050f47db2e5c5071e0e84e7a27bba9
|
||||
> changea
|
||||
>
|
||||
> diff -r 07f494440405 -r 4e322f7ce8e3 a
|
||||
> --- a Thu Jan 01 00:00:00 1970 +0000
|
||||
> +++ a Thu Jan 01 00:00:00 1970 +0000
|
||||
> @@ -1,1 +1,2 @@
|
||||
> a
|
||||
> +a
|
||||
> EOF
|
||||
applying patch from stdin
|
||||
$ hg rollback
|
||||
repository tip rolled back to revision 1 (undo commit)
|
||||
working directory now based on revision 0
|
||||
|
||||
Test unsupported combinations
|
||||
|
||||
$ hg import --bypass --no-commit ../test.diff
|
||||
abort: cannot use --no-commit with --bypass
|
||||
[255]
|
||||
$ hg import --bypass --similarity 50 ../test.diff
|
||||
abort: cannot use --similarity with --bypass
|
||||
[255]
|
||||
|
||||
Test commit editor
|
||||
|
||||
$ hg diff -c 1 > ../test.diff
|
||||
$ HGEDITOR=cat hg import --bypass ../test.diff
|
||||
applying ../test.diff
|
||||
|
||||
|
||||
HG: Enter commit message. Lines beginning with 'HG:' are removed.
|
||||
HG: Leave message empty to abort commit.
|
||||
HG: --
|
||||
HG: user: test
|
||||
HG: branch 'default'
|
||||
HG: changed a
|
||||
abort: empty commit message
|
||||
[255]
|
||||
|
||||
Test patch.eol is handled
|
||||
|
||||
$ python -c 'file("a", "wb").write("a\r\n")'
|
||||
$ hg ci -m makeacrlf
|
||||
$ hg import -m 'should fail because of eol' --bypass ../test.diff
|
||||
applying ../test.diff
|
||||
patching file a
|
||||
Hunk #1 FAILED at 0
|
||||
abort: patch failed to apply
|
||||
[255]
|
||||
$ hg --config patch.eol=auto import -d '0 0' -m 'test patch.eol' --bypass ../test.diff
|
||||
applying ../test.diff
|
||||
$ shortlog
|
||||
o 3:d7805b4d2cb3 test 0 0 - default - test patch.eol
|
||||
|
|
||||
@ 2:872023de769d test 0 0 - default - makeacrlf
|
||||
|
|
||||
| o 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|/
|
||||
o 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
|
||||
Test applying multiple patches
|
||||
|
||||
$ hg up -qC 0
|
||||
$ echo e > e
|
||||
$ hg ci -Am adde
|
||||
adding e
|
||||
created new head
|
||||
$ hg export . > ../patch1.diff
|
||||
$ hg up -qC 1
|
||||
$ echo f > f
|
||||
$ hg ci -Am addf
|
||||
adding f
|
||||
$ hg export . > ../patch2.diff
|
||||
$ cd ..
|
||||
$ hg clone -r1 repo-options repo-multi1
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 2 changesets with 2 changes to 1 files
|
||||
updating to branch foo
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
$ cd repo-multi1
|
||||
$ hg up 0
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
$ hg import --bypass ../patch1.diff ../patch2.diff
|
||||
applying ../patch1.diff
|
||||
applying ../patch2.diff
|
||||
applied 16581080145e
|
||||
$ shortlog
|
||||
o 3:bc8ca3f8a7c4 test 0 0 - default - addf
|
||||
|
|
||||
o 2:16581080145e test 0 0 - default - adde
|
||||
|
|
||||
| o 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|/
|
||||
@ 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
|
||||
Test applying multiple patches with --exact
|
||||
|
||||
$ cd ..
|
||||
$ hg clone -r1 repo-options repo-multi2
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 2 changesets with 2 changes to 1 files
|
||||
updating to branch foo
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
$ cd repo-multi2
|
||||
$ hg import --bypass --exact ../patch1.diff ../patch2.diff
|
||||
applying ../patch1.diff
|
||||
applying ../patch2.diff
|
||||
applied 16581080145e
|
||||
$ shortlog
|
||||
o 3:d60cb8989666 test 0 0 - foo - addf
|
||||
|
|
||||
| o 2:16581080145e test 0 0 - default - adde
|
||||
| |
|
||||
@ | 1:4e322f7ce8e3 test 0 0 - foo - changea
|
||||
|/
|
||||
o 0:07f494440405 test 0 0 - default - adda
|
||||
|
||||
|
||||
$ cd ..
|
||||
|
||||
Test complicated patch with --exact
|
||||
|
||||
$ hg init repo-exact
|
||||
$ cd repo-exact
|
||||
$ echo a > a
|
||||
$ echo c > c
|
||||
$ echo d > d
|
||||
$ echo e > e
|
||||
$ echo f > f
|
||||
$ chmod +x f
|
||||
$ ln -s c linkc
|
||||
$ hg ci -Am t
|
||||
adding a
|
||||
adding c
|
||||
adding d
|
||||
adding e
|
||||
adding f
|
||||
adding linkc
|
||||
$ hg cp a aa1
|
||||
$ echo b >> a
|
||||
$ echo b > b
|
||||
$ hg add b
|
||||
$ hg cp a aa2
|
||||
$ echo aa >> aa2
|
||||
$ chmod +x e
|
||||
$ chmod -x f
|
||||
$ ln -s a linka
|
||||
$ hg rm d
|
||||
$ hg rm linkc
|
||||
$ hg mv c cc
|
||||
$ hg ci -m patch
|
||||
$ hg export --git . > ../test.diff
|
||||
$ hg up -C null
|
||||
0 files updated, 0 files merged, 7 files removed, 0 files unresolved
|
||||
$ hg purge
|
||||
$ hg st
|
||||
$ hg import --bypass --exact ../test.diff
|
||||
applying ../test.diff
|
||||
|
||||
The patch should have matched the exported revision and generated no additional
|
||||
data. If not, diff both heads to debug it.
|
||||
|
||||
$ shortlog
|
||||
o 1:2978fd5c8aa4 test 0 0 - default - patch
|
||||
|
|
||||
o 0:a0e19e636a43 test 0 0 - default - t
|
||||
|
Loading…
Reference in New Issue
Block a user