Show More
@@ -0,0 +1,45 b'' | |||
|
1 | #!/bin/sh | |
|
2 | ||
|
3 | cat >findbranch.py <<EOF | |
|
4 | import re, sys | |
|
5 | ||
|
6 | head_re = re.compile('^#(?:(?:\\s+([A-Za-z][A-Za-z0-9_]*)(?:\\s.*)?)|(?:\\s*))$') | |
|
7 | ||
|
8 | for line in sys.stdin: | |
|
9 | hmatch = head_re.match(line) | |
|
10 | if not hmatch: | |
|
11 | sys.exit(1) | |
|
12 | if hmatch.group(1) == 'Branch': | |
|
13 | sys.exit(0) | |
|
14 | sys.exit(1) | |
|
15 | EOF | |
|
16 | hg init a | |
|
17 | cd a | |
|
18 | echo "Rev 1" >rev | |
|
19 | hg add rev | |
|
20 | hg commit -m "No branch." | |
|
21 | hg branch abranch | |
|
22 | echo "Rev 2" >rev | |
|
23 | hg commit -m "With branch." | |
|
24 | if hg export 0 | python ../findbranch.py; then | |
|
25 | echo "Export of default branch revision has Branch header" 1>&2 | |
|
26 | exit 1 | |
|
27 | fi | |
|
28 | if hg export 1 | python ../findbranch.py; then | |
|
29 | : # Do nothing | |
|
30 | else | |
|
31 | echo "Export of branch revision is missing Branch header" 1>&2 | |
|
32 | exit 1 | |
|
33 | fi | |
|
34 | # Make sure import still works with branch information in patches. | |
|
35 | cd .. | |
|
36 | hg init b | |
|
37 | cd b | |
|
38 | hg -R ../a export 0 | hg import - | |
|
39 | hg -R ../a export 1 | hg import - | |
|
40 | cd .. | |
|
41 | rm -rf b | |
|
42 | hg init b | |
|
43 | cd b | |
|
44 | hg -R ../a export 0 | hg import --exact - | |
|
45 | hg -R ../a export 1 | hg import --exact - |
@@ -0,0 +1,4 b'' | |||
|
1 | applying patch from stdin | |
|
2 | applying patch from stdin | |
|
3 | applying patch from stdin | |
|
4 | applying patch from stdin |
@@ -30,7 +30,7 b' from mercurial import hg, ui, util, fanc' | |||
|
30 | 30 | class Abort(Exception): pass |
|
31 | 31 | class NoRepo(Exception): pass |
|
32 | 32 | |
|
33 | class commit: | |
|
33 | class commit(object): | |
|
34 | 34 | def __init__(self, **parts): |
|
35 | 35 | for x in "author date desc parents".split(): |
|
36 | 36 | if not x in parts: |
@@ -56,8 +56,89 b' def recode(s):' | |||
|
56 | 56 | except: |
|
57 | 57 | return s.decode("utf-8", "replace").encode("utf-8") |
|
58 | 58 | |
|
59 | class converter_source(object): | |
|
60 | """Conversion source interface""" | |
|
61 | ||
|
62 | def __init__(self, path): | |
|
63 | """Initialize conversion source (or raise NoRepo("message") | |
|
64 | exception if path is not a valid repository)""" | |
|
65 | raise NotImplementedError() | |
|
66 | ||
|
67 | def getheads(self): | |
|
68 | """Return a list of this repository's heads""" | |
|
69 | raise NotImplementedError() | |
|
70 | ||
|
71 | def getfile(self, name, rev): | |
|
72 | """Return file contents as a string""" | |
|
73 | raise NotImplementedError() | |
|
74 | ||
|
75 | def getmode(self, name, rev): | |
|
76 | """Return file mode, eg. '', 'x', or 'l'""" | |
|
77 | raise NotImplementedError() | |
|
78 | ||
|
79 | def getchanges(self, version): | |
|
80 | """Return sorted list of (filename, id) tuples for all files changed in rev. | |
|
81 | ||
|
82 | id just tells us which revision to return in getfile(), e.g. in | |
|
83 | git it's an object hash.""" | |
|
84 | raise NotImplementedError() | |
|
85 | ||
|
86 | def getcommit(self, version): | |
|
87 | """Return the commit object for version""" | |
|
88 | raise NotImplementedError() | |
|
89 | ||
|
90 | def gettags(self): | |
|
91 | """Return the tags as a dictionary of name: revision""" | |
|
92 | raise NotImplementedError() | |
|
93 | ||
|
94 | class converter_sink(object): | |
|
95 | """Conversion sink (target) interface""" | |
|
96 | ||
|
97 | def __init__(self, path): | |
|
98 | """Initialize conversion sink (or raise NoRepo("message") | |
|
99 | exception if path is not a valid repository)""" | |
|
100 | raise NotImplementedError() | |
|
101 | ||
|
102 | def getheads(self): | |
|
103 | """Return a list of this repository's heads""" | |
|
104 | raise NotImplementedError() | |
|
105 | ||
|
106 | def mapfile(self): | |
|
107 | """Path to a file that will contain lines | |
|
108 | source_rev_id sink_rev_id | |
|
109 | mapping equivalent revision identifiers for each system.""" | |
|
110 | raise NotImplementedError() | |
|
111 | ||
|
112 | def putfile(self, f, e, data): | |
|
113 | """Put file for next putcommit(). | |
|
114 | f: path to file | |
|
115 | e: '', 'x', or 'l' (regular file, executable, or symlink) | |
|
116 | data: file contents""" | |
|
117 | raise NotImplementedError() | |
|
118 | ||
|
119 | def delfile(self, f): | |
|
120 | """Delete file for next putcommit(). | |
|
121 | f: path to file""" | |
|
122 | raise NotImplementedError() | |
|
123 | ||
|
124 | def putcommit(self, files, parents, commit): | |
|
125 | """Create a revision with all changed files listed in 'files' | |
|
126 | and having listed parents. 'commit' is a commit object containing | |
|
127 | at a minimum the author, date, and message for this changeset. | |
|
128 | Called after putfile() and delfile() calls. Note that the sink | |
|
129 | repository is not told to update itself to a particular revision | |
|
130 | (or even what that revision would be) before it receives the | |
|
131 | file data.""" | |
|
132 | raise NotImplementedError() | |
|
133 | ||
|
134 | def puttags(self, tags): | |
|
135 | """Put tags into sink. | |
|
136 | tags: {tagname: sink_rev_id, ...}""" | |
|
137 | raise NotImplementedError() | |
|
138 | ||
|
139 | ||
|
59 | 140 | # CVS conversion code inspired by hg-cvs-import and git-cvsimport |
|
60 | class convert_cvs: | |
|
141 | class convert_cvs(converter_source): | |
|
61 | 142 | def __init__(self, path): |
|
62 | 143 | self.path = path |
|
63 | 144 | cvs = os.path.join(path, "CVS") |
@@ -288,7 +369,7 b' class convert_cvs:' | |||
|
288 | 369 | def gettags(self): |
|
289 | 370 | return self.tags |
|
290 | 371 | |
|
291 | class convert_git: | |
|
372 | class convert_git(converter_source): | |
|
292 | 373 | def __init__(self, path): |
|
293 | 374 | if os.path.isdir(path + "/.git"): |
|
294 | 375 | path += "/.git" |
@@ -374,7 +455,7 b' class convert_git:' | |||
|
374 | 455 | |
|
375 | 456 | return tags |
|
376 | 457 | |
|
377 | class convert_mercurial: | |
|
458 | class convert_mercurial(converter_sink): | |
|
378 | 459 | def __init__(self, path): |
|
379 | 460 | self.path = path |
|
380 | 461 | u = ui.ui() |
@@ -471,7 +552,7 b' def converter(path):' | |||
|
471 | 552 | pass |
|
472 | 553 | abort("%s: unknown repository type\n" % path) |
|
473 | 554 | |
|
474 | class convert: | |
|
555 | class convert(object): | |
|
475 | 556 | def __init__(self, source, dest, mapfile, opts): |
|
476 | 557 | |
|
477 | 558 | self.source = source |
@@ -380,7 +380,7 b' typeset -A _hg_cmd_globals' | |||
|
380 | 380 | _arguments -s -w : $_hg_global_opts $_hg_pat_opts \ |
|
381 | 381 | '(--addremove -A)'{-A,--addremove}'[mark new/missing files as added/removed before committing]' \ |
|
382 | 382 | '(--message -m)'{-m+,--message}'[use <text> as commit message]:text:' \ |
|
383 | '(--logfile -l)'{-l+,--logfile}'[read commit message from <file>]:log file:_file -g \*.txt' \ | |
|
383 | '(--logfile -l)'{-l+,--logfile}'[read commit message from <file>]:log file:_files -g \*.txt' \ | |
|
384 | 384 | '(--date -d)'{-d+,--date}'[record datecode as commit date]:date code:' \ |
|
385 | 385 | '(--user -u)'{-u+,--user}'[record user as commiter]:user:' \ |
|
386 | 386 | '*:file:_hg_files' |
@@ -182,7 +182,7 b' def archive(ui, repo, dest, **opts):' | |||
|
182 | 182 | archival.archive(repo, dest, node, kind, not opts['no_decode'], |
|
183 | 183 | matchfn, prefix) |
|
184 | 184 | |
|
185 | def backout(ui, repo, rev, **opts): | |
|
185 | def backout(ui, repo, node=None, rev=None, **opts): | |
|
186 | 186 | '''reverse effect of earlier changeset |
|
187 | 187 | |
|
188 | 188 | Commit the backed out changes as a new changeset. The new |
@@ -199,6 +199,11 b' def backout(ui, repo, rev, **opts):' | |||
|
199 | 199 | changeset afterwards. This saves you from doing the merge by |
|
200 | 200 | hand. The result of this merge is not committed, as for a normal |
|
201 | 201 | merge.''' |
|
202 | if rev and node: | |
|
203 | raise util.Abort(_("please specify just one revision")) | |
|
204 | ||
|
205 | if not rev: | |
|
206 | rev = node | |
|
202 | 207 | |
|
203 | 208 | bail_if_changed(repo) |
|
204 | 209 | op1, op2 = repo.dirstate.parents() |
@@ -1511,10 +1516,10 b' def import_(ui, repo, patch1, *patches, ' | |||
|
1511 | 1516 | |
|
1512 | 1517 | if pf == '-': |
|
1513 | 1518 | ui.status(_("applying patch from stdin\n")) |
|
1514 | tmpname, message, user, date, nodeid, p1, p2 = patch.extract(ui, sys.stdin) | |
|
1519 | tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, sys.stdin) | |
|
1515 | 1520 | else: |
|
1516 | 1521 | ui.status(_("applying %s\n") % p) |
|
1517 | tmpname, message, user, date, nodeid, p1, p2 = patch.extract(ui, file(pf)) | |
|
1522 | tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, file(pf)) | |
|
1518 | 1523 | |
|
1519 | 1524 | if tmpname is None: |
|
1520 | 1525 | raise util.Abort(_('no diffs found')) |
@@ -1542,6 +1547,7 b' def import_(ui, repo, patch1, *patches, ' | |||
|
1542 | 1547 | if p1 != wp[0].node(): |
|
1543 | 1548 | hg.clean(repo, p1, wlock=wlock) |
|
1544 | 1549 | repo.dirstate.setparents(p1, p2) |
|
1550 | repo.dirstate.setbranch(branch or 'default') | |
|
1545 | 1551 | elif p2: |
|
1546 | 1552 | try: |
|
1547 | 1553 | p1 = repo.lookup(p1) |
@@ -1826,7 +1832,7 b' def manifest(ui, repo, rev=None):' | |||
|
1826 | 1832 | ui.write("%3s " % (m.execf(f) and "755" or "644")) |
|
1827 | 1833 | ui.write("%s\n" % f) |
|
1828 | 1834 | |
|
1829 | def merge(ui, repo, node=None, force=None): | |
|
1835 | def merge(ui, repo, node=None, force=None, rev=None): | |
|
1830 | 1836 | """merge working directory with another revision |
|
1831 | 1837 | |
|
1832 | 1838 | Merge the contents of the current working directory and the |
@@ -1840,6 +1846,12 b' def merge(ui, repo, node=None, force=Non' | |||
|
1840 | 1846 | revision to merge with must be provided. |
|
1841 | 1847 | """ |
|
1842 | 1848 | |
|
1849 | if rev and node: | |
|
1850 | raise util.Abort(_("please specify just one revision")) | |
|
1851 | ||
|
1852 | if not node: | |
|
1853 | node = rev | |
|
1854 | ||
|
1843 | 1855 | if not node: |
|
1844 | 1856 | heads = repo.heads() |
|
1845 | 1857 | if len(heads) > 2: |
@@ -2552,7 +2564,7 b' def unbundle(ui, repo, fname, **opts):' | |||
|
2552 | 2564 | modheads = repo.addchangegroup(gen, 'unbundle', 'bundle:' + fname) |
|
2553 | 2565 | return postincoming(ui, repo, modheads, opts['update']) |
|
2554 | 2566 | |
|
2555 | def update(ui, repo, node=None, clean=False, date=None): | |
|
2567 | def update(ui, repo, node=None, rev=None, clean=False, date=None): | |
|
2556 | 2568 | """update working directory |
|
2557 | 2569 | |
|
2558 | 2570 | Update the working directory to the specified revision, or the |
@@ -2568,15 +2580,21 b' def update(ui, repo, node=None, clean=Fa' | |||
|
2568 | 2580 | By default, update will refuse to run if doing so would require |
|
2569 | 2581 | discarding local changes. |
|
2570 | 2582 | """ |
|
2583 | if rev and node: | |
|
2584 | raise util.Abort(_("please specify just one revision")) | |
|
2585 | ||
|
2586 | if not rev: | |
|
2587 | rev = node | |
|
2588 | ||
|
2571 | 2589 | if date: |
|
2572 |
if |
|
|
2590 | if rev: | |
|
2573 | 2591 | raise util.Abort(_("you can't specify a revision and a date")) |
|
2574 |
|
|
|
2592 | rev = cmdutil.finddate(ui, repo, date) | |
|
2575 | 2593 | |
|
2576 | 2594 | if clean: |
|
2577 |
return hg.clean(repo, |
|
|
2595 | return hg.clean(repo, rev) | |
|
2578 | 2596 | else: |
|
2579 |
return hg.update(repo, |
|
|
2597 | return hg.update(repo, rev) | |
|
2580 | 2598 | |
|
2581 | 2599 | def verify(ui, repo): |
|
2582 | 2600 | """verify the integrity of the repository |
@@ -2676,8 +2694,9 b' table = {' | |||
|
2676 | 2694 | ('d', 'date', '', _('record datecode as commit date')), |
|
2677 | 2695 | ('', 'parent', '', _('parent to choose when backing out merge')), |
|
2678 | 2696 | ('u', 'user', '', _('record user as committer')), |
|
2697 | ('r', 'rev', '', _('revision to backout')), | |
|
2679 | 2698 | ] + walkopts + commitopts, |
|
2680 | _('hg backout [OPTION]... REV')), | |
|
2699 | _('hg backout [OPTION]... [-r] REV')), | |
|
2681 | 2700 | "branch": (branch, |
|
2682 | 2701 | [('f', 'force', None, |
|
2683 | 2702 | _('set branch name even if it shadows an existing branch'))], |
@@ -2852,8 +2871,10 b' table = {' | |||
|
2852 | 2871 | "manifest": (manifest, [], _('hg manifest [REV]')), |
|
2853 | 2872 | "^merge": |
|
2854 | 2873 | (merge, |
|
2855 |
[('f', 'force', None, _('force a merge with outstanding changes')) |
|
|
2856 | _('hg merge [-f] [REV]')), | |
|
2874 | [('f', 'force', None, _('force a merge with outstanding changes')), | |
|
2875 | ('r', 'rev', '', _('revision to merge')), | |
|
2876 | ], | |
|
2877 | _('hg merge [-f] [[-r] REV]')), | |
|
2857 | 2878 | "outgoing|out": (outgoing, |
|
2858 | 2879 | [('M', 'no-merges', None, _('do not show merges')), |
|
2859 | 2880 | ('f', 'force', None, |
@@ -2984,8 +3005,9 b' table = {' | |||
|
2984 | 3005 | "^update|up|checkout|co": |
|
2985 | 3006 | (update, |
|
2986 | 3007 | [('C', 'clean', None, _('overwrite locally modified files')), |
|
2987 |
('d', 'date', '', _('tipmost revision matching date')) |
|
|
2988 | _('hg update [-C] [-d DATE] [REV]')), | |
|
3008 | ('d', 'date', '', _('tipmost revision matching date')), | |
|
3009 | ('r', 'rev', '', _('revision'))], | |
|
3010 | _('hg update [-C] [-d DATE] [[-r] REV]')), | |
|
2989 | 3011 | "verify": (verify, [], _('hg verify')), |
|
2990 | 3012 | "version": (version_, [], _('hg version')), |
|
2991 | 3013 | } |
@@ -66,6 +66,8 b' class dirstate(object):' | |||
|
66 | 66 | syntaxes = {'re': 'relre:', 'regexp': 'relre:', 'glob': 'relglob:'} |
|
67 | 67 | def parselines(fp): |
|
68 | 68 | for line in fp: |
|
69 | if not line.endswith('\n'): | |
|
70 | line += '\n' | |
|
69 | 71 | escape = False |
|
70 | 72 | for i in xrange(len(line)): |
|
71 | 73 | if escape: escape = False |
@@ -55,6 +55,7 b' def extract(ui, fileobj):' | |||
|
55 | 55 | # should try to parse msg['Date'] |
|
56 | 56 | date = None |
|
57 | 57 | nodeid = None |
|
58 | branch = None | |
|
58 | 59 | parents = [] |
|
59 | 60 | |
|
60 | 61 | if message: |
@@ -99,6 +100,8 b' def extract(ui, fileobj):' | |||
|
99 | 100 | ui.debug('From: %s\n' % user) |
|
100 | 101 | elif line.startswith("# Date "): |
|
101 | 102 | date = line[7:] |
|
103 | elif line.startswith("# Branch "): | |
|
104 | branch = line[9:] | |
|
102 | 105 | elif line.startswith("# Node ID "): |
|
103 | 106 | nodeid = line[10:] |
|
104 | 107 | elif line.startswith("# Parent "): |
@@ -123,10 +126,10 b' def extract(ui, fileobj):' | |||
|
123 | 126 | tmpfp.close() |
|
124 | 127 | if not diffs_seen: |
|
125 | 128 | os.unlink(tmpname) |
|
126 | return None, message, user, date, None, None, None | |
|
129 | return None, message, user, date, branch, None, None, None | |
|
127 | 130 | p1 = parents and parents.pop(0) or None |
|
128 | 131 | p2 = parents and parents.pop(0) or None |
|
129 | return tmpname, message, user, date, nodeid, p1, p2 | |
|
132 | return tmpname, message, user, date, branch, nodeid, p1, p2 | |
|
130 | 133 | |
|
131 | 134 | GP_PATCH = 1 << 0 # we have to run patch |
|
132 | 135 | GP_FILTER = 1 << 1 # there's some copy/rename operation |
@@ -1,6 +1,25 b'' | |||
|
1 | 1 | #!/bin/sh |
|
2 | 2 | |
|
3 | 3 | hg init |
|
4 | ||
|
5 | # Test issue 562: .hgignore requires newline at end | |
|
6 | touch foo | |
|
7 | touch bar | |
|
8 | touch baz | |
|
9 | cat > makeignore.py <<EOF | |
|
10 | f = open(".hgignore", "w") | |
|
11 | f.write("ignore\n") | |
|
12 | f.write("foo\n") | |
|
13 | # No EOL here | |
|
14 | f.write("bar") | |
|
15 | f.close() | |
|
16 | EOF | |
|
17 | ||
|
18 | python makeignore.py | |
|
19 | echo % should display baz only | |
|
20 | hg status | |
|
21 | rm foo bar baz .hgignore makeignore.py | |
|
22 | ||
|
4 | 23 | touch a.o |
|
5 | 24 | touch a.c |
|
6 | 25 | touch syntax |
General Comments 0
You need to be logged in to leave comments.
Login now