##// END OF EJS Templates
merge: with stable
Augie Fackler -
r50054:9d1e9689 merge default draft
parent child Browse files
Show More
@@ -21,7 +21,7 b' except ImportError:'
21 # available. Relax C module requirements.
21 # available. Relax C module requirements.
22 os.environ['HGMODULEPOLICY'] = 'allow'
22 os.environ['HGMODULEPOLICY'] = 'allow'
23 # import from the live mercurial repo
23 # import from the live mercurial repo
24 sys.path.insert(0, "..")
24 sys.path.insert(0, os.path.abspath(".."))
25 from mercurial import demandimport
25 from mercurial import demandimport
26
26
27 demandimport.enable()
27 demandimport.enable()
@@ -46,6 +46,7 b' from . import ('
46 context,
46 context,
47 copies,
47 copies,
48 dagparser,
48 dagparser,
49 dirstateutils,
49 encoding,
50 encoding,
50 error,
51 error,
51 exchange,
52 exchange,
@@ -939,6 +940,12 b' def debugdeltachain(ui, repo, file_=None'
939 (b'', b'datesort', None, _(b'sort by saved mtime')),
940 (b'', b'datesort', None, _(b'sort by saved mtime')),
940 (
941 (
941 b'',
942 b'',
943 b'docket',
944 False,
945 _(b'display the docket (metadata file) instead'),
946 ),
947 (
948 b'',
942 b'all',
949 b'all',
943 False,
950 False,
944 _(b'display dirstate-v2 tree nodes that would not exist in v1'),
951 _(b'display dirstate-v2 tree nodes that would not exist in v1'),
@@ -949,6 +956,33 b' def debugdeltachain(ui, repo, file_=None'
949 def debugstate(ui, repo, **opts):
956 def debugstate(ui, repo, **opts):
950 """show the contents of the current dirstate"""
957 """show the contents of the current dirstate"""
951
958
959 if opts.get("docket"):
960 if not repo.dirstate._use_dirstate_v2:
961 raise error.Abort(_(b'dirstate v1 does not have a docket'))
962
963 docket = repo.dirstate._map.docket
964 (
965 start_offset,
966 root_nodes,
967 nodes_with_entry,
968 nodes_with_copy,
969 unused_bytes,
970 _unused,
971 ignore_pattern,
972 ) = dirstateutils.v2.TREE_METADATA.unpack(docket.tree_metadata)
973
974 ui.write(_(b"size of dirstate data: %d\n") % docket.data_size)
975 ui.write(_(b"data file uuid: %s\n") % docket.uuid)
976 ui.write(_(b"start offset of root nodes: %d\n") % start_offset)
977 ui.write(_(b"number of root nodes: %d\n") % root_nodes)
978 ui.write(_(b"nodes with entries: %d\n") % nodes_with_entry)
979 ui.write(_(b"nodes with copies: %d\n") % nodes_with_copy)
980 ui.write(_(b"number of unused bytes: %d\n") % unused_bytes)
981 ui.write(
982 _(b"ignore pattern hash: %s\n") % binascii.hexlify(ignore_pattern)
983 )
984 return
985
952 nodates = not opts['dates']
986 nodates = not opts['dates']
953 if opts.get('nodates') is not None:
987 if opts.get('nodates') is not None:
954 nodates = True
988 nodates = True
@@ -983,22 +1017,6 b' def debugstate(ui, repo, **opts):'
983
1017
984
1018
985 @command(
1019 @command(
986 b'debugdirstateignorepatternshash',
987 [],
988 _(b''),
989 )
990 def debugdirstateignorepatternshash(ui, repo, **opts):
991 """show the hash of ignore patterns stored in dirstate if v2,
992 or nothing for dirstate-v2
993 """
994 if repo.dirstate._use_dirstate_v2:
995 docket = repo.dirstate._map.docket
996 hash_len = 20 # 160 bits for SHA-1
997 hash_bytes = docket.tree_metadata[-hash_len:]
998 ui.write(binascii.hexlify(hash_bytes) + b'\n')
999
1000
1001 @command(
1002 b'debugdiscovery',
1020 b'debugdiscovery',
1003 [
1021 [
1004 (b'', b'old', None, _(b'use old-style discovery')),
1022 (b'', b'old', None, _(b'use old-style discovery')),
@@ -28,7 +28,8 b' in progress. For more experimental work '
28 Checking for Rust
28 Checking for Rust
29 =================
29 =================
30
30
31 You may already have the Rust extensions depending on how you install Mercurial.
31 You may already have the Rust extensions depending on how you install
32 Mercurial::
32
33
33 $ hg debuginstall | grep -i rust
34 $ hg debuginstall | grep -i rust
34 checking Rust extensions (installed)
35 checking Rust extensions (installed)
@@ -46,7 +47,7 b' version to use.'
46 Using pip
47 Using pip
47 ---------
48 ---------
48
49
49 Users of `pip` can install the Rust extensions with the following command:
50 Users of `pip` can install the Rust extensions with the following command::
50
51
51 $ pip install mercurial --global-option --rust --no-use-pep517
52 $ pip install mercurial --global-option --rust --no-use-pep517
52
53
@@ -3175,7 +3175,7 b' class localrepository:'
3175 # Save commit message in case this transaction gets rolled back
3175 # Save commit message in case this transaction gets rolled back
3176 # (e.g. by a pretxncommit hook). Leave the content alone on
3176 # (e.g. by a pretxncommit hook). Leave the content alone on
3177 # the assumption that the user will use the same editor again.
3177 # the assumption that the user will use the same editor again.
3178 msgfn = self.savecommitmessage(cctx._text)
3178 msg_path = self.savecommitmessage(cctx._text)
3179
3179
3180 # commit subs and write new state
3180 # commit subs and write new state
3181 if subs:
3181 if subs:
@@ -3205,13 +3205,14 b' class localrepository:'
3205 except: # re-raises
3205 except: # re-raises
3206 if edited:
3206 if edited:
3207 self.ui.write(
3207 self.ui.write(
3208 _(b'note: commit message saved in %s\n') % msgfn
3208 _(b'note: commit message saved in %s\n') % msg_path
3209 )
3209 )
3210 self.ui.write(
3210 self.ui.write(
3211 _(
3211 _(
3212 b"note: use 'hg commit --logfile "
3212 b"note: use 'hg commit --logfile "
3213 b".hg/last-message.txt --edit' to reuse it\n"
3213 b"%s --edit' to reuse it\n"
3214 )
3214 )
3215 % msg_path
3215 )
3216 )
3216 raise
3217 raise
3217
3218
@@ -590,9 +590,9 b' checksum = "e2abad23fbc42b3700f2f279844d'
590
590
591 [[package]]
591 [[package]]
592 name = "libc"
592 name = "libc"
593 version = "0.2.119"
593 version = "0.2.124"
594 source = "registry+https://github.com/rust-lang/crates.io-index"
594 source = "registry+https://github.com/rust-lang/crates.io-index"
595 checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
595 checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50"
596
596
597 [[package]]
597 [[package]]
598 name = "libm"
598 name = "libm"
@@ -1032,6 +1032,7 b' dependencies = ['
1032 "micro-timer 0.4.0",
1032 "micro-timer 0.4.0",
1033 "regex",
1033 "regex",
1034 "users",
1034 "users",
1035 "which",
1035 ]
1036 ]
1036
1037
1037 [[package]]
1038 [[package]]
@@ -1251,6 +1252,17 b' source = "registry+https://github.com/ru'
1251 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1252 checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
1252
1253
1253 [[package]]
1254 [[package]]
1255 name = "which"
1256 version = "4.2.5"
1257 source = "registry+https://github.com/rust-lang/crates.io-index"
1258 checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae"
1259 dependencies = [
1260 "either",
1261 "lazy_static",
1262 "libc",
1263 ]
1264
1265 [[package]]
1254 name = "winapi"
1266 name = "winapi"
1255 version = "0.3.9"
1267 version = "0.3.9"
1256 source = "registry+https://github.com/rust-lang/crates.io-index"
1268 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -622,13 +622,18 b' pub(super) fn write('
622
622
623 let root_nodes = writer.write_nodes(dirstate_map.root.as_ref())?;
623 let root_nodes = writer.write_nodes(dirstate_map.root.as_ref())?;
624
624
625 let unreachable_bytes = if append {
626 dirstate_map.unreachable_bytes
627 } else {
628 0
629 };
625 let meta = TreeMetadata {
630 let meta = TreeMetadata {
626 root_nodes,
631 root_nodes,
627 nodes_with_entry_count: dirstate_map.nodes_with_entry_count.into(),
632 nodes_with_entry_count: dirstate_map.nodes_with_entry_count.into(),
628 nodes_with_copy_source_count: dirstate_map
633 nodes_with_copy_source_count: dirstate_map
629 .nodes_with_copy_source_count
634 .nodes_with_copy_source_count
630 .into(),
635 .into(),
631 unreachable_bytes: dirstate_map.unreachable_bytes.into(),
636 unreachable_bytes: unreachable_bytes.into(),
632 unused: [0; 4],
637 unused: [0; 4],
633 ignore_patterns_hash: dirstate_map.ignore_patterns_hash,
638 ignore_patterns_hash: dirstate_map.ignore_patterns_hash,
634 };
639 };
@@ -17,3 +17,6 b' pub const UNSUCCESSFUL: ExitCode = 1;'
17
17
18 /// Command or feature not implemented by rhg
18 /// Command or feature not implemented by rhg
19 pub const UNIMPLEMENTED: ExitCode = 252;
19 pub const UNIMPLEMENTED: ExitCode = 252;
20
21 /// The fallback path is not valid
22 pub const INVALID_FALLBACK: ExitCode = 253;
@@ -424,25 +424,32 b' impl Repo {'
424 // it’s unset
424 // it’s unset
425 let parents = self.dirstate_parents()?;
425 let parents = self.dirstate_parents()?;
426 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() {
426 let (packed_dirstate, old_uuid_to_remove) = if self.has_dirstate_v2() {
427 let uuid = self.dirstate_data_file_uuid.get_or_init(self)?;
427 let uuid_opt = self.dirstate_data_file_uuid.get_or_init(self)?;
428 let mut uuid = uuid.as_ref();
428 let uuid_opt = uuid_opt.as_ref();
429 let can_append = uuid.is_some();
429 let can_append = uuid_opt.is_some();
430 let (data, tree_metadata, append, old_data_size) =
430 let (data, tree_metadata, append, old_data_size) =
431 map.pack_v2(can_append)?;
431 map.pack_v2(can_append)?;
432 if !append {
432
433 uuid = None
433 // Reuse the uuid, or generate a new one, keeping the old for
434 }
434 // deletion.
435 let (uuid, old_uuid) = if let Some(uuid) = uuid {
435 let (uuid, old_uuid) = match uuid_opt {
436 let as_str = std::str::from_utf8(uuid)
436 Some(uuid) => {
437 .map_err(|_| {
437 let as_str = std::str::from_utf8(uuid)
438 HgError::corrupted("non-UTF-8 dirstate data file ID")
438 .map_err(|_| {
439 })?
439 HgError::corrupted(
440 .to_owned();
440 "non-UTF-8 dirstate data file ID",
441 let old_uuid_to_remove = Some(as_str.to_owned());
441 )
442 (as_str, old_uuid_to_remove)
442 })?
443 } else {
443 .to_owned();
444 (DirstateDocket::new_uid(), None)
444 if append {
445 (as_str, None)
446 } else {
447 (DirstateDocket::new_uid(), Some(as_str))
448 }
449 }
450 None => (DirstateDocket::new_uid(), None),
445 };
451 };
452
446 let data_filename = format!("dirstate.{}", uuid);
453 let data_filename = format!("dirstate.{}", uuid);
447 let data_filename = self.hg_vfs().join(data_filename);
454 let data_filename = self.hg_vfs().join(data_filename);
448 let mut options = std::fs::OpenOptions::new();
455 let mut options = std::fs::OpenOptions::new();
@@ -21,3 +21,4 b' regex = "1.5.5"'
21 env_logger = "0.9.0"
21 env_logger = "0.9.0"
22 format-bytes = "0.3.0"
22 format-bytes = "0.3.0"
23 users = "0.11.0"
23 users = "0.11.0"
24 which = "4.2.5"
@@ -29,6 +29,9 b' pub enum CommandError {'
29 /// `rhg` may attempt to silently fall back to Python-based `hg`, which
29 /// `rhg` may attempt to silently fall back to Python-based `hg`, which
30 /// may or may not support this feature.
30 /// may or may not support this feature.
31 UnsupportedFeature { message: Vec<u8> },
31 UnsupportedFeature { message: Vec<u8> },
32 /// The fallback executable does not exist (or has some other problem if
33 /// we end up being more precise about broken fallbacks).
34 InvalidFallback { path: Vec<u8>, err: String },
32 }
35 }
33
36
34 impl CommandError {
37 impl CommandError {
@@ -13,6 +13,7 b' use hg::utils::files::{get_bytes_from_os'
13 use hg::utils::SliceExt;
13 use hg::utils::SliceExt;
14 use std::collections::HashSet;
14 use std::collections::HashSet;
15 use std::ffi::OsString;
15 use std::ffi::OsString;
16 use std::os::unix::prelude::CommandExt;
16 use std::path::PathBuf;
17 use std::path::PathBuf;
17 use std::process::Command;
18 use std::process::Command;
18
19
@@ -381,12 +382,14 b' fn exit_code('
381 }
382 }
382 }
383 }
383 Err(CommandError::Unsuccessful) => exit_codes::UNSUCCESSFUL,
384 Err(CommandError::Unsuccessful) => exit_codes::UNSUCCESSFUL,
384
385 // Exit with a specific code and no error message to let a potential
385 // Exit with a specific code and no error message to let a potential
386 // wrapper script fallback to Python-based Mercurial.
386 // wrapper script fallback to Python-based Mercurial.
387 Err(CommandError::UnsupportedFeature { .. }) => {
387 Err(CommandError::UnsupportedFeature { .. }) => {
388 exit_codes::UNIMPLEMENTED
388 exit_codes::UNIMPLEMENTED
389 }
389 }
390 Err(CommandError::InvalidFallback { .. }) => {
391 exit_codes::INVALID_FALLBACK
392 }
390 }
393 }
391 }
394 }
392
395
@@ -432,6 +435,17 b" fn exit<'a>("
432 } else {
435 } else {
433 log::debug!("falling back (see trace-level log)");
436 log::debug!("falling back (see trace-level log)");
434 log::trace!("{}", local_to_utf8(message));
437 log::trace!("{}", local_to_utf8(message));
438 if let Err(err) = which::which(executable_path) {
439 exit_no_fallback(
440 ui,
441 OnUnsupported::Abort,
442 Err(CommandError::InvalidFallback {
443 path: executable.to_owned(),
444 err: err.to_string(),
445 }),
446 use_detailed_exit_code,
447 )
448 }
435 // `args` is now `argv[1..]` since we’ve already consumed
449 // `args` is now `argv[1..]` since we’ve already consumed
436 // `argv[0]`
450 // `argv[0]`
437 let mut command = Command::new(executable_path);
451 let mut command = Command::new(executable_path);
@@ -439,19 +453,19 b" fn exit<'a>("
439 if let Some(initial) = initial_current_dir {
453 if let Some(initial) = initial_current_dir {
440 command.current_dir(initial);
454 command.current_dir(initial);
441 }
455 }
442 let result = command.status();
456 // We don't use subprocess because proper signal handling is harder
443 match result {
457 // and we don't want to keep `rhg` around after a fallback anyway.
444 Ok(status) => std::process::exit(
458 // For example, if `rhg` is run in the background and falls back to
445 status.code().unwrap_or(exit_codes::ABORT),
459 // `hg` which, in turn, waits for a signal, we'll get stuck if
446 ),
460 // we're doing plain subprocess.
447 Err(error) => {
461 //
448 let _ = ui.write_stderr(&format_bytes!(
462 // If `exec` returns, we can only assume our process is very broken
449 b"tried to fall back to a '{}' sub-process but got error {}\n",
463 // (see its documentation), so only try to forward the error code
450 executable, format_bytes::Utf8(error)
464 // when exiting.
451 ));
465 let err = command.exec();
452 on_unsupported = OnUnsupported::Abort
466 std::process::exit(
453 }
467 err.raw_os_error().unwrap_or(exit_codes::ABORT),
454 }
468 );
455 }
469 }
456 }
470 }
457 exit_no_fallback(ui, on_unsupported, result, use_detailed_exit_code)
471 exit_no_fallback(ui, on_unsupported, result, use_detailed_exit_code)
@@ -488,6 +502,13 b' fn exit_no_fallback('
488 OnUnsupported::Fallback { .. } => unreachable!(),
502 OnUnsupported::Fallback { .. } => unreachable!(),
489 }
503 }
490 }
504 }
505 Err(CommandError::InvalidFallback { path, err }) => {
506 let _ = ui.write_stderr(&format_bytes!(
507 b"abort: invalid fallback '{}': {}\n",
508 path,
509 err.as_bytes(),
510 ));
511 }
491 }
512 }
492 std::process::exit(exit_code(&result, use_detailed_exit_code))
513 std::process::exit(exit_code(&result, use_detailed_exit_code))
493 }
514 }
@@ -94,7 +94,6 b' Show debug commands if there are no othe'
94 debugdate
94 debugdate
95 debugdeltachain
95 debugdeltachain
96 debugdirstate
96 debugdirstate
97 debugdirstateignorepatternshash
98 debugdiscovery
97 debugdiscovery
99 debugdownload
98 debugdownload
100 debugextensions
99 debugextensions
@@ -285,8 +284,7 b' Show all commands + options'
285 debugdata: changelog, manifest, dir
284 debugdata: changelog, manifest, dir
286 debugdate: extended
285 debugdate: extended
287 debugdeltachain: changelog, manifest, dir, template
286 debugdeltachain: changelog, manifest, dir, template
288 debugdirstateignorepatternshash:
287 debugdirstate: nodates, dates, datesort, docket, all
289 debugdirstate: nodates, dates, datesort, all
290 debugdiscovery: old, nonheads, rev, seed, local-as-revs, remote-as-revs, ssh, remotecmd, insecure, template
288 debugdiscovery: old, nonheads, rev, seed, local-as-revs, remote-as-revs, ssh, remotecmd, insecure, template
291 debugdownload: output
289 debugdownload: output
292 debugextensions: template
290 debugextensions: template
@@ -119,4 +119,88 b' infinite loop.'
119 C hgext3rd/__init__.py
119 C hgext3rd/__init__.py
120
120
121 $ cd ..
121 $ cd ..
122
123 Check that the old dirstate data file is removed correctly and the new one is
124 valid.
125
126 $ dirstate_data_files () {
127 > find .hg -maxdepth 1 -name "dirstate.*"
128 > }
129
130 $ find_dirstate_uuid () {
131 > hg debugstate --docket | grep uuid | sed 's/.*uuid: \(.*\)/\1/'
132 > }
133
134 $ dirstate_uuid_has_not_changed () {
135 > # Non-Rust always rewrites the whole dirstate
136 > if [ $# -eq 1 ] || ([ -n "$HGMODULEPOLICY" ] && [ -z "${HGMODULEPOLICY##*rust*}" ]) || [ -n "$RHG_INSTALLED_AS_HG" ]; then
137 > test $current_uid = $(find_dirstate_uuid)
138 > else
139 > echo "not testing because using Python implementation"
140 > fi
141 > }
142
143 $ cd ..
144 $ hg init append-mostly
145 $ cd append-mostly
146 $ mkdir dir dir2
147 $ touch dir/a dir/b dir/c dir/d dir/e dir2/f
148 $ hg commit -Aqm initial
149 $ hg st
150 $ dirstate_data_files | wc -l
151 *1 (re)
152 $ current_uid=$(find_dirstate_uuid)
153
154 Nothing changes here
155
156 $ hg st
157 $ dirstate_data_files | wc -l
158 *1 (re)
159 $ dirstate_uuid_has_not_changed
160 not testing because using Python implementation (no-rust no-rhg !)
161
162 Trigger an append with a small change
163
164 $ echo "modified" > dir2/f
165 $ hg st
166 M dir2/f
167 $ dirstate_data_files | wc -l
168 *1 (re)
169 $ dirstate_uuid_has_not_changed
170 not testing because using Python implementation (no-rust no-rhg !)
171
172 Unused bytes counter is non-0 when appending
173 $ touch file
174 $ hg add file
175 $ current_uid=$(find_dirstate_uuid)
176
177 Trigger a rust/rhg run which updates the unused bytes value
178 $ hg st
179 M dir2/f
180 A file
181 $ dirstate_data_files | wc -l
182 *1 (re)
183 $ dirstate_uuid_has_not_changed
184 not testing because using Python implementation (no-rust no-rhg !)
185
186 $ hg debugstate --docket | grep unused
187 number of unused bytes: 0 (no-rust no-rhg !)
188 number of unused bytes: [1-9]\d* (re) (rhg no-rust !)
189 number of unused bytes: [1-9]\d* (re) (rust no-rhg !)
190 number of unused bytes: [1-9]\d* (re) (rust rhg !)
191
192 Delete most of the dirstate to trigger a non-append
193 $ hg rm dir/a dir/b dir/c dir/d
194 $ dirstate_data_files | wc -l
195 *1 (re)
196 $ dirstate_uuid_has_not_changed also-if-python
197 [1]
198
199 Check that unused bytes counter is reset when creating a new docket
200
201 $ hg debugstate --docket | grep unused
202 number of unused bytes: 0
203
122 #endif
204 #endif
205
206 $ cd ..
@@ -1013,8 +1013,6 b' Test list of internal help commands'
1013 dump information about delta chains in a revlog
1013 dump information about delta chains in a revlog
1014 debugdirstate
1014 debugdirstate
1015 show the contents of the current dirstate
1015 show the contents of the current dirstate
1016 debugdirstateignorepatternshash
1017 show the hash of ignore patterns stored in dirstate if v2,
1018 debugdiscovery
1016 debugdiscovery
1019 runs the changeset discovery protocol in isolation
1017 runs the changeset discovery protocol in isolation
1020 debugdownload
1018 debugdownload
@@ -418,14 +418,14 b' This is an optimization that is only rel'
418 $ hg status > /dev/null
418 $ hg status > /dev/null
419 $ cat .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
419 $ cat .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
420 sha1=6e315b60f15fb5dfa02be00f3e2c8f923051f5ff
420 sha1=6e315b60f15fb5dfa02be00f3e2c8f923051f5ff
421 $ hg debugdirstateignorepatternshash
421 $ hg debugstate --docket | grep ignore
422 6e315b60f15fb5dfa02be00f3e2c8f923051f5ff
422 ignore pattern hash: 6e315b60f15fb5dfa02be00f3e2c8f923051f5ff
423
423
424 $ echo rel > .hg/testhgignorerel
424 $ echo rel > .hg/testhgignorerel
425 $ hg status > /dev/null
425 $ hg status > /dev/null
426 $ cat .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
426 $ cat .hg/testhgignore .hg/testhgignorerel .hgignore dir2/.hgignore dir1/.hgignore dir1/.hgignoretwo | $TESTDIR/f --sha1
427 sha1=dea19cc7119213f24b6b582a4bae7b0cb063e34e
427 sha1=dea19cc7119213f24b6b582a4bae7b0cb063e34e
428 $ hg debugdirstateignorepatternshash
428 $ hg debugstate --docket | grep ignore
429 dea19cc7119213f24b6b582a4bae7b0cb063e34e
429 ignore pattern hash: dea19cc7119213f24b6b582a4bae7b0cb063e34e
430
430
431 #endif
431 #endif
@@ -356,6 +356,8 b' check saving last-message.txt, at first'
356 A f
356 A f
357
357
358 $ rm -f .hg/last-message.txt
358 $ rm -f .hg/last-message.txt
359 $ mkdir dir
360 $ cd dir
359 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit tip --commands - 2>&1 << EOF
361 $ HGEDITOR="sh $TESTTMP/editor.sh" hg histedit tip --commands - 2>&1 << EOF
360 > mess 1fd3b2fe7754 f
362 > mess 1fd3b2fe7754 f
361 > EOF
363 > EOF
@@ -372,10 +374,11 b' check saving last-message.txt, at first'
372 ====
374 ====
373 transaction abort!
375 transaction abort!
374 rollback completed
376 rollback completed
375 note: commit message saved in .hg/last-message.txt
377 note: commit message saved in ../.hg/last-message.txt
376 note: use 'hg commit --logfile .hg/last-message.txt --edit' to reuse it
378 note: use 'hg commit --logfile ../.hg/last-message.txt --edit' to reuse it
377 abort: pretxncommit.unexpectedabort hook exited with status 1
379 abort: pretxncommit.unexpectedabort hook exited with status 1
378 [40]
380 [40]
381 $ cd ..
379 $ cat .hg/last-message.txt
382 $ cat .hg/last-message.txt
380 f
383 f
381
384
@@ -179,15 +179,8 b' Fallback to Python'
179 [1]
179 [1]
180
180
181 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=hg-non-existent
181 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=hg-non-existent
182 tried to fall back to a 'hg-non-existent' sub-process but got error $ENOENT$
182 abort: invalid fallback 'hg-non-existent': cannot find binary path
183 unsupported feature: error: Found argument '--exclude' which wasn't expected, or isn't valid in this context
183 [253]
184
185 USAGE:
186 rhg cat [OPTIONS] <FILE>...
187
188 For more information try --help
189
190 [252]
191
184
192 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=rhg
185 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=rhg
193 Blocking recursive fallback. The 'rhg.fallback-executable = rhg' config points to `rhg` itself.
186 Blocking recursive fallback. The 'rhg.fallback-executable = rhg' config points to `rhg` itself.
General Comments 0
You need to be logged in to leave comments. Login now