Show More
@@ -172,3 +172,4 b' ede3bf31fe63677fdf5bd8db687977d4e3d792ed' | |||||
172 | 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 |
@@ -185,3 +185,4 b' ede3bf31fe63677fdf5bd8db687977d4e3d792ed' | |||||
185 | 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2 |
|
185 | 5405cb1a79010ac50c58cd84e6f50c4556bf2a4c 4.7.2 | |
186 | 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0 |
|
186 | 956ec6f1320df26f3133ec40f3de866ea0695fd7 4.8rc0 | |
187 | a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8 |
|
187 | a91a2837150bdcb27ae76b3646e6c93cd6a15904 4.8 | |
|
188 | 1c8c54cf97256f4468da2eb4dbee24f7f3888e71 4.8.1 |
@@ -430,6 +430,7 b' def uisetup(ui):' | |||||
430 | if args: |
|
430 | if args: | |
431 | cmdline += ' ' + args |
|
431 | cmdline += ' ' + args | |
432 | command(cmd, extdiffopts[:], _('hg %s [OPTION]... [FILE]...') % cmd, |
|
432 | command(cmd, extdiffopts[:], _('hg %s [OPTION]... [FILE]...') % cmd, | |
|
433 | helpcategory=command.CATEGORY_FILE_CONTENTS, | |||
433 | inferrepo=True)(savedcmd(path, cmdline)) |
|
434 | inferrepo=True)(savedcmd(path, cmdline)) | |
434 |
|
435 | |||
435 | # tell hggettext to extract docstrings from these functions: |
|
436 | # tell hggettext to extract docstrings from these functions: |
@@ -542,7 +542,7 b' class rebaseruntime(object):' | |||||
542 | p1, p2, base = defineparents(repo, rev, self.destmap, |
|
542 | p1, p2, base = defineparents(repo, rev, self.destmap, | |
543 | self.state, self.skipped, |
|
543 | self.state, self.skipped, | |
544 | self.obsoletenotrebased) |
|
544 | self.obsoletenotrebased) | |
545 | if len(repo[None].parents()) == 2: |
|
545 | if not self.inmemory and len(repo[None].parents()) == 2: | |
546 | repo.ui.debug('resuming interrupted rebase\n') |
|
546 | repo.ui.debug('resuming interrupted rebase\n') | |
547 | else: |
|
547 | else: | |
548 | overrides = {('ui', 'forcemerge'): opts.get('tool', '')} |
|
548 | overrides = {('ui', 'forcemerge'): opts.get('tool', '')} | |
@@ -867,7 +867,11 b' def rebase(ui, repo, **opts):' | |||||
867 | except error.InMemoryMergeConflictsError: |
|
867 | except error.InMemoryMergeConflictsError: | |
868 | ui.warn(_('hit merge conflicts; re-running rebase without in-memory' |
|
868 | ui.warn(_('hit merge conflicts; re-running rebase without in-memory' | |
869 | ' merge\n')) |
|
869 | ' merge\n')) | |
870 | _dorebase(ui, repo, action='abort', opts={}) |
|
870 | # TODO: Make in-memory merge not use the on-disk merge state, so | |
|
871 | # we don't have to clean it here | |||
|
872 | mergemod.mergestate.clean(repo) | |||
|
873 | clearstatus(repo) | |||
|
874 | clearcollapsemsg(repo) | |||
871 | return _dorebase(ui, repo, action, opts, inmemory=False) |
|
875 | return _dorebase(ui, repo, action, opts, inmemory=False) | |
872 | else: |
|
876 | else: | |
873 | return _dorebase(ui, repo, action, opts) |
|
877 | return _dorebase(ui, repo, action, opts) |
@@ -158,6 +158,12 b' static const char *index_deref(indexObje' | |||||
158 | return (const char *)(self->buf.buf) + pos * v1_hdrsize; |
|
158 | return (const char *)(self->buf.buf) + pos * v1_hdrsize; | |
159 | } |
|
159 | } | |
160 |
|
160 | |||
|
161 | /* | |||
|
162 | * Get parents of the given rev. | |||
|
163 | * | |||
|
164 | * The specified rev must be valid and must not be nullrev. A returned | |||
|
165 | * parent revision may be nullrev, but is guaranteed to be in valid range. | |||
|
166 | */ | |||
161 | static inline int index_get_parents(indexObject *self, Py_ssize_t rev, int *ps, |
|
167 | static inline int index_get_parents(indexObject *self, Py_ssize_t rev, int *ps, | |
162 | int maxrev) |
|
168 | int maxrev) | |
163 | { |
|
169 | { | |
@@ -180,7 +186,7 b' static inline int index_get_parents(inde' | |||||
180 | } |
|
186 | } | |
181 | /* If index file is corrupted, ps[] may point to invalid revisions. So |
|
187 | /* If index file is corrupted, ps[] may point to invalid revisions. So | |
182 | * there is a risk of buffer overflow to trust them unconditionally. */ |
|
188 | * there is a risk of buffer overflow to trust them unconditionally. */ | |
183 | if (ps[0] > maxrev || ps[1] > maxrev) { |
|
189 | if (ps[0] < -1 || ps[0] > maxrev || ps[1] < -1 || ps[1] > maxrev) { | |
184 | PyErr_SetString(PyExc_ValueError, "parent out of range"); |
|
190 | PyErr_SetString(PyExc_ValueError, "parent out of range"); | |
185 | return -1; |
|
191 | return -1; | |
186 | } |
|
192 | } | |
@@ -2688,6 +2694,16 b' void rustlazyancestors_drop(rustlazyance' | |||||
2688 | int rustlazyancestors_next(rustlazyancestorsObject *self); |
|
2694 | int rustlazyancestors_next(rustlazyancestorsObject *self); | |
2689 | int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev); |
|
2695 | int rustlazyancestors_contains(rustlazyancestorsObject *self, long rev); | |
2690 |
|
2696 | |||
|
2697 | static int index_get_parents_checked(indexObject *self, Py_ssize_t rev, int *ps, | |||
|
2698 | int maxrev) | |||
|
2699 | { | |||
|
2700 | if (rev < 0 || rev >= index_length(self)) { | |||
|
2701 | PyErr_SetString(PyExc_ValueError, "rev out of range"); | |||
|
2702 | return -1; | |||
|
2703 | } | |||
|
2704 | return index_get_parents(self, rev, ps, maxrev); | |||
|
2705 | } | |||
|
2706 | ||||
2691 | /* CPython instance methods */ |
|
2707 | /* CPython instance methods */ | |
2692 | static int rustla_init(rustlazyancestorsObject *self, PyObject *args) |
|
2708 | static int rustla_init(rustlazyancestorsObject *self, PyObject *args) | |
2693 | { |
|
2709 | { | |
@@ -2729,7 +2745,8 b' static int rustla_init(rustlazyancestors' | |||||
2729 | initrevs, stoprev, inclusive); |
|
2745 | initrevs, stoprev, inclusive); | |
2730 | if (self->iter == NULL) { |
|
2746 | if (self->iter == NULL) { | |
2731 | /* if this is because of GraphError::ParentOutOfRange |
|
2747 | /* if this is because of GraphError::ParentOutOfRange | |
2732 |
* index_get_parents() has already set the proper |
|
2748 | * index_get_parents_checked() has already set the proper | |
|
2749 | * ValueError */ | |||
2733 | goto bail; |
|
2750 | goto bail; | |
2734 | } |
|
2751 | } | |
2735 |
|
2752 |
@@ -526,7 +526,15 b' class unixforkingservice(object):' | |||||
526 | # waiting for recv() will receive ECONNRESET. |
|
526 | # waiting for recv() will receive ECONNRESET. | |
527 | self._unlinksocket() |
|
527 | self._unlinksocket() | |
528 | exiting = True |
|
528 | exiting = True | |
529 | ready = selector.select(timeout=h.pollinterval) |
|
529 | try: | |
|
530 | ready = selector.select(timeout=h.pollinterval) | |||
|
531 | except OSError as inst: | |||
|
532 | # selectors2 raises ETIMEDOUT if timeout exceeded while | |||
|
533 | # handling signal interrupt. That's probably wrong, but | |||
|
534 | # we can easily get around it. | |||
|
535 | if inst.errno != errno.ETIMEDOUT: | |||
|
536 | raise | |||
|
537 | ready = [] | |||
530 | if not ready: |
|
538 | if not ready: | |
531 | # only exit if we completed all queued requests |
|
539 | # only exit if we completed all queued requests | |
532 | if exiting: |
|
540 | if exiting: |
@@ -1843,6 +1843,11 b' class overlayworkingctx(committablectx):' | |||||
1843 | else: |
|
1843 | else: | |
1844 | return self._wrappedctx[path].flags() |
|
1844 | return self._wrappedctx[path].flags() | |
1845 |
|
1845 | |||
|
1846 | def __contains__(self, key): | |||
|
1847 | if key in self._cache: | |||
|
1848 | return self._cache[key]['exists'] | |||
|
1849 | return key in self.p1() | |||
|
1850 | ||||
1846 | def _existsinparent(self, path): |
|
1851 | def _existsinparent(self, path): | |
1847 | try: |
|
1852 | try: | |
1848 | # ``commitctx` raises a ``ManifestLookupError`` if a path does not |
|
1853 | # ``commitctx` raises a ``ManifestLookupError`` if a path does not | |
@@ -1877,19 +1882,19 b' class overlayworkingctx(committablectx):' | |||||
1877 | components = path.split('/') |
|
1882 | components = path.split('/') | |
1878 | for i in pycompat.xrange(len(components)): |
|
1883 | for i in pycompat.xrange(len(components)): | |
1879 | component = "/".join(components[0:i]) |
|
1884 | component = "/".join(components[0:i]) | |
1880 |
if component in self |
|
1885 | if component in self: | |
1881 | fail(path, component) |
|
1886 | fail(path, component) | |
1882 |
|
1887 | |||
1883 | # Test the other direction -- that this path from p2 isn't a directory |
|
1888 | # Test the other direction -- that this path from p2 isn't a directory | |
1884 | # in p1 (test that p1 doesn't any paths matching `path/*`). |
|
1889 | # in p1 (test that p1 doesn't have any paths matching `path/*`). | |
1885 |
match = |
|
1890 | match = self.match(pats=[path + '/'], default=b'path') | |
1886 | matches = self.p1().manifest().matches(match) |
|
1891 | matches = self.p1().manifest().matches(match) | |
1887 | mfiles = matches.keys() |
|
1892 | mfiles = matches.keys() | |
1888 | if len(mfiles) > 0: |
|
1893 | if len(mfiles) > 0: | |
1889 | if len(mfiles) == 1 and mfiles[0] == path: |
|
1894 | if len(mfiles) == 1 and mfiles[0] == path: | |
1890 | return |
|
1895 | return | |
1891 | # omit the files which are deleted in current IMM wctx |
|
1896 | # omit the files which are deleted in current IMM wctx | |
1892 |
mfiles = [m for m in mfiles if self |
|
1897 | mfiles = [m for m in mfiles if m in self] | |
1893 | if not mfiles: |
|
1898 | if not mfiles: | |
1894 | return |
|
1899 | return | |
1895 | raise error.Abort("error: file '%s' cannot be written because " |
|
1900 | raise error.Abort("error: file '%s' cannot be written because " |
@@ -708,7 +708,7 b' else:' | |||||
708 | if expires is not None: |
|
708 | if expires is not None: | |
709 | current_time = monotonic() |
|
709 | current_time = monotonic() | |
710 | if current_time > expires: |
|
710 | if current_time > expires: | |
711 |
raise OSError(errno |
|
711 | raise OSError(errno.ETIMEDOUT, 'Connection timed out') | |
712 | if recalc_timeout: |
|
712 | if recalc_timeout: | |
713 | if "timeout" in kwargs: |
|
713 | if "timeout" in kwargs: | |
714 | kwargs["timeout"] = expires - current_time |
|
714 | kwargs["timeout"] = expires - current_time |
@@ -377,25 +377,30 b' class clienthandler(object):' | |||||
377 | # This can raise. The caller can handle it. |
|
377 | # This can raise. The caller can handle it. | |
378 | response._onresponsedata(meta['data']) |
|
378 | response._onresponsedata(meta['data']) | |
379 |
|
379 | |||
380 | # If we got a content redirect response, we want to fetch it and |
|
380 | # We need to be careful about resolving futures prematurely. If a | |
381 | # expose the data as if we received it inline. But we also want to |
|
381 | # response is a redirect response, resolving the future before the | |
382 | # keep our internal request accounting in order. Our strategy is to |
|
382 | # redirect is processed would result in the consumer seeing an | |
383 | # basically put meaningful response handling on pause until EOS occurs |
|
383 | # empty stream of objects, since they'd be consuming our | |
384 | # and the stream accounting is in a good state. At that point, we follow |
|
384 | # response.objects() instead of the redirect's response.objects(). | |
385 | # the redirect and replace the response object with its data. |
|
385 | # | |
|
386 | # Our strategy is to not resolve/finish the request until either | |||
|
387 | # EOS occurs or until the initial response object is fully received. | |||
386 |
|
388 | |||
387 | redirect = response._redirect |
|
389 | # Always react to eos. | |
388 | handlefuture = False if redirect else True |
|
|||
389 |
|
||||
390 | if meta['eos']: |
|
390 | if meta['eos']: | |
391 | response._oninputcomplete() |
|
391 | response._oninputcomplete() | |
392 | del self._requests[frame.requestid] |
|
392 | del self._requests[frame.requestid] | |
393 |
|
393 | |||
394 | if redirect: |
|
394 | # Not EOS but we haven't decoded the initial response object yet. | |
395 | self._followredirect(frame.requestid, redirect) |
|
395 | # Return and wait for more data. | |
396 | return |
|
396 | elif not response._seeninitial: | |
|
397 | return | |||
397 |
|
398 | |||
398 | if not handlefuture: |
|
399 | # The specification says no objects should follow the initial/redirect | |
|
400 | # object. So it should be safe to handle the redirect object if one is | |||
|
401 | # decoded, without having to wait for EOS. | |||
|
402 | if response._redirect: | |||
|
403 | self._followredirect(frame.requestid, response._redirect) | |||
399 | return |
|
404 | return | |
400 |
|
405 | |||
401 | # If the command has a decoder, we wait until all input has been |
|
406 | # If the command has a decoder, we wait until all input has been | |
@@ -458,7 +463,10 b' class clienthandler(object):' | |||||
458 | self._redirects.append((requestid, res)) |
|
463 | self._redirects.append((requestid, res)) | |
459 |
|
464 | |||
460 | def _processredirect(self, rid, res): |
|
465 | def _processredirect(self, rid, res): | |
461 |
"""Called to continue processing a response from a redirect. |
|
466 | """Called to continue processing a response from a redirect. | |
|
467 | ||||
|
468 | Returns a bool indicating if the redirect is still serviceable. | |||
|
469 | """ | |||
462 | response = self._responses[rid] |
|
470 | response = self._responses[rid] | |
463 |
|
471 | |||
464 | try: |
|
472 | try: | |
@@ -470,7 +478,7 b' class clienthandler(object):' | |||||
470 | response._oninputcomplete() |
|
478 | response._oninputcomplete() | |
471 |
|
479 | |||
472 | if rid not in self._futures: |
|
480 | if rid not in self._futures: | |
473 | return |
|
481 | return bool(data) | |
474 |
|
482 | |||
475 | if response.command not in COMMAND_DECODERS: |
|
483 | if response.command not in COMMAND_DECODERS: | |
476 | self._futures[rid].set_result(response.objects()) |
|
484 | self._futures[rid].set_result(response.objects()) |
@@ -2,11 +2,36 b'' | |||||
2 |
|
2 | |||
3 | $ cd $TESTDIR/../contrib/fuzz |
|
3 | $ cd $TESTDIR/../contrib/fuzz | |
4 |
|
4 | |||
|
5 | which(1) could exit nonzero, but that's fine because we'll still end | |||
|
6 | up without a valid executable, so we don't need to check $? here. | |||
|
7 | ||||
|
8 | $ if which gmake >/dev/null 2>&1; then | |||
|
9 | > MAKE=gmake | |||
|
10 | > else | |||
|
11 | > MAKE=make | |||
|
12 | > fi | |||
|
13 | ||||
|
14 | $ havefuzz() { | |||
|
15 | > cat > $TESTTMP/dummy.cc <<EOF | |||
|
16 | > #include <stdlib.h> | |||
|
17 | > #include <stdint.h> | |||
|
18 | > int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { return 0; } | |||
|
19 | > int main(int argc, char **argv) { | |||
|
20 | > const char data[] = "asdf"; | |||
|
21 | > return LLVMFuzzerTestOneInput((const uint8_t *)data, 4); | |||
|
22 | > } | |||
|
23 | > EOF | |||
|
24 | > $CXX $TESTTMP/dummy.cc -o $TESTTMP/dummy \ | |||
|
25 | > -fsanitize=fuzzer-no-link,address || return 1 | |||
|
26 | > } | |||
|
27 | ||||
5 |
|
|
28 | #if clang-libfuzzer | |
6 | $ make -s clean all |
|
29 | $ CXX=clang++ havefuzz || exit 80 | |
|
30 | $ $MAKE -s clean all | |||
7 |
|
|
31 | #endif | |
8 |
|
|
32 | #if no-clang-libfuzzer clang-6.0 | |
9 | $ make -s clean all CC=clang-6.0 CXX=clang++-6.0 |
|
33 | $ CXX=clang++-6.0 havefuzz || exit 80 | |
|
34 | $ $MAKE -s clean all CC=clang-6.0 CXX=clang++-6.0 | |||
10 |
|
|
35 | #endif | |
11 |
|
|
36 | #if no-clang-libfuzzer no-clang-6.0 | |
12 | $ exit 80 |
|
37 | $ exit 80 |
@@ -133,12 +133,18 b' Test corrupted p1/p2 fields that could c' | |||||
133 | $ cd invalidparent |
|
133 | $ cd invalidparent | |
134 |
|
134 | |||
135 | $ hg clone --pull -q --config phases.publish=False ../a limit |
|
135 | $ hg clone --pull -q --config phases.publish=False ../a limit | |
|
136 | $ hg clone --pull -q --config phases.publish=False ../a neglimit | |||
136 | $ hg clone --pull -q --config phases.publish=False ../a segv |
|
137 | $ hg clone --pull -q --config phases.publish=False ../a segv | |
137 | $ rm -R limit/.hg/cache segv/.hg/cache |
|
138 | $ rm -R limit/.hg/cache neglimit/.hg/cache segv/.hg/cache | |
138 |
|
139 | |||
139 | $ "$PYTHON" <<EOF |
|
140 | $ "$PYTHON" <<EOF | |
140 | > data = open("limit/.hg/store/00changelog.i", "rb").read() |
|
141 | > data = open("limit/.hg/store/00changelog.i", "rb").read() | |
141 | > for n, p in [(b'limit', b'\0\0\0\x02'), (b'segv', b'\0\x01\0\0')]: |
|
142 | > poisons = [ | |
|
143 | > (b'limit', b'\0\0\0\x02'), | |||
|
144 | > (b'neglimit', b'\xff\xff\xff\xfe'), | |||
|
145 | > (b'segv', b'\0\x01\0\0'), | |||
|
146 | > ] | |||
|
147 | > for n, p in poisons: | |||
142 | > # corrupt p1 at rev0 and p2 at rev1 |
|
148 | > # corrupt p1 at rev0 and p2 at rev1 | |
143 | > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:] |
|
149 | > d = data[:24] + p + data[28:127 + 28] + p + data[127 + 32:] | |
144 | > open(n + b"/.hg/store/00changelog.i", "wb").write(d) |
|
150 | > open(n + b"/.hg/store/00changelog.i", "wb").write(d) | |
@@ -154,6 +160,11 b' Test corrupted p1/p2 fields that could c' | |||||
154 | 0 1 1 -1 base 63 62 63 1.01613 63 0 0.00000 |
|
160 | 0 1 1 -1 base 63 62 63 1.01613 63 0 0.00000 | |
155 | 1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000 |
|
161 | 1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000 | |
156 |
|
162 | |||
|
163 | $ hg -R neglimit debugrevlogindex -f1 -c | |||
|
164 | rev flag size link p1 p2 nodeid | |||
|
165 | 0 0000 62 0 -2 -1 7c31755bf9b5 | |||
|
166 | 1 0000 65 1 0 -2 26333235a41c | |||
|
167 | ||||
157 |
$ |
|
168 | $ hg -R segv debugrevlogindex -f1 -c | |
158 | rev flag size link p1 p2 nodeid |
|
169 | rev flag size link p1 p2 nodeid | |
159 | 0 0000 62 0 65536 -1 7c31755bf9b5 |
|
170 | 0 0000 62 0 65536 -1 7c31755bf9b5 | |
@@ -193,6 +204,12 b' Test corrupted p1/p2 fields that could c' | |||||
193 | index_headrevs: parent out of range |
|
204 | index_headrevs: parent out of range | |
194 | find_gca_candidates: parent out of range |
|
205 | find_gca_candidates: parent out of range | |
195 | find_deepest: parent out of range |
|
206 | find_deepest: parent out of range | |
|
207 | $ "$PYTHON" test.py neglimit/.hg/store | |||
|
208 | reachableroots: parent out of range | |||
|
209 | compute_phases_map_sets: parent out of range | |||
|
210 | index_headrevs: parent out of range | |||
|
211 | find_gca_candidates: parent out of range | |||
|
212 | find_deepest: parent out of range | |||
196 | $ "$PYTHON" test.py segv/.hg/store |
|
213 | $ "$PYTHON" test.py segv/.hg/store | |
197 | reachableroots: parent out of range |
|
214 | reachableroots: parent out of range | |
198 | compute_phases_map_sets: parent out of range |
|
215 | compute_phases_map_sets: parent out of range |
@@ -1,5 +1,7 b'' | |||||
1 | #require symlink execbit |
|
1 | #require symlink execbit | |
2 | $ cat << EOF >> $HGRCPATH |
|
2 | $ cat << EOF >> $HGRCPATH | |
|
3 | > [phases] | |||
|
4 | > publish=False | |||
3 | > [extensions] |
|
5 | > [extensions] | |
4 | > amend= |
|
6 | > amend= | |
5 | > rebase= |
|
7 | > rebase= | |
@@ -54,6 +56,7 b' Rebase a simple DAG:' | |||||
54 | b (no-eol) |
|
56 | b (no-eol) | |
55 | $ hg cat -r 2 c |
|
57 | $ hg cat -r 2 c | |
56 | c (no-eol) |
|
58 | c (no-eol) | |
|
59 | $ cd .. | |||
57 |
|
60 | |||
58 | Case 2: |
|
61 | Case 2: | |
59 | $ hg init repo2 |
|
62 | $ hg init repo2 | |
@@ -177,7 +180,7 b' Test reporting of path conflicts' | |||||
177 |
|
180 | |||
178 | $ hg rebase -r . -d 2 |
|
181 | $ hg rebase -r . -d 2 | |
179 | rebasing 4:daf7dfc139cb "a/a" (tip) |
|
182 | rebasing 4:daf7dfc139cb "a/a" (tip) | |
180 |
saved backup bundle to $TESTTMP/repo |
|
183 | saved backup bundle to $TESTTMP/repo2/.hg/strip-backup/daf7dfc139cb-fdbfcf4f-rebase.hg | |
181 |
|
184 | |||
182 | $ hg tglog |
|
185 | $ hg tglog | |
183 | @ 4: c6ad37a4f250 'a/a' |
|
186 | @ 4: c6ad37a4f250 'a/a' | |
@@ -218,7 +221,7 b' Test reporting of path conflicts' | |||||
218 |
|
221 | |||
219 | $ hg rebase -r . -d 5 |
|
222 | $ hg rebase -r . -d 5 | |
220 | rebasing 7:855e9797387e "added a back!" (tip) |
|
223 | rebasing 7:855e9797387e "added a back!" (tip) | |
221 |
saved backup bundle to $TESTTMP/repo |
|
224 | saved backup bundle to $TESTTMP/repo2/.hg/strip-backup/855e9797387e-81ee4c5d-rebase.hg | |
222 |
|
225 | |||
223 | $ hg tglog |
|
226 | $ hg tglog | |
224 | @ 7: bb3f02be2688 'added a back!' |
|
227 | @ 7: bb3f02be2688 'added a back!' | |
@@ -237,9 +240,48 b' Test reporting of path conflicts' | |||||
237 | |/ |
|
240 | |/ | |
238 | o 0: b173517d0057 'a' |
|
241 | o 0: b173517d0057 'a' | |
239 |
|
242 | |||
|
243 | $ mkdir c | |||
|
244 | $ echo c > c/c | |||
|
245 | $ hg add c/c | |||
|
246 | $ hg ci -m 'c/c' | |||
|
247 | $ hg rebase -r . -d 3 -n | |||
|
248 | starting dry-run rebase; repository will not be changed | |||
|
249 | rebasing 8:755f0104af9b "c/c" (tip) | |||
|
250 | abort: error: 'c/c' conflicts with file 'c' in 3. | |||
|
251 | [255] | |||
|
252 | $ hg rebase -r 3 -d . -n | |||
|
253 | starting dry-run rebase; repository will not be changed | |||
|
254 | rebasing 3:844a7de3e617 "c" | |||
|
255 | abort: error: file 'c' cannot be written because 'c/' is a folder in 755f0104af9b (containing 1 entries: c/c) | |||
|
256 | [255] | |||
240 |
|
257 | |||
241 | $ cd .. |
|
258 | $ cd .. | |
242 |
|
259 | |||
|
260 | Test path auditing (issue5818) | |||
|
261 | ||||
|
262 | $ mkdir lib_ | |||
|
263 | $ ln -s lib_ lib | |||
|
264 | $ hg init repo | |||
|
265 | $ cd repo | |||
|
266 | $ mkdir -p ".$TESTTMP/lib" | |||
|
267 | $ touch ".$TESTTMP/lib/a" | |||
|
268 | $ hg add ".$TESTTMP/lib/a" | |||
|
269 | $ hg ci -m 'a' | |||
|
270 | ||||
|
271 | $ touch ".$TESTTMP/lib/b" | |||
|
272 | $ hg add ".$TESTTMP/lib/b" | |||
|
273 | $ hg ci -m 'b' | |||
|
274 | ||||
|
275 | $ hg up -q '.^' | |||
|
276 | $ touch ".$TESTTMP/lib/c" | |||
|
277 | $ hg add ".$TESTTMP/lib/c" | |||
|
278 | $ hg ci -m 'c' | |||
|
279 | created new head | |||
|
280 | $ hg rebase -s 1 -d . | |||
|
281 | rebasing 1:* "b" (glob) | |||
|
282 | saved backup bundle to $TESTTMP/repo/.hg/strip-backup/*-rebase.hg (glob) | |||
|
283 | $ cd .. | |||
|
284 | ||||
243 | Test dry-run rebasing |
|
285 | Test dry-run rebasing | |
244 |
|
286 | |||
245 | $ hg init repo3 |
|
287 | $ hg init repo3 | |
@@ -420,7 +462,6 b' In-memory rebase that fails due to merge' | |||||
420 | transaction abort! |
|
462 | transaction abort! | |
421 | rollback completed |
|
463 | rollback completed | |
422 | hit merge conflicts; re-running rebase without in-memory merge |
|
464 | hit merge conflicts; re-running rebase without in-memory merge | |
423 | rebase aborted |
|
|||
424 | rebasing 2:177f92b77385 "c" |
|
465 | rebasing 2:177f92b77385 "c" | |
425 | rebasing 3:055a42cdd887 "d" |
|
466 | rebasing 3:055a42cdd887 "d" | |
426 | rebasing 4:e860deea161a "e" |
|
467 | rebasing 4:e860deea161a "e" | |
@@ -428,6 +469,46 b' In-memory rebase that fails due to merge' | |||||
428 | warning: conflicts while merging e! (edit, then use 'hg resolve --mark') |
|
469 | warning: conflicts while merging e! (edit, then use 'hg resolve --mark') | |
429 | unresolved conflicts (see hg resolve, then hg rebase --continue) |
|
470 | unresolved conflicts (see hg resolve, then hg rebase --continue) | |
430 | [1] |
|
471 | [1] | |
|
472 | $ hg rebase --abort | |||
|
473 | saved backup bundle to $TESTTMP/repo3/.hg/strip-backup/c1e524d4287c-f91f82e1-backup.hg | |||
|
474 | rebase aborted | |||
|
475 | ||||
|
476 | Retrying without in-memory merge won't lose working copy changes | |||
|
477 | $ cd .. | |||
|
478 | $ hg clone repo3 repo3-dirty -q | |||
|
479 | $ cd repo3-dirty | |||
|
480 | $ echo dirty > a | |||
|
481 | $ hg rebase -s 2 -d 7 | |||
|
482 | rebasing 2:177f92b77385 "c" | |||
|
483 | rebasing 3:055a42cdd887 "d" | |||
|
484 | rebasing 4:e860deea161a "e" | |||
|
485 | merging e | |||
|
486 | transaction abort! | |||
|
487 | rollback completed | |||
|
488 | hit merge conflicts; re-running rebase without in-memory merge | |||
|
489 | abort: uncommitted changes | |||
|
490 | [255] | |||
|
491 | $ cat a | |||
|
492 | dirty | |||
|
493 | ||||
|
494 | Retrying without in-memory merge won't lose merge state | |||
|
495 | $ cd .. | |||
|
496 | $ hg clone repo3 repo3-merge-state -q | |||
|
497 | $ cd repo3-merge-state | |||
|
498 | $ hg merge 4 | |||
|
499 | merging e | |||
|
500 | warning: conflicts while merging e! (edit, then use 'hg resolve --mark') | |||
|
501 | 2 files updated, 0 files merged, 0 files removed, 1 files unresolved | |||
|
502 | use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon | |||
|
503 | [1] | |||
|
504 | $ hg resolve -l | |||
|
505 | U e | |||
|
506 | $ hg rebase -s 2 -d 7 | |||
|
507 | rebasing 2:177f92b77385 "c" | |||
|
508 | abort: outstanding merge conflicts | |||
|
509 | [255] | |||
|
510 | $ hg resolve -l | |||
|
511 | U e | |||
431 |
|
512 | |||
432 | ========================== |
|
513 | ========================== | |
433 | Test for --confirm option| |
|
514 | Test for --confirm option| |
General Comments 0
You need to be logged in to leave comments.
Login now