##// END OF EJS Templates
rhg: add resolve_file_args to path_utils.rs...
Mitchell Kember -
r53438:f33f37ac tip default
parent child Browse files
Show More
@@ -1,116 +1,78
1 use crate::error::CommandError;
1 use crate::error::CommandError;
2 use crate::utils::path_utils::resolve_file_args;
2 use clap::Arg;
3 use clap::Arg;
3 use format_bytes::format_bytes;
4 use format_bytes::format_bytes;
4 use hg::operations::cat;
5 use hg::operations::cat;
5 use hg::utils::hg_path::HgPathBuf;
6 use std::ffi::OsString;
6 use std::ffi::OsString;
7 use std::os::unix::prelude::OsStrExt;
8
7
9 pub const HELP_TEXT: &str = "
8 pub const HELP_TEXT: &str = "
10 Output the current or given revision of files
9 Output the current or given revision of files
11 ";
10 ";
12
11
13 pub fn args() -> clap::Command {
12 pub fn args() -> clap::Command {
14 clap::command!("cat")
13 clap::command!("cat")
15 .arg(
14 .arg(
16 Arg::new("rev")
15 Arg::new("rev")
17 .help("search the repository as it is in REV")
16 .help("search the repository as it is in REV")
18 .short('r')
17 .short('r')
19 .long("rev")
18 .long("rev")
20 .value_name("REV"),
19 .value_name("REV"),
21 )
20 )
22 .arg(
21 .arg(
23 clap::Arg::new("files")
22 clap::Arg::new("files")
24 .required(true)
23 .required(true)
25 .num_args(1..)
24 .num_args(1..)
26 .value_name("FILE")
25 .value_name("FILE")
27 .value_parser(clap::value_parser!(std::ffi::OsString))
26 .value_parser(clap::value_parser!(std::ffi::OsString))
28 .help("Files to output"),
27 .help("Files to output"),
29 )
28 )
30 .about(HELP_TEXT)
29 .about(HELP_TEXT)
31 }
30 }
32
31
33 #[logging_timer::time("trace")]
32 #[logging_timer::time("trace")]
34 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
33 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
35 let cat_enabled = invocation.config.get_bool(b"rhg", b"cat")?;
34 let cat_enabled = invocation.config.get_bool(b"rhg", b"cat")?;
36 if !cat_enabled {
35 if !cat_enabled {
37 return Err(CommandError::unsupported(
36 return Err(CommandError::unsupported(
38 "cat is disabled in rhg (enable it with 'rhg.cat = true' \
37 "cat is disabled in rhg (enable it with 'rhg.cat = true' \
39 or enable fallback with 'rhg.on-unsupported = fallback')",
38 or enable fallback with 'rhg.on-unsupported = fallback')",
40 ));
39 ));
41 }
40 }
42
41
43 let rev = invocation.subcommand_args.get_one::<String>("rev");
44 let file_args =
45 match invocation.subcommand_args.get_many::<OsString>("files") {
46 Some(files) => files
47 .filter(|s| !s.is_empty())
48 .map(|s| s.as_os_str())
49 .collect(),
50 None => vec![],
51 };
52
53 let repo = invocation.repo?;
42 let repo = invocation.repo?;
54 let cwd = hg::utils::current_dir()?;
55 let working_directory = repo.working_directory_path();
56 let working_directory = cwd.join(working_directory); // Make it absolute
57
58 let mut files = vec![];
59 for file in file_args {
60 if file.as_bytes().starts_with(b"set:") {
61 let message = "fileset";
62 return Err(CommandError::unsupported(message));
63 }
64
43
65 let normalized = cwd.join(file);
44 let rev = invocation.subcommand_args.get_one::<String>("rev");
66 // TODO: actually normalize `..` path segments etc?
45 let files = match invocation.subcommand_args.get_many::<OsString>("files")
67 let dotted = normalized.components().any(|c| c.as_os_str() == "..");
46 {
68 if file.as_bytes() == b"." || dotted {
47 None => vec![],
69 let message = "`..` or `.` path segment";
48 Some(files) => resolve_file_args(repo, files)?,
70 return Err(CommandError::unsupported(message));
49 };
71 }
50
72 let relative_path = working_directory
73 .strip_prefix(&cwd)
74 .unwrap_or(&working_directory);
75 let stripped = normalized
76 .strip_prefix(&working_directory)
77 .map_err(|_| {
78 CommandError::abort(format!(
79 "abort: {} not under root '{}'\n(consider using '--cwd {}')",
80 String::from_utf8_lossy(file.as_bytes()),
81 working_directory.display(),
82 relative_path.display(),
83 ))
84 })?;
85 let hg_file = HgPathBuf::try_from(stripped.to_path_buf())
86 .map_err(|e| CommandError::abort(e.to_string()))?;
87 files.push(hg_file);
88 }
89 let files = files.iter().map(|file| file.as_ref()).collect();
51 let files = files.iter().map(|file| file.as_ref()).collect();
90 // TODO probably move this to a util function like `repo.default_rev` or
52 // TODO probably move this to a util function like `repo.default_rev` or
91 // something when it's used somewhere else
53 // something when it's used somewhere else
92 let rev = match rev {
54 let rev = match rev {
93 Some(r) => r.to_string(),
55 Some(r) => r.to_string(),
94 None => format!("{:x}", repo.dirstate_parents()?.p1),
56 None => format!("{:x}", repo.dirstate_parents()?.p1),
95 };
57 };
96
58
97 let output = cat(repo, &rev, files)?;
59 let output = cat(repo, &rev, files)?;
98 for (_file, contents) in output.results {
60 for (_file, contents) in output.results {
99 invocation.ui.write_stdout(&contents)?;
61 invocation.ui.write_stdout(&contents)?;
100 }
62 }
101 if !output.missing.is_empty() {
63 if !output.missing.is_empty() {
102 let short = format!("{:x}", output.node.short()).into_bytes();
64 let short = format!("{:x}", output.node.short()).into_bytes();
103 for path in &output.missing {
65 for path in &output.missing {
104 invocation.ui.write_stderr(&format_bytes!(
66 invocation.ui.write_stderr(&format_bytes!(
105 b"{}: no such file in rev {}\n",
67 b"{}: no such file in rev {}\n",
106 path.as_bytes(),
68 path.as_bytes(),
107 short
69 short
108 ))?;
70 ))?;
109 }
71 }
110 }
72 }
111 if output.found_any {
73 if output.found_any {
112 Ok(())
74 Ok(())
113 } else {
75 } else {
114 Err(CommandError::Unsuccessful)
76 Err(CommandError::Unsuccessful)
115 }
77 }
116 }
78 }
@@ -1,55 +1,96
1 // path utils module
1 // path utils module
2 //
2 //
3 // This software may be used and distributed according to the terms of the
3 // This software may be used and distributed according to the terms of the
4 // GNU General Public License version 2 or any later version.
4 // GNU General Public License version 2 or any later version.
5
5
6 use hg::errors::HgError;
6 use hg::errors::HgError;
7 use hg::repo::Repo;
7 use hg::repo::Repo;
8 use hg::utils::current_dir;
8 use hg::utils::current_dir;
9 use hg::utils::files::{get_bytes_from_path, relativize_path};
9 use hg::utils::files::{get_bytes_from_path, relativize_path};
10 use hg::utils::hg_path::HgPath;
10 use hg::utils::hg_path::HgPath;
11 use hg::utils::hg_path::HgPathBuf;
11 use hg::utils::hg_path::HgPathBuf;
12 use std::borrow::Cow;
12 use std::borrow::Cow;
13 use std::ffi::OsString;
14
15 use crate::error::CommandError;
13
16
14 pub struct RelativizePaths {
17 pub struct RelativizePaths {
15 repo_root: HgPathBuf,
18 repo_root: HgPathBuf,
16 cwd: HgPathBuf,
19 cwd: HgPathBuf,
17 outside_repo: bool,
20 outside_repo: bool,
18 }
21 }
19
22
20 impl RelativizePaths {
23 impl RelativizePaths {
21 pub fn new(repo: &Repo) -> Result<Self, HgError> {
24 pub fn new(repo: &Repo) -> Result<Self, HgError> {
22 let cwd = current_dir()?;
25 let cwd = current_dir()?;
23 let repo_root = repo.working_directory_path();
26 let repo_root = repo.working_directory_path();
24 let repo_root = cwd.join(repo_root); // Make it absolute
27 let repo_root = cwd.join(repo_root); // Make it absolute
25 let repo_root_hgpath =
28 let repo_root_hgpath =
26 HgPathBuf::from(get_bytes_from_path(&repo_root));
29 HgPathBuf::from(get_bytes_from_path(&repo_root));
27
30
28 if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&repo_root) {
31 if let Ok(cwd_relative_to_repo) = cwd.strip_prefix(&repo_root) {
29 // The current directory is inside the repo, so we can work with
32 // The current directory is inside the repo, so we can work with
30 // relative paths
33 // relative paths
31 Ok(Self {
34 Ok(Self {
32 repo_root: repo_root_hgpath,
35 repo_root: repo_root_hgpath,
33 cwd: HgPathBuf::from(get_bytes_from_path(
36 cwd: HgPathBuf::from(get_bytes_from_path(
34 cwd_relative_to_repo,
37 cwd_relative_to_repo,
35 )),
38 )),
36 outside_repo: false,
39 outside_repo: false,
37 })
40 })
38 } else {
41 } else {
39 Ok(Self {
42 Ok(Self {
40 repo_root: repo_root_hgpath,
43 repo_root: repo_root_hgpath,
41 cwd: HgPathBuf::from(get_bytes_from_path(cwd)),
44 cwd: HgPathBuf::from(get_bytes_from_path(cwd)),
42 outside_repo: true,
45 outside_repo: true,
43 })
46 })
44 }
47 }
45 }
48 }
46
49
47 pub fn relativize<'a>(&self, path: &'a HgPath) -> Cow<'a, [u8]> {
50 pub fn relativize<'a>(&self, path: &'a HgPath) -> Cow<'a, [u8]> {
48 if self.outside_repo {
51 if self.outside_repo {
49 let joined = self.repo_root.join(path);
52 let joined = self.repo_root.join(path);
50 Cow::Owned(relativize_path(&joined, &self.cwd).into_owned())
53 Cow::Owned(relativize_path(&joined, &self.cwd).into_owned())
51 } else {
54 } else {
52 relativize_path(path, &self.cwd)
55 relativize_path(path, &self.cwd)
53 }
56 }
54 }
57 }
55 }
58 }
59
60 /// Resolves `FILE ...` arguments to a list of paths in the repository.
61 pub fn resolve_file_args<'a>(
62 repo: &Repo,
63 file_args: impl Iterator<Item = &'a OsString>,
64 ) -> Result<Vec<HgPathBuf>, CommandError> {
65 let cwd = hg::utils::current_dir()?;
66 let root = cwd.join(repo.working_directory_path());
67 let mut result = Vec::new();
68 for pattern in file_args {
69 // TODO: Support all the formats in `hg help patterns`.
70 if pattern.as_encoded_bytes().contains(&b':') {
71 return Err(CommandError::unsupported(
72 "rhg does not support file patterns",
73 ));
74 }
75 // TODO: use hg::utils::files::canonical_path (currently doesn't work).
76 let path = cwd.join(pattern);
77 let dotted = path.components().any(|c| c.as_os_str() == "..");
78 if pattern.as_encoded_bytes() == b"." || dotted {
79 let message = "`..` or `.` path segment";
80 return Err(CommandError::unsupported(message));
81 }
82 let relative_path = root.strip_prefix(&cwd).unwrap_or(&root);
83 let stripped = path.strip_prefix(&root).map_err(|_| {
84 CommandError::abort(format!(
85 "abort: {} not under root '{}'\n(consider using '--cwd {}')",
86 String::from_utf8_lossy(pattern.as_encoded_bytes()),
87 root.display(),
88 relative_path.display(),
89 ))
90 })?;
91 let hg_file = HgPathBuf::try_from(stripped.to_path_buf())
92 .map_err(|e| CommandError::abort(e.to_string()))?;
93 result.push(hg_file);
94 }
95 Ok(result)
96 }
@@ -1,458 +1,458
1 #require rhg
1 #require rhg
2
2
3 $ NO_FALLBACK="env RHG_ON_UNSUPPORTED=abort"
3 $ NO_FALLBACK="env RHG_ON_UNSUPPORTED=abort"
4
4
5 Unimplemented command
5 Unimplemented command
6 $ $NO_FALLBACK rhg unimplemented-command
6 $ $NO_FALLBACK rhg unimplemented-command
7 unsupported feature: error: unrecognized subcommand 'unimplemented-command'
7 unsupported feature: error: unrecognized subcommand 'unimplemented-command'
8
8
9 Usage: rhg [OPTIONS] <COMMAND>
9 Usage: rhg [OPTIONS] <COMMAND>
10
10
11 For more information, try '--help'.
11 For more information, try '--help'.
12
12
13 [252]
13 [252]
14 $ rhg unimplemented-command --config rhg.on-unsupported=abort-silent
14 $ rhg unimplemented-command --config rhg.on-unsupported=abort-silent
15 [252]
15 [252]
16
16
17 Finding root
17 Finding root
18 $ $NO_FALLBACK rhg root
18 $ $NO_FALLBACK rhg root
19 abort: no repository found in '$TESTTMP' (.hg not found)!
19 abort: no repository found in '$TESTTMP' (.hg not found)!
20 [255]
20 [255]
21
21
22 $ hg init repository
22 $ hg init repository
23 $ cd repository
23 $ cd repository
24 $ $NO_FALLBACK rhg root
24 $ $NO_FALLBACK rhg root
25 $TESTTMP/repository
25 $TESTTMP/repository
26
26
27 Reading and setting configuration
27 Reading and setting configuration
28 $ echo "[ui]" >> $HGRCPATH
28 $ echo "[ui]" >> $HGRCPATH
29 $ echo "username = user1" >> $HGRCPATH
29 $ echo "username = user1" >> $HGRCPATH
30 $ echo "[extensions]" >> $HGRCPATH
30 $ echo "[extensions]" >> $HGRCPATH
31 $ echo "sparse =" >> $HGRCPATH
31 $ echo "sparse =" >> $HGRCPATH
32 $ $NO_FALLBACK rhg config ui.username
32 $ $NO_FALLBACK rhg config ui.username
33 user1
33 user1
34 $ echo "[ui]" >> .hg/hgrc
34 $ echo "[ui]" >> .hg/hgrc
35 $ echo "username = user2" >> .hg/hgrc
35 $ echo "username = user2" >> .hg/hgrc
36 $ $NO_FALLBACK rhg config ui.username
36 $ $NO_FALLBACK rhg config ui.username
37 user2
37 user2
38 $ $NO_FALLBACK rhg --config ui.username=user3 config ui.username
38 $ $NO_FALLBACK rhg --config ui.username=user3 config ui.username
39 user3
39 user3
40
40
41 Unwritable file descriptor
41 Unwritable file descriptor
42 $ $NO_FALLBACK rhg root > /dev/full
42 $ $NO_FALLBACK rhg root > /dev/full
43 abort: No space left on device (os error 28)
43 abort: No space left on device (os error 28)
44 [255]
44 [255]
45
45
46 Deleted repository
46 Deleted repository
47 $ rm -rf `pwd`
47 $ rm -rf `pwd`
48 $ $NO_FALLBACK rhg root
48 $ $NO_FALLBACK rhg root
49 abort: error getting current working directory: $ENOENT$
49 abort: error getting current working directory: $ENOENT$
50 [255]
50 [255]
51
51
52 Listing tracked files
52 Listing tracked files
53 $ cd $TESTTMP
53 $ cd $TESTTMP
54 $ hg init repository
54 $ hg init repository
55 $ cd repository
55 $ cd repository
56 $ for i in 1 2 3; do
56 $ for i in 1 2 3; do
57 > echo $i >> file$i
57 > echo $i >> file$i
58 > hg add file$i
58 > hg add file$i
59 > done
59 > done
60 > hg commit -m "commit $i" -q
60 > hg commit -m "commit $i" -q
61
61
62 Listing tracked files from root
62 Listing tracked files from root
63 $ $NO_FALLBACK rhg files
63 $ $NO_FALLBACK rhg files
64 file1
64 file1
65 file2
65 file2
66 file3
66 file3
67
67
68 Listing tracked files from subdirectory
68 Listing tracked files from subdirectory
69 $ mkdir -p path/to/directory
69 $ mkdir -p path/to/directory
70 $ cd path/to/directory
70 $ cd path/to/directory
71 $ $NO_FALLBACK rhg files
71 $ $NO_FALLBACK rhg files
72 ../../../file1
72 ../../../file1
73 ../../../file2
73 ../../../file2
74 ../../../file3
74 ../../../file3
75
75
76 $ $NO_FALLBACK rhg files --config ui.relative-paths=legacy
76 $ $NO_FALLBACK rhg files --config ui.relative-paths=legacy
77 ../../../file1
77 ../../../file1
78 ../../../file2
78 ../../../file2
79 ../../../file3
79 ../../../file3
80
80
81 $ $NO_FALLBACK rhg files --config ui.relative-paths=false
81 $ $NO_FALLBACK rhg files --config ui.relative-paths=false
82 file1
82 file1
83 file2
83 file2
84 file3
84 file3
85
85
86 $ $NO_FALLBACK rhg files --config ui.relative-paths=true
86 $ $NO_FALLBACK rhg files --config ui.relative-paths=true
87 ../../../file1
87 ../../../file1
88 ../../../file2
88 ../../../file2
89 ../../../file3
89 ../../../file3
90
90
91 Listing tracked files through broken pipe
91 Listing tracked files through broken pipe
92 $ $NO_FALLBACK rhg files | head -n 1
92 $ $NO_FALLBACK rhg files | head -n 1
93 ../../../file1
93 ../../../file1
94
94
95 Status with --rev and --change
95 Status with --rev and --change
96 $ cd $TESTTMP/repository
96 $ cd $TESTTMP/repository
97 $ $NO_FALLBACK rhg status --change null
97 $ $NO_FALLBACK rhg status --change null
98 $ $NO_FALLBACK rhg status --change 0
98 $ $NO_FALLBACK rhg status --change 0
99 A file1
99 A file1
100 A file2
100 A file2
101 A file3
101 A file3
102 $ $NO_FALLBACK rhg status --rev null --rev 0
102 $ $NO_FALLBACK rhg status --rev null --rev 0
103 A file1
103 A file1
104 A file2
104 A file2
105 A file3
105 A file3
106
106
107 Status with --change --copies
107 Status with --change --copies
108 $ hg copy file2 file2copy
108 $ hg copy file2 file2copy
109 $ hg rename file3 file3rename
109 $ hg rename file3 file3rename
110 $ hg commit -m "commit 4" -q
110 $ hg commit -m "commit 4" -q
111 $ $NO_FALLBACK rhg status --change . --copies
111 $ $NO_FALLBACK rhg status --change . --copies
112 A file2copy
112 A file2copy
113 file2
113 file2
114 A file3rename
114 A file3rename
115 file3
115 file3
116 R file3
116 R file3
117
117
118 Debuging data in inline index
118 Debuging data in inline index
119 $ cd $TESTTMP
119 $ cd $TESTTMP
120 $ rm -rf repository
120 $ rm -rf repository
121 $ hg init repository
121 $ hg init repository
122 $ cd repository
122 $ cd repository
123 $ for i in 1 2 3 4 5 6; do
123 $ for i in 1 2 3 4 5 6; do
124 > echo $i >> file-$i
124 > echo $i >> file-$i
125 > hg add file-$i
125 > hg add file-$i
126 > hg commit -m "Commit $i" -q
126 > hg commit -m "Commit $i" -q
127 > done
127 > done
128 $ $NO_FALLBACK rhg debugdata -c 2
128 $ $NO_FALLBACK rhg debugdata -c 2
129 8d0267cb034247ebfa5ee58ce59e22e57a492297
129 8d0267cb034247ebfa5ee58ce59e22e57a492297
130 test
130 test
131 0 0
131 0 0
132 file-3
132 file-3
133
133
134 Commit 3 (no-eol)
134 Commit 3 (no-eol)
135 $ $NO_FALLBACK rhg debugdata -m 2
135 $ $NO_FALLBACK rhg debugdata -m 2
136 file-1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
136 file-1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc)
137 file-2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc)
137 file-2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc)
138 file-3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc)
138 file-3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc)
139
139
140 Debuging with full node id
140 Debuging with full node id
141 $ $NO_FALLBACK rhg debugdata -c `hg log -r 0 -T '{node}'`
141 $ $NO_FALLBACK rhg debugdata -c `hg log -r 0 -T '{node}'`
142 d1d1c679d3053e8926061b6f45ca52009f011e3f
142 d1d1c679d3053e8926061b6f45ca52009f011e3f
143 test
143 test
144 0 0
144 0 0
145 file-1
145 file-1
146
146
147 Commit 1 (no-eol)
147 Commit 1 (no-eol)
148
148
149 Specifying revisions by changeset ID
149 Specifying revisions by changeset ID
150 $ hg log -T '{node}\n'
150 $ hg log -T '{node}\n'
151 c6ad58c44207b6ff8a4fbbca7045a5edaa7e908b
151 c6ad58c44207b6ff8a4fbbca7045a5edaa7e908b
152 d654274993d0149eecc3cc03214f598320211900
152 d654274993d0149eecc3cc03214f598320211900
153 f646af7e96481d3a5470b695cf30ad8e3ab6c575
153 f646af7e96481d3a5470b695cf30ad8e3ab6c575
154 cf8b83f14ead62b374b6e91a0e9303b85dfd9ed7
154 cf8b83f14ead62b374b6e91a0e9303b85dfd9ed7
155 91c6f6e73e39318534dc415ea4e8a09c99cd74d6
155 91c6f6e73e39318534dc415ea4e8a09c99cd74d6
156 6ae9681c6d30389694d8701faf24b583cf3ccafe
156 6ae9681c6d30389694d8701faf24b583cf3ccafe
157 $ $NO_FALLBACK rhg files -r cf8b83
157 $ $NO_FALLBACK rhg files -r cf8b83
158 file-1
158 file-1
159 file-2
159 file-2
160 file-3
160 file-3
161 $ $NO_FALLBACK rhg cat -r cf8b83 file-2
161 $ $NO_FALLBACK rhg cat -r cf8b83 file-2
162 2
162 2
163 $ $NO_FALLBACK rhg cat --rev cf8b83 file-2
163 $ $NO_FALLBACK rhg cat --rev cf8b83 file-2
164 2
164 2
165 $ $NO_FALLBACK rhg cat -r c file-2
165 $ $NO_FALLBACK rhg cat -r c file-2
166 abort: ambiguous revision identifier: c
166 abort: ambiguous revision identifier: c
167 [255]
167 [255]
168 $ $NO_FALLBACK rhg cat -r d file-2
168 $ $NO_FALLBACK rhg cat -r d file-2
169 2
169 2
170 $ $NO_FALLBACK rhg cat -r 0000 file-2
170 $ $NO_FALLBACK rhg cat -r 0000 file-2
171 file-2: no such file in rev 000000000000
171 file-2: no such file in rev 000000000000
172 [1]
172 [1]
173
173
174 Cat files
174 Cat files
175 $ cd $TESTTMP
175 $ cd $TESTTMP
176 $ rm -rf repository
176 $ rm -rf repository
177 $ hg init repository
177 $ hg init repository
178 $ cd repository
178 $ cd repository
179 $ echo "original content" > original
179 $ echo "original content" > original
180 $ hg add original
180 $ hg add original
181 $ hg commit -m "add original" original
181 $ hg commit -m "add original" original
182 Without `--rev`
182 Without `--rev`
183 $ $NO_FALLBACK rhg cat original
183 $ $NO_FALLBACK rhg cat original
184 original content
184 original content
185 With `--rev`
185 With `--rev`
186 $ $NO_FALLBACK rhg cat -r 0 original
186 $ $NO_FALLBACK rhg cat -r 0 original
187 original content
187 original content
188 Cat copied file should not display copy metadata
188 Cat copied file should not display copy metadata
189 $ hg copy original copy_of_original
189 $ hg copy original copy_of_original
190 $ hg commit -m "add copy of original"
190 $ hg commit -m "add copy of original"
191 $ $NO_FALLBACK rhg cat original
191 $ $NO_FALLBACK rhg cat original
192 original content
192 original content
193 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
193 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
194 original content
194 original content
195
195
196
196
197 Fallback to Python
197 Fallback to Python
198 $ $NO_FALLBACK rhg cat original --exclude="*.rs"
198 $ $NO_FALLBACK rhg cat original --exclude="*.rs"
199 unsupported feature: error: unexpected argument '--exclude' found
199 unsupported feature: error: unexpected argument '--exclude' found
200
200
201 tip: to pass '--exclude' as a value, use '-- --exclude'
201 tip: to pass '--exclude' as a value, use '-- --exclude'
202
202
203 Usage: rhg cat <FILE>...
203 Usage: rhg cat <FILE>...
204
204
205 For more information, try '--help'.
205 For more information, try '--help'.
206
206
207 [252]
207 [252]
208 $ rhg cat original --exclude="*.rs"
208 $ rhg cat original --exclude="*.rs"
209 original content
209 original content
210
210
211 Check that `fallback-immediately` overrides `$NO_FALLBACK`
211 Check that `fallback-immediately` overrides `$NO_FALLBACK`
212 $ $NO_FALLBACK rhg cat original --exclude="*.rs" --config rhg.fallback-immediately=1
212 $ $NO_FALLBACK rhg cat original --exclude="*.rs" --config rhg.fallback-immediately=1
213 original content
213 original content
214
214
215 $ (unset RHG_FALLBACK_EXECUTABLE; rhg cat original --exclude="*.rs")
215 $ (unset RHG_FALLBACK_EXECUTABLE; rhg cat original --exclude="*.rs")
216 abort: 'rhg.on-unsupported=fallback' without 'rhg.fallback-executable' set.
216 abort: 'rhg.on-unsupported=fallback' without 'rhg.fallback-executable' set.
217 [255]
217 [255]
218
218
219 $ (unset RHG_FALLBACK_EXECUTABLE; rhg cat original)
219 $ (unset RHG_FALLBACK_EXECUTABLE; rhg cat original)
220 original content
220 original content
221
221
222 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=false
222 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=false
223 [1]
223 [1]
224
224
225 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=hg-non-existent
225 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=hg-non-existent
226 abort: invalid fallback 'hg-non-existent': cannot find binary path
226 abort: invalid fallback 'hg-non-existent': cannot find binary path
227 [253]
227 [253]
228
228
229 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=rhg
229 $ rhg cat original --exclude="*.rs" --config rhg.fallback-executable=rhg
230 Blocking recursive fallback. The 'rhg.fallback-executable = rhg' config points to `rhg` itself.
230 Blocking recursive fallback. The 'rhg.fallback-executable = rhg' config points to `rhg` itself.
231 unsupported feature: error: unexpected argument '--exclude' found
231 unsupported feature: error: unexpected argument '--exclude' found
232
232
233 tip: to pass '--exclude' as a value, use '-- --exclude'
233 tip: to pass '--exclude' as a value, use '-- --exclude'
234
234
235 Usage: rhg cat <FILE>...
235 Usage: rhg cat <FILE>...
236
236
237 For more information, try '--help'.
237 For more information, try '--help'.
238
238
239 [252]
239 [252]
240
240
241 Fallback with shell path segments
241 Fallback with shell path segments
242 $ $NO_FALLBACK rhg cat .
242 $ $NO_FALLBACK rhg cat .
243 unsupported feature: `..` or `.` path segment
243 unsupported feature: `..` or `.` path segment
244 [252]
244 [252]
245 $ $NO_FALLBACK rhg cat ..
245 $ $NO_FALLBACK rhg cat ..
246 unsupported feature: `..` or `.` path segment
246 unsupported feature: `..` or `.` path segment
247 [252]
247 [252]
248 $ $NO_FALLBACK rhg cat ../..
248 $ $NO_FALLBACK rhg cat ../..
249 unsupported feature: `..` or `.` path segment
249 unsupported feature: `..` or `.` path segment
250 [252]
250 [252]
251
251
252 Fallback with filesets
252 Fallback with filesets
253 $ $NO_FALLBACK rhg cat "set:c or b"
253 $ $NO_FALLBACK rhg cat "set:c or b"
254 unsupported feature: fileset
254 unsupported feature: rhg does not support file patterns
255 [252]
255 [252]
256
256
257 Fallback with generic hooks
257 Fallback with generic hooks
258 $ $NO_FALLBACK rhg cat original --config hooks.pre-cat=something
258 $ $NO_FALLBACK rhg cat original --config hooks.pre-cat=something
259 unsupported feature: pre-cat hook defined
259 unsupported feature: pre-cat hook defined
260 [252]
260 [252]
261
261
262 $ $NO_FALLBACK rhg cat original --config hooks.post-cat=something
262 $ $NO_FALLBACK rhg cat original --config hooks.post-cat=something
263 unsupported feature: post-cat hook defined
263 unsupported feature: post-cat hook defined
264 [252]
264 [252]
265
265
266 $ $NO_FALLBACK rhg cat original --config hooks.fail-cat=something
266 $ $NO_FALLBACK rhg cat original --config hooks.fail-cat=something
267 unsupported feature: fail-cat hook defined
267 unsupported feature: fail-cat hook defined
268 [252]
268 [252]
269
269
270 Fallback with [defaults]
270 Fallback with [defaults]
271 $ $NO_FALLBACK rhg cat original --config "defaults.cat=-r null"
271 $ $NO_FALLBACK rhg cat original --config "defaults.cat=-r null"
272 unsupported feature: `defaults` config set
272 unsupported feature: `defaults` config set
273 [252]
273 [252]
274
274
275
275
276 Requirements
276 Requirements
277 $ $NO_FALLBACK rhg debugrequirements
277 $ $NO_FALLBACK rhg debugrequirements
278 dotencode
278 dotencode
279 fncache
279 fncache
280 generaldelta
280 generaldelta
281 persistent-nodemap
281 persistent-nodemap
282 revlog-compression-zstd (zstd !)
282 revlog-compression-zstd (zstd !)
283 revlogv1
283 revlogv1
284 share-safe
284 share-safe
285 sparserevlog
285 sparserevlog
286 store
286 store
287
287
288 $ echo indoor-pool >> .hg/requires
288 $ echo indoor-pool >> .hg/requires
289 $ $NO_FALLBACK rhg files
289 $ $NO_FALLBACK rhg files
290 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
290 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
291 [252]
291 [252]
292
292
293 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
293 $ $NO_FALLBACK rhg cat -r 1 copy_of_original
294 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
294 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
295 [252]
295 [252]
296
296
297 $ $NO_FALLBACK rhg debugrequirements
297 $ $NO_FALLBACK rhg debugrequirements
298 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
298 unsupported feature: repository requires feature unknown to this Mercurial: indoor-pool
299 [252]
299 [252]
300
300
301 $ echo -e '\xFF' >> .hg/requires
301 $ echo -e '\xFF' >> .hg/requires
302 $ $NO_FALLBACK rhg debugrequirements
302 $ $NO_FALLBACK rhg debugrequirements
303 abort: parse error in 'requires' file
303 abort: parse error in 'requires' file
304 [255]
304 [255]
305
305
306 Persistent nodemap
306 Persistent nodemap
307 $ cd $TESTTMP
307 $ cd $TESTTMP
308 $ rm -rf repository
308 $ rm -rf repository
309 $ hg --config format.use-persistent-nodemap=no init repository
309 $ hg --config format.use-persistent-nodemap=no init repository
310 $ cd repository
310 $ cd repository
311 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
311 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
312 [1]
312 [1]
313 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
313 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
314 $ hg id -r tip
314 $ hg id -r tip
315 c3ae8dec9fad tip
315 c3ae8dec9fad tip
316 $ ls .hg/store/00changelog*
316 $ ls .hg/store/00changelog*
317 .hg/store/00changelog.d
317 .hg/store/00changelog.d
318 .hg/store/00changelog.i
318 .hg/store/00changelog.i
319 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
319 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
320 of
320 of
321
321
322 $ cd $TESTTMP
322 $ cd $TESTTMP
323 $ rm -rf repository
323 $ rm -rf repository
324 $ hg --config format.use-persistent-nodemap=True init repository
324 $ hg --config format.use-persistent-nodemap=True init repository
325 $ cd repository
325 $ cd repository
326 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
326 $ $NO_FALLBACK rhg debugrequirements | grep nodemap
327 persistent-nodemap
327 persistent-nodemap
328 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
328 $ hg debugbuilddag .+5000 --overwritten-file --config "storage.revlog.nodemap.mode=warn"
329 $ hg id -r tip
329 $ hg id -r tip
330 c3ae8dec9fad tip
330 c3ae8dec9fad tip
331 $ ls .hg/store/00changelog*
331 $ ls .hg/store/00changelog*
332 .hg/store/00changelog-*.nd (glob)
332 .hg/store/00changelog-*.nd (glob)
333 .hg/store/00changelog.d
333 .hg/store/00changelog.d
334 .hg/store/00changelog.i
334 .hg/store/00changelog.i
335 .hg/store/00changelog.n
335 .hg/store/00changelog.n
336
336
337 Rhg status on a sparse repo with nodemap (this specific combination used to crash in 6.5.2)
337 Rhg status on a sparse repo with nodemap (this specific combination used to crash in 6.5.2)
338
338
339 $ hg debugsparse -X excluded-dir
339 $ hg debugsparse -X excluded-dir
340 $ $NO_FALLBACK rhg status
340 $ $NO_FALLBACK rhg status
341
341
342 Specifying revisions by changeset ID
342 Specifying revisions by changeset ID
343 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
343 $ $NO_FALLBACK rhg files -r c3ae8dec9fad
344 of
344 of
345 $ $NO_FALLBACK rhg cat -r c3ae8dec9fad of
345 $ $NO_FALLBACK rhg cat -r c3ae8dec9fad of
346 r5000
346 r5000
347
347
348 Crate a shared repository
348 Crate a shared repository
349
349
350 $ echo "[extensions]" >> $HGRCPATH
350 $ echo "[extensions]" >> $HGRCPATH
351 $ echo "share = " >> $HGRCPATH
351 $ echo "share = " >> $HGRCPATH
352
352
353 $ cd $TESTTMP
353 $ cd $TESTTMP
354 $ hg init repo1
354 $ hg init repo1
355 $ echo a > repo1/a
355 $ echo a > repo1/a
356 $ hg -R repo1 commit -A -m'init'
356 $ hg -R repo1 commit -A -m'init'
357 adding a
357 adding a
358
358
359 $ hg share repo1 repo2
359 $ hg share repo1 repo2
360 updating working directory
360 updating working directory
361 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
361 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
362
362
363 And check that basic rhg commands work with sharing
363 And check that basic rhg commands work with sharing
364
364
365 $ $NO_FALLBACK rhg files -R repo2
365 $ $NO_FALLBACK rhg files -R repo2
366 repo2/a
366 repo2/a
367 $ $NO_FALLBACK rhg -R repo2 cat -r 0 repo2/a
367 $ $NO_FALLBACK rhg -R repo2 cat -r 0 repo2/a
368 a
368 a
369
369
370 Same with relative sharing
370 Same with relative sharing
371
371
372 $ hg share repo2 repo3 --relative
372 $ hg share repo2 repo3 --relative
373 updating working directory
373 updating working directory
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
374 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
375
375
376 $ $NO_FALLBACK rhg files -R repo3
376 $ $NO_FALLBACK rhg files -R repo3
377 repo3/a
377 repo3/a
378 $ $NO_FALLBACK rhg -R repo3 cat -r 0 repo3/a
378 $ $NO_FALLBACK rhg -R repo3 cat -r 0 repo3/a
379 a
379 a
380
380
381 Same with share-safe
381 Same with share-safe
382
382
383 $ echo "[format]" >> $HGRCPATH
383 $ echo "[format]" >> $HGRCPATH
384 $ echo "use-share-safe = True" >> $HGRCPATH
384 $ echo "use-share-safe = True" >> $HGRCPATH
385
385
386 $ cd $TESTTMP
386 $ cd $TESTTMP
387 $ hg init repo4
387 $ hg init repo4
388 $ cd repo4
388 $ cd repo4
389 $ echo a > a
389 $ echo a > a
390 $ hg commit -A -m'init'
390 $ hg commit -A -m'init'
391 adding a
391 adding a
392
392
393 $ cd ..
393 $ cd ..
394 $ hg share repo4 repo5
394 $ hg share repo4 repo5
395 updating working directory
395 updating working directory
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
396 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
397
397
398 And check that basic rhg commands work with sharing
398 And check that basic rhg commands work with sharing
399
399
400 $ cd repo5
400 $ cd repo5
401 $ $NO_FALLBACK rhg files
401 $ $NO_FALLBACK rhg files
402 a
402 a
403 $ $NO_FALLBACK rhg cat -r 0 a
403 $ $NO_FALLBACK rhg cat -r 0 a
404 a
404 a
405
405
406 The blackbox extension is supported
406 The blackbox extension is supported
407
407
408 $ echo "[extensions]" >> $HGRCPATH
408 $ echo "[extensions]" >> $HGRCPATH
409 $ echo "blackbox =" >> $HGRCPATH
409 $ echo "blackbox =" >> $HGRCPATH
410 $ echo "[blackbox]" >> $HGRCPATH
410 $ echo "[blackbox]" >> $HGRCPATH
411 $ echo "maxsize = 1" >> $HGRCPATH
411 $ echo "maxsize = 1" >> $HGRCPATH
412 $ $NO_FALLBACK rhg files > /dev/null
412 $ $NO_FALLBACK rhg files > /dev/null
413 $ cat .hg/blackbox.log
413 $ cat .hg/blackbox.log
414 ????-??-?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files exited 0 after * seconds (glob)
414 ????-??-?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files exited 0 after * seconds (glob)
415 $ cat .hg/blackbox.log.1
415 $ cat .hg/blackbox.log.1
416 ????-??-?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files (glob)
416 ????-??-?? ??:??:??.??? * @d3873e73d99ef67873dac33fbcc66268d5d2b6f4 (*)> (rust) files (glob)
417
417
418 Subrepos are not supported
418 Subrepos are not supported
419
419
420 $ touch .hgsub
420 $ touch .hgsub
421 $ $NO_FALLBACK rhg files
421 $ $NO_FALLBACK rhg files
422 unsupported feature: subrepos (.hgsub is present)
422 unsupported feature: subrepos (.hgsub is present)
423 [252]
423 [252]
424 $ rhg files
424 $ rhg files
425 a
425 a
426 $ rm .hgsub
426 $ rm .hgsub
427
427
428 The `:required` extension suboptions are correctly ignored
428 The `:required` extension suboptions are correctly ignored
429
429
430 $ echo "[extensions]" >> $HGRCPATH
430 $ echo "[extensions]" >> $HGRCPATH
431 $ echo "blackbox:required = yes" >> $HGRCPATH
431 $ echo "blackbox:required = yes" >> $HGRCPATH
432 $ rhg files
432 $ rhg files
433 a
433 a
434 $ echo "*:required = yes" >> $HGRCPATH
434 $ echo "*:required = yes" >> $HGRCPATH
435 $ rhg files
435 $ rhg files
436 a
436 a
437
437
438 Check that we expand both user and environment in ignore includes (HOME is TESTTMP)
438 Check that we expand both user and environment in ignore includes (HOME is TESTTMP)
439
439
440 $ echo "specificprefix" > ~/ignore.expected-extension
440 $ echo "specificprefix" > ~/ignore.expected-extension
441 $ touch specificprefix
441 $ touch specificprefix
442 $ $NO_FALLBACK rhg st
442 $ $NO_FALLBACK rhg st
443 ? specificprefix
443 ? specificprefix
444 $ $NO_FALLBACK RHG_EXT_TEST=expected-extension rhg st --config 'ui.ignore=~/ignore.${RHG_EXT_TEST}'
444 $ $NO_FALLBACK RHG_EXT_TEST=expected-extension rhg st --config 'ui.ignore=~/ignore.${RHG_EXT_TEST}'
445
445
446 We can ignore all extensions at once
446 We can ignore all extensions at once
447
447
448 $ echo "[extensions]" >> $HGRCPATH
448 $ echo "[extensions]" >> $HGRCPATH
449 $ echo "thisextensionbetternotexist=" >> $HGRCPATH
449 $ echo "thisextensionbetternotexist=" >> $HGRCPATH
450 $ echo "thisextensionbetternotexisteither=" >> $HGRCPATH
450 $ echo "thisextensionbetternotexisteither=" >> $HGRCPATH
451 $ $NO_FALLBACK rhg files
451 $ $NO_FALLBACK rhg files
452 unsupported feature: extensions: thisextensionbetternotexist, thisextensionbetternotexisteither (consider adding them to 'rhg.ignored-extensions' config)
452 unsupported feature: extensions: thisextensionbetternotexist, thisextensionbetternotexisteither (consider adding them to 'rhg.ignored-extensions' config)
453 [252]
453 [252]
454
454
455 $ echo "[rhg]" >> $HGRCPATH
455 $ echo "[rhg]" >> $HGRCPATH
456 $ echo "ignored-extensions=*" >> $HGRCPATH
456 $ echo "ignored-extensions=*" >> $HGRCPATH
457 $ $NO_FALLBACK rhg files
457 $ $NO_FALLBACK rhg files
458 a
458 a
General Comments 0
You need to be logged in to leave comments. Login now