Show More
@@ -21,7 +21,7 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 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 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 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 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 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 |
|
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 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 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 |
msg |
|
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 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') % msg |
|
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" |
|
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 checksum = "e2abad23fbc42b3700f2f279844d | |||||
590 |
|
590 | |||
591 | [[package]] |
|
591 | [[package]] | |
592 | name = "libc" |
|
592 | name = "libc" | |
593 |
version = "0.2.1 |
|
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 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 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 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: |
|
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 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 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 |
|
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) = |
|
435 | let (uuid, old_uuid) = match uuid_opt { | |
|
436 | Some(uuid) => { | |||
436 | let as_str = std::str::from_utf8(uuid) |
|
437 | let as_str = std::str::from_utf8(uuid) | |
437 | .map_err(|_| { |
|
438 | .map_err(|_| { | |
438 |
HgError::corrupted( |
|
439 | HgError::corrupted( | |
|
440 | "non-UTF-8 dirstate data file ID", | |||
|
441 | ) | |||
439 | })? |
|
442 | })? | |
440 | .to_owned(); |
|
443 | .to_owned(); | |
441 | let old_uuid_to_remove = Some(as_str.to_owned()); |
|
444 | if append { | |
442 |
(as_str, |
|
445 | (as_str, None) | |
443 | } else { |
|
446 | } else { | |
444 |
(DirstateDocket::new_uid(), |
|
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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