changeset 1810 | 7596611ab3d5 |
parent 1808 | 7036cd7f770d |
child 1839 | 876e4e6ad82b |
1809:ef53d200df3d | 1810:7596611ab3d5 |
---|---|
28 self.full_series = [] |
28 self.full_series = [] |
29 self.applied_dirty = 0 |
29 self.applied_dirty = 0 |
30 self.series_dirty = 0 |
30 self.series_dirty = 0 |
31 self.series_path = os.path.join(self.path, "series") |
31 self.series_path = os.path.join(self.path, "series") |
32 self.status_path = os.path.join(self.path, "status") |
32 self.status_path = os.path.join(self.path, "status") |
33 |
33 |
34 s = self.series_path |
34 s = self.series_path |
35 if os.path.exists(s): |
35 if os.path.exists(s): |
36 self.full_series = self.opener(s).read().splitlines() |
36 self.full_series = self.opener(s).read().splitlines() |
37 self.read_series(self.full_series) |
37 self.read_series(self.full_series) |
38 |
38 |
63 s = s.rstrip() |
63 s = s.rstrip() |
64 if len(s) > 0: |
64 if len(s) > 0: |
65 yield s |
65 yield s |
66 self.series = [] |
66 self.series = [] |
67 self.series = [ x for x in matcher(list) ] |
67 self.series = [ x for x in matcher(list) ] |
68 |
68 |
69 def save_dirty(self): |
69 def save_dirty(self): |
70 if self.applied_dirty: |
70 if self.applied_dirty: |
71 if len(self.applied) > 0: |
71 if len(self.applied) > 0: |
72 nl = "\n" |
72 nl = "\n" |
73 else: |
73 else: |
84 |
84 |
85 def readheaders(self, patch): |
85 def readheaders(self, patch): |
86 def eatdiff(lines): |
86 def eatdiff(lines): |
87 while lines: |
87 while lines: |
88 l = lines[-1] |
88 l = lines[-1] |
89 if l.startswith("diff -") or \ |
89 if (l.startswith("diff -") or |
90 l.startswith("Index:") or \ |
90 l.startswith("Index:") or |
91 l.startswith("==========="): |
91 l.startswith("===========")): |
92 del lines[-1] |
92 del lines[-1] |
93 else: |
93 else: |
94 break |
94 break |
95 def eatempty(lines): |
95 def eatempty(lines): |
96 while lines: |
96 while lines: |
124 elif not line.startswith("# ") and line: |
124 elif not line.startswith("# ") and line: |
125 message.append(line) |
125 message.append(line) |
126 format = None |
126 format = None |
127 elif line == '# HG changeset patch': |
127 elif line == '# HG changeset patch': |
128 format = "hgpatch" |
128 format = "hgpatch" |
129 elif format != "tagdone" and \ |
129 elif (format != "tagdone" and (line.startswith("Subject: ") or |
130 (line.startswith("Subject: ") or \ |
130 line.startswith("subject: "))): |
131 line.startswith("subject: ")): |
|
132 subject = line[9:] |
131 subject = line[9:] |
133 format = "tag" |
132 format = "tag" |
134 elif format != "tagdone" and \ |
133 elif (format != "tagdone" and (line.startswith("From: ") or |
135 (line.startswith("From: ") or \ |
134 line.startswith("from: "))): |
136 line.startswith("from: ")): |
|
137 user = line[6:] |
135 user = line[6:] |
138 format = "tag" |
136 format = "tag" |
139 elif format == "tag" and line == "": |
137 elif format == "tag" and line == "": |
140 # when looking for tags (subject: from: etc) they |
138 # when looking for tags (subject: from: etc) they |
141 # end once you find a blank line in the source |
139 # end once you find a blank line in the source |
155 message.insert(0, subject) |
153 message.insert(0, subject) |
156 return (message, comments, user, diffstart > 1) |
154 return (message, comments, user, diffstart > 1) |
157 |
155 |
158 def mergeone(self, repo, mergeq, head, patch, rev, wlock): |
156 def mergeone(self, repo, mergeq, head, patch, rev, wlock): |
159 # first try just applying the patch |
157 # first try just applying the patch |
160 (err, n) = self.apply(repo, [ patch ], update_status=False, |
158 (err, n) = self.apply(repo, [ patch ], update_status=False, |
161 strict=True, merge=rev, wlock=wlock) |
159 strict=True, merge=rev, wlock=wlock) |
162 |
160 |
163 if err == 0: |
161 if err == 0: |
164 return (err, n) |
162 return (err, n) |
165 |
163 |
193 comments = "\n".join(comments) + '\n\n' |
191 comments = "\n".join(comments) + '\n\n' |
194 patchf.write(comments) |
192 patchf.write(comments) |
195 commands.dodiff(patchf, self.ui, repo, head, n) |
193 commands.dodiff(patchf, self.ui, repo, head, n) |
196 patchf.close() |
194 patchf.close() |
197 return (0, n) |
195 return (0, n) |
198 |
196 |
199 def qparents(self, repo, rev=None): |
197 def qparents(self, repo, rev=None): |
200 if rev is None: |
198 if rev is None: |
201 (p1, p2) = repo.dirstate.parents() |
199 (p1, p2) = repo.dirstate.parents() |
202 if p2 == revlog.nullid: |
200 if p2 == revlog.nullid: |
203 return p1 |
201 return p1 |
251 self.applied_dirty = 1 |
249 self.applied_dirty = 1 |
252 if err: |
250 if err: |
253 return (err, head) |
251 return (err, head) |
254 return (0, head) |
252 return (0, head) |
255 |
253 |
256 def apply(self, repo, series, list=False, update_status=True, |
254 def apply(self, repo, series, list=False, update_status=True, |
257 strict=False, patchdir=None, merge=None, wlock=None): |
255 strict=False, patchdir=None, merge=None, wlock=None): |
258 # TODO unify with commands.py |
256 # TODO unify with commands.py |
259 if not patchdir: |
257 if not patchdir: |
260 patchdir = self.path |
258 patchdir = self.path |
261 pwd = os.getcwd() |
259 pwd = os.getcwd() |
283 if list: |
281 if list: |
284 message.append("\nimported patch %s" % patch) |
282 message.append("\nimported patch %s" % patch) |
285 message = '\n'.join(message) |
283 message = '\n'.join(message) |
286 |
284 |
287 try: |
285 try: |
288 f = os.popen("patch -p1 --no-backup-if-mismatch < '%s'" % |
286 f = os.popen("patch -p1 --no-backup-if-mismatch < '%s'" % (pf)) |
289 (pf)) |
|
290 except: |
287 except: |
291 self.ui.warn("patch failed, unable to continue (try -v)\n") |
288 self.ui.warn("patch failed, unable to continue (try -v)\n") |
292 err = 1 |
289 err = 1 |
293 break |
290 break |
294 files = [] |
291 files = [] |
297 l = l.rstrip('\r\n'); |
294 l = l.rstrip('\r\n'); |
298 if self.ui.verbose: |
295 if self.ui.verbose: |
299 self.ui.warn(l + "\n") |
296 self.ui.warn(l + "\n") |
300 if l[:14] == 'patching file ': |
297 if l[:14] == 'patching file ': |
301 pf = os.path.normpath(l[14:]) |
298 pf = os.path.normpath(l[14:]) |
302 # when patch finds a space in the file name, it puts |
299 # when patch finds a space in the file name, it puts |
303 # single quotes around the filename. strip them off |
300 # single quotes around the filename. strip them off |
304 if pf[0] == "'" and pf[-1] == "'": |
301 if pf[0] == "'" and pf[-1] == "'": |
305 pf = pf[1:-1] |
302 pf = pf[1:-1] |
306 if pf not in files: |
303 if pf not in files: |
307 files.append(pf) |
304 files.append(pf) |
321 printed_file = True |
318 printed_file = True |
322 self.ui.warn(l + '\n') |
319 self.ui.warn(l + '\n') |
323 patcherr = f.close() |
320 patcherr = f.close() |
324 |
321 |
325 if merge and len(files) > 0: |
322 if merge and len(files) > 0: |
326 # Mark as merged and update dirstate parent info |
323 # Mark as merged and update dirstate parent info |
327 repo.dirstate.update(repo.dirstate.filterfiles(files), 'm') |
324 repo.dirstate.update(repo.dirstate.filterfiles(files), 'm') |
328 p1, p2 = repo.dirstate.parents() |
325 p1, p2 = repo.dirstate.parents() |
329 repo.dirstate.setparents(p1, merge) |
326 repo.dirstate.setparents(p1, merge) |
330 if len(files) > 0: |
327 if len(files) > 0: |
331 commands.addremove_lock(self.ui, repo, files, |
328 commands.addremove_lock(self.ui, repo, files, |
332 opts={}, wlock=wlock) |
329 opts={}, wlock=wlock) |
333 n = repo.commit(files, message, user, force=1, lock=lock, |
330 n = repo.commit(files, message, user, force=1, lock=lock, |
334 wlock=wlock) |
331 wlock=wlock) |
335 |
332 |
336 if n == None: |
333 if n == None: |
368 sys.exit(1) |
365 sys.exit(1) |
369 i = self.find_series(patch) |
366 i = self.find_series(patch) |
370 del self.full_series[i] |
367 del self.full_series[i] |
371 self.read_series(self.full_series) |
368 self.read_series(self.full_series) |
372 self.series_dirty = 1 |
369 self.series_dirty = 1 |
373 |
370 |
374 def check_toppatch(self, repo): |
371 def check_toppatch(self, repo): |
375 if len(self.applied) > 0: |
372 if len(self.applied) > 0: |
376 (top, patch) = self.applied[-1].split(':') |
373 (top, patch) = self.applied[-1].split(':') |
377 top = revlog.bin(top) |
374 top = revlog.bin(top) |
378 pp = repo.dirstate.parents() |
375 pp = repo.dirstate.parents() |
391 self.check_localchanges(repo) |
388 self.check_localchanges(repo) |
392 self.check_toppatch(repo) |
389 self.check_toppatch(repo) |
393 wlock = repo.wlock() |
390 wlock = repo.wlock() |
394 insert = self.series_end() |
391 insert = self.series_end() |
395 if msg: |
392 if msg: |
396 n = repo.commit([], "[mq]: %s" % msg, force=True, wlock=wlock) |
393 n = repo.commit([], "[mq]: %s" % msg, force=True, wlock=wlock) |
397 else: |
394 else: |
398 n = repo.commit([], "New patch: %s" % patch, force=True, wlock=wlock) |
395 n = repo.commit([], |
396 "New patch: %s" % patch, force=True, wlock=wlock) |
|
399 if n == None: |
397 if n == None: |
400 self.ui.warn("repo commit failed\n") |
398 self.ui.warn("repo commit failed\n") |
401 sys.exit(1) |
399 sys.exit(1) |
402 self.full_series[insert:insert] = [patch] |
400 self.full_series[insert:insert] = [patch] |
403 self.applied.append(revlog.hex(n) + ":" + patch) |
401 self.applied.append(revlog.hex(n) + ":" + patch) |
536 if rev not in r: |
534 if rev not in r: |
537 saveheads.append(h) |
535 saveheads.append(h) |
538 for x in r: |
536 for x in r: |
539 if chlog.rev(x) > revnum: |
537 if chlog.rev(x) > revnum: |
540 savebases[x] = 1 |
538 savebases[x] = 1 |
541 |
539 |
542 # create a changegroup for all the branches we need to keep |
540 # create a changegroup for all the branches we need to keep |
543 if backup is "all": |
541 if backup is "all": |
544 backupch = repo.changegroupsubset([rev], chlog.heads(), 'strip') |
542 backupch = repo.changegroupsubset([rev], chlog.heads(), 'strip') |
545 bundle(backupch) |
543 bundle(backupch) |
546 if saveheads: |
544 if saveheads: |
555 if saveheads: |
553 if saveheads: |
556 self.ui.status("adding branch\n") |
554 self.ui.status("adding branch\n") |
557 commands.unbundle(self.ui, repo, chgrpfile, update=False) |
555 commands.unbundle(self.ui, repo, chgrpfile, update=False) |
558 if backup is not "strip": |
556 if backup is not "strip": |
559 os.unlink(chgrpfile) |
557 os.unlink(chgrpfile) |
560 |
558 |
561 def isapplied(self, patch): |
559 def isapplied(self, patch): |
562 """returns (index, rev, patch)""" |
560 """returns (index, rev, patch)""" |
563 for i in xrange(len(self.applied)): |
561 for i in xrange(len(self.applied)): |
564 p = self.applied[i] |
562 p = self.applied[i] |
565 a = p.split(':') |
563 a = p.split(':') |
585 else: |
583 else: |
586 self.ui.warn("patch %s not in series\n" % patch) |
584 self.ui.warn("patch %s not in series\n" % patch) |
587 sys.exit(1) |
585 sys.exit(1) |
588 return patch |
586 return patch |
589 |
587 |
590 def push(self, repo, patch=None, force=False, list=False, |
588 def push(self, repo, patch=None, force=False, list=False, |
591 mergeq=None, wlock=None): |
589 mergeq=None, wlock=None): |
592 if not wlock: |
590 if not wlock: |
593 wlock = repo.wlock() |
591 wlock = repo.wlock() |
594 patch = self.lookup(patch) |
592 patch = self.lookup(patch) |
595 if patch and self.isapplied(patch): |
593 if patch and self.isapplied(patch): |
596 self.ui.warn("patch %s is already applied\n" % patch) |
594 self.ui.warn("patch %s is already applied\n" % patch) |
597 sys.exit(1) |
595 sys.exit(1) |
598 if self.series_end() == len(self.series): |
596 if self.series_end() == len(self.series): |
599 self.ui.warn("File series fully applied\n") |
597 self.ui.warn("File series fully applied\n") |
600 sys.exit(1) |
598 sys.exit(1) |
601 if not force: |
599 if not force: |
602 self.check_localchanges(repo) |
600 self.check_localchanges(repo) |
603 |
601 |
604 self.applied_dirty = 1; |
602 self.applied_dirty = 1; |
605 start = self.series_end() |
603 start = self.series_end() |
606 if start > 0: |
604 if start > 0: |
607 self.check_toppatch(repo) |
605 self.check_toppatch(repo) |
608 if not patch: |
606 if not patch: |
615 ret = self.mergepatch(repo, mergeq, s, wlock) |
613 ret = self.mergepatch(repo, mergeq, s, wlock) |
616 else: |
614 else: |
617 ret = self.apply(repo, s, list, wlock=wlock) |
615 ret = self.apply(repo, s, list, wlock=wlock) |
618 top = self.applied[-1].split(':')[1] |
616 top = self.applied[-1].split(':')[1] |
619 if ret[0]: |
617 if ret[0]: |
620 self.ui.write("Errors during apply, please fix and refresh %s\n" % |
618 self.ui.write("Errors during apply, please fix and refresh %s\n" % |
621 top) |
619 top) |
622 else: |
620 else: |
623 self.ui.write("Now at: %s\n" % top) |
621 self.ui.write("Now at: %s\n" % top) |
624 return ret[0] |
622 return ret[0] |
625 |
623 |
723 comments = "\n".join(comments) + '\n\n' |
721 comments = "\n".join(comments) + '\n\n' |
724 patchf.write(comments) |
722 patchf.write(comments) |
725 |
723 |
726 tip = repo.changelog.tip() |
724 tip = repo.changelog.tip() |
727 if top == tip: |
725 if top == tip: |
728 # if the top of our patch queue is also the tip, there is an |
726 # if the top of our patch queue is also the tip, there is an |
729 # optimization here. We update the dirstate in place and strip |
727 # optimization here. We update the dirstate in place and strip |
730 # off the tip commit. Then just commit the current directory |
728 # off the tip commit. Then just commit the current directory |
731 # tree. We can also send repo.commit the list of files |
729 # tree. We can also send repo.commit the list of files |
732 # changed to speed up the diff |
730 # changed to speed up the diff |
733 # |
731 # |
734 # in short mode, we only diff the files included in the |
732 # in short mode, we only diff the files included in the |
735 # patch already |
733 # patch already |
736 # |
734 # |
737 # this should really read: |
735 # this should really read: |
738 #(cc, dd, aa, aa2, uu) = repo.changes(tip, patchparent) |
736 #(cc, dd, aa, aa2, uu) = repo.changes(tip, patchparent) |
739 # but we do it backwards to take advantage of manifest/chlog |
737 # but we do it backwards to take advantage of manifest/chlog |
740 # caching against the next repo.changes call |
738 # caching against the next repo.changes call |
741 # |
739 # |
742 (cc, aa, dd, aa2, uu) = repo.changes(patchparent, tip) |
740 (cc, aa, dd, aa2, uu) = repo.changes(patchparent, tip) |
743 if short: |
741 if short: |
744 filelist = cc + aa + dd |
742 filelist = cc + aa + dd |
745 else: |
743 else: |
746 filelist = None |
744 filelist = None |
775 |
773 |
776 c = list(util.unique(cc)) |
774 c = list(util.unique(cc)) |
777 r = list(util.unique(dd)) |
775 r = list(util.unique(dd)) |
778 a = list(util.unique(aa)) |
776 a = list(util.unique(aa)) |
779 filelist = list(util.unique(c + r + a )) |
777 filelist = list(util.unique(c + r + a )) |
780 commands.dodiff(patchf, self.ui, repo, patchparent, None, |
778 commands.dodiff(patchf, self.ui, repo, patchparent, None, |
781 filelist, changes=(c, a, r, [], u)) |
779 filelist, changes=(c, a, r, [], u)) |
782 patchf.close() |
780 patchf.close() |
783 |
781 |
784 changes = repo.changelog.read(tip) |
782 changes = repo.changelog.read(tip) |
785 repo.dirstate.setparents(*cparents) |
783 repo.dirstate.setparents(*cparents) |
786 repo.dirstate.update(a, 'a') |
784 repo.dirstate.update(a, 'a') |
787 repo.dirstate.update(r, 'r') |
785 repo.dirstate.update(r, 'r') |
788 repo.dirstate.update(c, 'n') |
786 repo.dirstate.update(c, 'n') |
789 repo.dirstate.forget(forget) |
787 repo.dirstate.forget(forget) |
790 |
788 |
791 if not message: |
789 if not message: |
792 message = "patch queue: %s\n" % patch |
790 message = "patch queue: %s\n" % patch |
793 else: |
791 else: |
817 start = self.series_end() |
815 start = self.series_end() |
818 else: |
816 else: |
819 start = self.series.index(patch) + 1 |
817 start = self.series.index(patch) + 1 |
820 for p in self.series[start:]: |
818 for p in self.series[start:]: |
821 self.ui.write("%s\n" % p) |
819 self.ui.write("%s\n" % p) |
822 |
820 |
823 def qseries(self, repo, missing=None): |
821 def qseries(self, repo, missing=None): |
824 start = self.series_end() |
822 start = self.series_end() |
825 if not missing: |
823 if not missing: |
826 for p in self.series[:start]: |
824 for p in self.series[:start]: |
827 if self.ui.verbose: |
825 if self.ui.verbose: |
836 for root, dirs, files in os.walk(self.path): |
834 for root, dirs, files in os.walk(self.path): |
837 d = root[len(self.path) + 1:] |
835 d = root[len(self.path) + 1:] |
838 for f in files: |
836 for f in files: |
839 fl = os.path.join(d, f) |
837 fl = os.path.join(d, f) |
840 if (fl not in self.series and fl != "status" and |
838 if (fl not in self.series and fl != "status" and |
841 fl != "series" and not fl.startswith('.')): |
839 fl != "series" and not fl.startswith('.')): |
842 list.append(fl) |
840 list.append(fl) |
843 list.sort() |
841 list.sort() |
844 if list: |
842 if list: |
845 for x in list: |
843 for x in list: |
846 if self.ui.verbose: |
844 if self.ui.verbose: |
847 self.ui.write("D ") |
845 self.ui.write("D ") |
848 self.ui.write("%s\n" % x) |
846 self.ui.write("%s\n" % x) |
849 |
847 |
850 def issaveline(self, l): |
848 def issaveline(self, l): |
900 update = True |
898 update = True |
901 else: |
899 else: |
902 update = False |
900 update = False |
903 self.strip(repo, rev, update=update, backup='strip') |
901 self.strip(repo, rev, update=update, backup='strip') |
904 if qpp: |
902 if qpp: |
905 self.ui.warn("saved queue repository parents: %s %s\n" % |
903 self.ui.warn("saved queue repository parents: %s %s\n" % |
906 (hg.short(qpp[0]), hg.short(qpp[1]))) |
904 (hg.short(qpp[0]), hg.short(qpp[1]))) |
907 if qupdate: |
905 if qupdate: |
908 print "queue directory updating" |
906 print "queue directory updating" |
909 r = self.qrepo() |
907 r = self.qrepo() |
910 if not r: |
908 if not r: |
917 self.ui.warn("save: no patches applied, exiting\n") |
915 self.ui.warn("save: no patches applied, exiting\n") |
918 return 1 |
916 return 1 |
919 if self.issaveline(self.applied[-1]): |
917 if self.issaveline(self.applied[-1]): |
920 self.ui.warn("status is already saved\n") |
918 self.ui.warn("status is already saved\n") |
921 return 1 |
919 return 1 |
922 |
920 |
923 ar = [ ':' + x for x in self.full_series ] |
921 ar = [ ':' + x for x in self.full_series ] |
924 if not msg: |
922 if not msg: |
925 msg = "hg patches saved state" |
923 msg = "hg patches saved state" |
926 else: |
924 else: |
927 msg = "hg patches: " + msg.rstrip('\r\n') |
925 msg = "hg patches: " + msg.rstrip('\r\n') |
928 r = self.qrepo() |
926 r = self.qrepo() |
929 if r: |
927 if r: |
930 pp = r.dirstate.parents() |
928 pp = r.dirstate.parents() |
931 msg += "\nDirstate: %s %s" % (hg.hex(pp[0]), hg.hex(pp[1])) |
929 msg += "\nDirstate: %s %s" % (hg.hex(pp[0]), hg.hex(pp[1])) |
932 msg += "\n\nPatch Data:\n" |
930 msg += "\n\nPatch Data:\n" |
933 text = msg + "\n".join(self.applied) + '\n' + (ar and "\n".join(ar) |
931 text = msg + "\n".join(self.applied) + '\n' + (ar and "\n".join(ar) |
934 + '\n' or "") |
932 + '\n' or "") |
935 n = repo.commit(None, text, user=None, force=1) |
933 n = repo.commit(None, text, user=None, force=1) |
936 if not n: |
934 if not n: |
937 self.ui.warn("repo commit failed\n") |
935 self.ui.warn("repo commit failed\n") |
938 return 1 |
936 return 1 |
939 self.applied.append(revlog.hex(n) + ":" + '.hg.patches.save.line') |
937 self.applied.append(revlog.hex(n) + ":" + '.hg.patches.save.line') |
965 def appliedname(self, index): |
963 def appliedname(self, index): |
966 p = self.applied[index] |
964 p = self.applied[index] |
967 if not self.ui.verbose: |
965 if not self.ui.verbose: |
968 p = p.split(':')[1] |
966 p = p.split(':')[1] |
969 return p |
967 return p |
970 |
968 |
971 def top(self, repo): |
969 def top(self, repo): |
972 if len(self.applied): |
970 if len(self.applied): |
973 p = self.appliedname(-1) |
971 p = self.appliedname(-1) |
974 self.ui.write(p + '\n') |
972 self.ui.write(p + '\n') |
975 else: |
973 else: |
996 self.ui.warn("-n option not valid when importing multiple files\n") |
994 self.ui.warn("-n option not valid when importing multiple files\n") |
997 sys.exit(1) |
995 sys.exit(1) |
998 i = 0 |
996 i = 0 |
999 for filename in files: |
997 for filename in files: |
1000 if existing: |
998 if existing: |
1001 if not patch: |
999 if not patch: |
1002 patch = filename |
1000 patch = filename |
1003 if not os.path.isfile(os.path.join(self.path, patch)): |
1001 if not os.path.isfile(os.path.join(self.path, patch)): |
1004 self.ui.warn("patch %s does not exist\n" % patch) |
1002 self.ui.warn("patch %s does not exist\n" % patch) |
1005 sys.exit(1) |
1003 sys.exit(1) |
1006 else: |
1004 else: |
1045 return 0 |
1043 return 0 |
1046 |
1044 |
1047 def qimport(ui, repo, *filename, **opts): |
1045 def qimport(ui, repo, *filename, **opts): |
1048 """import a patch""" |
1046 """import a patch""" |
1049 q = repomap[repo] |
1047 q = repomap[repo] |
1050 q.qimport(repo, filename, patch=opts['name'], |
1048 q.qimport(repo, filename, patch=opts['name'], |
1051 existing=opts['existing'], force=opts['force']) |
1049 existing=opts['existing'], force=opts['force']) |
1052 q.save_dirty() |
1050 q.save_dirty() |
1053 return 0 |
1051 return 0 |
1054 |
1052 |
1055 def init(ui, repo, **opts): |
1053 def init(ui, repo, **opts): |
1056 """init a new queue repository""" |
1054 """init a new queue repository""" |
1125 max = index |
1123 max = index |
1126 maxname = f |
1124 maxname = f |
1127 if maxname: |
1125 if maxname: |
1128 return (os.path.join(dir, maxname), max) |
1126 return (os.path.join(dir, maxname), max) |
1129 return (None, None) |
1127 return (None, None) |
1130 |
1128 |
1131 def savename(path): |
1129 def savename(path): |
1132 (last, index) = lastsavename(path) |
1130 (last, index) = lastsavename(path) |
1133 if last is None: |
1131 if last is None: |
1134 index = 0 |
1132 index = 0 |
1135 newpath = path + ".%d" % (index + 1) |
1133 newpath = path + ".%d" % (index + 1) |
1137 |
1135 |
1138 def push(ui, repo, patch=None, **opts): |
1136 def push(ui, repo, patch=None, **opts): |
1139 """push the next patch onto the stack""" |
1137 """push the next patch onto the stack""" |
1140 q = repomap[repo] |
1138 q = repomap[repo] |
1141 mergeq = None |
1139 mergeq = None |
1142 |
1140 |
1143 if opts['all']: |
1141 if opts['all']: |
1144 patch = q.series[-1] |
1142 patch = q.series[-1] |
1145 if opts['merge']: |
1143 if opts['merge']: |
1146 if opts['name']: |
1144 if opts['name']: |
1147 newpath = opts['name'] |
1145 newpath = opts['name'] |
1148 else: |
1146 else: |
1149 newpath,i = lastsavename(q.path) |
1147 newpath, i = lastsavename(q.path) |
1150 if not newpath: |
1148 if not newpath: |
1151 ui.warn("no saved queues found, please use -n\n") |
1149 ui.warn("no saved queues found, please use -n\n") |
1152 return 1 |
1150 return 1 |
1153 mergeq = queue(ui, repo.join(""), newpath) |
1151 mergeq = queue(ui, repo.join(""), newpath) |
1154 ui.warn("merging with queue at: %s\n" % mergeq.path) |
1152 ui.warn("merging with queue at: %s\n" % mergeq.path) |
1155 ret = q.push(repo, patch, force=opts['force'], list=opts['list'], |
1153 ret = q.push(repo, patch, force=opts['force'], list=opts['list'], |
1156 mergeq=mergeq) |
1154 mergeq=mergeq) |
1157 q.save_dirty() |
1155 q.save_dirty() |
1158 return ret |
1156 return ret |
1159 |
1157 |
1160 def pop(ui, repo, patch=None, **opts): |
1158 def pop(ui, repo, patch=None, **opts): |
1175 def restore(ui, repo, rev, **opts): |
1173 def restore(ui, repo, rev, **opts): |
1176 """restore the queue state saved by a rev""" |
1174 """restore the queue state saved by a rev""" |
1177 rev = repo.lookup(rev) |
1175 rev = repo.lookup(rev) |
1178 q = repomap[repo] |
1176 q = repomap[repo] |
1179 q.restore(repo, rev, delete=opts['delete'], |
1177 q.restore(repo, rev, delete=opts['delete'], |
1180 qupdate=opts['update']) |
1178 qupdate=opts['update']) |
1181 q.save_dirty() |
1179 q.save_dirty() |
1182 return 0 |
1180 return 0 |
1183 |
1181 |
1184 def save(ui, repo, **opts): |
1182 def save(ui, repo, **opts): |
1185 """save current queue state""" |
1183 """save current queue state""" |
1193 if opts['name']: |
1191 if opts['name']: |
1194 newpath = os.path.join(q.basepath, opts['name']) |
1192 newpath = os.path.join(q.basepath, opts['name']) |
1195 if os.path.exists(newpath): |
1193 if os.path.exists(newpath): |
1196 if not os.path.isdir(newpath): |
1194 if not os.path.isdir(newpath): |
1197 ui.warn("destination %s exists and is not a directory\n" % |
1195 ui.warn("destination %s exists and is not a directory\n" % |
1198 newpath) |
1196 newpath) |
1199 sys.exit(1) |
1197 sys.exit(1) |
1200 if not opts['force']: |
1198 if not opts['force']: |
1201 ui.warn("destination %s exists, use -f to force\n" % |
1199 ui.warn("destination %s exists, use -f to force\n" % |
1202 newpath) |
1200 newpath) |
1203 sys.exit(1) |
1201 sys.exit(1) |
1204 else: |
1202 else: |
1205 newpath = savename(path) |
1203 newpath = savename(path) |
1206 ui.warn("copy %s to %s\n" % (path, newpath)) |
1204 ui.warn("copy %s to %s\n" % (path, newpath)) |
1207 util.copyfiles(path, newpath) |
1205 util.copyfiles(path, newpath) |
1209 try: |
1207 try: |
1210 os.unlink(q.status_path) |
1208 os.unlink(q.status_path) |
1211 except: |
1209 except: |
1212 pass |
1210 pass |
1213 return 0 |
1211 return 0 |
1214 |
1212 |
1215 def strip(ui, repo, rev, **opts): |
1213 def strip(ui, repo, rev, **opts): |
1216 """strip a revision and all later revs on the same branch""" |
1214 """strip a revision and all later revs on the same branch""" |
1217 rev = repo.lookup(rev) |
1215 rev = repo.lookup(rev) |
1218 backup = 'all' |
1216 backup = 'all' |
1219 if opts['backup']: |
1217 if opts['backup']: |
1230 |
1228 |
1231 def reposetup(ui, repo): |
1229 def reposetup(ui, repo): |
1232 repomap[repo] = queue(ui, repo.join("")) |
1230 repomap[repo] = queue(ui, repo.join("")) |
1233 |
1231 |
1234 cmdtable = { |
1232 cmdtable = { |
1235 "qapplied": (applied, [], "hg qapplied [patch]"), |
1233 "qapplied": (applied, [], 'hg qapplied [patch]'), |
1236 "qcommit|qci": (commit, |
1234 "qcommit|qci": |
1237 [('A', 'addremove', None, _('run addremove during commit')), |
1235 (commit, |
1238 ('I', 'include', [], _('include names matching the given patterns')), |
1236 [('A', 'addremove', None, _('run addremove during commit')), |
1239 ('X', 'exclude', [], _('exclude names matching the given patterns')), |
1237 ('I', 'include', [], _('include names matching the given patterns')), |
1240 ('m', 'message', "", _('use <text> as commit message')), |
1238 ('X', 'exclude', [], _('exclude names matching the given patterns')), |
1241 ('l', 'logfile', "", _('read the commit message from <file>')), |
1239 ('m', 'message', '', _('use <text> as commit message')), |
1242 ('d', 'date', "", _('record datecode as commit date')), |
1240 ('l', 'logfile', '', _('read the commit message from <file>')), |
1243 ('u', 'user', "", _('record user as commiter'))], |
1241 ('d', 'date', '', _('record datecode as commit date')), |
1244 "hg qcommit [options] [files]"), |
1242 ('u', 'user', '', _('record user as commiter'))], |
1245 "^qdiff": (diff, [], "hg qdiff [files]"), |
1243 'hg qcommit [options] [files]'), |
1246 "qdelete": (delete, [], "hg qdelete [patch]"), |
1244 "^qdiff": (diff, [], 'hg qdiff [files]'), |
1247 "^qimport": (qimport, [('e', 'existing', None, 'import file in patch dir'), |
1245 "qdelete": (delete, [], 'hg qdelete [patch]'), |
1248 ('n', 'name', "", 'patch file name'), |
1246 "^qimport": |
1249 ('f', 'force', None, 'overwrite existing files')], |
1247 (qimport, |
1250 "hg qimport"), |
1248 [('e', 'existing', None, 'import file in patch dir'), |
1251 "^qinit": (init, [('c', 'create-repo', None, 'create patch repository')], |
1249 ('n', 'name', '', 'patch file name'), |
1252 "hg [-c] qinit"), |
1250 ('f', 'force', None, 'overwrite existing files')], |
1253 "qnew": (new, [('m', 'message', "", 'commit message'), |
1251 'hg qimport'), |
1254 ('f', 'force', None, 'force')], |
1252 "^qinit": |
1255 "hg qnew [-m message ] patch"), |
1253 (init, |
1256 "qnext": (next, [], "hg qnext"), |
1254 [('c', 'create-repo', None, 'create patch repository')], |
1257 "qprev": (prev, [], "hg qprev"), |
1255 'hg [-c] qinit'), |
1258 "^qpop": (pop, [('a', 'all', None, 'pop all patches'), |
1256 "qnew": |
1259 ('n', 'name', "", 'queue name to pop'), |
1257 (new, |
1260 ('f', 'force', None, 'forget any local changes')], |
1258 [('m', 'message', '', 'commit message'), |
1261 'hg qpop [options] [patch/index]'), |
1259 ('f', 'force', None, 'force')], |
1262 "^qpush": (push, [('f', 'force', None, 'apply if the patch has rejects'), |
1260 'hg qnew [-m message ] patch'), |
1263 ('l', 'list', None, 'list patch name in commit text'), |
1261 "qnext": (next, [], 'hg qnext'), |
1264 ('a', 'all', None, 'apply all patches'), |
1262 "qprev": (prev, [], 'hg qprev'), |
1265 ('m', 'merge', None, 'merge from another queue'), |
1263 "^qpop": |
1266 ('n', 'name', "", 'merge queue name')], |
1264 (pop, |
1267 'hg qpush [options] [patch/index]'), |
1265 [('a', 'all', None, 'pop all patches'), |
1268 "^qrefresh": (refresh, [('s', 'short', None, 'short refresh')],"hg qrefresh"), |
1266 ('n', 'name', '', 'queue name to pop'), |
1269 "qrestore": (restore, [('d', 'delete', None, 'delete save entry'), |
1267 ('f', 'force', None, 'forget any local changes')], |
1270 ('u', 'update', None, 'update queue working dir')], |
1268 'hg qpop [options] [patch/index]'), |
1271 'hg qrestore rev'), |
1269 "^qpush": |
1272 "qsave": (save, [('m', 'message', "", 'commit message'), |
1270 (push, |
1273 ('c', 'copy', None, 'copy patch directory'), |
1271 [('f', 'force', None, 'apply if the patch has rejects'), |
1274 ('n', 'name', "", 'copy directory name'), |
1272 ('l', 'list', None, 'list patch name in commit text'), |
1275 ('e', 'empty', None, 'clear queue status file'), |
1273 ('a', 'all', None, 'apply all patches'), |
1276 ('f', 'force', None, 'force copy')], 'hg qsave'), |
1274 ('m', 'merge', None, 'merge from another queue'), |
1277 "qseries": (series, [('m', 'missing', None, 'print patches not in series')], |
1275 ('n', 'name', '', 'merge queue name')], |
1278 "hg qseries"), |
1276 'hg qpush [options] [patch/index]'), |
1279 "^strip": (strip, [('f', 'force', None, 'force multi-head removal'), |
1277 "^qrefresh": |
1280 ('b', 'backup', None, 'bundle unrelated changesets'), |
1278 (refresh, |
1281 ('n', 'nobackup', None, 'no backups')], "hg strip rev"), |
1279 [('s', 'short', None, 'short refresh')], |
1282 "qtop": (top, [], "hg qtop"), |
1280 'hg qrefresh'), |
1283 "qunapplied": (unapplied, [], "hg qunapplied [patch]"), |
1281 "qrestore": |
1284 "qversion": (version, [], "hg qversion") |
1282 (restore, |
1283 [('d', 'delete', None, 'delete save entry'), |
|
1284 ('u', 'update', None, 'update queue working dir')], |
|
1285 'hg qrestore rev'), |
|
1286 "qsave": |
|
1287 (save, |
|
1288 [('m', 'message', '', 'commit message'), |
|
1289 ('c', 'copy', None, 'copy patch directory'), |
|
1290 ('n', 'name', '', 'copy directory name'), |
|
1291 ('e', 'empty', None, 'clear queue status file'), |
|
1292 ('f', 'force', None, 'force copy')], |
|
1293 'hg qsave'), |
|
1294 "qseries": |
|
1295 (series, |
|
1296 [('m', 'missing', None, 'print patches not in series')], |
|
1297 'hg qseries'), |
|
1298 "^strip": |
|
1299 (strip, |
|
1300 [('f', 'force', None, 'force multi-head removal'), |
|
1301 ('b', 'backup', None, 'bundle unrelated changesets'), |
|
1302 ('n', 'nobackup', None, 'no backups')], |
|
1303 'hg strip rev'), |
|
1304 "qtop": (top, [], 'hg qtop'), |
|
1305 "qunapplied": (unapplied, [], 'hg qunapplied [patch]'), |
|
1306 "qversion": (version, [], 'hg qversion') |
|
1285 } |
1307 } |
1286 |
1308 |