##// END OF EJS Templates
Teach mq about git patches
Brendan Cully -
r2934:2f190e99 default
parent child Browse files
Show More
@@ -252,6 +252,9 b' class queue:'
252 252
253 253 for line in file(pf):
254 254 line = line.rstrip()
255 if line.startswith('diff --git'):
256 diffstart = 2
257 break
255 258 if diffstart:
256 259 if line.startswith('+++ '):
257 260 diffstart = 2
@@ -408,7 +411,7 b' class queue:'
408 411 self.ui.warn("patch failed, unable to continue (try -v)\n")
409 412 return (False, [], False)
410 413
411 return (True, files.keys(), fuzz)
414 return (True, files, fuzz)
412 415
413 416 def apply(self, repo, series, list=False, update_status=True,
414 417 strict=False, patchdir=None, merge=None, wlock=None):
@@ -421,42 +424,37 b' class queue:'
421 424 lock = repo.lock()
422 425 tr = repo.transaction()
423 426 n = None
424 for patch in series:
425 pushable, reason = self.pushable(patch)
427 for patchname in series:
428 pushable, reason = self.pushable(patchname)
426 429 if not pushable:
427 self.explain_pushable(patch, all_patches=True)
430 self.explain_pushable(patchname, all_patches=True)
428 431 continue
429 self.ui.warn("applying %s\n" % patch)
430 pf = os.path.join(patchdir, patch)
432 self.ui.warn("applying %s\n" % patchname)
433 pf = os.path.join(patchdir, patchname)
431 434
432 435 try:
433 message, comments, user, date, patchfound = self.readheaders(patch)
436 message, comments, user, date, patchfound = self.readheaders(patchname)
434 437 except:
435 self.ui.warn("Unable to read %s\n" % pf)
438 self.ui.warn("Unable to read %s\n" % patchname)
436 439 err = 1
437 440 break
438 441
439 442 if not message:
440 message = "imported patch %s\n" % patch
443 message = "imported patch %s\n" % patchname
441 444 else:
442 445 if list:
443 message.append("\nimported patch %s" % patch)
446 message.append("\nimported patch %s" % patchname)
444 447 message = '\n'.join(message)
445 448
446 449 (patcherr, files, fuzz) = self.patch(repo, pf)
447 450 patcherr = not patcherr
448 451
449 if merge and len(files) > 0:
452 if merge and files:
450 453 # Mark as merged and update dirstate parent info
451 repo.dirstate.update(repo.dirstate.filterfiles(files), 'm')
454 repo.dirstate.update(repo.dirstate.filterfiles(files.keys()), 'm')
452 455 p1, p2 = repo.dirstate.parents()
453 456 repo.dirstate.setparents(p1, merge)
454 if len(files) > 0:
455 cwd = repo.getcwd()
456 cfiles = files
457 if cwd:
458 cfiles = [util.pathto(cwd, f) for f in files]
459 cmdutil.addremove(repo, cfiles, wlock=wlock)
457 files = patch.updatedir(self.ui, repo, files, wlock=wlock)
460 458 n = repo.commit(files, message, user, date, force=1, lock=lock,
461 459 wlock=wlock)
462 460
@@ -464,11 +462,11 b' class queue:'
464 462 raise util.Abort(_("repo commit failed"))
465 463
466 464 if update_status:
467 self.applied.append(statusentry(revlog.hex(n), patch))
465 self.applied.append(statusentry(revlog.hex(n), patchname))
468 466
469 467 if patcherr:
470 468 if not patchfound:
471 self.ui.warn("patch %s is empty\n" % patch)
469 self.ui.warn("patch %s is empty\n" % patchname)
472 470 err = 0
473 471 else:
474 472 self.ui.warn("patch failed, rejects left in working dir\n")
@@ -999,7 +997,10 b' class queue:'
999 997
1000 998 changes = repo.changelog.read(tip)
1001 999 repo.dirstate.setparents(*cparents)
1000 copies = [(f, repo.dirstate.copied(f)) for f in a]
1002 1001 repo.dirstate.update(a, 'a')
1002 for dst, src in copies:
1003 repo.dirstate.copy(src, dst)
1003 1004 repo.dirstate.update(r, 'r')
1004 1005 repo.dirstate.update(m, 'n')
1005 1006 repo.dirstate.forget(forget)
@@ -343,10 +343,27 b' def diff(repo, node1=None, node2=None, f'
343 343
344 344 if not node1:
345 345 node1 = repo.dirstate.parents()[0]
346
347 clcache = {}
348 def getchangelog(n):
349 if n not in clcache:
350 clcache[n] = repo.changelog.read(n)
351 return clcache[n]
352 mcache = {}
353 def getmanifest(n):
354 if n not in mcache:
355 mcache[n] = repo.manifest.read(n)
356 return mcache[n]
357 fcache = {}
358 def getfile(f):
359 if f not in fcache:
360 fcache[f] = repo.file(f)
361 return fcache[f]
362
346 363 # reading the data for node1 early allows it to play nicely
347 364 # with repo.status and the revlog cache.
348 change = repo.changelog.read(node1)
349 mmap = repo.manifest.read(change[0])
365 change = getchangelog(node1)
366 mmap = getmanifest(change[0])
350 367 date1 = util.datestr(change[2])
351 368
352 369 if not changes:
@@ -367,17 +384,32 b' def diff(repo, node1=None, node2=None, f'
367 384 if not modified and not added and not removed:
368 385 return
369 386
387 def renamedbetween(f, n1, n2):
388 r1, r2 = map(repo.changelog.rev, (n1, n2))
389 src = None
390 while r2 > r1:
391 cl = getchangelog(n2)[0]
392 m = getmanifest(cl)
393 try:
394 src = getfile(f).renamed(m[f])
395 except KeyError:
396 return None
397 if src:
398 f = src[0]
399 n2 = repo.changelog.parents(n2)[0]
400 r2 = repo.changelog.rev(n2)
401 return src
402
370 403 if node2:
371 change = repo.changelog.read(node2)
372 mmap2 = repo.manifest.read(change[0])
404 change = getchangelog(node2)
405 mmap2 = getmanifest(change[0])
373 406 _date2 = util.datestr(change[2])
374 407 def date2(f):
375 408 return _date2
376 409 def read(f):
377 return repo.file(f).read(mmap2[f])
410 return getfile(f).read(mmap2[f])
378 411 def renamed(f):
379 src = repo.file(f).renamed(mmap2[f])
380 return src and src[0] or None
412 return renamedbetween(f, node1, node2)
381 413 else:
382 414 tz = util.makedate()[1]
383 415 _date2 = util.datestr()
@@ -390,7 +422,18 b' def diff(repo, node1=None, node2=None, f'
390 422 def read(f):
391 423 return repo.wread(f)
392 424 def renamed(f):
393 return repo.dirstate.copies.get(f)
425 src = repo.dirstate.copies.get(f)
426 parent = repo.dirstate.parents()[0]
427 if src:
428 f = src[0]
429 of = renamedbetween(f, node1, parent)
430 if of:
431 return of
432 elif src:
433 cl = getchangelog(parent)[0]
434 return (src, getmanifest(cl)[src])
435 else:
436 return None
394 437
395 438 if repo.ui.quiet:
396 439 r = None
@@ -404,7 +447,7 b' def diff(repo, node1=None, node2=None, f'
404 447 src = renamed(f)
405 448 if src:
406 449 copied[f] = src
407 srcs = [x[1] for x in copied.items()]
450 srcs = [x[1][0] for x in copied.items()]
408 451
409 452 all = modified + added + removed
410 453 all.sort()
@@ -413,7 +456,7 b' def diff(repo, node1=None, node2=None, f'
413 456 tn = None
414 457 dodiff = True
415 458 if f in mmap:
416 to = repo.file(f).read(mmap[f])
459 to = getfile(f).read(mmap[f])
417 460 if f not in removed:
418 461 tn = read(f)
419 462 if opts.git:
@@ -432,13 +475,13 b' def diff(repo, node1=None, node2=None, f'
432 475 else:
433 476 mode = gitmode(util.is_exec(repo.wjoin(f), None))
434 477 if f in copied:
435 a = copied[f]
478 a, arev = copied[f]
436 479 omode = gitmode(mmap.execf(a))
437 480 addmodehdr(header, omode, mode)
438 481 op = a in removed and 'rename' or 'copy'
439 482 header.append('%s from %s\n' % (op, a))
440 483 header.append('%s to %s\n' % (op, f))
441 to = repo.file(a).read(mmap[a])
484 to = getfile(a).read(arev)
442 485 else:
443 486 header.append('new file mode %s\n' % mode)
444 487 elif f in removed:
@@ -126,3 +126,28 b' echo x>x'
126 126 hg ci -Ama
127 127 hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/'
128 128 hg unbundle .hg/strip-backup/*
129
130 cat >>$HGTMP/.hgrc <<EOF
131 [diff]
132 git = True
133 EOF
134 cd ..
135 hg init git
136 cd git
137 hg qinit
138
139 hg qnew -m'new file' new
140 echo foo > new
141 chmod +x new
142 hg add new
143 hg qrefresh
144 sed -e "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/new
145
146 hg qnew -m'copy file' copy
147 hg cp new copy
148 hg qrefresh
149 sed -e "s/\(\(---\|+++\) [a-zA-Z0-9_/.-]*\).*/\1/" .hg/patches/copy
150
151 hg qpop
152 hg qpush
153 hg qdiff
@@ -127,3 +127,22 b' adding manifests'
127 127 adding file changes
128 128 added 1 changesets with 1 changes to 1 files
129 129 (run 'hg update' to get a working copy)
130 new file
131
132 diff --git a/new b/new
133 new file mode 100755
134 --- /dev/null
135 +++ b/new
136 @@ -0,0 +1,1 @@
137 +foo
138 copy file
139
140 diff --git a/new b/copy
141 copy from new
142 copy to copy
143 Now at: new
144 applying copy
145 Now at: copy
146 diff --git a/new b/copy
147 copy from new
148 copy to copy
General Comments 0
You need to be logged in to leave comments. Login now