|
@@
-7,7
+7,7
b''
|
|
7
|
# GNU General Public License version 2 or any later version.
|
|
7
|
# GNU General Public License version 2 or any later version.
|
|
8
|
|
|
8
|
|
|
9
|
import cStringIO, email.Parser, os, errno, re
|
|
9
|
import cStringIO, email.Parser, os, errno, re
|
|
10
|
import tempfile, zlib
|
|
10
|
import tempfile, zlib, shutil
|
|
11
|
|
|
11
|
|
|
12
|
from i18n import _
|
|
12
|
from i18n import _
|
|
13
|
from node import hex, nullid, short
|
|
13
|
from node import hex, nullid, short
|
|
@@
-362,10
+362,11
b' class abstractbackend(object):'
|
|
362
|
"""
|
|
362
|
"""
|
|
363
|
raise NotImplementedError
|
|
363
|
raise NotImplementedError
|
|
364
|
|
|
364
|
|
|
365
|
def setfile(self, fname, data, mode):
|
|
365
|
def setfile(self, fname, data, mode, copysource):
|
|
366
|
"""Write data to target file fname and set its mode. mode is a
|
|
366
|
"""Write data to target file fname and set its mode. mode is a
|
|
367
|
(islink, isexec) tuple. If data is None, the file content should
|
|
367
|
(islink, isexec) tuple. If data is None, the file content should
|
|
368
|
be left unchanged.
|
|
368
|
be left unchanged. If the file is modified after being copied,
|
|
|
|
|
369
|
copysource is set to the original file name.
|
|
369
|
"""
|
|
370
|
"""
|
|
370
|
raise NotImplementedError
|
|
371
|
raise NotImplementedError
|
|
371
|
|
|
372
|
|
|
@@
-380,13
+381,6
b' class abstractbackend(object):'
|
|
380
|
"""
|
|
381
|
"""
|
|
381
|
pass
|
|
382
|
pass
|
|
382
|
|
|
383
|
|
|
383
|
def copy(self, src, dst):
|
|
|
|
|
384
|
"""Copy src file into dst file. Create intermediate directories if
|
|
|
|
|
385
|
necessary. Files are specified relatively to the patching base
|
|
|
|
|
386
|
directory.
|
|
|
|
|
387
|
"""
|
|
|
|
|
388
|
raise NotImplementedError
|
|
|
|
|
389
|
|
|
|
|
|
390
|
def exists(self, fname):
|
|
384
|
def exists(self, fname):
|
|
391
|
raise NotImplementedError
|
|
385
|
raise NotImplementedError
|
|
392
|
|
|
386
|
|
|
@@
-411,7
+405,7
b' class fsbackend(abstractbackend):'
|
|
411
|
raise
|
|
405
|
raise
|
|
412
|
return (self.opener.read(fname), (islink, isexec))
|
|
406
|
return (self.opener.read(fname), (islink, isexec))
|
|
413
|
|
|
407
|
|
|
414
|
def setfile(self, fname, data, mode):
|
|
408
|
def setfile(self, fname, data, mode, copysource):
|
|
415
|
islink, isexec = mode
|
|
409
|
islink, isexec = mode
|
|
416
|
if data is None:
|
|
410
|
if data is None:
|
|
417
|
util.setflags(self._join(fname), islink, isexec)
|
|
411
|
util.setflags(self._join(fname), islink, isexec)
|
|
@@
-439,23
+433,6
b' class fsbackend(abstractbackend):'
|
|
439
|
fp.writelines(lines)
|
|
433
|
fp.writelines(lines)
|
|
440
|
fp.close()
|
|
434
|
fp.close()
|
|
441
|
|
|
435
|
|
|
442
|
def copy(self, src, dst):
|
|
|
|
|
443
|
basedir = self.opener.base
|
|
|
|
|
444
|
abssrc, absdst = [scmutil.canonpath(basedir, basedir, x)
|
|
|
|
|
445
|
for x in [src, dst]]
|
|
|
|
|
446
|
if os.path.lexists(absdst):
|
|
|
|
|
447
|
raise util.Abort(_("cannot create %s: destination already exists")
|
|
|
|
|
448
|
% dst)
|
|
|
|
|
449
|
dstdir = os.path.dirname(absdst)
|
|
|
|
|
450
|
if dstdir and not os.path.isdir(dstdir):
|
|
|
|
|
451
|
try:
|
|
|
|
|
452
|
os.makedirs(dstdir)
|
|
|
|
|
453
|
except IOError:
|
|
|
|
|
454
|
raise util.Abort(
|
|
|
|
|
455
|
_("cannot create %s: unable to create destination directory")
|
|
|
|
|
456
|
% dst)
|
|
|
|
|
457
|
util.copyfile(abssrc, absdst)
|
|
|
|
|
458
|
|
|
|
|
|
459
|
def exists(self, fname):
|
|
436
|
def exists(self, fname):
|
|
460
|
return os.path.lexists(self._join(fname))
|
|
437
|
return os.path.lexists(self._join(fname))
|
|
461
|
|
|
438
|
|
|
@@
-468,8
+445,10
b' class workingbackend(fsbackend):'
|
|
468
|
self.changed = set()
|
|
445
|
self.changed = set()
|
|
469
|
self.copied = []
|
|
446
|
self.copied = []
|
|
470
|
|
|
447
|
|
|
471
|
def setfile(self, fname, data, mode):
|
|
448
|
def setfile(self, fname, data, mode, copysource):
|
|
472
|
super(workingbackend, self).setfile(fname, data, mode)
|
|
449
|
super(workingbackend, self).setfile(fname, data, mode, copysource)
|
|
|
|
|
450
|
if copysource is not None:
|
|
|
|
|
451
|
self.copied.append((copysource, fname))
|
|
473
|
self.changed.add(fname)
|
|
452
|
self.changed.add(fname)
|
|
474
|
|
|
453
|
|
|
475
|
def unlink(self, fname):
|
|
454
|
def unlink(self, fname):
|
|
@@
-477,11
+456,6
b' class workingbackend(fsbackend):'
|
|
477
|
self.removed.add(fname)
|
|
456
|
self.removed.add(fname)
|
|
478
|
self.changed.add(fname)
|
|
457
|
self.changed.add(fname)
|
|
479
|
|
|
458
|
|
|
480
|
def copy(self, src, dst):
|
|
|
|
|
481
|
super(workingbackend, self).copy(src, dst)
|
|
|
|
|
482
|
self.copied.append((src, dst))
|
|
|
|
|
483
|
self.changed.add(dst)
|
|
|
|
|
484
|
|
|
|
|
|
485
|
def close(self):
|
|
459
|
def close(self):
|
|
486
|
wctx = self.repo[None]
|
|
460
|
wctx = self.repo[None]
|
|
487
|
addremoved = set(self.changed)
|
|
461
|
addremoved = set(self.changed)
|
|
@@
-498,14
+472,40
b' class workingbackend(fsbackend):'
|
|
498
|
scmutil.addremove(self.repo, addremoved, similarity=self.similarity)
|
|
472
|
scmutil.addremove(self.repo, addremoved, similarity=self.similarity)
|
|
499
|
return sorted(self.changed)
|
|
473
|
return sorted(self.changed)
|
|
500
|
|
|
474
|
|
|
|
|
|
475
|
class filestore(object):
|
|
|
|
|
476
|
def __init__(self):
|
|
|
|
|
477
|
self.opener = None
|
|
|
|
|
478
|
self.files = {}
|
|
|
|
|
479
|
self.created = 0
|
|
|
|
|
480
|
|
|
|
|
|
481
|
def setfile(self, fname, data, mode):
|
|
|
|
|
482
|
if self.opener is None:
|
|
|
|
|
483
|
root = tempfile.mkdtemp(prefix='hg-patch-')
|
|
|
|
|
484
|
self.opener = scmutil.opener(root)
|
|
|
|
|
485
|
# Avoid filename issues with these simple names
|
|
|
|
|
486
|
fn = str(self.created)
|
|
|
|
|
487
|
self.opener.write(fn, data)
|
|
|
|
|
488
|
self.created += 1
|
|
|
|
|
489
|
self.files[fname] = (fn, mode)
|
|
|
|
|
490
|
|
|
|
|
|
491
|
def getfile(self, fname):
|
|
|
|
|
492
|
if fname not in self.files:
|
|
|
|
|
493
|
raise IOError()
|
|
|
|
|
494
|
fn, mode = self.files[fname]
|
|
|
|
|
495
|
return self.opener.read(fn), mode
|
|
|
|
|
496
|
|
|
|
|
|
497
|
def close(self):
|
|
|
|
|
498
|
if self.opener:
|
|
|
|
|
499
|
shutil.rmtree(self.opener.base)
|
|
|
|
|
500
|
|
|
501
|
# @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
|
|
501
|
# @@ -start,len +start,len @@ or @@ -start +start @@ if len is 1
|
|
502
|
unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
|
|
502
|
unidesc = re.compile('@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@')
|
|
503
|
contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
|
|
503
|
contextdesc = re.compile('(---|\*\*\*) (\d+)(,(\d+))? (---|\*\*\*)')
|
|
504
|
eolmodes = ['strict', 'crlf', 'lf', 'auto']
|
|
504
|
eolmodes = ['strict', 'crlf', 'lf', 'auto']
|
|
505
|
|
|
505
|
|
|
506
|
class patchfile(object):
|
|
506
|
class patchfile(object):
|
|
507
|
def __init__(self, ui, fname, backend, mode, create, remove, missing=False,
|
|
507
|
def __init__(self, ui, fname, backend, store, mode, create, remove,
|
|
508
|
eolmode='strict'):
|
|
508
|
eolmode='strict', copysource=None):
|
|
509
|
self.fname = fname
|
|
509
|
self.fname = fname
|
|
510
|
self.eolmode = eolmode
|
|
510
|
self.eolmode = eolmode
|
|
511
|
self.eol = None
|
|
511
|
self.eol = None
|
|
@@
-513,36
+513,43
b' class patchfile(object):'
|
|
513
|
self.ui = ui
|
|
513
|
self.ui = ui
|
|
514
|
self.lines = []
|
|
514
|
self.lines = []
|
|
515
|
self.exists = False
|
|
515
|
self.exists = False
|
|
516
|
self.missing = missing
|
|
516
|
self.missing = True
|
|
517
|
self.mode = mode
|
|
517
|
self.mode = mode
|
|
|
|
|
518
|
self.copysource = copysource
|
|
518
|
self.create = create
|
|
519
|
self.create = create
|
|
519
|
self.remove = remove
|
|
520
|
self.remove = remove
|
|
520
|
if not missing:
|
|
521
|
try:
|
|
521
|
try:
|
|
522
|
if copysource is None:
|
|
522
|
data, mode = self.backend.getfile(fname)
|
|
523
|
data, mode = backend.getfile(fname)
|
|
523
|
if data:
|
|
|
|
|
524
|
self.lines = data.splitlines(True)
|
|
|
|
|
525
|
if self.mode is None:
|
|
|
|
|
526
|
self.mode = mode
|
|
|
|
|
527
|
if self.lines:
|
|
|
|
|
528
|
# Normalize line endings
|
|
|
|
|
529
|
if self.lines[0].endswith('\r\n'):
|
|
|
|
|
530
|
self.eol = '\r\n'
|
|
|
|
|
531
|
elif self.lines[0].endswith('\n'):
|
|
|
|
|
532
|
self.eol = '\n'
|
|
|
|
|
533
|
if eolmode != 'strict':
|
|
|
|
|
534
|
nlines = []
|
|
|
|
|
535
|
for l in self.lines:
|
|
|
|
|
536
|
if l.endswith('\r\n'):
|
|
|
|
|
537
|
l = l[:-2] + '\n'
|
|
|
|
|
538
|
nlines.append(l)
|
|
|
|
|
539
|
self.lines = nlines
|
|
|
|
|
540
|
self.exists = True
|
|
524
|
self.exists = True
|
|
541
|
except IOError:
|
|
525
|
else:
|
|
542
|
if self.mode is None:
|
|
526
|
data, mode = store.getfile(copysource)
|
|
543
|
self.mode = (False, False)
|
|
527
|
self.exists = backend.exists(fname)
|
|
544
|
else:
|
|
528
|
self.missing = False
|
|
545
|
self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
|
|
529
|
if data:
|
|
|
|
|
530
|
self.lines = data.splitlines(True)
|
|
|
|
|
531
|
if self.mode is None:
|
|
|
|
|
532
|
self.mode = mode
|
|
|
|
|
533
|
if self.lines:
|
|
|
|
|
534
|
# Normalize line endings
|
|
|
|
|
535
|
if self.lines[0].endswith('\r\n'):
|
|
|
|
|
536
|
self.eol = '\r\n'
|
|
|
|
|
537
|
elif self.lines[0].endswith('\n'):
|
|
|
|
|
538
|
self.eol = '\n'
|
|
|
|
|
539
|
if eolmode != 'strict':
|
|
|
|
|
540
|
nlines = []
|
|
|
|
|
541
|
for l in self.lines:
|
|
|
|
|
542
|
if l.endswith('\r\n'):
|
|
|
|
|
543
|
l = l[:-2] + '\n'
|
|
|
|
|
544
|
nlines.append(l)
|
|
|
|
|
545
|
self.lines = nlines
|
|
|
|
|
546
|
except IOError:
|
|
|
|
|
547
|
if create:
|
|
|
|
|
548
|
self.missing = False
|
|
|
|
|
549
|
if self.mode is None:
|
|
|
|
|
550
|
self.mode = (False, False)
|
|
|
|
|
551
|
if self.missing:
|
|
|
|
|
552
|
self.ui.warn(_("unable to find '%s' for patching\n") % self.fname)
|
|
546
|
|
|
553
|
|
|
547
|
self.hash = {}
|
|
554
|
self.hash = {}
|
|
548
|
self.dirty = 0
|
|
555
|
self.dirty = 0
|
|
@@
-569,7
+576,7
b' class patchfile(object):'
|
|
569
|
rawlines.append(l)
|
|
576
|
rawlines.append(l)
|
|
570
|
lines = rawlines
|
|
577
|
lines = rawlines
|
|
571
|
|
|
578
|
|
|
572
|
self.backend.setfile(fname, ''.join(lines), mode)
|
|
579
|
self.backend.setfile(fname, ''.join(lines), mode, self.copysource)
|
|
573
|
|
|
580
|
|
|
574
|
def printfile(self, warn):
|
|
581
|
def printfile(self, warn):
|
|
575
|
if self.fileprinted:
|
|
582
|
if self.fileprinted:
|
|
@@
-623,7
+630,11
b' class patchfile(object):'
|
|
623
|
return -1
|
|
630
|
return -1
|
|
624
|
|
|
631
|
|
|
625
|
if self.exists and self.create:
|
|
632
|
if self.exists and self.create:
|
|
626
|
self.ui.warn(_("file %s already exists\n") % self.fname)
|
|
633
|
if self.copysource:
|
|
|
|
|
634
|
self.ui.warn(_("cannot create %s: destination already "
|
|
|
|
|
635
|
"exists\n" % self.fname))
|
|
|
|
|
636
|
else:
|
|
|
|
|
637
|
self.ui.warn(_("file %s already exists\n") % self.fname)
|
|
627
|
self.rej.append(h)
|
|
638
|
self.rej.append(h)
|
|
628
|
return -1
|
|
639
|
return -1
|
|
629
|
|
|
640
|
|
|
@@
-1005,10
+1016,10
b' def selectfile(backend, afile_orig, bfil'
|
|
1005
|
# Git patches do not play games. Excluding copies from the
|
|
1016
|
# Git patches do not play games. Excluding copies from the
|
|
1006
|
# following heuristic avoids a lot of confusion
|
|
1017
|
# following heuristic avoids a lot of confusion
|
|
1007
|
fname = pathstrip(gp.path, strip - 1)[1]
|
|
1018
|
fname = pathstrip(gp.path, strip - 1)[1]
|
|
1008
|
create = gp.op == 'ADD'
|
|
1019
|
create = gp.op in ('ADD', 'COPY', 'RENAME')
|
|
1009
|
remove = gp.op == 'DELETE'
|
|
1020
|
remove = gp.op == 'DELETE'
|
|
1010
|
missing = not create and not backend.exists(fname)
|
|
1021
|
missing = not create and not backend.exists(fname)
|
|
1011
|
return fname, missing, create, remove
|
|
1022
|
return fname, create, remove
|
|
1012
|
nulla = afile_orig == "/dev/null"
|
|
1023
|
nulla = afile_orig == "/dev/null"
|
|
1013
|
nullb = bfile_orig == "/dev/null"
|
|
1024
|
nullb = bfile_orig == "/dev/null"
|
|
1014
|
create = nulla and hunk.starta == 0 and hunk.lena == 0
|
|
1025
|
create = nulla and hunk.starta == 0 and hunk.lena == 0
|
|
@@
-1050,7
+1061,7
b' def selectfile(backend, afile_orig, bfil'
|
|
1050
|
else:
|
|
1061
|
else:
|
|
1051
|
raise PatchError(_("undefined source and destination files"))
|
|
1062
|
raise PatchError(_("undefined source and destination files"))
|
|
1052
|
|
|
1063
|
|
|
1053
|
return fname, missing, create, remove
|
|
1064
|
return fname, create, remove
|
|
1054
|
|
|
1065
|
|
|
1055
|
def scangitpatch(lr, firstline):
|
|
1066
|
def scangitpatch(lr, firstline):
|
|
1056
|
"""
|
|
1067
|
"""
|
|
@@
-1177,7
+1188,7
b' def iterhunks(fp):'
|
|
1177
|
gp = gitpatches.pop()[1]
|
|
1188
|
gp = gitpatches.pop()[1]
|
|
1178
|
yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp)
|
|
1189
|
yield 'file', ('a/' + gp.path, 'b/' + gp.path, None, gp)
|
|
1179
|
|
|
1190
|
|
|
1180
|
def applydiff(ui, fp, changed, backend, strip=1, eolmode='strict'):
|
|
1191
|
def applydiff(ui, fp, changed, backend, store, strip=1, eolmode='strict'):
|
|
1181
|
"""Reads a patch from fp and tries to apply it.
|
|
1192
|
"""Reads a patch from fp and tries to apply it.
|
|
1182
|
|
|
1193
|
|
|
1183
|
The dict 'changed' is filled in with all of the filenames changed
|
|
1194
|
The dict 'changed' is filled in with all of the filenames changed
|
|
@@
-1188,10
+1199,11
b' def applydiff(ui, fp, changed, backend, '
|
|
1188
|
read in binary mode. Otherwise, line endings are ignored when
|
|
1199
|
read in binary mode. Otherwise, line endings are ignored when
|
|
1189
|
patching then normalized according to 'eolmode'.
|
|
1200
|
patching then normalized according to 'eolmode'.
|
|
1190
|
"""
|
|
1201
|
"""
|
|
1191
|
return _applydiff(ui, fp, patchfile, backend, changed, strip=strip,
|
|
1202
|
return _applydiff(ui, fp, patchfile, backend, store, changed, strip=strip,
|
|
1192
|
eolmode=eolmode)
|
|
1203
|
eolmode=eolmode)
|
|
1193
|
|
|
1204
|
|
|
1194
|
def _applydiff(ui, fp, patcher, backend, changed, strip=1, eolmode='strict'):
|
|
1205
|
def _applydiff(ui, fp, patcher, backend, store, changed, strip=1,
|
|
|
|
|
1206
|
eolmode='strict'):
|
|
1195
|
|
|
1207
|
|
|
1196
|
def pstrip(p):
|
|
1208
|
def pstrip(p):
|
|
1197
|
return pathstrip(p, strip - 1)[1]
|
|
1209
|
return pathstrip(p, strip - 1)[1]
|
|
@@
-1214,30
+1226,42
b' def _applydiff(ui, fp, patcher, backend,'
|
|
1214
|
rejects += current_file.close()
|
|
1226
|
rejects += current_file.close()
|
|
1215
|
current_file = None
|
|
1227
|
current_file = None
|
|
1216
|
afile, bfile, first_hunk, gp = values
|
|
1228
|
afile, bfile, first_hunk, gp = values
|
|
|
|
|
1229
|
copysource = None
|
|
1217
|
if gp:
|
|
1230
|
if gp:
|
|
1218
|
path = pstrip(gp.path)
|
|
1231
|
path = pstrip(gp.path)
|
|
|
|
|
1232
|
if gp.oldpath:
|
|
|
|
|
1233
|
copysource = pstrip(gp.oldpath)
|
|
1219
|
changed[path] = gp
|
|
1234
|
changed[path] = gp
|
|
1220
|
if gp.op == 'DELETE':
|
|
1235
|
if gp.op == 'DELETE':
|
|
1221
|
backend.unlink(path)
|
|
1236
|
backend.unlink(path)
|
|
1222
|
continue
|
|
1237
|
continue
|
|
1223
|
if gp.op == 'RENAME':
|
|
1238
|
if gp.op == 'RENAME':
|
|
1224
|
backend.unlink(pstrip(gp.oldpath))
|
|
1239
|
backend.unlink(copysource)
|
|
1225
|
if gp.mode and not first_hunk:
|
|
1240
|
if not first_hunk:
|
|
1226
|
data = None
|
|
1241
|
data, mode = None, None
|
|
1227
|
if gp.op == 'ADD':
|
|
1242
|
if gp.op in ('RENAME', 'COPY'):
|
|
1228
|
# Added files without content have no hunk and
|
|
1243
|
data, mode = store.getfile(copysource)
|
|
1229
|
# must be created
|
|
1244
|
if gp.mode:
|
|
1230
|
data = ''
|
|
1245
|
mode = gp.mode
|
|
1231
|
backend.setfile(path, data, gp.mode)
|
|
1246
|
if gp.op == 'ADD':
|
|
|
|
|
1247
|
# Added files without content have no hunk and
|
|
|
|
|
1248
|
# must be created
|
|
|
|
|
1249
|
data = ''
|
|
|
|
|
1250
|
if data or mode:
|
|
|
|
|
1251
|
if (gp.op in ('ADD', 'RENAME', 'COPY')
|
|
|
|
|
1252
|
and backend.exists(path)):
|
|
|
|
|
1253
|
raise PatchError(_("cannot create %s: destination "
|
|
|
|
|
1254
|
"already exists") % path)
|
|
|
|
|
1255
|
backend.setfile(path, data, mode, copysource)
|
|
1232
|
if not first_hunk:
|
|
1256
|
if not first_hunk:
|
|
1233
|
continue
|
|
1257
|
continue
|
|
1234
|
try:
|
|
1258
|
try:
|
|
1235
|
mode = gp and gp.mode or None
|
|
1259
|
mode = gp and gp.mode or None
|
|
1236
|
current_file, missing, create, remove = selectfile(
|
|
1260
|
current_file, create, remove = selectfile(
|
|
1237
|
backend, afile, bfile, first_hunk, strip, gp)
|
|
1261
|
backend, afile, bfile, first_hunk, strip, gp)
|
|
1238
|
current_file = patcher(ui, current_file, backend, mode,
|
|
1262
|
current_file = patcher(ui, current_file, backend, store, mode,
|
|
1239
|
create, remove, missing=missing,
|
|
1263
|
create, remove, eolmode=eolmode,
|
|
1240
|
eolmode=eolmode)
|
|
1264
|
copysource=copysource)
|
|
1241
|
except PatchError, inst:
|
|
1265
|
except PatchError, inst:
|
|
1242
|
ui.warn(str(inst) + '\n')
|
|
1266
|
ui.warn(str(inst) + '\n')
|
|
1243
|
current_file = None
|
|
1267
|
current_file = None
|
|
@@
-1245,7
+1269,9
b' def _applydiff(ui, fp, patcher, backend,'
|
|
1245
|
continue
|
|
1269
|
continue
|
|
1246
|
elif state == 'git':
|
|
1270
|
elif state == 'git':
|
|
1247
|
for gp in values:
|
|
1271
|
for gp in values:
|
|
1248
|
backend.copy(pstrip(gp.oldpath), pstrip(gp.path))
|
|
1272
|
path = pstrip(gp.oldpath)
|
|
|
|
|
1273
|
data, mode = backend.getfile(path)
|
|
|
|
|
1274
|
store.setfile(path, data, mode)
|
|
1249
|
else:
|
|
1275
|
else:
|
|
1250
|
raise util.Abort(_('unsupported parser state: %s') % state)
|
|
1276
|
raise util.Abort(_('unsupported parser state: %s') % state)
|
|
1251
|
|
|
1277
|
|
|
@@
-1316,17
+1342,20
b' def internalpatch(ui, repo, patchobj, st'
|
|
1316
|
raise util.Abort(_('unsupported line endings type: %s') % eolmode)
|
|
1342
|
raise util.Abort(_('unsupported line endings type: %s') % eolmode)
|
|
1317
|
eolmode = eolmode.lower()
|
|
1343
|
eolmode = eolmode.lower()
|
|
1318
|
|
|
1344
|
|
|
|
|
|
1345
|
store = filestore()
|
|
1319
|
backend = workingbackend(ui, repo, similarity)
|
|
1346
|
backend = workingbackend(ui, repo, similarity)
|
|
1320
|
try:
|
|
1347
|
try:
|
|
1321
|
fp = open(patchobj, 'rb')
|
|
1348
|
fp = open(patchobj, 'rb')
|
|
1322
|
except TypeError:
|
|
1349
|
except TypeError:
|
|
1323
|
fp = patchobj
|
|
1350
|
fp = patchobj
|
|
1324
|
try:
|
|
1351
|
try:
|
|
1325
|
ret = applydiff(ui, fp, files, backend, strip=strip, eolmode=eolmode)
|
|
1352
|
ret = applydiff(ui, fp, files, backend, store, strip=strip,
|
|
|
|
|
1353
|
eolmode=eolmode)
|
|
1326
|
finally:
|
|
1354
|
finally:
|
|
1327
|
if fp != patchobj:
|
|
1355
|
if fp != patchobj:
|
|
1328
|
fp.close()
|
|
1356
|
fp.close()
|
|
1329
|
files.update(dict.fromkeys(backend.close()))
|
|
1357
|
files.update(dict.fromkeys(backend.close()))
|
|
|
|
|
1358
|
store.close()
|
|
1330
|
if ret < 0:
|
|
1359
|
if ret < 0:
|
|
1331
|
raise PatchError(_('patch failed to apply'))
|
|
1360
|
raise PatchError(_('patch failed to apply'))
|
|
1332
|
return ret > 0
|
|
1361
|
return ret > 0
|
|
@@
-1370,7
+1399,7
b' def changedfiles(ui, repo, patchpath, st'
|
|
1370
|
changed.add(pathstrip(gp.oldpath, strip - 1)[1])
|
|
1399
|
changed.add(pathstrip(gp.oldpath, strip - 1)[1])
|
|
1371
|
if not first_hunk:
|
|
1400
|
if not first_hunk:
|
|
1372
|
continue
|
|
1401
|
continue
|
|
1373
|
current_file, missing, create, remove = selectfile(
|
|
1402
|
current_file, create, remove = selectfile(
|
|
1374
|
backend, afile, bfile, first_hunk, strip, gp)
|
|
1403
|
backend, afile, bfile, first_hunk, strip, gp)
|
|
1375
|
changed.add(current_file)
|
|
1404
|
changed.add(current_file)
|
|
1376
|
elif state not in ('hunk', 'git'):
|
|
1405
|
elif state not in ('hunk', 'git'):
|