##// 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 for line in file(pf):
253 for line in file(pf):
254 line = line.rstrip()
254 line = line.rstrip()
255 if line.startswith('diff --git'):
256 diffstart = 2
257 break
255 if diffstart:
258 if diffstart:
256 if line.startswith('+++ '):
259 if line.startswith('+++ '):
257 diffstart = 2
260 diffstart = 2
@@ -408,7 +411,7 b' class queue:'
408 self.ui.warn("patch failed, unable to continue (try -v)\n")
411 self.ui.warn("patch failed, unable to continue (try -v)\n")
409 return (False, [], False)
412 return (False, [], False)
410
413
411 return (True, files.keys(), fuzz)
414 return (True, files, fuzz)
412
415
413 def apply(self, repo, series, list=False, update_status=True,
416 def apply(self, repo, series, list=False, update_status=True,
414 strict=False, patchdir=None, merge=None, wlock=None):
417 strict=False, patchdir=None, merge=None, wlock=None):
@@ -421,42 +424,37 b' class queue:'
421 lock = repo.lock()
424 lock = repo.lock()
422 tr = repo.transaction()
425 tr = repo.transaction()
423 n = None
426 n = None
424 for patch in series:
427 for patchname in series:
425 pushable, reason = self.pushable(patch)
428 pushable, reason = self.pushable(patchname)
426 if not pushable:
429 if not pushable:
427 self.explain_pushable(patch, all_patches=True)
430 self.explain_pushable(patchname, all_patches=True)
428 continue
431 continue
429 self.ui.warn("applying %s\n" % patch)
432 self.ui.warn("applying %s\n" % patchname)
430 pf = os.path.join(patchdir, patch)
433 pf = os.path.join(patchdir, patchname)
431
434
432 try:
435 try:
433 message, comments, user, date, patchfound = self.readheaders(patch)
436 message, comments, user, date, patchfound = self.readheaders(patchname)
434 except:
437 except:
435 self.ui.warn("Unable to read %s\n" % pf)
438 self.ui.warn("Unable to read %s\n" % patchname)
436 err = 1
439 err = 1
437 break
440 break
438
441
439 if not message:
442 if not message:
440 message = "imported patch %s\n" % patch
443 message = "imported patch %s\n" % patchname
441 else:
444 else:
442 if list:
445 if list:
443 message.append("\nimported patch %s" % patch)
446 message.append("\nimported patch %s" % patchname)
444 message = '\n'.join(message)
447 message = '\n'.join(message)
445
448
446 (patcherr, files, fuzz) = self.patch(repo, pf)
449 (patcherr, files, fuzz) = self.patch(repo, pf)
447 patcherr = not patcherr
450 patcherr = not patcherr
448
451
449 if merge and len(files) > 0:
452 if merge and files:
450 # Mark as merged and update dirstate parent info
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 p1, p2 = repo.dirstate.parents()
455 p1, p2 = repo.dirstate.parents()
453 repo.dirstate.setparents(p1, merge)
456 repo.dirstate.setparents(p1, merge)
454 if len(files) > 0:
457 files = patch.updatedir(self.ui, repo, files, wlock=wlock)
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)
460 n = repo.commit(files, message, user, date, force=1, lock=lock,
458 n = repo.commit(files, message, user, date, force=1, lock=lock,
461 wlock=wlock)
459 wlock=wlock)
462
460
@@ -464,11 +462,11 b' class queue:'
464 raise util.Abort(_("repo commit failed"))
462 raise util.Abort(_("repo commit failed"))
465
463
466 if update_status:
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 if patcherr:
467 if patcherr:
470 if not patchfound:
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 err = 0
470 err = 0
473 else:
471 else:
474 self.ui.warn("patch failed, rejects left in working dir\n")
472 self.ui.warn("patch failed, rejects left in working dir\n")
@@ -999,7 +997,10 b' class queue:'
999
997
1000 changes = repo.changelog.read(tip)
998 changes = repo.changelog.read(tip)
1001 repo.dirstate.setparents(*cparents)
999 repo.dirstate.setparents(*cparents)
1000 copies = [(f, repo.dirstate.copied(f)) for f in a]
1002 repo.dirstate.update(a, 'a')
1001 repo.dirstate.update(a, 'a')
1002 for dst, src in copies:
1003 repo.dirstate.copy(src, dst)
1003 repo.dirstate.update(r, 'r')
1004 repo.dirstate.update(r, 'r')
1004 repo.dirstate.update(m, 'n')
1005 repo.dirstate.update(m, 'n')
1005 repo.dirstate.forget(forget)
1006 repo.dirstate.forget(forget)
@@ -343,10 +343,27 b' def diff(repo, node1=None, node2=None, f'
343
343
344 if not node1:
344 if not node1:
345 node1 = repo.dirstate.parents()[0]
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 # reading the data for node1 early allows it to play nicely
363 # reading the data for node1 early allows it to play nicely
347 # with repo.status and the revlog cache.
364 # with repo.status and the revlog cache.
348 change = repo.changelog.read(node1)
365 change = getchangelog(node1)
349 mmap = repo.manifest.read(change[0])
366 mmap = getmanifest(change[0])
350 date1 = util.datestr(change[2])
367 date1 = util.datestr(change[2])
351
368
352 if not changes:
369 if not changes:
@@ -367,17 +384,32 b' def diff(repo, node1=None, node2=None, f'
367 if not modified and not added and not removed:
384 if not modified and not added and not removed:
368 return
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 if node2:
403 if node2:
371 change = repo.changelog.read(node2)
404 change = getchangelog(node2)
372 mmap2 = repo.manifest.read(change[0])
405 mmap2 = getmanifest(change[0])
373 _date2 = util.datestr(change[2])
406 _date2 = util.datestr(change[2])
374 def date2(f):
407 def date2(f):
375 return _date2
408 return _date2
376 def read(f):
409 def read(f):
377 return repo.file(f).read(mmap2[f])
410 return getfile(f).read(mmap2[f])
378 def renamed(f):
411 def renamed(f):
379 src = repo.file(f).renamed(mmap2[f])
412 return renamedbetween(f, node1, node2)
380 return src and src[0] or None
381 else:
413 else:
382 tz = util.makedate()[1]
414 tz = util.makedate()[1]
383 _date2 = util.datestr()
415 _date2 = util.datestr()
@@ -390,7 +422,18 b' def diff(repo, node1=None, node2=None, f'
390 def read(f):
422 def read(f):
391 return repo.wread(f)
423 return repo.wread(f)
392 def renamed(f):
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 if repo.ui.quiet:
438 if repo.ui.quiet:
396 r = None
439 r = None
@@ -404,7 +447,7 b' def diff(repo, node1=None, node2=None, f'
404 src = renamed(f)
447 src = renamed(f)
405 if src:
448 if src:
406 copied[f] = src
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 all = modified + added + removed
452 all = modified + added + removed
410 all.sort()
453 all.sort()
@@ -413,7 +456,7 b' def diff(repo, node1=None, node2=None, f'
413 tn = None
456 tn = None
414 dodiff = True
457 dodiff = True
415 if f in mmap:
458 if f in mmap:
416 to = repo.file(f).read(mmap[f])
459 to = getfile(f).read(mmap[f])
417 if f not in removed:
460 if f not in removed:
418 tn = read(f)
461 tn = read(f)
419 if opts.git:
462 if opts.git:
@@ -432,13 +475,13 b' def diff(repo, node1=None, node2=None, f'
432 else:
475 else:
433 mode = gitmode(util.is_exec(repo.wjoin(f), None))
476 mode = gitmode(util.is_exec(repo.wjoin(f), None))
434 if f in copied:
477 if f in copied:
435 a = copied[f]
478 a, arev = copied[f]
436 omode = gitmode(mmap.execf(a))
479 omode = gitmode(mmap.execf(a))
437 addmodehdr(header, omode, mode)
480 addmodehdr(header, omode, mode)
438 op = a in removed and 'rename' or 'copy'
481 op = a in removed and 'rename' or 'copy'
439 header.append('%s from %s\n' % (op, a))
482 header.append('%s from %s\n' % (op, a))
440 header.append('%s to %s\n' % (op, f))
483 header.append('%s to %s\n' % (op, f))
441 to = repo.file(a).read(mmap[a])
484 to = getfile(a).read(arev)
442 else:
485 else:
443 header.append('new file mode %s\n' % mode)
486 header.append('new file mode %s\n' % mode)
444 elif f in removed:
487 elif f in removed:
@@ -126,3 +126,28 b' echo x>x'
126 hg ci -Ama
126 hg ci -Ama
127 hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/'
127 hg strip tip 2>&1 | sed 's/\(saving bundle to \).*/\1/'
128 hg unbundle .hg/strip-backup/*
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 adding file changes
127 adding file changes
128 added 1 changesets with 1 changes to 1 files
128 added 1 changesets with 1 changes to 1 files
129 (run 'hg update' to get a working copy)
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