##// END OF EJS Templates
rhg: support "!" syntax for disabling extensions...
Raphaël Gomès -
r50372:f3cd2d6e default
parent child Browse files
Show More
@@ -1,809 +1,814 b''
1 1 extern crate log;
2 2 use crate::error::CommandError;
3 3 use crate::ui::{local_to_utf8, Ui};
4 4 use clap::App;
5 5 use clap::AppSettings;
6 6 use clap::Arg;
7 7 use clap::ArgMatches;
8 8 use format_bytes::{format_bytes, join};
9 9 use hg::config::{Config, ConfigSource};
10 10 use hg::repo::{Repo, RepoError};
11 11 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
12 12 use hg::utils::SliceExt;
13 13 use hg::{exit_codes, requirements};
14 14 use std::collections::HashSet;
15 15 use std::ffi::OsString;
16 16 use std::os::unix::prelude::CommandExt;
17 17 use std::path::PathBuf;
18 18 use std::process::Command;
19 19
20 20 mod blackbox;
21 21 mod color;
22 22 mod error;
23 23 mod ui;
24 24 pub mod utils {
25 25 pub mod path_utils;
26 26 }
27 27
28 28 fn main_with_result(
29 29 argv: Vec<OsString>,
30 30 process_start_time: &blackbox::ProcessStartTime,
31 31 ui: &ui::Ui,
32 32 repo: Result<&Repo, &NoRepoInCwdError>,
33 33 config: &Config,
34 34 ) -> Result<(), CommandError> {
35 35 check_unsupported(config, repo)?;
36 36
37 37 let app = App::new("rhg")
38 38 .global_setting(AppSettings::AllowInvalidUtf8)
39 39 .global_setting(AppSettings::DisableVersion)
40 40 .setting(AppSettings::SubcommandRequired)
41 41 .setting(AppSettings::VersionlessSubcommands)
42 42 .arg(
43 43 Arg::with_name("repository")
44 44 .help("repository root directory")
45 45 .short("-R")
46 46 .long("--repository")
47 47 .value_name("REPO")
48 48 .takes_value(true)
49 49 // Both ok: `hg -R ./foo log` or `hg log -R ./foo`
50 50 .global(true),
51 51 )
52 52 .arg(
53 53 Arg::with_name("config")
54 54 .help("set/override config option (use 'section.name=value')")
55 55 .long("--config")
56 56 .value_name("CONFIG")
57 57 .takes_value(true)
58 58 .global(true)
59 59 // Ok: `--config section.key1=val --config section.key2=val2`
60 60 .multiple(true)
61 61 // Not ok: `--config section.key1=val section.key2=val2`
62 62 .number_of_values(1),
63 63 )
64 64 .arg(
65 65 Arg::with_name("cwd")
66 66 .help("change working directory")
67 67 .long("--cwd")
68 68 .value_name("DIR")
69 69 .takes_value(true)
70 70 .global(true),
71 71 )
72 72 .arg(
73 73 Arg::with_name("color")
74 74 .help("when to colorize (boolean, always, auto, never, or debug)")
75 75 .long("--color")
76 76 .value_name("TYPE")
77 77 .takes_value(true)
78 78 .global(true),
79 79 )
80 80 .version("0.0.1");
81 81 let app = add_subcommand_args(app);
82 82
83 83 let matches = app.clone().get_matches_from_safe(argv.iter())?;
84 84
85 85 let (subcommand_name, subcommand_matches) = matches.subcommand();
86 86
87 87 // Mercurial allows users to define "defaults" for commands, fallback
88 88 // if a default is detected for the current command
89 89 let defaults = config.get_str(b"defaults", subcommand_name.as_bytes());
90 90 if defaults?.is_some() {
91 91 let msg = "`defaults` config set";
92 92 return Err(CommandError::unsupported(msg));
93 93 }
94 94
95 95 for prefix in ["pre", "post", "fail"].iter() {
96 96 // Mercurial allows users to define generic hooks for commands,
97 97 // fallback if any are detected
98 98 let item = format!("{}-{}", prefix, subcommand_name);
99 99 let hook_for_command = config.get_str(b"hooks", item.as_bytes())?;
100 100 if hook_for_command.is_some() {
101 101 let msg = format!("{}-{} hook defined", prefix, subcommand_name);
102 102 return Err(CommandError::unsupported(msg));
103 103 }
104 104 }
105 105 let run = subcommand_run_fn(subcommand_name)
106 106 .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
107 107 let subcommand_args = subcommand_matches
108 108 .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
109 109
110 110 let invocation = CliInvocation {
111 111 ui,
112 112 subcommand_args,
113 113 config,
114 114 repo,
115 115 };
116 116
117 117 if let Ok(repo) = repo {
118 118 // We don't support subrepos, fallback if the subrepos file is present
119 119 if repo.working_directory_vfs().join(".hgsub").exists() {
120 120 let msg = "subrepos (.hgsub is present)";
121 121 return Err(CommandError::unsupported(msg));
122 122 }
123 123 }
124 124
125 125 if config.is_extension_enabled(b"blackbox") {
126 126 let blackbox =
127 127 blackbox::Blackbox::new(&invocation, process_start_time)?;
128 128 blackbox.log_command_start(argv.iter());
129 129 let result = run(&invocation);
130 130 blackbox.log_command_end(
131 131 argv.iter(),
132 132 exit_code(
133 133 &result,
134 134 // TODO: show a warning or combine with original error if
135 135 // `get_bool` returns an error
136 136 config
137 137 .get_bool(b"ui", b"detailed-exit-code")
138 138 .unwrap_or(false),
139 139 ),
140 140 );
141 141 result
142 142 } else {
143 143 run(&invocation)
144 144 }
145 145 }
146 146
147 147 fn rhg_main(argv: Vec<OsString>) -> ! {
148 148 // Run this first, before we find out if the blackbox extension is even
149 149 // enabled, in order to include everything in-between in the duration
150 150 // measurements. Reading config files can be slow if they’re on NFS.
151 151 let process_start_time = blackbox::ProcessStartTime::now();
152 152
153 153 env_logger::init();
154 154
155 155 let early_args = EarlyArgs::parse(&argv);
156 156
157 157 let initial_current_dir = early_args.cwd.map(|cwd| {
158 158 let cwd = get_path_from_bytes(&cwd);
159 159 std::env::current_dir()
160 160 .and_then(|initial| {
161 161 std::env::set_current_dir(cwd)?;
162 162 Ok(initial)
163 163 })
164 164 .unwrap_or_else(|error| {
165 165 exit(
166 166 &argv,
167 167 &None,
168 168 &Ui::new_infallible(&Config::empty()),
169 169 OnUnsupported::Abort,
170 170 Err(CommandError::abort(format!(
171 171 "abort: {}: '{}'",
172 172 error,
173 173 cwd.display()
174 174 ))),
175 175 false,
176 176 )
177 177 })
178 178 });
179 179
180 180 let mut non_repo_config =
181 181 Config::load_non_repo().unwrap_or_else(|error| {
182 182 // Normally this is decided based on config, but we don’t have that
183 183 // available. As of this writing config loading never returns an
184 184 // "unsupported" error but that is not enforced by the type system.
185 185 let on_unsupported = OnUnsupported::Abort;
186 186
187 187 exit(
188 188 &argv,
189 189 &initial_current_dir,
190 190 &Ui::new_infallible(&Config::empty()),
191 191 on_unsupported,
192 192 Err(error.into()),
193 193 false,
194 194 )
195 195 });
196 196
197 197 non_repo_config
198 198 .load_cli_args(early_args.config, early_args.color)
199 199 .unwrap_or_else(|error| {
200 200 exit(
201 201 &argv,
202 202 &initial_current_dir,
203 203 &Ui::new_infallible(&non_repo_config),
204 204 OnUnsupported::from_config(&non_repo_config),
205 205 Err(error.into()),
206 206 non_repo_config
207 207 .get_bool(b"ui", b"detailed-exit-code")
208 208 .unwrap_or(false),
209 209 )
210 210 });
211 211
212 212 if let Some(repo_path_bytes) = &early_args.repo {
213 213 lazy_static::lazy_static! {
214 214 static ref SCHEME_RE: regex::bytes::Regex =
215 215 // Same as `_matchscheme` in `mercurial/util.py`
216 216 regex::bytes::Regex::new("^[a-zA-Z0-9+.\\-]+:").unwrap();
217 217 }
218 218 if SCHEME_RE.is_match(&repo_path_bytes) {
219 219 exit(
220 220 &argv,
221 221 &initial_current_dir,
222 222 &Ui::new_infallible(&non_repo_config),
223 223 OnUnsupported::from_config(&non_repo_config),
224 224 Err(CommandError::UnsupportedFeature {
225 225 message: format_bytes!(
226 226 b"URL-like --repository {}",
227 227 repo_path_bytes
228 228 ),
229 229 }),
230 230 // TODO: show a warning or combine with original error if
231 231 // `get_bool` returns an error
232 232 non_repo_config
233 233 .get_bool(b"ui", b"detailed-exit-code")
234 234 .unwrap_or(false),
235 235 )
236 236 }
237 237 }
238 238 let repo_arg = early_args.repo.unwrap_or(Vec::new());
239 239 let repo_path: Option<PathBuf> = {
240 240 if repo_arg.is_empty() {
241 241 None
242 242 } else {
243 243 let local_config = {
244 244 if std::env::var_os("HGRCSKIPREPO").is_none() {
245 245 // TODO: handle errors from find_repo_root
246 246 if let Ok(current_dir_path) = Repo::find_repo_root() {
247 247 let config_files = vec![
248 248 ConfigSource::AbsPath(
249 249 current_dir_path.join(".hg/hgrc"),
250 250 ),
251 251 ConfigSource::AbsPath(
252 252 current_dir_path.join(".hg/hgrc-not-shared"),
253 253 ),
254 254 ];
255 255 // TODO: handle errors from
256 256 // `load_from_explicit_sources`
257 257 Config::load_from_explicit_sources(config_files).ok()
258 258 } else {
259 259 None
260 260 }
261 261 } else {
262 262 None
263 263 }
264 264 };
265 265
266 266 let non_repo_config_val = {
267 267 let non_repo_val = non_repo_config.get(b"paths", &repo_arg);
268 268 match &non_repo_val {
269 269 Some(val) if val.len() > 0 => home::home_dir()
270 270 .unwrap_or_else(|| PathBuf::from("~"))
271 271 .join(get_path_from_bytes(val))
272 272 .canonicalize()
273 273 // TODO: handle error and make it similar to python
274 274 // implementation maybe?
275 275 .ok(),
276 276 _ => None,
277 277 }
278 278 };
279 279
280 280 let config_val = match &local_config {
281 281 None => non_repo_config_val,
282 282 Some(val) => {
283 283 let local_config_val = val.get(b"paths", &repo_arg);
284 284 match &local_config_val {
285 285 Some(val) if val.len() > 0 => {
286 286 // presence of a local_config assures that
287 287 // current_dir
288 288 // wont result in an Error
289 289 let canpath = hg::utils::current_dir()
290 290 .unwrap()
291 291 .join(get_path_from_bytes(val))
292 292 .canonicalize();
293 293 canpath.ok().or(non_repo_config_val)
294 294 }
295 295 _ => non_repo_config_val,
296 296 }
297 297 }
298 298 };
299 299 config_val.or(Some(get_path_from_bytes(&repo_arg).to_path_buf()))
300 300 }
301 301 };
302 302
303 303 let repo_result = match Repo::find(&non_repo_config, repo_path.to_owned())
304 304 {
305 305 Ok(repo) => Ok(repo),
306 306 Err(RepoError::NotFound { at }) if repo_path.is_none() => {
307 307 // Not finding a repo is not fatal yet, if `-R` was not given
308 308 Err(NoRepoInCwdError { cwd: at })
309 309 }
310 310 Err(error) => exit(
311 311 &argv,
312 312 &initial_current_dir,
313 313 &Ui::new_infallible(&non_repo_config),
314 314 OnUnsupported::from_config(&non_repo_config),
315 315 Err(error.into()),
316 316 // TODO: show a warning or combine with original error if
317 317 // `get_bool` returns an error
318 318 non_repo_config
319 319 .get_bool(b"ui", b"detailed-exit-code")
320 320 .unwrap_or(false),
321 321 ),
322 322 };
323 323
324 324 let config = if let Ok(repo) = &repo_result {
325 325 repo.config()
326 326 } else {
327 327 &non_repo_config
328 328 };
329 329 let ui = Ui::new(&config).unwrap_or_else(|error| {
330 330 exit(
331 331 &argv,
332 332 &initial_current_dir,
333 333 &Ui::new_infallible(&config),
334 334 OnUnsupported::from_config(&config),
335 335 Err(error.into()),
336 336 config
337 337 .get_bool(b"ui", b"detailed-exit-code")
338 338 .unwrap_or(false),
339 339 )
340 340 });
341 341 let on_unsupported = OnUnsupported::from_config(config);
342 342
343 343 let result = main_with_result(
344 344 argv.iter().map(|s| s.to_owned()).collect(),
345 345 &process_start_time,
346 346 &ui,
347 347 repo_result.as_ref(),
348 348 config,
349 349 );
350 350 exit(
351 351 &argv,
352 352 &initial_current_dir,
353 353 &ui,
354 354 on_unsupported,
355 355 result,
356 356 // TODO: show a warning or combine with original error if `get_bool`
357 357 // returns an error
358 358 config
359 359 .get_bool(b"ui", b"detailed-exit-code")
360 360 .unwrap_or(false),
361 361 )
362 362 }
363 363
364 364 fn main() -> ! {
365 365 rhg_main(std::env::args_os().collect())
366 366 }
367 367
368 368 fn exit_code(
369 369 result: &Result<(), CommandError>,
370 370 use_detailed_exit_code: bool,
371 371 ) -> i32 {
372 372 match result {
373 373 Ok(()) => exit_codes::OK,
374 374 Err(CommandError::Abort {
375 375 message: _,
376 376 detailed_exit_code,
377 377 }) => {
378 378 if use_detailed_exit_code {
379 379 *detailed_exit_code
380 380 } else {
381 381 exit_codes::ABORT
382 382 }
383 383 }
384 384 Err(CommandError::Unsuccessful) => exit_codes::UNSUCCESSFUL,
385 385 // Exit with a specific code and no error message to let a potential
386 386 // wrapper script fallback to Python-based Mercurial.
387 387 Err(CommandError::UnsupportedFeature { .. }) => {
388 388 exit_codes::UNIMPLEMENTED
389 389 }
390 390 Err(CommandError::InvalidFallback { .. }) => {
391 391 exit_codes::INVALID_FALLBACK
392 392 }
393 393 }
394 394 }
395 395
396 396 fn exit<'a>(
397 397 original_args: &'a [OsString],
398 398 initial_current_dir: &Option<PathBuf>,
399 399 ui: &Ui,
400 400 mut on_unsupported: OnUnsupported,
401 401 result: Result<(), CommandError>,
402 402 use_detailed_exit_code: bool,
403 403 ) -> ! {
404 404 if let (
405 405 OnUnsupported::Fallback { executable },
406 406 Err(CommandError::UnsupportedFeature { message }),
407 407 ) = (&on_unsupported, &result)
408 408 {
409 409 let mut args = original_args.iter();
410 410 let executable = match executable {
411 411 None => {
412 412 exit_no_fallback(
413 413 ui,
414 414 OnUnsupported::Abort,
415 415 Err(CommandError::abort(
416 416 "abort: 'rhg.on-unsupported=fallback' without \
417 417 'rhg.fallback-executable' set.",
418 418 )),
419 419 false,
420 420 );
421 421 }
422 422 Some(executable) => executable,
423 423 };
424 424 let executable_path = get_path_from_bytes(&executable);
425 425 let this_executable = args.next().expect("exepcted argv[0] to exist");
426 426 if executable_path == &PathBuf::from(this_executable) {
427 427 // Avoid spawning infinitely many processes until resource
428 428 // exhaustion.
429 429 let _ = ui.write_stderr(&format_bytes!(
430 430 b"Blocking recursive fallback. The 'rhg.fallback-executable = {}' config \
431 431 points to `rhg` itself.\n",
432 432 executable
433 433 ));
434 434 on_unsupported = OnUnsupported::Abort
435 435 } else {
436 436 log::debug!("falling back (see trace-level log)");
437 437 log::trace!("{}", local_to_utf8(message));
438 438 if let Err(err) = which::which(executable_path) {
439 439 exit_no_fallback(
440 440 ui,
441 441 OnUnsupported::Abort,
442 442 Err(CommandError::InvalidFallback {
443 443 path: executable.to_owned(),
444 444 err: err.to_string(),
445 445 }),
446 446 use_detailed_exit_code,
447 447 )
448 448 }
449 449 // `args` is now `argv[1..]` since we’ve already consumed
450 450 // `argv[0]`
451 451 let mut command = Command::new(executable_path);
452 452 command.args(args);
453 453 if let Some(initial) = initial_current_dir {
454 454 command.current_dir(initial);
455 455 }
456 456 // We don't use subprocess because proper signal handling is harder
457 457 // and we don't want to keep `rhg` around after a fallback anyway.
458 458 // For example, if `rhg` is run in the background and falls back to
459 459 // `hg` which, in turn, waits for a signal, we'll get stuck if
460 460 // we're doing plain subprocess.
461 461 //
462 462 // If `exec` returns, we can only assume our process is very broken
463 463 // (see its documentation), so only try to forward the error code
464 464 // when exiting.
465 465 let err = command.exec();
466 466 std::process::exit(
467 467 err.raw_os_error().unwrap_or(exit_codes::ABORT),
468 468 );
469 469 }
470 470 }
471 471 exit_no_fallback(ui, on_unsupported, result, use_detailed_exit_code)
472 472 }
473 473
474 474 fn exit_no_fallback(
475 475 ui: &Ui,
476 476 on_unsupported: OnUnsupported,
477 477 result: Result<(), CommandError>,
478 478 use_detailed_exit_code: bool,
479 479 ) -> ! {
480 480 match &result {
481 481 Ok(_) => {}
482 482 Err(CommandError::Unsuccessful) => {}
483 483 Err(CommandError::Abort {
484 484 message,
485 485 detailed_exit_code: _,
486 486 }) => {
487 487 if !message.is_empty() {
488 488 // Ignore errors when writing to stderr, we’re already exiting
489 489 // with failure code so there’s not much more we can do.
490 490 let _ = ui.write_stderr(&format_bytes!(b"{}\n", message));
491 491 }
492 492 }
493 493 Err(CommandError::UnsupportedFeature { message }) => {
494 494 match on_unsupported {
495 495 OnUnsupported::Abort => {
496 496 let _ = ui.write_stderr(&format_bytes!(
497 497 b"unsupported feature: {}\n",
498 498 message
499 499 ));
500 500 }
501 501 OnUnsupported::AbortSilent => {}
502 502 OnUnsupported::Fallback { .. } => unreachable!(),
503 503 }
504 504 }
505 505 Err(CommandError::InvalidFallback { path, err }) => {
506 506 let _ = ui.write_stderr(&format_bytes!(
507 507 b"abort: invalid fallback '{}': {}\n",
508 508 path,
509 509 err.as_bytes(),
510 510 ));
511 511 }
512 512 }
513 513 std::process::exit(exit_code(&result, use_detailed_exit_code))
514 514 }
515 515
516 516 macro_rules! subcommands {
517 517 ($( $command: ident )+) => {
518 518 mod commands {
519 519 $(
520 520 pub mod $command;
521 521 )+
522 522 }
523 523
524 524 fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
525 525 app
526 526 $(
527 527 .subcommand(commands::$command::args())
528 528 )+
529 529 }
530 530
531 531 pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
532 532
533 533 fn subcommand_run_fn(name: &str) -> Option<RunFn> {
534 534 match name {
535 535 $(
536 536 stringify!($command) => Some(commands::$command::run),
537 537 )+
538 538 _ => None,
539 539 }
540 540 }
541 541 };
542 542 }
543 543
544 544 subcommands! {
545 545 cat
546 546 debugdata
547 547 debugrequirements
548 548 debugignorerhg
549 549 files
550 550 root
551 551 config
552 552 status
553 553 }
554 554
555 555 pub struct CliInvocation<'a> {
556 556 ui: &'a Ui,
557 557 subcommand_args: &'a ArgMatches<'a>,
558 558 config: &'a Config,
559 559 /// References inside `Result` is a bit peculiar but allow
560 560 /// `invocation.repo?` to work out with `&CliInvocation` since this
561 561 /// `Result` type is `Copy`.
562 562 repo: Result<&'a Repo, &'a NoRepoInCwdError>,
563 563 }
564 564
565 565 struct NoRepoInCwdError {
566 566 cwd: PathBuf,
567 567 }
568 568
569 569 /// CLI arguments to be parsed "early" in order to be able to read
570 570 /// configuration before using Clap. Ideally we would also use Clap for this,
571 571 /// see <https://github.com/clap-rs/clap/discussions/2366>.
572 572 ///
573 573 /// These arguments are still declared when we do use Clap later, so that Clap
574 574 /// does not return an error for their presence.
575 575 struct EarlyArgs {
576 576 /// Values of all `--config` arguments. (Possibly none)
577 577 config: Vec<Vec<u8>>,
578 578 /// Value of all the `--color` argument, if any.
579 579 color: Option<Vec<u8>>,
580 580 /// Value of the `-R` or `--repository` argument, if any.
581 581 repo: Option<Vec<u8>>,
582 582 /// Value of the `--cwd` argument, if any.
583 583 cwd: Option<Vec<u8>>,
584 584 }
585 585
586 586 impl EarlyArgs {
587 587 fn parse<'a>(args: impl IntoIterator<Item = &'a OsString>) -> Self {
588 588 let mut args = args.into_iter().map(get_bytes_from_os_str);
589 589 let mut config = Vec::new();
590 590 let mut color = None;
591 591 let mut repo = None;
592 592 let mut cwd = None;
593 593 // Use `while let` instead of `for` so that we can also call
594 594 // `args.next()` inside the loop.
595 595 while let Some(arg) = args.next() {
596 596 if arg == b"--config" {
597 597 if let Some(value) = args.next() {
598 598 config.push(value)
599 599 }
600 600 } else if let Some(value) = arg.drop_prefix(b"--config=") {
601 601 config.push(value.to_owned())
602 602 }
603 603
604 604 if arg == b"--color" {
605 605 if let Some(value) = args.next() {
606 606 color = Some(value)
607 607 }
608 608 } else if let Some(value) = arg.drop_prefix(b"--color=") {
609 609 color = Some(value.to_owned())
610 610 }
611 611
612 612 if arg == b"--cwd" {
613 613 if let Some(value) = args.next() {
614 614 cwd = Some(value)
615 615 }
616 616 } else if let Some(value) = arg.drop_prefix(b"--cwd=") {
617 617 cwd = Some(value.to_owned())
618 618 }
619 619
620 620 if arg == b"--repository" || arg == b"-R" {
621 621 if let Some(value) = args.next() {
622 622 repo = Some(value)
623 623 }
624 624 } else if let Some(value) = arg.drop_prefix(b"--repository=") {
625 625 repo = Some(value.to_owned())
626 626 } else if let Some(value) = arg.drop_prefix(b"-R") {
627 627 repo = Some(value.to_owned())
628 628 }
629 629 }
630 630 Self {
631 631 config,
632 632 color,
633 633 repo,
634 634 cwd,
635 635 }
636 636 }
637 637 }
638 638
639 639 /// What to do when encountering some unsupported feature.
640 640 ///
641 641 /// See `HgError::UnsupportedFeature` and `CommandError::UnsupportedFeature`.
642 642 enum OnUnsupported {
643 643 /// Print an error message describing what feature is not supported,
644 644 /// and exit with code 252.
645 645 Abort,
646 646 /// Silently exit with code 252.
647 647 AbortSilent,
648 648 /// Try running a Python implementation
649 649 Fallback { executable: Option<Vec<u8>> },
650 650 }
651 651
652 652 impl OnUnsupported {
653 653 const DEFAULT: Self = OnUnsupported::Abort;
654 654
655 655 fn from_config(config: &Config) -> Self {
656 656 match config
657 657 .get(b"rhg", b"on-unsupported")
658 658 .map(|value| value.to_ascii_lowercase())
659 659 .as_deref()
660 660 {
661 661 Some(b"abort") => OnUnsupported::Abort,
662 662 Some(b"abort-silent") => OnUnsupported::AbortSilent,
663 663 Some(b"fallback") => OnUnsupported::Fallback {
664 664 executable: config
665 665 .get(b"rhg", b"fallback-executable")
666 666 .map(|x| x.to_owned()),
667 667 },
668 668 None => Self::DEFAULT,
669 669 Some(_) => {
670 670 // TODO: warn about unknown config value
671 671 Self::DEFAULT
672 672 }
673 673 }
674 674 }
675 675 }
676 676
677 677 /// The `*` extension is an edge-case for config sub-options that apply to all
678 678 /// extensions. For now, only `:required` exists, but that may change in the
679 679 /// future.
680 680 const SUPPORTED_EXTENSIONS: &[&[u8]] =
681 681 &[b"blackbox", b"share", b"sparse", b"narrow", b"*"];
682 682
683 683 fn check_extensions(config: &Config) -> Result<(), CommandError> {
684 684 if let Some(b"*") = config.get(b"rhg", b"ignored-extensions") {
685 685 // All extensions are to be ignored, nothing to do here
686 686 return Ok(());
687 687 }
688 688
689 689 let enabled: HashSet<&[u8]> = config
690 .get_section_keys(b"extensions")
691 .into_iter()
692 .map(|extension| {
690 .iter_section(b"extensions")
691 .filter_map(|(extension, value)| {
692 if value == b"!" {
693 // Filter out disabled extensions
694 return None;
695 }
693 696 // Ignore extension suboptions. Only `required` exists for now.
694 697 // `rhg` either supports an extension or doesn't, so it doesn't
695 698 // make sense to consider the loading of an extension.
696 extension.split_2(b':').unwrap_or((extension, b"")).0
699 let actual_extension =
700 extension.split_2(b':').unwrap_or((extension, b"")).0;
701 Some(actual_extension)
697 702 })
698 703 .collect();
699 704
700 705 let mut unsupported = enabled;
701 706 for supported in SUPPORTED_EXTENSIONS {
702 707 unsupported.remove(supported);
703 708 }
704 709
705 710 if let Some(ignored_list) = config.get_list(b"rhg", b"ignored-extensions")
706 711 {
707 712 for ignored in ignored_list {
708 713 unsupported.remove(ignored.as_slice());
709 714 }
710 715 }
711 716
712 717 if unsupported.is_empty() {
713 718 Ok(())
714 719 } else {
715 720 let mut unsupported: Vec<_> = unsupported.into_iter().collect();
716 721 // Sort the extensions to get a stable output
717 722 unsupported.sort();
718 723 Err(CommandError::UnsupportedFeature {
719 724 message: format_bytes!(
720 725 b"extensions: {} (consider adding them to 'rhg.ignored-extensions' config)",
721 726 join(unsupported, b", ")
722 727 ),
723 728 })
724 729 }
725 730 }
726 731
727 732 /// Array of tuples of (auto upgrade conf, feature conf, local requirement)
728 733 const AUTO_UPGRADES: &[((&str, &str), (&str, &str), &str)] = &[
729 734 (
730 735 ("format", "use-share-safe.automatic-upgrade-of-mismatching-repositories"),
731 736 ("format", "use-share-safe"),
732 737 requirements::SHARESAFE_REQUIREMENT,
733 738 ),
734 739 (
735 740 ("format", "use-dirstate-tracked-hint.automatic-upgrade-of-mismatching-repositories"),
736 741 ("format", "use-dirstate-tracked-hint"),
737 742 requirements::DIRSTATE_TRACKED_HINT_V1,
738 743 ),
739 744 (
740 745 ("use-dirstate-v2", "automatic-upgrade-of-mismatching-repositories"),
741 746 ("format", "use-dirstate-v2"),
742 747 requirements::DIRSTATE_V2_REQUIREMENT,
743 748 ),
744 749 ];
745 750
746 751 /// Mercurial allows users to automatically upgrade their repository.
747 752 /// `rhg` does not have the ability to upgrade yet, so fallback if an upgrade
748 753 /// is needed.
749 754 fn check_auto_upgrade(
750 755 config: &Config,
751 756 reqs: &HashSet<String>,
752 757 ) -> Result<(), CommandError> {
753 758 for (upgrade_conf, feature_conf, local_req) in AUTO_UPGRADES.iter() {
754 759 let auto_upgrade = config
755 760 .get_bool(upgrade_conf.0.as_bytes(), upgrade_conf.1.as_bytes())?;
756 761
757 762 if auto_upgrade {
758 763 let want_it = config.get_bool(
759 764 feature_conf.0.as_bytes(),
760 765 feature_conf.1.as_bytes(),
761 766 )?;
762 767 let have_it = reqs.contains(*local_req);
763 768
764 769 let action = match (want_it, have_it) {
765 770 (true, false) => Some("upgrade"),
766 771 (false, true) => Some("downgrade"),
767 772 _ => None,
768 773 };
769 774 if let Some(action) = action {
770 775 let message = format!(
771 776 "automatic {} {}.{}",
772 777 action, upgrade_conf.0, upgrade_conf.1
773 778 );
774 779 return Err(CommandError::unsupported(message));
775 780 }
776 781 }
777 782 }
778 783 Ok(())
779 784 }
780 785
781 786 fn check_unsupported(
782 787 config: &Config,
783 788 repo: Result<&Repo, &NoRepoInCwdError>,
784 789 ) -> Result<(), CommandError> {
785 790 check_extensions(config)?;
786 791
787 792 if std::env::var_os("HG_PENDING").is_some() {
788 793 // TODO: only if the value is `== repo.working_directory`?
789 794 // What about relative v.s. absolute paths?
790 795 Err(CommandError::unsupported("$HG_PENDING"))?
791 796 }
792 797
793 798 if let Ok(repo) = repo {
794 799 if repo.has_subrepos()? {
795 800 Err(CommandError::unsupported("sub-repositories"))?
796 801 }
797 802 check_auto_upgrade(config, repo.requirements())?;
798 803 }
799 804
800 805 if config.has_non_empty_section(b"encode") {
801 806 Err(CommandError::unsupported("[encode] config"))?
802 807 }
803 808
804 809 if config.has_non_empty_section(b"decode") {
805 810 Err(CommandError::unsupported("[decode] config"))?
806 811 }
807 812
808 813 Ok(())
809 814 }
@@ -1,2970 +1,2974 b''
1 1 Log on empty repository: checking consistency
2 2
3 3 $ hg init empty
4 4 $ cd empty
5 5 $ hg log
6 6 $ hg log -r 1
7 7 abort: unknown revision '1'
8 8 [10]
9 9 $ hg log -r -1:0
10 10 abort: unknown revision '-1'
11 11 [10]
12 12 $ hg log -r 'branch(name)'
13 13 abort: unknown revision 'name'
14 14 [10]
15 15 $ hg log -r null -q
16 16 -1:000000000000
17 17
18 18 $ cd ..
19 19
20 20 The g is crafted to have 2 filelog topological heads in a linear
21 21 changeset graph
22 22
23 23 $ hg init a
24 24 $ cd a
25 25 $ echo a > a
26 26 $ echo f > f
27 27 $ hg ci -Ama -d '1 0'
28 28 adding a
29 29 adding f
30 30
31 31 $ hg cp a b
32 32 $ hg cp f g
33 33 $ hg ci -mb -d '2 0'
34 34
35 35 $ mkdir dir
36 36 $ hg mv b dir
37 37 $ echo g >> g
38 38 $ echo f >> f
39 39 $ hg ci -mc -d '3 0'
40 40
41 41 $ hg mv a b
42 42 $ hg cp -f f g
43 43 $ echo a > d
44 44 $ hg add d
45 45 $ hg ci -md -d '4 0'
46 46
47 47 $ hg mv dir/b e
48 48 $ hg ci -me -d '5 0'
49 49
50 50 Make sure largefiles doesn't interfere with logging a regular file
51 51 $ hg --debug log a -T '{rev}: {desc}\n' --config extensions.largefiles=
52 52 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
53 53 updated patterns: .hglf/a, a
54 54 0: a
55 55 $ hg log a
56 56 changeset: 0:9161b9aeaf16
57 57 user: test
58 58 date: Thu Jan 01 00:00:01 1970 +0000
59 59 summary: a
60 60
61 61 $ hg log glob:a*
62 62 changeset: 3:2ca5ba701980
63 63 user: test
64 64 date: Thu Jan 01 00:00:04 1970 +0000
65 65 summary: d
66 66
67 67 changeset: 0:9161b9aeaf16
68 68 user: test
69 69 date: Thu Jan 01 00:00:01 1970 +0000
70 70 summary: a
71 71
72 72 $ hg --debug log glob:a* -T '{rev}: {desc}\n' --config extensions.largefiles=
73 73 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
74 74 updated patterns: glob:.hglf/a*, glob:a*
75 75 3: d
76 76 0: a
77 77
78 78 log on directory
79 79
80 80 $ hg log dir
81 81 changeset: 4:7e4639b4691b
82 82 tag: tip
83 83 user: test
84 84 date: Thu Jan 01 00:00:05 1970 +0000
85 85 summary: e
86 86
87 87 changeset: 2:f8954cd4dc1f
88 88 user: test
89 89 date: Thu Jan 01 00:00:03 1970 +0000
90 90 summary: c
91 91
92 92 $ hg log somethingthatdoesntexist dir
93 93 changeset: 4:7e4639b4691b
94 94 tag: tip
95 95 user: test
96 96 date: Thu Jan 01 00:00:05 1970 +0000
97 97 summary: e
98 98
99 99 changeset: 2:f8954cd4dc1f
100 100 user: test
101 101 date: Thu Jan 01 00:00:03 1970 +0000
102 102 summary: c
103 103
104 104
105 105 log empty path (or repo root) of slow path shouldn't crash (issue6478)
106 106
107 107 $ hg log -ql1 '' inexistent
108 108 4:7e4639b4691b
109 109 $ hg log -ql1 . inexistent
110 110 4:7e4639b4691b
111 111 $ hg log -ql1 "`pwd`" inexistent
112 112 4:7e4639b4691b
113 113
114 114 $ hg log -ql1 '' e
115 115 4:7e4639b4691b
116 116 $ hg log -ql1 . e
117 117 4:7e4639b4691b
118 118 $ hg log -ql1 "`pwd`" e
119 119 4:7e4639b4691b
120 120
121 121 log -f empty path (or repo root) shouldn't crash
122 122
123 123 $ hg log -qfl1 '' inexistent
124 124 abort: cannot follow file not in parent revision: "inexistent"
125 125 [20]
126 126 $ hg log -qfl1 . inexistent
127 127 abort: cannot follow file not in parent revision: "inexistent"
128 128 [20]
129 129 $ hg log -qfl1 "`pwd`" inexistent
130 130 abort: cannot follow file not in parent revision: "inexistent"
131 131 [20]
132 132
133 133 $ hg log -qfl1 '' e
134 134 4:7e4639b4691b
135 135 $ hg log -qfl1 . e
136 136 4:7e4639b4691b
137 137 $ hg log -qfl1 "`pwd`" e
138 138 4:7e4639b4691b
139 139
140 140 -X, with explicit path
141 141
142 142 $ hg log a -X a
143 143
144 144 -f, non-existent directory
145 145
146 146 $ hg log -f dir
147 147 abort: cannot follow file not in parent revision: "dir"
148 148 [20]
149 149
150 150 -f, directory
151 151
152 152 $ hg up -q 3
153 153 $ hg log -f dir
154 154 changeset: 2:f8954cd4dc1f
155 155 user: test
156 156 date: Thu Jan 01 00:00:03 1970 +0000
157 157 summary: c
158 158
159 159 -f, directory with --patch
160 160
161 161 $ hg log -f dir -p
162 162 changeset: 2:f8954cd4dc1f
163 163 user: test
164 164 date: Thu Jan 01 00:00:03 1970 +0000
165 165 summary: c
166 166
167 167 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
168 168 --- /dev/null* (glob)
169 169 +++ b/dir/b* (glob)
170 170 @@ -0,0 +1,1 @@
171 171 +a
172 172
173 173
174 174 -f, pattern
175 175
176 176 $ hg log -f -I 'dir**' -p
177 177 changeset: 2:f8954cd4dc1f
178 178 user: test
179 179 date: Thu Jan 01 00:00:03 1970 +0000
180 180 summary: c
181 181
182 182 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
183 183 --- /dev/null* (glob)
184 184 +++ b/dir/b* (glob)
185 185 @@ -0,0 +1,1 @@
186 186 +a
187 187
188 188 $ hg up -q 4
189 189
190 190 -f, a wrong style
191 191
192 192 $ hg log -f -l1 --style something
193 193 abort: style 'something' not found
194 194 (available styles: bisect, changelog, compact, default, phases, show, status, xml)
195 195 [255]
196 196
197 197 -f, phases style
198 198
199 199
200 200 $ hg log -f -l1 --style phases
201 201 changeset: 4:7e4639b4691b
202 202 tag: tip
203 203 phase: draft
204 204 user: test
205 205 date: Thu Jan 01 00:00:05 1970 +0000
206 206 summary: e
207 207
208 208
209 209 $ hg log -f -l1 --style phases -q
210 210 4:7e4639b4691b
211 211
212 212 -f, but no args
213 213
214 214 $ hg log -f
215 215 changeset: 4:7e4639b4691b
216 216 tag: tip
217 217 user: test
218 218 date: Thu Jan 01 00:00:05 1970 +0000
219 219 summary: e
220 220
221 221 changeset: 3:2ca5ba701980
222 222 user: test
223 223 date: Thu Jan 01 00:00:04 1970 +0000
224 224 summary: d
225 225
226 226 changeset: 2:f8954cd4dc1f
227 227 user: test
228 228 date: Thu Jan 01 00:00:03 1970 +0000
229 229 summary: c
230 230
231 231 changeset: 1:d89b0a12d229
232 232 user: test
233 233 date: Thu Jan 01 00:00:02 1970 +0000
234 234 summary: b
235 235
236 236 changeset: 0:9161b9aeaf16
237 237 user: test
238 238 date: Thu Jan 01 00:00:01 1970 +0000
239 239 summary: a
240 240
241 241
242 242 one rename
243 243
244 244 $ hg up -q 2
245 245 $ hg log -vf a
246 246 changeset: 0:9161b9aeaf16
247 247 user: test
248 248 date: Thu Jan 01 00:00:01 1970 +0000
249 249 files: a f
250 250 description:
251 251 a
252 252
253 253
254 254
255 255 many renames
256 256
257 257 $ hg up -q tip
258 258 $ hg log -vf e
259 259 changeset: 4:7e4639b4691b
260 260 tag: tip
261 261 user: test
262 262 date: Thu Jan 01 00:00:05 1970 +0000
263 263 files: dir/b e
264 264 description:
265 265 e
266 266
267 267
268 268 changeset: 2:f8954cd4dc1f
269 269 user: test
270 270 date: Thu Jan 01 00:00:03 1970 +0000
271 271 files: b dir/b f g
272 272 description:
273 273 c
274 274
275 275
276 276 changeset: 1:d89b0a12d229
277 277 user: test
278 278 date: Thu Jan 01 00:00:02 1970 +0000
279 279 files: b g
280 280 description:
281 281 b
282 282
283 283
284 284 changeset: 0:9161b9aeaf16
285 285 user: test
286 286 date: Thu Jan 01 00:00:01 1970 +0000
287 287 files: a f
288 288 description:
289 289 a
290 290
291 291
292 292
293 293
294 294 log -pf dir/b
295 295
296 296 $ hg up -q 3
297 297 $ hg log -pf dir/b
298 298 changeset: 2:f8954cd4dc1f
299 299 user: test
300 300 date: Thu Jan 01 00:00:03 1970 +0000
301 301 summary: c
302 302
303 303 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
304 304 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
305 305 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
306 306 @@ -0,0 +1,1 @@
307 307 +a
308 308
309 309 changeset: 1:d89b0a12d229
310 310 user: test
311 311 date: Thu Jan 01 00:00:02 1970 +0000
312 312 summary: b
313 313
314 314 diff -r 9161b9aeaf16 -r d89b0a12d229 b
315 315 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
316 316 +++ b/b Thu Jan 01 00:00:02 1970 +0000
317 317 @@ -0,0 +1,1 @@
318 318 +a
319 319
320 320 changeset: 0:9161b9aeaf16
321 321 user: test
322 322 date: Thu Jan 01 00:00:01 1970 +0000
323 323 summary: a
324 324
325 325 diff -r 000000000000 -r 9161b9aeaf16 a
326 326 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
327 327 +++ b/a Thu Jan 01 00:00:01 1970 +0000
328 328 @@ -0,0 +1,1 @@
329 329 +a
330 330
331 331
332 332 log -pf b inside dir
333 333
334 334 $ hg --cwd=dir log -pf b
335 335 changeset: 2:f8954cd4dc1f
336 336 user: test
337 337 date: Thu Jan 01 00:00:03 1970 +0000
338 338 summary: c
339 339
340 340 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
341 341 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
342 342 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
343 343 @@ -0,0 +1,1 @@
344 344 +a
345 345
346 346 changeset: 1:d89b0a12d229
347 347 user: test
348 348 date: Thu Jan 01 00:00:02 1970 +0000
349 349 summary: b
350 350
351 351 diff -r 9161b9aeaf16 -r d89b0a12d229 b
352 352 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
353 353 +++ b/b Thu Jan 01 00:00:02 1970 +0000
354 354 @@ -0,0 +1,1 @@
355 355 +a
356 356
357 357 changeset: 0:9161b9aeaf16
358 358 user: test
359 359 date: Thu Jan 01 00:00:01 1970 +0000
360 360 summary: a
361 361
362 362 diff -r 000000000000 -r 9161b9aeaf16 a
363 363 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
364 364 +++ b/a Thu Jan 01 00:00:01 1970 +0000
365 365 @@ -0,0 +1,1 @@
366 366 +a
367 367
368 368
369 369 log -pf, but no args
370 370
371 371 $ hg log -pf
372 372 changeset: 3:2ca5ba701980
373 373 user: test
374 374 date: Thu Jan 01 00:00:04 1970 +0000
375 375 summary: d
376 376
377 377 diff -r f8954cd4dc1f -r 2ca5ba701980 a
378 378 --- a/a Thu Jan 01 00:00:03 1970 +0000
379 379 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
380 380 @@ -1,1 +0,0 @@
381 381 -a
382 382 diff -r f8954cd4dc1f -r 2ca5ba701980 b
383 383 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
384 384 +++ b/b Thu Jan 01 00:00:04 1970 +0000
385 385 @@ -0,0 +1,1 @@
386 386 +a
387 387 diff -r f8954cd4dc1f -r 2ca5ba701980 d
388 388 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
389 389 +++ b/d Thu Jan 01 00:00:04 1970 +0000
390 390 @@ -0,0 +1,1 @@
391 391 +a
392 392 diff -r f8954cd4dc1f -r 2ca5ba701980 g
393 393 --- a/g Thu Jan 01 00:00:03 1970 +0000
394 394 +++ b/g Thu Jan 01 00:00:04 1970 +0000
395 395 @@ -1,2 +1,2 @@
396 396 f
397 397 -g
398 398 +f
399 399
400 400 changeset: 2:f8954cd4dc1f
401 401 user: test
402 402 date: Thu Jan 01 00:00:03 1970 +0000
403 403 summary: c
404 404
405 405 diff -r d89b0a12d229 -r f8954cd4dc1f b
406 406 --- a/b Thu Jan 01 00:00:02 1970 +0000
407 407 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
408 408 @@ -1,1 +0,0 @@
409 409 -a
410 410 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
411 411 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
412 412 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
413 413 @@ -0,0 +1,1 @@
414 414 +a
415 415 diff -r d89b0a12d229 -r f8954cd4dc1f f
416 416 --- a/f Thu Jan 01 00:00:02 1970 +0000
417 417 +++ b/f Thu Jan 01 00:00:03 1970 +0000
418 418 @@ -1,1 +1,2 @@
419 419 f
420 420 +f
421 421 diff -r d89b0a12d229 -r f8954cd4dc1f g
422 422 --- a/g Thu Jan 01 00:00:02 1970 +0000
423 423 +++ b/g Thu Jan 01 00:00:03 1970 +0000
424 424 @@ -1,1 +1,2 @@
425 425 f
426 426 +g
427 427
428 428 changeset: 1:d89b0a12d229
429 429 user: test
430 430 date: Thu Jan 01 00:00:02 1970 +0000
431 431 summary: b
432 432
433 433 diff -r 9161b9aeaf16 -r d89b0a12d229 b
434 434 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
435 435 +++ b/b Thu Jan 01 00:00:02 1970 +0000
436 436 @@ -0,0 +1,1 @@
437 437 +a
438 438 diff -r 9161b9aeaf16 -r d89b0a12d229 g
439 439 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
440 440 +++ b/g Thu Jan 01 00:00:02 1970 +0000
441 441 @@ -0,0 +1,1 @@
442 442 +f
443 443
444 444 changeset: 0:9161b9aeaf16
445 445 user: test
446 446 date: Thu Jan 01 00:00:01 1970 +0000
447 447 summary: a
448 448
449 449 diff -r 000000000000 -r 9161b9aeaf16 a
450 450 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
451 451 +++ b/a Thu Jan 01 00:00:01 1970 +0000
452 452 @@ -0,0 +1,1 @@
453 453 +a
454 454 diff -r 000000000000 -r 9161b9aeaf16 f
455 455 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
456 456 +++ b/f Thu Jan 01 00:00:01 1970 +0000
457 457 @@ -0,0 +1,1 @@
458 458 +f
459 459
460 460
461 461 log -vf dir/b
462 462
463 463 $ hg log -vf dir/b
464 464 changeset: 2:f8954cd4dc1f
465 465 user: test
466 466 date: Thu Jan 01 00:00:03 1970 +0000
467 467 files: b dir/b f g
468 468 description:
469 469 c
470 470
471 471
472 472 changeset: 1:d89b0a12d229
473 473 user: test
474 474 date: Thu Jan 01 00:00:02 1970 +0000
475 475 files: b g
476 476 description:
477 477 b
478 478
479 479
480 480 changeset: 0:9161b9aeaf16
481 481 user: test
482 482 date: Thu Jan 01 00:00:01 1970 +0000
483 483 files: a f
484 484 description:
485 485 a
486 486
487 487
488 488 Respects ui.logtemplate and command-templates.log configs (the latter takes
489 489 precedence)
490 490
491 491 $ hg log -r 0 --config ui.logtemplate="foo {rev}\n"
492 492 foo 0
493 493 $ hg log -r 0 --config command-templates.log="bar {rev}\n"
494 494 bar 0
495 495 $ hg log -r 0 --config ui.logtemplate="foo {rev}\n" \
496 496 > --config command-templates.log="bar {rev}\n"
497 497 bar 0
498 498
499 499
500 500 -f and multiple filelog heads
501 501
502 502 $ hg up -q 2
503 503 $ hg log -f g --template '{rev}\n'
504 504 2
505 505 1
506 506 0
507 507 $ hg up -q tip
508 508 $ hg log -f g --template '{rev}\n'
509 509 3
510 510 2
511 511 0
512 512
513 513 follow files from the specified revisions (issue4959)
514 514
515 515 $ hg log -G -T '{rev} {files},{file_copies % " {source}->{name}"}\n'
516 516 @ 4 dir/b e, dir/b->e
517 517 |
518 518 o 3 a b d g, a->b f->g
519 519 |
520 520 o 2 b dir/b f g, b->dir/b
521 521 |
522 522 o 1 b g, a->b f->g
523 523 |
524 524 o 0 a f,
525 525
526 526
527 527 $ hg log -T '{rev}\n' -fr 4 e
528 528 4
529 529 2
530 530 1
531 531 0
532 532 $ hg log -T '{rev}\n' -fr 2 g
533 533 2
534 534 1
535 535 0
536 536 $ hg log -T '{rev}\n' -fr '2+3' g
537 537 3
538 538 2
539 539 1
540 540 0
541 541
542 542 follow files from the specified revisions with glob patterns (issue5053)
543 543 (BROKEN: should follow copies from e@4)
544 544
545 545 $ hg log -T '{rev}\n' -fr4 e -X '[abcdfg]'
546 546 4
547 547 2 (false !)
548 548 1 (false !)
549 549 0 (false !)
550 550
551 551 follow files from the specified revisions with missing patterns
552 552
553 553 $ hg log -T '{rev}\n' -fr4 e x
554 554 abort: cannot follow file not in any of the specified revisions: "x"
555 555 [20]
556 556
557 557 follow files from the specified revisions with directory patterns
558 558 (BROKEN: should follow copies from dir/b@2)
559 559
560 560 $ hg log -T '{rev}\n' -fr2 dir/b dir
561 561 2
562 562 1 (false !)
563 563 0 (false !)
564 564
565 565 follow files from multiple revisions, but the pattern is missing in
566 566 one of the specified revisions
567 567
568 568 $ hg log -T '{rev}\n' -fr'2+4' dir/b e
569 569 e: no such file in rev f8954cd4dc1f
570 570 dir/b: no such file in rev 7e4639b4691b
571 571 4
572 572 2
573 573 1
574 574 0
575 575
576 576 follow files from multiple revisions, and the pattern matches a file in
577 577 one revision but matches a directory in another:
578 578 (BROKEN: should follow copies from dir/b@2 and dir/b/g@5)
579 579 (BROKEN: the revision 4 should not be included since dir/b/g@5 is unchanged)
580 580
581 581 $ mkdir -p dir/b
582 582 $ hg mv g dir/b
583 583 $ hg ci -m 'make dir/b a directory'
584 584
585 585 $ hg log -T '{rev}\n' -fr'2+5' dir/b
586 586 5
587 587 4
588 588 3 (false !)
589 589 2
590 590 1 (false !)
591 591 0 (false !)
592 592
593 593 $ hg --config extensions.strip= strip -r. --no-backup
594 594 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
595 595
596 596 follow files from the specified revisions across copies with -p/--patch
597 597
598 598 $ hg log -T '== rev: {rev},{file_copies % " {source}->{name}"} ==\n' -fpr 4 e g
599 599 == rev: 4, dir/b->e ==
600 600 diff -r 2ca5ba701980 -r 7e4639b4691b e
601 601 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
602 602 +++ b/e Thu Jan 01 00:00:05 1970 +0000
603 603 @@ -0,0 +1,1 @@
604 604 +a
605 605
606 606 == rev: 3, a->b f->g ==
607 607 diff -r f8954cd4dc1f -r 2ca5ba701980 g
608 608 --- a/g Thu Jan 01 00:00:03 1970 +0000
609 609 +++ b/g Thu Jan 01 00:00:04 1970 +0000
610 610 @@ -1,2 +1,2 @@
611 611 f
612 612 -g
613 613 +f
614 614
615 615 == rev: 2, b->dir/b ==
616 616 diff -r d89b0a12d229 -r f8954cd4dc1f dir/b
617 617 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
618 618 +++ b/dir/b Thu Jan 01 00:00:03 1970 +0000
619 619 @@ -0,0 +1,1 @@
620 620 +a
621 621 diff -r d89b0a12d229 -r f8954cd4dc1f f
622 622 --- a/f Thu Jan 01 00:00:02 1970 +0000
623 623 +++ b/f Thu Jan 01 00:00:03 1970 +0000
624 624 @@ -1,1 +1,2 @@
625 625 f
626 626 +f
627 627
628 628 == rev: 1, a->b f->g ==
629 629 diff -r 9161b9aeaf16 -r d89b0a12d229 b
630 630 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
631 631 +++ b/b Thu Jan 01 00:00:02 1970 +0000
632 632 @@ -0,0 +1,1 @@
633 633 +a
634 634
635 635 == rev: 0, ==
636 636 diff -r 000000000000 -r 9161b9aeaf16 a
637 637 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
638 638 +++ b/a Thu Jan 01 00:00:01 1970 +0000
639 639 @@ -0,0 +1,1 @@
640 640 +a
641 641 diff -r 000000000000 -r 9161b9aeaf16 f
642 642 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
643 643 +++ b/f Thu Jan 01 00:00:01 1970 +0000
644 644 @@ -0,0 +1,1 @@
645 645 +f
646 646
647 647
648 648 log copies with --copies
649 649
650 650 $ hg log -vC --template '{rev} {file_copies}\n'
651 651 4 e (dir/b)
652 652 3 b (a)g (f)
653 653 2 dir/b (b)
654 654 1 b (a)g (f)
655 655 0
656 656
657 657 log copies switch without --copies, with old filecopy template
658 658
659 659 $ hg log -v --template '{rev} {file_copies_switch%filecopy}\n'
660 660 4
661 661 3
662 662 2
663 663 1
664 664 0
665 665
666 666 log copies switch with --copies
667 667
668 668 $ hg log -vC --template '{rev} {file_copies_switch}\n'
669 669 4 e (dir/b)
670 670 3 b (a)g (f)
671 671 2 dir/b (b)
672 672 1 b (a)g (f)
673 673 0
674 674
675 675
676 676 log copies with hardcoded style and with --style=default
677 677
678 678 $ hg log -vC -r4
679 679 changeset: 4:7e4639b4691b
680 680 tag: tip
681 681 user: test
682 682 date: Thu Jan 01 00:00:05 1970 +0000
683 683 files: dir/b e
684 684 copies: e (dir/b)
685 685 description:
686 686 e
687 687
688 688
689 689 $ hg log -vC -r4 --style=default
690 690 changeset: 4:7e4639b4691b
691 691 tag: tip
692 692 user: test
693 693 date: Thu Jan 01 00:00:05 1970 +0000
694 694 files: dir/b e
695 695 copies: e (dir/b)
696 696 description:
697 697 e
698 698
699 699
700 700 $ hg log -vC -r4 -Tjson
701 701 [
702 702 {
703 703 "bookmarks": [],
704 704 "branch": "default",
705 705 "copies": {"e": "dir/b"},
706 706 "date": [5, 0],
707 707 "desc": "e",
708 708 "files": ["dir/b", "e"],
709 709 "node": "7e4639b4691b9f84b81036a8d4fb218ce3c5e3a3",
710 710 "parents": ["2ca5ba7019804f1f597249caddf22a64d34df0ba"],
711 711 "phase": "draft",
712 712 "rev": 4,
713 713 "tags": ["tip"],
714 714 "user": "test"
715 715 }
716 716 ]
717 717
718 718 log copies, non-linear manifest
719 719
720 720 $ hg up -C 3
721 721 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
722 722 $ hg mv dir/b e
723 723 $ echo foo > foo
724 724 $ hg ci -Ame2 -d '6 0'
725 725 adding foo
726 726 created new head
727 727 $ hg log -v --template '{rev} {file_copies}\n' -r 5
728 728 5 e (dir/b)
729 729
730 730
731 731 log copies, execute bit set
732 732
733 733 #if execbit
734 734 $ chmod +x e
735 735 $ hg ci -me3 -d '7 0'
736 736 $ hg log -v --template '{rev} {file_copies}\n' -r 6
737 737 6
738 738 #endif
739 739
740 740 log copies, empty set
741 741
742 742 $ hg log --copies -r '0 and not 0'
743 743
744 744 log -p d
745 745
746 746 $ hg log -pv d
747 747 changeset: 3:2ca5ba701980
748 748 user: test
749 749 date: Thu Jan 01 00:00:04 1970 +0000
750 750 files: a b d g
751 751 description:
752 752 d
753 753
754 754
755 755 diff -r f8954cd4dc1f -r 2ca5ba701980 d
756 756 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
757 757 +++ b/d Thu Jan 01 00:00:04 1970 +0000
758 758 @@ -0,0 +1,1 @@
759 759 +a
760 760
761 761
762 762
763 763 log --removed file
764 764
765 765 $ hg log --removed -v a
766 766 changeset: 3:2ca5ba701980
767 767 user: test
768 768 date: Thu Jan 01 00:00:04 1970 +0000
769 769 files: a b d g
770 770 description:
771 771 d
772 772
773 773
774 774 changeset: 0:9161b9aeaf16
775 775 user: test
776 776 date: Thu Jan 01 00:00:01 1970 +0000
777 777 files: a f
778 778 description:
779 779 a
780 780
781 781
782 782
783 783 log --removed revrange file
784 784
785 785 $ hg log --removed -v -r0:2 a
786 786 changeset: 0:9161b9aeaf16
787 787 user: test
788 788 date: Thu Jan 01 00:00:01 1970 +0000
789 789 files: a f
790 790 description:
791 791 a
792 792
793 793
794 794 $ cd ..
795 795
796 796 log --follow tests
797 797
798 798 $ hg init follow
799 799 $ cd follow
800 800
801 801 $ echo base > base
802 802 $ hg ci -Ambase -d '1 0'
803 803 adding base
804 804
805 805 $ echo r1 >> base
806 806 $ hg ci -Amr1 -d '1 0'
807 807 $ echo r2 >> base
808 808 $ hg ci -Amr2 -d '1 0'
809 809
810 810 $ hg up -C 1
811 811 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
812 812 $ echo b1 > b1
813 813
814 814 log -r "follow('set:clean()')"
815 815
816 816 $ hg log -r "follow('set:clean()')"
817 817 changeset: 0:67e992f2c4f3
818 818 user: test
819 819 date: Thu Jan 01 00:00:01 1970 +0000
820 820 summary: base
821 821
822 822 changeset: 1:3d5bf5654eda
823 823 user: test
824 824 date: Thu Jan 01 00:00:01 1970 +0000
825 825 summary: r1
826 826
827 827
828 828 $ hg ci -Amb1 -d '1 0'
829 829 adding b1
830 830 created new head
831 831
832 832
833 833 log -f
834 834
835 835 $ hg log -f
836 836 changeset: 3:e62f78d544b4
837 837 tag: tip
838 838 parent: 1:3d5bf5654eda
839 839 user: test
840 840 date: Thu Jan 01 00:00:01 1970 +0000
841 841 summary: b1
842 842
843 843 changeset: 1:3d5bf5654eda
844 844 user: test
845 845 date: Thu Jan 01 00:00:01 1970 +0000
846 846 summary: r1
847 847
848 848 changeset: 0:67e992f2c4f3
849 849 user: test
850 850 date: Thu Jan 01 00:00:01 1970 +0000
851 851 summary: base
852 852
853 853
854 854 log -r follow('glob:b*')
855 855
856 856 $ hg log -r "follow('glob:b*')"
857 857 changeset: 0:67e992f2c4f3
858 858 user: test
859 859 date: Thu Jan 01 00:00:01 1970 +0000
860 860 summary: base
861 861
862 862 changeset: 1:3d5bf5654eda
863 863 user: test
864 864 date: Thu Jan 01 00:00:01 1970 +0000
865 865 summary: r1
866 866
867 867 changeset: 3:e62f78d544b4
868 868 tag: tip
869 869 parent: 1:3d5bf5654eda
870 870 user: test
871 871 date: Thu Jan 01 00:00:01 1970 +0000
872 872 summary: b1
873 873
874 874 log -f -r '1 + 4'
875 875
876 876 $ hg up -C 0
877 877 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
878 878 $ echo b2 > b2
879 879 $ hg ci -Amb2 -d '1 0'
880 880 adding b2
881 881 created new head
882 882 $ hg log -f -r '1 + 4'
883 883 changeset: 4:ddb82e70d1a1
884 884 tag: tip
885 885 parent: 0:67e992f2c4f3
886 886 user: test
887 887 date: Thu Jan 01 00:00:01 1970 +0000
888 888 summary: b2
889 889
890 890 changeset: 1:3d5bf5654eda
891 891 user: test
892 892 date: Thu Jan 01 00:00:01 1970 +0000
893 893 summary: r1
894 894
895 895 changeset: 0:67e992f2c4f3
896 896 user: test
897 897 date: Thu Jan 01 00:00:01 1970 +0000
898 898 summary: base
899 899
900 900
901 901 log -fr with aliases: 'A' should be expanded, but 'reverse()' should have no
902 902 effect
903 903
904 904 $ hg log --config 'revsetalias.reverse(x)=x' --config 'revsetalias.A=1+4' -qfrA
905 905 4:ddb82e70d1a1
906 906 1:3d5bf5654eda
907 907 0:67e992f2c4f3
908 908
909 909 log -r "follow('set:grep(b2)')"
910 910
911 911 $ hg log -r "follow('set:grep(b2)')"
912 912 changeset: 4:ddb82e70d1a1
913 913 tag: tip
914 914 parent: 0:67e992f2c4f3
915 915 user: test
916 916 date: Thu Jan 01 00:00:01 1970 +0000
917 917 summary: b2
918 918
919 919 log -r "follow('set:grep(b2)', 4)"
920 920
921 921 $ hg up -qC 0
922 922 $ hg log -r "follow('set:grep(b2)', 4)"
923 923 changeset: 4:ddb82e70d1a1
924 924 tag: tip
925 925 parent: 0:67e992f2c4f3
926 926 user: test
927 927 date: Thu Jan 01 00:00:01 1970 +0000
928 928 summary: b2
929 929
930 930
931 931 follow files starting from multiple revisions:
932 932
933 933 $ hg log -T '{rev}: {files}\n' -r "follow('glob:b?', startrev=2+3+4)"
934 934 3: b1
935 935 4: b2
936 936
937 937 follow files starting from empty revision:
938 938
939 939 $ hg log -T '{rev}: {files}\n' -r "follow('glob:*', startrev=.-.)"
940 940
941 941 follow starting from revisions:
942 942
943 943 $ hg log -Gq -r "follow(startrev=2+4)"
944 944 o 4:ddb82e70d1a1
945 945 |
946 946 | o 2:60c670bf5b30
947 947 | |
948 948 | o 1:3d5bf5654eda
949 949 |/
950 950 @ 0:67e992f2c4f3
951 951
952 952
953 953 follow the current revision:
954 954
955 955 $ hg log -Gq -r "follow()"
956 956 @ 0:67e992f2c4f3
957 957
958 958
959 959 $ hg up -qC 4
960 960
961 961 log -f -r null
962 962
963 963 $ hg log -f -r null
964 964 changeset: -1:000000000000
965 965 user:
966 966 date: Thu Jan 01 00:00:00 1970 +0000
967 967
968 968 $ hg log -f -r null -G
969 969 o changeset: -1:000000000000
970 970 user:
971 971 date: Thu Jan 01 00:00:00 1970 +0000
972 972
973 973
974 974
975 975 log -f with null parent
976 976
977 977 $ hg up -C null
978 978 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
979 979 $ hg log -f
980 980
981 981
982 982 log -r . with two parents
983 983
984 984 $ hg up -C 3
985 985 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
986 986 $ hg merge tip
987 987 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
988 988 (branch merge, don't forget to commit)
989 989 $ hg log -r .
990 990 changeset: 3:e62f78d544b4
991 991 parent: 1:3d5bf5654eda
992 992 user: test
993 993 date: Thu Jan 01 00:00:01 1970 +0000
994 994 summary: b1
995 995
996 996
997 997
998 998 log -r . with one parent
999 999
1000 1000 $ hg ci -mm12 -d '1 0'
1001 1001 $ hg log -r .
1002 1002 changeset: 5:302e9dd6890d
1003 1003 tag: tip
1004 1004 parent: 3:e62f78d544b4
1005 1005 parent: 4:ddb82e70d1a1
1006 1006 user: test
1007 1007 date: Thu Jan 01 00:00:01 1970 +0000
1008 1008 summary: m12
1009 1009
1010 1010
1011 1011 $ echo postm >> b1
1012 1012 $ hg ci -Amb1.1 -d'1 0'
1013 1013
1014 1014
1015 1015 log --follow-first
1016 1016
1017 1017 $ hg log --follow-first
1018 1018 changeset: 6:2404bbcab562
1019 1019 tag: tip
1020 1020 user: test
1021 1021 date: Thu Jan 01 00:00:01 1970 +0000
1022 1022 summary: b1.1
1023 1023
1024 1024 changeset: 5:302e9dd6890d
1025 1025 parent: 3:e62f78d544b4
1026 1026 parent: 4:ddb82e70d1a1
1027 1027 user: test
1028 1028 date: Thu Jan 01 00:00:01 1970 +0000
1029 1029 summary: m12
1030 1030
1031 1031 changeset: 3:e62f78d544b4
1032 1032 parent: 1:3d5bf5654eda
1033 1033 user: test
1034 1034 date: Thu Jan 01 00:00:01 1970 +0000
1035 1035 summary: b1
1036 1036
1037 1037 changeset: 1:3d5bf5654eda
1038 1038 user: test
1039 1039 date: Thu Jan 01 00:00:01 1970 +0000
1040 1040 summary: r1
1041 1041
1042 1042 changeset: 0:67e992f2c4f3
1043 1043 user: test
1044 1044 date: Thu Jan 01 00:00:01 1970 +0000
1045 1045 summary: base
1046 1046
1047 1047
1048 1048
1049 1049 log -P 2
1050 1050
1051 1051 $ hg log -P 2
1052 1052 changeset: 6:2404bbcab562
1053 1053 tag: tip
1054 1054 user: test
1055 1055 date: Thu Jan 01 00:00:01 1970 +0000
1056 1056 summary: b1.1
1057 1057
1058 1058 changeset: 5:302e9dd6890d
1059 1059 parent: 3:e62f78d544b4
1060 1060 parent: 4:ddb82e70d1a1
1061 1061 user: test
1062 1062 date: Thu Jan 01 00:00:01 1970 +0000
1063 1063 summary: m12
1064 1064
1065 1065 changeset: 4:ddb82e70d1a1
1066 1066 parent: 0:67e992f2c4f3
1067 1067 user: test
1068 1068 date: Thu Jan 01 00:00:01 1970 +0000
1069 1069 summary: b2
1070 1070
1071 1071 changeset: 3:e62f78d544b4
1072 1072 parent: 1:3d5bf5654eda
1073 1073 user: test
1074 1074 date: Thu Jan 01 00:00:01 1970 +0000
1075 1075 summary: b1
1076 1076
1077 1077
1078 1078
1079 1079 log -r tip -p --git
1080 1080
1081 1081 $ hg log -r tip -p --git
1082 1082 changeset: 6:2404bbcab562
1083 1083 tag: tip
1084 1084 user: test
1085 1085 date: Thu Jan 01 00:00:01 1970 +0000
1086 1086 summary: b1.1
1087 1087
1088 1088 diff --git a/b1 b/b1
1089 1089 --- a/b1
1090 1090 +++ b/b1
1091 1091 @@ -1,1 +1,2 @@
1092 1092 b1
1093 1093 +postm
1094 1094
1095 1095
1096 1096
1097 1097 log -r ""
1098 1098
1099 1099 $ hg log -r ''
1100 1100 hg: parse error: empty query
1101 1101 [10]
1102 1102
1103 1103 log -r <some unknown node id>
1104 1104
1105 1105 $ hg log -r 1000000000000000000000000000000000000000
1106 1106 abort: unknown revision '1000000000000000000000000000000000000000'
1107 1107 [10]
1108 1108
1109 1109 log -k r1
1110 1110
1111 1111 $ hg log -k r1
1112 1112 changeset: 1:3d5bf5654eda
1113 1113 user: test
1114 1114 date: Thu Jan 01 00:00:01 1970 +0000
1115 1115 summary: r1
1116 1116
1117 1117 log -p -l2 --color=always
1118 1118
1119 1119 $ hg --config extensions.color= --config color.mode=ansi \
1120 1120 > log -p -l2 --color=always
1121 1121 \x1b[0;33mchangeset: 6:2404bbcab562\x1b[0m (esc)
1122 1122 tag: tip
1123 1123 user: test
1124 1124 date: Thu Jan 01 00:00:01 1970 +0000
1125 1125 summary: b1.1
1126 1126
1127 1127 \x1b[0;1mdiff -r 302e9dd6890d -r 2404bbcab562 b1\x1b[0m (esc)
1128 1128 \x1b[0;31;1m--- a/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1129 1129 \x1b[0;32;1m+++ b/b1 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1130 1130 \x1b[0;35m@@ -1,1 +1,2 @@\x1b[0m (esc)
1131 1131 b1
1132 1132 \x1b[0;32m+postm\x1b[0m (esc)
1133 1133
1134 1134 \x1b[0;33mchangeset: 5:302e9dd6890d\x1b[0m (esc)
1135 1135 parent: 3:e62f78d544b4
1136 1136 parent: 4:ddb82e70d1a1
1137 1137 user: test
1138 1138 date: Thu Jan 01 00:00:01 1970 +0000
1139 1139 summary: m12
1140 1140
1141 1141 \x1b[0;1mdiff -r e62f78d544b4 -r 302e9dd6890d b2\x1b[0m (esc)
1142 1142 \x1b[0;31;1m--- /dev/null Thu Jan 01 00:00:00 1970 +0000\x1b[0m (esc)
1143 1143 \x1b[0;32;1m+++ b/b2 Thu Jan 01 00:00:01 1970 +0000\x1b[0m (esc)
1144 1144 \x1b[0;35m@@ -0,0 +1,1 @@\x1b[0m (esc)
1145 1145 \x1b[0;32m+b2\x1b[0m (esc)
1146 1146
1147 1147
1148 1148
1149 1149 log -r tip --stat
1150 1150
1151 1151 $ hg log -r tip --stat
1152 1152 changeset: 6:2404bbcab562
1153 1153 tag: tip
1154 1154 user: test
1155 1155 date: Thu Jan 01 00:00:01 1970 +0000
1156 1156 summary: b1.1
1157 1157
1158 1158 b1 | 1 +
1159 1159 1 files changed, 1 insertions(+), 0 deletions(-)
1160 1160
1161 1161
1162 1162 $ cd ..
1163 1163
1164 1164 log --follow --patch FILE in repository where linkrev isn't trustworthy
1165 1165 (issue5376, issue6124)
1166 1166
1167 1167 $ hg init follow-dup
1168 1168 $ cd follow-dup
1169 1169 $ cat <<EOF >> .hg/hgrc
1170 1170 > [command-templates]
1171 1171 > log = '=== {rev}: {desc}\n'
1172 1172 > [diff]
1173 1173 > nodates = True
1174 1174 > EOF
1175 1175 $ echo 0 >> a
1176 1176 $ hg ci -qAm 'a0'
1177 1177 $ echo 1 >> a
1178 1178 $ hg ci -m 'a1'
1179 1179 $ hg up -q 0
1180 1180 $ echo 1 >> a
1181 1181 $ touch b
1182 1182 $ hg ci -qAm 'a1 with b'
1183 1183 $ echo 3 >> a
1184 1184 $ hg ci -m 'a3'
1185 1185
1186 1186 fctx.rev() == 2, but fctx.linkrev() == 1
1187 1187
1188 1188 $ hg log -pf a
1189 1189 === 3: a3
1190 1190 diff -r 4ea02ba94d66 -r e7a6331a34f0 a
1191 1191 --- a/a
1192 1192 +++ b/a
1193 1193 @@ -1,2 +1,3 @@
1194 1194 0
1195 1195 1
1196 1196 +3
1197 1197
1198 1198 === 2: a1 with b
1199 1199 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
1200 1200 --- a/a
1201 1201 +++ b/a
1202 1202 @@ -1,1 +1,2 @@
1203 1203 0
1204 1204 +1
1205 1205
1206 1206 === 0: a0
1207 1207 diff -r 000000000000 -r 49b5e81287e2 a
1208 1208 --- /dev/null
1209 1209 +++ b/a
1210 1210 @@ -0,0 +1,1 @@
1211 1211 +0
1212 1212
1213 1213 $ hg log -pr . a
1214 1214 === 3: a3
1215 1215 diff -r 4ea02ba94d66 -r e7a6331a34f0 a
1216 1216 --- a/a
1217 1217 +++ b/a
1218 1218 @@ -1,2 +1,3 @@
1219 1219 0
1220 1220 1
1221 1221 +3
1222 1222
1223 1223
1224 1224 fctx.introrev() == 2, but fctx.linkrev() == 1
1225 1225
1226 1226 $ hg up -q 2
1227 1227 $ hg log -pf a
1228 1228 === 2: a1 with b
1229 1229 diff -r 49b5e81287e2 -r 4ea02ba94d66 a
1230 1230 --- a/a
1231 1231 +++ b/a
1232 1232 @@ -1,1 +1,2 @@
1233 1233 0
1234 1234 +1
1235 1235
1236 1236 === 0: a0
1237 1237 diff -r 000000000000 -r 49b5e81287e2 a
1238 1238 --- /dev/null
1239 1239 +++ b/a
1240 1240 @@ -0,0 +1,1 @@
1241 1241 +0
1242 1242
1243 1243
1244 1244 BROKEN: should show the same diff as for rev 2 above
1245 1245 $ hg log -pr . a
1246 1246
1247 1247 $ cd ..
1248 1248
1249 1249 Multiple copy sources of a file:
1250 1250
1251 1251 $ hg init follow-multi
1252 1252 $ cd follow-multi
1253 1253 $ echo 0 >> a
1254 1254 $ hg ci -qAm 'a'
1255 1255 $ hg cp a b
1256 1256 $ hg ci -m 'a->b'
1257 1257 $ echo 2 >> a
1258 1258 $ hg ci -m 'a'
1259 1259 $ echo 3 >> b
1260 1260 $ hg ci -m 'b'
1261 1261 $ echo 4 >> a
1262 1262 $ echo 4 >> b
1263 1263 $ hg ci -m 'a,b'
1264 1264 $ echo 5 >> a
1265 1265 $ hg ci -m 'a0'
1266 1266 $ echo 6 >> b
1267 1267 $ hg ci -m 'b0'
1268 1268 $ hg up -q 4
1269 1269 $ echo 7 >> b
1270 1270 $ hg ci -m 'b1'
1271 1271 created new head
1272 1272 $ echo 8 >> a
1273 1273 $ hg ci -m 'a1'
1274 1274 $ hg rm a
1275 1275 $ hg mv b a
1276 1276 $ hg ci -m 'b1->a1'
1277 1277 $ hg merge -qt :local
1278 1278 $ hg ci -m '(a0,b1->a1)->a'
1279 1279
1280 1280 $ hg log -GT '{rev}: {desc}\n'
1281 1281 @ 10: (a0,b1->a1)->a
1282 1282 |\
1283 1283 | o 9: b1->a1
1284 1284 | |
1285 1285 | o 8: a1
1286 1286 | |
1287 1287 | o 7: b1
1288 1288 | |
1289 1289 o | 6: b0
1290 1290 | |
1291 1291 o | 5: a0
1292 1292 |/
1293 1293 o 4: a,b
1294 1294 |
1295 1295 o 3: b
1296 1296 |
1297 1297 o 2: a
1298 1298 |
1299 1299 o 1: a->b
1300 1300 |
1301 1301 o 0: a
1302 1302
1303 1303
1304 1304 since file 'a' has multiple copy sources at the revision 4, ancestors can't
1305 1305 be indexed solely by fctx.linkrev().
1306 1306
1307 1307 $ hg log -T '{rev}: {desc}\n' -f a
1308 1308 10: (a0,b1->a1)->a
1309 1309 9: b1->a1
1310 1310 7: b1
1311 1311 5: a0
1312 1312 4: a,b
1313 1313 3: b
1314 1314 2: a
1315 1315 1: a->b
1316 1316 0: a
1317 1317
1318 1318 $ cd ..
1319 1319
1320 1320 Test that log should respect the order of -rREV even if multiple OR conditions
1321 1321 are specified (issue5100):
1322 1322
1323 1323 $ hg init revorder
1324 1324 $ cd revorder
1325 1325
1326 1326 $ hg branch -q b0
1327 1327 $ echo 0 >> f0
1328 1328 $ hg ci -qAm k0 -u u0
1329 1329 $ hg branch -q b1
1330 1330 $ echo 1 >> f1
1331 1331 $ hg ci -qAm k1 -u u1
1332 1332 $ hg branch -q b2
1333 1333 $ echo 2 >> f2
1334 1334 $ hg ci -qAm k2 -u u2
1335 1335
1336 1336 $ hg update -q b2
1337 1337 $ echo 3 >> f2
1338 1338 $ hg ci -qAm k2 -u u2
1339 1339 $ hg update -q b1
1340 1340 $ echo 4 >> f1
1341 1341 $ hg ci -qAm k1 -u u1
1342 1342 $ hg update -q b0
1343 1343 $ echo 5 >> f0
1344 1344 $ hg ci -qAm k0 -u u0
1345 1345
1346 1346 summary of revisions:
1347 1347
1348 1348 $ hg log -G -T '{rev} {branch} {author} {desc} {files}\n'
1349 1349 @ 5 b0 u0 k0 f0
1350 1350 |
1351 1351 | o 4 b1 u1 k1 f1
1352 1352 | |
1353 1353 | | o 3 b2 u2 k2 f2
1354 1354 | | |
1355 1355 | | o 2 b2 u2 k2 f2
1356 1356 | |/
1357 1357 | o 1 b1 u1 k1 f1
1358 1358 |/
1359 1359 o 0 b0 u0 k0 f0
1360 1360
1361 1361
1362 1362 log -b BRANCH in ascending order:
1363 1363
1364 1364 $ hg log -r0:tip -T '{rev} {branch}\n' -b b0 -b b1
1365 1365 0 b0
1366 1366 1 b1
1367 1367 4 b1
1368 1368 5 b0
1369 1369 $ hg log -r0:tip -T '{rev} {branch}\n' -b b1 -b b0
1370 1370 0 b0
1371 1371 1 b1
1372 1372 4 b1
1373 1373 5 b0
1374 1374
1375 1375 log --only-branch BRANCH in descending order:
1376 1376
1377 1377 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b1 --only-branch b2
1378 1378 4 b1
1379 1379 3 b2
1380 1380 2 b2
1381 1381 1 b1
1382 1382 $ hg log -rtip:0 -T '{rev} {branch}\n' --only-branch b2 --only-branch b1
1383 1383 4 b1
1384 1384 3 b2
1385 1385 2 b2
1386 1386 1 b1
1387 1387
1388 1388 log -u USER in ascending order, against compound set:
1389 1389
1390 1390 $ hg log -r'::head()' -T '{rev} {author}\n' -u u0 -u u2
1391 1391 0 u0
1392 1392 2 u2
1393 1393 3 u2
1394 1394 5 u0
1395 1395 $ hg log -r'::head()' -T '{rev} {author}\n' -u u2 -u u0
1396 1396 0 u0
1397 1397 2 u2
1398 1398 3 u2
1399 1399 5 u0
1400 1400
1401 1401 log -k TEXT in descending order, against compound set:
1402 1402
1403 1403 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k0 -k k1 -k k2
1404 1404 5 k0
1405 1405 3 k2
1406 1406 2 k2
1407 1407 1 k1
1408 1408 0 k0
1409 1409 $ hg log -r'5 + reverse(::3)' -T '{rev} {desc}\n' -k k2 -k k1 -k k0
1410 1410 5 k0
1411 1411 3 k2
1412 1412 2 k2
1413 1413 1 k1
1414 1414 0 k0
1415 1415
1416 1416 log -b/-u/-k shouldn't accept string-matcher syntax:
1417 1417
1418 1418 $ hg log -b 're:.*'
1419 1419 abort: unknown revision 're:.*'
1420 1420 [10]
1421 1421 $ hg log -k 're:.*'
1422 1422 $ hg log -u 're:.*'
1423 1423
1424 1424 log FILE in ascending order, against dagrange:
1425 1425
1426 1426 $ hg log -r1:: -T '{rev} {files}\n' f1 f2
1427 1427 1 f1
1428 1428 2 f2
1429 1429 3 f2
1430 1430 4 f1
1431 1431 $ hg log -r1:: -T '{rev} {files}\n' f2 f1
1432 1432 1 f1
1433 1433 2 f2
1434 1434 3 f2
1435 1435 4 f1
1436 1436
1437 1437 $ cd ..
1438 1438
1439 1439 User
1440 1440
1441 1441 $ hg init usertest
1442 1442 $ cd usertest
1443 1443
1444 1444 $ echo a > a
1445 1445 $ hg ci -A -m "a" -u "User One <user1@example.org>"
1446 1446 adding a
1447 1447 $ echo b > b
1448 1448 $ hg ci -A -m "b" -u "User Two <user2@example.org>"
1449 1449 adding b
1450 1450
1451 1451 $ hg log -u "User One <user1@example.org>"
1452 1452 changeset: 0:29a4c94f1924
1453 1453 user: User One <user1@example.org>
1454 1454 date: Thu Jan 01 00:00:00 1970 +0000
1455 1455 summary: a
1456 1456
1457 1457 $ hg log -u "user1" -u "user2"
1458 1458 changeset: 1:e834b5e69c0e
1459 1459 tag: tip
1460 1460 user: User Two <user2@example.org>
1461 1461 date: Thu Jan 01 00:00:00 1970 +0000
1462 1462 summary: b
1463 1463
1464 1464 changeset: 0:29a4c94f1924
1465 1465 user: User One <user1@example.org>
1466 1466 date: Thu Jan 01 00:00:00 1970 +0000
1467 1467 summary: a
1468 1468
1469 1469 $ hg log -u "user3"
1470 1470
1471 1471 "-u USER" shouldn't be overridden by "user(USER)" alias
1472 1472
1473 1473 $ hg log --config 'revsetalias.user(x)=branch(x)' -u default
1474 1474 $ hg log --config 'revsetalias.user(x)=branch(x)' -u user1
1475 1475 changeset: 0:29a4c94f1924
1476 1476 user: User One <user1@example.org>
1477 1477 date: Thu Jan 01 00:00:00 1970 +0000
1478 1478 summary: a
1479 1479
1480 1480
1481 1481 $ cd ..
1482 1482
1483 1483 $ hg init branches
1484 1484 $ cd branches
1485 1485
1486 1486 $ echo a > a
1487 1487 $ hg ci -A -m "commit on default"
1488 1488 adding a
1489 1489 $ hg branch test
1490 1490 marked working directory as branch test
1491 1491 (branches are permanent and global, did you want a bookmark?)
1492 1492 $ echo b > b
1493 1493 $ hg ci -A -m "commit on test"
1494 1494 adding b
1495 1495
1496 1496 $ hg up default
1497 1497 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1498 1498 $ echo c > c
1499 1499 $ hg ci -A -m "commit on default"
1500 1500 adding c
1501 1501 $ hg up test
1502 1502 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1503 1503 $ echo c > c
1504 1504 $ hg ci -A -m "commit on test"
1505 1505 adding c
1506 1506
1507 1507
1508 1508 log -b default
1509 1509
1510 1510 $ hg log -b default
1511 1511 changeset: 2:c3a4f03cc9a7
1512 1512 parent: 0:24427303d56f
1513 1513 user: test
1514 1514 date: Thu Jan 01 00:00:00 1970 +0000
1515 1515 summary: commit on default
1516 1516
1517 1517 changeset: 0:24427303d56f
1518 1518 user: test
1519 1519 date: Thu Jan 01 00:00:00 1970 +0000
1520 1520 summary: commit on default
1521 1521
1522 1522
1523 1523
1524 1524 log -b test
1525 1525
1526 1526 $ hg log -b test
1527 1527 changeset: 3:f5d8de11c2e2
1528 1528 branch: test
1529 1529 tag: tip
1530 1530 parent: 1:d32277701ccb
1531 1531 user: test
1532 1532 date: Thu Jan 01 00:00:00 1970 +0000
1533 1533 summary: commit on test
1534 1534
1535 1535 changeset: 1:d32277701ccb
1536 1536 branch: test
1537 1537 user: test
1538 1538 date: Thu Jan 01 00:00:00 1970 +0000
1539 1539 summary: commit on test
1540 1540
1541 1541
1542 1542
1543 1543 log -b dummy
1544 1544
1545 1545 $ hg log -b dummy
1546 1546 abort: unknown revision 'dummy'
1547 1547 [10]
1548 1548
1549 1549
1550 1550 log -b .
1551 1551
1552 1552 $ hg log -b .
1553 1553 changeset: 3:f5d8de11c2e2
1554 1554 branch: test
1555 1555 tag: tip
1556 1556 parent: 1:d32277701ccb
1557 1557 user: test
1558 1558 date: Thu Jan 01 00:00:00 1970 +0000
1559 1559 summary: commit on test
1560 1560
1561 1561 changeset: 1:d32277701ccb
1562 1562 branch: test
1563 1563 user: test
1564 1564 date: Thu Jan 01 00:00:00 1970 +0000
1565 1565 summary: commit on test
1566 1566
1567 1567
1568 1568
1569 1569 log -b default -b test
1570 1570
1571 1571 $ hg log -b default -b test
1572 1572 changeset: 3:f5d8de11c2e2
1573 1573 branch: test
1574 1574 tag: tip
1575 1575 parent: 1:d32277701ccb
1576 1576 user: test
1577 1577 date: Thu Jan 01 00:00:00 1970 +0000
1578 1578 summary: commit on test
1579 1579
1580 1580 changeset: 2:c3a4f03cc9a7
1581 1581 parent: 0:24427303d56f
1582 1582 user: test
1583 1583 date: Thu Jan 01 00:00:00 1970 +0000
1584 1584 summary: commit on default
1585 1585
1586 1586 changeset: 1:d32277701ccb
1587 1587 branch: test
1588 1588 user: test
1589 1589 date: Thu Jan 01 00:00:00 1970 +0000
1590 1590 summary: commit on test
1591 1591
1592 1592 changeset: 0:24427303d56f
1593 1593 user: test
1594 1594 date: Thu Jan 01 00:00:00 1970 +0000
1595 1595 summary: commit on default
1596 1596
1597 1597
1598 1598
1599 1599 log -b default -b .
1600 1600
1601 1601 $ hg log -b default -b .
1602 1602 changeset: 3:f5d8de11c2e2
1603 1603 branch: test
1604 1604 tag: tip
1605 1605 parent: 1:d32277701ccb
1606 1606 user: test
1607 1607 date: Thu Jan 01 00:00:00 1970 +0000
1608 1608 summary: commit on test
1609 1609
1610 1610 changeset: 2:c3a4f03cc9a7
1611 1611 parent: 0:24427303d56f
1612 1612 user: test
1613 1613 date: Thu Jan 01 00:00:00 1970 +0000
1614 1614 summary: commit on default
1615 1615
1616 1616 changeset: 1:d32277701ccb
1617 1617 branch: test
1618 1618 user: test
1619 1619 date: Thu Jan 01 00:00:00 1970 +0000
1620 1620 summary: commit on test
1621 1621
1622 1622 changeset: 0:24427303d56f
1623 1623 user: test
1624 1624 date: Thu Jan 01 00:00:00 1970 +0000
1625 1625 summary: commit on default
1626 1626
1627 1627
1628 1628
1629 1629 log -b . -b test
1630 1630
1631 1631 $ hg log -b . -b test
1632 1632 changeset: 3:f5d8de11c2e2
1633 1633 branch: test
1634 1634 tag: tip
1635 1635 parent: 1:d32277701ccb
1636 1636 user: test
1637 1637 date: Thu Jan 01 00:00:00 1970 +0000
1638 1638 summary: commit on test
1639 1639
1640 1640 changeset: 1:d32277701ccb
1641 1641 branch: test
1642 1642 user: test
1643 1643 date: Thu Jan 01 00:00:00 1970 +0000
1644 1644 summary: commit on test
1645 1645
1646 1646
1647 1647
1648 1648 log -b 2
1649 1649
1650 1650 $ hg log -b 2
1651 1651 changeset: 2:c3a4f03cc9a7
1652 1652 parent: 0:24427303d56f
1653 1653 user: test
1654 1654 date: Thu Jan 01 00:00:00 1970 +0000
1655 1655 summary: commit on default
1656 1656
1657 1657 changeset: 0:24427303d56f
1658 1658 user: test
1659 1659 date: Thu Jan 01 00:00:00 1970 +0000
1660 1660 summary: commit on default
1661 1661
1662 1662 #if gettext
1663 1663
1664 1664 Test that all log names are translated (e.g. branches, bookmarks, tags):
1665 1665
1666 1666 $ hg bookmark babar -r tip
1667 1667
1668 1668 $ HGENCODING=UTF-8 LANGUAGE=de hg log -r tip
1669 1669 \xc3\x84nderung: 3:f5d8de11c2e2 (esc)
1670 1670 Zweig: test
1671 1671 Lesezeichen: babar
1672 1672 Marke: tip
1673 1673 Vorg\xc3\xa4nger: 1:d32277701ccb (esc)
1674 1674 Nutzer: test
1675 1675 Datum: Thu Jan 01 00:00:00 1970 +0000
1676 1676 Zusammenfassung: commit on test
1677 1677
1678 1678 $ hg bookmark -d babar
1679 1679
1680 1680 #endif
1681 1681
1682 1682 log -p --cwd dir (in subdir)
1683 1683
1684 1684 $ mkdir dir
1685 1685 $ hg log -p --cwd dir
1686 1686 changeset: 3:f5d8de11c2e2
1687 1687 branch: test
1688 1688 tag: tip
1689 1689 parent: 1:d32277701ccb
1690 1690 user: test
1691 1691 date: Thu Jan 01 00:00:00 1970 +0000
1692 1692 summary: commit on test
1693 1693
1694 1694 diff -r d32277701ccb -r f5d8de11c2e2 c
1695 1695 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1696 1696 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1697 1697 @@ -0,0 +1,1 @@
1698 1698 +c
1699 1699
1700 1700 changeset: 2:c3a4f03cc9a7
1701 1701 parent: 0:24427303d56f
1702 1702 user: test
1703 1703 date: Thu Jan 01 00:00:00 1970 +0000
1704 1704 summary: commit on default
1705 1705
1706 1706 diff -r 24427303d56f -r c3a4f03cc9a7 c
1707 1707 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1708 1708 +++ b/c Thu Jan 01 00:00:00 1970 +0000
1709 1709 @@ -0,0 +1,1 @@
1710 1710 +c
1711 1711
1712 1712 changeset: 1:d32277701ccb
1713 1713 branch: test
1714 1714 user: test
1715 1715 date: Thu Jan 01 00:00:00 1970 +0000
1716 1716 summary: commit on test
1717 1717
1718 1718 diff -r 24427303d56f -r d32277701ccb b
1719 1719 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1720 1720 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1721 1721 @@ -0,0 +1,1 @@
1722 1722 +b
1723 1723
1724 1724 changeset: 0:24427303d56f
1725 1725 user: test
1726 1726 date: Thu Jan 01 00:00:00 1970 +0000
1727 1727 summary: commit on default
1728 1728
1729 1729 diff -r 000000000000 -r 24427303d56f a
1730 1730 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1731 1731 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1732 1732 @@ -0,0 +1,1 @@
1733 1733 +a
1734 1734
1735 1735
1736 1736
1737 1737 log -p -R repo
1738 1738
1739 1739 $ cd dir
1740 1740 $ hg log -p -R .. ../a
1741 1741 changeset: 0:24427303d56f
1742 1742 user: test
1743 1743 date: Thu Jan 01 00:00:00 1970 +0000
1744 1744 summary: commit on default
1745 1745
1746 1746 diff -r 000000000000 -r 24427303d56f a
1747 1747 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1748 1748 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1749 1749 @@ -0,0 +1,1 @@
1750 1750 +a
1751 1751
1752 1752
1753 1753 $ cd ../..
1754 1754
1755 1755 $ hg init follow2
1756 1756 $ cd follow2
1757 1757
1758 1758 # Build the following history:
1759 1759 # tip - o - x - o - x - x
1760 1760 # \ /
1761 1761 # o - o - o - x
1762 1762 # \ /
1763 1763 # o
1764 1764 #
1765 1765 # Where "o" is a revision containing "foo" and
1766 1766 # "x" is a revision without "foo"
1767 1767
1768 1768 $ touch init
1769 1769 $ hg ci -A -m "init, unrelated"
1770 1770 adding init
1771 1771 $ echo 'foo' > init
1772 1772 $ hg ci -m "change, unrelated"
1773 1773 $ echo 'foo' > foo
1774 1774 $ hg ci -A -m "add unrelated old foo"
1775 1775 adding foo
1776 1776 $ hg rm foo
1777 1777 $ hg ci -m "delete foo, unrelated"
1778 1778 $ echo 'related' > foo
1779 1779 $ hg ci -A -m "add foo, related"
1780 1780 adding foo
1781 1781
1782 1782 $ hg up 0
1783 1783 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1784 1784 $ touch branch
1785 1785 $ hg ci -A -m "first branch, unrelated"
1786 1786 adding branch
1787 1787 created new head
1788 1788 $ touch foo
1789 1789 $ hg ci -A -m "create foo, related"
1790 1790 adding foo
1791 1791 $ echo 'change' > foo
1792 1792 $ hg ci -m "change foo, related"
1793 1793
1794 1794 $ hg up 6
1795 1795 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1796 1796 $ echo 'change foo in branch' > foo
1797 1797 $ hg ci -m "change foo in branch, related"
1798 1798 created new head
1799 1799 $ hg merge 7
1800 1800 merging foo
1801 1801 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1802 1802 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
1803 1803 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
1804 1804 [1]
1805 1805 $ echo 'merge 1' > foo
1806 1806 $ hg resolve -m foo
1807 1807 (no more unresolved files)
1808 1808 $ hg ci -m "First merge, related"
1809 1809
1810 1810 $ hg merge 4
1811 1811 merging foo
1812 1812 warning: conflicts while merging foo! (edit, then use 'hg resolve --mark')
1813 1813 1 files updated, 0 files merged, 0 files removed, 1 files unresolved
1814 1814 use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
1815 1815 [1]
1816 1816 $ echo 'merge 2' > foo
1817 1817 $ hg resolve -m foo
1818 1818 (no more unresolved files)
1819 1819 $ hg ci -m "Last merge, related"
1820 1820
1821 1821 $ hg log --graph
1822 1822 @ changeset: 10:4dae8563d2c5
1823 1823 |\ tag: tip
1824 1824 | | parent: 9:7b35701b003e
1825 1825 | | parent: 4:88176d361b69
1826 1826 | | user: test
1827 1827 | | date: Thu Jan 01 00:00:00 1970 +0000
1828 1828 | | summary: Last merge, related
1829 1829 | |
1830 1830 | o changeset: 9:7b35701b003e
1831 1831 | |\ parent: 8:e5416ad8a855
1832 1832 | | | parent: 7:87fe3144dcfa
1833 1833 | | | user: test
1834 1834 | | | date: Thu Jan 01 00:00:00 1970 +0000
1835 1835 | | | summary: First merge, related
1836 1836 | | |
1837 1837 | | o changeset: 8:e5416ad8a855
1838 1838 | | | parent: 6:dc6c325fe5ee
1839 1839 | | | user: test
1840 1840 | | | date: Thu Jan 01 00:00:00 1970 +0000
1841 1841 | | | summary: change foo in branch, related
1842 1842 | | |
1843 1843 | o | changeset: 7:87fe3144dcfa
1844 1844 | |/ user: test
1845 1845 | | date: Thu Jan 01 00:00:00 1970 +0000
1846 1846 | | summary: change foo, related
1847 1847 | |
1848 1848 | o changeset: 6:dc6c325fe5ee
1849 1849 | | user: test
1850 1850 | | date: Thu Jan 01 00:00:00 1970 +0000
1851 1851 | | summary: create foo, related
1852 1852 | |
1853 1853 | o changeset: 5:73db34516eb9
1854 1854 | | parent: 0:e87515fd044a
1855 1855 | | user: test
1856 1856 | | date: Thu Jan 01 00:00:00 1970 +0000
1857 1857 | | summary: first branch, unrelated
1858 1858 | |
1859 1859 o | changeset: 4:88176d361b69
1860 1860 | | user: test
1861 1861 | | date: Thu Jan 01 00:00:00 1970 +0000
1862 1862 | | summary: add foo, related
1863 1863 | |
1864 1864 o | changeset: 3:dd78ae4afb56
1865 1865 | | user: test
1866 1866 | | date: Thu Jan 01 00:00:00 1970 +0000
1867 1867 | | summary: delete foo, unrelated
1868 1868 | |
1869 1869 o | changeset: 2:c4c64aedf0f7
1870 1870 | | user: test
1871 1871 | | date: Thu Jan 01 00:00:00 1970 +0000
1872 1872 | | summary: add unrelated old foo
1873 1873 | |
1874 1874 o | changeset: 1:e5faa7440653
1875 1875 |/ user: test
1876 1876 | date: Thu Jan 01 00:00:00 1970 +0000
1877 1877 | summary: change, unrelated
1878 1878 |
1879 1879 o changeset: 0:e87515fd044a
1880 1880 user: test
1881 1881 date: Thu Jan 01 00:00:00 1970 +0000
1882 1882 summary: init, unrelated
1883 1883
1884 1884
1885 1885 $ hg --traceback log -f foo
1886 1886 changeset: 10:4dae8563d2c5
1887 1887 tag: tip
1888 1888 parent: 9:7b35701b003e
1889 1889 parent: 4:88176d361b69
1890 1890 user: test
1891 1891 date: Thu Jan 01 00:00:00 1970 +0000
1892 1892 summary: Last merge, related
1893 1893
1894 1894 changeset: 9:7b35701b003e
1895 1895 parent: 8:e5416ad8a855
1896 1896 parent: 7:87fe3144dcfa
1897 1897 user: test
1898 1898 date: Thu Jan 01 00:00:00 1970 +0000
1899 1899 summary: First merge, related
1900 1900
1901 1901 changeset: 8:e5416ad8a855
1902 1902 parent: 6:dc6c325fe5ee
1903 1903 user: test
1904 1904 date: Thu Jan 01 00:00:00 1970 +0000
1905 1905 summary: change foo in branch, related
1906 1906
1907 1907 changeset: 7:87fe3144dcfa
1908 1908 user: test
1909 1909 date: Thu Jan 01 00:00:00 1970 +0000
1910 1910 summary: change foo, related
1911 1911
1912 1912 changeset: 6:dc6c325fe5ee
1913 1913 user: test
1914 1914 date: Thu Jan 01 00:00:00 1970 +0000
1915 1915 summary: create foo, related
1916 1916
1917 1917 changeset: 4:88176d361b69
1918 1918 user: test
1919 1919 date: Thu Jan 01 00:00:00 1970 +0000
1920 1920 summary: add foo, related
1921 1921
1922 1922
1923 1923 Also check when maxrev < lastrevfilelog
1924 1924
1925 1925 $ hg --traceback log -f -r4 foo
1926 1926 changeset: 4:88176d361b69
1927 1927 user: test
1928 1928 date: Thu Jan 01 00:00:00 1970 +0000
1929 1929 summary: add foo, related
1930 1930
1931 1931 $ cd ..
1932 1932
1933 1933 Issue2383: hg log showing _less_ differences than hg diff
1934 1934
1935 1935 $ hg init issue2383
1936 1936 $ cd issue2383
1937 1937
1938 1938 Create a test repo:
1939 1939
1940 1940 $ echo a > a
1941 1941 $ hg ci -Am0
1942 1942 adding a
1943 1943 $ echo b > b
1944 1944 $ hg ci -Am1
1945 1945 adding b
1946 1946 $ hg co 0
1947 1947 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
1948 1948 $ echo b > a
1949 1949 $ hg ci -m2
1950 1950 created new head
1951 1951
1952 1952 Merge:
1953 1953
1954 1954 $ hg merge
1955 1955 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1956 1956 (branch merge, don't forget to commit)
1957 1957
1958 1958 Make sure there's a file listed in the merge to trigger the bug:
1959 1959
1960 1960 $ echo c > a
1961 1961 $ hg ci -m3
1962 1962
1963 1963 Two files shown here in diff:
1964 1964
1965 1965 $ hg diff --rev 2:3
1966 1966 diff -r b09be438c43a -r 8e07aafe1edc a
1967 1967 --- a/a Thu Jan 01 00:00:00 1970 +0000
1968 1968 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1969 1969 @@ -1,1 +1,1 @@
1970 1970 -b
1971 1971 +c
1972 1972 diff -r b09be438c43a -r 8e07aafe1edc b
1973 1973 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1974 1974 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1975 1975 @@ -0,0 +1,1 @@
1976 1976 +b
1977 1977
1978 1978 Diff here should be the same:
1979 1979
1980 1980 $ hg log -vpr 3
1981 1981 changeset: 3:8e07aafe1edc
1982 1982 tag: tip
1983 1983 parent: 2:b09be438c43a
1984 1984 parent: 1:925d80f479bb
1985 1985 user: test
1986 1986 date: Thu Jan 01 00:00:00 1970 +0000
1987 1987 files: a
1988 1988 description:
1989 1989 3
1990 1990
1991 1991
1992 1992 diff -r b09be438c43a -r 8e07aafe1edc a
1993 1993 --- a/a Thu Jan 01 00:00:00 1970 +0000
1994 1994 +++ b/a Thu Jan 01 00:00:00 1970 +0000
1995 1995 @@ -1,1 +1,1 @@
1996 1996 -b
1997 1997 +c
1998 1998 diff -r b09be438c43a -r 8e07aafe1edc b
1999 1999 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2000 2000 +++ b/b Thu Jan 01 00:00:00 1970 +0000
2001 2001 @@ -0,0 +1,1 @@
2002 2002 +b
2003 2003
2004 2004
2005 2005 Test that diff.merge is respected (file b was added on one side and
2006 2006 and therefore merged cleanly)
2007 2007
2008 2008 $ hg log -pr 3 --config diff.merge=yes
2009 2009 changeset: 3:8e07aafe1edc
2010 2010 tag: tip
2011 2011 parent: 2:b09be438c43a
2012 2012 parent: 1:925d80f479bb
2013 2013 user: test
2014 2014 date: Thu Jan 01 00:00:00 1970 +0000
2015 2015 summary: 3
2016 2016
2017 2017 diff -r 8e07aafe1edc a
2018 2018 --- a/a Thu Jan 01 00:00:00 1970 +0000
2019 2019 +++ b/a Thu Jan 01 00:00:00 1970 +0000
2020 2020 @@ -1,1 +1,1 @@
2021 2021 -b
2022 2022 +c
2023 2023
2024 2024 $ cd ..
2025 2025
2026 2026 'hg log -r rev fn' when last(filelog(fn)) != rev
2027 2027
2028 2028 $ hg init simplelog
2029 2029 $ cd simplelog
2030 2030 $ echo f > a
2031 2031 $ hg ci -Am'a' -d '0 0'
2032 2032 adding a
2033 2033 $ echo f >> a
2034 2034 $ hg ci -Am'a bis' -d '1 0'
2035 2035
2036 2036 $ hg log -r0 a
2037 2037 changeset: 0:9f758d63dcde
2038 2038 user: test
2039 2039 date: Thu Jan 01 00:00:00 1970 +0000
2040 2040 summary: a
2041 2041
2042 2042 enable obsolete to test hidden feature
2043 2043
2044 2044 $ cat >> $HGRCPATH << EOF
2045 2045 > [experimental]
2046 2046 > evolution.createmarkers=True
2047 2047 > EOF
2048 2048
2049 2049 $ hg log --template='{rev}:{node}\n'
2050 2050 1:a765632148dc55d38c35c4f247c618701886cb2f
2051 2051 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2052 2052 $ hg debugobsolete a765632148dc55d38c35c4f247c618701886cb2f
2053 2053 1 new obsolescence markers
2054 2054 obsoleted 1 changesets
2055 2055 $ hg up null -q
2056 2056 $ hg log --template='{rev}:{node}\n'
2057 2057 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2058 2058 $ hg log --template='{rev}:{node}\n' --hidden
2059 2059 1:a765632148dc55d38c35c4f247c618701886cb2f
2060 2060 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2061 2061 $ hg log -r a
2062 2062 abort: hidden revision 'a' is pruned
2063 2063 (use --hidden to access hidden revisions)
2064 2064 [10]
2065 2065
2066 2066 test that parent prevent a changeset to be hidden
2067 2067
2068 2068 $ hg up 1 -q --hidden
2069 2069 updated to hidden changeset a765632148dc
2070 2070 (hidden revision 'a765632148dc' is pruned)
2071 2071 $ hg log --template='{rev}:{node}\n'
2072 2072 1:a765632148dc55d38c35c4f247c618701886cb2f
2073 2073 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2074 2074
2075 2075 test that second parent prevent a changeset to be hidden too
2076 2076
2077 2077 $ hg debugsetparents 0 1 # nothing suitable to merge here
2078 2078 $ hg log --template='{rev}:{node}\n'
2079 2079 1:a765632148dc55d38c35c4f247c618701886cb2f
2080 2080 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2081 2081 $ hg debugsetparents 1
2082 2082 $ hg up -q null
2083 2083
2084 2084 bookmarks prevent a changeset being hidden
2085 2085
2086 2086 $ hg bookmark --hidden -r 1 X
2087 2087 bookmarking hidden changeset a765632148dc
2088 2088 (hidden revision 'a765632148dc' is pruned)
2089 2089 $ hg log --template '{rev}:{node}\n'
2090 2090 1:a765632148dc55d38c35c4f247c618701886cb2f
2091 2091 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2092 2092 $ hg bookmark -d X
2093 2093
2094 2094 divergent bookmarks are not hidden
2095 2095
2096 2096 $ hg bookmark --hidden -r 1 X@foo
2097 2097 bookmarking hidden changeset a765632148dc
2098 2098 (hidden revision 'a765632148dc' is pruned)
2099 2099 $ hg log --template '{rev}:{node}\n'
2100 2100 1:a765632148dc55d38c35c4f247c618701886cb2f
2101 2101 0:9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2102 2102
2103 2103 test hidden revision 0 (issue5385)
2104 2104
2105 2105 $ hg bookmark -d X@foo
2106 2106 $ hg up null -q
2107 2107 $ hg debugobsolete 9f758d63dcde62d547ebfb08e1e7ee96535f2b05
2108 2108 1 new obsolescence markers
2109 2109 obsoleted 1 changesets
2110 2110 $ echo f > b
2111 2111 $ hg ci -Am'b' -d '2 0'
2112 2112 adding b
2113 2113 $ echo f >> b
2114 2114 $ hg ci -m'b bis' -d '3 0'
2115 2115 $ hg log -T'{rev}:{node}\n'
2116 2116 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2117 2117 2:94375ec45bddd2a824535fc04855bd058c926ec0
2118 2118
2119 2119 $ hg log -T'{rev}:{node}\n' -r:
2120 2120 2:94375ec45bddd2a824535fc04855bd058c926ec0
2121 2121 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2122 2122 $ hg log -T'{rev}:{node}\n' -r:tip
2123 2123 2:94375ec45bddd2a824535fc04855bd058c926ec0
2124 2124 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2125 2125 $ hg log -T'{rev}:{node}\n' -r:0
2126 2126 abort: hidden revision '0' is pruned
2127 2127 (use --hidden to access hidden revisions)
2128 2128 [10]
2129 2129 $ hg log -T'{rev}:{node}\n' -f
2130 2130 3:d7d28b288a6b83d5d2cf49f10c5974deed3a1d2e
2131 2131 2:94375ec45bddd2a824535fc04855bd058c926ec0
2132 2132
2133 2133 clear extensions configuration
2134 2134 $ echo '[extensions]' >> $HGRCPATH
2135 2135 $ echo "obs=!" >> $HGRCPATH
2136 2136 $ cd ..
2137 2137
2138 2138 test -u/-k for problematic encoding
2139 2139 # unicode: cp932:
2140 2140 # u30A2 0x83 0x41(= 'A')
2141 2141 # u30C2 0x83 0x61(= 'a')
2142 2142
2143 2143 $ hg init problematicencoding
2144 2144 $ cd problematicencoding
2145 2145
2146 2146 >>> with open('setup.sh', 'wb') as f:
2147 2147 ... f.write(u'''
2148 2148 ... echo a > text
2149 2149 ... hg add text
2150 2150 ... hg --encoding utf-8 commit -u '\u30A2' -m none
2151 2151 ... echo b > text
2152 2152 ... hg --encoding utf-8 commit -u '\u30C2' -m none
2153 2153 ... echo c > text
2154 2154 ... hg --encoding utf-8 commit -u none -m '\u30A2'
2155 2155 ... echo d > text
2156 2156 ... hg --encoding utf-8 commit -u none -m '\u30C2'
2157 2157 ... '''.encode('utf-8')) and None
2158 2158 $ sh < setup.sh
2159 2159
2160 #if no-rhg
2161
2160 2162 test in problematic encoding
2161 2163 >>> with open('test.sh', 'wb') as f:
2162 2164 ... f.write(u'''
2163 2165 ... hg --encoding cp932 log --template '{rev}\\n' -u '\u30A2'
2164 2166 ... echo ====
2165 2167 ... hg --encoding cp932 log --template '{rev}\\n' -u '\u30C2'
2166 2168 ... echo ====
2167 2169 ... hg --encoding cp932 log --template '{rev}\\n' -k '\u30A2'
2168 2170 ... echo ====
2169 2171 ... hg --encoding cp932 log --template '{rev}\\n' -k '\u30C2'
2170 2172 ... '''.encode('cp932')) and None
2171 2173 $ sh < test.sh
2172 2174 0
2173 2175 ====
2174 2176 1
2175 2177 ====
2176 2178 2
2177 2179 0
2178 2180 ====
2179 2181 3
2180 2182 1
2181 2183
2184 #endif
2185
2182 2186 $ cd ..
2183 2187
2184 2188 test hg log on non-existent files and on directories
2185 2189 $ hg init issue1340
2186 2190 $ cd issue1340
2187 2191 $ mkdir d1; mkdir D2; mkdir D3.i; mkdir d4.hg; mkdir d5.d; mkdir .d6
2188 2192 $ echo 1 > d1/f1
2189 2193 $ echo 1 > D2/f1
2190 2194 $ echo 1 > D3.i/f1
2191 2195 $ echo 1 > d4.hg/f1
2192 2196 $ echo 1 > d5.d/f1
2193 2197 $ echo 1 > .d6/f1
2194 2198 $ hg -q add .
2195 2199 $ hg commit -m "a bunch of weird directories"
2196 2200 $ hg log -l1 d1/f1 | grep changeset
2197 2201 changeset: 0:65624cd9070a
2198 2202 $ hg log -l1 f1
2199 2203 $ hg log -l1 . | grep changeset
2200 2204 changeset: 0:65624cd9070a
2201 2205 $ hg log -l1 ./ | grep changeset
2202 2206 changeset: 0:65624cd9070a
2203 2207 $ hg log -l1 d1 | grep changeset
2204 2208 changeset: 0:65624cd9070a
2205 2209 $ hg log -l1 D2 | grep changeset
2206 2210 changeset: 0:65624cd9070a
2207 2211 $ hg log -l1 D2/f1 | grep changeset
2208 2212 changeset: 0:65624cd9070a
2209 2213 $ hg log -l1 D3.i | grep changeset
2210 2214 changeset: 0:65624cd9070a
2211 2215 $ hg log -l1 D3.i/f1 | grep changeset
2212 2216 changeset: 0:65624cd9070a
2213 2217 $ hg log -l1 d4.hg | grep changeset
2214 2218 changeset: 0:65624cd9070a
2215 2219 $ hg log -l1 d4.hg/f1 | grep changeset
2216 2220 changeset: 0:65624cd9070a
2217 2221 $ hg log -l1 d5.d | grep changeset
2218 2222 changeset: 0:65624cd9070a
2219 2223 $ hg log -l1 d5.d/f1 | grep changeset
2220 2224 changeset: 0:65624cd9070a
2221 2225 $ hg log -l1 .d6 | grep changeset
2222 2226 changeset: 0:65624cd9070a
2223 2227 $ hg log -l1 .d6/f1 | grep changeset
2224 2228 changeset: 0:65624cd9070a
2225 2229
2226 2230 issue3772: hg log -r :null showing revision 0 as well
2227 2231
2228 2232 $ hg log -r :null
2229 2233 changeset: 0:65624cd9070a
2230 2234 tag: tip
2231 2235 user: test
2232 2236 date: Thu Jan 01 00:00:00 1970 +0000
2233 2237 summary: a bunch of weird directories
2234 2238
2235 2239 changeset: -1:000000000000
2236 2240 user:
2237 2241 date: Thu Jan 01 00:00:00 1970 +0000
2238 2242
2239 2243 $ hg log -r null:null
2240 2244 changeset: -1:000000000000
2241 2245 user:
2242 2246 date: Thu Jan 01 00:00:00 1970 +0000
2243 2247
2244 2248 working-directory revision requires special treatment
2245 2249
2246 2250 clean:
2247 2251
2248 2252 $ hg log -r 'wdir()' --debug
2249 2253 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2250 2254 phase: draft
2251 2255 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
2252 2256 parent: -1:0000000000000000000000000000000000000000
2253 2257 manifest: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2254 2258 user: test
2255 2259 date: [A-Za-z0-9:+ ]+ (re)
2256 2260 extra: branch=default
2257 2261
2258 2262 $ hg log -r 'wdir()' -p --stat
2259 2263 changeset: 2147483647:ffffffffffff
2260 2264 parent: 0:65624cd9070a
2261 2265 user: test
2262 2266 date: [A-Za-z0-9:+ ]+ (re)
2263 2267
2264 2268
2265 2269
2266 2270
2267 2271 dirty:
2268 2272
2269 2273 $ echo 2 >> d1/f1
2270 2274 $ echo 2 > d1/f2
2271 2275 $ hg add d1/f2
2272 2276 $ hg remove .d6/f1
2273 2277 $ hg status
2274 2278 M d1/f1
2275 2279 A d1/f2
2276 2280 R .d6/f1
2277 2281
2278 2282 $ hg log -r 'wdir()'
2279 2283 changeset: 2147483647:ffffffffffff
2280 2284 parent: 0:65624cd9070a
2281 2285 user: test
2282 2286 date: [A-Za-z0-9:+ ]+ (re)
2283 2287
2284 2288 $ hg log -r 'wdir()' -q
2285 2289 2147483647:ffffffffffff
2286 2290
2287 2291 $ hg log -r 'wdir()' --debug
2288 2292 changeset: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2289 2293 phase: draft
2290 2294 parent: 0:65624cd9070a035fa7191a54f2b8af39f16b0c08
2291 2295 parent: -1:0000000000000000000000000000000000000000
2292 2296 manifest: 2147483647:ffffffffffffffffffffffffffffffffffffffff
2293 2297 user: test
2294 2298 date: [A-Za-z0-9:+ ]+ (re)
2295 2299 files: d1/f1
2296 2300 files+: d1/f2
2297 2301 files-: .d6/f1
2298 2302 extra: branch=default
2299 2303
2300 2304 $ hg log -r 'wdir()' -p --stat --git
2301 2305 changeset: 2147483647:ffffffffffff
2302 2306 parent: 0:65624cd9070a
2303 2307 user: test
2304 2308 date: [A-Za-z0-9:+ ]+ (re)
2305 2309
2306 2310 .d6/f1 | 1 -
2307 2311 d1/f1 | 1 +
2308 2312 d1/f2 | 1 +
2309 2313 3 files changed, 2 insertions(+), 1 deletions(-)
2310 2314
2311 2315 diff --git a/.d6/f1 b/.d6/f1
2312 2316 deleted file mode 100644
2313 2317 --- a/.d6/f1
2314 2318 +++ /dev/null
2315 2319 @@ -1,1 +0,0 @@
2316 2320 -1
2317 2321 diff --git a/d1/f1 b/d1/f1
2318 2322 --- a/d1/f1
2319 2323 +++ b/d1/f1
2320 2324 @@ -1,1 +1,2 @@
2321 2325 1
2322 2326 +2
2323 2327 diff --git a/d1/f2 b/d1/f2
2324 2328 new file mode 100644
2325 2329 --- /dev/null
2326 2330 +++ b/d1/f2
2327 2331 @@ -0,0 +1,1 @@
2328 2332 +2
2329 2333
2330 2334 $ hg log -r 'wdir()' -Tjson
2331 2335 [
2332 2336 {
2333 2337 "bookmarks": [],
2334 2338 "branch": "default",
2335 2339 "date": [*, 0], (glob)
2336 2340 "desc": "",
2337 2341 "node": "ffffffffffffffffffffffffffffffffffffffff",
2338 2342 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"],
2339 2343 "phase": "draft",
2340 2344 "rev": 2147483647,
2341 2345 "tags": [],
2342 2346 "user": "test"
2343 2347 }
2344 2348 ]
2345 2349
2346 2350 $ hg log -r 'wdir()' -Tjson -q
2347 2351 [
2348 2352 {
2349 2353 "node": "ffffffffffffffffffffffffffffffffffffffff",
2350 2354 "rev": 2147483647
2351 2355 }
2352 2356 ]
2353 2357
2354 2358 $ hg log -r 'wdir()' -Tjson --debug
2355 2359 [
2356 2360 {
2357 2361 "added": ["d1/f2"],
2358 2362 "bookmarks": [],
2359 2363 "branch": "default",
2360 2364 "date": [*, 0], (glob)
2361 2365 "desc": "",
2362 2366 "extra": {"branch": "default"},
2363 2367 "manifest": "ffffffffffffffffffffffffffffffffffffffff",
2364 2368 "modified": ["d1/f1"],
2365 2369 "node": "ffffffffffffffffffffffffffffffffffffffff",
2366 2370 "parents": ["65624cd9070a035fa7191a54f2b8af39f16b0c08"],
2367 2371 "phase": "draft",
2368 2372 "removed": [".d6/f1"],
2369 2373 "rev": 2147483647,
2370 2374 "tags": [],
2371 2375 "user": "test"
2372 2376 }
2373 2377 ]
2374 2378
2375 2379 follow files from wdir
2376 2380
2377 2381 $ hg cp d1/f1 f1-copy
2378 2382 $ hg stat --all
2379 2383 M d1/f1
2380 2384 A d1/f2
2381 2385 A f1-copy
2382 2386 d1/f1
2383 2387 R .d6/f1
2384 2388 C D2/f1
2385 2389 C D3.i/f1
2386 2390 C d4.hg/f1
2387 2391 C d5.d/f1
2388 2392
2389 2393 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d5.d/f1
2390 2394 == 2147483647 ==
2391 2395
2392 2396 == 0 ==
2393 2397 d5.d/f1 | 1 +
2394 2398 1 files changed, 1 insertions(+), 0 deletions(-)
2395 2399
2396 2400
2397 2401 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d1/f1
2398 2402 == 2147483647 ==
2399 2403 d1/f1 | 1 +
2400 2404 1 files changed, 1 insertions(+), 0 deletions(-)
2401 2405
2402 2406 == 0 ==
2403 2407 d1/f1 | 1 +
2404 2408 1 files changed, 1 insertions(+), 0 deletions(-)
2405 2409
2406 2410
2407 2411 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat d1/f2
2408 2412 == 2147483647 ==
2409 2413 d1/f2 | 1 +
2410 2414 1 files changed, 1 insertions(+), 0 deletions(-)
2411 2415
2412 2416
2413 2417 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat f1-copy
2414 2418 == 2147483647 ==
2415 2419 f1-copy | 1 +
2416 2420 1 files changed, 1 insertions(+), 0 deletions(-)
2417 2421
2418 2422 == 0 ==
2419 2423 d1/f1 | 1 +
2420 2424 1 files changed, 1 insertions(+), 0 deletions(-)
2421 2425
2422 2426
2423 2427 $ hg log -T '== {rev} ==\n' -fr'wdir()' --git --stat notfound
2424 2428 abort: cannot follow file not in any of the specified revisions: "notfound"
2425 2429 [20]
2426 2430
2427 2431 follow files from wdir and non-wdir revision:
2428 2432
2429 2433 $ hg log -T '{rev}\n' -fr'wdir()+.' f1-copy
2430 2434 f1-copy: no such file in rev 65624cd9070a
2431 2435 2147483647
2432 2436 0
2433 2437
2434 2438 follow added/removed files from wdir parent
2435 2439
2436 2440 $ hg log -T '{rev}\n' -f d1/f2
2437 2441 abort: cannot follow nonexistent file: "d1/f2"
2438 2442 [20]
2439 2443
2440 2444 $ hg log -T '{rev}\n' -f f1-copy
2441 2445 abort: cannot follow nonexistent file: "f1-copy"
2442 2446 [20]
2443 2447
2444 2448 $ hg log -T '{rev}\n' -f .d6/f1
2445 2449 abort: cannot follow file not in parent revision: ".d6/f1"
2446 2450 [20]
2447 2451
2448 2452 $ hg revert -aqC
2449 2453
2450 2454 Check that adding an arbitrary name shows up in log automatically
2451 2455
2452 2456 $ cat > ../names.py <<EOF
2453 2457 > """A small extension to test adding arbitrary names to a repo"""
2454 2458 > from mercurial import namespaces
2455 2459 >
2456 2460 > def reposetup(ui, repo):
2457 2461 > if not repo.local():
2458 2462 > return
2459 2463 > foo = {b'foo': repo[0].node()}
2460 2464 > names = lambda r: foo.keys()
2461 2465 > namemap = lambda r, name: foo.get(name)
2462 2466 > nodemap = lambda r, node: [name for name, n in foo.items()
2463 2467 > if n == node]
2464 2468 > ns = namespaces.namespace(
2465 2469 > b"bars", templatename=b"bar", logname=b"barlog",
2466 2470 > colorname=b"barcolor", listnames=names, namemap=namemap,
2467 2471 > nodemap=nodemap)
2468 2472 >
2469 2473 > repo.names.addnamespace(ns)
2470 2474 > EOF
2471 2475
2472 2476 $ hg --config extensions.names=../names.py log -r 0
2473 2477 changeset: 0:65624cd9070a
2474 2478 tag: tip
2475 2479 barlog: foo
2476 2480 user: test
2477 2481 date: Thu Jan 01 00:00:00 1970 +0000
2478 2482 summary: a bunch of weird directories
2479 2483
2480 2484 $ hg --config extensions.names=../names.py \
2481 2485 > --config extensions.color= --config color.log.barcolor=red \
2482 2486 > --color=always log -r 0
2483 2487 \x1b[0;33mchangeset: 0:65624cd9070a\x1b[0m (esc)
2484 2488 tag: tip
2485 2489 \x1b[0;31mbarlog: foo\x1b[0m (esc)
2486 2490 user: test
2487 2491 date: Thu Jan 01 00:00:00 1970 +0000
2488 2492 summary: a bunch of weird directories
2489 2493
2490 2494 $ hg --config extensions.names=../names.py log -r 0 --template '{bars}\n'
2491 2495 foo
2492 2496
2493 2497 Templater parse errors:
2494 2498
2495 2499 simple error
2496 2500 $ hg log -r . -T '{shortest(node}'
2497 2501 hg: parse error at 14: unexpected token: end
2498 2502 ({shortest(node}
2499 2503 ^ here)
2500 2504 [10]
2501 2505
2502 2506 multi-line template with error
2503 2507 $ hg log -r . -T 'line 1
2504 2508 > line2
2505 2509 > {shortest(node}
2506 2510 > line4\nline5'
2507 2511 hg: parse error at 27: unexpected token: end
2508 2512 (line 1\nline2\n{shortest(node}\nline4\nline5
2509 2513 ^ here)
2510 2514 [10]
2511 2515
2512 2516 $ cd ..
2513 2517
2514 2518 New namespace is registered per repo instance, but the template keyword
2515 2519 is global. So we shouldn't expect the namespace always exists. Using
2516 2520 ssh:// makes sure a bundle repository is created from scratch. (issue6301)
2517 2521
2518 2522 $ hg clone -qr0 "ssh://user@dummy/`pwd`/a" a-clone
2519 2523 $ hg incoming --config extensions.names=names.py -R a-clone \
2520 2524 > -T '{bars}\n' -l1
2521 2525 comparing with ssh://user@dummy/$TESTTMP/a
2522 2526 searching for changes
2523 2527
2524 2528
2525 2529 hg log -f dir across branches
2526 2530
2527 2531 $ hg init acrossbranches
2528 2532 $ cd acrossbranches
2529 2533 $ mkdir d
2530 2534 $ echo a > d/a && hg ci -Aqm a
2531 2535 $ echo b > d/a && hg ci -Aqm b
2532 2536 $ hg up -q 0
2533 2537 $ echo b > d/a && hg ci -Aqm c
2534 2538 $ hg log -f d -T '{desc}' -G
2535 2539 @ c
2536 2540 |
2537 2541 o a
2538 2542
2539 2543 Ensure that largefiles doesn't interfere with following a normal file
2540 2544 $ hg --config extensions.largefiles= log -f d -T '{desc}' -G
2541 2545 The fsmonitor extension is incompatible with the largefiles extension and has been disabled. (fsmonitor !)
2542 2546 @ c
2543 2547 |
2544 2548 o a
2545 2549
2546 2550 $ hg log -f d/a -T '{desc}' -G
2547 2551 @ c
2548 2552 |
2549 2553 o a
2550 2554
2551 2555 $ cd ..
2552 2556
2553 2557 hg log -f with linkrev pointing to another branch
2554 2558 -------------------------------------------------
2555 2559
2556 2560 create history with a filerev whose linkrev points to another branch
2557 2561
2558 2562 $ hg init branchedlinkrev
2559 2563 $ cd branchedlinkrev
2560 2564 $ echo 1 > a
2561 2565 $ hg commit -Am 'content1'
2562 2566 adding a
2563 2567 $ echo 2 > a
2564 2568 $ hg commit -m 'content2'
2565 2569 $ hg up --rev 'desc(content1)'
2566 2570 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2567 2571 $ echo unrelated > unrelated
2568 2572 $ hg commit -Am 'unrelated'
2569 2573 adding unrelated
2570 2574 created new head
2571 2575 $ hg graft -r 'desc(content2)'
2572 2576 grafting 1:2294ae80ad84 "content2"
2573 2577 $ echo 3 > a
2574 2578 $ hg commit -m 'content3'
2575 2579 $ hg log -G
2576 2580 @ changeset: 4:50b9b36e9c5d
2577 2581 | tag: tip
2578 2582 | user: test
2579 2583 | date: Thu Jan 01 00:00:00 1970 +0000
2580 2584 | summary: content3
2581 2585 |
2582 2586 o changeset: 3:15b2327059e5
2583 2587 | user: test
2584 2588 | date: Thu Jan 01 00:00:00 1970 +0000
2585 2589 | summary: content2
2586 2590 |
2587 2591 o changeset: 2:2029acd1168c
2588 2592 | parent: 0:ae0a3c9f9e95
2589 2593 | user: test
2590 2594 | date: Thu Jan 01 00:00:00 1970 +0000
2591 2595 | summary: unrelated
2592 2596 |
2593 2597 | o changeset: 1:2294ae80ad84
2594 2598 |/ user: test
2595 2599 | date: Thu Jan 01 00:00:00 1970 +0000
2596 2600 | summary: content2
2597 2601 |
2598 2602 o changeset: 0:ae0a3c9f9e95
2599 2603 user: test
2600 2604 date: Thu Jan 01 00:00:00 1970 +0000
2601 2605 summary: content1
2602 2606
2603 2607
2604 2608 log -f on the file should list the graft result.
2605 2609
2606 2610 $ hg log -Gf a
2607 2611 @ changeset: 4:50b9b36e9c5d
2608 2612 | tag: tip
2609 2613 | user: test
2610 2614 | date: Thu Jan 01 00:00:00 1970 +0000
2611 2615 | summary: content3
2612 2616 |
2613 2617 o changeset: 3:15b2327059e5
2614 2618 : user: test
2615 2619 : date: Thu Jan 01 00:00:00 1970 +0000
2616 2620 : summary: content2
2617 2621 :
2618 2622 o changeset: 0:ae0a3c9f9e95
2619 2623 user: test
2620 2624 date: Thu Jan 01 00:00:00 1970 +0000
2621 2625 summary: content1
2622 2626
2623 2627
2624 2628 plain log lists the original version
2625 2629 (XXX we should probably list both)
2626 2630
2627 2631 $ hg log -G a
2628 2632 @ changeset: 4:50b9b36e9c5d
2629 2633 : tag: tip
2630 2634 : user: test
2631 2635 : date: Thu Jan 01 00:00:00 1970 +0000
2632 2636 : summary: content3
2633 2637 :
2634 2638 : o changeset: 1:2294ae80ad84
2635 2639 :/ user: test
2636 2640 : date: Thu Jan 01 00:00:00 1970 +0000
2637 2641 : summary: content2
2638 2642 :
2639 2643 o changeset: 0:ae0a3c9f9e95
2640 2644 user: test
2641 2645 date: Thu Jan 01 00:00:00 1970 +0000
2642 2646 summary: content1
2643 2647
2644 2648
2645 2649 hg log -f from the grafted changeset
2646 2650 (The bootstrap should properly take the topology in account)
2647 2651
2648 2652 $ hg up 'desc(content3)^'
2649 2653 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
2650 2654 $ hg log -Gf a
2651 2655 @ changeset: 3:15b2327059e5
2652 2656 : user: test
2653 2657 : date: Thu Jan 01 00:00:00 1970 +0000
2654 2658 : summary: content2
2655 2659 :
2656 2660 o changeset: 0:ae0a3c9f9e95
2657 2661 user: test
2658 2662 date: Thu Jan 01 00:00:00 1970 +0000
2659 2663 summary: content1
2660 2664
2661 2665
2662 2666 Test that we use the first non-hidden changeset in that case.
2663 2667
2664 2668 (hide the changeset)
2665 2669
2666 2670 $ hg log -T '{node}\n' -r 1
2667 2671 2294ae80ad8447bc78383182eeac50cb049df623
2668 2672 $ hg debugobsolete 2294ae80ad8447bc78383182eeac50cb049df623
2669 2673 1 new obsolescence markers
2670 2674 obsoleted 1 changesets
2671 2675 $ hg log -G
2672 2676 o changeset: 4:50b9b36e9c5d
2673 2677 | tag: tip
2674 2678 | user: test
2675 2679 | date: Thu Jan 01 00:00:00 1970 +0000
2676 2680 | summary: content3
2677 2681 |
2678 2682 @ changeset: 3:15b2327059e5
2679 2683 | user: test
2680 2684 | date: Thu Jan 01 00:00:00 1970 +0000
2681 2685 | summary: content2
2682 2686 |
2683 2687 o changeset: 2:2029acd1168c
2684 2688 | parent: 0:ae0a3c9f9e95
2685 2689 | user: test
2686 2690 | date: Thu Jan 01 00:00:00 1970 +0000
2687 2691 | summary: unrelated
2688 2692 |
2689 2693 o changeset: 0:ae0a3c9f9e95
2690 2694 user: test
2691 2695 date: Thu Jan 01 00:00:00 1970 +0000
2692 2696 summary: content1
2693 2697
2694 2698
2695 2699 Check that log on the file does not drop the file revision.
2696 2700
2697 2701 $ hg log -G a
2698 2702 o changeset: 4:50b9b36e9c5d
2699 2703 | tag: tip
2700 2704 | user: test
2701 2705 | date: Thu Jan 01 00:00:00 1970 +0000
2702 2706 | summary: content3
2703 2707 |
2704 2708 @ changeset: 3:15b2327059e5
2705 2709 : user: test
2706 2710 : date: Thu Jan 01 00:00:00 1970 +0000
2707 2711 : summary: content2
2708 2712 :
2709 2713 o changeset: 0:ae0a3c9f9e95
2710 2714 user: test
2711 2715 date: Thu Jan 01 00:00:00 1970 +0000
2712 2716 summary: content1
2713 2717
2714 2718
2715 2719 Even when a head revision is linkrev-shadowed.
2716 2720
2717 2721 $ hg log -T '{node}\n' -r 4
2718 2722 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2719 2723 $ hg debugobsolete 50b9b36e9c5df2c6fc6dcefa8ad0da929e84aed2
2720 2724 1 new obsolescence markers
2721 2725 obsoleted 1 changesets
2722 2726 $ hg log -G a
2723 2727 @ changeset: 3:15b2327059e5
2724 2728 : tag: tip
2725 2729 : user: test
2726 2730 : date: Thu Jan 01 00:00:00 1970 +0000
2727 2731 : summary: content2
2728 2732 :
2729 2733 o changeset: 0:ae0a3c9f9e95
2730 2734 user: test
2731 2735 date: Thu Jan 01 00:00:00 1970 +0000
2732 2736 summary: content1
2733 2737
2734 2738
2735 2739 $ cd ..
2736 2740
2737 2741 Even when the file revision is missing from some head:
2738 2742
2739 2743 $ hg init issue4490
2740 2744 $ cd issue4490
2741 2745 $ echo '[experimental]' >> .hg/hgrc
2742 2746 $ echo 'evolution.createmarkers=True' >> .hg/hgrc
2743 2747 $ echo a > a
2744 2748 $ hg ci -Am0
2745 2749 adding a
2746 2750 $ echo b > b
2747 2751 $ hg ci -Am1
2748 2752 adding b
2749 2753 $ echo B > b
2750 2754 $ hg ci --amend -m 1
2751 2755 $ hg up 0
2752 2756 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
2753 2757 $ echo c > c
2754 2758 $ hg ci -Am2
2755 2759 adding c
2756 2760 created new head
2757 2761 $ hg up 'head() and not .'
2758 2762 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
2759 2763 $ hg log -G
2760 2764 o changeset: 3:db815d6d32e6
2761 2765 | tag: tip
2762 2766 | parent: 0:f7b1eb17ad24
2763 2767 | user: test
2764 2768 | date: Thu Jan 01 00:00:00 1970 +0000
2765 2769 | summary: 2
2766 2770 |
2767 2771 | @ changeset: 2:9bc8ce7f9356
2768 2772 |/ parent: 0:f7b1eb17ad24
2769 2773 | user: test
2770 2774 | date: Thu Jan 01 00:00:00 1970 +0000
2771 2775 | summary: 1
2772 2776 |
2773 2777 o changeset: 0:f7b1eb17ad24
2774 2778 user: test
2775 2779 date: Thu Jan 01 00:00:00 1970 +0000
2776 2780 summary: 0
2777 2781
2778 2782 $ hg log -f -G b
2779 2783 @ changeset: 2:9bc8ce7f9356
2780 2784 | parent: 0:f7b1eb17ad24
2781 2785 ~ user: test
2782 2786 date: Thu Jan 01 00:00:00 1970 +0000
2783 2787 summary: 1
2784 2788
2785 2789 $ hg log -G b
2786 2790 @ changeset: 2:9bc8ce7f9356
2787 2791 | parent: 0:f7b1eb17ad24
2788 2792 ~ user: test
2789 2793 date: Thu Jan 01 00:00:00 1970 +0000
2790 2794 summary: 1
2791 2795
2792 2796 $ cd ..
2793 2797
2794 2798 Check proper report when the manifest changes but not the file issue4499
2795 2799 ------------------------------------------------------------------------
2796 2800
2797 2801 $ hg init issue4499
2798 2802 $ cd issue4499
2799 2803 $ for f in A B C D F E G H I J K L M N O P Q R S T U; do
2800 2804 > echo 1 > $f;
2801 2805 > hg add $f;
2802 2806 > done
2803 2807 $ hg commit -m 'A1B1C1'
2804 2808 $ echo 2 > A
2805 2809 $ echo 2 > B
2806 2810 $ echo 2 > C
2807 2811 $ hg commit -m 'A2B2C2'
2808 2812 $ hg up 0
2809 2813 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
2810 2814 $ echo 3 > A
2811 2815 $ echo 2 > B
2812 2816 $ echo 2 > C
2813 2817 $ hg commit -m 'A3B2C2'
2814 2818 created new head
2815 2819
2816 2820 $ hg log -G
2817 2821 @ changeset: 2:fe5fc3d0eb17
2818 2822 | tag: tip
2819 2823 | parent: 0:abf4f0e38563
2820 2824 | user: test
2821 2825 | date: Thu Jan 01 00:00:00 1970 +0000
2822 2826 | summary: A3B2C2
2823 2827 |
2824 2828 | o changeset: 1:07dcc6b312c0
2825 2829 |/ user: test
2826 2830 | date: Thu Jan 01 00:00:00 1970 +0000
2827 2831 | summary: A2B2C2
2828 2832 |
2829 2833 o changeset: 0:abf4f0e38563
2830 2834 user: test
2831 2835 date: Thu Jan 01 00:00:00 1970 +0000
2832 2836 summary: A1B1C1
2833 2837
2834 2838
2835 2839 Log -f on B should reports current changesets
2836 2840
2837 2841 $ hg log -fG B
2838 2842 @ changeset: 2:fe5fc3d0eb17
2839 2843 | tag: tip
2840 2844 | parent: 0:abf4f0e38563
2841 2845 | user: test
2842 2846 | date: Thu Jan 01 00:00:00 1970 +0000
2843 2847 | summary: A3B2C2
2844 2848 |
2845 2849 o changeset: 0:abf4f0e38563
2846 2850 user: test
2847 2851 date: Thu Jan 01 00:00:00 1970 +0000
2848 2852 summary: A1B1C1
2849 2853
2850 2854 $ cd ..
2851 2855
2852 2856 --- going to test line wrap fix on using both --stat and -G (issue5800)
2853 2857 $ hg init issue5800
2854 2858 $ cd issue5800
2855 2859 $ touch a
2856 2860 $ hg ci -Am 'add a'
2857 2861 adding a
2858 2862 ---- now we are going to add 300 lines to a
2859 2863 $ for i in `$TESTDIR/seq.py 1 300`; do echo $i >> a; done
2860 2864 $ hg ci -m 'modify a'
2861 2865 $ hg log
2862 2866 changeset: 1:a98683e6a834
2863 2867 tag: tip
2864 2868 user: test
2865 2869 date: Thu Jan 01 00:00:00 1970 +0000
2866 2870 summary: modify a
2867 2871
2868 2872 changeset: 0:ac82d8b1f7c4
2869 2873 user: test
2870 2874 date: Thu Jan 01 00:00:00 1970 +0000
2871 2875 summary: add a
2872 2876
2873 2877 ---- now visualise the changes we made without template
2874 2878 $ hg log -l1 -r a98683e6a834 --stat -G
2875 2879 @ changeset: 1:a98683e6a834
2876 2880 | tag: tip
2877 2881 ~ user: test
2878 2882 date: Thu Jan 01 00:00:00 1970 +0000
2879 2883 summary: modify a
2880 2884
2881 2885 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2882 2886 1 files changed, 300 insertions(+), 0 deletions(-)
2883 2887
2884 2888 ---- with template
2885 2889 $ hg log -l1 -r a98683e6a834 --stat -G -T bisect
2886 2890 @ changeset: 1:a98683e6a834
2887 2891 | bisect:
2888 2892 ~ tag: tip
2889 2893 user: test
2890 2894 date: Thu Jan 01 00:00:00 1970 +0000
2891 2895 summary: modify a
2892 2896
2893 2897 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2894 2898 1 files changed, 300 insertions(+), 0 deletions(-)
2895 2899
2896 2900 $ hg log -l1 -r a98683e6a834 --stat -G -T changelog
2897 2901 1970-01-01 test <test>
2898 2902
2899 2903 @ * a:
2900 2904 | modify a
2901 2905 ~ [a98683e6a834] [tip]
2902 2906
2903 2907 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2904 2908 1 files changed, 300 insertions(+), 0 deletions(-)
2905 2909
2906 2910 $ hg log -l1 -r a98683e6a834 --stat -G -T compact
2907 2911 @ 1[tip] a98683e6a834 1970-01-01 00:00 +0000 test
2908 2912 | modify a
2909 2913 ~
2910 2914 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2911 2915 1 files changed, 300 insertions(+), 0 deletions(-)
2912 2916
2913 2917 $ hg log -l1 -r a98683e6a834 --stat -G -T default
2914 2918 @ changeset: 1:a98683e6a834
2915 2919 | tag: tip
2916 2920 ~ user: test
2917 2921 date: Thu Jan 01 00:00:00 1970 +0000
2918 2922 summary: modify a
2919 2923
2920 2924 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2921 2925 1 files changed, 300 insertions(+), 0 deletions(-)
2922 2926
2923 2927 $ hg log -l1 -r a98683e6a834 --stat -G -T phases
2924 2928 @ changeset: 1:a98683e6a834
2925 2929 | tag: tip
2926 2930 ~ phase: draft
2927 2931 user: test
2928 2932 date: Thu Jan 01 00:00:00 1970 +0000
2929 2933 summary: modify a
2930 2934
2931 2935 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2932 2936 1 files changed, 300 insertions(+), 0 deletions(-)
2933 2937
2934 2938 $ hg log -l1 -r a98683e6a834 --stat -G -T show
2935 2939 @ changeset: 1:a98683e6a834
2936 2940 | tag: tip
2937 2941 ~ user: test
2938 2942 date: Thu Jan 01 00:00:00 1970 +0000
2939 2943 summary: modify a
2940 2944
2941 2945 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2942 2946 1 files changed, 300 insertions(+), 0 deletions(-)
2943 2947
2944 2948 $ hg log -l1 -r a98683e6a834 --stat -G -T status
2945 2949 @ changeset: 1:a98683e6a834
2946 2950 | tag: tip
2947 2951 ~ user: test
2948 2952 date: Thu Jan 01 00:00:00 1970 +0000
2949 2953 summary: modify a
2950 2954 files:
2951 2955 M a
2952 2956
2953 2957 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2954 2958 1 files changed, 300 insertions(+), 0 deletions(-)
2955 2959
2956 2960 $ hg log -l1 -r a98683e6a834 --stat -G -T xml
2957 2961 <?xml version="1.0"?>
2958 2962 <log>
2959 2963 @ <logentry revision="1" node="a98683e6a8340830a7683909768b62871e84bc9d">
2960 2964 | <tag>tip</tag>
2961 2965 ~ <author email="test">test</author>
2962 2966 <date>1970-01-01T00:00:00+00:00</date>
2963 2967 <msg xml:space="preserve">modify a</msg>
2964 2968 </logentry>
2965 2969 a | 300 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2966 2970 1 files changed, 300 insertions(+), 0 deletions(-)
2967 2971
2968 2972 </log>
2969 2973
2970 2974 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now