Show More
@@ -1,587 +1,589 | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | 2 | # |
|
3 | 3 | # check-code - a style and portability checker for Mercurial |
|
4 | 4 | # |
|
5 | 5 | # Copyright 2010 Matt Mackall <mpm@selenic.com> |
|
6 | 6 | # |
|
7 | 7 | # This software may be used and distributed according to the terms of the |
|
8 | 8 | # GNU General Public License version 2 or any later version. |
|
9 | 9 | |
|
10 | 10 | """style and portability checker for Mercurial |
|
11 | 11 | |
|
12 | 12 | when a rule triggers wrong, do one of the following (prefer one from top): |
|
13 | 13 | * do the work-around the rule suggests |
|
14 | 14 | * doublecheck that it is a false match |
|
15 | 15 | * improve the rule pattern |
|
16 | 16 | * add an ignore pattern to the rule (3rd arg) which matches your good line |
|
17 | 17 | (you can append a short comment and match this, like: #re-raises, # no-py24) |
|
18 | 18 | * change the pattern to a warning and list the exception in test-check-code-hg |
|
19 | 19 | * ONLY use no--check-code for skipping entire files from external sources |
|
20 | 20 | """ |
|
21 | 21 | |
|
22 | 22 | import re, glob, os, sys |
|
23 | 23 | import keyword |
|
24 | 24 | import optparse |
|
25 | 25 | try: |
|
26 | 26 | import re2 |
|
27 | 27 | except ImportError: |
|
28 | 28 | re2 = None |
|
29 | 29 | |
|
30 | 30 | def compilere(pat, multiline=False): |
|
31 | 31 | if multiline: |
|
32 | 32 | pat = '(?m)' + pat |
|
33 | 33 | if re2: |
|
34 | 34 | try: |
|
35 | 35 | return re2.compile(pat) |
|
36 | 36 | except re2.error: |
|
37 | 37 | pass |
|
38 | 38 | return re.compile(pat) |
|
39 | 39 | |
|
40 | 40 | def repquote(m): |
|
41 | 41 | fromc = '.:' |
|
42 | 42 | tochr = 'pq' |
|
43 | 43 | def encodechr(i): |
|
44 | 44 | if i > 255: |
|
45 | 45 | return 'u' |
|
46 | 46 | c = chr(i) |
|
47 | 47 | if c in ' \n': |
|
48 | 48 | return c |
|
49 | 49 | if c.isalpha(): |
|
50 | 50 | return 'x' |
|
51 | 51 | if c.isdigit(): |
|
52 | 52 | return 'n' |
|
53 | 53 | try: |
|
54 | 54 | return tochr[fromc.find(c)] |
|
55 | 55 | except (ValueError, IndexError): |
|
56 | 56 | return 'o' |
|
57 | 57 | t = m.group('text') |
|
58 | 58 | tt = ''.join(encodechr(i) for i in xrange(256)) |
|
59 | 59 | t = t.translate(tt) |
|
60 | 60 | return m.group('quote') + t + m.group('quote') |
|
61 | 61 | |
|
62 | 62 | def reppython(m): |
|
63 | 63 | comment = m.group('comment') |
|
64 | 64 | if comment: |
|
65 | 65 | l = len(comment.rstrip()) |
|
66 | 66 | return "#" * l + comment[l:] |
|
67 | 67 | return repquote(m) |
|
68 | 68 | |
|
69 | 69 | def repcomment(m): |
|
70 | 70 | return m.group(1) + "#" * len(m.group(2)) |
|
71 | 71 | |
|
72 | 72 | def repccomment(m): |
|
73 | 73 | t = re.sub(r"((?<=\n) )|\S", "x", m.group(2)) |
|
74 | 74 | return m.group(1) + t + "*/" |
|
75 | 75 | |
|
76 | 76 | def repcallspaces(m): |
|
77 | 77 | t = re.sub(r"\n\s+", "\n", m.group(2)) |
|
78 | 78 | return m.group(1) + t |
|
79 | 79 | |
|
80 | 80 | def repinclude(m): |
|
81 | 81 | return m.group(1) + "<foo>" |
|
82 | 82 | |
|
83 | 83 | def rephere(m): |
|
84 | 84 | t = re.sub(r"\S", "x", m.group(2)) |
|
85 | 85 | return m.group(1) + t |
|
86 | 86 | |
|
87 | 87 | |
|
88 | 88 | testpats = [ |
|
89 | 89 | [ |
|
90 | 90 | (r'pushd|popd', "don't use 'pushd' or 'popd', use 'cd'"), |
|
91 | 91 | (r'\W\$?\(\([^\)\n]*\)\)', "don't use (()) or $(()), use 'expr'"), |
|
92 | 92 | (r'grep.*-q', "don't use 'grep -q', redirect to /dev/null"), |
|
93 | 93 | (r'(?<!hg )grep.* -a', "don't use 'grep -a', use in-line python"), |
|
94 | 94 | (r'sed.*-i', "don't use 'sed -i', use a temporary file"), |
|
95 | 95 | (r'\becho\b.*\\n', "don't use 'echo \\n', use printf"), |
|
96 | 96 | (r'echo -n', "don't use 'echo -n', use printf"), |
|
97 | 97 | (r'(^|\|\s*)\bwc\b[^|]*$\n(?!.*\(re\))', "filter wc output"), |
|
98 | 98 | (r'head -c', "don't use 'head -c', use 'dd'"), |
|
99 | 99 | (r'tail -n', "don't use the '-n' option to tail, just use '-<num>'"), |
|
100 | 100 | (r'sha1sum', "don't use sha1sum, use $TESTDIR/md5sum.py"), |
|
101 | 101 | (r'ls.*-\w*R', "don't use 'ls -R', use 'find'"), |
|
102 | 102 | (r'printf.*[^\\]\\([1-9]|0\d)', "don't use 'printf \NNN', use Python"), |
|
103 | 103 | (r'printf.*[^\\]\\x', "don't use printf \\x, use Python"), |
|
104 | 104 | (r'\$\(.*\)', "don't use $(expr), use `expr`"), |
|
105 | 105 | (r'rm -rf \*', "don't use naked rm -rf, target a directory"), |
|
106 | 106 | (r'(^|\|\s*)grep (-\w\s+)*[^|]*[(|]\w', |
|
107 | 107 | "use egrep for extended grep syntax"), |
|
108 | 108 | (r'/bin/', "don't use explicit paths for tools"), |
|
109 | 109 | (r'[^\n]\Z', "no trailing newline"), |
|
110 | 110 | (r'export .*=', "don't export and assign at once"), |
|
111 | 111 | (r'^source\b', "don't use 'source', use '.'"), |
|
112 | 112 | (r'touch -d', "don't use 'touch -d', use 'touch -t' instead"), |
|
113 | 113 | (r'ls +[^|\n-]+ +-', "options to 'ls' must come before filenames"), |
|
114 | 114 | (r'[^>\n]>\s*\$HGRCPATH', "don't overwrite $HGRCPATH, append to it"), |
|
115 | 115 | (r'^stop\(\)', "don't use 'stop' as a shell function name"), |
|
116 | 116 | (r'(\[|\btest\b).*-e ', "don't use 'test -e', use 'test -f'"), |
|
117 | 117 | (r'\[\[\s+[^\]]*\]\]', "don't use '[[ ]]', use '[ ]'"), |
|
118 | 118 | (r'^alias\b.*=', "don't use alias, use a function"), |
|
119 | 119 | (r'if\s*!', "don't use '!' to negate exit status"), |
|
120 | 120 | (r'/dev/u?random', "don't use entropy, use /dev/zero"), |
|
121 | 121 | (r'do\s*true;\s*done', "don't use true as loop body, use sleep 0"), |
|
122 | 122 | (r'^( *)\t', "don't use tabs to indent"), |
|
123 | 123 | (r'sed (-e )?\'(\d+|/[^/]*/)i(?!\\\n)', |
|
124 | 124 | "put a backslash-escaped newline after sed 'i' command"), |
|
125 | 125 | (r'^diff *-\w*[uU].*$\n(^ \$ |^$)', "prefix diff -u/-U with cmp"), |
|
126 | 126 | (r'^\s+(if)? diff *-\w*[uU]', "prefix diff -u/-U with cmp"), |
|
127 | 127 | (r'seq ', "don't use 'seq', use $TESTDIR/seq.py"), |
|
128 | 128 | (r'\butil\.Abort\b', "directly use error.Abort"), |
|
129 | 129 | (r'\|&', "don't use |&, use 2>&1"), |
|
130 | 130 | (r'\w = +\w', "only one space after = allowed"), |
|
131 | 131 | ], |
|
132 | 132 | # warnings |
|
133 | 133 | [ |
|
134 | 134 | (r'^function', "don't use 'function', use old style"), |
|
135 | 135 | (r'^diff.*-\w*N', "don't use 'diff -N'"), |
|
136 | 136 | (r'\$PWD|\${PWD}', "don't use $PWD, use `pwd`"), |
|
137 | 137 | (r'^([^"\'\n]|("[^"\n]*")|(\'[^\'\n]*\'))*\^', "^ must be quoted"), |
|
138 | 138 | (r'kill (`|\$\()', "don't use kill, use killdaemons.py") |
|
139 | 139 | ] |
|
140 | 140 | ] |
|
141 | 141 | |
|
142 | 142 | testfilters = [ |
|
143 | 143 | (r"( *)(#([^\n]*\S)?)", repcomment), |
|
144 | 144 | (r"<<(\S+)((.|\n)*?\n\1)", rephere), |
|
145 | 145 | ] |
|
146 | 146 | |
|
147 | 147 | winglobmsg = "use (glob) to match Windows paths too" |
|
148 | 148 | uprefix = r"^ \$ " |
|
149 | 149 | utestpats = [ |
|
150 | 150 | [ |
|
151 | 151 | (r'^(\S.*|| [$>] \S.*)[ \t]\n', "trailing whitespace on non-output"), |
|
152 | 152 | (uprefix + r'.*\|\s*sed[^|>\n]*\n', |
|
153 | 153 | "use regex test output patterns instead of sed"), |
|
154 | 154 | (uprefix + r'(true|exit 0)', "explicit zero exit unnecessary"), |
|
155 | 155 | (uprefix + r'.*(?<!\[)\$\?', "explicit exit code checks unnecessary"), |
|
156 | 156 | (uprefix + r'.*\|\| echo.*(fail|error)', |
|
157 | 157 | "explicit exit code checks unnecessary"), |
|
158 | 158 | (uprefix + r'set -e', "don't use set -e"), |
|
159 | 159 | (uprefix + r'(\s|fi\b|done\b)', "use > for continued lines"), |
|
160 | 160 | (uprefix + r'.*:\.\S*/', "x:.y in a path does not work on msys, rewrite " |
|
161 | 161 | "as x://.y, or see `hg log -k msys` for alternatives", r'-\S+:\.|' #-Rxxx |
|
162 | 162 | '# no-msys'), # in test-pull.t which is skipped on windows |
|
163 | 163 | (r'^ saved backup bundle to \$TESTTMP.*\.hg$', winglobmsg), |
|
164 | 164 | (r'^ changeset .* references (corrupted|missing) \$TESTTMP/.*[^)]$', |
|
165 | 165 | winglobmsg), |
|
166 | 166 | (r'^ pulling from \$TESTTMP/.*[^)]$', winglobmsg, |
|
167 | 167 | '\$TESTTMP/unix-repo$'), # in test-issue1802.t which skipped on windows |
|
168 | 168 | (r'^ reverting (?!subrepo ).*/.*[^)]$', winglobmsg), |
|
169 | 169 | (r'^ cloning subrepo \S+/.*[^)]$', winglobmsg), |
|
170 | 170 | (r'^ pushing to \$TESTTMP/.*[^)]$', winglobmsg), |
|
171 | 171 | (r'^ pushing subrepo \S+/\S+ to.*[^)]$', winglobmsg), |
|
172 | 172 | (r'^ moving \S+/.*[^)]$', winglobmsg), |
|
173 | 173 | (r'^ no changes made to subrepo since.*/.*[^)]$', winglobmsg), |
|
174 | 174 | (r'^ .*: largefile \S+ not available from file:.*/.*[^)]$', winglobmsg), |
|
175 | 175 | (r'^ .*file://\$TESTTMP', |
|
176 | 176 | 'write "file:/*/$TESTTMP" + (glob) to match on windows too'), |
|
177 | 177 | (r'^ (cat|find): .*: No such file or directory', |
|
178 | 178 | 'use test -f to test for file existence'), |
|
179 | (r'^ diff -[^ -]*p', | |
|
180 | "don't use (external) diff with -p for portability"), | |
|
179 | 181 | ], |
|
180 | 182 | # warnings |
|
181 | 183 | [ |
|
182 | 184 | (r'^ [^*?/\n]* \(glob\)$', |
|
183 | 185 | "glob match with no glob character (?*/)"), |
|
184 | 186 | ] |
|
185 | 187 | ] |
|
186 | 188 | |
|
187 | 189 | for i in [0, 1]: |
|
188 | 190 | for tp in testpats[i]: |
|
189 | 191 | p = tp[0] |
|
190 | 192 | m = tp[1] |
|
191 | 193 | if p.startswith(r'^'): |
|
192 | 194 | p = r"^ [$>] (%s)" % p[1:] |
|
193 | 195 | else: |
|
194 | 196 | p = r"^ [$>] .*(%s)" % p |
|
195 | 197 | utestpats[i].append((p, m) + tp[2:]) |
|
196 | 198 | |
|
197 | 199 | utestfilters = [ |
|
198 | 200 | (r"<<(\S+)((.|\n)*?\n > \1)", rephere), |
|
199 | 201 | (r"( *)(#([^\n]*\S)?)", repcomment), |
|
200 | 202 | ] |
|
201 | 203 | |
|
202 | 204 | pypats = [ |
|
203 | 205 | [ |
|
204 | 206 | (r'^\s*def\s*\w+\s*\(.*,\s*\(', |
|
205 | 207 | "tuple parameter unpacking not available in Python 3+"), |
|
206 | 208 | (r'lambda\s*\(.*,.*\)', |
|
207 | 209 | "tuple parameter unpacking not available in Python 3+"), |
|
208 | 210 | (r'import (.+,[^.]+\.[^.]+|[^.]+\.[^.]+,)', |
|
209 | 211 | '2to3 can\'t always rewrite "import qux, foo.bar", ' |
|
210 | 212 | 'use "import foo.bar" on its own line instead.'), |
|
211 | 213 | (r'(?<!def)\s+(cmp)\(', "cmp is not available in Python 3+"), |
|
212 | 214 | (r'\breduce\s*\(.*', "reduce is not available in Python 3+"), |
|
213 | 215 | (r'dict\(.*=', 'dict() is different in Py2 and 3 and is slower than {}', |
|
214 | 216 | 'dict-from-generator'), |
|
215 | 217 | (r'\.has_key\b', "dict.has_key is not available in Python 3+"), |
|
216 | 218 | (r'\s<>\s', '<> operator is not available in Python 3+, use !='), |
|
217 | 219 | (r'^\s*\t', "don't use tabs"), |
|
218 | 220 | (r'\S;\s*\n', "semicolon"), |
|
219 | 221 | (r'[^_]_\([ \t\n]*(?:"[^"]+"[ \t\n+]*)+%', "don't use % inside _()"), |
|
220 | 222 | (r"[^_]_\([ \t\n]*(?:'[^']+'[ \t\n+]*)+%", "don't use % inside _()"), |
|
221 | 223 | (r'(\w|\)),\w', "missing whitespace after ,"), |
|
222 | 224 | (r'(\w|\))[+/*\-<>]\w', "missing whitespace in expression"), |
|
223 | 225 | (r'^\s+(\w|\.)+=\w[^,()\n]*$', "missing whitespace in assignment"), |
|
224 | 226 | (r'\w\s=\s\s+\w', "gratuitous whitespace after ="), |
|
225 | 227 | (r'.{81}', "line too long"), |
|
226 | 228 | (r' x+[xo][\'"]\n\s+[\'"]x', 'string join across lines with no space'), |
|
227 | 229 | (r'[^\n]\Z', "no trailing newline"), |
|
228 | 230 | (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), |
|
229 | 231 | # (r'^\s+[^_ \n][^_. \n]+_[^_\n]+\s*=', |
|
230 | 232 | # "don't use underbars in identifiers"), |
|
231 | 233 | (r'^\s+(self\.)?[A-za-z][a-z0-9]+[A-Z]\w* = ', |
|
232 | 234 | "don't use camelcase in identifiers"), |
|
233 | 235 | (r'^\s*(if|while|def|class|except|try)\s[^[\n]*:\s*[^\\n]#\s]+', |
|
234 | 236 | "linebreak after :"), |
|
235 | 237 | (r'class\s[^( \n]+:', "old-style class, use class foo(object)"), |
|
236 | 238 | (r'class\s[^( \n]+\(\):', |
|
237 | 239 | "class foo() creates old style object, use class foo(object)"), |
|
238 | 240 | (r'\b(%s)\(' % '|'.join(k for k in keyword.kwlist |
|
239 | 241 | if k not in ('print', 'exec')), |
|
240 | 242 | "Python keyword is not a function"), |
|
241 | 243 | (r',]', "unneeded trailing ',' in list"), |
|
242 | 244 | # (r'class\s[A-Z][^\(]*\((?!Exception)', |
|
243 | 245 | # "don't capitalize non-exception classes"), |
|
244 | 246 | # (r'in range\(', "use xrange"), |
|
245 | 247 | # (r'^\s*print\s+', "avoid using print in core and extensions"), |
|
246 | 248 | (r'[\x80-\xff]', "non-ASCII character literal"), |
|
247 | 249 | (r'("\')\.format\(', "str.format() has no bytes counterpart, use %"), |
|
248 | 250 | (r'^\s*(%s)\s\s' % '|'.join(keyword.kwlist), |
|
249 | 251 | "gratuitous whitespace after Python keyword"), |
|
250 | 252 | (r'([\(\[][ \t]\S)|(\S[ \t][\)\]])', "gratuitous whitespace in () or []"), |
|
251 | 253 | # (r'\s\s=', "gratuitous whitespace before ="), |
|
252 | 254 | (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S', |
|
253 | 255 | "missing whitespace around operator"), |
|
254 | 256 | (r'[^>< ](\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\s', |
|
255 | 257 | "missing whitespace around operator"), |
|
256 | 258 | (r'\s(\+=|-=|!=|<>|<=|>=|<<=|>>=|%=)\S', |
|
257 | 259 | "missing whitespace around operator"), |
|
258 | 260 | (r'[^^+=*/!<>&| %-](\s=|=\s)[^= ]', |
|
259 | 261 | "wrong whitespace around ="), |
|
260 | 262 | (r'\([^()]*( =[^=]|[^<>!=]= )', |
|
261 | 263 | "no whitespace around = for named parameters"), |
|
262 | 264 | (r'raise Exception', "don't raise generic exceptions"), |
|
263 | 265 | (r'raise [^,(]+, (\([^\)]+\)|[^,\(\)]+)$', |
|
264 | 266 | "don't use old-style two-argument raise, use Exception(message)"), |
|
265 | 267 | (r' is\s+(not\s+)?["\'0-9-]', "object comparison with literal"), |
|
266 | 268 | (r' [=!]=\s+(True|False|None)', |
|
267 | 269 | "comparison with singleton, use 'is' or 'is not' instead"), |
|
268 | 270 | (r'^\s*(while|if) [01]:', |
|
269 | 271 | "use True/False for constant Boolean expression"), |
|
270 | 272 | (r'(?:(?<!def)\s+|\()hasattr', |
|
271 | 273 | 'hasattr(foo, bar) is broken, use util.safehasattr(foo, bar) instead'), |
|
272 | 274 | (r'opener\([^)]*\).read\(', |
|
273 | 275 | "use opener.read() instead"), |
|
274 | 276 | (r'opener\([^)]*\).write\(', |
|
275 | 277 | "use opener.write() instead"), |
|
276 | 278 | (r'[\s\(](open|file)\([^)]*\)\.read\(', |
|
277 | 279 | "use util.readfile() instead"), |
|
278 | 280 | (r'[\s\(](open|file)\([^)]*\)\.write\(', |
|
279 | 281 | "use util.writefile() instead"), |
|
280 | 282 | (r'^[\s\(]*(open(er)?|file)\([^)]*\)', |
|
281 | 283 | "always assign an opened file to a variable, and close it afterwards"), |
|
282 | 284 | (r'[\s\(](open|file)\([^)]*\)\.', |
|
283 | 285 | "always assign an opened file to a variable, and close it afterwards"), |
|
284 | 286 | (r'(?i)descend[e]nt', "the proper spelling is descendAnt"), |
|
285 | 287 | (r'\.debug\(\_', "don't mark debug messages for translation"), |
|
286 | 288 | (r'\.strip\(\)\.split\(\)', "no need to strip before splitting"), |
|
287 | 289 | (r'^\s*except\s*:', "naked except clause", r'#.*re-raises'), |
|
288 | 290 | (r'^\s*except\s([^\(,]+|\([^\)]+\))\s*,', |
|
289 | 291 | 'legacy exception syntax; use "as" instead of ","'), |
|
290 | 292 | (r':\n( )*( ){1,3}[^ ]', "must indent 4 spaces"), |
|
291 | 293 | (r'ui\.(status|progress|write|note|warn)\([\'\"]x', |
|
292 | 294 | "missing _() in ui message (use () to hide false-positives)"), |
|
293 | 295 | (r'release\(.*wlock, .*lock\)', "wrong lock release order"), |
|
294 | 296 | (r'\b__bool__\b', "__bool__ should be __nonzero__ in Python 2"), |
|
295 | 297 | (r'os\.path\.join\(.*, *(""|\'\')\)', |
|
296 | 298 | "use pathutil.normasprefix(path) instead of os.path.join(path, '')"), |
|
297 | 299 | (r'\s0[0-7]+\b', 'legacy octal syntax; use "0o" prefix instead of "0"'), |
|
298 | 300 | # XXX only catch mutable arguments on the first line of the definition |
|
299 | 301 | (r'def.*[( ]\w+=\{\}', "don't use mutable default arguments"), |
|
300 | 302 | (r'\butil\.Abort\b', "directly use error.Abort"), |
|
301 | 303 | ], |
|
302 | 304 | # warnings |
|
303 | 305 | [ |
|
304 | 306 | (r'(^| )pp +xxxxqq[ \n][^\n]', "add two newlines after '.. note::'"), |
|
305 | 307 | ] |
|
306 | 308 | ] |
|
307 | 309 | |
|
308 | 310 | pyfilters = [ |
|
309 | 311 | (r"""(?msx)(?P<comment>\#.*?$)| |
|
310 | 312 | ((?P<quote>('''|\"\"\"|(?<!')'(?!')|(?<!")"(?!"))) |
|
311 | 313 | (?P<text>(([^\\]|\\.)*?)) |
|
312 | 314 | (?P=quote))""", reppython), |
|
313 | 315 | ] |
|
314 | 316 | |
|
315 | 317 | txtfilters = [] |
|
316 | 318 | |
|
317 | 319 | txtpats = [ |
|
318 | 320 | [ |
|
319 | 321 | ('\s$', 'trailing whitespace'), |
|
320 | 322 | ('.. note::[ \n][^\n]', 'add two newlines after note::') |
|
321 | 323 | ], |
|
322 | 324 | [] |
|
323 | 325 | ] |
|
324 | 326 | |
|
325 | 327 | cpats = [ |
|
326 | 328 | [ |
|
327 | 329 | (r'//', "don't use //-style comments"), |
|
328 | 330 | (r'^ ', "don't use spaces to indent"), |
|
329 | 331 | (r'\S\t', "don't use tabs except for indent"), |
|
330 | 332 | (r'(\S[ \t]+|^[ \t]+)\n', "trailing whitespace"), |
|
331 | 333 | (r'.{81}', "line too long"), |
|
332 | 334 | (r'(while|if|do|for)\(', "use space after while/if/do/for"), |
|
333 | 335 | (r'return\(', "return is not a function"), |
|
334 | 336 | (r' ;', "no space before ;"), |
|
335 | 337 | (r'[^;] \)', "no space before )"), |
|
336 | 338 | (r'[)][{]', "space between ) and {"), |
|
337 | 339 | (r'\w+\* \w+', "use int *foo, not int* foo"), |
|
338 | 340 | (r'\W\([^\)]+\) \w+', "use (int)foo, not (int) foo"), |
|
339 | 341 | (r'\w+ (\+\+|--)', "use foo++, not foo ++"), |
|
340 | 342 | (r'\w,\w', "missing whitespace after ,"), |
|
341 | 343 | (r'^[^#]\w[+/*]\w', "missing whitespace in expression"), |
|
342 | 344 | (r'\w\s=\s\s+\w', "gratuitous whitespace after ="), |
|
343 | 345 | (r'^#\s+\w', "use #foo, not # foo"), |
|
344 | 346 | (r'[^\n]\Z', "no trailing newline"), |
|
345 | 347 | (r'^\s*#import\b', "use only #include in standard C code"), |
|
346 | 348 | ], |
|
347 | 349 | # warnings |
|
348 | 350 | [] |
|
349 | 351 | ] |
|
350 | 352 | |
|
351 | 353 | cfilters = [ |
|
352 | 354 | (r'(/\*)(((\*(?!/))|[^*])*)\*/', repccomment), |
|
353 | 355 | (r'''(?P<quote>(?<!")")(?P<text>([^"]|\\")+)"(?!")''', repquote), |
|
354 | 356 | (r'''(#\s*include\s+<)([^>]+)>''', repinclude), |
|
355 | 357 | (r'(\()([^)]+\))', repcallspaces), |
|
356 | 358 | ] |
|
357 | 359 | |
|
358 | 360 | inutilpats = [ |
|
359 | 361 | [ |
|
360 | 362 | (r'\bui\.', "don't use ui in util"), |
|
361 | 363 | ], |
|
362 | 364 | # warnings |
|
363 | 365 | [] |
|
364 | 366 | ] |
|
365 | 367 | |
|
366 | 368 | inrevlogpats = [ |
|
367 | 369 | [ |
|
368 | 370 | (r'\brepo\.', "don't use repo in revlog"), |
|
369 | 371 | ], |
|
370 | 372 | # warnings |
|
371 | 373 | [] |
|
372 | 374 | ] |
|
373 | 375 | |
|
374 | 376 | webtemplatefilters = [] |
|
375 | 377 | |
|
376 | 378 | webtemplatepats = [ |
|
377 | 379 | [], |
|
378 | 380 | [ |
|
379 | 381 | (r'{desc(\|(?!websub|firstline)[^\|]*)+}', |
|
380 | 382 | 'follow desc keyword with either firstline or websub'), |
|
381 | 383 | ] |
|
382 | 384 | ] |
|
383 | 385 | |
|
384 | 386 | checks = [ |
|
385 | 387 | ('python', r'.*\.(py|cgi)$', r'^#!.*python', pyfilters, pypats), |
|
386 | 388 | ('test script', r'(.*/)?test-[^.~]*$', '', testfilters, testpats), |
|
387 | 389 | ('c', r'.*\.[ch]$', '', cfilters, cpats), |
|
388 | 390 | ('unified test', r'.*\.t$', '', utestfilters, utestpats), |
|
389 | 391 | ('layering violation repo in revlog', r'mercurial/revlog\.py', '', |
|
390 | 392 | pyfilters, inrevlogpats), |
|
391 | 393 | ('layering violation ui in util', r'mercurial/util\.py', '', pyfilters, |
|
392 | 394 | inutilpats), |
|
393 | 395 | ('txt', r'.*\.txt$', '', txtfilters, txtpats), |
|
394 | 396 | ('web template', r'mercurial/templates/.*\.tmpl', '', |
|
395 | 397 | webtemplatefilters, webtemplatepats), |
|
396 | 398 | ] |
|
397 | 399 | |
|
398 | 400 | def _preparepats(): |
|
399 | 401 | for c in checks: |
|
400 | 402 | failandwarn = c[-1] |
|
401 | 403 | for pats in failandwarn: |
|
402 | 404 | for i, pseq in enumerate(pats): |
|
403 | 405 | # fix-up regexes for multi-line searches |
|
404 | 406 | p = pseq[0] |
|
405 | 407 | # \s doesn't match \n |
|
406 | 408 | p = re.sub(r'(?<!\\)\\s', r'[ \\t]', p) |
|
407 | 409 | # [^...] doesn't match newline |
|
408 | 410 | p = re.sub(r'(?<!\\)\[\^', r'[^\\n', p) |
|
409 | 411 | |
|
410 | 412 | pats[i] = (re.compile(p, re.MULTILINE),) + pseq[1:] |
|
411 | 413 | filters = c[3] |
|
412 | 414 | for i, flt in enumerate(filters): |
|
413 | 415 | filters[i] = re.compile(flt[0]), flt[1] |
|
414 | 416 | _preparepats() |
|
415 | 417 | |
|
416 | 418 | class norepeatlogger(object): |
|
417 | 419 | def __init__(self): |
|
418 | 420 | self._lastseen = None |
|
419 | 421 | |
|
420 | 422 | def log(self, fname, lineno, line, msg, blame): |
|
421 | 423 | """print error related a to given line of a given file. |
|
422 | 424 | |
|
423 | 425 | The faulty line will also be printed but only once in the case |
|
424 | 426 | of multiple errors. |
|
425 | 427 | |
|
426 | 428 | :fname: filename |
|
427 | 429 | :lineno: line number |
|
428 | 430 | :line: actual content of the line |
|
429 | 431 | :msg: error message |
|
430 | 432 | """ |
|
431 | 433 | msgid = fname, lineno, line |
|
432 | 434 | if msgid != self._lastseen: |
|
433 | 435 | if blame: |
|
434 | 436 | print "%s:%d (%s):" % (fname, lineno, blame) |
|
435 | 437 | else: |
|
436 | 438 | print "%s:%d:" % (fname, lineno) |
|
437 | 439 | print " > %s" % line |
|
438 | 440 | self._lastseen = msgid |
|
439 | 441 | print " " + msg |
|
440 | 442 | |
|
441 | 443 | _defaultlogger = norepeatlogger() |
|
442 | 444 | |
|
443 | 445 | def getblame(f): |
|
444 | 446 | lines = [] |
|
445 | 447 | for l in os.popen('hg annotate -un %s' % f): |
|
446 | 448 | start, line = l.split(':', 1) |
|
447 | 449 | user, rev = start.split() |
|
448 | 450 | lines.append((line[1:-1], user, rev)) |
|
449 | 451 | return lines |
|
450 | 452 | |
|
451 | 453 | def checkfile(f, logfunc=_defaultlogger.log, maxerr=None, warnings=False, |
|
452 | 454 | blame=False, debug=False, lineno=True): |
|
453 | 455 | """checks style and portability of a given file |
|
454 | 456 | |
|
455 | 457 | :f: filepath |
|
456 | 458 | :logfunc: function used to report error |
|
457 | 459 | logfunc(filename, linenumber, linecontent, errormessage) |
|
458 | 460 | :maxerr: number of error to display before aborting. |
|
459 | 461 | Set to false (default) to report all errors |
|
460 | 462 | |
|
461 | 463 | return True if no error is found, False otherwise. |
|
462 | 464 | """ |
|
463 | 465 | blamecache = None |
|
464 | 466 | result = True |
|
465 | 467 | |
|
466 | 468 | try: |
|
467 | 469 | fp = open(f) |
|
468 | 470 | except IOError as e: |
|
469 | 471 | print "Skipping %s, %s" % (f, str(e).split(':', 1)[0]) |
|
470 | 472 | return result |
|
471 | 473 | pre = post = fp.read() |
|
472 | 474 | fp.close() |
|
473 | 475 | |
|
474 | 476 | for name, match, magic, filters, pats in checks: |
|
475 | 477 | if debug: |
|
476 | 478 | print name, f |
|
477 | 479 | fc = 0 |
|
478 | 480 | if not (re.match(match, f) or (magic and re.search(magic, f))): |
|
479 | 481 | if debug: |
|
480 | 482 | print "Skipping %s for %s it doesn't match %s" % ( |
|
481 | 483 | name, match, f) |
|
482 | 484 | continue |
|
483 | 485 | if "no-" "check-code" in pre: |
|
484 | 486 | # If you're looking at this line, it's because a file has: |
|
485 | 487 | # no- check- code |
|
486 | 488 | # but the reason to output skipping is to make life for |
|
487 | 489 | # tests easier. So, instead of writing it with a normal |
|
488 | 490 | # spelling, we write it with the expected spelling from |
|
489 | 491 | # tests/test-check-code.t |
|
490 | 492 | print "Skipping %s it has no-che?k-code (glob)" % f |
|
491 | 493 | return "Skip" # skip checking this file |
|
492 | 494 | for p, r in filters: |
|
493 | 495 | post = re.sub(p, r, post) |
|
494 | 496 | nerrs = len(pats[0]) # nerr elements are errors |
|
495 | 497 | if warnings: |
|
496 | 498 | pats = pats[0] + pats[1] |
|
497 | 499 | else: |
|
498 | 500 | pats = pats[0] |
|
499 | 501 | # print post # uncomment to show filtered version |
|
500 | 502 | |
|
501 | 503 | if debug: |
|
502 | 504 | print "Checking %s for %s" % (name, f) |
|
503 | 505 | |
|
504 | 506 | prelines = None |
|
505 | 507 | errors = [] |
|
506 | 508 | for i, pat in enumerate(pats): |
|
507 | 509 | if len(pat) == 3: |
|
508 | 510 | p, msg, ignore = pat |
|
509 | 511 | else: |
|
510 | 512 | p, msg = pat |
|
511 | 513 | ignore = None |
|
512 | 514 | if i >= nerrs: |
|
513 | 515 | msg = "warning: " + msg |
|
514 | 516 | |
|
515 | 517 | pos = 0 |
|
516 | 518 | n = 0 |
|
517 | 519 | for m in p.finditer(post): |
|
518 | 520 | if prelines is None: |
|
519 | 521 | prelines = pre.splitlines() |
|
520 | 522 | postlines = post.splitlines(True) |
|
521 | 523 | |
|
522 | 524 | start = m.start() |
|
523 | 525 | while n < len(postlines): |
|
524 | 526 | step = len(postlines[n]) |
|
525 | 527 | if pos + step > start: |
|
526 | 528 | break |
|
527 | 529 | pos += step |
|
528 | 530 | n += 1 |
|
529 | 531 | l = prelines[n] |
|
530 | 532 | |
|
531 | 533 | if ignore and re.search(ignore, l, re.MULTILINE): |
|
532 | 534 | if debug: |
|
533 | 535 | print "Skipping %s for %s:%s (ignore pattern)" % ( |
|
534 | 536 | name, f, n) |
|
535 | 537 | continue |
|
536 | 538 | bd = "" |
|
537 | 539 | if blame: |
|
538 | 540 | bd = 'working directory' |
|
539 | 541 | if not blamecache: |
|
540 | 542 | blamecache = getblame(f) |
|
541 | 543 | if n < len(blamecache): |
|
542 | 544 | bl, bu, br = blamecache[n] |
|
543 | 545 | if bl == l: |
|
544 | 546 | bd = '%s@%s' % (bu, br) |
|
545 | 547 | |
|
546 | 548 | errors.append((f, lineno and n + 1, l, msg, bd)) |
|
547 | 549 | result = False |
|
548 | 550 | |
|
549 | 551 | errors.sort() |
|
550 | 552 | for e in errors: |
|
551 | 553 | logfunc(*e) |
|
552 | 554 | fc += 1 |
|
553 | 555 | if maxerr and fc >= maxerr: |
|
554 | 556 | print " (too many errors, giving up)" |
|
555 | 557 | break |
|
556 | 558 | |
|
557 | 559 | return result |
|
558 | 560 | |
|
559 | 561 | if __name__ == "__main__": |
|
560 | 562 | parser = optparse.OptionParser("%prog [options] [files]") |
|
561 | 563 | parser.add_option("-w", "--warnings", action="store_true", |
|
562 | 564 | help="include warning-level checks") |
|
563 | 565 | parser.add_option("-p", "--per-file", type="int", |
|
564 | 566 | help="max warnings per file") |
|
565 | 567 | parser.add_option("-b", "--blame", action="store_true", |
|
566 | 568 | help="use annotate to generate blame info") |
|
567 | 569 | parser.add_option("", "--debug", action="store_true", |
|
568 | 570 | help="show debug information") |
|
569 | 571 | parser.add_option("", "--nolineno", action="store_false", |
|
570 | 572 | dest='lineno', help="don't show line numbers") |
|
571 | 573 | |
|
572 | 574 | parser.set_defaults(per_file=15, warnings=False, blame=False, debug=False, |
|
573 | 575 | lineno=True) |
|
574 | 576 | (options, args) = parser.parse_args() |
|
575 | 577 | |
|
576 | 578 | if len(args) == 0: |
|
577 | 579 | check = glob.glob("*") |
|
578 | 580 | else: |
|
579 | 581 | check = args |
|
580 | 582 | |
|
581 | 583 | ret = 0 |
|
582 | 584 | for f in check: |
|
583 | 585 | if not checkfile(f, maxerr=options.per_file, warnings=options.warnings, |
|
584 | 586 | blame=options.blame, debug=options.debug, |
|
585 | 587 | lineno=options.lineno): |
|
586 | 588 | ret = 1 |
|
587 | 589 | sys.exit(ret) |
@@ -1,830 +1,836 | |||
|
1 | $ cat >> $HGRCPATH <<EOF | |
|
2 | > [defaults] | |
|
3 | > # for portability | |
|
4 | > extdiff = --option -Nru | |
|
5 | > EOF | |
|
6 | ||
|
1 | 7 | Create a repo with some stuff in it: |
|
2 | 8 | |
|
3 | 9 | $ hg init a |
|
4 | 10 | $ cd a |
|
5 | 11 | $ echo a > a |
|
6 | 12 | $ echo a > d |
|
7 | 13 | $ echo a > e |
|
8 | 14 | $ hg ci -qAm0 |
|
9 | 15 | $ echo b > a |
|
10 | 16 | $ hg ci -m1 -u bar |
|
11 | 17 | $ hg mv a b |
|
12 | 18 | $ hg ci -m2 |
|
13 | 19 | $ hg cp b c |
|
14 | 20 | $ hg ci -m3 -u baz |
|
15 | 21 | $ echo b > d |
|
16 | 22 | $ echo f > e |
|
17 | 23 | $ hg ci -m4 |
|
18 | 24 | $ hg up -q 3 |
|
19 | 25 | $ echo b > e |
|
20 | 26 | $ hg branch -q stable |
|
21 | 27 | $ hg ci -m5 |
|
22 | 28 | $ hg merge -q default --tool internal:local |
|
23 | 29 |
$ |
|
24 | 30 | $ hg ci -m6 |
|
25 | 31 | $ hg phase --public 3 |
|
26 | 32 | $ hg phase --force --secret 6 |
|
27 | 33 | |
|
28 | 34 | $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n' |
|
29 | 35 | @ test@6.secret: 6 |
|
30 | 36 | |\ |
|
31 | 37 | | o test@5.draft: 5 |
|
32 | 38 | | | |
|
33 | 39 | o | test@4.draft: 4 |
|
34 | 40 | |/ |
|
35 | 41 | o baz@3.public: 3 |
|
36 | 42 | | |
|
37 | 43 | o test@2.public: 2 |
|
38 | 44 | | |
|
39 | 45 | o bar@1.public: 1 |
|
40 | 46 | | |
|
41 | 47 | o test@0.public: 0 |
|
42 | 48 | |
|
43 | 49 | |
|
44 | 50 | Need to specify a rev: |
|
45 | 51 | |
|
46 | 52 | $ hg graft |
|
47 | 53 | abort: no revisions specified |
|
48 | 54 | [255] |
|
49 | 55 | |
|
50 | 56 | Can't graft ancestor: |
|
51 | 57 | |
|
52 | 58 | $ hg graft 1 2 |
|
53 | 59 | skipping ancestor revision 1:5d205f8b35b6 |
|
54 | 60 | skipping ancestor revision 2:5c095ad7e90f |
|
55 | 61 | [255] |
|
56 | 62 | |
|
57 | 63 | Specify revisions with -r: |
|
58 | 64 | |
|
59 | 65 | $ hg graft -r 1 -r 2 |
|
60 | 66 | skipping ancestor revision 1:5d205f8b35b6 |
|
61 | 67 | skipping ancestor revision 2:5c095ad7e90f |
|
62 | 68 | [255] |
|
63 | 69 | |
|
64 | 70 | $ hg graft -r 1 2 |
|
65 | 71 | warning: inconsistent use of --rev might give unexpected revision ordering! |
|
66 | 72 | skipping ancestor revision 2:5c095ad7e90f |
|
67 | 73 | skipping ancestor revision 1:5d205f8b35b6 |
|
68 | 74 | [255] |
|
69 | 75 | |
|
70 | 76 | Can't graft with dirty wd: |
|
71 | 77 | |
|
72 | 78 | $ hg up -q 0 |
|
73 | 79 | $ echo foo > a |
|
74 | 80 | $ hg graft 1 |
|
75 | 81 | abort: uncommitted changes |
|
76 | 82 | [255] |
|
77 | 83 | $ hg revert a |
|
78 | 84 | |
|
79 | 85 | Graft a rename: |
|
80 | 86 | (this also tests that editor is invoked if '--edit' is specified) |
|
81 | 87 | |
|
82 | 88 | $ hg status --rev "2^1" --rev 2 |
|
83 | 89 | A b |
|
84 | 90 | R a |
|
85 | 91 | $ HGEDITOR=cat hg graft 2 -u foo --edit |
|
86 | 92 | grafting 2:5c095ad7e90f "2" |
|
87 | 93 | merging a and b to b |
|
88 | 94 | 2 |
|
89 | 95 | |
|
90 | 96 | |
|
91 | 97 | HG: Enter commit message. Lines beginning with 'HG:' are removed. |
|
92 | 98 | HG: Leave message empty to abort commit. |
|
93 | 99 | HG: -- |
|
94 | 100 | HG: user: foo |
|
95 | 101 | HG: branch 'default' |
|
96 | 102 | HG: added b |
|
97 | 103 | HG: removed a |
|
98 | 104 | $ hg export tip --git |
|
99 | 105 | # HG changeset patch |
|
100 | 106 | # User foo |
|
101 | 107 | # Date 0 0 |
|
102 | 108 | # Thu Jan 01 00:00:00 1970 +0000 |
|
103 | 109 | # Node ID ef0ef43d49e79e81ddafdc7997401ba0041efc82 |
|
104 | 110 | # Parent 68795b066622ca79a25816a662041d8f78f3cd9e |
|
105 | 111 | 2 |
|
106 | 112 | |
|
107 | 113 | diff --git a/a b/b |
|
108 | 114 | rename from a |
|
109 | 115 | rename to b |
|
110 | 116 | |
|
111 | 117 | Look for extra:source |
|
112 | 118 | |
|
113 | 119 | $ hg log --debug -r tip |
|
114 | 120 | changeset: 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82 |
|
115 | 121 | tag: tip |
|
116 | 122 | phase: draft |
|
117 | 123 | parent: 0:68795b066622ca79a25816a662041d8f78f3cd9e |
|
118 | 124 | parent: -1:0000000000000000000000000000000000000000 |
|
119 | 125 | manifest: 7:e59b6b228f9cbf9903d5e9abf996e083a1f533eb |
|
120 | 126 | user: foo |
|
121 | 127 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
122 | 128 | files+: b |
|
123 | 129 | files-: a |
|
124 | 130 | extra: branch=default |
|
125 | 131 | extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4 |
|
126 | 132 | description: |
|
127 | 133 | 2 |
|
128 | 134 | |
|
129 | 135 | |
|
130 | 136 | |
|
131 | 137 | Graft out of order, skipping a merge and a duplicate |
|
132 | 138 | (this also tests that editor is not invoked if '--edit' is not specified) |
|
133 | 139 | |
|
134 | 140 | $ hg graft 1 5 4 3 'merge()' 2 -n |
|
135 | 141 | skipping ungraftable merge revision 6 |
|
136 | 142 | skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7) |
|
137 | 143 | grafting 1:5d205f8b35b6 "1" |
|
138 | 144 | grafting 5:97f8bfe72746 "5" |
|
139 | 145 | grafting 4:9c233e8e184d "4" |
|
140 | 146 | grafting 3:4c60f11aa304 "3" |
|
141 | 147 | |
|
142 | 148 | $ HGEDITOR=cat hg graft 1 5 'merge()' 2 --debug |
|
143 | 149 | skipping ungraftable merge revision 6 |
|
144 | 150 | scanning for duplicate grafts |
|
145 | 151 | skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7) |
|
146 | 152 | grafting 1:5d205f8b35b6 "1" |
|
147 | 153 | searching for copies back to rev 1 |
|
148 | 154 | unmatched files in local: |
|
149 | 155 | b |
|
150 | 156 | all copies found (* = to merge, ! = divergent, % = renamed and deleted): |
|
151 | 157 | src: 'a' -> dst: 'b' * |
|
152 | 158 | checking for directory renames |
|
153 | 159 | resolving manifests |
|
154 | 160 | branchmerge: True, force: True, partial: False |
|
155 | 161 | ancestor: 68795b066622, local: ef0ef43d49e7+, remote: 5d205f8b35b6 |
|
156 | 162 | preserving b for resolve of b |
|
157 | 163 | b: local copied/moved from a -> m (premerge) |
|
158 | 164 | picked tool ':merge' for b (binary False symlink False changedelete False) |
|
159 | 165 | merging b and a to b |
|
160 | 166 | my b@ef0ef43d49e7+ other a@5d205f8b35b6 ancestor a@68795b066622 |
|
161 | 167 | premerge successful |
|
162 | 168 | committing files: |
|
163 | 169 | b |
|
164 | 170 | committing manifest |
|
165 | 171 | committing changelog |
|
166 | 172 | grafting 5:97f8bfe72746 "5" |
|
167 | 173 | searching for copies back to rev 1 |
|
168 | 174 | resolving manifests |
|
169 | 175 | branchmerge: True, force: True, partial: False |
|
170 | 176 | ancestor: 4c60f11aa304, local: 6b9e5368ca4e+, remote: 97f8bfe72746 |
|
171 | 177 | e: remote is newer -> g |
|
172 | 178 | getting e |
|
173 | 179 | b: remote unchanged -> k |
|
174 | 180 | committing files: |
|
175 | 181 | e |
|
176 | 182 | committing manifest |
|
177 | 183 | committing changelog |
|
178 | 184 | $ HGEDITOR=cat hg graft 4 3 --log --debug |
|
179 | 185 | scanning for duplicate grafts |
|
180 | 186 | grafting 4:9c233e8e184d "4" |
|
181 | 187 | searching for copies back to rev 1 |
|
182 | 188 | resolving manifests |
|
183 | 189 | branchmerge: True, force: True, partial: False |
|
184 | 190 | ancestor: 4c60f11aa304, local: 1905859650ec+, remote: 9c233e8e184d |
|
185 | 191 | preserving e for resolve of e |
|
186 | 192 | d: remote is newer -> g |
|
187 | 193 | getting d |
|
188 | 194 | b: remote unchanged -> k |
|
189 | 195 | e: versions differ -> m (premerge) |
|
190 | 196 | picked tool ':merge' for e (binary False symlink False changedelete False) |
|
191 | 197 | merging e |
|
192 | 198 | my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304 |
|
193 | 199 | e: versions differ -> m (merge) |
|
194 | 200 | picked tool ':merge' for e (binary False symlink False changedelete False) |
|
195 | 201 | my e@1905859650ec+ other e@9c233e8e184d ancestor e@4c60f11aa304 |
|
196 | 202 | warning: conflicts while merging e! (edit, then use 'hg resolve --mark') |
|
197 | 203 | abort: unresolved conflicts, can't continue |
|
198 | 204 | (use hg resolve and hg graft --continue --log) |
|
199 | 205 | [255] |
|
200 | 206 | |
|
201 | 207 | Summary should mention graft: |
|
202 | 208 | |
|
203 | 209 | $ hg summary |grep graft |
|
204 | 210 | commit: 2 modified, 2 unknown, 1 unresolved (graft in progress) |
|
205 | 211 | |
|
206 | 212 | Commit while interrupted should fail: |
|
207 | 213 | |
|
208 | 214 | $ hg ci -m 'commit interrupted graft' |
|
209 | 215 | abort: graft in progress |
|
210 | 216 | (use 'hg graft --continue' or 'hg update' to abort) |
|
211 | 217 | [255] |
|
212 | 218 | |
|
213 | 219 | Abort the graft and try committing: |
|
214 | 220 | |
|
215 | 221 | $ hg up -C . |
|
216 | 222 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
217 | 223 | $ echo c >> e |
|
218 | 224 | $ hg ci -mtest |
|
219 | 225 | |
|
220 | 226 | $ hg strip . --config extensions.strip= |
|
221 | 227 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
222 | 228 | saved backup bundle to $TESTTMP/a/.hg/strip-backup/*-backup.hg (glob) |
|
223 | 229 | |
|
224 | 230 | Graft again: |
|
225 | 231 | |
|
226 | 232 | $ hg graft 1 5 4 3 'merge()' 2 |
|
227 | 233 | skipping ungraftable merge revision 6 |
|
228 | 234 | skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7) |
|
229 | 235 | skipping revision 1:5d205f8b35b6 (already grafted to 8:6b9e5368ca4e) |
|
230 | 236 | skipping revision 5:97f8bfe72746 (already grafted to 9:1905859650ec) |
|
231 | 237 | grafting 4:9c233e8e184d "4" |
|
232 | 238 | merging e |
|
233 | 239 | warning: conflicts while merging e! (edit, then use 'hg resolve --mark') |
|
234 | 240 | abort: unresolved conflicts, can't continue |
|
235 | 241 | (use hg resolve and hg graft --continue) |
|
236 | 242 | [255] |
|
237 | 243 | |
|
238 | 244 | Continue without resolve should fail: |
|
239 | 245 | |
|
240 | 246 | $ hg graft -c |
|
241 | 247 | grafting 4:9c233e8e184d "4" |
|
242 | 248 | abort: unresolved merge conflicts (see "hg help resolve") |
|
243 | 249 | [255] |
|
244 | 250 | |
|
245 | 251 | Fix up: |
|
246 | 252 | |
|
247 | 253 | $ echo b > e |
|
248 | 254 | $ hg resolve -m e |
|
249 | 255 | (no more unresolved files) |
|
250 | 256 | continue: hg graft --continue |
|
251 | 257 | |
|
252 | 258 | Continue with a revision should fail: |
|
253 | 259 | |
|
254 | 260 | $ hg graft -c 6 |
|
255 | 261 | abort: can't specify --continue and revisions |
|
256 | 262 | [255] |
|
257 | 263 | |
|
258 | 264 | $ hg graft -c -r 6 |
|
259 | 265 | abort: can't specify --continue and revisions |
|
260 | 266 | [255] |
|
261 | 267 | |
|
262 | 268 | Continue for real, clobber usernames |
|
263 | 269 | |
|
264 | 270 | $ hg graft -c -U |
|
265 | 271 | grafting 4:9c233e8e184d "4" |
|
266 | 272 | grafting 3:4c60f11aa304 "3" |
|
267 | 273 | |
|
268 | 274 | Compare with original: |
|
269 | 275 | |
|
270 | 276 | $ hg diff -r 6 |
|
271 | 277 | $ hg status --rev 0:. -C |
|
272 | 278 | M d |
|
273 | 279 | M e |
|
274 | 280 | A b |
|
275 | 281 | a |
|
276 | 282 | A c |
|
277 | 283 | a |
|
278 | 284 | R a |
|
279 | 285 | |
|
280 | 286 | View graph: |
|
281 | 287 | |
|
282 | 288 | $ hg log -G --template '{author}@{rev}.{phase}: {desc}\n' |
|
283 | 289 | @ test@11.draft: 3 |
|
284 | 290 | | |
|
285 | 291 | o test@10.draft: 4 |
|
286 | 292 | | |
|
287 | 293 | o test@9.draft: 5 |
|
288 | 294 | | |
|
289 | 295 | o bar@8.draft: 1 |
|
290 | 296 | | |
|
291 | 297 | o foo@7.draft: 2 |
|
292 | 298 | | |
|
293 | 299 | | o test@6.secret: 6 |
|
294 | 300 | | |\ |
|
295 | 301 | | | o test@5.draft: 5 |
|
296 | 302 | | | | |
|
297 | 303 | | o | test@4.draft: 4 |
|
298 | 304 | | |/ |
|
299 | 305 | | o baz@3.public: 3 |
|
300 | 306 | | | |
|
301 | 307 | | o test@2.public: 2 |
|
302 | 308 | | | |
|
303 | 309 | | o bar@1.public: 1 |
|
304 | 310 | |/ |
|
305 | 311 | o test@0.public: 0 |
|
306 | 312 | |
|
307 | 313 | Graft again onto another branch should preserve the original source |
|
308 | 314 | $ hg up -q 0 |
|
309 | 315 | $ echo 'g'>g |
|
310 | 316 | $ hg add g |
|
311 | 317 | $ hg ci -m 7 |
|
312 | 318 | created new head |
|
313 | 319 | $ hg graft 7 |
|
314 | 320 | grafting 7:ef0ef43d49e7 "2" |
|
315 | 321 | |
|
316 | 322 | $ hg log -r 7 --template '{rev}:{node}\n' |
|
317 | 323 | 7:ef0ef43d49e79e81ddafdc7997401ba0041efc82 |
|
318 | 324 | $ hg log -r 2 --template '{rev}:{node}\n' |
|
319 | 325 | 2:5c095ad7e90f871700f02dd1fa5012cb4498a2d4 |
|
320 | 326 | |
|
321 | 327 | $ hg log --debug -r tip |
|
322 | 328 | changeset: 13:7a4785234d87ec1aa420ed6b11afe40fa73e12a9 |
|
323 | 329 | tag: tip |
|
324 | 330 | phase: draft |
|
325 | 331 | parent: 12:b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f |
|
326 | 332 | parent: -1:0000000000000000000000000000000000000000 |
|
327 | 333 | manifest: 13:dc313617b8c32457c0d589e0dbbedfe71f3cd637 |
|
328 | 334 | user: foo |
|
329 | 335 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
330 | 336 | files+: b |
|
331 | 337 | files-: a |
|
332 | 338 | extra: branch=default |
|
333 | 339 | extra: intermediate-source=ef0ef43d49e79e81ddafdc7997401ba0041efc82 |
|
334 | 340 | extra: source=5c095ad7e90f871700f02dd1fa5012cb4498a2d4 |
|
335 | 341 | description: |
|
336 | 342 | 2 |
|
337 | 343 | |
|
338 | 344 | |
|
339 | 345 | Disallow grafting an already grafted cset onto its original branch |
|
340 | 346 | $ hg up -q 6 |
|
341 | 347 | $ hg graft 7 |
|
342 | 348 | skipping already grafted revision 7:ef0ef43d49e7 (was grafted from 2:5c095ad7e90f) |
|
343 | 349 | [255] |
|
344 | 350 | |
|
345 | 351 | $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 |
|
346 | 352 | --- */hg-5c095ad7e90f.patch * +0000 (glob) |
|
347 | 353 | +++ */hg-7a4785234d87.patch * +0000 (glob) |
|
348 | 354 | @@ -1,18 +1,18 @@ |
|
349 | 355 | # HG changeset patch |
|
350 | 356 | -# User test |
|
351 | 357 | +# User foo |
|
352 | 358 | # Date 0 0 |
|
353 | 359 | # Thu Jan 01 00:00:00 1970 +0000 |
|
354 | 360 | -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4 |
|
355 | 361 | -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04 |
|
356 | 362 | +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9 |
|
357 | 363 | +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f |
|
358 | 364 | 2 |
|
359 | 365 | |
|
360 | 366 | -diff -r 5d205f8b35b6 -r 5c095ad7e90f a |
|
361 | 367 | +diff -r b592ea63bb0c -r 7a4785234d87 a |
|
362 | 368 | --- a/a Thu Jan 01 00:00:00 1970 +0000 |
|
363 | 369 | +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|
364 | 370 | @@ -1,1 +0,0 @@ |
|
365 | 371 | --b |
|
366 | 372 | -diff -r 5d205f8b35b6 -r 5c095ad7e90f b |
|
367 | 373 | +-a |
|
368 | 374 | +diff -r b592ea63bb0c -r 7a4785234d87 b |
|
369 | 375 | --- /dev/null Thu Jan 01 00:00:00 1970 +0000 |
|
370 | 376 | +++ b/b Thu Jan 01 00:00:00 1970 +0000 |
|
371 | 377 | @@ -0,0 +1,1 @@ |
|
372 | 378 | -+b |
|
373 | 379 | ++a |
|
374 | 380 | [1] |
|
375 | 381 | |
|
376 | 382 | $ hg extdiff --config extensions.extdiff= --patch -r 2 -r 13 -X . |
|
377 | 383 | --- */hg-5c095ad7e90f.patch * +0000 (glob) |
|
378 | 384 | +++ */hg-7a4785234d87.patch * +0000 (glob) |
|
379 | 385 | @@ -1,8 +1,8 @@ |
|
380 | 386 | # HG changeset patch |
|
381 | 387 | -# User test |
|
382 | 388 | +# User foo |
|
383 | 389 | # Date 0 0 |
|
384 | 390 | # Thu Jan 01 00:00:00 1970 +0000 |
|
385 | 391 | -# Node ID 5c095ad7e90f871700f02dd1fa5012cb4498a2d4 |
|
386 | 392 | -# Parent 5d205f8b35b66bc36375c9534ffd3237730e8f04 |
|
387 | 393 | +# Node ID 7a4785234d87ec1aa420ed6b11afe40fa73e12a9 |
|
388 | 394 | +# Parent b592ea63bb0c19a6c5c44685ee29a2284f9f1b8f |
|
389 | 395 | 2 |
|
390 | 396 | |
|
391 | 397 | [1] |
|
392 | 398 | |
|
393 | 399 | Disallow grafting already grafted csets with the same origin onto each other |
|
394 | 400 | $ hg up -q 13 |
|
395 | 401 | $ hg graft 2 |
|
396 | 402 | skipping revision 2:5c095ad7e90f (already grafted to 13:7a4785234d87) |
|
397 | 403 | [255] |
|
398 | 404 | $ hg graft 7 |
|
399 | 405 | skipping already grafted revision 7:ef0ef43d49e7 (13:7a4785234d87 also has origin 2:5c095ad7e90f) |
|
400 | 406 | [255] |
|
401 | 407 | |
|
402 | 408 | $ hg up -q 7 |
|
403 | 409 | $ hg graft 2 |
|
404 | 410 | skipping revision 2:5c095ad7e90f (already grafted to 7:ef0ef43d49e7) |
|
405 | 411 | [255] |
|
406 | 412 | $ hg graft tip |
|
407 | 413 | skipping already grafted revision 13:7a4785234d87 (7:ef0ef43d49e7 also has origin 2:5c095ad7e90f) |
|
408 | 414 | [255] |
|
409 | 415 | |
|
410 | 416 | Graft with --log |
|
411 | 417 | |
|
412 | 418 | $ hg up -Cq 1 |
|
413 | 419 | $ hg graft 3 --log -u foo |
|
414 | 420 | grafting 3:4c60f11aa304 "3" |
|
415 | 421 | warning: can't find ancestor for 'c' copied from 'b'! |
|
416 | 422 | $ hg log --template '{rev} {parents} {desc}\n' -r tip |
|
417 | 423 | 14 1:5d205f8b35b6 3 |
|
418 | 424 | (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8) |
|
419 | 425 | |
|
420 | 426 | Resolve conflicted graft |
|
421 | 427 | $ hg up -q 0 |
|
422 | 428 | $ echo b > a |
|
423 | 429 | $ hg ci -m 8 |
|
424 | 430 | created new head |
|
425 | 431 | $ echo c > a |
|
426 | 432 | $ hg ci -m 9 |
|
427 | 433 | $ hg graft 1 --tool internal:fail |
|
428 | 434 | grafting 1:5d205f8b35b6 "1" |
|
429 | 435 | abort: unresolved conflicts, can't continue |
|
430 | 436 | (use hg resolve and hg graft --continue) |
|
431 | 437 | [255] |
|
432 | 438 | $ hg resolve --all |
|
433 | 439 | merging a |
|
434 | 440 | warning: conflicts while merging a! (edit, then use 'hg resolve --mark') |
|
435 | 441 | [1] |
|
436 | 442 | $ cat a |
|
437 | 443 | <<<<<<< local: aaa4406d4f0a - test: 9 |
|
438 | 444 | c |
|
439 | 445 | ======= |
|
440 | 446 | b |
|
441 | 447 | >>>>>>> other: 5d205f8b35b6 - bar: 1 |
|
442 | 448 | $ echo b > a |
|
443 | 449 | $ hg resolve -m a |
|
444 | 450 | (no more unresolved files) |
|
445 | 451 | continue: hg graft --continue |
|
446 | 452 | $ hg graft -c |
|
447 | 453 | grafting 1:5d205f8b35b6 "1" |
|
448 | 454 | $ hg export tip --git |
|
449 | 455 | # HG changeset patch |
|
450 | 456 | # User bar |
|
451 | 457 | # Date 0 0 |
|
452 | 458 | # Thu Jan 01 00:00:00 1970 +0000 |
|
453 | 459 | # Node ID f67661df0c4804d301f064f332b57e7d5ddaf2be |
|
454 | 460 | # Parent aaa4406d4f0ae9befd6e58c82ec63706460cbca6 |
|
455 | 461 | 1 |
|
456 | 462 | |
|
457 | 463 | diff --git a/a b/a |
|
458 | 464 | --- a/a |
|
459 | 465 | +++ b/a |
|
460 | 466 | @@ -1,1 +1,1 @@ |
|
461 | 467 | -c |
|
462 | 468 | +b |
|
463 | 469 | |
|
464 | 470 | Resolve conflicted graft with rename |
|
465 | 471 | $ echo c > a |
|
466 | 472 | $ hg ci -m 10 |
|
467 | 473 | $ hg graft 2 --tool internal:fail |
|
468 | 474 | grafting 2:5c095ad7e90f "2" |
|
469 | 475 | abort: unresolved conflicts, can't continue |
|
470 | 476 | (use hg resolve and hg graft --continue) |
|
471 | 477 | [255] |
|
472 | 478 | $ hg resolve --all |
|
473 | 479 | merging a and b to b |
|
474 | 480 | (no more unresolved files) |
|
475 | 481 | continue: hg graft --continue |
|
476 | 482 | $ hg graft -c |
|
477 | 483 | grafting 2:5c095ad7e90f "2" |
|
478 | 484 | $ hg export tip --git |
|
479 | 485 | # HG changeset patch |
|
480 | 486 | # User test |
|
481 | 487 | # Date 0 0 |
|
482 | 488 | # Thu Jan 01 00:00:00 1970 +0000 |
|
483 | 489 | # Node ID 9627f653b421c61fc1ea4c4e366745070fa3d2bc |
|
484 | 490 | # Parent ee295f490a40b97f3d18dd4c4f1c8936c233b612 |
|
485 | 491 | 2 |
|
486 | 492 | |
|
487 | 493 | diff --git a/a b/b |
|
488 | 494 | rename from a |
|
489 | 495 | rename to b |
|
490 | 496 | |
|
491 | 497 | Test simple origin(), with and without args |
|
492 | 498 | $ hg log -r 'origin()' |
|
493 | 499 | changeset: 1:5d205f8b35b6 |
|
494 | 500 | user: bar |
|
495 | 501 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
496 | 502 | summary: 1 |
|
497 | 503 | |
|
498 | 504 | changeset: 2:5c095ad7e90f |
|
499 | 505 | user: test |
|
500 | 506 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
501 | 507 | summary: 2 |
|
502 | 508 | |
|
503 | 509 | changeset: 3:4c60f11aa304 |
|
504 | 510 | user: baz |
|
505 | 511 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
506 | 512 | summary: 3 |
|
507 | 513 | |
|
508 | 514 | changeset: 4:9c233e8e184d |
|
509 | 515 | user: test |
|
510 | 516 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
511 | 517 | summary: 4 |
|
512 | 518 | |
|
513 | 519 | changeset: 5:97f8bfe72746 |
|
514 | 520 | branch: stable |
|
515 | 521 | parent: 3:4c60f11aa304 |
|
516 | 522 | user: test |
|
517 | 523 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
518 | 524 | summary: 5 |
|
519 | 525 | |
|
520 | 526 | $ hg log -r 'origin(7)' |
|
521 | 527 | changeset: 2:5c095ad7e90f |
|
522 | 528 | user: test |
|
523 | 529 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
524 | 530 | summary: 2 |
|
525 | 531 | |
|
526 | 532 | Now transplant a graft to test following through copies |
|
527 | 533 | $ hg up -q 0 |
|
528 | 534 | $ hg branch -q dev |
|
529 | 535 | $ hg ci -qm "dev branch" |
|
530 | 536 | $ hg --config extensions.transplant= transplant -q 7 |
|
531 | 537 | $ hg log -r 'origin(.)' |
|
532 | 538 | changeset: 2:5c095ad7e90f |
|
533 | 539 | user: test |
|
534 | 540 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
535 | 541 | summary: 2 |
|
536 | 542 | |
|
537 | 543 | Test that the graft and transplant markers in extra are converted, allowing |
|
538 | 544 | origin() to still work. Note that these recheck the immediately preceeding two |
|
539 | 545 | tests. |
|
540 | 546 | $ hg --quiet --config extensions.convert= --config convert.hg.saverev=True convert . ../converted |
|
541 | 547 | |
|
542 | 548 | The graft case |
|
543 | 549 | $ hg -R ../converted log -r 7 --template "{rev}: {node}\n{join(extras, '\n')}\n" |
|
544 | 550 | 7: 7ae846e9111fc8f57745634250c7b9ac0a60689b |
|
545 | 551 | branch=default |
|
546 | 552 | convert_revision=ef0ef43d49e79e81ddafdc7997401ba0041efc82 |
|
547 | 553 | source=e0213322b2c1a5d5d236c74e79666441bee67a7d |
|
548 | 554 | $ hg -R ../converted log -r 'origin(7)' |
|
549 | 555 | changeset: 2:e0213322b2c1 |
|
550 | 556 | user: test |
|
551 | 557 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
552 | 558 | summary: 2 |
|
553 | 559 | |
|
554 | 560 | Test that template correctly expands more than one 'extra' (issue4362), and that |
|
555 | 561 | 'intermediate-source' is converted. |
|
556 | 562 | $ hg -R ../converted log -r 13 --template "{extras % ' Extra: {extra}\n'}" |
|
557 | 563 | Extra: branch=default |
|
558 | 564 | Extra: convert_revision=7a4785234d87ec1aa420ed6b11afe40fa73e12a9 |
|
559 | 565 | Extra: intermediate-source=7ae846e9111fc8f57745634250c7b9ac0a60689b |
|
560 | 566 | Extra: source=e0213322b2c1a5d5d236c74e79666441bee67a7d |
|
561 | 567 | |
|
562 | 568 | The transplant case |
|
563 | 569 | $ hg -R ../converted log -r tip --template "{rev}: {node}\n{join(extras, '\n')}\n" |
|
564 | 570 | 21: fbb6c5cc81002f2b4b49c9d731404688bcae5ade |
|
565 | 571 | branch=dev |
|
566 | 572 | convert_revision=7e61b508e709a11d28194a5359bc3532d910af21 |
|
567 | 573 | transplant_source=z\xe8F\xe9\x11\x1f\xc8\xf5wEcBP\xc7\xb9\xac (esc) |
|
568 | 574 | `h\x9b (esc) |
|
569 | 575 | $ hg -R ../converted log -r 'origin(tip)' |
|
570 | 576 | changeset: 2:e0213322b2c1 |
|
571 | 577 | user: test |
|
572 | 578 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
573 | 579 | summary: 2 |
|
574 | 580 | |
|
575 | 581 | |
|
576 | 582 | Test simple destination |
|
577 | 583 | $ hg log -r 'destination()' |
|
578 | 584 | changeset: 7:ef0ef43d49e7 |
|
579 | 585 | parent: 0:68795b066622 |
|
580 | 586 | user: foo |
|
581 | 587 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
582 | 588 | summary: 2 |
|
583 | 589 | |
|
584 | 590 | changeset: 8:6b9e5368ca4e |
|
585 | 591 | user: bar |
|
586 | 592 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
587 | 593 | summary: 1 |
|
588 | 594 | |
|
589 | 595 | changeset: 9:1905859650ec |
|
590 | 596 | user: test |
|
591 | 597 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
592 | 598 | summary: 5 |
|
593 | 599 | |
|
594 | 600 | changeset: 10:52dc0b4c6907 |
|
595 | 601 | user: test |
|
596 | 602 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
597 | 603 | summary: 4 |
|
598 | 604 | |
|
599 | 605 | changeset: 11:882b35362a6b |
|
600 | 606 | user: test |
|
601 | 607 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
602 | 608 | summary: 3 |
|
603 | 609 | |
|
604 | 610 | changeset: 13:7a4785234d87 |
|
605 | 611 | user: foo |
|
606 | 612 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
607 | 613 | summary: 2 |
|
608 | 614 | |
|
609 | 615 | changeset: 14:f64defefacee |
|
610 | 616 | parent: 1:5d205f8b35b6 |
|
611 | 617 | user: foo |
|
612 | 618 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
613 | 619 | summary: 3 |
|
614 | 620 | |
|
615 | 621 | changeset: 17:f67661df0c48 |
|
616 | 622 | user: bar |
|
617 | 623 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
618 | 624 | summary: 1 |
|
619 | 625 | |
|
620 | 626 | changeset: 19:9627f653b421 |
|
621 | 627 | user: test |
|
622 | 628 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
623 | 629 | summary: 2 |
|
624 | 630 | |
|
625 | 631 | changeset: 21:7e61b508e709 |
|
626 | 632 | branch: dev |
|
627 | 633 | tag: tip |
|
628 | 634 | user: foo |
|
629 | 635 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
630 | 636 | summary: 2 |
|
631 | 637 | |
|
632 | 638 | $ hg log -r 'destination(2)' |
|
633 | 639 | changeset: 7:ef0ef43d49e7 |
|
634 | 640 | parent: 0:68795b066622 |
|
635 | 641 | user: foo |
|
636 | 642 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
637 | 643 | summary: 2 |
|
638 | 644 | |
|
639 | 645 | changeset: 13:7a4785234d87 |
|
640 | 646 | user: foo |
|
641 | 647 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
642 | 648 | summary: 2 |
|
643 | 649 | |
|
644 | 650 | changeset: 19:9627f653b421 |
|
645 | 651 | user: test |
|
646 | 652 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
647 | 653 | summary: 2 |
|
648 | 654 | |
|
649 | 655 | changeset: 21:7e61b508e709 |
|
650 | 656 | branch: dev |
|
651 | 657 | tag: tip |
|
652 | 658 | user: foo |
|
653 | 659 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
654 | 660 | summary: 2 |
|
655 | 661 | |
|
656 | 662 | Transplants of grafts can find a destination... |
|
657 | 663 | $ hg log -r 'destination(7)' |
|
658 | 664 | changeset: 21:7e61b508e709 |
|
659 | 665 | branch: dev |
|
660 | 666 | tag: tip |
|
661 | 667 | user: foo |
|
662 | 668 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
663 | 669 | summary: 2 |
|
664 | 670 | |
|
665 | 671 | ... grafts of grafts unfortunately can't |
|
666 | 672 | $ hg graft -q 13 |
|
667 | 673 | warning: can't find ancestor for 'b' copied from 'a'! |
|
668 | 674 | $ hg log -r 'destination(13)' |
|
669 | 675 | All copies of a cset |
|
670 | 676 | $ hg log -r 'origin(13) or destination(origin(13))' |
|
671 | 677 | changeset: 2:5c095ad7e90f |
|
672 | 678 | user: test |
|
673 | 679 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
674 | 680 | summary: 2 |
|
675 | 681 | |
|
676 | 682 | changeset: 7:ef0ef43d49e7 |
|
677 | 683 | parent: 0:68795b066622 |
|
678 | 684 | user: foo |
|
679 | 685 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
680 | 686 | summary: 2 |
|
681 | 687 | |
|
682 | 688 | changeset: 13:7a4785234d87 |
|
683 | 689 | user: foo |
|
684 | 690 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
685 | 691 | summary: 2 |
|
686 | 692 | |
|
687 | 693 | changeset: 19:9627f653b421 |
|
688 | 694 | user: test |
|
689 | 695 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
690 | 696 | summary: 2 |
|
691 | 697 | |
|
692 | 698 | changeset: 21:7e61b508e709 |
|
693 | 699 | branch: dev |
|
694 | 700 | user: foo |
|
695 | 701 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
696 | 702 | summary: 2 |
|
697 | 703 | |
|
698 | 704 | changeset: 22:d1cb6591fa4b |
|
699 | 705 | branch: dev |
|
700 | 706 | tag: tip |
|
701 | 707 | user: foo |
|
702 | 708 | date: Thu Jan 01 00:00:00 1970 +0000 |
|
703 | 709 | summary: 2 |
|
704 | 710 | |
|
705 | 711 | |
|
706 | 712 | graft works on complex revset |
|
707 | 713 | |
|
708 | 714 | $ hg graft 'origin(13) or destination(origin(13))' |
|
709 | 715 | skipping ancestor revision 21:7e61b508e709 |
|
710 | 716 | skipping ancestor revision 22:d1cb6591fa4b |
|
711 | 717 | skipping revision 2:5c095ad7e90f (already grafted to 22:d1cb6591fa4b) |
|
712 | 718 | grafting 7:ef0ef43d49e7 "2" |
|
713 | 719 | warning: can't find ancestor for 'b' copied from 'a'! |
|
714 | 720 | grafting 13:7a4785234d87 "2" |
|
715 | 721 | warning: can't find ancestor for 'b' copied from 'a'! |
|
716 | 722 | grafting 19:9627f653b421 "2" |
|
717 | 723 | merging b |
|
718 | 724 | warning: can't find ancestor for 'b' copied from 'a'! |
|
719 | 725 | |
|
720 | 726 | graft with --force (still doesn't graft merges) |
|
721 | 727 | |
|
722 | 728 | $ hg graft 19 0 6 |
|
723 | 729 | skipping ungraftable merge revision 6 |
|
724 | 730 | skipping ancestor revision 0:68795b066622 |
|
725 | 731 | skipping already grafted revision 19:9627f653b421 (22:d1cb6591fa4b also has origin 2:5c095ad7e90f) |
|
726 | 732 | [255] |
|
727 | 733 | $ hg graft 19 0 6 --force |
|
728 | 734 | skipping ungraftable merge revision 6 |
|
729 | 735 | grafting 19:9627f653b421 "2" |
|
730 | 736 | merging b |
|
731 | 737 | warning: can't find ancestor for 'b' copied from 'a'! |
|
732 | 738 | grafting 0:68795b066622 "0" |
|
733 | 739 | |
|
734 | 740 | graft --force after backout |
|
735 | 741 | |
|
736 | 742 | $ echo abc > a |
|
737 | 743 | $ hg ci -m 28 |
|
738 | 744 | $ hg backout 28 |
|
739 | 745 | reverting a |
|
740 | 746 | changeset 29:53177ba928f6 backs out changeset 28:50a516bb8b57 |
|
741 | 747 | $ hg graft 28 |
|
742 | 748 | skipping ancestor revision 28:50a516bb8b57 |
|
743 | 749 | [255] |
|
744 | 750 | $ hg graft 28 --force |
|
745 | 751 | grafting 28:50a516bb8b57 "28" |
|
746 | 752 | merging a |
|
747 | 753 | $ cat a |
|
748 | 754 | abc |
|
749 | 755 | |
|
750 | 756 | graft --continue after --force |
|
751 | 757 | |
|
752 | 758 | $ echo def > a |
|
753 | 759 | $ hg ci -m 31 |
|
754 | 760 | $ hg graft 28 --force --tool internal:fail |
|
755 | 761 | grafting 28:50a516bb8b57 "28" |
|
756 | 762 | abort: unresolved conflicts, can't continue |
|
757 | 763 | (use hg resolve and hg graft --continue) |
|
758 | 764 | [255] |
|
759 | 765 | $ hg resolve --all |
|
760 | 766 | merging a |
|
761 | 767 | warning: conflicts while merging a! (edit, then use 'hg resolve --mark') |
|
762 | 768 | [1] |
|
763 | 769 | $ echo abc > a |
|
764 | 770 | $ hg resolve -m a |
|
765 | 771 | (no more unresolved files) |
|
766 | 772 | continue: hg graft --continue |
|
767 | 773 | $ hg graft -c |
|
768 | 774 | grafting 28:50a516bb8b57 "28" |
|
769 | 775 | $ cat a |
|
770 | 776 | abc |
|
771 | 777 | |
|
772 | 778 | Continue testing same origin policy, using revision numbers from test above |
|
773 | 779 | but do some destructive editing of the repo: |
|
774 | 780 | |
|
775 | 781 | $ hg up -qC 7 |
|
776 | 782 | $ hg tag -l -r 13 tmp |
|
777 | 783 | $ hg --config extensions.strip= strip 2 |
|
778 | 784 | saved backup bundle to $TESTTMP/a/.hg/strip-backup/5c095ad7e90f-d323a1e4-backup.hg (glob) |
|
779 | 785 | $ hg graft tmp |
|
780 | 786 | skipping already grafted revision 8:7a4785234d87 (2:ef0ef43d49e7 also has unknown origin 5c095ad7e90f) |
|
781 | 787 | [255] |
|
782 | 788 | |
|
783 | 789 | Empty graft |
|
784 | 790 | |
|
785 | 791 | $ hg up -qr 26 |
|
786 | 792 | $ hg tag -f something |
|
787 | 793 | $ hg graft -qr 27 |
|
788 | 794 | $ hg graft -f 27 |
|
789 | 795 | grafting 27:ed6c7e54e319 "28" |
|
790 | 796 | note: graft of 27:ed6c7e54e319 created no changes to commit |
|
791 | 797 | |
|
792 | 798 | $ cd .. |
|
793 | 799 | |
|
794 | 800 | Graft to duplicate a commit |
|
795 | 801 | |
|
796 | 802 | $ hg init graftsibling |
|
797 | 803 | $ cd graftsibling |
|
798 | 804 | $ touch a |
|
799 | 805 | $ hg commit -qAm a |
|
800 | 806 | $ touch b |
|
801 | 807 | $ hg commit -qAm b |
|
802 | 808 | $ hg log -G -T '{rev}\n' |
|
803 | 809 | @ 1 |
|
804 | 810 | | |
|
805 | 811 | o 0 |
|
806 | 812 | |
|
807 | 813 | $ hg up -q 0 |
|
808 | 814 | $ hg graft -r 1 |
|
809 | 815 | grafting 1:0e067c57feba "b" (tip) |
|
810 | 816 | $ hg log -G -T '{rev}\n' |
|
811 | 817 | @ 2 |
|
812 | 818 | | |
|
813 | 819 | | o 1 |
|
814 | 820 | |/ |
|
815 | 821 | o 0 |
|
816 | 822 | |
|
817 | 823 | Graft to duplicate a commit twice |
|
818 | 824 | |
|
819 | 825 | $ hg up -q 0 |
|
820 | 826 | $ hg graft -r 2 |
|
821 | 827 | grafting 2:044ec77f6389 "b" (tip) |
|
822 | 828 | $ hg log -G -T '{rev}\n' |
|
823 | 829 | @ 3 |
|
824 | 830 | | |
|
825 | 831 | | o 2 |
|
826 | 832 | |/ |
|
827 | 833 | | o 1 |
|
828 | 834 | |/ |
|
829 | 835 | o 0 |
|
830 | 836 |
@@ -1,741 +1,744 | |||
|
1 | 1 | This file focuses mainly on updating largefiles in the working |
|
2 | 2 | directory (and ".hg/largefiles/dirstate") |
|
3 | 3 | |
|
4 | 4 | $ cat >> $HGRCPATH <<EOF |
|
5 | 5 | > [ui] |
|
6 | 6 | > merge = internal:fail |
|
7 | 7 | > [extensions] |
|
8 | 8 | > largefiles = |
|
9 | > [defaults] | |
|
10 | > # for portability | |
|
11 | > extdiff = --option -Nru | |
|
9 | 12 | > EOF |
|
10 | 13 | |
|
11 | 14 | $ hg init repo |
|
12 | 15 | $ cd repo |
|
13 | 16 | |
|
14 | 17 | $ echo large1 > large1 |
|
15 | 18 | $ echo large2 > large2 |
|
16 | 19 | $ hg add --large large1 large2 |
|
17 | 20 | $ echo normal1 > normal1 |
|
18 | 21 | $ hg add normal1 |
|
19 | 22 | $ hg commit -m '#0' |
|
20 | 23 | $ echo 'large1 in #1' > large1 |
|
21 | 24 | $ echo 'normal1 in #1' > normal1 |
|
22 | 25 | $ hg commit -m '#1' |
|
23 | 26 | $ hg extdiff -r '.^' --config extensions.extdiff= |
|
24 |
diff -N |
|
|
27 | diff -Nru repo.0d9d9b8dc9a3/.hglf/large1 repo/.hglf/large1 | |
|
25 | 28 | --- repo.0d9d9b8dc9a3/.hglf/large1 * (glob) |
|
26 | 29 | +++ repo/.hglf/large1 * (glob) |
|
27 | 30 | @@ -1 +1 @@ |
|
28 | 31 | -4669e532d5b2c093a78eca010077e708a071bb64 |
|
29 | 32 | +58e24f733a964da346e2407a2bee99d9001184f5 |
|
30 |
diff -N |
|
|
33 | diff -Nru repo.0d9d9b8dc9a3/normal1 repo/normal1 | |
|
31 | 34 | --- repo.0d9d9b8dc9a3/normal1 * (glob) |
|
32 | 35 | +++ repo/normal1 * (glob) |
|
33 | 36 | @@ -1 +1 @@ |
|
34 | 37 | -normal1 |
|
35 | 38 | +normal1 in #1 |
|
36 | 39 | [1] |
|
37 | 40 | $ hg update -q -C 0 |
|
38 | 41 | $ echo 'large2 in #2' > large2 |
|
39 | 42 | $ hg commit -m '#2' |
|
40 | 43 | created new head |
|
41 | 44 | |
|
42 | 45 | Test that update also updates the lfdirstate of 'unsure' largefiles after |
|
43 | 46 | hashing them: |
|
44 | 47 | |
|
45 | 48 | The previous operations will usually have left us with largefiles with a mtime |
|
46 | 49 | within the same second as the dirstate was written. |
|
47 | 50 | The lfdirstate entries will thus have been written with an invalidated/unset |
|
48 | 51 | mtime to make sure further changes within the same second is detected. |
|
49 | 52 | We will however occasionally be "lucky" and get a tick between writing |
|
50 | 53 | largefiles and writing dirstate so we get valid lfdirstate timestamps. The |
|
51 | 54 | following verification is thus disabled but can be verified manually. |
|
52 | 55 | |
|
53 | 56 | #if false |
|
54 | 57 | $ hg debugdirstate --large --nodate |
|
55 | 58 | n 644 7 unset large1 |
|
56 | 59 | n 644 13 unset large2 |
|
57 | 60 | #endif |
|
58 | 61 | |
|
59 | 62 | Wait to make sure we get a tick so the mtime of the largefiles become valid. |
|
60 | 63 | |
|
61 | 64 | $ sleep 1 |
|
62 | 65 | |
|
63 | 66 | A linear merge will update standins before performing the actual merge. It will |
|
64 | 67 | do a lfdirstate status walk and find 'unset'/'unsure' files, hash them, and |
|
65 | 68 | update the corresponding standins. |
|
66 | 69 | Verify that it actually marks the clean files as clean in lfdirstate so |
|
67 | 70 | we don't have to hash them again next time we update. |
|
68 | 71 | |
|
69 | 72 | $ hg up |
|
70 | 73 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
71 | 74 | 1 other heads for branch "default" |
|
72 | 75 | $ hg debugdirstate --large --nodate |
|
73 | 76 | n 644 7 set large1 |
|
74 | 77 | n 644 13 set large2 |
|
75 | 78 | |
|
76 | 79 | Test that lfdirstate keeps track of last modification of largefiles and |
|
77 | 80 | prevents unnecessary hashing of content - also after linear/noop update |
|
78 | 81 | |
|
79 | 82 | $ sleep 1 |
|
80 | 83 | $ hg st |
|
81 | 84 | $ hg debugdirstate --large --nodate |
|
82 | 85 | n 644 7 set large1 |
|
83 | 86 | n 644 13 set large2 |
|
84 | 87 | $ hg up |
|
85 | 88 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
86 | 89 | 1 other heads for branch "default" |
|
87 | 90 | $ hg debugdirstate --large --nodate |
|
88 | 91 | n 644 7 set large1 |
|
89 | 92 | n 644 13 set large2 |
|
90 | 93 | |
|
91 | 94 | Test that "hg merge" updates largefiles from "other" correctly |
|
92 | 95 | |
|
93 | 96 | (getting largefiles from "other" normally) |
|
94 | 97 | |
|
95 | 98 | $ hg status -A large1 |
|
96 | 99 | C large1 |
|
97 | 100 | $ cat large1 |
|
98 | 101 | large1 |
|
99 | 102 | $ cat .hglf/large1 |
|
100 | 103 | 4669e532d5b2c093a78eca010077e708a071bb64 |
|
101 | 104 | $ hg merge --config debug.dirstate.delaywrite=2 |
|
102 | 105 | getting changed largefiles |
|
103 | 106 | 1 largefiles updated, 0 removed |
|
104 | 107 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
105 | 108 | (branch merge, don't forget to commit) |
|
106 | 109 | $ hg status -A large1 |
|
107 | 110 | M large1 |
|
108 | 111 | $ cat large1 |
|
109 | 112 | large1 in #1 |
|
110 | 113 | $ cat .hglf/large1 |
|
111 | 114 | 58e24f733a964da346e2407a2bee99d9001184f5 |
|
112 | 115 | $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]' |
|
113 | 116 | -4669e532d5b2c093a78eca010077e708a071bb64 |
|
114 | 117 | +58e24f733a964da346e2407a2bee99d9001184f5 |
|
115 | 118 | |
|
116 | 119 | (getting largefiles from "other" via conflict prompt) |
|
117 | 120 | |
|
118 | 121 | $ hg update -q -C 2 |
|
119 | 122 | $ echo 'large1 in #3' > large1 |
|
120 | 123 | $ echo 'normal1 in #3' > normal1 |
|
121 | 124 | $ hg commit -m '#3' |
|
122 | 125 | $ cat .hglf/large1 |
|
123 | 126 | e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
124 | 127 | $ hg merge --config debug.dirstate.delaywrite=2 --config ui.interactive=True <<EOF |
|
125 | 128 | > o |
|
126 | 129 | > EOF |
|
127 | 130 | largefile large1 has a merge conflict |
|
128 | 131 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
129 | 132 | keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or |
|
130 | 133 | take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o |
|
131 | 134 | merging normal1 |
|
132 | 135 | warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark') |
|
133 | 136 | getting changed largefiles |
|
134 | 137 | 1 largefiles updated, 0 removed |
|
135 | 138 | 0 files updated, 1 files merged, 0 files removed, 1 files unresolved |
|
136 | 139 | use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon |
|
137 | 140 | [1] |
|
138 | 141 | $ hg status -A large1 |
|
139 | 142 | M large1 |
|
140 | 143 | $ cat large1 |
|
141 | 144 | large1 in #1 |
|
142 | 145 | $ cat .hglf/large1 |
|
143 | 146 | 58e24f733a964da346e2407a2bee99d9001184f5 |
|
144 | 147 | |
|
145 | 148 | (merge non-existing largefiles from "other" via conflict prompt - |
|
146 | 149 | make sure the following commit doesn't abort in a confusing way when trying to |
|
147 | 150 | mark the non-existing file as normal in lfdirstate) |
|
148 | 151 | |
|
149 | 152 | $ mv .hg/largefiles/58e24f733a964da346e2407a2bee99d9001184f5 . |
|
150 | 153 | $ hg update -q -C 3 |
|
151 | 154 | $ hg merge --config largefiles.usercache=not --config debug.dirstate.delaywrite=2 --tool :local --config ui.interactive=True <<EOF |
|
152 | 155 | > o |
|
153 | 156 | > EOF |
|
154 | 157 | largefile large1 has a merge conflict |
|
155 | 158 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
156 | 159 | keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or |
|
157 | 160 | take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o |
|
158 | 161 | getting changed largefiles |
|
159 | 162 | large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob) |
|
160 | 163 | 0 largefiles updated, 0 removed |
|
161 | 164 | 0 files updated, 2 files merged, 0 files removed, 0 files unresolved |
|
162 | 165 | (branch merge, don't forget to commit) |
|
163 | 166 | $ hg commit -m '1-2-3 testing' --config largefiles.usercache=not |
|
164 | 167 | large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from local store |
|
165 | 168 | $ hg up -C . --config largefiles.usercache=not |
|
166 | 169 | getting changed largefiles |
|
167 | 170 | large1: largefile 58e24f733a964da346e2407a2bee99d9001184f5 not available from file:/*/$TESTTMP/repo (glob) |
|
168 | 171 | 0 largefiles updated, 0 removed |
|
169 | 172 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
170 | 173 | $ hg st large1 |
|
171 | 174 | ! large1 |
|
172 | 175 | $ hg rollback -q |
|
173 | 176 | $ mv 58e24f733a964da346e2407a2bee99d9001184f5 .hg/largefiles/ |
|
174 | 177 | |
|
175 | 178 | Test that "hg revert -r REV" updates largefiles from "REV" correctly |
|
176 | 179 | |
|
177 | 180 | $ hg update -q -C 3 |
|
178 | 181 | $ hg status -A large1 |
|
179 | 182 | C large1 |
|
180 | 183 | $ cat large1 |
|
181 | 184 | large1 in #3 |
|
182 | 185 | $ cat .hglf/large1 |
|
183 | 186 | e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
184 | 187 | $ hg diff -c 1 --nodates .hglf/large1 | grep '^[+-][0-9a-z]' |
|
185 | 188 | -4669e532d5b2c093a78eca010077e708a071bb64 |
|
186 | 189 | +58e24f733a964da346e2407a2bee99d9001184f5 |
|
187 | 190 | $ hg revert --no-backup -r 1 --config debug.dirstate.delaywrite=2 large1 |
|
188 | 191 | $ hg status -A large1 |
|
189 | 192 | M large1 |
|
190 | 193 | $ cat large1 |
|
191 | 194 | large1 in #1 |
|
192 | 195 | $ cat .hglf/large1 |
|
193 | 196 | 58e24f733a964da346e2407a2bee99d9001184f5 |
|
194 | 197 | |
|
195 | 198 | Test that "hg rollback" restores status of largefiles correctly |
|
196 | 199 | |
|
197 | 200 | $ hg update -C -q |
|
198 | 201 | $ hg remove large1 |
|
199 | 202 | $ test -f .hglf/large1 |
|
200 | 203 | [1] |
|
201 | 204 | $ hg forget large2 |
|
202 | 205 | $ test -f .hglf/large2 |
|
203 | 206 | [1] |
|
204 | 207 | $ echo largeX > largeX |
|
205 | 208 | $ hg add --large largeX |
|
206 | 209 | $ cat .hglf/largeX |
|
207 | 210 | |
|
208 | 211 | $ hg commit -m 'will be rollback-ed soon' |
|
209 | 212 | $ echo largeY > largeY |
|
210 | 213 | $ hg add --large largeY |
|
211 | 214 | #if windows |
|
212 | 215 | $ hg status -A large1 |
|
213 | 216 | large1: * (glob) |
|
214 | 217 | #else |
|
215 | 218 | $ hg status -A large1 |
|
216 | 219 | large1: No such file or directory |
|
217 | 220 | #endif |
|
218 | 221 | $ hg status -A large2 |
|
219 | 222 | ? large2 |
|
220 | 223 | $ hg status -A largeX |
|
221 | 224 | C largeX |
|
222 | 225 | $ hg status -A largeY |
|
223 | 226 | A largeY |
|
224 | 227 | $ hg rollback |
|
225 | 228 | repository tip rolled back to revision 3 (undo commit) |
|
226 | 229 | working directory now based on revision 3 |
|
227 | 230 | $ hg status -A large1 |
|
228 | 231 | R large1 |
|
229 | 232 | $ test -f .hglf/large1 |
|
230 | 233 | [1] |
|
231 | 234 | $ hg status -A large2 |
|
232 | 235 | R large2 |
|
233 | 236 | $ test -f .hglf/large2 |
|
234 | 237 | [1] |
|
235 | 238 | $ hg status -A largeX |
|
236 | 239 | A largeX |
|
237 | 240 | $ cat .hglf/largeX |
|
238 | 241 | |
|
239 | 242 | $ hg status -A largeY |
|
240 | 243 | ? largeY |
|
241 | 244 | $ test -f .hglf/largeY |
|
242 | 245 | [1] |
|
243 | 246 | |
|
244 | 247 | Test that "hg rollback" restores standins correctly |
|
245 | 248 | |
|
246 | 249 | $ hg commit -m 'will be rollback-ed soon' |
|
247 | 250 | $ hg update -q -C 2 |
|
248 | 251 | $ cat large1 |
|
249 | 252 | large1 |
|
250 | 253 | $ cat .hglf/large1 |
|
251 | 254 | 4669e532d5b2c093a78eca010077e708a071bb64 |
|
252 | 255 | $ cat large2 |
|
253 | 256 | large2 in #2 |
|
254 | 257 | $ cat .hglf/large2 |
|
255 | 258 | 3cfce6277e7668985707b6887ce56f9f62f6ccd9 |
|
256 | 259 | |
|
257 | 260 | $ hg rollback -q -f |
|
258 | 261 | $ cat large1 |
|
259 | 262 | large1 |
|
260 | 263 | $ cat .hglf/large1 |
|
261 | 264 | 4669e532d5b2c093a78eca010077e708a071bb64 |
|
262 | 265 | $ cat large2 |
|
263 | 266 | large2 in #2 |
|
264 | 267 | $ cat .hglf/large2 |
|
265 | 268 | 3cfce6277e7668985707b6887ce56f9f62f6ccd9 |
|
266 | 269 | |
|
267 | 270 | (rollback the parent of the working directory, when the parent of it |
|
268 | 271 | is not branch-tip) |
|
269 | 272 | |
|
270 | 273 | $ hg update -q -C 1 |
|
271 | 274 | $ cat .hglf/large1 |
|
272 | 275 | 58e24f733a964da346e2407a2bee99d9001184f5 |
|
273 | 276 | $ cat .hglf/large2 |
|
274 | 277 | 1deebade43c8c498a3c8daddac0244dc55d1331d |
|
275 | 278 | |
|
276 | 279 | $ echo normalX > normalX |
|
277 | 280 | $ hg add normalX |
|
278 | 281 | $ hg commit -m 'will be rollback-ed soon' |
|
279 | 282 | $ hg rollback -q |
|
280 | 283 | |
|
281 | 284 | $ cat .hglf/large1 |
|
282 | 285 | 58e24f733a964da346e2407a2bee99d9001184f5 |
|
283 | 286 | $ cat .hglf/large2 |
|
284 | 287 | 1deebade43c8c498a3c8daddac0244dc55d1331d |
|
285 | 288 | |
|
286 | 289 | Test that "hg status" shows status of largefiles correctly just after |
|
287 | 290 | automated commit like rebase/transplant |
|
288 | 291 | |
|
289 | 292 | $ cat >> .hg/hgrc <<EOF |
|
290 | 293 | > [extensions] |
|
291 | 294 | > rebase = |
|
292 | 295 | > strip = |
|
293 | 296 | > transplant = |
|
294 | 297 | > EOF |
|
295 | 298 | $ hg update -q -C 1 |
|
296 | 299 | $ hg remove large1 |
|
297 | 300 | $ echo largeX > largeX |
|
298 | 301 | $ hg add --large largeX |
|
299 | 302 | $ hg commit -m '#4' |
|
300 | 303 | |
|
301 | 304 | $ hg rebase -s 1 -d 2 --keep |
|
302 | 305 | rebasing 1:72518492caa6 "#1" |
|
303 | 306 | rebasing 4:07d6153b5c04 "#4" (tip) |
|
304 | 307 | #if windows |
|
305 | 308 | $ hg status -A large1 |
|
306 | 309 | large1: * (glob) |
|
307 | 310 | #else |
|
308 | 311 | $ hg status -A large1 |
|
309 | 312 | large1: No such file or directory |
|
310 | 313 | #endif |
|
311 | 314 | $ hg status -A largeX |
|
312 | 315 | C largeX |
|
313 | 316 | $ hg strip -q 5 |
|
314 | 317 | |
|
315 | 318 | $ hg update -q -C 2 |
|
316 | 319 | $ hg transplant -q 1 4 |
|
317 | 320 | #if windows |
|
318 | 321 | $ hg status -A large1 |
|
319 | 322 | large1: * (glob) |
|
320 | 323 | #else |
|
321 | 324 | $ hg status -A large1 |
|
322 | 325 | large1: No such file or directory |
|
323 | 326 | #endif |
|
324 | 327 | $ hg status -A largeX |
|
325 | 328 | C largeX |
|
326 | 329 | $ hg strip -q 5 |
|
327 | 330 | |
|
328 | 331 | $ hg update -q -C 2 |
|
329 | 332 | $ hg transplant -q --merge 1 --merge 4 |
|
330 | 333 | #if windows |
|
331 | 334 | $ hg status -A large1 |
|
332 | 335 | large1: * (glob) |
|
333 | 336 | #else |
|
334 | 337 | $ hg status -A large1 |
|
335 | 338 | large1: No such file or directory |
|
336 | 339 | #endif |
|
337 | 340 | $ hg status -A largeX |
|
338 | 341 | C largeX |
|
339 | 342 | $ hg strip -q 5 |
|
340 | 343 | |
|
341 | 344 | Test that linear merge can detect modification (and conflict) correctly |
|
342 | 345 | |
|
343 | 346 | (linear merge without conflict) |
|
344 | 347 | |
|
345 | 348 | $ echo 'large2 for linear merge (no conflict)' > large2 |
|
346 | 349 | $ hg update 3 --config debug.dirstate.delaywrite=2 |
|
347 | 350 | getting changed largefiles |
|
348 | 351 | 1 largefiles updated, 0 removed |
|
349 | 352 | 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
350 | 353 | $ hg status -A large2 |
|
351 | 354 | M large2 |
|
352 | 355 | $ cat large2 |
|
353 | 356 | large2 for linear merge (no conflict) |
|
354 | 357 | $ cat .hglf/large2 |
|
355 | 358 | 9c4bf8f1b33536d6e5f89447e10620cfe52ea710 |
|
356 | 359 | |
|
357 | 360 | (linear merge with conflict, choosing "other") |
|
358 | 361 | |
|
359 | 362 | $ hg update -q -C 2 |
|
360 | 363 | $ echo 'large1 for linear merge (conflict)' > large1 |
|
361 | 364 | $ hg update 3 --config ui.interactive=True <<EOF |
|
362 | 365 | > o |
|
363 | 366 | > EOF |
|
364 | 367 | largefile large1 has a merge conflict |
|
365 | 368 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
366 | 369 | keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or |
|
367 | 370 | take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? o |
|
368 | 371 | getting changed largefiles |
|
369 | 372 | 1 largefiles updated, 0 removed |
|
370 | 373 | 1 files updated, 1 files merged, 0 files removed, 0 files unresolved |
|
371 | 374 | $ hg status -A large1 |
|
372 | 375 | C large1 |
|
373 | 376 | $ cat large1 |
|
374 | 377 | large1 in #3 |
|
375 | 378 | $ cat .hglf/large1 |
|
376 | 379 | e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
377 | 380 | |
|
378 | 381 | (linear merge with conflict, choosing "local") |
|
379 | 382 | |
|
380 | 383 | $ hg update -q -C 2 |
|
381 | 384 | $ echo 'large1 for linear merge (conflict)' > large1 |
|
382 | 385 | $ hg update 3 --config debug.dirstate.delaywrite=2 |
|
383 | 386 | largefile large1 has a merge conflict |
|
384 | 387 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
385 | 388 | keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or |
|
386 | 389 | take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l |
|
387 | 390 | 1 files updated, 1 files merged, 0 files removed, 0 files unresolved |
|
388 | 391 | $ hg status -A large1 |
|
389 | 392 | M large1 |
|
390 | 393 | $ cat large1 |
|
391 | 394 | large1 for linear merge (conflict) |
|
392 | 395 | $ cat .hglf/large1 |
|
393 | 396 | ba94c2efe5b7c5e0af8d189295ce00553b0612b7 |
|
394 | 397 | |
|
395 | 398 | Test a linear merge to a revision containing same-name normal file |
|
396 | 399 | |
|
397 | 400 | $ hg update -q -C 3 |
|
398 | 401 | $ hg remove large2 |
|
399 | 402 | $ echo 'large2 as normal file' > large2 |
|
400 | 403 | $ hg add large2 |
|
401 | 404 | $ echo 'large3 as normal file' > large3 |
|
402 | 405 | $ hg add large3 |
|
403 | 406 | $ hg commit -m '#5' |
|
404 | 407 | $ hg manifest |
|
405 | 408 | .hglf/large1 |
|
406 | 409 | large2 |
|
407 | 410 | large3 |
|
408 | 411 | normal1 |
|
409 | 412 | |
|
410 | 413 | (modified largefile is already switched to normal) |
|
411 | 414 | |
|
412 | 415 | $ hg update -q -C 2 |
|
413 | 416 | $ echo 'modified large2 for linear merge' > large2 |
|
414 | 417 | $ hg update -q 5 |
|
415 | 418 | remote turned local largefile large2 into a normal file |
|
416 | 419 | keep (l)argefile or use (n)ormal file? l |
|
417 | 420 | $ hg debugdirstate --nodates | grep large2 |
|
418 | 421 | a 0 -1 unset .hglf/large2 |
|
419 | 422 | r 0 0 set large2 |
|
420 | 423 | $ hg status -A large2 |
|
421 | 424 | A large2 |
|
422 | 425 | $ cat large2 |
|
423 | 426 | modified large2 for linear merge |
|
424 | 427 | |
|
425 | 428 | (added largefile is already committed as normal) |
|
426 | 429 | |
|
427 | 430 | $ hg update -q -C 2 |
|
428 | 431 | $ echo 'large3 as large file for linear merge' > large3 |
|
429 | 432 | $ hg add --large large3 |
|
430 | 433 | $ hg update -q 5 |
|
431 | 434 | remote turned local largefile large3 into a normal file |
|
432 | 435 | keep (l)argefile or use (n)ormal file? l |
|
433 | 436 | $ hg debugdirstate --nodates | grep large3 |
|
434 | 437 | a 0 -1 unset .hglf/large3 |
|
435 | 438 | r 0 0 set large3 |
|
436 | 439 | $ hg status -A large3 |
|
437 | 440 | A large3 |
|
438 | 441 | $ cat large3 |
|
439 | 442 | large3 as large file for linear merge |
|
440 | 443 | $ rm -f large3 .hglf/large3 |
|
441 | 444 | |
|
442 | 445 | Test that the internal linear merging works correctly |
|
443 | 446 | (both heads are stripped to keep pairing of revision number and commit log) |
|
444 | 447 | |
|
445 | 448 | $ hg update -q -C 2 |
|
446 | 449 | $ hg strip 3 4 |
|
447 | 450 | saved backup bundle to $TESTTMP/repo/.hg/strip-backup/9530e27857f7-2e7b195d-backup.hg (glob) |
|
448 | 451 | $ mv .hg/strip-backup/9530e27857f7-2e7b195d-backup.hg $TESTTMP |
|
449 | 452 | |
|
450 | 453 | (internal linear merging at "hg pull --update") |
|
451 | 454 | |
|
452 | 455 | $ echo 'large1 for linear merge (conflict)' > large1 |
|
453 | 456 | $ echo 'large2 for linear merge (conflict with normal file)' > large2 |
|
454 | 457 | $ hg pull --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg |
|
455 | 458 | pulling from $TESTTMP/9530e27857f7-2e7b195d-backup.hg (glob) |
|
456 | 459 | searching for changes |
|
457 | 460 | adding changesets |
|
458 | 461 | adding manifests |
|
459 | 462 | adding file changes |
|
460 | 463 | added 3 changesets with 5 changes to 5 files |
|
461 | 464 | remote turned local largefile large2 into a normal file |
|
462 | 465 | keep (l)argefile or use (n)ormal file? l |
|
463 | 466 | largefile large1 has a merge conflict |
|
464 | 467 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
465 | 468 | keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or |
|
466 | 469 | take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l |
|
467 | 470 | 2 files updated, 1 files merged, 0 files removed, 0 files unresolved |
|
468 | 471 | 1 other heads for branch "default" |
|
469 | 472 | |
|
470 | 473 | $ hg status -A large1 |
|
471 | 474 | M large1 |
|
472 | 475 | $ cat large1 |
|
473 | 476 | large1 for linear merge (conflict) |
|
474 | 477 | $ cat .hglf/large1 |
|
475 | 478 | ba94c2efe5b7c5e0af8d189295ce00553b0612b7 |
|
476 | 479 | $ hg status -A large2 |
|
477 | 480 | A large2 |
|
478 | 481 | $ cat large2 |
|
479 | 482 | large2 for linear merge (conflict with normal file) |
|
480 | 483 | $ cat .hglf/large2 |
|
481 | 484 | d7591fe9be0f6227d90bddf3e4f52ff41fc1f544 |
|
482 | 485 | |
|
483 | 486 | (internal linear merging at "hg unbundle --update") |
|
484 | 487 | |
|
485 | 488 | $ hg update -q -C 2 |
|
486 | 489 | $ hg rollback -q |
|
487 | 490 | |
|
488 | 491 | $ echo 'large1 for linear merge (conflict)' > large1 |
|
489 | 492 | $ echo 'large2 for linear merge (conflict with normal file)' > large2 |
|
490 | 493 | $ hg unbundle --update --config debug.dirstate.delaywrite=2 $TESTTMP/9530e27857f7-2e7b195d-backup.hg |
|
491 | 494 | adding changesets |
|
492 | 495 | adding manifests |
|
493 | 496 | adding file changes |
|
494 | 497 | added 3 changesets with 5 changes to 5 files |
|
495 | 498 | remote turned local largefile large2 into a normal file |
|
496 | 499 | keep (l)argefile or use (n)ormal file? l |
|
497 | 500 | largefile large1 has a merge conflict |
|
498 | 501 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
499 | 502 | keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or |
|
500 | 503 | take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l |
|
501 | 504 | 2 files updated, 1 files merged, 0 files removed, 0 files unresolved |
|
502 | 505 | 1 other heads for branch "default" |
|
503 | 506 | |
|
504 | 507 | $ hg status -A large1 |
|
505 | 508 | M large1 |
|
506 | 509 | $ cat large1 |
|
507 | 510 | large1 for linear merge (conflict) |
|
508 | 511 | $ cat .hglf/large1 |
|
509 | 512 | ba94c2efe5b7c5e0af8d189295ce00553b0612b7 |
|
510 | 513 | $ hg status -A large2 |
|
511 | 514 | A large2 |
|
512 | 515 | $ cat large2 |
|
513 | 516 | large2 for linear merge (conflict with normal file) |
|
514 | 517 | $ cat .hglf/large2 |
|
515 | 518 | d7591fe9be0f6227d90bddf3e4f52ff41fc1f544 |
|
516 | 519 | |
|
517 | 520 | (internal linear merging in subrepo at "hg update") |
|
518 | 521 | |
|
519 | 522 | $ cd .. |
|
520 | 523 | $ hg init subparent |
|
521 | 524 | $ cd subparent |
|
522 | 525 | |
|
523 | 526 | $ hg clone -q -u 2 ../repo sub |
|
524 | 527 | $ cat > .hgsub <<EOF |
|
525 | 528 | > sub = sub |
|
526 | 529 | > EOF |
|
527 | 530 | $ hg add .hgsub |
|
528 | 531 | $ hg commit -m '#0@parent' |
|
529 | 532 | $ cat .hgsubstate |
|
530 | 533 | f74e50bd9e5594b7cf1e6c5cbab86ddd25f3ca2f sub |
|
531 | 534 | $ hg -R sub update -q |
|
532 | 535 | $ hg commit -m '#1@parent' |
|
533 | 536 | $ cat .hgsubstate |
|
534 | 537 | d65e59e952a9638e2ce863b41a420ca723dd3e8d sub |
|
535 | 538 | $ hg update -q 0 |
|
536 | 539 | |
|
537 | 540 | $ echo 'large1 for linear merge (conflict)' > sub/large1 |
|
538 | 541 | $ echo 'large2 for linear merge (conflict with normal file)' > sub/large2 |
|
539 | 542 | $ hg update --config ui.interactive=True --config debug.dirstate.delaywrite=2 <<EOF |
|
540 | 543 | > m |
|
541 | 544 | > r |
|
542 | 545 | > l |
|
543 | 546 | > l |
|
544 | 547 | > EOF |
|
545 | 548 | subrepository sub diverged (local revision: f74e50bd9e55, remote revision: d65e59e952a9) |
|
546 | 549 | (M)erge, keep (l)ocal or keep (r)emote? m |
|
547 | 550 | subrepository sources for sub differ (in checked out version) |
|
548 | 551 | use (l)ocal source (f74e50bd9e55) or (r)emote source (d65e59e952a9)? r |
|
549 | 552 | remote turned local largefile large2 into a normal file |
|
550 | 553 | keep (l)argefile or use (n)ormal file? l |
|
551 | 554 | largefile large1 has a merge conflict |
|
552 | 555 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
553 | 556 | keep (l)ocal ba94c2efe5b7c5e0af8d189295ce00553b0612b7 or |
|
554 | 557 | take (o)ther e5bb990443d6a92aaf7223813720f7566c9dd05b? l |
|
555 | 558 | 2 files updated, 1 files merged, 0 files removed, 0 files unresolved |
|
556 | 559 | 0 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
557 | 560 | |
|
558 | 561 | $ hg -R sub status -A sub/large1 |
|
559 | 562 | M sub/large1 |
|
560 | 563 | $ cat sub/large1 |
|
561 | 564 | large1 for linear merge (conflict) |
|
562 | 565 | $ cat sub/.hglf/large1 |
|
563 | 566 | ba94c2efe5b7c5e0af8d189295ce00553b0612b7 |
|
564 | 567 | $ hg -R sub status -A sub/large2 |
|
565 | 568 | A sub/large2 |
|
566 | 569 | $ cat sub/large2 |
|
567 | 570 | large2 for linear merge (conflict with normal file) |
|
568 | 571 | $ cat sub/.hglf/large2 |
|
569 | 572 | d7591fe9be0f6227d90bddf3e4f52ff41fc1f544 |
|
570 | 573 | |
|
571 | 574 | $ cd .. |
|
572 | 575 | $ cd repo |
|
573 | 576 | |
|
574 | 577 | Test that rebase updates largefiles in the working directory even if |
|
575 | 578 | it is aborted by conflict. |
|
576 | 579 | |
|
577 | 580 | $ hg update -q -C 3 |
|
578 | 581 | $ cat .hglf/large1 |
|
579 | 582 | e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
580 | 583 | $ cat large1 |
|
581 | 584 | large1 in #3 |
|
582 | 585 | $ hg rebase -s 1 -d 3 --keep --config ui.interactive=True <<EOF |
|
583 | 586 | > o |
|
584 | 587 | > EOF |
|
585 | 588 | rebasing 1:72518492caa6 "#1" |
|
586 | 589 | largefile large1 has a merge conflict |
|
587 | 590 | ancestor was 4669e532d5b2c093a78eca010077e708a071bb64 |
|
588 | 591 | keep (l)ocal e5bb990443d6a92aaf7223813720f7566c9dd05b or |
|
589 | 592 | take (o)ther 58e24f733a964da346e2407a2bee99d9001184f5? o |
|
590 | 593 | merging normal1 |
|
591 | 594 | warning: conflicts while merging normal1! (edit, then use 'hg resolve --mark') |
|
592 | 595 | unresolved conflicts (see hg resolve, then hg rebase --continue) |
|
593 | 596 | [1] |
|
594 | 597 | $ cat .hglf/large1 |
|
595 | 598 | 58e24f733a964da346e2407a2bee99d9001184f5 |
|
596 | 599 | $ cat large1 |
|
597 | 600 | large1 in #1 |
|
598 | 601 | |
|
599 | 602 | Test that rebase updates standins for manually modified largefiles at |
|
600 | 603 | the 1st commit of resuming. |
|
601 | 604 | |
|
602 | 605 | $ echo "manually modified before 'hg rebase --continue'" > large1 |
|
603 | 606 | $ hg resolve -m normal1 |
|
604 | 607 | (no more unresolved files) |
|
605 | 608 | continue: hg rebase --continue |
|
606 | 609 | $ hg rebase --continue --config ui.interactive=True <<EOF |
|
607 | 610 | > c |
|
608 | 611 | > EOF |
|
609 | 612 | rebasing 1:72518492caa6 "#1" |
|
610 | 613 | rebasing 4:07d6153b5c04 "#4" |
|
611 | 614 | local changed .hglf/large1 which remote deleted |
|
612 | 615 | use (c)hanged version, (d)elete, or leave (u)nresolved? c |
|
613 | 616 | |
|
614 | 617 | $ hg diff -c "tip~1" --nodates .hglf/large1 | grep '^[+-][0-9a-z]' |
|
615 | 618 | -e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
616 | 619 | +8a4f783556e7dea21139ca0466eafce954c75c13 |
|
617 | 620 | $ rm -f large1 |
|
618 | 621 | $ hg update -q -C tip |
|
619 | 622 | $ cat large1 |
|
620 | 623 | manually modified before 'hg rebase --continue' |
|
621 | 624 | |
|
622 | 625 | Test that transplant updates largefiles, of which standins are safely |
|
623 | 626 | changed, even if it is aborted by conflict of other. |
|
624 | 627 | |
|
625 | 628 | $ hg update -q -C 5 |
|
626 | 629 | $ cat .hglf/large1 |
|
627 | 630 | e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
628 | 631 | $ cat large1 |
|
629 | 632 | large1 in #3 |
|
630 | 633 | $ hg diff -c 4 .hglf/largeX | grep '^[+-][0-9a-z]' |
|
631 | 634 | +fa44618ea25181aff4f48b70428294790cec9f61 |
|
632 | 635 | $ hg transplant 4 |
|
633 | 636 | applying 07d6153b5c04 |
|
634 | 637 | patching file .hglf/large1 |
|
635 | 638 | Hunk #1 FAILED at 0 |
|
636 | 639 | 1 out of 1 hunks FAILED -- saving rejects to file .hglf/large1.rej |
|
637 | 640 | patch failed to apply |
|
638 | 641 | abort: fix up the working directory and run hg transplant --continue |
|
639 | 642 | [255] |
|
640 | 643 | $ hg status -A large1 |
|
641 | 644 | C large1 |
|
642 | 645 | $ cat .hglf/large1 |
|
643 | 646 | e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
644 | 647 | $ cat large1 |
|
645 | 648 | large1 in #3 |
|
646 | 649 | $ hg status -A largeX |
|
647 | 650 | A largeX |
|
648 | 651 | $ cat .hglf/largeX |
|
649 | 652 | fa44618ea25181aff4f48b70428294790cec9f61 |
|
650 | 653 | $ cat largeX |
|
651 | 654 | largeX |
|
652 | 655 | |
|
653 | 656 | Test that transplant updates standins for manually modified largefiles |
|
654 | 657 | at the 1st commit of resuming. |
|
655 | 658 | |
|
656 | 659 | $ echo "manually modified before 'hg transplant --continue'" > large1 |
|
657 | 660 | $ hg transplant --continue |
|
658 | 661 | 07d6153b5c04 transplanted as f1bf30eb88cc |
|
659 | 662 | $ hg diff -c tip .hglf/large1 | grep '^[+-][0-9a-z]' |
|
660 | 663 | -e5bb990443d6a92aaf7223813720f7566c9dd05b |
|
661 | 664 | +6a4f36d4075fbe0f30ec1d26ca44e63c05903671 |
|
662 | 665 | $ rm -f large1 |
|
663 | 666 | $ hg update -q -C tip |
|
664 | 667 | $ cat large1 |
|
665 | 668 | manually modified before 'hg transplant --continue' |
|
666 | 669 | |
|
667 | 670 | Test that "hg status" doesn't show removal of largefiles not managed |
|
668 | 671 | in the target context. |
|
669 | 672 | |
|
670 | 673 | $ hg update -q -C 4 |
|
671 | 674 | $ hg remove largeX |
|
672 | 675 | $ hg status -A largeX |
|
673 | 676 | R largeX |
|
674 | 677 | $ hg status -A --rev '.^1' largeX |
|
675 | 678 | |
|
676 | 679 | #if execbit |
|
677 | 680 | |
|
678 | 681 | Test that "hg status" against revisions other than parent notices exec |
|
679 | 682 | bit changes of largefiles. |
|
680 | 683 | |
|
681 | 684 | $ hg update -q -C 4 |
|
682 | 685 | |
|
683 | 686 | (the case that large2 doesn't have exec bit in the target context but |
|
684 | 687 | in the working context) |
|
685 | 688 | |
|
686 | 689 | $ chmod +x large2 |
|
687 | 690 | $ hg status -A --rev 0 large2 |
|
688 | 691 | M large2 |
|
689 | 692 | $ hg commit -m 'chmod +x large2' |
|
690 | 693 | |
|
691 | 694 | (the case that large2 has exec bit in the target context but not in |
|
692 | 695 | the working context) |
|
693 | 696 | |
|
694 | 697 | $ echo dummy > dummy |
|
695 | 698 | $ hg add dummy |
|
696 | 699 | $ hg commit -m 'revision for separation' |
|
697 | 700 | $ chmod -x large2 |
|
698 | 701 | $ hg status -A --rev '.^1' large2 |
|
699 | 702 | M large2 |
|
700 | 703 | |
|
701 | 704 | #else |
|
702 | 705 | |
|
703 | 706 | Test that "hg status" against revisions other than parent ignores exec |
|
704 | 707 | bit correctly on the platform being unaware of it. |
|
705 | 708 | |
|
706 | 709 | $ hg update -q -C 4 |
|
707 | 710 | |
|
708 | 711 | $ cat > exec-bit.patch <<EOF |
|
709 | 712 | > # HG changeset patch |
|
710 | 713 | > # User test |
|
711 | 714 | > # Date 0 0 |
|
712 | 715 | > # Thu Jan 01 00:00:00 1970 +0000 |
|
713 | 716 | > # Node ID be1b433a65b12b27b5519d92213e14f7e1769b90 |
|
714 | 717 | > # Parent 07d6153b5c04313efb75deec9ba577de7faeb727 |
|
715 | 718 | > chmod +x large2 |
|
716 | 719 | > |
|
717 | 720 | > diff --git a/.hglf/large2 b/.hglf/large2 |
|
718 | 721 | > old mode 100644 |
|
719 | 722 | > new mode 100755 |
|
720 | 723 | > EOF |
|
721 | 724 | $ hg import --exact --bypass exec-bit.patch |
|
722 | 725 | applying exec-bit.patch |
|
723 | 726 | $ hg status -A --rev tip large2 |
|
724 | 727 | C large2 |
|
725 | 728 | |
|
726 | 729 | #endif |
|
727 | 730 | |
|
728 | 731 | $ cd .. |
|
729 | 732 | |
|
730 | 733 | Test that "hg convert" avoids copying largefiles from the working |
|
731 | 734 | directory into store, because "hg convert" doesn't update largefiles |
|
732 | 735 | in the working directory (removing files under ".cache/largefiles" |
|
733 | 736 | forces "hg convert" to copy corresponding largefiles) |
|
734 | 737 | |
|
735 | 738 | $ cat >> $HGRCPATH <<EOF |
|
736 | 739 | > [extensions] |
|
737 | 740 | > convert = |
|
738 | 741 | > EOF |
|
739 | 742 | |
|
740 | 743 | $ rm $TESTTMP/.cache/largefiles/6a4f36d4075fbe0f30ec1d26ca44e63c05903671 |
|
741 | 744 | $ hg convert -q repo repo.converted |
@@ -1,804 +1,810 | |||
|
1 | $ cat >> $HGRCPATH <<EOF | |
|
2 | > [defaults] | |
|
3 | > # for portability | |
|
4 | > extdiff = --option -Nru | |
|
5 | > EOF | |
|
6 | ||
|
1 | 7 | Preparing the subrepository 'sub2' |
|
2 | 8 | |
|
3 | 9 | $ hg init sub2 |
|
4 | 10 | $ echo sub2 > sub2/sub2 |
|
5 | 11 | $ hg add -R sub2 |
|
6 | 12 | adding sub2/sub2 (glob) |
|
7 | 13 | $ hg commit -R sub2 -m "sub2 import" |
|
8 | 14 | |
|
9 | 15 | Preparing the 'sub1' repo which depends on the subrepo 'sub2' |
|
10 | 16 | |
|
11 | 17 | $ hg init sub1 |
|
12 | 18 | $ echo sub1 > sub1/sub1 |
|
13 | 19 | $ echo "sub2 = ../sub2" > sub1/.hgsub |
|
14 | 20 | $ hg clone sub2 sub1/sub2 |
|
15 | 21 | updating to branch default |
|
16 | 22 | 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
17 | 23 | $ hg add -R sub1 |
|
18 | 24 | adding sub1/.hgsub (glob) |
|
19 | 25 | adding sub1/sub1 (glob) |
|
20 | 26 | $ hg commit -R sub1 -m "sub1 import" |
|
21 | 27 | |
|
22 | 28 | Preparing the 'main' repo which depends on the subrepo 'sub1' |
|
23 | 29 | |
|
24 | 30 | $ hg init main |
|
25 | 31 | $ echo main > main/main |
|
26 | 32 | $ echo "sub1 = ../sub1" > main/.hgsub |
|
27 | 33 | $ hg clone sub1 main/sub1 |
|
28 | 34 | updating to branch default |
|
29 | 35 | cloning subrepo sub2 from $TESTTMP/sub2 |
|
30 | 36 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
31 | 37 | $ hg add -R main |
|
32 | 38 | adding main/.hgsub (glob) |
|
33 | 39 | adding main/main (glob) |
|
34 | 40 | $ hg commit -R main -m "main import" |
|
35 | 41 | |
|
36 | 42 | Cleaning both repositories, just as a clone -U |
|
37 | 43 | |
|
38 | 44 | $ hg up -C -R sub2 null |
|
39 | 45 | 0 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
40 | 46 | $ hg up -C -R sub1 null |
|
41 | 47 | 0 files updated, 0 files merged, 3 files removed, 0 files unresolved |
|
42 | 48 | $ hg up -C -R main null |
|
43 | 49 | 0 files updated, 0 files merged, 3 files removed, 0 files unresolved |
|
44 | 50 | $ rm -rf main/sub1 |
|
45 | 51 | $ rm -rf sub1/sub2 |
|
46 | 52 | |
|
47 | 53 | Clone main |
|
48 | 54 | |
|
49 | 55 | $ hg --config extensions.largefiles= clone main cloned |
|
50 | 56 | updating to branch default |
|
51 | 57 | cloning subrepo sub1 from $TESTTMP/sub1 |
|
52 | 58 | cloning subrepo sub1/sub2 from $TESTTMP/sub2 (glob) |
|
53 | 59 | 3 files updated, 0 files merged, 0 files removed, 0 files unresolved |
|
54 | 60 | |
|
55 | 61 | Largefiles is NOT enabled in the clone if the source repo doesn't require it |
|
56 | 62 | $ cat cloned/.hg/hgrc |
|
57 | 63 | # example repository config (see "hg help config" for more info) |
|
58 | 64 | [paths] |
|
59 | 65 | default = $TESTTMP/main (glob) |
|
60 | 66 | |
|
61 | 67 | # path aliases to other clones of this repo in URLs or filesystem paths |
|
62 | 68 | # (see "hg help config.paths" for more info) |
|
63 | 69 | # |
|
64 | 70 | # default-push = ssh://jdoe@example.net/hg/jdoes-fork |
|
65 | 71 | # my-fork = ssh://jdoe@example.net/hg/jdoes-fork |
|
66 | 72 | # my-clone = /home/jdoe/jdoes-clone |
|
67 | 73 | |
|
68 | 74 | [ui] |
|
69 | 75 | # name and email (local to this repository, optional), e.g. |
|
70 | 76 | # username = Jane Doe <jdoe@example.com> |
|
71 | 77 | |
|
72 | 78 | Checking cloned repo ids |
|
73 | 79 | |
|
74 | 80 | $ printf "cloned " ; hg id -R cloned |
|
75 | 81 | cloned 7f491f53a367 tip |
|
76 | 82 | $ printf "cloned/sub1 " ; hg id -R cloned/sub1 |
|
77 | 83 | cloned/sub1 fc3b4ce2696f tip |
|
78 | 84 | $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2 |
|
79 | 85 | cloned/sub1/sub2 c57a0840e3ba tip |
|
80 | 86 | |
|
81 | 87 | debugsub output for main and sub1 |
|
82 | 88 | |
|
83 | 89 | $ hg debugsub -R cloned |
|
84 | 90 | path sub1 |
|
85 | 91 | source ../sub1 |
|
86 | 92 | revision fc3b4ce2696f7741438c79207583768f2ce6b0dd |
|
87 | 93 | $ hg debugsub -R cloned/sub1 |
|
88 | 94 | path sub2 |
|
89 | 95 | source ../sub2 |
|
90 | 96 | revision c57a0840e3badd667ef3c3ef65471609acb2ba3c |
|
91 | 97 | |
|
92 | 98 | Modifying deeply nested 'sub2' |
|
93 | 99 | |
|
94 | 100 | $ echo modified > cloned/sub1/sub2/sub2 |
|
95 | 101 | $ hg commit --subrepos -m "deep nested modif should trigger a commit" -R cloned |
|
96 | 102 | committing subrepository sub1 |
|
97 | 103 | committing subrepository sub1/sub2 (glob) |
|
98 | 104 | |
|
99 | 105 | Checking modified node ids |
|
100 | 106 | |
|
101 | 107 | $ printf "cloned " ; hg id -R cloned |
|
102 | 108 | cloned ffe6649062fe tip |
|
103 | 109 | $ printf "cloned/sub1 " ; hg id -R cloned/sub1 |
|
104 | 110 | cloned/sub1 2ecb03bf44a9 tip |
|
105 | 111 | $ printf "cloned/sub1/sub2 " ; hg id -R cloned/sub1/sub2 |
|
106 | 112 | cloned/sub1/sub2 53dd3430bcaf tip |
|
107 | 113 | |
|
108 | 114 | debugsub output for main and sub1 |
|
109 | 115 | |
|
110 | 116 | $ hg debugsub -R cloned |
|
111 | 117 | path sub1 |
|
112 | 118 | source ../sub1 |
|
113 | 119 | revision 2ecb03bf44a94e749e8669481dd9069526ce7cb9 |
|
114 | 120 | $ hg debugsub -R cloned/sub1 |
|
115 | 121 | path sub2 |
|
116 | 122 | source ../sub2 |
|
117 | 123 | revision 53dd3430bcaf5ab4a7c48262bcad6d441f510487 |
|
118 | 124 | |
|
119 | 125 | Check that deep archiving works |
|
120 | 126 | |
|
121 | 127 | $ cd cloned |
|
122 | 128 | $ echo 'test' > sub1/sub2/test.txt |
|
123 | 129 | $ hg --config extensions.largefiles=! add sub1/sub2/test.txt |
|
124 | 130 | $ mkdir sub1/sub2/folder |
|
125 | 131 | $ echo 'subfolder' > sub1/sub2/folder/test.txt |
|
126 | 132 | $ hg ci -ASm "add test.txt" |
|
127 | 133 | adding sub1/sub2/folder/test.txt |
|
128 | 134 | committing subrepository sub1 |
|
129 | 135 | committing subrepository sub1/sub2 (glob) |
|
130 | 136 | |
|
131 | 137 | .. but first take a detour through some deep removal testing |
|
132 | 138 | |
|
133 | 139 | $ hg remove -S -I 're:.*.txt' . |
|
134 | 140 | removing sub1/sub2/folder/test.txt (glob) |
|
135 | 141 | removing sub1/sub2/test.txt (glob) |
|
136 | 142 | $ hg status -S |
|
137 | 143 | R sub1/sub2/folder/test.txt |
|
138 | 144 | R sub1/sub2/test.txt |
|
139 | 145 | $ hg update -Cq |
|
140 | 146 | $ hg remove -I 're:.*.txt' sub1 |
|
141 | 147 | $ hg status -S |
|
142 | 148 | $ hg remove sub1/sub2/folder/test.txt |
|
143 | 149 | $ hg remove sub1/.hgsubstate |
|
144 | 150 | $ mv sub1/.hgsub sub1/x.hgsub |
|
145 | 151 | $ hg status -S |
|
146 | 152 | warning: subrepo spec file 'sub1/.hgsub' not found |
|
147 | 153 | R sub1/.hgsubstate |
|
148 | 154 | R sub1/sub2/folder/test.txt |
|
149 | 155 | ! sub1/.hgsub |
|
150 | 156 | ? sub1/x.hgsub |
|
151 | 157 | $ mv sub1/x.hgsub sub1/.hgsub |
|
152 | 158 | $ hg update -Cq |
|
153 | 159 | $ touch sub1/foo |
|
154 | 160 | $ hg forget sub1/sub2/folder/test.txt |
|
155 | 161 | $ rm sub1/sub2/test.txt |
|
156 | 162 | |
|
157 | 163 | Test relative path printing + subrepos |
|
158 | 164 | $ mkdir -p foo/bar |
|
159 | 165 | $ cd foo |
|
160 | 166 | $ touch bar/abc |
|
161 | 167 | $ hg addremove -S .. |
|
162 | 168 | adding ../sub1/sub2/folder/test.txt (glob) |
|
163 | 169 | removing ../sub1/sub2/test.txt (glob) |
|
164 | 170 | adding ../sub1/foo (glob) |
|
165 | 171 | adding bar/abc (glob) |
|
166 | 172 | $ cd .. |
|
167 | 173 | $ hg status -S |
|
168 | 174 | A foo/bar/abc |
|
169 | 175 | A sub1/foo |
|
170 | 176 | R sub1/sub2/test.txt |
|
171 | 177 | |
|
172 | 178 | Archive wdir() with subrepos |
|
173 | 179 | $ hg rm main |
|
174 | 180 | $ hg archive -S -r 'wdir()' ../wdir |
|
175 | 181 |
$ diff -r . ../wdir | egrep -v '\.hg$ |
|
176 | 182 | Only in ../wdir: .hg_archival.txt |
|
177 | 183 | |
|
178 | 184 | $ find ../wdir -type f | sort |
|
179 | 185 | ../wdir/.hg_archival.txt |
|
180 | 186 | ../wdir/.hgsub |
|
181 | 187 | ../wdir/.hgsubstate |
|
182 | 188 | ../wdir/foo/bar/abc |
|
183 | 189 | ../wdir/sub1/.hgsub |
|
184 | 190 | ../wdir/sub1/.hgsubstate |
|
185 | 191 | ../wdir/sub1/foo |
|
186 | 192 | ../wdir/sub1/sub1 |
|
187 | 193 | ../wdir/sub1/sub2/folder/test.txt |
|
188 | 194 | ../wdir/sub1/sub2/sub2 |
|
189 | 195 | |
|
190 | 196 | $ cat ../wdir/.hg_archival.txt |
|
191 | 197 | repo: 7f491f53a367861f47ee64a80eb997d1f341b77a |
|
192 | 198 | node: 9bb10eebee29dc0f1201dcf5977b811a540255fd+ |
|
193 | 199 | branch: default |
|
194 | 200 | latesttag: null |
|
195 | 201 | latesttagdistance: 4 |
|
196 | 202 | changessincelatesttag: 4 |
|
197 | 203 | |
|
198 | 204 | Attempting to archive 'wdir()' with a missing file is handled gracefully |
|
199 | 205 | $ rm sub1/sub1 |
|
200 | 206 | $ rm -r ../wdir |
|
201 | 207 | $ hg archive -v -S -r 'wdir()' ../wdir |
|
202 | 208 | $ find ../wdir -type f | sort |
|
203 | 209 | ../wdir/.hg_archival.txt |
|
204 | 210 | ../wdir/.hgsub |
|
205 | 211 | ../wdir/.hgsubstate |
|
206 | 212 | ../wdir/foo/bar/abc |
|
207 | 213 | ../wdir/sub1/.hgsub |
|
208 | 214 | ../wdir/sub1/.hgsubstate |
|
209 | 215 | ../wdir/sub1/foo |
|
210 | 216 | ../wdir/sub1/sub2/folder/test.txt |
|
211 | 217 | ../wdir/sub1/sub2/sub2 |
|
212 | 218 | |
|
213 | 219 | Continue relative path printing + subrepos |
|
214 | 220 | $ hg update -Cq |
|
215 | 221 | $ rm -r ../wdir |
|
216 | 222 | $ hg archive -S -r 'wdir()' ../wdir |
|
217 | 223 | $ cat ../wdir/.hg_archival.txt |
|
218 | 224 | repo: 7f491f53a367861f47ee64a80eb997d1f341b77a |
|
219 | 225 | node: 9bb10eebee29dc0f1201dcf5977b811a540255fd |
|
220 | 226 | branch: default |
|
221 | 227 | latesttag: null |
|
222 | 228 | latesttagdistance: 4 |
|
223 | 229 | changessincelatesttag: 4 |
|
224 | 230 | |
|
225 | 231 | $ touch sub1/sub2/folder/bar |
|
226 | 232 | $ hg addremove sub1/sub2 |
|
227 | 233 | adding sub1/sub2/folder/bar (glob) |
|
228 | 234 | $ hg status -S |
|
229 | 235 | A sub1/sub2/folder/bar |
|
230 | 236 | ? foo/bar/abc |
|
231 | 237 | ? sub1/foo |
|
232 | 238 | $ hg update -Cq |
|
233 | 239 | $ hg addremove sub1 |
|
234 | 240 | adding sub1/sub2/folder/bar (glob) |
|
235 | 241 | adding sub1/foo (glob) |
|
236 | 242 | $ hg update -Cq |
|
237 | 243 | $ rm sub1/sub2/folder/test.txt |
|
238 | 244 | $ rm sub1/sub2/test.txt |
|
239 | 245 | $ hg ci -ASm "remove test.txt" |
|
240 | 246 | adding sub1/sub2/folder/bar |
|
241 | 247 | removing sub1/sub2/folder/test.txt |
|
242 | 248 | removing sub1/sub2/test.txt |
|
243 | 249 | adding sub1/foo |
|
244 | 250 | adding foo/bar/abc |
|
245 | 251 | committing subrepository sub1 |
|
246 | 252 | committing subrepository sub1/sub2 (glob) |
|
247 | 253 | |
|
248 | 254 | $ hg forget sub1/sub2/sub2 |
|
249 | 255 | $ echo x > sub1/sub2/x.txt |
|
250 | 256 | $ hg add sub1/sub2/x.txt |
|
251 | 257 | |
|
252 | 258 | Files sees uncommitted adds and removes in subrepos |
|
253 | 259 | $ hg files -S |
|
254 | 260 | .hgsub |
|
255 | 261 | .hgsubstate |
|
256 | 262 | foo/bar/abc (glob) |
|
257 | 263 | main |
|
258 | 264 | sub1/.hgsub (glob) |
|
259 | 265 | sub1/.hgsubstate (glob) |
|
260 | 266 | sub1/foo (glob) |
|
261 | 267 | sub1/sub1 (glob) |
|
262 | 268 | sub1/sub2/folder/bar (glob) |
|
263 | 269 | sub1/sub2/x.txt (glob) |
|
264 | 270 | |
|
265 | 271 | $ hg files -S "set:eol('dos') or eol('unix') or size('<= 0')" |
|
266 | 272 | .hgsub |
|
267 | 273 | .hgsubstate |
|
268 | 274 | foo/bar/abc (glob) |
|
269 | 275 | main |
|
270 | 276 | sub1/.hgsub (glob) |
|
271 | 277 | sub1/.hgsubstate (glob) |
|
272 | 278 | sub1/foo (glob) |
|
273 | 279 | sub1/sub1 (glob) |
|
274 | 280 | sub1/sub2/folder/bar (glob) |
|
275 | 281 | sub1/sub2/x.txt (glob) |
|
276 | 282 | |
|
277 | 283 | $ hg files -r '.^' -S "set:eol('dos') or eol('unix')" |
|
278 | 284 | .hgsub |
|
279 | 285 | .hgsubstate |
|
280 | 286 | main |
|
281 | 287 | sub1/.hgsub (glob) |
|
282 | 288 | sub1/.hgsubstate (glob) |
|
283 | 289 | sub1/sub1 (glob) |
|
284 | 290 | sub1/sub2/folder/test.txt (glob) |
|
285 | 291 | sub1/sub2/sub2 (glob) |
|
286 | 292 | sub1/sub2/test.txt (glob) |
|
287 | 293 | |
|
288 | 294 | $ hg files sub1 |
|
289 | 295 | sub1/.hgsub (glob) |
|
290 | 296 | sub1/.hgsubstate (glob) |
|
291 | 297 | sub1/foo (glob) |
|
292 | 298 | sub1/sub1 (glob) |
|
293 | 299 | sub1/sub2/folder/bar (glob) |
|
294 | 300 | sub1/sub2/x.txt (glob) |
|
295 | 301 | |
|
296 | 302 | $ hg files sub1/sub2 |
|
297 | 303 | sub1/sub2/folder/bar (glob) |
|
298 | 304 | sub1/sub2/x.txt (glob) |
|
299 | 305 | |
|
300 | 306 | $ hg files -S -r '.^' sub1/sub2/folder |
|
301 | 307 | sub1/sub2/folder/test.txt (glob) |
|
302 | 308 | |
|
303 | 309 | $ hg files -S -r '.^' sub1/sub2/missing |
|
304 | 310 | sub1/sub2/missing: no such file in rev 78026e779ea6 (glob) |
|
305 | 311 | [1] |
|
306 | 312 | |
|
307 | 313 | $ hg files -r '.^' sub1/ |
|
308 | 314 | sub1/.hgsub (glob) |
|
309 | 315 | sub1/.hgsubstate (glob) |
|
310 | 316 | sub1/sub1 (glob) |
|
311 | 317 | sub1/sub2/folder/test.txt (glob) |
|
312 | 318 | sub1/sub2/sub2 (glob) |
|
313 | 319 | sub1/sub2/test.txt (glob) |
|
314 | 320 | |
|
315 | 321 | $ hg files -r '.^' sub1/sub2 |
|
316 | 322 | sub1/sub2/folder/test.txt (glob) |
|
317 | 323 | sub1/sub2/sub2 (glob) |
|
318 | 324 | sub1/sub2/test.txt (glob) |
|
319 | 325 | |
|
320 | 326 | $ hg rollback -q |
|
321 | 327 | $ hg up -Cq |
|
322 | 328 | |
|
323 | 329 | $ hg --config extensions.largefiles=! archive -S ../archive_all |
|
324 | 330 | $ find ../archive_all | sort |
|
325 | 331 | ../archive_all |
|
326 | 332 | ../archive_all/.hg_archival.txt |
|
327 | 333 | ../archive_all/.hgsub |
|
328 | 334 | ../archive_all/.hgsubstate |
|
329 | 335 | ../archive_all/main |
|
330 | 336 | ../archive_all/sub1 |
|
331 | 337 | ../archive_all/sub1/.hgsub |
|
332 | 338 | ../archive_all/sub1/.hgsubstate |
|
333 | 339 | ../archive_all/sub1/sub1 |
|
334 | 340 | ../archive_all/sub1/sub2 |
|
335 | 341 | ../archive_all/sub1/sub2/folder |
|
336 | 342 | ../archive_all/sub1/sub2/folder/test.txt |
|
337 | 343 | ../archive_all/sub1/sub2/sub2 |
|
338 | 344 | ../archive_all/sub1/sub2/test.txt |
|
339 | 345 | |
|
340 | 346 | Check that archive -X works in deep subrepos |
|
341 | 347 | |
|
342 | 348 | $ hg --config extensions.largefiles=! archive -S -X '**test*' ../archive_exclude |
|
343 | 349 | $ find ../archive_exclude | sort |
|
344 | 350 | ../archive_exclude |
|
345 | 351 | ../archive_exclude/.hg_archival.txt |
|
346 | 352 | ../archive_exclude/.hgsub |
|
347 | 353 | ../archive_exclude/.hgsubstate |
|
348 | 354 | ../archive_exclude/main |
|
349 | 355 | ../archive_exclude/sub1 |
|
350 | 356 | ../archive_exclude/sub1/.hgsub |
|
351 | 357 | ../archive_exclude/sub1/.hgsubstate |
|
352 | 358 | ../archive_exclude/sub1/sub1 |
|
353 | 359 | ../archive_exclude/sub1/sub2 |
|
354 | 360 | ../archive_exclude/sub1/sub2/sub2 |
|
355 | 361 | |
|
356 | 362 | $ hg --config extensions.largefiles=! archive -S -I '**test*' ../archive_include |
|
357 | 363 | $ find ../archive_include | sort |
|
358 | 364 | ../archive_include |
|
359 | 365 | ../archive_include/sub1 |
|
360 | 366 | ../archive_include/sub1/sub2 |
|
361 | 367 | ../archive_include/sub1/sub2/folder |
|
362 | 368 | ../archive_include/sub1/sub2/folder/test.txt |
|
363 | 369 | ../archive_include/sub1/sub2/test.txt |
|
364 | 370 | |
|
365 | 371 | Check that deep archive works with largefiles (which overrides hgsubrepo impl) |
|
366 | 372 | This also tests the repo.ui regression in 43fb170a23bd, and that lf subrepo |
|
367 | 373 | subrepos are archived properly. |
|
368 | 374 | Note that add --large through a subrepo currently adds the file as a normal file |
|
369 | 375 | |
|
370 | 376 | $ echo "large" > sub1/sub2/large.bin |
|
371 | 377 | $ hg --config extensions.largefiles= add --large -R sub1/sub2 sub1/sub2/large.bin |
|
372 | 378 | $ echo "large" > large.bin |
|
373 | 379 | $ hg --config extensions.largefiles= add --large large.bin |
|
374 | 380 | $ hg --config extensions.largefiles= ci -S -m "add large files" |
|
375 | 381 | committing subrepository sub1 |
|
376 | 382 | committing subrepository sub1/sub2 (glob) |
|
377 | 383 | |
|
378 | 384 | $ hg --config extensions.largefiles= archive -S ../archive_lf |
|
379 | 385 | $ find ../archive_lf | sort |
|
380 | 386 | ../archive_lf |
|
381 | 387 | ../archive_lf/.hg_archival.txt |
|
382 | 388 | ../archive_lf/.hgsub |
|
383 | 389 | ../archive_lf/.hgsubstate |
|
384 | 390 | ../archive_lf/large.bin |
|
385 | 391 | ../archive_lf/main |
|
386 | 392 | ../archive_lf/sub1 |
|
387 | 393 | ../archive_lf/sub1/.hgsub |
|
388 | 394 | ../archive_lf/sub1/.hgsubstate |
|
389 | 395 | ../archive_lf/sub1/sub1 |
|
390 | 396 | ../archive_lf/sub1/sub2 |
|
391 | 397 | ../archive_lf/sub1/sub2/folder |
|
392 | 398 | ../archive_lf/sub1/sub2/folder/test.txt |
|
393 | 399 | ../archive_lf/sub1/sub2/large.bin |
|
394 | 400 | ../archive_lf/sub1/sub2/sub2 |
|
395 | 401 | ../archive_lf/sub1/sub2/test.txt |
|
396 | 402 | $ rm -rf ../archive_lf |
|
397 | 403 | |
|
398 | 404 | Exclude large files from main and sub-sub repo |
|
399 | 405 | |
|
400 | 406 | $ hg --config extensions.largefiles= archive -S -X '**.bin' ../archive_lf |
|
401 | 407 | $ find ../archive_lf | sort |
|
402 | 408 | ../archive_lf |
|
403 | 409 | ../archive_lf/.hg_archival.txt |
|
404 | 410 | ../archive_lf/.hgsub |
|
405 | 411 | ../archive_lf/.hgsubstate |
|
406 | 412 | ../archive_lf/main |
|
407 | 413 | ../archive_lf/sub1 |
|
408 | 414 | ../archive_lf/sub1/.hgsub |
|
409 | 415 | ../archive_lf/sub1/.hgsubstate |
|
410 | 416 | ../archive_lf/sub1/sub1 |
|
411 | 417 | ../archive_lf/sub1/sub2 |
|
412 | 418 | ../archive_lf/sub1/sub2/folder |
|
413 | 419 | ../archive_lf/sub1/sub2/folder/test.txt |
|
414 | 420 | ../archive_lf/sub1/sub2/sub2 |
|
415 | 421 | ../archive_lf/sub1/sub2/test.txt |
|
416 | 422 | $ rm -rf ../archive_lf |
|
417 | 423 | |
|
418 | 424 | Exclude normal files from main and sub-sub repo |
|
419 | 425 | |
|
420 | 426 | $ hg --config extensions.largefiles= archive -S -X '**.txt' -p '.' ../archive_lf.tgz |
|
421 | 427 | $ tar -tzf ../archive_lf.tgz | sort |
|
422 | 428 | .hgsub |
|
423 | 429 | .hgsubstate |
|
424 | 430 | large.bin |
|
425 | 431 | main |
|
426 | 432 | sub1/.hgsub |
|
427 | 433 | sub1/.hgsubstate |
|
428 | 434 | sub1/sub1 |
|
429 | 435 | sub1/sub2/large.bin |
|
430 | 436 | sub1/sub2/sub2 |
|
431 | 437 | |
|
432 | 438 | Include normal files from within a largefiles subrepo |
|
433 | 439 | |
|
434 | 440 | $ hg --config extensions.largefiles= archive -S -I '**.txt' ../archive_lf |
|
435 | 441 | $ find ../archive_lf | sort |
|
436 | 442 | ../archive_lf |
|
437 | 443 | ../archive_lf/.hg_archival.txt |
|
438 | 444 | ../archive_lf/sub1 |
|
439 | 445 | ../archive_lf/sub1/sub2 |
|
440 | 446 | ../archive_lf/sub1/sub2/folder |
|
441 | 447 | ../archive_lf/sub1/sub2/folder/test.txt |
|
442 | 448 | ../archive_lf/sub1/sub2/test.txt |
|
443 | 449 | $ rm -rf ../archive_lf |
|
444 | 450 | |
|
445 | 451 | Include large files from within a largefiles subrepo |
|
446 | 452 | |
|
447 | 453 | $ hg --config extensions.largefiles= archive -S -I '**.bin' ../archive_lf |
|
448 | 454 | $ find ../archive_lf | sort |
|
449 | 455 | ../archive_lf |
|
450 | 456 | ../archive_lf/large.bin |
|
451 | 457 | ../archive_lf/sub1 |
|
452 | 458 | ../archive_lf/sub1/sub2 |
|
453 | 459 | ../archive_lf/sub1/sub2/large.bin |
|
454 | 460 | $ rm -rf ../archive_lf |
|
455 | 461 | |
|
456 | 462 | Find an exact largefile match in a largefiles subrepo |
|
457 | 463 | |
|
458 | 464 | $ hg --config extensions.largefiles= archive -S -I 'sub1/sub2/large.bin' ../archive_lf |
|
459 | 465 | $ find ../archive_lf | sort |
|
460 | 466 | ../archive_lf |
|
461 | 467 | ../archive_lf/sub1 |
|
462 | 468 | ../archive_lf/sub1/sub2 |
|
463 | 469 | ../archive_lf/sub1/sub2/large.bin |
|
464 | 470 | $ rm -rf ../archive_lf |
|
465 | 471 | |
|
466 | 472 | The local repo enables largefiles if a largefiles repo is cloned |
|
467 | 473 | $ hg showconfig extensions |
|
468 | 474 | abort: repository requires features unknown to this Mercurial: largefiles! |
|
469 | 475 | (see https://mercurial-scm.org/wiki/MissingRequirement for more information) |
|
470 | 476 | [255] |
|
471 | 477 | $ hg --config extensions.largefiles= clone -qU . ../lfclone |
|
472 | 478 | $ cat ../lfclone/.hg/hgrc |
|
473 | 479 | # example repository config (see "hg help config" for more info) |
|
474 | 480 | [paths] |
|
475 | 481 | default = $TESTTMP/cloned (glob) |
|
476 | 482 | |
|
477 | 483 | # path aliases to other clones of this repo in URLs or filesystem paths |
|
478 | 484 | # (see "hg help config.paths" for more info) |
|
479 | 485 | # |
|
480 | 486 | # default-push = ssh://jdoe@example.net/hg/jdoes-fork |
|
481 | 487 | # my-fork = ssh://jdoe@example.net/hg/jdoes-fork |
|
482 | 488 | # my-clone = /home/jdoe/jdoes-clone |
|
483 | 489 | |
|
484 | 490 | [ui] |
|
485 | 491 | # name and email (local to this repository, optional), e.g. |
|
486 | 492 | # username = Jane Doe <jdoe@example.com> |
|
487 | 493 | |
|
488 | 494 | [extensions] |
|
489 | 495 | largefiles= |
|
490 | 496 | |
|
491 | 497 | Find an exact match to a standin (should archive nothing) |
|
492 | 498 | $ hg --config extensions.largefiles= archive -S -I 'sub/sub2/.hglf/large.bin' ../archive_lf |
|
493 | 499 | $ find ../archive_lf 2> /dev/null | sort |
|
494 | 500 | |
|
495 | 501 | $ cat >> $HGRCPATH <<EOF |
|
496 | 502 | > [extensions] |
|
497 | 503 | > largefiles= |
|
498 | 504 | > [largefiles] |
|
499 | 505 | > patterns=glob:**.dat |
|
500 | 506 | > EOF |
|
501 | 507 | |
|
502 | 508 | Test forget through a deep subrepo with the largefiles extension, both a |
|
503 | 509 | largefile and a normal file. Then a largefile that hasn't been committed yet. |
|
504 | 510 | $ touch sub1/sub2/untracked.txt |
|
505 | 511 | $ touch sub1/sub2/large.dat |
|
506 | 512 | $ hg forget sub1/sub2/large.bin sub1/sub2/test.txt sub1/sub2/untracked.txt |
|
507 | 513 | not removing sub1/sub2/untracked.txt: file is already untracked (glob) |
|
508 | 514 | [1] |
|
509 | 515 | $ hg add --large --dry-run -v sub1/sub2/untracked.txt |
|
510 | 516 | adding sub1/sub2/untracked.txt as a largefile (glob) |
|
511 | 517 | $ hg add --large -v sub1/sub2/untracked.txt |
|
512 | 518 | adding sub1/sub2/untracked.txt as a largefile (glob) |
|
513 | 519 | $ hg add --normal -v sub1/sub2/large.dat |
|
514 | 520 | adding sub1/sub2/large.dat (glob) |
|
515 | 521 | $ hg forget -v sub1/sub2/untracked.txt |
|
516 | 522 | removing sub1/sub2/untracked.txt (glob) |
|
517 | 523 | $ hg status -S |
|
518 | 524 | A sub1/sub2/large.dat |
|
519 | 525 | R sub1/sub2/large.bin |
|
520 | 526 | R sub1/sub2/test.txt |
|
521 | 527 | ? foo/bar/abc |
|
522 | 528 | ? sub1/sub2/untracked.txt |
|
523 | 529 | ? sub1/sub2/x.txt |
|
524 | 530 | $ hg add sub1/sub2 |
|
525 | 531 | |
|
526 | 532 | $ hg archive -S -r 'wdir()' ../wdir2 |
|
527 | 533 | $ diff -r . ../wdir2 | egrep -v '\.hg$|^Common subdirectories:' |
|
528 | 534 | Only in ../wdir2: .hg_archival.txt |
|
529 | 535 | Only in .: .hglf |
|
530 | 536 | Only in .: foo |
|
531 | 537 | Only in ./sub1/sub2: large.bin |
|
532 | 538 | Only in ./sub1/sub2: test.txt |
|
533 | 539 | Only in ./sub1/sub2: untracked.txt |
|
534 | 540 | Only in ./sub1/sub2: x.txt |
|
535 | 541 | $ find ../wdir2 -type f | sort |
|
536 | 542 | ../wdir2/.hg_archival.txt |
|
537 | 543 | ../wdir2/.hgsub |
|
538 | 544 | ../wdir2/.hgsubstate |
|
539 | 545 | ../wdir2/large.bin |
|
540 | 546 | ../wdir2/main |
|
541 | 547 | ../wdir2/sub1/.hgsub |
|
542 | 548 | ../wdir2/sub1/.hgsubstate |
|
543 | 549 | ../wdir2/sub1/sub1 |
|
544 | 550 | ../wdir2/sub1/sub2/folder/test.txt |
|
545 | 551 | ../wdir2/sub1/sub2/large.dat |
|
546 | 552 | ../wdir2/sub1/sub2/sub2 |
|
547 | 553 | $ hg status -S -mac -n | sort |
|
548 | 554 | .hgsub |
|
549 | 555 | .hgsubstate |
|
550 | 556 | large.bin |
|
551 | 557 | main |
|
552 | 558 | sub1/.hgsub |
|
553 | 559 | sub1/.hgsubstate |
|
554 | 560 | sub1/sub1 |
|
555 | 561 | sub1/sub2/folder/test.txt |
|
556 | 562 | sub1/sub2/large.dat |
|
557 | 563 | sub1/sub2/sub2 |
|
558 | 564 | |
|
559 | 565 | $ hg ci -Sqm 'forget testing' |
|
560 | 566 | |
|
561 | 567 | Test 'wdir()' modified file archiving with largefiles |
|
562 | 568 | $ echo 'mod' > main |
|
563 | 569 | $ echo 'mod' > large.bin |
|
564 | 570 | $ echo 'mod' > sub1/sub2/large.dat |
|
565 | 571 | $ hg archive -S -r 'wdir()' ../wdir3 |
|
566 | 572 | $ diff -r . ../wdir3 | egrep -v '\.hg$|^Common subdirectories' |
|
567 | 573 | Only in ../wdir3: .hg_archival.txt |
|
568 | 574 | Only in .: .hglf |
|
569 | 575 | Only in .: foo |
|
570 | 576 | Only in ./sub1/sub2: large.bin |
|
571 | 577 | Only in ./sub1/sub2: test.txt |
|
572 | 578 | Only in ./sub1/sub2: untracked.txt |
|
573 | 579 | Only in ./sub1/sub2: x.txt |
|
574 | 580 | $ find ../wdir3 -type f | sort |
|
575 | 581 | ../wdir3/.hg_archival.txt |
|
576 | 582 | ../wdir3/.hgsub |
|
577 | 583 | ../wdir3/.hgsubstate |
|
578 | 584 | ../wdir3/large.bin |
|
579 | 585 | ../wdir3/main |
|
580 | 586 | ../wdir3/sub1/.hgsub |
|
581 | 587 | ../wdir3/sub1/.hgsubstate |
|
582 | 588 | ../wdir3/sub1/sub1 |
|
583 | 589 | ../wdir3/sub1/sub2/folder/test.txt |
|
584 | 590 | ../wdir3/sub1/sub2/large.dat |
|
585 | 591 | ../wdir3/sub1/sub2/sub2 |
|
586 | 592 | $ hg up -Cq |
|
587 | 593 | |
|
588 | 594 | Test issue4330: commit a directory where only normal files have changed |
|
589 | 595 | $ touch foo/bar/large.dat |
|
590 | 596 | $ hg add --large foo/bar/large.dat |
|
591 | 597 | $ hg ci -m 'add foo/bar/large.dat' |
|
592 | 598 | $ touch a.txt |
|
593 | 599 | $ touch a.dat |
|
594 | 600 | $ hg add -v foo/bar/abc a.txt a.dat |
|
595 | 601 | adding a.dat as a largefile |
|
596 | 602 | adding a.txt |
|
597 | 603 | adding foo/bar/abc (glob) |
|
598 | 604 | $ hg ci -m 'dir commit with only normal file deltas' foo/bar |
|
599 | 605 | $ hg status |
|
600 | 606 | A a.dat |
|
601 | 607 | A a.txt |
|
602 | 608 | |
|
603 | 609 | Test a directory commit with a changed largefile and a changed normal file |
|
604 | 610 | $ echo changed > foo/bar/large.dat |
|
605 | 611 | $ echo changed > foo/bar/abc |
|
606 | 612 | $ hg ci -m 'dir commit with normal and lf file deltas' foo |
|
607 | 613 | $ hg status |
|
608 | 614 | A a.dat |
|
609 | 615 | A a.txt |
|
610 | 616 | |
|
611 | 617 | $ hg ci -m "add a.*" |
|
612 | 618 | $ hg mv a.dat b.dat |
|
613 | 619 | $ hg mv foo/bar/abc foo/bar/def |
|
614 | 620 | $ hg status -C |
|
615 | 621 | A b.dat |
|
616 | 622 | a.dat |
|
617 | 623 | A foo/bar/def |
|
618 | 624 | foo/bar/abc |
|
619 | 625 | R a.dat |
|
620 | 626 | R foo/bar/abc |
|
621 | 627 | |
|
622 | 628 | $ hg ci -m "move large and normal" |
|
623 | 629 | $ hg status -C --rev '.^' --rev . |
|
624 | 630 | A b.dat |
|
625 | 631 | a.dat |
|
626 | 632 | A foo/bar/def |
|
627 | 633 | foo/bar/abc |
|
628 | 634 | R a.dat |
|
629 | 635 | R foo/bar/abc |
|
630 | 636 | |
|
631 | 637 | |
|
632 | 638 | $ echo foo > main |
|
633 | 639 | $ hg ci -m "mod parent only" |
|
634 | 640 | $ hg init sub3 |
|
635 | 641 | $ echo "sub3 = sub3" >> .hgsub |
|
636 | 642 | $ echo xyz > sub3/a.txt |
|
637 | 643 | $ hg add sub3/a.txt |
|
638 | 644 | $ hg ci -Sm "add sub3" |
|
639 | 645 | committing subrepository sub3 |
|
640 | 646 | $ cat .hgsub | grep -v sub3 > .hgsub1 |
|
641 | 647 | $ mv .hgsub1 .hgsub |
|
642 | 648 | $ hg ci -m "remove sub3" |
|
643 | 649 | |
|
644 | 650 | $ hg log -r "subrepo()" --style compact |
|
645 | 651 | 0 7f491f53a367 1970-01-01 00:00 +0000 test |
|
646 | 652 | main import |
|
647 | 653 | |
|
648 | 654 | 1 ffe6649062fe 1970-01-01 00:00 +0000 test |
|
649 | 655 | deep nested modif should trigger a commit |
|
650 | 656 | |
|
651 | 657 | 2 9bb10eebee29 1970-01-01 00:00 +0000 test |
|
652 | 658 | add test.txt |
|
653 | 659 | |
|
654 | 660 | 3 7c64f035294f 1970-01-01 00:00 +0000 test |
|
655 | 661 | add large files |
|
656 | 662 | |
|
657 | 663 | 4 f734a59e2e35 1970-01-01 00:00 +0000 test |
|
658 | 664 | forget testing |
|
659 | 665 | |
|
660 | 666 | 11 9685a22af5db 1970-01-01 00:00 +0000 test |
|
661 | 667 | add sub3 |
|
662 | 668 | |
|
663 | 669 | 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test |
|
664 | 670 | remove sub3 |
|
665 | 671 | |
|
666 | 672 | $ hg log -r "subrepo('sub3')" --style compact |
|
667 | 673 | 11 9685a22af5db 1970-01-01 00:00 +0000 test |
|
668 | 674 | add sub3 |
|
669 | 675 | |
|
670 | 676 | 12[tip] 2e0485b475b9 1970-01-01 00:00 +0000 test |
|
671 | 677 | remove sub3 |
|
672 | 678 | |
|
673 | 679 | $ hg log -r "subrepo('bogus')" --style compact |
|
674 | 680 | |
|
675 | 681 | |
|
676 | 682 | Test .hgsubstate in the R state |
|
677 | 683 | |
|
678 | 684 | $ hg rm .hgsub .hgsubstate |
|
679 | 685 | $ hg ci -m 'trash subrepo tracking' |
|
680 | 686 | |
|
681 | 687 | $ hg log -r "subrepo('re:sub\d+')" --style compact |
|
682 | 688 | 0 7f491f53a367 1970-01-01 00:00 +0000 test |
|
683 | 689 | main import |
|
684 | 690 | |
|
685 | 691 | 1 ffe6649062fe 1970-01-01 00:00 +0000 test |
|
686 | 692 | deep nested modif should trigger a commit |
|
687 | 693 | |
|
688 | 694 | 2 9bb10eebee29 1970-01-01 00:00 +0000 test |
|
689 | 695 | add test.txt |
|
690 | 696 | |
|
691 | 697 | 3 7c64f035294f 1970-01-01 00:00 +0000 test |
|
692 | 698 | add large files |
|
693 | 699 | |
|
694 | 700 | 4 f734a59e2e35 1970-01-01 00:00 +0000 test |
|
695 | 701 | forget testing |
|
696 | 702 | |
|
697 | 703 | 11 9685a22af5db 1970-01-01 00:00 +0000 test |
|
698 | 704 | add sub3 |
|
699 | 705 | |
|
700 | 706 | 12 2e0485b475b9 1970-01-01 00:00 +0000 test |
|
701 | 707 | remove sub3 |
|
702 | 708 | |
|
703 | 709 | 13[tip] a68b2c361653 1970-01-01 00:00 +0000 test |
|
704 | 710 | trash subrepo tracking |
|
705 | 711 | |
|
706 | 712 | |
|
707 | 713 | Restore the trashed subrepo tracking |
|
708 | 714 | |
|
709 | 715 | $ hg rollback -q |
|
710 | 716 | $ hg update -Cq . |
|
711 | 717 | |
|
712 | 718 | Interaction with extdiff, largefiles and subrepos |
|
713 | 719 | |
|
714 | 720 | $ hg --config extensions.extdiff= extdiff -S |
|
715 | 721 | |
|
716 | 722 | $ hg --config extensions.extdiff= extdiff -r '.^' -S |
|
717 |
diff -N |
|
|
723 | diff -Nru cloned.*/.hgsub cloned/.hgsub (glob) | |
|
718 | 724 | --- cloned.*/.hgsub * +0000 (glob) |
|
719 | 725 | +++ cloned/.hgsub * +0000 (glob) |
|
720 | 726 | @@ -1,2 +1 @@ |
|
721 | 727 | sub1 = ../sub1 |
|
722 | 728 | -sub3 = sub3 |
|
723 |
diff -N |
|
|
729 | diff -Nru cloned.*/.hgsubstate cloned/.hgsubstate (glob) | |
|
724 | 730 | --- cloned.*/.hgsubstate * +0000 (glob) |
|
725 | 731 | +++ cloned/.hgsubstate * +0000 (glob) |
|
726 | 732 | @@ -1,2 +1 @@ |
|
727 | 733 | 7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1 |
|
728 | 734 | -b1a26de6f2a045a9f079323693614ee322f1ff7e sub3 |
|
729 | 735 | [1] |
|
730 | 736 | |
|
731 | 737 | $ hg --config extensions.extdiff= extdiff -r 0 -r '.^' -S |
|
732 |
diff -N |
|
|
738 | diff -Nru cloned.*/.hglf/b.dat cloned.*/.hglf/b.dat (glob) | |
|
733 | 739 | --- cloned.*/.hglf/b.dat * (glob) |
|
734 | 740 | +++ cloned.*/.hglf/b.dat * (glob) |
|
735 | 741 | @@ -0,0 +1 @@ |
|
736 | 742 | +da39a3ee5e6b4b0d3255bfef95601890afd80709 |
|
737 |
diff -N |
|
|
743 | diff -Nru cloned.*/.hglf/foo/bar/large.dat cloned.*/.hglf/foo/bar/large.dat (glob) | |
|
738 | 744 | --- cloned.*/.hglf/foo/bar/large.dat * (glob) |
|
739 | 745 | +++ cloned.*/.hglf/foo/bar/large.dat * (glob) |
|
740 | 746 | @@ -0,0 +1 @@ |
|
741 | 747 | +2f6933b5ee0f5fdd823d9717d8729f3c2523811b |
|
742 |
diff -N |
|
|
748 | diff -Nru cloned.*/.hglf/large.bin cloned.*/.hglf/large.bin (glob) | |
|
743 | 749 | --- cloned.*/.hglf/large.bin * (glob) |
|
744 | 750 | +++ cloned.*/.hglf/large.bin * (glob) |
|
745 | 751 | @@ -0,0 +1 @@ |
|
746 | 752 | +7f7097b041ccf68cc5561e9600da4655d21c6d18 |
|
747 |
diff -N |
|
|
753 | diff -Nru cloned.*/.hgsub cloned.*/.hgsub (glob) | |
|
748 | 754 | --- cloned.*/.hgsub * (glob) |
|
749 | 755 | +++ cloned.*/.hgsub * (glob) |
|
750 | 756 | @@ -1 +1,2 @@ |
|
751 | 757 | sub1 = ../sub1 |
|
752 | 758 | +sub3 = sub3 |
|
753 |
diff -N |
|
|
759 | diff -Nru cloned.*/.hgsubstate cloned.*/.hgsubstate (glob) | |
|
754 | 760 | --- cloned.*/.hgsubstate * (glob) |
|
755 | 761 | +++ cloned.*/.hgsubstate * (glob) |
|
756 | 762 | @@ -1 +1,2 @@ |
|
757 | 763 | -fc3b4ce2696f7741438c79207583768f2ce6b0dd sub1 |
|
758 | 764 | +7a36fa02b66e61f27f3d4a822809f159479b8ab2 sub1 |
|
759 | 765 | +b1a26de6f2a045a9f079323693614ee322f1ff7e sub3 |
|
760 |
diff -N |
|
|
766 | diff -Nru cloned.*/foo/bar/def cloned.*/foo/bar/def (glob) | |
|
761 | 767 | --- cloned.*/foo/bar/def * (glob) |
|
762 | 768 | +++ cloned.*/foo/bar/def * (glob) |
|
763 | 769 | @@ -0,0 +1 @@ |
|
764 | 770 | +changed |
|
765 |
diff -N |
|
|
771 | diff -Nru cloned.*/main cloned.*/main (glob) | |
|
766 | 772 | --- cloned.*/main * (glob) |
|
767 | 773 | +++ cloned.*/main * (glob) |
|
768 | 774 | @@ -1 +1 @@ |
|
769 | 775 | -main |
|
770 | 776 | +foo |
|
771 |
diff -N |
|
|
777 | diff -Nru cloned.*/sub1/.hgsubstate cloned.*/sub1/.hgsubstate (glob) | |
|
772 | 778 | --- cloned.*/sub1/.hgsubstate * (glob) |
|
773 | 779 | +++ cloned.*/sub1/.hgsubstate * (glob) |
|
774 | 780 | @@ -1 +1 @@ |
|
775 | 781 | -c57a0840e3badd667ef3c3ef65471609acb2ba3c sub2 |
|
776 | 782 | +c77908c81ccea3794a896c79e98b0e004aee2e9e sub2 |
|
777 |
diff -N |
|
|
783 | diff -Nru cloned.*/sub1/sub2/folder/test.txt cloned.*/sub1/sub2/folder/test.txt (glob) | |
|
778 | 784 | --- cloned.*/sub1/sub2/folder/test.txt * (glob) |
|
779 | 785 | +++ cloned.*/sub1/sub2/folder/test.txt * (glob) |
|
780 | 786 | @@ -0,0 +1 @@ |
|
781 | 787 | +subfolder |
|
782 |
diff -N |
|
|
788 | diff -Nru cloned.*/sub1/sub2/sub2 cloned.*/sub1/sub2/sub2 (glob) | |
|
783 | 789 | --- cloned.*/sub1/sub2/sub2 * (glob) |
|
784 | 790 | +++ cloned.*/sub1/sub2/sub2 * (glob) |
|
785 | 791 | @@ -1 +1 @@ |
|
786 | 792 | -sub2 |
|
787 | 793 | +modified |
|
788 |
diff -N |
|
|
794 | diff -Nru cloned.*/sub3/a.txt cloned.*/sub3/a.txt (glob) | |
|
789 | 795 | --- cloned.*/sub3/a.txt * (glob) |
|
790 | 796 | +++ cloned.*/sub3/a.txt * (glob) |
|
791 | 797 | @@ -0,0 +1 @@ |
|
792 | 798 | +xyz |
|
793 | 799 | [1] |
|
794 | 800 | |
|
795 | 801 | $ echo mod > sub1/sub2/sub2 |
|
796 | 802 | $ hg --config extensions.extdiff= extdiff -S |
|
797 | 803 | --- */cloned.*/sub1/sub2/sub2 * (glob) |
|
798 | 804 | +++ */cloned/sub1/sub2/sub2 * (glob) |
|
799 | 805 | @@ -1 +1 @@ |
|
800 | 806 | -modified |
|
801 | 807 | +mod |
|
802 | 808 | [1] |
|
803 | 809 | |
|
804 | 810 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now