##// END OF EJS Templates
rhg: Config commands.status.terse is not supported...
Simon Sapin -
r49161:f9db8eeb default
parent child Browse files
Show More
@@ -1,315 +1,324 b''
1 // status.rs
1 // status.rs
2 //
2 //
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net>
3 // Copyright 2020, Georges Racinet <georges.racinets@octobus.net>
4 //
4 //
5 // This software may be used and distributed according to the terms of the
5 // This software may be used and distributed according to the terms of the
6 // GNU General Public License version 2 or any later version.
6 // GNU General Public License version 2 or any later version.
7
7
8 use crate::error::CommandError;
8 use crate::error::CommandError;
9 use crate::ui::{Ui, UiError};
9 use crate::ui::{Ui, UiError};
10 use crate::utils::path_utils::relativize_paths;
10 use crate::utils::path_utils::relativize_paths;
11 use clap::{Arg, SubCommand};
11 use clap::{Arg, SubCommand};
12 use hg;
12 use hg;
13 use hg::config::Config;
13 use hg::config::Config;
14 use hg::dirstate::TruncatedTimestamp;
14 use hg::dirstate::TruncatedTimestamp;
15 use hg::errors::HgError;
15 use hg::errors::HgError;
16 use hg::manifest::Manifest;
16 use hg::manifest::Manifest;
17 use hg::matchers::AlwaysMatcher;
17 use hg::matchers::AlwaysMatcher;
18 use hg::repo::Repo;
18 use hg::repo::Repo;
19 use hg::utils::hg_path::{hg_path_to_os_string, HgPath};
19 use hg::utils::hg_path::{hg_path_to_os_string, HgPath};
20 use hg::{HgPathCow, StatusOptions};
20 use hg::{HgPathCow, StatusOptions};
21 use log::{info, warn};
21 use log::{info, warn};
22 use std::borrow::Cow;
22 use std::borrow::Cow;
23
23
24 pub const HELP_TEXT: &str = "
24 pub const HELP_TEXT: &str = "
25 Show changed files in the working directory
25 Show changed files in the working directory
26
26
27 This is a pure Rust version of `hg status`.
27 This is a pure Rust version of `hg status`.
28
28
29 Some options might be missing, check the list below.
29 Some options might be missing, check the list below.
30 ";
30 ";
31
31
32 pub fn args() -> clap::App<'static, 'static> {
32 pub fn args() -> clap::App<'static, 'static> {
33 SubCommand::with_name("status")
33 SubCommand::with_name("status")
34 .alias("st")
34 .alias("st")
35 .about(HELP_TEXT)
35 .about(HELP_TEXT)
36 .arg(
36 .arg(
37 Arg::with_name("all")
37 Arg::with_name("all")
38 .help("show status of all files")
38 .help("show status of all files")
39 .short("-A")
39 .short("-A")
40 .long("--all"),
40 .long("--all"),
41 )
41 )
42 .arg(
42 .arg(
43 Arg::with_name("modified")
43 Arg::with_name("modified")
44 .help("show only modified files")
44 .help("show only modified files")
45 .short("-m")
45 .short("-m")
46 .long("--modified"),
46 .long("--modified"),
47 )
47 )
48 .arg(
48 .arg(
49 Arg::with_name("added")
49 Arg::with_name("added")
50 .help("show only added files")
50 .help("show only added files")
51 .short("-a")
51 .short("-a")
52 .long("--added"),
52 .long("--added"),
53 )
53 )
54 .arg(
54 .arg(
55 Arg::with_name("removed")
55 Arg::with_name("removed")
56 .help("show only removed files")
56 .help("show only removed files")
57 .short("-r")
57 .short("-r")
58 .long("--removed"),
58 .long("--removed"),
59 )
59 )
60 .arg(
60 .arg(
61 Arg::with_name("clean")
61 Arg::with_name("clean")
62 .help("show only clean files")
62 .help("show only clean files")
63 .short("-c")
63 .short("-c")
64 .long("--clean"),
64 .long("--clean"),
65 )
65 )
66 .arg(
66 .arg(
67 Arg::with_name("deleted")
67 Arg::with_name("deleted")
68 .help("show only deleted files")
68 .help("show only deleted files")
69 .short("-d")
69 .short("-d")
70 .long("--deleted"),
70 .long("--deleted"),
71 )
71 )
72 .arg(
72 .arg(
73 Arg::with_name("unknown")
73 Arg::with_name("unknown")
74 .help("show only unknown (not tracked) files")
74 .help("show only unknown (not tracked) files")
75 .short("-u")
75 .short("-u")
76 .long("--unknown"),
76 .long("--unknown"),
77 )
77 )
78 .arg(
78 .arg(
79 Arg::with_name("ignored")
79 Arg::with_name("ignored")
80 .help("show only ignored files")
80 .help("show only ignored files")
81 .short("-i")
81 .short("-i")
82 .long("--ignored"),
82 .long("--ignored"),
83 )
83 )
84 }
84 }
85
85
86 /// Pure data type allowing the caller to specify file states to display
86 /// Pure data type allowing the caller to specify file states to display
87 #[derive(Copy, Clone, Debug)]
87 #[derive(Copy, Clone, Debug)]
88 pub struct DisplayStates {
88 pub struct DisplayStates {
89 pub modified: bool,
89 pub modified: bool,
90 pub added: bool,
90 pub added: bool,
91 pub removed: bool,
91 pub removed: bool,
92 pub clean: bool,
92 pub clean: bool,
93 pub deleted: bool,
93 pub deleted: bool,
94 pub unknown: bool,
94 pub unknown: bool,
95 pub ignored: bool,
95 pub ignored: bool,
96 }
96 }
97
97
98 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
98 pub const DEFAULT_DISPLAY_STATES: DisplayStates = DisplayStates {
99 modified: true,
99 modified: true,
100 added: true,
100 added: true,
101 removed: true,
101 removed: true,
102 clean: false,
102 clean: false,
103 deleted: true,
103 deleted: true,
104 unknown: true,
104 unknown: true,
105 ignored: false,
105 ignored: false,
106 };
106 };
107
107
108 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
108 pub const ALL_DISPLAY_STATES: DisplayStates = DisplayStates {
109 modified: true,
109 modified: true,
110 added: true,
110 added: true,
111 removed: true,
111 removed: true,
112 clean: true,
112 clean: true,
113 deleted: true,
113 deleted: true,
114 unknown: true,
114 unknown: true,
115 ignored: true,
115 ignored: true,
116 };
116 };
117
117
118 impl DisplayStates {
118 impl DisplayStates {
119 pub fn is_empty(&self) -> bool {
119 pub fn is_empty(&self) -> bool {
120 !(self.modified
120 !(self.modified
121 || self.added
121 || self.added
122 || self.removed
122 || self.removed
123 || self.clean
123 || self.clean
124 || self.deleted
124 || self.deleted
125 || self.unknown
125 || self.unknown
126 || self.ignored)
126 || self.ignored)
127 }
127 }
128 }
128 }
129
129
130 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
130 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
131 let status_enabled_default = false;
131 let status_enabled_default = false;
132 let status_enabled = invocation.config.get_option(b"rhg", b"status")?;
132 let status_enabled = invocation.config.get_option(b"rhg", b"status")?;
133 if !status_enabled.unwrap_or(status_enabled_default) {
133 if !status_enabled.unwrap_or(status_enabled_default) {
134 return Err(CommandError::unsupported(
134 return Err(CommandError::unsupported(
135 "status is experimental in rhg (enable it with 'rhg.status = true' \
135 "status is experimental in rhg (enable it with 'rhg.status = true' \
136 or enable fallback with 'rhg.on-unsupported = fallback')"
136 or enable fallback with 'rhg.on-unsupported = fallback')"
137 ));
137 ));
138 }
138 }
139
139
140 // TODO: lift these limitations
140 // TODO: lift these limitations
141 if invocation.config.get_bool(b"ui", b"tweakdefaults")? {
141 if invocation.config.get_bool(b"ui", b"tweakdefaults")? {
142 return Err(CommandError::unsupported(
142 return Err(CommandError::unsupported(
143 "ui.tweakdefaults is not yet supported with rhg status",
143 "ui.tweakdefaults is not yet supported with rhg status",
144 ));
144 ));
145 }
145 }
146 if invocation.config.get_bool(b"ui", b"statuscopies")? {
146 if invocation.config.get_bool(b"ui", b"statuscopies")? {
147 return Err(CommandError::unsupported(
147 return Err(CommandError::unsupported(
148 "ui.statuscopies is not yet supported with rhg status",
148 "ui.statuscopies is not yet supported with rhg status",
149 ));
149 ));
150 }
150 }
151 if invocation
152 .config
153 .get(b"commands", b"status.terse")
154 .is_some()
155 {
156 return Err(CommandError::unsupported(
157 "status.terse is not yet supported with rhg status",
158 ));
159 }
151
160
152 let ui = invocation.ui;
161 let ui = invocation.ui;
153 let config = invocation.config;
162 let config = invocation.config;
154 let args = invocation.subcommand_args;
163 let args = invocation.subcommand_args;
155 let display_states = if args.is_present("all") {
164 let display_states = if args.is_present("all") {
156 // TODO when implementing `--quiet`: it excludes clean files
165 // TODO when implementing `--quiet`: it excludes clean files
157 // from `--all`
166 // from `--all`
158 ALL_DISPLAY_STATES
167 ALL_DISPLAY_STATES
159 } else {
168 } else {
160 let requested = DisplayStates {
169 let requested = DisplayStates {
161 modified: args.is_present("modified"),
170 modified: args.is_present("modified"),
162 added: args.is_present("added"),
171 added: args.is_present("added"),
163 removed: args.is_present("removed"),
172 removed: args.is_present("removed"),
164 clean: args.is_present("clean"),
173 clean: args.is_present("clean"),
165 deleted: args.is_present("deleted"),
174 deleted: args.is_present("deleted"),
166 unknown: args.is_present("unknown"),
175 unknown: args.is_present("unknown"),
167 ignored: args.is_present("ignored"),
176 ignored: args.is_present("ignored"),
168 };
177 };
169 if requested.is_empty() {
178 if requested.is_empty() {
170 DEFAULT_DISPLAY_STATES
179 DEFAULT_DISPLAY_STATES
171 } else {
180 } else {
172 requested
181 requested
173 }
182 }
174 };
183 };
175
184
176 let repo = invocation.repo?;
185 let repo = invocation.repo?;
177 let mut dmap = repo.dirstate_map_mut()?;
186 let mut dmap = repo.dirstate_map_mut()?;
178
187
179 let options = StatusOptions {
188 let options = StatusOptions {
180 // TODO should be provided by the dirstate parsing and
189 // TODO should be provided by the dirstate parsing and
181 // hence be stored on dmap. Using a value that assumes we aren't
190 // hence be stored on dmap. Using a value that assumes we aren't
182 // below the time resolution granularity of the FS and the
191 // below the time resolution granularity of the FS and the
183 // dirstate.
192 // dirstate.
184 last_normal_time: TruncatedTimestamp::new_truncate(0, 0),
193 last_normal_time: TruncatedTimestamp::new_truncate(0, 0),
185 // we're currently supporting file systems with exec flags only
194 // we're currently supporting file systems with exec flags only
186 // anyway
195 // anyway
187 check_exec: true,
196 check_exec: true,
188 list_clean: display_states.clean,
197 list_clean: display_states.clean,
189 list_unknown: display_states.unknown,
198 list_unknown: display_states.unknown,
190 list_ignored: display_states.ignored,
199 list_ignored: display_states.ignored,
191 collect_traversed_dirs: false,
200 collect_traversed_dirs: false,
192 };
201 };
193 let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded
202 let ignore_file = repo.working_directory_vfs().join(".hgignore"); // TODO hardcoded
194 let (mut ds_status, pattern_warnings) = dmap.status(
203 let (mut ds_status, pattern_warnings) = dmap.status(
195 &AlwaysMatcher,
204 &AlwaysMatcher,
196 repo.working_directory_path().to_owned(),
205 repo.working_directory_path().to_owned(),
197 vec![ignore_file],
206 vec![ignore_file],
198 options,
207 options,
199 )?;
208 )?;
200 if !pattern_warnings.is_empty() {
209 if !pattern_warnings.is_empty() {
201 warn!("Pattern warnings: {:?}", &pattern_warnings);
210 warn!("Pattern warnings: {:?}", &pattern_warnings);
202 }
211 }
203
212
204 if !ds_status.bad.is_empty() {
213 if !ds_status.bad.is_empty() {
205 warn!("Bad matches {:?}", &(ds_status.bad))
214 warn!("Bad matches {:?}", &(ds_status.bad))
206 }
215 }
207 if !ds_status.unsure.is_empty() {
216 if !ds_status.unsure.is_empty() {
208 info!(
217 info!(
209 "Files to be rechecked by retrieval from filelog: {:?}",
218 "Files to be rechecked by retrieval from filelog: {:?}",
210 &ds_status.unsure
219 &ds_status.unsure
211 );
220 );
212 }
221 }
213 if !ds_status.unsure.is_empty()
222 if !ds_status.unsure.is_empty()
214 && (display_states.modified || display_states.clean)
223 && (display_states.modified || display_states.clean)
215 {
224 {
216 let p1 = repo.dirstate_parents()?.p1;
225 let p1 = repo.dirstate_parents()?.p1;
217 let manifest = repo.manifest_for_node(p1).map_err(|e| {
226 let manifest = repo.manifest_for_node(p1).map_err(|e| {
218 CommandError::from((e, &*format!("{:x}", p1.short())))
227 CommandError::from((e, &*format!("{:x}", p1.short())))
219 })?;
228 })?;
220 for to_check in ds_status.unsure {
229 for to_check in ds_status.unsure {
221 if cat_file_is_modified(repo, &manifest, &to_check)? {
230 if cat_file_is_modified(repo, &manifest, &to_check)? {
222 if display_states.modified {
231 if display_states.modified {
223 ds_status.modified.push(to_check);
232 ds_status.modified.push(to_check);
224 }
233 }
225 } else {
234 } else {
226 if display_states.clean {
235 if display_states.clean {
227 ds_status.clean.push(to_check);
236 ds_status.clean.push(to_check);
228 }
237 }
229 }
238 }
230 }
239 }
231 }
240 }
232 if display_states.modified {
241 if display_states.modified {
233 display_status_paths(ui, repo, config, &mut ds_status.modified, b"M")?;
242 display_status_paths(ui, repo, config, &mut ds_status.modified, b"M")?;
234 }
243 }
235 if display_states.added {
244 if display_states.added {
236 display_status_paths(ui, repo, config, &mut ds_status.added, b"A")?;
245 display_status_paths(ui, repo, config, &mut ds_status.added, b"A")?;
237 }
246 }
238 if display_states.removed {
247 if display_states.removed {
239 display_status_paths(ui, repo, config, &mut ds_status.removed, b"R")?;
248 display_status_paths(ui, repo, config, &mut ds_status.removed, b"R")?;
240 }
249 }
241 if display_states.deleted {
250 if display_states.deleted {
242 display_status_paths(ui, repo, config, &mut ds_status.deleted, b"!")?;
251 display_status_paths(ui, repo, config, &mut ds_status.deleted, b"!")?;
243 }
252 }
244 if display_states.unknown {
253 if display_states.unknown {
245 display_status_paths(ui, repo, config, &mut ds_status.unknown, b"?")?;
254 display_status_paths(ui, repo, config, &mut ds_status.unknown, b"?")?;
246 }
255 }
247 if display_states.ignored {
256 if display_states.ignored {
248 display_status_paths(ui, repo, config, &mut ds_status.ignored, b"I")?;
257 display_status_paths(ui, repo, config, &mut ds_status.ignored, b"I")?;
249 }
258 }
250 if display_states.clean {
259 if display_states.clean {
251 display_status_paths(ui, repo, config, &mut ds_status.clean, b"C")?;
260 display_status_paths(ui, repo, config, &mut ds_status.clean, b"C")?;
252 }
261 }
253 Ok(())
262 Ok(())
254 }
263 }
255
264
256 // Probably more elegant to use a Deref or Borrow trait rather than
265 // Probably more elegant to use a Deref or Borrow trait rather than
257 // harcode HgPathBuf, but probably not really useful at this point
266 // harcode HgPathBuf, but probably not really useful at this point
258 fn display_status_paths(
267 fn display_status_paths(
259 ui: &Ui,
268 ui: &Ui,
260 repo: &Repo,
269 repo: &Repo,
261 config: &Config,
270 config: &Config,
262 paths: &mut [HgPathCow],
271 paths: &mut [HgPathCow],
263 status_prefix: &[u8],
272 status_prefix: &[u8],
264 ) -> Result<(), CommandError> {
273 ) -> Result<(), CommandError> {
265 paths.sort_unstable();
274 paths.sort_unstable();
266 let mut relative: bool = config.get_bool(b"ui", b"relative-paths")?;
275 let mut relative: bool = config.get_bool(b"ui", b"relative-paths")?;
267 relative = config
276 relative = config
268 .get_option(b"commands", b"status.relative")?
277 .get_option(b"commands", b"status.relative")?
269 .unwrap_or(relative);
278 .unwrap_or(relative);
270 if relative && !ui.plain() {
279 if relative && !ui.plain() {
271 relativize_paths(
280 relativize_paths(
272 repo,
281 repo,
273 paths,
282 paths,
274 |path: Cow<[u8]>| -> Result<(), UiError> {
283 |path: Cow<[u8]>| -> Result<(), UiError> {
275 ui.write_stdout(
284 ui.write_stdout(
276 &[status_prefix, b" ", path.as_ref(), b"\n"].concat(),
285 &[status_prefix, b" ", path.as_ref(), b"\n"].concat(),
277 )
286 )
278 },
287 },
279 )?;
288 )?;
280 } else {
289 } else {
281 for path in paths {
290 for path in paths {
282 // Same TODO as in commands::root
291 // Same TODO as in commands::root
283 let bytes: &[u8] = path.as_bytes();
292 let bytes: &[u8] = path.as_bytes();
284 // TODO optim, probably lots of unneeded copies here, especially
293 // TODO optim, probably lots of unneeded copies here, especially
285 // if out stream is buffered
294 // if out stream is buffered
286 ui.write_stdout(&[status_prefix, b" ", bytes, b"\n"].concat())?;
295 ui.write_stdout(&[status_prefix, b" ", bytes, b"\n"].concat())?;
287 }
296 }
288 }
297 }
289 Ok(())
298 Ok(())
290 }
299 }
291
300
292 /// Check if a file is modified by comparing actual repo store and file system.
301 /// Check if a file is modified by comparing actual repo store and file system.
293 ///
302 ///
294 /// This meant to be used for those that the dirstate cannot resolve, due
303 /// This meant to be used for those that the dirstate cannot resolve, due
295 /// to time resolution limits.
304 /// to time resolution limits.
296 ///
305 ///
297 /// TODO: detect permission bits and similar metadata modifications
306 /// TODO: detect permission bits and similar metadata modifications
298 fn cat_file_is_modified(
307 fn cat_file_is_modified(
299 repo: &Repo,
308 repo: &Repo,
300 manifest: &Manifest,
309 manifest: &Manifest,
301 hg_path: &HgPath,
310 hg_path: &HgPath,
302 ) -> Result<bool, HgError> {
311 ) -> Result<bool, HgError> {
303 let file_node = manifest
312 let file_node = manifest
304 .find_file(hg_path)?
313 .find_file(hg_path)?
305 .expect("ambgious file not in p1");
314 .expect("ambgious file not in p1");
306 let filelog = repo.filelog(hg_path)?;
315 let filelog = repo.filelog(hg_path)?;
307 let filelog_entry = filelog.data_for_node(file_node).map_err(|_| {
316 let filelog_entry = filelog.data_for_node(file_node).map_err(|_| {
308 HgError::corrupted("filelog missing node from manifest")
317 HgError::corrupted("filelog missing node from manifest")
309 })?;
318 })?;
310 let contents_in_p1 = filelog_entry.data()?;
319 let contents_in_p1 = filelog_entry.data()?;
311
320
312 let fs_path = hg_path_to_os_string(hg_path).expect("HgPath conversion");
321 let fs_path = hg_path_to_os_string(hg_path).expect("HgPath conversion");
313 let fs_contents = repo.working_directory_vfs().read(fs_path)?;
322 let fs_contents = repo.working_directory_vfs().read(fs_path)?;
314 return Ok(contents_in_p1 != &*fs_contents);
323 return Ok(contents_in_p1 != &*fs_contents);
315 }
324 }
@@ -1,283 +1,279 b''
1 TODO: fix rhg bugs that make this test fail when status is enabled
2 $ unset RHG_STATUS
3
4
5 $ mkdir folder
1 $ mkdir folder
6 $ cd folder
2 $ cd folder
7 $ hg init
3 $ hg init
8 $ mkdir x x/l x/m x/n x/l/u x/l/u/a
4 $ mkdir x x/l x/m x/n x/l/u x/l/u/a
9 $ touch a b x/aa.o x/bb.o
5 $ touch a b x/aa.o x/bb.o
10 $ hg status
6 $ hg status
11 ? a
7 ? a
12 ? b
8 ? b
13 ? x/aa.o
9 ? x/aa.o
14 ? x/bb.o
10 ? x/bb.o
15
11
16 $ hg status --terse u
12 $ hg status --terse u
17 ? a
13 ? a
18 ? b
14 ? b
19 ? x/
15 ? x/
20 $ hg status --terse maudric
16 $ hg status --terse maudric
21 ? a
17 ? a
22 ? b
18 ? b
23 ? x/
19 ? x/
24 $ hg status --terse madric
20 $ hg status --terse madric
25 ? a
21 ? a
26 ? b
22 ? b
27 ? x/aa.o
23 ? x/aa.o
28 ? x/bb.o
24 ? x/bb.o
29 $ hg status --terse f
25 $ hg status --terse f
30 abort: 'f' not recognized
26 abort: 'f' not recognized
31 [10]
27 [10]
32
28
33 Add a .hgignore so that we can also have ignored files
29 Add a .hgignore so that we can also have ignored files
34
30
35 $ echo ".*\.o" > .hgignore
31 $ echo ".*\.o" > .hgignore
36 $ hg status
32 $ hg status
37 ? .hgignore
33 ? .hgignore
38 ? a
34 ? a
39 ? b
35 ? b
40 $ hg status -i
36 $ hg status -i
41 I x/aa.o
37 I x/aa.o
42 I x/bb.o
38 I x/bb.o
43
39
44 Tersing ignored files
40 Tersing ignored files
45 $ hg status -t i --ignored
41 $ hg status -t i --ignored
46 I x/
42 I x/
47
43
48 Adding more files
44 Adding more files
49 $ mkdir y
45 $ mkdir y
50 $ touch x/aa x/bb y/l y/m y/l.o y/m.o
46 $ touch x/aa x/bb y/l y/m y/l.o y/m.o
51 $ touch x/l/aa x/m/aa x/n/aa x/l/u/bb x/l/u/a/bb
47 $ touch x/l/aa x/m/aa x/n/aa x/l/u/bb x/l/u/a/bb
52
48
53 $ hg status
49 $ hg status
54 ? .hgignore
50 ? .hgignore
55 ? a
51 ? a
56 ? b
52 ? b
57 ? x/aa
53 ? x/aa
58 ? x/bb
54 ? x/bb
59 ? x/l/aa
55 ? x/l/aa
60 ? x/l/u/a/bb
56 ? x/l/u/a/bb
61 ? x/l/u/bb
57 ? x/l/u/bb
62 ? x/m/aa
58 ? x/m/aa
63 ? x/n/aa
59 ? x/n/aa
64 ? y/l
60 ? y/l
65 ? y/m
61 ? y/m
66
62
67 $ hg status --terse u
63 $ hg status --terse u
68 ? .hgignore
64 ? .hgignore
69 ? a
65 ? a
70 ? b
66 ? b
71 ? x/
67 ? x/
72 ? y/
68 ? y/
73
69
74 Run from subdirectory
70 Run from subdirectory
75 $ hg status --terse u --cwd x/l
71 $ hg status --terse u --cwd x/l
76 ? .hgignore
72 ? .hgignore
77 ? a
73 ? a
78 ? b
74 ? b
79 ? x/
75 ? x/
80 ? y/
76 ? y/
81 $ relstatus() {
77 $ relstatus() {
82 > hg status --terse u --config commands.status.relative=1 "$@";
78 > hg status --terse u --config commands.status.relative=1 "$@";
83 > }
79 > }
84 This should probably have {"l/", "m/", "n/"} instead of {"."}. They should
80 This should probably have {"l/", "m/", "n/"} instead of {"."}. They should
85 probably come after "../y/".
81 probably come after "../y/".
86 $ relstatus --cwd x
82 $ relstatus --cwd x
87 ? ../.hgignore
83 ? ../.hgignore
88 ? ../a
84 ? ../a
89 ? ../b
85 ? ../b
90 ? .
86 ? .
91 ? ../y/
87 ? ../y/
92 This should probably have {"u/", "../m/", "../n/"} instead of {"../"}.
88 This should probably have {"u/", "../m/", "../n/"} instead of {"../"}.
93 $ relstatus --cwd x/l
89 $ relstatus --cwd x/l
94 ? ../../.hgignore
90 ? ../../.hgignore
95 ? ../../a
91 ? ../../a
96 ? ../../b
92 ? ../../b
97 ? ../
93 ? ../
98 ? ../../y/
94 ? ../../y/
99 This should probably have {"a/", "bb", "../aa", "../../m/", "../../n/"}
95 This should probably have {"a/", "bb", "../aa", "../../m/", "../../n/"}
100 instead of {"../../"}.
96 instead of {"../../"}.
101 $ relstatus --cwd x/l/u
97 $ relstatus --cwd x/l/u
102 ? ../../../.hgignore
98 ? ../../../.hgignore
103 ? ../../../a
99 ? ../../../a
104 ? ../../../b
100 ? ../../../b
105 ? ../../
101 ? ../../
106 ? ../../../y/
102 ? ../../../y/
107 This should probably have {"bb", "../bb", "../../aa", "../../../m/",
103 This should probably have {"bb", "../bb", "../../aa", "../../../m/",
108 "../../../n/"} instead of {"../../../"}.
104 "../../../n/"} instead of {"../../../"}.
109 $ relstatus --cwd x/l/u/a
105 $ relstatus --cwd x/l/u/a
110 ? ../../../../.hgignore
106 ? ../../../../.hgignore
111 ? ../../../../a
107 ? ../../../../a
112 ? ../../../../b
108 ? ../../../../b
113 ? ../../../
109 ? ../../../
114 ? ../../../../y/
110 ? ../../../../y/
115
111
116 $ hg add x/aa x/bb .hgignore
112 $ hg add x/aa x/bb .hgignore
117 $ hg status --terse au
113 $ hg status --terse au
118 A .hgignore
114 A .hgignore
119 A x/aa
115 A x/aa
120 A x/bb
116 A x/bb
121 ? a
117 ? a
122 ? b
118 ? b
123 ? x/l/
119 ? x/l/
124 ? x/m/
120 ? x/m/
125 ? x/n/
121 ? x/n/
126 ? y/
122 ? y/
127
123
128 Including ignored files
124 Including ignored files
129
125
130 $ hg status --terse aui
126 $ hg status --terse aui
131 A .hgignore
127 A .hgignore
132 A x/aa
128 A x/aa
133 A x/bb
129 A x/bb
134 ? a
130 ? a
135 ? b
131 ? b
136 ? x/l/
132 ? x/l/
137 ? x/m/
133 ? x/m/
138 ? x/n/
134 ? x/n/
139 ? y/l
135 ? y/l
140 ? y/m
136 ? y/m
141 $ hg status --terse au -i
137 $ hg status --terse au -i
142 I x/aa.o
138 I x/aa.o
143 I x/bb.o
139 I x/bb.o
144 I y/l.o
140 I y/l.o
145 I y/m.o
141 I y/m.o
146
142
147 Committing some of the files
143 Committing some of the files
148
144
149 $ hg commit x/aa x/bb .hgignore -m "First commit"
145 $ hg commit x/aa x/bb .hgignore -m "First commit"
150 $ hg status
146 $ hg status
151 ? a
147 ? a
152 ? b
148 ? b
153 ? x/l/aa
149 ? x/l/aa
154 ? x/l/u/a/bb
150 ? x/l/u/a/bb
155 ? x/l/u/bb
151 ? x/l/u/bb
156 ? x/m/aa
152 ? x/m/aa
157 ? x/n/aa
153 ? x/n/aa
158 ? y/l
154 ? y/l
159 ? y/m
155 ? y/m
160 $ hg status --terse mardu
156 $ hg status --terse mardu
161 ? a
157 ? a
162 ? b
158 ? b
163 ? x/l/
159 ? x/l/
164 ? x/m/
160 ? x/m/
165 ? x/n/
161 ? x/n/
166 ? y/
162 ? y/
167
163
168 Modifying already committed files
164 Modifying already committed files
169
165
170 $ echo "Hello" >> x/aa
166 $ echo "Hello" >> x/aa
171 $ echo "World" >> x/bb
167 $ echo "World" >> x/bb
172 $ hg status --terse maurdc
168 $ hg status --terse maurdc
173 M x/aa
169 M x/aa
174 M x/bb
170 M x/bb
175 ? a
171 ? a
176 ? b
172 ? b
177 ? x/l/
173 ? x/l/
178 ? x/m/
174 ? x/m/
179 ? x/n/
175 ? x/n/
180 ? y/
176 ? y/
181
177
182 Respecting other flags
178 Respecting other flags
183
179
184 $ hg status --terse marduic --all
180 $ hg status --terse marduic --all
185 M x/aa
181 M x/aa
186 M x/bb
182 M x/bb
187 ? a
183 ? a
188 ? b
184 ? b
189 ? x/l/
185 ? x/l/
190 ? x/m/
186 ? x/m/
191 ? x/n/
187 ? x/n/
192 ? y/l
188 ? y/l
193 ? y/m
189 ? y/m
194 I x/aa.o
190 I x/aa.o
195 I x/bb.o
191 I x/bb.o
196 I y/l.o
192 I y/l.o
197 I y/m.o
193 I y/m.o
198 C .hgignore
194 C .hgignore
199 $ hg status --terse marduic -a
195 $ hg status --terse marduic -a
200 $ hg status --terse marduic -c
196 $ hg status --terse marduic -c
201 C .hgignore
197 C .hgignore
202 $ hg status --terse marduic -m
198 $ hg status --terse marduic -m
203 M x/aa
199 M x/aa
204 M x/bb
200 M x/bb
205
201
206 Passing 'i' in terse value will consider the ignored files while tersing
202 Passing 'i' in terse value will consider the ignored files while tersing
207
203
208 $ hg status --terse marduic -u
204 $ hg status --terse marduic -u
209 ? a
205 ? a
210 ? b
206 ? b
211 ? x/l/
207 ? x/l/
212 ? x/m/
208 ? x/m/
213 ? x/n/
209 ? x/n/
214 ? y/l
210 ? y/l
215 ? y/m
211 ? y/m
216
212
217 Omitting 'i' in terse value does not consider ignored files while tersing
213 Omitting 'i' in terse value does not consider ignored files while tersing
218
214
219 $ hg status --terse marduc -u
215 $ hg status --terse marduc -u
220 ? a
216 ? a
221 ? b
217 ? b
222 ? x/l/
218 ? x/l/
223 ? x/m/
219 ? x/m/
224 ? x/n/
220 ? x/n/
225 ? y/
221 ? y/
226
222
227 Trying with --rev
223 Trying with --rev
228
224
229 $ hg status --terse marduic --rev 0 --rev 1
225 $ hg status --terse marduic --rev 0 --rev 1
230 abort: cannot use --terse with --rev
226 abort: cannot use --terse with --rev
231 [10]
227 [10]
232
228
233 Config item to set the default terseness
229 Config item to set the default terseness
234 $ cat <<EOF >> $HGRCPATH
230 $ cat <<EOF >> $HGRCPATH
235 > [commands]
231 > [commands]
236 > status.terse = u
232 > status.terse = u
237 > EOF
233 > EOF
238 $ hg status -mu
234 $ hg status -mu
239 M x/aa
235 M x/aa
240 M x/bb
236 M x/bb
241 ? a
237 ? a
242 ? b
238 ? b
243 ? x/l/
239 ? x/l/
244 ? x/m/
240 ? x/m/
245 ? x/n/
241 ? x/n/
246 ? y/
242 ? y/
247
243
248 Command line flag overrides the default
244 Command line flag overrides the default
249 $ hg status --terse=
245 $ hg status --terse=
250 M x/aa
246 M x/aa
251 M x/bb
247 M x/bb
252 ? a
248 ? a
253 ? b
249 ? b
254 ? x/l/aa
250 ? x/l/aa
255 ? x/l/u/a/bb
251 ? x/l/u/a/bb
256 ? x/l/u/bb
252 ? x/l/u/bb
257 ? x/m/aa
253 ? x/m/aa
258 ? x/n/aa
254 ? x/n/aa
259 ? y/l
255 ? y/l
260 ? y/m
256 ? y/m
261 $ hg status --terse=mardu
257 $ hg status --terse=mardu
262 M x/aa
258 M x/aa
263 M x/bb
259 M x/bb
264 ? a
260 ? a
265 ? b
261 ? b
266 ? x/l/
262 ? x/l/
267 ? x/m/
263 ? x/m/
268 ? x/n/
264 ? x/n/
269 ? y/
265 ? y/
270
266
271 Specifying --rev should still work, with the terseness disabled.
267 Specifying --rev should still work, with the terseness disabled.
272 $ hg status --rev 0
268 $ hg status --rev 0
273 M x/aa
269 M x/aa
274 M x/bb
270 M x/bb
275 ? a
271 ? a
276 ? b
272 ? b
277 ? x/l/aa
273 ? x/l/aa
278 ? x/l/u/a/bb
274 ? x/l/u/a/bb
279 ? x/l/u/bb
275 ? x/l/u/bb
280 ? x/m/aa
276 ? x/m/aa
281 ? x/n/aa
277 ? x/n/aa
282 ? y/l
278 ? y/l
283 ? y/m
279 ? y/m
General Comments 0
You need to be logged in to leave comments. Login now