##// END OF EJS Templates
rhg: $HG_PENDING is not supported...
Simon Sapin -
r49159:5b986503 default
parent child Browse files
Show More
@@ -1,618 +1,630 b''
1 extern crate log;
1 extern crate log;
2 use crate::error::CommandError;
2 use crate::ui::Ui;
3 use crate::ui::Ui;
3 use clap::App;
4 use clap::App;
4 use clap::AppSettings;
5 use clap::AppSettings;
5 use clap::Arg;
6 use clap::Arg;
6 use clap::ArgMatches;
7 use clap::ArgMatches;
7 use format_bytes::{format_bytes, join};
8 use format_bytes::{format_bytes, join};
8 use hg::config::{Config, ConfigSource};
9 use hg::config::{Config, ConfigSource};
9 use hg::exit_codes;
10 use hg::exit_codes;
10 use hg::repo::{Repo, RepoError};
11 use hg::repo::{Repo, RepoError};
11 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
12 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
12 use hg::utils::SliceExt;
13 use hg::utils::SliceExt;
13 use std::ffi::OsString;
14 use std::ffi::OsString;
14 use std::path::PathBuf;
15 use std::path::PathBuf;
15 use std::process::Command;
16 use std::process::Command;
16
17
17 mod blackbox;
18 mod blackbox;
18 mod error;
19 mod error;
19 mod ui;
20 mod ui;
20 pub mod utils {
21 pub mod utils {
21 pub mod path_utils;
22 pub mod path_utils;
22 }
23 }
23 use error::CommandError;
24
24
25 fn main_with_result(
25 fn main_with_result(
26 process_start_time: &blackbox::ProcessStartTime,
26 process_start_time: &blackbox::ProcessStartTime,
27 ui: &ui::Ui,
27 ui: &ui::Ui,
28 repo: Result<&Repo, &NoRepoInCwdError>,
28 repo: Result<&Repo, &NoRepoInCwdError>,
29 config: &Config,
29 config: &Config,
30 ) -> Result<(), CommandError> {
30 ) -> Result<(), CommandError> {
31 check_extensions(config)?;
31 check_unsupported(config)?;
32
32
33 let app = App::new("rhg")
33 let app = App::new("rhg")
34 .global_setting(AppSettings::AllowInvalidUtf8)
34 .global_setting(AppSettings::AllowInvalidUtf8)
35 .global_setting(AppSettings::DisableVersion)
35 .global_setting(AppSettings::DisableVersion)
36 .setting(AppSettings::SubcommandRequired)
36 .setting(AppSettings::SubcommandRequired)
37 .setting(AppSettings::VersionlessSubcommands)
37 .setting(AppSettings::VersionlessSubcommands)
38 .arg(
38 .arg(
39 Arg::with_name("repository")
39 Arg::with_name("repository")
40 .help("repository root directory")
40 .help("repository root directory")
41 .short("-R")
41 .short("-R")
42 .long("--repository")
42 .long("--repository")
43 .value_name("REPO")
43 .value_name("REPO")
44 .takes_value(true)
44 .takes_value(true)
45 // Both ok: `hg -R ./foo log` or `hg log -R ./foo`
45 // Both ok: `hg -R ./foo log` or `hg log -R ./foo`
46 .global(true),
46 .global(true),
47 )
47 )
48 .arg(
48 .arg(
49 Arg::with_name("config")
49 Arg::with_name("config")
50 .help("set/override config option (use 'section.name=value')")
50 .help("set/override config option (use 'section.name=value')")
51 .long("--config")
51 .long("--config")
52 .value_name("CONFIG")
52 .value_name("CONFIG")
53 .takes_value(true)
53 .takes_value(true)
54 .global(true)
54 .global(true)
55 // Ok: `--config section.key1=val --config section.key2=val2`
55 // Ok: `--config section.key1=val --config section.key2=val2`
56 .multiple(true)
56 .multiple(true)
57 // Not ok: `--config section.key1=val section.key2=val2`
57 // Not ok: `--config section.key1=val section.key2=val2`
58 .number_of_values(1),
58 .number_of_values(1),
59 )
59 )
60 .arg(
60 .arg(
61 Arg::with_name("cwd")
61 Arg::with_name("cwd")
62 .help("change working directory")
62 .help("change working directory")
63 .long("--cwd")
63 .long("--cwd")
64 .value_name("DIR")
64 .value_name("DIR")
65 .takes_value(true)
65 .takes_value(true)
66 .global(true),
66 .global(true),
67 )
67 )
68 .version("0.0.1");
68 .version("0.0.1");
69 let app = add_subcommand_args(app);
69 let app = add_subcommand_args(app);
70
70
71 let matches = app.clone().get_matches_safe()?;
71 let matches = app.clone().get_matches_safe()?;
72
72
73 let (subcommand_name, subcommand_matches) = matches.subcommand();
73 let (subcommand_name, subcommand_matches) = matches.subcommand();
74
74
75 // Mercurial allows users to define "defaults" for commands, fallback
75 // Mercurial allows users to define "defaults" for commands, fallback
76 // if a default is detected for the current command
76 // if a default is detected for the current command
77 let defaults = config.get_str(b"defaults", subcommand_name.as_bytes());
77 let defaults = config.get_str(b"defaults", subcommand_name.as_bytes());
78 if defaults?.is_some() {
78 if defaults?.is_some() {
79 let msg = "`defaults` config set";
79 let msg = "`defaults` config set";
80 return Err(CommandError::unsupported(msg));
80 return Err(CommandError::unsupported(msg));
81 }
81 }
82
82
83 for prefix in ["pre", "post", "fail"].iter() {
83 for prefix in ["pre", "post", "fail"].iter() {
84 // Mercurial allows users to define generic hooks for commands,
84 // Mercurial allows users to define generic hooks for commands,
85 // fallback if any are detected
85 // fallback if any are detected
86 let item = format!("{}-{}", prefix, subcommand_name);
86 let item = format!("{}-{}", prefix, subcommand_name);
87 let hook_for_command = config.get_str(b"hooks", item.as_bytes())?;
87 let hook_for_command = config.get_str(b"hooks", item.as_bytes())?;
88 if hook_for_command.is_some() {
88 if hook_for_command.is_some() {
89 let msg = format!("{}-{} hook defined", prefix, subcommand_name);
89 let msg = format!("{}-{} hook defined", prefix, subcommand_name);
90 return Err(CommandError::unsupported(msg));
90 return Err(CommandError::unsupported(msg));
91 }
91 }
92 }
92 }
93 let run = subcommand_run_fn(subcommand_name)
93 let run = subcommand_run_fn(subcommand_name)
94 .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
94 .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
95 let subcommand_args = subcommand_matches
95 let subcommand_args = subcommand_matches
96 .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
96 .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
97
97
98 let invocation = CliInvocation {
98 let invocation = CliInvocation {
99 ui,
99 ui,
100 subcommand_args,
100 subcommand_args,
101 config,
101 config,
102 repo,
102 repo,
103 };
103 };
104
104
105 if let Ok(repo) = repo {
105 if let Ok(repo) = repo {
106 // We don't support subrepos, fallback if the subrepos file is present
106 // We don't support subrepos, fallback if the subrepos file is present
107 if repo.working_directory_vfs().join(".hgsub").exists() {
107 if repo.working_directory_vfs().join(".hgsub").exists() {
108 let msg = "subrepos (.hgsub is present)";
108 let msg = "subrepos (.hgsub is present)";
109 return Err(CommandError::unsupported(msg));
109 return Err(CommandError::unsupported(msg));
110 }
110 }
111 }
111 }
112
112
113 let blackbox = blackbox::Blackbox::new(&invocation, process_start_time)?;
113 let blackbox = blackbox::Blackbox::new(&invocation, process_start_time)?;
114 blackbox.log_command_start();
114 blackbox.log_command_start();
115 let result = run(&invocation);
115 let result = run(&invocation);
116 blackbox.log_command_end(exit_code(
116 blackbox.log_command_end(exit_code(
117 &result,
117 &result,
118 // TODO: show a warning or combine with original error if `get_bool`
118 // TODO: show a warning or combine with original error if `get_bool`
119 // returns an error
119 // returns an error
120 config
120 config
121 .get_bool(b"ui", b"detailed-exit-code")
121 .get_bool(b"ui", b"detailed-exit-code")
122 .unwrap_or(false),
122 .unwrap_or(false),
123 ));
123 ));
124 result
124 result
125 }
125 }
126
126
127 fn main() {
127 fn main() {
128 // Run this first, before we find out if the blackbox extension is even
128 // Run this first, before we find out if the blackbox extension is even
129 // enabled, in order to include everything in-between in the duration
129 // enabled, in order to include everything in-between in the duration
130 // measurements. Reading config files can be slow if they’re on NFS.
130 // measurements. Reading config files can be slow if they’re on NFS.
131 let process_start_time = blackbox::ProcessStartTime::now();
131 let process_start_time = blackbox::ProcessStartTime::now();
132
132
133 env_logger::init();
133 env_logger::init();
134 let ui = ui::Ui::new();
134 let ui = ui::Ui::new();
135
135
136 let early_args = EarlyArgs::parse(std::env::args_os());
136 let early_args = EarlyArgs::parse(std::env::args_os());
137
137
138 let initial_current_dir = early_args.cwd.map(|cwd| {
138 let initial_current_dir = early_args.cwd.map(|cwd| {
139 let cwd = get_path_from_bytes(&cwd);
139 let cwd = get_path_from_bytes(&cwd);
140 std::env::current_dir()
140 std::env::current_dir()
141 .and_then(|initial| {
141 .and_then(|initial| {
142 std::env::set_current_dir(cwd)?;
142 std::env::set_current_dir(cwd)?;
143 Ok(initial)
143 Ok(initial)
144 })
144 })
145 .unwrap_or_else(|error| {
145 .unwrap_or_else(|error| {
146 exit(
146 exit(
147 &None,
147 &None,
148 &ui,
148 &ui,
149 OnUnsupported::Abort,
149 OnUnsupported::Abort,
150 Err(CommandError::abort(format!(
150 Err(CommandError::abort(format!(
151 "abort: {}: '{}'",
151 "abort: {}: '{}'",
152 error,
152 error,
153 cwd.display()
153 cwd.display()
154 ))),
154 ))),
155 false,
155 false,
156 )
156 )
157 })
157 })
158 });
158 });
159
159
160 let mut non_repo_config =
160 let mut non_repo_config =
161 Config::load_non_repo().unwrap_or_else(|error| {
161 Config::load_non_repo().unwrap_or_else(|error| {
162 // Normally this is decided based on config, but we don’t have that
162 // Normally this is decided based on config, but we don’t have that
163 // available. As of this writing config loading never returns an
163 // available. As of this writing config loading never returns an
164 // "unsupported" error but that is not enforced by the type system.
164 // "unsupported" error but that is not enforced by the type system.
165 let on_unsupported = OnUnsupported::Abort;
165 let on_unsupported = OnUnsupported::Abort;
166
166
167 exit(
167 exit(
168 &initial_current_dir,
168 &initial_current_dir,
169 &ui,
169 &ui,
170 on_unsupported,
170 on_unsupported,
171 Err(error.into()),
171 Err(error.into()),
172 false,
172 false,
173 )
173 )
174 });
174 });
175
175
176 non_repo_config
176 non_repo_config
177 .load_cli_args_config(early_args.config)
177 .load_cli_args_config(early_args.config)
178 .unwrap_or_else(|error| {
178 .unwrap_or_else(|error| {
179 exit(
179 exit(
180 &initial_current_dir,
180 &initial_current_dir,
181 &ui,
181 &ui,
182 OnUnsupported::from_config(&ui, &non_repo_config),
182 OnUnsupported::from_config(&ui, &non_repo_config),
183 Err(error.into()),
183 Err(error.into()),
184 non_repo_config
184 non_repo_config
185 .get_bool(b"ui", b"detailed-exit-code")
185 .get_bool(b"ui", b"detailed-exit-code")
186 .unwrap_or(false),
186 .unwrap_or(false),
187 )
187 )
188 });
188 });
189
189
190 if let Some(repo_path_bytes) = &early_args.repo {
190 if let Some(repo_path_bytes) = &early_args.repo {
191 lazy_static::lazy_static! {
191 lazy_static::lazy_static! {
192 static ref SCHEME_RE: regex::bytes::Regex =
192 static ref SCHEME_RE: regex::bytes::Regex =
193 // Same as `_matchscheme` in `mercurial/util.py`
193 // Same as `_matchscheme` in `mercurial/util.py`
194 regex::bytes::Regex::new("^[a-zA-Z0-9+.\\-]+:").unwrap();
194 regex::bytes::Regex::new("^[a-zA-Z0-9+.\\-]+:").unwrap();
195 }
195 }
196 if SCHEME_RE.is_match(&repo_path_bytes) {
196 if SCHEME_RE.is_match(&repo_path_bytes) {
197 exit(
197 exit(
198 &initial_current_dir,
198 &initial_current_dir,
199 &ui,
199 &ui,
200 OnUnsupported::from_config(&ui, &non_repo_config),
200 OnUnsupported::from_config(&ui, &non_repo_config),
201 Err(CommandError::UnsupportedFeature {
201 Err(CommandError::UnsupportedFeature {
202 message: format_bytes!(
202 message: format_bytes!(
203 b"URL-like --repository {}",
203 b"URL-like --repository {}",
204 repo_path_bytes
204 repo_path_bytes
205 ),
205 ),
206 }),
206 }),
207 // TODO: show a warning or combine with original error if
207 // TODO: show a warning or combine with original error if
208 // `get_bool` returns an error
208 // `get_bool` returns an error
209 non_repo_config
209 non_repo_config
210 .get_bool(b"ui", b"detailed-exit-code")
210 .get_bool(b"ui", b"detailed-exit-code")
211 .unwrap_or(false),
211 .unwrap_or(false),
212 )
212 )
213 }
213 }
214 }
214 }
215 let repo_arg = early_args.repo.unwrap_or(Vec::new());
215 let repo_arg = early_args.repo.unwrap_or(Vec::new());
216 let repo_path: Option<PathBuf> = {
216 let repo_path: Option<PathBuf> = {
217 if repo_arg.is_empty() {
217 if repo_arg.is_empty() {
218 None
218 None
219 } else {
219 } else {
220 let local_config = {
220 let local_config = {
221 if std::env::var_os("HGRCSKIPREPO").is_none() {
221 if std::env::var_os("HGRCSKIPREPO").is_none() {
222 // TODO: handle errors from find_repo_root
222 // TODO: handle errors from find_repo_root
223 if let Ok(current_dir_path) = Repo::find_repo_root() {
223 if let Ok(current_dir_path) = Repo::find_repo_root() {
224 let config_files = vec![
224 let config_files = vec![
225 ConfigSource::AbsPath(
225 ConfigSource::AbsPath(
226 current_dir_path.join(".hg/hgrc"),
226 current_dir_path.join(".hg/hgrc"),
227 ),
227 ),
228 ConfigSource::AbsPath(
228 ConfigSource::AbsPath(
229 current_dir_path.join(".hg/hgrc-not-shared"),
229 current_dir_path.join(".hg/hgrc-not-shared"),
230 ),
230 ),
231 ];
231 ];
232 // TODO: handle errors from
232 // TODO: handle errors from
233 // `load_from_explicit_sources`
233 // `load_from_explicit_sources`
234 Config::load_from_explicit_sources(config_files).ok()
234 Config::load_from_explicit_sources(config_files).ok()
235 } else {
235 } else {
236 None
236 None
237 }
237 }
238 } else {
238 } else {
239 None
239 None
240 }
240 }
241 };
241 };
242
242
243 let non_repo_config_val = {
243 let non_repo_config_val = {
244 let non_repo_val = non_repo_config.get(b"paths", &repo_arg);
244 let non_repo_val = non_repo_config.get(b"paths", &repo_arg);
245 match &non_repo_val {
245 match &non_repo_val {
246 Some(val) if val.len() > 0 => home::home_dir()
246 Some(val) if val.len() > 0 => home::home_dir()
247 .unwrap_or_else(|| PathBuf::from("~"))
247 .unwrap_or_else(|| PathBuf::from("~"))
248 .join(get_path_from_bytes(val))
248 .join(get_path_from_bytes(val))
249 .canonicalize()
249 .canonicalize()
250 // TODO: handle error and make it similar to python
250 // TODO: handle error and make it similar to python
251 // implementation maybe?
251 // implementation maybe?
252 .ok(),
252 .ok(),
253 _ => None,
253 _ => None,
254 }
254 }
255 };
255 };
256
256
257 let config_val = match &local_config {
257 let config_val = match &local_config {
258 None => non_repo_config_val,
258 None => non_repo_config_val,
259 Some(val) => {
259 Some(val) => {
260 let local_config_val = val.get(b"paths", &repo_arg);
260 let local_config_val = val.get(b"paths", &repo_arg);
261 match &local_config_val {
261 match &local_config_val {
262 Some(val) if val.len() > 0 => {
262 Some(val) if val.len() > 0 => {
263 // presence of a local_config assures that
263 // presence of a local_config assures that
264 // current_dir
264 // current_dir
265 // wont result in an Error
265 // wont result in an Error
266 let canpath = hg::utils::current_dir()
266 let canpath = hg::utils::current_dir()
267 .unwrap()
267 .unwrap()
268 .join(get_path_from_bytes(val))
268 .join(get_path_from_bytes(val))
269 .canonicalize();
269 .canonicalize();
270 canpath.ok().or(non_repo_config_val)
270 canpath.ok().or(non_repo_config_val)
271 }
271 }
272 _ => non_repo_config_val,
272 _ => non_repo_config_val,
273 }
273 }
274 }
274 }
275 };
275 };
276 config_val.or(Some(get_path_from_bytes(&repo_arg).to_path_buf()))
276 config_val.or(Some(get_path_from_bytes(&repo_arg).to_path_buf()))
277 }
277 }
278 };
278 };
279
279
280 let repo_result = match Repo::find(&non_repo_config, repo_path.to_owned())
280 let repo_result = match Repo::find(&non_repo_config, repo_path.to_owned())
281 {
281 {
282 Ok(repo) => Ok(repo),
282 Ok(repo) => Ok(repo),
283 Err(RepoError::NotFound { at }) if repo_path.is_none() => {
283 Err(RepoError::NotFound { at }) if repo_path.is_none() => {
284 // Not finding a repo is not fatal yet, if `-R` was not given
284 // Not finding a repo is not fatal yet, if `-R` was not given
285 Err(NoRepoInCwdError { cwd: at })
285 Err(NoRepoInCwdError { cwd: at })
286 }
286 }
287 Err(error) => exit(
287 Err(error) => exit(
288 &initial_current_dir,
288 &initial_current_dir,
289 &ui,
289 &ui,
290 OnUnsupported::from_config(&ui, &non_repo_config),
290 OnUnsupported::from_config(&ui, &non_repo_config),
291 Err(error.into()),
291 Err(error.into()),
292 // TODO: show a warning or combine with original error if
292 // TODO: show a warning or combine with original error if
293 // `get_bool` returns an error
293 // `get_bool` returns an error
294 non_repo_config
294 non_repo_config
295 .get_bool(b"ui", b"detailed-exit-code")
295 .get_bool(b"ui", b"detailed-exit-code")
296 .unwrap_or(false),
296 .unwrap_or(false),
297 ),
297 ),
298 };
298 };
299
299
300 let config = if let Ok(repo) = &repo_result {
300 let config = if let Ok(repo) = &repo_result {
301 repo.config()
301 repo.config()
302 } else {
302 } else {
303 &non_repo_config
303 &non_repo_config
304 };
304 };
305 let on_unsupported = OnUnsupported::from_config(&ui, config);
305 let on_unsupported = OnUnsupported::from_config(&ui, config);
306
306
307 let result = main_with_result(
307 let result = main_with_result(
308 &process_start_time,
308 &process_start_time,
309 &ui,
309 &ui,
310 repo_result.as_ref(),
310 repo_result.as_ref(),
311 config,
311 config,
312 );
312 );
313 exit(
313 exit(
314 &initial_current_dir,
314 &initial_current_dir,
315 &ui,
315 &ui,
316 on_unsupported,
316 on_unsupported,
317 result,
317 result,
318 // TODO: show a warning or combine with original error if `get_bool`
318 // TODO: show a warning or combine with original error if `get_bool`
319 // returns an error
319 // returns an error
320 config
320 config
321 .get_bool(b"ui", b"detailed-exit-code")
321 .get_bool(b"ui", b"detailed-exit-code")
322 .unwrap_or(false),
322 .unwrap_or(false),
323 )
323 )
324 }
324 }
325
325
326 fn exit_code(
326 fn exit_code(
327 result: &Result<(), CommandError>,
327 result: &Result<(), CommandError>,
328 use_detailed_exit_code: bool,
328 use_detailed_exit_code: bool,
329 ) -> i32 {
329 ) -> i32 {
330 match result {
330 match result {
331 Ok(()) => exit_codes::OK,
331 Ok(()) => exit_codes::OK,
332 Err(CommandError::Abort {
332 Err(CommandError::Abort {
333 message: _,
333 message: _,
334 detailed_exit_code,
334 detailed_exit_code,
335 }) => {
335 }) => {
336 if use_detailed_exit_code {
336 if use_detailed_exit_code {
337 *detailed_exit_code
337 *detailed_exit_code
338 } else {
338 } else {
339 exit_codes::ABORT
339 exit_codes::ABORT
340 }
340 }
341 }
341 }
342 Err(CommandError::Unsuccessful) => exit_codes::UNSUCCESSFUL,
342 Err(CommandError::Unsuccessful) => exit_codes::UNSUCCESSFUL,
343
343
344 // Exit with a specific code and no error message to let a potential
344 // Exit with a specific code and no error message to let a potential
345 // wrapper script fallback to Python-based Mercurial.
345 // wrapper script fallback to Python-based Mercurial.
346 Err(CommandError::UnsupportedFeature { .. }) => {
346 Err(CommandError::UnsupportedFeature { .. }) => {
347 exit_codes::UNIMPLEMENTED
347 exit_codes::UNIMPLEMENTED
348 }
348 }
349 }
349 }
350 }
350 }
351
351
352 fn exit(
352 fn exit(
353 initial_current_dir: &Option<PathBuf>,
353 initial_current_dir: &Option<PathBuf>,
354 ui: &Ui,
354 ui: &Ui,
355 mut on_unsupported: OnUnsupported,
355 mut on_unsupported: OnUnsupported,
356 result: Result<(), CommandError>,
356 result: Result<(), CommandError>,
357 use_detailed_exit_code: bool,
357 use_detailed_exit_code: bool,
358 ) -> ! {
358 ) -> ! {
359 if let (
359 if let (
360 OnUnsupported::Fallback { executable },
360 OnUnsupported::Fallback { executable },
361 Err(CommandError::UnsupportedFeature { .. }),
361 Err(CommandError::UnsupportedFeature { .. }),
362 ) = (&on_unsupported, &result)
362 ) = (&on_unsupported, &result)
363 {
363 {
364 let mut args = std::env::args_os();
364 let mut args = std::env::args_os();
365 let executable_path = get_path_from_bytes(&executable);
365 let executable_path = get_path_from_bytes(&executable);
366 let this_executable = args.next().expect("exepcted argv[0] to exist");
366 let this_executable = args.next().expect("exepcted argv[0] to exist");
367 if executable_path == &PathBuf::from(this_executable) {
367 if executable_path == &PathBuf::from(this_executable) {
368 // Avoid spawning infinitely many processes until resource
368 // Avoid spawning infinitely many processes until resource
369 // exhaustion.
369 // exhaustion.
370 let _ = ui.write_stderr(&format_bytes!(
370 let _ = ui.write_stderr(&format_bytes!(
371 b"Blocking recursive fallback. The 'rhg.fallback-executable = {}' config \
371 b"Blocking recursive fallback. The 'rhg.fallback-executable = {}' config \
372 points to `rhg` itself.\n",
372 points to `rhg` itself.\n",
373 executable
373 executable
374 ));
374 ));
375 on_unsupported = OnUnsupported::Abort
375 on_unsupported = OnUnsupported::Abort
376 } else {
376 } else {
377 // `args` is now `argv[1..]` since we’ve already consumed `argv[0]`
377 // `args` is now `argv[1..]` since we’ve already consumed `argv[0]`
378 let mut command = Command::new(executable_path);
378 let mut command = Command::new(executable_path);
379 command.args(args);
379 command.args(args);
380 if let Some(initial) = initial_current_dir {
380 if let Some(initial) = initial_current_dir {
381 command.current_dir(initial);
381 command.current_dir(initial);
382 }
382 }
383 let result = command.status();
383 let result = command.status();
384 match result {
384 match result {
385 Ok(status) => std::process::exit(
385 Ok(status) => std::process::exit(
386 status.code().unwrap_or(exit_codes::ABORT),
386 status.code().unwrap_or(exit_codes::ABORT),
387 ),
387 ),
388 Err(error) => {
388 Err(error) => {
389 let _ = ui.write_stderr(&format_bytes!(
389 let _ = ui.write_stderr(&format_bytes!(
390 b"tried to fall back to a '{}' sub-process but got error {}\n",
390 b"tried to fall back to a '{}' sub-process but got error {}\n",
391 executable, format_bytes::Utf8(error)
391 executable, format_bytes::Utf8(error)
392 ));
392 ));
393 on_unsupported = OnUnsupported::Abort
393 on_unsupported = OnUnsupported::Abort
394 }
394 }
395 }
395 }
396 }
396 }
397 }
397 }
398 exit_no_fallback(ui, on_unsupported, result, use_detailed_exit_code)
398 exit_no_fallback(ui, on_unsupported, result, use_detailed_exit_code)
399 }
399 }
400
400
401 fn exit_no_fallback(
401 fn exit_no_fallback(
402 ui: &Ui,
402 ui: &Ui,
403 on_unsupported: OnUnsupported,
403 on_unsupported: OnUnsupported,
404 result: Result<(), CommandError>,
404 result: Result<(), CommandError>,
405 use_detailed_exit_code: bool,
405 use_detailed_exit_code: bool,
406 ) -> ! {
406 ) -> ! {
407 match &result {
407 match &result {
408 Ok(_) => {}
408 Ok(_) => {}
409 Err(CommandError::Unsuccessful) => {}
409 Err(CommandError::Unsuccessful) => {}
410 Err(CommandError::Abort {
410 Err(CommandError::Abort {
411 message,
411 message,
412 detailed_exit_code: _,
412 detailed_exit_code: _,
413 }) => {
413 }) => {
414 if !message.is_empty() {
414 if !message.is_empty() {
415 // Ignore errors when writing to stderr, we’re already exiting
415 // Ignore errors when writing to stderr, we’re already exiting
416 // with failure code so there’s not much more we can do.
416 // with failure code so there’s not much more we can do.
417 let _ = ui.write_stderr(&format_bytes!(b"{}\n", message));
417 let _ = ui.write_stderr(&format_bytes!(b"{}\n", message));
418 }
418 }
419 }
419 }
420 Err(CommandError::UnsupportedFeature { message }) => {
420 Err(CommandError::UnsupportedFeature { message }) => {
421 match on_unsupported {
421 match on_unsupported {
422 OnUnsupported::Abort => {
422 OnUnsupported::Abort => {
423 let _ = ui.write_stderr(&format_bytes!(
423 let _ = ui.write_stderr(&format_bytes!(
424 b"unsupported feature: {}\n",
424 b"unsupported feature: {}\n",
425 message
425 message
426 ));
426 ));
427 }
427 }
428 OnUnsupported::AbortSilent => {}
428 OnUnsupported::AbortSilent => {}
429 OnUnsupported::Fallback { .. } => unreachable!(),
429 OnUnsupported::Fallback { .. } => unreachable!(),
430 }
430 }
431 }
431 }
432 }
432 }
433 std::process::exit(exit_code(&result, use_detailed_exit_code))
433 std::process::exit(exit_code(&result, use_detailed_exit_code))
434 }
434 }
435
435
436 macro_rules! subcommands {
436 macro_rules! subcommands {
437 ($( $command: ident )+) => {
437 ($( $command: ident )+) => {
438 mod commands {
438 mod commands {
439 $(
439 $(
440 pub mod $command;
440 pub mod $command;
441 )+
441 )+
442 }
442 }
443
443
444 fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
444 fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
445 app
445 app
446 $(
446 $(
447 .subcommand(commands::$command::args())
447 .subcommand(commands::$command::args())
448 )+
448 )+
449 }
449 }
450
450
451 pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
451 pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>;
452
452
453 fn subcommand_run_fn(name: &str) -> Option<RunFn> {
453 fn subcommand_run_fn(name: &str) -> Option<RunFn> {
454 match name {
454 match name {
455 $(
455 $(
456 stringify!($command) => Some(commands::$command::run),
456 stringify!($command) => Some(commands::$command::run),
457 )+
457 )+
458 _ => None,
458 _ => None,
459 }
459 }
460 }
460 }
461 };
461 };
462 }
462 }
463
463
464 subcommands! {
464 subcommands! {
465 cat
465 cat
466 debugdata
466 debugdata
467 debugrequirements
467 debugrequirements
468 files
468 files
469 root
469 root
470 config
470 config
471 status
471 status
472 }
472 }
473
473
474 pub struct CliInvocation<'a> {
474 pub struct CliInvocation<'a> {
475 ui: &'a Ui,
475 ui: &'a Ui,
476 subcommand_args: &'a ArgMatches<'a>,
476 subcommand_args: &'a ArgMatches<'a>,
477 config: &'a Config,
477 config: &'a Config,
478 /// References inside `Result` is a bit peculiar but allow
478 /// References inside `Result` is a bit peculiar but allow
479 /// `invocation.repo?` to work out with `&CliInvocation` since this
479 /// `invocation.repo?` to work out with `&CliInvocation` since this
480 /// `Result` type is `Copy`.
480 /// `Result` type is `Copy`.
481 repo: Result<&'a Repo, &'a NoRepoInCwdError>,
481 repo: Result<&'a Repo, &'a NoRepoInCwdError>,
482 }
482 }
483
483
484 struct NoRepoInCwdError {
484 struct NoRepoInCwdError {
485 cwd: PathBuf,
485 cwd: PathBuf,
486 }
486 }
487
487
488 /// CLI arguments to be parsed "early" in order to be able to read
488 /// CLI arguments to be parsed "early" in order to be able to read
489 /// configuration before using Clap. Ideally we would also use Clap for this,
489 /// configuration before using Clap. Ideally we would also use Clap for this,
490 /// see <https://github.com/clap-rs/clap/discussions/2366>.
490 /// see <https://github.com/clap-rs/clap/discussions/2366>.
491 ///
491 ///
492 /// These arguments are still declared when we do use Clap later, so that Clap
492 /// These arguments are still declared when we do use Clap later, so that Clap
493 /// does not return an error for their presence.
493 /// does not return an error for their presence.
494 struct EarlyArgs {
494 struct EarlyArgs {
495 /// Values of all `--config` arguments. (Possibly none)
495 /// Values of all `--config` arguments. (Possibly none)
496 config: Vec<Vec<u8>>,
496 config: Vec<Vec<u8>>,
497 /// Value of the `-R` or `--repository` argument, if any.
497 /// Value of the `-R` or `--repository` argument, if any.
498 repo: Option<Vec<u8>>,
498 repo: Option<Vec<u8>>,
499 /// Value of the `--cwd` argument, if any.
499 /// Value of the `--cwd` argument, if any.
500 cwd: Option<Vec<u8>>,
500 cwd: Option<Vec<u8>>,
501 }
501 }
502
502
503 impl EarlyArgs {
503 impl EarlyArgs {
504 fn parse(args: impl IntoIterator<Item = OsString>) -> Self {
504 fn parse(args: impl IntoIterator<Item = OsString>) -> Self {
505 let mut args = args.into_iter().map(get_bytes_from_os_str);
505 let mut args = args.into_iter().map(get_bytes_from_os_str);
506 let mut config = Vec::new();
506 let mut config = Vec::new();
507 let mut repo = None;
507 let mut repo = None;
508 let mut cwd = None;
508 let mut cwd = None;
509 // Use `while let` instead of `for` so that we can also call
509 // Use `while let` instead of `for` so that we can also call
510 // `args.next()` inside the loop.
510 // `args.next()` inside the loop.
511 while let Some(arg) = args.next() {
511 while let Some(arg) = args.next() {
512 if arg == b"--config" {
512 if arg == b"--config" {
513 if let Some(value) = args.next() {
513 if let Some(value) = args.next() {
514 config.push(value)
514 config.push(value)
515 }
515 }
516 } else if let Some(value) = arg.drop_prefix(b"--config=") {
516 } else if let Some(value) = arg.drop_prefix(b"--config=") {
517 config.push(value.to_owned())
517 config.push(value.to_owned())
518 }
518 }
519
519
520 if arg == b"--cwd" {
520 if arg == b"--cwd" {
521 if let Some(value) = args.next() {
521 if let Some(value) = args.next() {
522 cwd = Some(value)
522 cwd = Some(value)
523 }
523 }
524 } else if let Some(value) = arg.drop_prefix(b"--cwd=") {
524 } else if let Some(value) = arg.drop_prefix(b"--cwd=") {
525 cwd = Some(value.to_owned())
525 cwd = Some(value.to_owned())
526 }
526 }
527
527
528 if arg == b"--repository" || arg == b"-R" {
528 if arg == b"--repository" || arg == b"-R" {
529 if let Some(value) = args.next() {
529 if let Some(value) = args.next() {
530 repo = Some(value)
530 repo = Some(value)
531 }
531 }
532 } else if let Some(value) = arg.drop_prefix(b"--repository=") {
532 } else if let Some(value) = arg.drop_prefix(b"--repository=") {
533 repo = Some(value.to_owned())
533 repo = Some(value.to_owned())
534 } else if let Some(value) = arg.drop_prefix(b"-R") {
534 } else if let Some(value) = arg.drop_prefix(b"-R") {
535 repo = Some(value.to_owned())
535 repo = Some(value.to_owned())
536 }
536 }
537 }
537 }
538 Self { config, repo, cwd }
538 Self { config, repo, cwd }
539 }
539 }
540 }
540 }
541
541
542 /// What to do when encountering some unsupported feature.
542 /// What to do when encountering some unsupported feature.
543 ///
543 ///
544 /// See `HgError::UnsupportedFeature` and `CommandError::UnsupportedFeature`.
544 /// See `HgError::UnsupportedFeature` and `CommandError::UnsupportedFeature`.
545 enum OnUnsupported {
545 enum OnUnsupported {
546 /// Print an error message describing what feature is not supported,
546 /// Print an error message describing what feature is not supported,
547 /// and exit with code 252.
547 /// and exit with code 252.
548 Abort,
548 Abort,
549 /// Silently exit with code 252.
549 /// Silently exit with code 252.
550 AbortSilent,
550 AbortSilent,
551 /// Try running a Python implementation
551 /// Try running a Python implementation
552 Fallback { executable: Vec<u8> },
552 Fallback { executable: Vec<u8> },
553 }
553 }
554
554
555 impl OnUnsupported {
555 impl OnUnsupported {
556 const DEFAULT: Self = OnUnsupported::Abort;
556 const DEFAULT: Self = OnUnsupported::Abort;
557
557
558 fn from_config(ui: &Ui, config: &Config) -> Self {
558 fn from_config(ui: &Ui, config: &Config) -> Self {
559 match config
559 match config
560 .get(b"rhg", b"on-unsupported")
560 .get(b"rhg", b"on-unsupported")
561 .map(|value| value.to_ascii_lowercase())
561 .map(|value| value.to_ascii_lowercase())
562 .as_deref()
562 .as_deref()
563 {
563 {
564 Some(b"abort") => OnUnsupported::Abort,
564 Some(b"abort") => OnUnsupported::Abort,
565 Some(b"abort-silent") => OnUnsupported::AbortSilent,
565 Some(b"abort-silent") => OnUnsupported::AbortSilent,
566 Some(b"fallback") => OnUnsupported::Fallback {
566 Some(b"fallback") => OnUnsupported::Fallback {
567 executable: config
567 executable: config
568 .get(b"rhg", b"fallback-executable")
568 .get(b"rhg", b"fallback-executable")
569 .unwrap_or_else(|| {
569 .unwrap_or_else(|| {
570 exit_no_fallback(
570 exit_no_fallback(
571 ui,
571 ui,
572 Self::Abort,
572 Self::Abort,
573 Err(CommandError::abort(
573 Err(CommandError::abort(
574 "abort: 'rhg.on-unsupported=fallback' without \
574 "abort: 'rhg.on-unsupported=fallback' without \
575 'rhg.fallback-executable' set."
575 'rhg.fallback-executable' set."
576 )),
576 )),
577 false,
577 false,
578 )
578 )
579 })
579 })
580 .to_owned(),
580 .to_owned(),
581 },
581 },
582 None => Self::DEFAULT,
582 None => Self::DEFAULT,
583 Some(_) => {
583 Some(_) => {
584 // TODO: warn about unknown config value
584 // TODO: warn about unknown config value
585 Self::DEFAULT
585 Self::DEFAULT
586 }
586 }
587 }
587 }
588 }
588 }
589 }
589 }
590
590
591 const SUPPORTED_EXTENSIONS: &[&[u8]] = &[b"blackbox", b"share"];
591 const SUPPORTED_EXTENSIONS: &[&[u8]] = &[b"blackbox", b"share"];
592
592
593 fn check_extensions(config: &Config) -> Result<(), CommandError> {
593 fn check_extensions(config: &Config) -> Result<(), CommandError> {
594 let enabled = config.get_section_keys(b"extensions");
594 let enabled = config.get_section_keys(b"extensions");
595
595
596 let mut unsupported = enabled;
596 let mut unsupported = enabled;
597 for supported in SUPPORTED_EXTENSIONS {
597 for supported in SUPPORTED_EXTENSIONS {
598 unsupported.remove(supported);
598 unsupported.remove(supported);
599 }
599 }
600
600
601 if let Some(ignored_list) = config.get_list(b"rhg", b"ignored-extensions")
601 if let Some(ignored_list) = config.get_list(b"rhg", b"ignored-extensions")
602 {
602 {
603 for ignored in ignored_list {
603 for ignored in ignored_list {
604 unsupported.remove(ignored.as_slice());
604 unsupported.remove(ignored.as_slice());
605 }
605 }
606 }
606 }
607
607
608 if unsupported.is_empty() {
608 if unsupported.is_empty() {
609 Ok(())
609 Ok(())
610 } else {
610 } else {
611 Err(CommandError::UnsupportedFeature {
611 Err(CommandError::UnsupportedFeature {
612 message: format_bytes!(
612 message: format_bytes!(
613 b"extensions: {} (consider adding them to 'rhg.ignored-extensions' config)",
613 b"extensions: {} (consider adding them to 'rhg.ignored-extensions' config)",
614 join(unsupported, b", ")
614 join(unsupported, b", ")
615 ),
615 ),
616 })
616 })
617 }
617 }
618 }
618 }
619
620 fn check_unsupported(config: &Config) -> Result<(), CommandError> {
621 check_extensions(config)?;
622
623 if std::env::var_os("HG_PENDING").is_some() {
624 // TODO: only if the value is `== repo.working_directory`?
625 // What about relative v.s. absolute paths?
626 Err(CommandError::unsupported("$HG_PENDING"))?
627 }
628
629 Ok(())
630 }
@@ -1,2094 +1,2090 b''
1 TODO: fix rhg bugs that make this test fail when status is enabled
2 $ unset RHG_STATUS
3
4
5 $ hg init a
1 $ hg init a
6 $ mkdir a/d1
2 $ mkdir a/d1
7 $ mkdir a/d1/d2
3 $ mkdir a/d1/d2
8 $ echo line 1 > a/a
4 $ echo line 1 > a/a
9 $ echo line 1 > a/d1/d2/a
5 $ echo line 1 > a/d1/d2/a
10 $ hg --cwd a ci -Ama
6 $ hg --cwd a ci -Ama
11 adding a
7 adding a
12 adding d1/d2/a
8 adding d1/d2/a
13
9
14 $ echo line 2 >> a/a
10 $ echo line 2 >> a/a
15 $ hg --cwd a ci -u someone -d '1 0' -m'second change'
11 $ hg --cwd a ci -u someone -d '1 0' -m'second change'
16
12
17 import with no args:
13 import with no args:
18
14
19 $ hg --cwd a import
15 $ hg --cwd a import
20 abort: need at least one patch to import
16 abort: need at least one patch to import
21 [10]
17 [10]
22
18
23 generate patches for the test
19 generate patches for the test
24
20
25 $ hg --cwd a export tip > exported-tip.patch
21 $ hg --cwd a export tip > exported-tip.patch
26 $ hg --cwd a diff -r0:1 > diffed-tip.patch
22 $ hg --cwd a diff -r0:1 > diffed-tip.patch
27
23
28
24
29 import exported patch
25 import exported patch
30 (this also tests that editor is not invoked, if the patch contains the
26 (this also tests that editor is not invoked, if the patch contains the
31 commit message and '--edit' is not specified)
27 commit message and '--edit' is not specified)
32
28
33 $ hg clone -r0 a b
29 $ hg clone -r0 a b
34 adding changesets
30 adding changesets
35 adding manifests
31 adding manifests
36 adding file changes
32 adding file changes
37 added 1 changesets with 2 changes to 2 files
33 added 1 changesets with 2 changes to 2 files
38 new changesets 80971e65b431
34 new changesets 80971e65b431
39 updating to branch default
35 updating to branch default
40 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
36 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
41 $ HGEDITOR=cat hg --cwd b import --debug ../exported-tip.patch
37 $ HGEDITOR=cat hg --cwd b import --debug ../exported-tip.patch
42 applying ../exported-tip.patch
38 applying ../exported-tip.patch
43 Subject:
39 Subject:
44
40
45 Content-Type: text/plain
41 Content-Type: text/plain
46 found patch at byte 202
42 found patch at byte 202
47 patch generated by hg export
43 patch generated by hg export
48 From: someone
44 From: someone
49 Date: 1 0
45 Date: 1 0
50 Node ID: 1d4bd90af0e43687763d158dfa83ff2a4b6c0c32
46 Node ID: 1d4bd90af0e43687763d158dfa83ff2a4b6c0c32
51 message:
47 message:
52 second change
48 second change
53 patching file a
49 patching file a
54 committing files:
50 committing files:
55 a
51 a
56 committing manifest
52 committing manifest
57 committing changelog
53 committing changelog
58 created 1d4bd90af0e4
54 created 1d4bd90af0e4
59 updating the branch cache
55 updating the branch cache
60
56
61 message and committer and date should be same
57 message and committer and date should be same
62
58
63 $ hg --cwd b tip
59 $ hg --cwd b tip
64 changeset: 1:1d4bd90af0e4
60 changeset: 1:1d4bd90af0e4
65 tag: tip
61 tag: tip
66 user: someone
62 user: someone
67 date: Thu Jan 01 00:00:01 1970 +0000
63 date: Thu Jan 01 00:00:01 1970 +0000
68 summary: second change
64 summary: second change
69
65
70 $ rm -r b
66 $ rm -r b
71
67
72
68
73 import exported patch with external patcher
69 import exported patch with external patcher
74 (this also tests that editor is invoked, if the '--edit' is specified,
70 (this also tests that editor is invoked, if the '--edit' is specified,
75 regardless of the commit message in the patch)
71 regardless of the commit message in the patch)
76
72
77 $ cat > dummypatch.py <<EOF
73 $ cat > dummypatch.py <<EOF
78 > from __future__ import print_function
74 > from __future__ import print_function
79 > print('patching file a')
75 > print('patching file a')
80 > open('a', 'wb').write(b'line2\n')
76 > open('a', 'wb').write(b'line2\n')
81 > EOF
77 > EOF
82 $ hg clone -r0 a b
78 $ hg clone -r0 a b
83 adding changesets
79 adding changesets
84 adding manifests
80 adding manifests
85 adding file changes
81 adding file changes
86 added 1 changesets with 2 changes to 2 files
82 added 1 changesets with 2 changes to 2 files
87 new changesets 80971e65b431
83 new changesets 80971e65b431
88 updating to branch default
84 updating to branch default
89 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
85 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
90 $ HGEDITOR=cat hg --config ui.patch="\"$PYTHON\" ../dummypatch.py" --cwd b import --edit ../exported-tip.patch
86 $ HGEDITOR=cat hg --config ui.patch="\"$PYTHON\" ../dummypatch.py" --cwd b import --edit ../exported-tip.patch
91 applying ../exported-tip.patch
87 applying ../exported-tip.patch
92 second change
88 second change
93
89
94
90
95 HG: Enter commit message. Lines beginning with 'HG:' are removed.
91 HG: Enter commit message. Lines beginning with 'HG:' are removed.
96 HG: Leave message empty to abort commit.
92 HG: Leave message empty to abort commit.
97 HG: --
93 HG: --
98 HG: user: someone
94 HG: user: someone
99 HG: branch 'default'
95 HG: branch 'default'
100 HG: changed a
96 HG: changed a
101 $ cat b/a
97 $ cat b/a
102 line2
98 line2
103 $ rm -r b
99 $ rm -r b
104
100
105
101
106 import of plain diff should fail without message
102 import of plain diff should fail without message
107 (this also tests that editor is invoked, if the patch doesn't contain
103 (this also tests that editor is invoked, if the patch doesn't contain
108 the commit message, regardless of '--edit')
104 the commit message, regardless of '--edit')
109
105
110 $ hg clone -r0 a b
106 $ hg clone -r0 a b
111 adding changesets
107 adding changesets
112 adding manifests
108 adding manifests
113 adding file changes
109 adding file changes
114 added 1 changesets with 2 changes to 2 files
110 added 1 changesets with 2 changes to 2 files
115 new changesets 80971e65b431
111 new changesets 80971e65b431
116 updating to branch default
112 updating to branch default
117 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
113 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
118 $ cat > $TESTTMP/editor.sh <<EOF
114 $ cat > $TESTTMP/editor.sh <<EOF
119 > env | grep HGEDITFORM
115 > env | grep HGEDITFORM
120 > cat \$1
116 > cat \$1
121 > EOF
117 > EOF
122 $ HGEDITOR="sh $TESTTMP/editor.sh" hg --cwd b import ../diffed-tip.patch
118 $ HGEDITOR="sh $TESTTMP/editor.sh" hg --cwd b import ../diffed-tip.patch
123 applying ../diffed-tip.patch
119 applying ../diffed-tip.patch
124 HGEDITFORM=import.normal.normal
120 HGEDITFORM=import.normal.normal
125
121
126
122
127 HG: Enter commit message. Lines beginning with 'HG:' are removed.
123 HG: Enter commit message. Lines beginning with 'HG:' are removed.
128 HG: Leave message empty to abort commit.
124 HG: Leave message empty to abort commit.
129 HG: --
125 HG: --
130 HG: user: test
126 HG: user: test
131 HG: branch 'default'
127 HG: branch 'default'
132 HG: changed a
128 HG: changed a
133 abort: empty commit message
129 abort: empty commit message
134 [10]
130 [10]
135
131
136 Test avoiding editor invocation at applying the patch with --exact,
132 Test avoiding editor invocation at applying the patch with --exact,
137 even if commit message is empty
133 even if commit message is empty
138
134
139 $ echo a >> b/a
135 $ echo a >> b/a
140 $ hg --cwd b commit -m ' '
136 $ hg --cwd b commit -m ' '
141 $ hg --cwd b tip -T "{node}\n"
137 $ hg --cwd b tip -T "{node}\n"
142 d8804f3f5396d800812f579c8452796a5993bdb2
138 d8804f3f5396d800812f579c8452796a5993bdb2
143 $ hg --cwd b export -o ../empty-log.diff .
139 $ hg --cwd b export -o ../empty-log.diff .
144 $ hg --cwd b update -q -C ".^1"
140 $ hg --cwd b update -q -C ".^1"
145 $ hg --cwd b --config extensions.strip= strip -q tip
141 $ hg --cwd b --config extensions.strip= strip -q tip
146 $ HGEDITOR=cat hg --cwd b import --exact ../empty-log.diff
142 $ HGEDITOR=cat hg --cwd b import --exact ../empty-log.diff
147 applying ../empty-log.diff
143 applying ../empty-log.diff
148 $ hg --cwd b tip -T "{node}\n"
144 $ hg --cwd b tip -T "{node}\n"
149 d8804f3f5396d800812f579c8452796a5993bdb2
145 d8804f3f5396d800812f579c8452796a5993bdb2
150
146
151 $ rm -r b
147 $ rm -r b
152
148
153
149
154 import of plain diff should be ok with message
150 import of plain diff should be ok with message
155
151
156 $ hg clone -r0 a b
152 $ hg clone -r0 a b
157 adding changesets
153 adding changesets
158 adding manifests
154 adding manifests
159 adding file changes
155 adding file changes
160 added 1 changesets with 2 changes to 2 files
156 added 1 changesets with 2 changes to 2 files
161 new changesets 80971e65b431
157 new changesets 80971e65b431
162 updating to branch default
158 updating to branch default
163 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
164 $ hg --cwd b import -mpatch ../diffed-tip.patch
160 $ hg --cwd b import -mpatch ../diffed-tip.patch
165 applying ../diffed-tip.patch
161 applying ../diffed-tip.patch
166 $ rm -r b
162 $ rm -r b
167
163
168
164
169 import of plain diff with specific date and user
165 import of plain diff with specific date and user
170 (this also tests that editor is not invoked, if
166 (this also tests that editor is not invoked, if
171 '--message'/'--logfile' is specified and '--edit' is not)
167 '--message'/'--logfile' is specified and '--edit' is not)
172
168
173 $ hg clone -r0 a b
169 $ hg clone -r0 a b
174 adding changesets
170 adding changesets
175 adding manifests
171 adding manifests
176 adding file changes
172 adding file changes
177 added 1 changesets with 2 changes to 2 files
173 added 1 changesets with 2 changes to 2 files
178 new changesets 80971e65b431
174 new changesets 80971e65b431
179 updating to branch default
175 updating to branch default
180 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
176 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
181 $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../diffed-tip.patch
177 $ hg --cwd b import -mpatch -d '1 0' -u 'user@nowhere.net' ../diffed-tip.patch
182 applying ../diffed-tip.patch
178 applying ../diffed-tip.patch
183 $ hg -R b tip -pv
179 $ hg -R b tip -pv
184 changeset: 1:ca68f19f3a40
180 changeset: 1:ca68f19f3a40
185 tag: tip
181 tag: tip
186 user: user@nowhere.net
182 user: user@nowhere.net
187 date: Thu Jan 01 00:00:01 1970 +0000
183 date: Thu Jan 01 00:00:01 1970 +0000
188 files: a
184 files: a
189 description:
185 description:
190 patch
186 patch
191
187
192
188
193 diff -r 80971e65b431 -r ca68f19f3a40 a
189 diff -r 80971e65b431 -r ca68f19f3a40 a
194 --- a/a Thu Jan 01 00:00:00 1970 +0000
190 --- a/a Thu Jan 01 00:00:00 1970 +0000
195 +++ b/a Thu Jan 01 00:00:01 1970 +0000
191 +++ b/a Thu Jan 01 00:00:01 1970 +0000
196 @@ -1,1 +1,2 @@
192 @@ -1,1 +1,2 @@
197 line 1
193 line 1
198 +line 2
194 +line 2
199
195
200 $ rm -r b
196 $ rm -r b
201
197
202
198
203 import of plain diff should be ok with --no-commit
199 import of plain diff should be ok with --no-commit
204 (this also tests that editor is not invoked, if '--no-commit' is
200 (this also tests that editor is not invoked, if '--no-commit' is
205 specified, regardless of '--edit')
201 specified, regardless of '--edit')
206
202
207 $ hg clone -r0 a b
203 $ hg clone -r0 a b
208 adding changesets
204 adding changesets
209 adding manifests
205 adding manifests
210 adding file changes
206 adding file changes
211 added 1 changesets with 2 changes to 2 files
207 added 1 changesets with 2 changes to 2 files
212 new changesets 80971e65b431
208 new changesets 80971e65b431
213 updating to branch default
209 updating to branch default
214 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
210 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
215 $ HGEDITOR=cat hg --cwd b import --no-commit --edit ../diffed-tip.patch
211 $ HGEDITOR=cat hg --cwd b import --no-commit --edit ../diffed-tip.patch
216 applying ../diffed-tip.patch
212 applying ../diffed-tip.patch
217 $ hg --cwd b diff --nodates
213 $ hg --cwd b diff --nodates
218 diff -r 80971e65b431 a
214 diff -r 80971e65b431 a
219 --- a/a
215 --- a/a
220 +++ b/a
216 +++ b/a
221 @@ -1,1 +1,2 @@
217 @@ -1,1 +1,2 @@
222 line 1
218 line 1
223 +line 2
219 +line 2
224 $ rm -r b
220 $ rm -r b
225
221
226
222
227 import of malformed plain diff should fail
223 import of malformed plain diff should fail
228
224
229 $ hg clone -r0 a b
225 $ hg clone -r0 a b
230 adding changesets
226 adding changesets
231 adding manifests
227 adding manifests
232 adding file changes
228 adding file changes
233 added 1 changesets with 2 changes to 2 files
229 added 1 changesets with 2 changes to 2 files
234 new changesets 80971e65b431
230 new changesets 80971e65b431
235 updating to branch default
231 updating to branch default
236 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
232 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
237 $ sed 's/1,1/foo/' < diffed-tip.patch > broken.patch
233 $ sed 's/1,1/foo/' < diffed-tip.patch > broken.patch
238 $ hg --cwd b import -mpatch ../broken.patch
234 $ hg --cwd b import -mpatch ../broken.patch
239 applying ../broken.patch
235 applying ../broken.patch
240 abort: bad hunk #1
236 abort: bad hunk #1
241 [255]
237 [255]
242 $ rm -r b
238 $ rm -r b
243
239
244 hg -R repo import
240 hg -R repo import
245 put the clone in a subdir - having a directory named "a"
241 put the clone in a subdir - having a directory named "a"
246 used to hide a bug.
242 used to hide a bug.
247
243
248 $ mkdir dir
244 $ mkdir dir
249 $ hg clone -r0 a dir/b
245 $ hg clone -r0 a dir/b
250 adding changesets
246 adding changesets
251 adding manifests
247 adding manifests
252 adding file changes
248 adding file changes
253 added 1 changesets with 2 changes to 2 files
249 added 1 changesets with 2 changes to 2 files
254 new changesets 80971e65b431
250 new changesets 80971e65b431
255 updating to branch default
251 updating to branch default
256 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
252 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
257 $ cd dir
253 $ cd dir
258 $ hg -R b import ../exported-tip.patch
254 $ hg -R b import ../exported-tip.patch
259 applying ../exported-tip.patch
255 applying ../exported-tip.patch
260 $ cd ..
256 $ cd ..
261 $ rm -r dir
257 $ rm -r dir
262
258
263
259
264 import from stdin
260 import from stdin
265
261
266 $ hg clone -r0 a b
262 $ hg clone -r0 a b
267 adding changesets
263 adding changesets
268 adding manifests
264 adding manifests
269 adding file changes
265 adding file changes
270 added 1 changesets with 2 changes to 2 files
266 added 1 changesets with 2 changes to 2 files
271 new changesets 80971e65b431
267 new changesets 80971e65b431
272 updating to branch default
268 updating to branch default
273 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
269 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
274 $ hg --cwd b import - < exported-tip.patch
270 $ hg --cwd b import - < exported-tip.patch
275 applying patch from stdin
271 applying patch from stdin
276 $ rm -r b
272 $ rm -r b
277
273
278
274
279 import two patches in one stream
275 import two patches in one stream
280
276
281 $ hg init b
277 $ hg init b
282 $ hg --cwd a export 0:tip | hg --cwd b import -
278 $ hg --cwd a export 0:tip | hg --cwd b import -
283 applying patch from stdin
279 applying patch from stdin
284 $ hg --cwd a id
280 $ hg --cwd a id
285 1d4bd90af0e4 tip
281 1d4bd90af0e4 tip
286 $ hg --cwd b id
282 $ hg --cwd b id
287 1d4bd90af0e4 tip
283 1d4bd90af0e4 tip
288 $ rm -r b
284 $ rm -r b
289
285
290
286
291 override commit message
287 override commit message
292
288
293 $ hg clone -r0 a b
289 $ hg clone -r0 a b
294 adding changesets
290 adding changesets
295 adding manifests
291 adding manifests
296 adding file changes
292 adding file changes
297 added 1 changesets with 2 changes to 2 files
293 added 1 changesets with 2 changes to 2 files
298 new changesets 80971e65b431
294 new changesets 80971e65b431
299 updating to branch default
295 updating to branch default
300 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
296 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
301 $ hg --cwd b import -m 'override' - < exported-tip.patch
297 $ hg --cwd b import -m 'override' - < exported-tip.patch
302 applying patch from stdin
298 applying patch from stdin
303 $ hg --cwd b tip | grep override
299 $ hg --cwd b tip | grep override
304 summary: override
300 summary: override
305 $ rm -r b
301 $ rm -r b
306
302
307 $ cat > mkmsg.py <<EOF
303 $ cat > mkmsg.py <<EOF
308 > import email.message
304 > import email.message
309 > import sys
305 > import sys
310 > msg = email.message.Message()
306 > msg = email.message.Message()
311 > patch = open(sys.argv[1], 'rb').read()
307 > patch = open(sys.argv[1], 'rb').read()
312 > msg.set_payload(b'email commit message\n' + patch)
308 > msg.set_payload(b'email commit message\n' + patch)
313 > msg['Subject'] = 'email patch'
309 > msg['Subject'] = 'email patch'
314 > msg['From'] = 'email patcher'
310 > msg['From'] = 'email patcher'
315 > open(sys.argv[2], 'wb').write(bytes(msg))
311 > open(sys.argv[2], 'wb').write(bytes(msg))
316 > EOF
312 > EOF
317
313
318
314
319 plain diff in email, subject, message body
315 plain diff in email, subject, message body
320
316
321 $ hg clone -r0 a b
317 $ hg clone -r0 a b
322 adding changesets
318 adding changesets
323 adding manifests
319 adding manifests
324 adding file changes
320 adding file changes
325 added 1 changesets with 2 changes to 2 files
321 added 1 changesets with 2 changes to 2 files
326 new changesets 80971e65b431
322 new changesets 80971e65b431
327 updating to branch default
323 updating to branch default
328 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
324 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
329 $ "$PYTHON" mkmsg.py diffed-tip.patch msg.patch
325 $ "$PYTHON" mkmsg.py diffed-tip.patch msg.patch
330 $ hg --cwd b import ../msg.patch
326 $ hg --cwd b import ../msg.patch
331 applying ../msg.patch
327 applying ../msg.patch
332 $ hg --cwd b tip | grep email
328 $ hg --cwd b tip | grep email
333 user: email patcher
329 user: email patcher
334 summary: email patch
330 summary: email patch
335 $ rm -r b
331 $ rm -r b
336
332
337
333
338 plain diff in email, no subject, message body
334 plain diff in email, no subject, message body
339
335
340 $ hg clone -r0 a b
336 $ hg clone -r0 a b
341 adding changesets
337 adding changesets
342 adding manifests
338 adding manifests
343 adding file changes
339 adding file changes
344 added 1 changesets with 2 changes to 2 files
340 added 1 changesets with 2 changes to 2 files
345 new changesets 80971e65b431
341 new changesets 80971e65b431
346 updating to branch default
342 updating to branch default
347 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
343 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
348 $ grep -v '^Subject:' msg.patch | hg --cwd b import -
344 $ grep -v '^Subject:' msg.patch | hg --cwd b import -
349 applying patch from stdin
345 applying patch from stdin
350 $ rm -r b
346 $ rm -r b
351
347
352
348
353 plain diff in email, subject, no message body
349 plain diff in email, subject, no message body
354
350
355 $ hg clone -r0 a b
351 $ hg clone -r0 a b
356 adding changesets
352 adding changesets
357 adding manifests
353 adding manifests
358 adding file changes
354 adding file changes
359 added 1 changesets with 2 changes to 2 files
355 added 1 changesets with 2 changes to 2 files
360 new changesets 80971e65b431
356 new changesets 80971e65b431
361 updating to branch default
357 updating to branch default
362 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
358 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
363 $ grep -v '^email ' msg.patch | hg --cwd b import -
359 $ grep -v '^email ' msg.patch | hg --cwd b import -
364 applying patch from stdin
360 applying patch from stdin
365 $ rm -r b
361 $ rm -r b
366
362
367
363
368 plain diff in email, no subject, no message body, should fail
364 plain diff in email, no subject, no message body, should fail
369
365
370 $ hg clone -r0 a b
366 $ hg clone -r0 a b
371 adding changesets
367 adding changesets
372 adding manifests
368 adding manifests
373 adding file changes
369 adding file changes
374 added 1 changesets with 2 changes to 2 files
370 added 1 changesets with 2 changes to 2 files
375 new changesets 80971e65b431
371 new changesets 80971e65b431
376 updating to branch default
372 updating to branch default
377 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
373 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
378 $ egrep -v '^(Subject|email)' msg.patch | hg --cwd b import -
374 $ egrep -v '^(Subject|email)' msg.patch | hg --cwd b import -
379 applying patch from stdin
375 applying patch from stdin
380 abort: empty commit message
376 abort: empty commit message
381 [10]
377 [10]
382 $ rm -r b
378 $ rm -r b
383
379
384
380
385 hg export in email, should use patch header
381 hg export in email, should use patch header
386
382
387 $ hg clone -r0 a b
383 $ hg clone -r0 a b
388 adding changesets
384 adding changesets
389 adding manifests
385 adding manifests
390 adding file changes
386 adding file changes
391 added 1 changesets with 2 changes to 2 files
387 added 1 changesets with 2 changes to 2 files
392 new changesets 80971e65b431
388 new changesets 80971e65b431
393 updating to branch default
389 updating to branch default
394 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
390 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
395 $ "$PYTHON" mkmsg.py exported-tip.patch msg.patch
391 $ "$PYTHON" mkmsg.py exported-tip.patch msg.patch
396 $ cat msg.patch | hg --cwd b import -
392 $ cat msg.patch | hg --cwd b import -
397 applying patch from stdin
393 applying patch from stdin
398 $ hg --cwd b tip | grep second
394 $ hg --cwd b tip | grep second
399 summary: second change
395 summary: second change
400 $ rm -r b
396 $ rm -r b
401
397
402 hg email --plain, should read X-Mercurial-Node header
398 hg email --plain, should read X-Mercurial-Node header
403
399
404 $ cat >> a/.hg/hgrc << EOF
400 $ cat >> a/.hg/hgrc << EOF
405 > [extensions]
401 > [extensions]
406 > patchbomb =
402 > patchbomb =
407 > [email]
403 > [email]
408 > from = foo
404 > from = foo
409 > cc = foo
405 > cc = foo
410 > to = bar
406 > to = bar
411 > EOF
407 > EOF
412 $ hg --cwd a email -m ../tip-plain.mbox --plain --date '1970-1-1 0:1' tip
408 $ hg --cwd a email -m ../tip-plain.mbox --plain --date '1970-1-1 0:1' tip
413 this patch series consists of 1 patches.
409 this patch series consists of 1 patches.
414
410
415
411
416 sending [PATCH] second change ...
412 sending [PATCH] second change ...
417
413
418 $ hg clone -r0 a b -q
414 $ hg clone -r0 a b -q
419 $ hg --cwd b import --debug ../tip-plain.mbox
415 $ hg --cwd b import --debug ../tip-plain.mbox
420 applying ../tip-plain.mbox
416 applying ../tip-plain.mbox
421 Node ID: 1d4bd90af0e43687763d158dfa83ff2a4b6c0c32
417 Node ID: 1d4bd90af0e43687763d158dfa83ff2a4b6c0c32
422 Subject: second change
418 Subject: second change
423 From: foo
419 From: foo
424 Content-Type: text/plain
420 Content-Type: text/plain
425 found patch at byte 0
421 found patch at byte 0
426 message:
422 message:
427 second change
423 second change
428 patching file a
424 patching file a
429 committing files:
425 committing files:
430 a
426 a
431 committing manifest
427 committing manifest
432 committing changelog
428 committing changelog
433 created de620f6fe949
429 created de620f6fe949
434 updating the branch cache
430 updating the branch cache
435 $ hg --cwd b tip
431 $ hg --cwd b tip
436 changeset: 1:de620f6fe949
432 changeset: 1:de620f6fe949
437 tag: tip
433 tag: tip
438 user: foo
434 user: foo
439 date: Thu Jan 01 00:00:00 1970 +0000
435 date: Thu Jan 01 00:00:00 1970 +0000
440 summary: second change
436 summary: second change
441
437
442 $ hg --cwd b phase tip
438 $ hg --cwd b phase tip
443 1: draft
439 1: draft
444 $ rm -r b
440 $ rm -r b
445
441
446
442
447 hg import --secret
443 hg import --secret
448
444
449 $ hg clone -r0 a b -q
445 $ hg clone -r0 a b -q
450 $ hg --cwd b import --no-commit --secret ../exported-tip.patch
446 $ hg --cwd b import --no-commit --secret ../exported-tip.patch
451 abort: cannot specify both --no-commit and --secret
447 abort: cannot specify both --no-commit and --secret
452 [10]
448 [10]
453 $ hg --cwd b import --secret ../exported-tip.patch
449 $ hg --cwd b import --secret ../exported-tip.patch
454 applying ../exported-tip.patch
450 applying ../exported-tip.patch
455 $ hg --cwd b diff -c . --nodates
451 $ hg --cwd b diff -c . --nodates
456 diff -r 80971e65b431 -r 1d4bd90af0e4 a
452 diff -r 80971e65b431 -r 1d4bd90af0e4 a
457 --- a/a
453 --- a/a
458 +++ b/a
454 +++ b/a
459 @@ -1,1 +1,2 @@
455 @@ -1,1 +1,2 @@
460 line 1
456 line 1
461 +line 2
457 +line 2
462 $ hg --cwd b phase
458 $ hg --cwd b phase
463 1: secret
459 1: secret
464 $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
460 $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
465 $ HGEDITOR=cat hg --cwd b import --secret --edit ../exported-tip.patch
461 $ HGEDITOR=cat hg --cwd b import --secret --edit ../exported-tip.patch
466 applying ../exported-tip.patch
462 applying ../exported-tip.patch
467 second change
463 second change
468
464
469
465
470 HG: Enter commit message. Lines beginning with 'HG:' are removed.
466 HG: Enter commit message. Lines beginning with 'HG:' are removed.
471 HG: Leave message empty to abort commit.
467 HG: Leave message empty to abort commit.
472 HG: --
468 HG: --
473 HG: user: someone
469 HG: user: someone
474 HG: branch 'default'
470 HG: branch 'default'
475 HG: changed a
471 HG: changed a
476 $ hg --cwd b diff -c . --nodates
472 $ hg --cwd b diff -c . --nodates
477 diff -r 80971e65b431 -r 1d4bd90af0e4 a
473 diff -r 80971e65b431 -r 1d4bd90af0e4 a
478 --- a/a
474 --- a/a
479 +++ b/a
475 +++ b/a
480 @@ -1,1 +1,2 @@
476 @@ -1,1 +1,2 @@
481 line 1
477 line 1
482 +line 2
478 +line 2
483 $ hg --cwd b phase
479 $ hg --cwd b phase
484 1: secret
480 1: secret
485 $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
481 $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
486 $ hg --cwd b import --bypass --secret ../exported-tip.patch
482 $ hg --cwd b import --bypass --secret ../exported-tip.patch
487 applying ../exported-tip.patch
483 applying ../exported-tip.patch
488 $ hg --cwd b phase -r tip
484 $ hg --cwd b phase -r tip
489 1: secret
485 1: secret
490 $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
486 $ hg --cwd b --config extensions.strip= strip 1 --no-backup --quiet
491 $ rm -r b
487 $ rm -r b
492
488
493
489
494 subject: duplicate detection, removal of [PATCH]
490 subject: duplicate detection, removal of [PATCH]
495 The '---' tests the gitsendmail handling without proper mail headers
491 The '---' tests the gitsendmail handling without proper mail headers
496
492
497 $ cat > mkmsg2.py <<EOF
493 $ cat > mkmsg2.py <<EOF
498 > import email.message
494 > import email.message
499 > import sys
495 > import sys
500 > msg = email.message.Message()
496 > msg = email.message.Message()
501 > patch = open(sys.argv[1], 'rb').read()
497 > patch = open(sys.argv[1], 'rb').read()
502 > msg.set_payload(b'email patch\n\nnext line\n---\n' + patch)
498 > msg.set_payload(b'email patch\n\nnext line\n---\n' + patch)
503 > msg['Subject'] = '[PATCH] email patch'
499 > msg['Subject'] = '[PATCH] email patch'
504 > msg['From'] = 'email patcher'
500 > msg['From'] = 'email patcher'
505 > open(sys.argv[2], 'wb').write(bytes(msg))
501 > open(sys.argv[2], 'wb').write(bytes(msg))
506 > EOF
502 > EOF
507
503
508
504
509 plain diff in email, [PATCH] subject, message body with subject
505 plain diff in email, [PATCH] subject, message body with subject
510
506
511 $ hg clone -r0 a b
507 $ hg clone -r0 a b
512 adding changesets
508 adding changesets
513 adding manifests
509 adding manifests
514 adding file changes
510 adding file changes
515 added 1 changesets with 2 changes to 2 files
511 added 1 changesets with 2 changes to 2 files
516 new changesets 80971e65b431
512 new changesets 80971e65b431
517 updating to branch default
513 updating to branch default
518 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
514 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
519 $ "$PYTHON" mkmsg2.py diffed-tip.patch msg.patch
515 $ "$PYTHON" mkmsg2.py diffed-tip.patch msg.patch
520 $ cat msg.patch | hg --cwd b import -
516 $ cat msg.patch | hg --cwd b import -
521 applying patch from stdin
517 applying patch from stdin
522 $ hg --cwd b tip --template '{desc}\n'
518 $ hg --cwd b tip --template '{desc}\n'
523 email patch
519 email patch
524
520
525 next line
521 next line
526 $ rm -r b
522 $ rm -r b
527
523
528
524
529 Issue963: Parent of working dir incorrect after import of multiple
525 Issue963: Parent of working dir incorrect after import of multiple
530 patches and rollback
526 patches and rollback
531
527
532 We weren't backing up the correct dirstate file when importing many
528 We weren't backing up the correct dirstate file when importing many
533 patches: import patch1 patch2; rollback
529 patches: import patch1 patch2; rollback
534
530
535 $ echo line 3 >> a/a
531 $ echo line 3 >> a/a
536 $ hg --cwd a ci -m'third change'
532 $ hg --cwd a ci -m'third change'
537 $ hg --cwd a export -o '../patch%R' 1 2
533 $ hg --cwd a export -o '../patch%R' 1 2
538 $ hg clone -qr0 a b
534 $ hg clone -qr0 a b
539 $ hg --cwd b parents --template 'parent: {rev}\n'
535 $ hg --cwd b parents --template 'parent: {rev}\n'
540 parent: 0
536 parent: 0
541 $ hg --cwd b import -v ../patch1 ../patch2
537 $ hg --cwd b import -v ../patch1 ../patch2
542 applying ../patch1
538 applying ../patch1
543 patching file a
539 patching file a
544 committing files:
540 committing files:
545 a
541 a
546 committing manifest
542 committing manifest
547 committing changelog
543 committing changelog
548 created 1d4bd90af0e4
544 created 1d4bd90af0e4
549 applying ../patch2
545 applying ../patch2
550 patching file a
546 patching file a
551 committing files:
547 committing files:
552 a
548 a
553 committing manifest
549 committing manifest
554 committing changelog
550 committing changelog
555 created 6d019af21222
551 created 6d019af21222
556 $ hg --cwd b rollback
552 $ hg --cwd b rollback
557 repository tip rolled back to revision 0 (undo import)
553 repository tip rolled back to revision 0 (undo import)
558 working directory now based on revision 0
554 working directory now based on revision 0
559 $ hg --cwd b parents --template 'parent: {rev}\n'
555 $ hg --cwd b parents --template 'parent: {rev}\n'
560 parent: 0
556 parent: 0
561
557
562 Test that "hg rollback" doesn't restore dirstate to one at the
558 Test that "hg rollback" doesn't restore dirstate to one at the
563 beginning of the rolled back transaction in not-"parent-gone" case.
559 beginning of the rolled back transaction in not-"parent-gone" case.
564
560
565 invoking pretxncommit hook will cause marking '.hg/dirstate' as a file
561 invoking pretxncommit hook will cause marking '.hg/dirstate' as a file
566 to be restored when rolling back, after DirstateTransactionPlan (see wiki
562 to be restored when rolling back, after DirstateTransactionPlan (see wiki
567 page for detail).
563 page for detail).
568
564
569 $ hg --cwd b branch -q foobar
565 $ hg --cwd b branch -q foobar
570 $ hg --cwd b commit -m foobar
566 $ hg --cwd b commit -m foobar
571 $ hg --cwd b update 0 -q
567 $ hg --cwd b update 0 -q
572 $ hg --cwd b import ../patch1 ../patch2 --config hooks.pretxncommit=true
568 $ hg --cwd b import ../patch1 ../patch2 --config hooks.pretxncommit=true
573 applying ../patch1
569 applying ../patch1
574 applying ../patch2
570 applying ../patch2
575 $ hg --cwd b update -q 1
571 $ hg --cwd b update -q 1
576 $ hg --cwd b rollback -q
572 $ hg --cwd b rollback -q
577 $ hg --cwd b parents --template 'parent: {rev}\n'
573 $ hg --cwd b parents --template 'parent: {rev}\n'
578 parent: 1
574 parent: 1
579
575
580 $ hg --cwd b update -q -C 0
576 $ hg --cwd b update -q -C 0
581 $ hg --cwd b --config extensions.strip= strip -q 1
577 $ hg --cwd b --config extensions.strip= strip -q 1
582
578
583 Test visibility of in-memory dirstate changes inside transaction to
579 Test visibility of in-memory dirstate changes inside transaction to
584 external process
580 external process
585
581
586 $ echo foo > a/foo
582 $ echo foo > a/foo
587 $ hg --cwd a commit -A -m 'adding foo' foo
583 $ hg --cwd a commit -A -m 'adding foo' foo
588 $ hg --cwd a export -o '../patch%R' 3
584 $ hg --cwd a export -o '../patch%R' 3
589
585
590 $ cat > $TESTTMP/checkvisibility.sh <<EOF
586 $ cat > $TESTTMP/checkvisibility.sh <<EOF
591 > echo "===="
587 > echo "===="
592 > hg parents --template "VISIBLE {rev}:{node|short}\n"
588 > hg parents --template "VISIBLE {rev}:{node|short}\n"
593 > hg status -amr
589 > hg status -amr
594 > # test that pending changes are hidden
590 > # test that pending changes are hidden
595 > unset HG_PENDING
591 > unset HG_PENDING
596 > hg parents --template "ACTUAL {rev}:{node|short}\n"
592 > hg parents --template "ACTUAL {rev}:{node|short}\n"
597 > hg status -amr
593 > hg status -amr
598 > echo "===="
594 > echo "===="
599 > EOF
595 > EOF
600
596
601 == test visibility to external editor
597 == test visibility to external editor
602
598
603 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
599 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
604 ====
600 ====
605 VISIBLE 0:80971e65b431
601 VISIBLE 0:80971e65b431
606 ACTUAL 0:80971e65b431
602 ACTUAL 0:80971e65b431
607 ====
603 ====
608
604
609 $ HGEDITOR="sh $TESTTMP/checkvisibility.sh" hg --cwd b import -v --edit ../patch1 ../patch2 ../patch3
605 $ HGEDITOR="sh $TESTTMP/checkvisibility.sh" hg --cwd b import -v --edit ../patch1 ../patch2 ../patch3
610 applying ../patch1
606 applying ../patch1
611 patching file a
607 patching file a
612 ====
608 ====
613 VISIBLE 0:80971e65b431
609 VISIBLE 0:80971e65b431
614 M a
610 M a
615 ACTUAL 0:80971e65b431
611 ACTUAL 0:80971e65b431
616 M a
612 M a
617 ====
613 ====
618 committing files:
614 committing files:
619 a
615 a
620 committing manifest
616 committing manifest
621 committing changelog
617 committing changelog
622 created 1d4bd90af0e4
618 created 1d4bd90af0e4
623 applying ../patch2
619 applying ../patch2
624 patching file a
620 patching file a
625 ====
621 ====
626 VISIBLE 1:1d4bd90af0e4
622 VISIBLE 1:1d4bd90af0e4
627 M a
623 M a
628 ACTUAL 0:80971e65b431
624 ACTUAL 0:80971e65b431
629 M a
625 M a
630 ====
626 ====
631 committing files:
627 committing files:
632 a
628 a
633 committing manifest
629 committing manifest
634 committing changelog
630 committing changelog
635 created 6d019af21222
631 created 6d019af21222
636 applying ../patch3
632 applying ../patch3
637 patching file foo
633 patching file foo
638 adding foo
634 adding foo
639 ====
635 ====
640 VISIBLE 2:6d019af21222
636 VISIBLE 2:6d019af21222
641 A foo
637 A foo
642 ACTUAL 0:80971e65b431
638 ACTUAL 0:80971e65b431
643 M a
639 M a
644 ====
640 ====
645 committing files:
641 committing files:
646 foo
642 foo
647 committing manifest
643 committing manifest
648 committing changelog
644 committing changelog
649 created 55e3f75b2378
645 created 55e3f75b2378
650
646
651 $ hg --cwd b rollback -q
647 $ hg --cwd b rollback -q
652
648
653 (content of file "a" is already changed and it should be recognized as
649 (content of file "a" is already changed and it should be recognized as
654 "M", even though dirstate is restored to one before "hg import")
650 "M", even though dirstate is restored to one before "hg import")
655
651
656 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
652 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
657 ====
653 ====
658 VISIBLE 0:80971e65b431
654 VISIBLE 0:80971e65b431
659 M a
655 M a
660 ACTUAL 0:80971e65b431
656 ACTUAL 0:80971e65b431
661 M a
657 M a
662 ====
658 ====
663 $ hg --cwd b revert --no-backup a
659 $ hg --cwd b revert --no-backup a
664 $ rm -f b/foo
660 $ rm -f b/foo
665
661
666 == test visibility to precommit external hook
662 == test visibility to precommit external hook
667
663
668 $ cat >> b/.hg/hgrc <<EOF
664 $ cat >> b/.hg/hgrc <<EOF
669 > [hooks]
665 > [hooks]
670 > precommit.visibility = sh $TESTTMP/checkvisibility.sh
666 > precommit.visibility = sh $TESTTMP/checkvisibility.sh
671 > EOF
667 > EOF
672
668
673 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
669 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
674 ====
670 ====
675 VISIBLE 0:80971e65b431
671 VISIBLE 0:80971e65b431
676 ACTUAL 0:80971e65b431
672 ACTUAL 0:80971e65b431
677 ====
673 ====
678
674
679 $ hg --cwd b import ../patch1 ../patch2 ../patch3
675 $ hg --cwd b import ../patch1 ../patch2 ../patch3
680 applying ../patch1
676 applying ../patch1
681 ====
677 ====
682 VISIBLE 0:80971e65b431
678 VISIBLE 0:80971e65b431
683 M a
679 M a
684 ACTUAL 0:80971e65b431
680 ACTUAL 0:80971e65b431
685 M a
681 M a
686 ====
682 ====
687 applying ../patch2
683 applying ../patch2
688 ====
684 ====
689 VISIBLE 1:1d4bd90af0e4
685 VISIBLE 1:1d4bd90af0e4
690 M a
686 M a
691 ACTUAL 0:80971e65b431
687 ACTUAL 0:80971e65b431
692 M a
688 M a
693 ====
689 ====
694 applying ../patch3
690 applying ../patch3
695 ====
691 ====
696 VISIBLE 2:6d019af21222
692 VISIBLE 2:6d019af21222
697 A foo
693 A foo
698 ACTUAL 0:80971e65b431
694 ACTUAL 0:80971e65b431
699 M a
695 M a
700 ====
696 ====
701
697
702 $ hg --cwd b rollback -q
698 $ hg --cwd b rollback -q
703 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
699 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
704 ====
700 ====
705 VISIBLE 0:80971e65b431
701 VISIBLE 0:80971e65b431
706 M a
702 M a
707 ACTUAL 0:80971e65b431
703 ACTUAL 0:80971e65b431
708 M a
704 M a
709 ====
705 ====
710 $ hg --cwd b revert --no-backup a
706 $ hg --cwd b revert --no-backup a
711 $ rm -f b/foo
707 $ rm -f b/foo
712
708
713 $ cat >> b/.hg/hgrc <<EOF
709 $ cat >> b/.hg/hgrc <<EOF
714 > [hooks]
710 > [hooks]
715 > precommit.visibility =
711 > precommit.visibility =
716 > EOF
712 > EOF
717
713
718 == test visibility to pretxncommit external hook
714 == test visibility to pretxncommit external hook
719
715
720 $ cat >> b/.hg/hgrc <<EOF
716 $ cat >> b/.hg/hgrc <<EOF
721 > [hooks]
717 > [hooks]
722 > pretxncommit.visibility = sh $TESTTMP/checkvisibility.sh
718 > pretxncommit.visibility = sh $TESTTMP/checkvisibility.sh
723 > EOF
719 > EOF
724
720
725 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
721 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
726 ====
722 ====
727 VISIBLE 0:80971e65b431
723 VISIBLE 0:80971e65b431
728 ACTUAL 0:80971e65b431
724 ACTUAL 0:80971e65b431
729 ====
725 ====
730
726
731 $ hg --cwd b import ../patch1 ../patch2 ../patch3
727 $ hg --cwd b import ../patch1 ../patch2 ../patch3
732 applying ../patch1
728 applying ../patch1
733 ====
729 ====
734 VISIBLE 0:80971e65b431
730 VISIBLE 0:80971e65b431
735 M a
731 M a
736 ACTUAL 0:80971e65b431
732 ACTUAL 0:80971e65b431
737 M a
733 M a
738 ====
734 ====
739 applying ../patch2
735 applying ../patch2
740 ====
736 ====
741 VISIBLE 1:1d4bd90af0e4
737 VISIBLE 1:1d4bd90af0e4
742 M a
738 M a
743 ACTUAL 0:80971e65b431
739 ACTUAL 0:80971e65b431
744 M a
740 M a
745 ====
741 ====
746 applying ../patch3
742 applying ../patch3
747 ====
743 ====
748 VISIBLE 2:6d019af21222
744 VISIBLE 2:6d019af21222
749 A foo
745 A foo
750 ACTUAL 0:80971e65b431
746 ACTUAL 0:80971e65b431
751 M a
747 M a
752 ====
748 ====
753
749
754 $ hg --cwd b rollback -q
750 $ hg --cwd b rollback -q
755 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
751 $ (cd b && sh "$TESTTMP/checkvisibility.sh")
756 ====
752 ====
757 VISIBLE 0:80971e65b431
753 VISIBLE 0:80971e65b431
758 M a
754 M a
759 ACTUAL 0:80971e65b431
755 ACTUAL 0:80971e65b431
760 M a
756 M a
761 ====
757 ====
762 $ hg --cwd b revert --no-backup a
758 $ hg --cwd b revert --no-backup a
763 $ rm -f b/foo
759 $ rm -f b/foo
764
760
765 $ cat >> b/.hg/hgrc <<EOF
761 $ cat >> b/.hg/hgrc <<EOF
766 > [hooks]
762 > [hooks]
767 > pretxncommit.visibility =
763 > pretxncommit.visibility =
768 > EOF
764 > EOF
769
765
770 $ rm -r b
766 $ rm -r b
771
767
772
768
773 importing a patch in a subdirectory failed at the commit stage
769 importing a patch in a subdirectory failed at the commit stage
774
770
775 $ echo line 2 >> a/d1/d2/a
771 $ echo line 2 >> a/d1/d2/a
776 $ hg --cwd a ci -u someoneelse -d '1 0' -m'subdir change'
772 $ hg --cwd a ci -u someoneelse -d '1 0' -m'subdir change'
777
773
778 hg import in a subdirectory
774 hg import in a subdirectory
779
775
780 $ hg clone -r0 a b
776 $ hg clone -r0 a b
781 adding changesets
777 adding changesets
782 adding manifests
778 adding manifests
783 adding file changes
779 adding file changes
784 added 1 changesets with 2 changes to 2 files
780 added 1 changesets with 2 changes to 2 files
785 new changesets 80971e65b431
781 new changesets 80971e65b431
786 updating to branch default
782 updating to branch default
787 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
783 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
788 $ hg --cwd a export tip > tmp
784 $ hg --cwd a export tip > tmp
789 $ sed -e 's/d1\/d2\///' < tmp > subdir-tip.patch
785 $ sed -e 's/d1\/d2\///' < tmp > subdir-tip.patch
790 $ dir=`pwd`
786 $ dir=`pwd`
791 $ cd b/d1/d2 2>&1 > /dev/null
787 $ cd b/d1/d2 2>&1 > /dev/null
792 $ hg import ../../../subdir-tip.patch
788 $ hg import ../../../subdir-tip.patch
793 applying ../../../subdir-tip.patch
789 applying ../../../subdir-tip.patch
794 $ cd "$dir"
790 $ cd "$dir"
795
791
796 message should be 'subdir change'
792 message should be 'subdir change'
797 committer should be 'someoneelse'
793 committer should be 'someoneelse'
798
794
799 $ hg --cwd b tip
795 $ hg --cwd b tip
800 changeset: 1:3577f5aea227
796 changeset: 1:3577f5aea227
801 tag: tip
797 tag: tip
802 user: someoneelse
798 user: someoneelse
803 date: Thu Jan 01 00:00:01 1970 +0000
799 date: Thu Jan 01 00:00:01 1970 +0000
804 summary: subdir change
800 summary: subdir change
805
801
806
802
807 should be empty
803 should be empty
808
804
809 $ hg --cwd b status
805 $ hg --cwd b status
810
806
811
807
812 Test fuzziness (ambiguous patch location, fuzz=2)
808 Test fuzziness (ambiguous patch location, fuzz=2)
813
809
814 $ hg init fuzzy
810 $ hg init fuzzy
815 $ cd fuzzy
811 $ cd fuzzy
816 $ echo line1 > a
812 $ echo line1 > a
817 $ echo line0 >> a
813 $ echo line0 >> a
818 $ echo line3 >> a
814 $ echo line3 >> a
819 $ hg ci -Am adda
815 $ hg ci -Am adda
820 adding a
816 adding a
821 $ echo line1 > a
817 $ echo line1 > a
822 $ echo line2 >> a
818 $ echo line2 >> a
823 $ echo line0 >> a
819 $ echo line0 >> a
824 $ echo line3 >> a
820 $ echo line3 >> a
825 $ hg ci -m change a
821 $ hg ci -m change a
826 $ hg export tip > fuzzy-tip.patch
822 $ hg export tip > fuzzy-tip.patch
827 $ hg up -C 0
823 $ hg up -C 0
828 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
824 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
829 $ echo line1 > a
825 $ echo line1 > a
830 $ echo line0 >> a
826 $ echo line0 >> a
831 $ echo line1 >> a
827 $ echo line1 >> a
832 $ echo line0 >> a
828 $ echo line0 >> a
833 $ hg ci -m brancha
829 $ hg ci -m brancha
834 created new head
830 created new head
835 $ hg import --config patch.fuzz=0 -v fuzzy-tip.patch
831 $ hg import --config patch.fuzz=0 -v fuzzy-tip.patch
836 applying fuzzy-tip.patch
832 applying fuzzy-tip.patch
837 patching file a
833 patching file a
838 Hunk #1 FAILED at 0
834 Hunk #1 FAILED at 0
839 1 out of 1 hunks FAILED -- saving rejects to file a.rej
835 1 out of 1 hunks FAILED -- saving rejects to file a.rej
840 abort: patch failed to apply
836 abort: patch failed to apply
841 [255]
837 [255]
842 $ hg import --no-commit -v fuzzy-tip.patch
838 $ hg import --no-commit -v fuzzy-tip.patch
843 applying fuzzy-tip.patch
839 applying fuzzy-tip.patch
844 patching file a
840 patching file a
845 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
841 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
846 applied to working directory
842 applied to working directory
847 $ hg revert -a
843 $ hg revert -a
848 reverting a
844 reverting a
849
845
850 Test --exact failure
846 Test --exact failure
851
847
852 $ sed 's/^# Parent .*/# Parent '"`hg log -r. -T '{node}'`"'/' \
848 $ sed 's/^# Parent .*/# Parent '"`hg log -r. -T '{node}'`"'/' \
853 > < fuzzy-tip.patch > fuzzy-reparent.patch
849 > < fuzzy-tip.patch > fuzzy-reparent.patch
854 $ hg import --config patch.fuzz=0 --exact fuzzy-reparent.patch
850 $ hg import --config patch.fuzz=0 --exact fuzzy-reparent.patch
855 applying fuzzy-reparent.patch
851 applying fuzzy-reparent.patch
856 patching file a
852 patching file a
857 Hunk #1 FAILED at 0
853 Hunk #1 FAILED at 0
858 1 out of 1 hunks FAILED -- saving rejects to file a.rej
854 1 out of 1 hunks FAILED -- saving rejects to file a.rej
859 abort: patch failed to apply
855 abort: patch failed to apply
860 [255]
856 [255]
861 $ hg up -qC
857 $ hg up -qC
862 $ hg import --config patch.fuzz=2 --exact fuzzy-reparent.patch
858 $ hg import --config patch.fuzz=2 --exact fuzzy-reparent.patch
863 applying fuzzy-reparent.patch
859 applying fuzzy-reparent.patch
864 patching file a
860 patching file a
865 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
861 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
866 transaction abort!
862 transaction abort!
867 rollback completed
863 rollback completed
868 abort: patch is damaged or loses information
864 abort: patch is damaged or loses information
869 [255]
865 [255]
870 $ hg up -qC
866 $ hg up -qC
871
867
872 $ grep '^#' fuzzy-tip.patch > empty.patch
868 $ grep '^#' fuzzy-tip.patch > empty.patch
873 $ cat <<'EOF' >> empty.patch
869 $ cat <<'EOF' >> empty.patch
874 > change
870 > change
875 >
871 >
876 > diff -r bb90ef1daa38 -r 0e9b883378d4 a
872 > diff -r bb90ef1daa38 -r 0e9b883378d4 a
877 > --- a/a Thu Jan 01 00:00:00 1970 +0000
873 > --- a/a Thu Jan 01 00:00:00 1970 +0000
878 > --- b/a Thu Jan 01 00:00:00 1970 +0000
874 > --- b/a Thu Jan 01 00:00:00 1970 +0000
879 > EOF
875 > EOF
880 $ hg import --exact empty.patch
876 $ hg import --exact empty.patch
881 applying empty.patch
877 applying empty.patch
882 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
878 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
883 abort: patch is damaged or loses information
879 abort: patch is damaged or loses information
884 [255]
880 [255]
885 $ hg up -qC
881 $ hg up -qC
886
882
887 import with --no-commit should have written .hg/last-message.txt
883 import with --no-commit should have written .hg/last-message.txt
888
884
889 $ cat .hg/last-message.txt
885 $ cat .hg/last-message.txt
890 change (no-eol)
886 change (no-eol)
891
887
892
888
893 test fuzziness with eol=auto
889 test fuzziness with eol=auto
894
890
895 $ hg --config patch.eol=auto import --no-commit -v fuzzy-tip.patch
891 $ hg --config patch.eol=auto import --no-commit -v fuzzy-tip.patch
896 applying fuzzy-tip.patch
892 applying fuzzy-tip.patch
897 patching file a
893 patching file a
898 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
894 Hunk #1 succeeded at 2 with fuzz 1 (offset 0 lines).
899 applied to working directory
895 applied to working directory
900 $ cd ..
896 $ cd ..
901
897
902
898
903 Test hunk touching empty files (issue906)
899 Test hunk touching empty files (issue906)
904
900
905 $ hg init empty
901 $ hg init empty
906 $ cd empty
902 $ cd empty
907 $ touch a
903 $ touch a
908 $ touch b1
904 $ touch b1
909 $ touch c1
905 $ touch c1
910 $ echo d > d
906 $ echo d > d
911 $ hg ci -Am init
907 $ hg ci -Am init
912 adding a
908 adding a
913 adding b1
909 adding b1
914 adding c1
910 adding c1
915 adding d
911 adding d
916 $ echo a > a
912 $ echo a > a
917 $ echo b > b1
913 $ echo b > b1
918 $ hg mv b1 b2
914 $ hg mv b1 b2
919 $ echo c > c1
915 $ echo c > c1
920 $ hg copy c1 c2
916 $ hg copy c1 c2
921 $ rm d
917 $ rm d
922 $ touch d
918 $ touch d
923 $ hg diff --git
919 $ hg diff --git
924 diff --git a/a b/a
920 diff --git a/a b/a
925 --- a/a
921 --- a/a
926 +++ b/a
922 +++ b/a
927 @@ -0,0 +1,1 @@
923 @@ -0,0 +1,1 @@
928 +a
924 +a
929 diff --git a/b1 b/b2
925 diff --git a/b1 b/b2
930 rename from b1
926 rename from b1
931 rename to b2
927 rename to b2
932 --- a/b1
928 --- a/b1
933 +++ b/b2
929 +++ b/b2
934 @@ -0,0 +1,1 @@
930 @@ -0,0 +1,1 @@
935 +b
931 +b
936 diff --git a/c1 b/c1
932 diff --git a/c1 b/c1
937 --- a/c1
933 --- a/c1
938 +++ b/c1
934 +++ b/c1
939 @@ -0,0 +1,1 @@
935 @@ -0,0 +1,1 @@
940 +c
936 +c
941 diff --git a/c1 b/c2
937 diff --git a/c1 b/c2
942 copy from c1
938 copy from c1
943 copy to c2
939 copy to c2
944 --- a/c1
940 --- a/c1
945 +++ b/c2
941 +++ b/c2
946 @@ -0,0 +1,1 @@
942 @@ -0,0 +1,1 @@
947 +c
943 +c
948 diff --git a/d b/d
944 diff --git a/d b/d
949 --- a/d
945 --- a/d
950 +++ b/d
946 +++ b/d
951 @@ -1,1 +0,0 @@
947 @@ -1,1 +0,0 @@
952 -d
948 -d
953 $ hg ci -m empty
949 $ hg ci -m empty
954 $ hg export --git tip > empty.diff
950 $ hg export --git tip > empty.diff
955 $ hg up -C 0
951 $ hg up -C 0
956 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
952 4 files updated, 0 files merged, 2 files removed, 0 files unresolved
957 $ hg import empty.diff
953 $ hg import empty.diff
958 applying empty.diff
954 applying empty.diff
959 $ for name in a b1 b2 c1 c2 d; do
955 $ for name in a b1 b2 c1 c2 d; do
960 > echo % $name file
956 > echo % $name file
961 > test -f $name && cat $name
957 > test -f $name && cat $name
962 > done
958 > done
963 % a file
959 % a file
964 a
960 a
965 % b1 file
961 % b1 file
966 % b2 file
962 % b2 file
967 b
963 b
968 % c1 file
964 % c1 file
969 c
965 c
970 % c2 file
966 % c2 file
971 c
967 c
972 % d file
968 % d file
973 $ cd ..
969 $ cd ..
974
970
975
971
976 Test importing a patch ending with a binary file removal
972 Test importing a patch ending with a binary file removal
977
973
978 $ hg init binaryremoval
974 $ hg init binaryremoval
979 $ cd binaryremoval
975 $ cd binaryremoval
980 $ echo a > a
976 $ echo a > a
981 $ "$PYTHON" -c "open('b', 'wb').write(b'a\x00b')"
977 $ "$PYTHON" -c "open('b', 'wb').write(b'a\x00b')"
982 $ hg ci -Am addall
978 $ hg ci -Am addall
983 adding a
979 adding a
984 adding b
980 adding b
985 $ hg rm a
981 $ hg rm a
986 $ hg rm b
982 $ hg rm b
987 $ hg st
983 $ hg st
988 R a
984 R a
989 R b
985 R b
990 $ hg ci -m remove
986 $ hg ci -m remove
991 $ hg export --git . > remove.diff
987 $ hg export --git . > remove.diff
992 $ cat remove.diff | grep git
988 $ cat remove.diff | grep git
993 diff --git a/a b/a
989 diff --git a/a b/a
994 diff --git a/b b/b
990 diff --git a/b b/b
995 $ hg up -C 0
991 $ hg up -C 0
996 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
992 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
997 $ hg import remove.diff
993 $ hg import remove.diff
998 applying remove.diff
994 applying remove.diff
999 $ hg manifest
995 $ hg manifest
1000 $ cd ..
996 $ cd ..
1001
997
1002
998
1003 Issue927: test update+rename with common name
999 Issue927: test update+rename with common name
1004
1000
1005 $ hg init t
1001 $ hg init t
1006 $ cd t
1002 $ cd t
1007 $ touch a
1003 $ touch a
1008 $ hg ci -Am t
1004 $ hg ci -Am t
1009 adding a
1005 adding a
1010 $ echo a > a
1006 $ echo a > a
1011
1007
1012 Here, bfile.startswith(afile)
1008 Here, bfile.startswith(afile)
1013
1009
1014 $ hg copy a a2
1010 $ hg copy a a2
1015 $ hg ci -m copya
1011 $ hg ci -m copya
1016 $ hg export --git tip > copy.diff
1012 $ hg export --git tip > copy.diff
1017 $ hg up -C 0
1013 $ hg up -C 0
1018 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1014 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
1019 $ hg import copy.diff
1015 $ hg import copy.diff
1020 applying copy.diff
1016 applying copy.diff
1021
1017
1022 a should contain an 'a'
1018 a should contain an 'a'
1023
1019
1024 $ cat a
1020 $ cat a
1025 a
1021 a
1026
1022
1027 and a2 should have duplicated it
1023 and a2 should have duplicated it
1028
1024
1029 $ cat a2
1025 $ cat a2
1030 a
1026 a
1031 $ cd ..
1027 $ cd ..
1032
1028
1033
1029
1034 test -p0
1030 test -p0
1035
1031
1036 $ hg init p0
1032 $ hg init p0
1037 $ cd p0
1033 $ cd p0
1038 $ echo a > a
1034 $ echo a > a
1039 $ hg ci -Am t
1035 $ hg ci -Am t
1040 adding a
1036 adding a
1041 $ hg import -p foo
1037 $ hg import -p foo
1042 abort: invalid value 'foo' for option -p, expected int
1038 abort: invalid value 'foo' for option -p, expected int
1043 [10]
1039 [10]
1044 $ hg import -p0 - << EOF
1040 $ hg import -p0 - << EOF
1045 > foobar
1041 > foobar
1046 > --- a Sat Apr 12 22:43:58 2008 -0400
1042 > --- a Sat Apr 12 22:43:58 2008 -0400
1047 > +++ a Sat Apr 12 22:44:05 2008 -0400
1043 > +++ a Sat Apr 12 22:44:05 2008 -0400
1048 > @@ -1,1 +1,1 @@
1044 > @@ -1,1 +1,1 @@
1049 > -a
1045 > -a
1050 > +bb
1046 > +bb
1051 > EOF
1047 > EOF
1052 applying patch from stdin
1048 applying patch from stdin
1053 $ hg status
1049 $ hg status
1054 $ cat a
1050 $ cat a
1055 bb
1051 bb
1056
1052
1057 test --prefix
1053 test --prefix
1058
1054
1059 $ mkdir -p dir/dir2
1055 $ mkdir -p dir/dir2
1060 $ echo b > dir/dir2/b
1056 $ echo b > dir/dir2/b
1061 $ hg ci -Am b
1057 $ hg ci -Am b
1062 adding dir/dir2/b
1058 adding dir/dir2/b
1063 $ hg import -p2 --prefix dir - << EOF
1059 $ hg import -p2 --prefix dir - << EOF
1064 > foobar
1060 > foobar
1065 > --- drop1/drop2/dir2/b
1061 > --- drop1/drop2/dir2/b
1066 > +++ drop1/drop2/dir2/b
1062 > +++ drop1/drop2/dir2/b
1067 > @@ -1,1 +1,1 @@
1063 > @@ -1,1 +1,1 @@
1068 > -b
1064 > -b
1069 > +cc
1065 > +cc
1070 > EOF
1066 > EOF
1071 applying patch from stdin
1067 applying patch from stdin
1072 $ hg status
1068 $ hg status
1073 $ cat dir/dir2/b
1069 $ cat dir/dir2/b
1074 cc
1070 cc
1075 $ cd ..
1071 $ cd ..
1076
1072
1077
1073
1078 test paths outside repo root
1074 test paths outside repo root
1079
1075
1080 $ mkdir outside
1076 $ mkdir outside
1081 $ touch outside/foo
1077 $ touch outside/foo
1082 $ hg init inside
1078 $ hg init inside
1083 $ cd inside
1079 $ cd inside
1084 $ hg import - <<EOF
1080 $ hg import - <<EOF
1085 > diff --git a/a b/b
1081 > diff --git a/a b/b
1086 > rename from ../outside/foo
1082 > rename from ../outside/foo
1087 > rename to bar
1083 > rename to bar
1088 > EOF
1084 > EOF
1089 applying patch from stdin
1085 applying patch from stdin
1090 abort: path contains illegal component: ../outside/foo
1086 abort: path contains illegal component: ../outside/foo
1091 [255]
1087 [255]
1092 $ cd ..
1088 $ cd ..
1093
1089
1094
1090
1095 test import with similarity and git and strip (issue295 et al.)
1091 test import with similarity and git and strip (issue295 et al.)
1096
1092
1097 $ hg init sim
1093 $ hg init sim
1098 $ cd sim
1094 $ cd sim
1099 $ echo 'this is a test' > a
1095 $ echo 'this is a test' > a
1100 $ hg ci -Ama
1096 $ hg ci -Ama
1101 adding a
1097 adding a
1102 $ cat > ../rename.diff <<EOF
1098 $ cat > ../rename.diff <<EOF
1103 > diff --git a/foo/a b/foo/a
1099 > diff --git a/foo/a b/foo/a
1104 > deleted file mode 100644
1100 > deleted file mode 100644
1105 > --- a/foo/a
1101 > --- a/foo/a
1106 > +++ /dev/null
1102 > +++ /dev/null
1107 > @@ -1,1 +0,0 @@
1103 > @@ -1,1 +0,0 @@
1108 > -this is a test
1104 > -this is a test
1109 > diff --git a/foo/b b/foo/b
1105 > diff --git a/foo/b b/foo/b
1110 > new file mode 100644
1106 > new file mode 100644
1111 > --- /dev/null
1107 > --- /dev/null
1112 > +++ b/foo/b
1108 > +++ b/foo/b
1113 > @@ -0,0 +1,2 @@
1109 > @@ -0,0 +1,2 @@
1114 > +this is a test
1110 > +this is a test
1115 > +foo
1111 > +foo
1116 > EOF
1112 > EOF
1117 $ hg import --no-commit -v -s 1 ../rename.diff -p2
1113 $ hg import --no-commit -v -s 1 ../rename.diff -p2
1118 applying ../rename.diff
1114 applying ../rename.diff
1119 patching file a
1115 patching file a
1120 patching file b
1116 patching file b
1121 adding b
1117 adding b
1122 recording removal of a as rename to b (88% similar)
1118 recording removal of a as rename to b (88% similar)
1123 applied to working directory
1119 applied to working directory
1124 $ echo 'mod b' > b
1120 $ echo 'mod b' > b
1125 $ hg st -C
1121 $ hg st -C
1126 A b
1122 A b
1127 a
1123 a
1128 R a
1124 R a
1129 $ hg revert -a
1125 $ hg revert -a
1130 forgetting b
1126 forgetting b
1131 undeleting a
1127 undeleting a
1132 $ cat b
1128 $ cat b
1133 mod b
1129 mod b
1134 $ rm b
1130 $ rm b
1135 $ hg import --no-commit -v -s 100 ../rename.diff -p2
1131 $ hg import --no-commit -v -s 100 ../rename.diff -p2
1136 applying ../rename.diff
1132 applying ../rename.diff
1137 patching file a
1133 patching file a
1138 patching file b
1134 patching file b
1139 adding b
1135 adding b
1140 applied to working directory
1136 applied to working directory
1141 $ hg st -C
1137 $ hg st -C
1142 A b
1138 A b
1143 R a
1139 R a
1144 $ cd ..
1140 $ cd ..
1145
1141
1146
1142
1147 Issue1495: add empty file from the end of patch
1143 Issue1495: add empty file from the end of patch
1148
1144
1149 $ hg init addemptyend
1145 $ hg init addemptyend
1150 $ cd addemptyend
1146 $ cd addemptyend
1151 $ touch a
1147 $ touch a
1152 $ hg addremove
1148 $ hg addremove
1153 adding a
1149 adding a
1154 $ hg ci -m "commit"
1150 $ hg ci -m "commit"
1155 $ cat > a.patch <<EOF
1151 $ cat > a.patch <<EOF
1156 > add a, b
1152 > add a, b
1157 > diff --git a/a b/a
1153 > diff --git a/a b/a
1158 > --- a/a
1154 > --- a/a
1159 > +++ b/a
1155 > +++ b/a
1160 > @@ -0,0 +1,1 @@
1156 > @@ -0,0 +1,1 @@
1161 > +a
1157 > +a
1162 > diff --git a/b b/b
1158 > diff --git a/b b/b
1163 > new file mode 100644
1159 > new file mode 100644
1164 > EOF
1160 > EOF
1165 $ hg import --no-commit a.patch
1161 $ hg import --no-commit a.patch
1166 applying a.patch
1162 applying a.patch
1167
1163
1168 apply a good patch followed by an empty patch (mainly to ensure
1164 apply a good patch followed by an empty patch (mainly to ensure
1169 that dirstate is *not* updated when import crashes)
1165 that dirstate is *not* updated when import crashes)
1170 $ hg update -q -C .
1166 $ hg update -q -C .
1171 $ rm b
1167 $ rm b
1172 $ touch empty.patch
1168 $ touch empty.patch
1173 $ hg import a.patch empty.patch
1169 $ hg import a.patch empty.patch
1174 applying a.patch
1170 applying a.patch
1175 applying empty.patch
1171 applying empty.patch
1176 transaction abort!
1172 transaction abort!
1177 rollback completed
1173 rollback completed
1178 abort: empty.patch: no diffs found
1174 abort: empty.patch: no diffs found
1179 [10]
1175 [10]
1180 $ hg tip --template '{rev} {desc|firstline}\n'
1176 $ hg tip --template '{rev} {desc|firstline}\n'
1181 0 commit
1177 0 commit
1182 $ hg -q status
1178 $ hg -q status
1183 M a
1179 M a
1184 $ cd ..
1180 $ cd ..
1185
1181
1186 create file when source is not /dev/null
1182 create file when source is not /dev/null
1187
1183
1188 $ cat > create.patch <<EOF
1184 $ cat > create.patch <<EOF
1189 > diff -Naur proj-orig/foo proj-new/foo
1185 > diff -Naur proj-orig/foo proj-new/foo
1190 > --- proj-orig/foo 1969-12-31 16:00:00.000000000 -0800
1186 > --- proj-orig/foo 1969-12-31 16:00:00.000000000 -0800
1191 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
1187 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
1192 > @@ -0,0 +1,1 @@
1188 > @@ -0,0 +1,1 @@
1193 > +a
1189 > +a
1194 > EOF
1190 > EOF
1195
1191
1196 some people have patches like the following too
1192 some people have patches like the following too
1197
1193
1198 $ cat > create2.patch <<EOF
1194 $ cat > create2.patch <<EOF
1199 > diff -Naur proj-orig/foo proj-new/foo
1195 > diff -Naur proj-orig/foo proj-new/foo
1200 > --- proj-orig/foo.orig 1969-12-31 16:00:00.000000000 -0800
1196 > --- proj-orig/foo.orig 1969-12-31 16:00:00.000000000 -0800
1201 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
1197 > +++ proj-new/foo 2009-07-17 16:50:45.801368000 -0700
1202 > @@ -0,0 +1,1 @@
1198 > @@ -0,0 +1,1 @@
1203 > +a
1199 > +a
1204 > EOF
1200 > EOF
1205 $ hg init oddcreate
1201 $ hg init oddcreate
1206 $ cd oddcreate
1202 $ cd oddcreate
1207 $ hg import --no-commit ../create.patch
1203 $ hg import --no-commit ../create.patch
1208 applying ../create.patch
1204 applying ../create.patch
1209 $ cat foo
1205 $ cat foo
1210 a
1206 a
1211 $ rm foo
1207 $ rm foo
1212 $ hg revert foo
1208 $ hg revert foo
1213 $ hg import --no-commit ../create2.patch
1209 $ hg import --no-commit ../create2.patch
1214 applying ../create2.patch
1210 applying ../create2.patch
1215 $ cat foo
1211 $ cat foo
1216 a
1212 a
1217
1213
1218 $ cd ..
1214 $ cd ..
1219
1215
1220 Issue1859: first line mistaken for email headers
1216 Issue1859: first line mistaken for email headers
1221
1217
1222 $ hg init emailconfusion
1218 $ hg init emailconfusion
1223 $ cd emailconfusion
1219 $ cd emailconfusion
1224 $ cat > a.patch <<EOF
1220 $ cat > a.patch <<EOF
1225 > module: summary
1221 > module: summary
1226 >
1222 >
1227 > description
1223 > description
1228 >
1224 >
1229 >
1225 >
1230 > diff -r 000000000000 -r 9b4c1e343b55 test.txt
1226 > diff -r 000000000000 -r 9b4c1e343b55 test.txt
1231 > --- /dev/null
1227 > --- /dev/null
1232 > +++ b/a
1228 > +++ b/a
1233 > @@ -0,0 +1,1 @@
1229 > @@ -0,0 +1,1 @@
1234 > +a
1230 > +a
1235 > EOF
1231 > EOF
1236 $ hg import -d '0 0' a.patch
1232 $ hg import -d '0 0' a.patch
1237 applying a.patch
1233 applying a.patch
1238 $ hg parents -v
1234 $ hg parents -v
1239 changeset: 0:5a681217c0ad
1235 changeset: 0:5a681217c0ad
1240 tag: tip
1236 tag: tip
1241 user: test
1237 user: test
1242 date: Thu Jan 01 00:00:00 1970 +0000
1238 date: Thu Jan 01 00:00:00 1970 +0000
1243 files: a
1239 files: a
1244 description:
1240 description:
1245 module: summary
1241 module: summary
1246
1242
1247 description
1243 description
1248
1244
1249
1245
1250 $ cd ..
1246 $ cd ..
1251
1247
1252
1248
1253 in commit message
1249 in commit message
1254
1250
1255 $ hg init commitconfusion
1251 $ hg init commitconfusion
1256 $ cd commitconfusion
1252 $ cd commitconfusion
1257 $ cat > a.patch <<EOF
1253 $ cat > a.patch <<EOF
1258 > module: summary
1254 > module: summary
1259 >
1255 >
1260 > --- description
1256 > --- description
1261 >
1257 >
1262 > diff --git a/a b/a
1258 > diff --git a/a b/a
1263 > new file mode 100644
1259 > new file mode 100644
1264 > --- /dev/null
1260 > --- /dev/null
1265 > +++ b/a
1261 > +++ b/a
1266 > @@ -0,0 +1,1 @@
1262 > @@ -0,0 +1,1 @@
1267 > +a
1263 > +a
1268 > EOF
1264 > EOF
1269 > hg import -d '0 0' a.patch
1265 > hg import -d '0 0' a.patch
1270 > hg parents -v
1266 > hg parents -v
1271 > cd ..
1267 > cd ..
1272 >
1268 >
1273 > echo '% tricky header splitting'
1269 > echo '% tricky header splitting'
1274 > cat > trickyheaders.patch <<EOF
1270 > cat > trickyheaders.patch <<EOF
1275 > From: User A <user@a>
1271 > From: User A <user@a>
1276 > Subject: [PATCH] from: tricky!
1272 > Subject: [PATCH] from: tricky!
1277 >
1273 >
1278 > # HG changeset patch
1274 > # HG changeset patch
1279 > # User User B
1275 > # User User B
1280 > # Date 1266264441 18000
1276 > # Date 1266264441 18000
1281 > # Branch stable
1277 > # Branch stable
1282 > # Node ID f2be6a1170ac83bf31cb4ae0bad00d7678115bc0
1278 > # Node ID f2be6a1170ac83bf31cb4ae0bad00d7678115bc0
1283 > # Parent 0000000000000000000000000000000000000000
1279 > # Parent 0000000000000000000000000000000000000000
1284 > from: tricky!
1280 > from: tricky!
1285 >
1281 >
1286 > That is not a header.
1282 > That is not a header.
1287 >
1283 >
1288 > diff -r 000000000000 -r f2be6a1170ac foo
1284 > diff -r 000000000000 -r f2be6a1170ac foo
1289 > --- /dev/null
1285 > --- /dev/null
1290 > +++ b/foo
1286 > +++ b/foo
1291 > @@ -0,0 +1,1 @@
1287 > @@ -0,0 +1,1 @@
1292 > +foo
1288 > +foo
1293 > EOF
1289 > EOF
1294 applying a.patch
1290 applying a.patch
1295 changeset: 0:f34d9187897d
1291 changeset: 0:f34d9187897d
1296 tag: tip
1292 tag: tip
1297 user: test
1293 user: test
1298 date: Thu Jan 01 00:00:00 1970 +0000
1294 date: Thu Jan 01 00:00:00 1970 +0000
1299 files: a
1295 files: a
1300 description:
1296 description:
1301 module: summary
1297 module: summary
1302
1298
1303
1299
1304 % tricky header splitting
1300 % tricky header splitting
1305
1301
1306 $ hg init trickyheaders
1302 $ hg init trickyheaders
1307 $ cd trickyheaders
1303 $ cd trickyheaders
1308 $ hg import -d '0 0' ../trickyheaders.patch
1304 $ hg import -d '0 0' ../trickyheaders.patch
1309 applying ../trickyheaders.patch
1305 applying ../trickyheaders.patch
1310 $ hg export --git tip
1306 $ hg export --git tip
1311 # HG changeset patch
1307 # HG changeset patch
1312 # User User B
1308 # User User B
1313 # Date 0 0
1309 # Date 0 0
1314 # Thu Jan 01 00:00:00 1970 +0000
1310 # Thu Jan 01 00:00:00 1970 +0000
1315 # Node ID eb56ab91903632294ac504838508cb370c0901d2
1311 # Node ID eb56ab91903632294ac504838508cb370c0901d2
1316 # Parent 0000000000000000000000000000000000000000
1312 # Parent 0000000000000000000000000000000000000000
1317 from: tricky!
1313 from: tricky!
1318
1314
1319 That is not a header.
1315 That is not a header.
1320
1316
1321 diff --git a/foo b/foo
1317 diff --git a/foo b/foo
1322 new file mode 100644
1318 new file mode 100644
1323 --- /dev/null
1319 --- /dev/null
1324 +++ b/foo
1320 +++ b/foo
1325 @@ -0,0 +1,1 @@
1321 @@ -0,0 +1,1 @@
1326 +foo
1322 +foo
1327 $ cd ..
1323 $ cd ..
1328
1324
1329
1325
1330 Issue2102: hg export and hg import speak different languages
1326 Issue2102: hg export and hg import speak different languages
1331
1327
1332 $ hg init issue2102
1328 $ hg init issue2102
1333 $ cd issue2102
1329 $ cd issue2102
1334 $ mkdir -p src/cmd/gc
1330 $ mkdir -p src/cmd/gc
1335 $ touch src/cmd/gc/mksys.bash
1331 $ touch src/cmd/gc/mksys.bash
1336 $ hg ci -Am init
1332 $ hg ci -Am init
1337 adding src/cmd/gc/mksys.bash
1333 adding src/cmd/gc/mksys.bash
1338 $ hg import - <<EOF
1334 $ hg import - <<EOF
1339 > # HG changeset patch
1335 > # HG changeset patch
1340 > # User Rob Pike
1336 > # User Rob Pike
1341 > # Date 1216685449 25200
1337 > # Date 1216685449 25200
1342 > # Node ID 03aa2b206f499ad6eb50e6e207b9e710d6409c98
1338 > # Node ID 03aa2b206f499ad6eb50e6e207b9e710d6409c98
1343 > # Parent 93d10138ad8df586827ca90b4ddb5033e21a3a84
1339 > # Parent 93d10138ad8df586827ca90b4ddb5033e21a3a84
1344 > help management of empty pkg and lib directories in perforce
1340 > help management of empty pkg and lib directories in perforce
1345 >
1341 >
1346 > R=gri
1342 > R=gri
1347 > DELTA=4 (4 added, 0 deleted, 0 changed)
1343 > DELTA=4 (4 added, 0 deleted, 0 changed)
1348 > OCL=13328
1344 > OCL=13328
1349 > CL=13328
1345 > CL=13328
1350 >
1346 >
1351 > diff --git a/lib/place-holder b/lib/place-holder
1347 > diff --git a/lib/place-holder b/lib/place-holder
1352 > new file mode 100644
1348 > new file mode 100644
1353 > --- /dev/null
1349 > --- /dev/null
1354 > +++ b/lib/place-holder
1350 > +++ b/lib/place-holder
1355 > @@ -0,0 +1,2 @@
1351 > @@ -0,0 +1,2 @@
1356 > +perforce does not maintain empty directories.
1352 > +perforce does not maintain empty directories.
1357 > +this file helps.
1353 > +this file helps.
1358 > diff --git a/pkg/place-holder b/pkg/place-holder
1354 > diff --git a/pkg/place-holder b/pkg/place-holder
1359 > new file mode 100644
1355 > new file mode 100644
1360 > --- /dev/null
1356 > --- /dev/null
1361 > +++ b/pkg/place-holder
1357 > +++ b/pkg/place-holder
1362 > @@ -0,0 +1,2 @@
1358 > @@ -0,0 +1,2 @@
1363 > +perforce does not maintain empty directories.
1359 > +perforce does not maintain empty directories.
1364 > +this file helps.
1360 > +this file helps.
1365 > diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
1361 > diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
1366 > old mode 100644
1362 > old mode 100644
1367 > new mode 100755
1363 > new mode 100755
1368 > EOF
1364 > EOF
1369 applying patch from stdin
1365 applying patch from stdin
1370
1366
1371 #if execbit
1367 #if execbit
1372
1368
1373 $ hg sum
1369 $ hg sum
1374 parent: 1:d59915696727 tip
1370 parent: 1:d59915696727 tip
1375 help management of empty pkg and lib directories in perforce
1371 help management of empty pkg and lib directories in perforce
1376 branch: default
1372 branch: default
1377 commit: (clean)
1373 commit: (clean)
1378 update: (current)
1374 update: (current)
1379 phases: 2 draft
1375 phases: 2 draft
1380
1376
1381 $ hg diff --git -c tip
1377 $ hg diff --git -c tip
1382 diff --git a/lib/place-holder b/lib/place-holder
1378 diff --git a/lib/place-holder b/lib/place-holder
1383 new file mode 100644
1379 new file mode 100644
1384 --- /dev/null
1380 --- /dev/null
1385 +++ b/lib/place-holder
1381 +++ b/lib/place-holder
1386 @@ -0,0 +1,2 @@
1382 @@ -0,0 +1,2 @@
1387 +perforce does not maintain empty directories.
1383 +perforce does not maintain empty directories.
1388 +this file helps.
1384 +this file helps.
1389 diff --git a/pkg/place-holder b/pkg/place-holder
1385 diff --git a/pkg/place-holder b/pkg/place-holder
1390 new file mode 100644
1386 new file mode 100644
1391 --- /dev/null
1387 --- /dev/null
1392 +++ b/pkg/place-holder
1388 +++ b/pkg/place-holder
1393 @@ -0,0 +1,2 @@
1389 @@ -0,0 +1,2 @@
1394 +perforce does not maintain empty directories.
1390 +perforce does not maintain empty directories.
1395 +this file helps.
1391 +this file helps.
1396 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
1392 diff --git a/src/cmd/gc/mksys.bash b/src/cmd/gc/mksys.bash
1397 old mode 100644
1393 old mode 100644
1398 new mode 100755
1394 new mode 100755
1399
1395
1400 #else
1396 #else
1401
1397
1402 $ hg sum
1398 $ hg sum
1403 parent: 1:28f089cc9ccc tip
1399 parent: 1:28f089cc9ccc tip
1404 help management of empty pkg and lib directories in perforce
1400 help management of empty pkg and lib directories in perforce
1405 branch: default
1401 branch: default
1406 commit: (clean)
1402 commit: (clean)
1407 update: (current)
1403 update: (current)
1408 phases: 2 draft
1404 phases: 2 draft
1409
1405
1410 $ hg diff --git -c tip
1406 $ hg diff --git -c tip
1411 diff --git a/lib/place-holder b/lib/place-holder
1407 diff --git a/lib/place-holder b/lib/place-holder
1412 new file mode 100644
1408 new file mode 100644
1413 --- /dev/null
1409 --- /dev/null
1414 +++ b/lib/place-holder
1410 +++ b/lib/place-holder
1415 @@ -0,0 +1,2 @@
1411 @@ -0,0 +1,2 @@
1416 +perforce does not maintain empty directories.
1412 +perforce does not maintain empty directories.
1417 +this file helps.
1413 +this file helps.
1418 diff --git a/pkg/place-holder b/pkg/place-holder
1414 diff --git a/pkg/place-holder b/pkg/place-holder
1419 new file mode 100644
1415 new file mode 100644
1420 --- /dev/null
1416 --- /dev/null
1421 +++ b/pkg/place-holder
1417 +++ b/pkg/place-holder
1422 @@ -0,0 +1,2 @@
1418 @@ -0,0 +1,2 @@
1423 +perforce does not maintain empty directories.
1419 +perforce does not maintain empty directories.
1424 +this file helps.
1420 +this file helps.
1425
1421
1426 /* The mode change for mksys.bash is missing here, because on platforms */
1422 /* The mode change for mksys.bash is missing here, because on platforms */
1427 /* that don't support execbits, mode changes in patches are ignored when */
1423 /* that don't support execbits, mode changes in patches are ignored when */
1428 /* they are imported. This is obviously also the reason for why the hash */
1424 /* they are imported. This is obviously also the reason for why the hash */
1429 /* in the created changeset is different to the one you see above the */
1425 /* in the created changeset is different to the one you see above the */
1430 /* #else clause */
1426 /* #else clause */
1431
1427
1432 #endif
1428 #endif
1433 $ cd ..
1429 $ cd ..
1434
1430
1435
1431
1436 diff lines looking like headers
1432 diff lines looking like headers
1437
1433
1438 $ hg init difflineslikeheaders
1434 $ hg init difflineslikeheaders
1439 $ cd difflineslikeheaders
1435 $ cd difflineslikeheaders
1440 $ echo a >a
1436 $ echo a >a
1441 $ echo b >b
1437 $ echo b >b
1442 $ echo c >c
1438 $ echo c >c
1443 $ hg ci -Am1
1439 $ hg ci -Am1
1444 adding a
1440 adding a
1445 adding b
1441 adding b
1446 adding c
1442 adding c
1447
1443
1448 $ echo "key: value" >>a
1444 $ echo "key: value" >>a
1449 $ echo "key: value" >>b
1445 $ echo "key: value" >>b
1450 $ echo "foo" >>c
1446 $ echo "foo" >>c
1451 $ hg ci -m2
1447 $ hg ci -m2
1452
1448
1453 $ hg up -C 0
1449 $ hg up -C 0
1454 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1450 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1455 $ hg diff --git -c1 >want
1451 $ hg diff --git -c1 >want
1456 $ hg diff -c1 | hg import --no-commit -
1452 $ hg diff -c1 | hg import --no-commit -
1457 applying patch from stdin
1453 applying patch from stdin
1458 $ hg diff --git >have
1454 $ hg diff --git >have
1459 $ diff want have
1455 $ diff want have
1460 $ cd ..
1456 $ cd ..
1461
1457
1462 import a unified diff with no lines of context (diff -U0)
1458 import a unified diff with no lines of context (diff -U0)
1463
1459
1464 $ hg init diffzero
1460 $ hg init diffzero
1465 $ cd diffzero
1461 $ cd diffzero
1466 $ cat > f << EOF
1462 $ cat > f << EOF
1467 > c2
1463 > c2
1468 > c4
1464 > c4
1469 > c5
1465 > c5
1470 > EOF
1466 > EOF
1471 $ hg commit -Am0
1467 $ hg commit -Am0
1472 adding f
1468 adding f
1473
1469
1474 $ hg import --no-commit - << EOF
1470 $ hg import --no-commit - << EOF
1475 > # HG changeset patch
1471 > # HG changeset patch
1476 > # User test
1472 > # User test
1477 > # Date 0 0
1473 > # Date 0 0
1478 > # Node ID f4974ab632f3dee767567b0576c0ec9a4508575c
1474 > # Node ID f4974ab632f3dee767567b0576c0ec9a4508575c
1479 > # Parent 8679a12a975b819fae5f7ad3853a2886d143d794
1475 > # Parent 8679a12a975b819fae5f7ad3853a2886d143d794
1480 > 1
1476 > 1
1481 > diff -r 8679a12a975b -r f4974ab632f3 f
1477 > diff -r 8679a12a975b -r f4974ab632f3 f
1482 > --- a/f Thu Jan 01 00:00:00 1970 +0000
1478 > --- a/f Thu Jan 01 00:00:00 1970 +0000
1483 > +++ b/f Thu Jan 01 00:00:00 1970 +0000
1479 > +++ b/f Thu Jan 01 00:00:00 1970 +0000
1484 > @@ -0,0 +1,1 @@
1480 > @@ -0,0 +1,1 @@
1485 > +c1
1481 > +c1
1486 > @@ -1,0 +3,1 @@
1482 > @@ -1,0 +3,1 @@
1487 > +c3
1483 > +c3
1488 > @@ -3,1 +4,0 @@
1484 > @@ -3,1 +4,0 @@
1489 > -c5
1485 > -c5
1490 > EOF
1486 > EOF
1491 applying patch from stdin
1487 applying patch from stdin
1492
1488
1493 $ cat f
1489 $ cat f
1494 c1
1490 c1
1495 c2
1491 c2
1496 c3
1492 c3
1497 c4
1493 c4
1498
1494
1499 $ cd ..
1495 $ cd ..
1500
1496
1501 commit message that looks like a diff header (issue1879)
1497 commit message that looks like a diff header (issue1879)
1502
1498
1503 $ hg init headerlikemsg
1499 $ hg init headerlikemsg
1504 $ cd headerlikemsg
1500 $ cd headerlikemsg
1505 $ touch empty
1501 $ touch empty
1506 $ echo nonempty >> nonempty
1502 $ echo nonempty >> nonempty
1507 $ hg ci -qAl - <<EOF
1503 $ hg ci -qAl - <<EOF
1508 > blah blah
1504 > blah blah
1509 > diff blah
1505 > diff blah
1510 > blah blah
1506 > blah blah
1511 > EOF
1507 > EOF
1512 $ hg --config diff.git=1 log -pv
1508 $ hg --config diff.git=1 log -pv
1513 changeset: 0:c6ef204ef767
1509 changeset: 0:c6ef204ef767
1514 tag: tip
1510 tag: tip
1515 user: test
1511 user: test
1516 date: Thu Jan 01 00:00:00 1970 +0000
1512 date: Thu Jan 01 00:00:00 1970 +0000
1517 files: empty nonempty
1513 files: empty nonempty
1518 description:
1514 description:
1519 blah blah
1515 blah blah
1520 diff blah
1516 diff blah
1521 blah blah
1517 blah blah
1522
1518
1523
1519
1524 diff --git a/empty b/empty
1520 diff --git a/empty b/empty
1525 new file mode 100644
1521 new file mode 100644
1526 diff --git a/nonempty b/nonempty
1522 diff --git a/nonempty b/nonempty
1527 new file mode 100644
1523 new file mode 100644
1528 --- /dev/null
1524 --- /dev/null
1529 +++ b/nonempty
1525 +++ b/nonempty
1530 @@ -0,0 +1,1 @@
1526 @@ -0,0 +1,1 @@
1531 +nonempty
1527 +nonempty
1532
1528
1533
1529
1534 (without --git, empty file is lost, but commit message should be preserved)
1530 (without --git, empty file is lost, but commit message should be preserved)
1535
1531
1536 $ hg init plain
1532 $ hg init plain
1537 $ hg export 0 | hg -R plain import -
1533 $ hg export 0 | hg -R plain import -
1538 applying patch from stdin
1534 applying patch from stdin
1539 $ hg --config diff.git=1 -R plain log -pv
1535 $ hg --config diff.git=1 -R plain log -pv
1540 changeset: 0:60a2d231e71f
1536 changeset: 0:60a2d231e71f
1541 tag: tip
1537 tag: tip
1542 user: test
1538 user: test
1543 date: Thu Jan 01 00:00:00 1970 +0000
1539 date: Thu Jan 01 00:00:00 1970 +0000
1544 files: nonempty
1540 files: nonempty
1545 description:
1541 description:
1546 blah blah
1542 blah blah
1547 diff blah
1543 diff blah
1548 blah blah
1544 blah blah
1549
1545
1550
1546
1551 diff --git a/nonempty b/nonempty
1547 diff --git a/nonempty b/nonempty
1552 new file mode 100644
1548 new file mode 100644
1553 --- /dev/null
1549 --- /dev/null
1554 +++ b/nonempty
1550 +++ b/nonempty
1555 @@ -0,0 +1,1 @@
1551 @@ -0,0 +1,1 @@
1556 +nonempty
1552 +nonempty
1557
1553
1558
1554
1559 (with --git, patch contents should be fully preserved)
1555 (with --git, patch contents should be fully preserved)
1560
1556
1561 $ hg init git
1557 $ hg init git
1562 $ hg --config diff.git=1 export 0 | hg -R git import -
1558 $ hg --config diff.git=1 export 0 | hg -R git import -
1563 applying patch from stdin
1559 applying patch from stdin
1564 $ hg --config diff.git=1 -R git log -pv
1560 $ hg --config diff.git=1 -R git log -pv
1565 changeset: 0:c6ef204ef767
1561 changeset: 0:c6ef204ef767
1566 tag: tip
1562 tag: tip
1567 user: test
1563 user: test
1568 date: Thu Jan 01 00:00:00 1970 +0000
1564 date: Thu Jan 01 00:00:00 1970 +0000
1569 files: empty nonempty
1565 files: empty nonempty
1570 description:
1566 description:
1571 blah blah
1567 blah blah
1572 diff blah
1568 diff blah
1573 blah blah
1569 blah blah
1574
1570
1575
1571
1576 diff --git a/empty b/empty
1572 diff --git a/empty b/empty
1577 new file mode 100644
1573 new file mode 100644
1578 diff --git a/nonempty b/nonempty
1574 diff --git a/nonempty b/nonempty
1579 new file mode 100644
1575 new file mode 100644
1580 --- /dev/null
1576 --- /dev/null
1581 +++ b/nonempty
1577 +++ b/nonempty
1582 @@ -0,0 +1,1 @@
1578 @@ -0,0 +1,1 @@
1583 +nonempty
1579 +nonempty
1584
1580
1585
1581
1586 $ cd ..
1582 $ cd ..
1587
1583
1588 no segfault while importing a unified diff which start line is zero but chunk
1584 no segfault while importing a unified diff which start line is zero but chunk
1589 size is non-zero
1585 size is non-zero
1590
1586
1591 $ hg init startlinezero
1587 $ hg init startlinezero
1592 $ cd startlinezero
1588 $ cd startlinezero
1593 $ echo foo > foo
1589 $ echo foo > foo
1594 $ hg commit -Amfoo
1590 $ hg commit -Amfoo
1595 adding foo
1591 adding foo
1596
1592
1597 $ hg import --no-commit - << EOF
1593 $ hg import --no-commit - << EOF
1598 > diff a/foo b/foo
1594 > diff a/foo b/foo
1599 > --- a/foo
1595 > --- a/foo
1600 > +++ b/foo
1596 > +++ b/foo
1601 > @@ -0,1 +0,1 @@
1597 > @@ -0,1 +0,1 @@
1602 > foo
1598 > foo
1603 > EOF
1599 > EOF
1604 applying patch from stdin
1600 applying patch from stdin
1605
1601
1606 $ cd ..
1602 $ cd ..
1607
1603
1608 Test corner case involving fuzz and skew
1604 Test corner case involving fuzz and skew
1609
1605
1610 $ hg init morecornercases
1606 $ hg init morecornercases
1611 $ cd morecornercases
1607 $ cd morecornercases
1612
1608
1613 $ cat > 01-no-context-beginning-of-file.diff <<EOF
1609 $ cat > 01-no-context-beginning-of-file.diff <<EOF
1614 > diff --git a/a b/a
1610 > diff --git a/a b/a
1615 > --- a/a
1611 > --- a/a
1616 > +++ b/a
1612 > +++ b/a
1617 > @@ -1,0 +1,1 @@
1613 > @@ -1,0 +1,1 @@
1618 > +line
1614 > +line
1619 > EOF
1615 > EOF
1620
1616
1621 $ cat > 02-no-context-middle-of-file.diff <<EOF
1617 $ cat > 02-no-context-middle-of-file.diff <<EOF
1622 > diff --git a/a b/a
1618 > diff --git a/a b/a
1623 > --- a/a
1619 > --- a/a
1624 > +++ b/a
1620 > +++ b/a
1625 > @@ -1,1 +1,1 @@
1621 > @@ -1,1 +1,1 @@
1626 > -2
1622 > -2
1627 > +add some skew
1623 > +add some skew
1628 > @@ -2,0 +2,1 @@
1624 > @@ -2,0 +2,1 @@
1629 > +line
1625 > +line
1630 > EOF
1626 > EOF
1631
1627
1632 $ cat > 03-no-context-end-of-file.diff <<EOF
1628 $ cat > 03-no-context-end-of-file.diff <<EOF
1633 > diff --git a/a b/a
1629 > diff --git a/a b/a
1634 > --- a/a
1630 > --- a/a
1635 > +++ b/a
1631 > +++ b/a
1636 > @@ -10,0 +10,1 @@
1632 > @@ -10,0 +10,1 @@
1637 > +line
1633 > +line
1638 > EOF
1634 > EOF
1639
1635
1640 $ cat > 04-middle-of-file-completely-fuzzed.diff <<EOF
1636 $ cat > 04-middle-of-file-completely-fuzzed.diff <<EOF
1641 > diff --git a/a b/a
1637 > diff --git a/a b/a
1642 > --- a/a
1638 > --- a/a
1643 > +++ b/a
1639 > +++ b/a
1644 > @@ -1,1 +1,1 @@
1640 > @@ -1,1 +1,1 @@
1645 > -2
1641 > -2
1646 > +add some skew
1642 > +add some skew
1647 > @@ -2,2 +2,3 @@
1643 > @@ -2,2 +2,3 @@
1648 > not matching, should fuzz
1644 > not matching, should fuzz
1649 > ... a bit
1645 > ... a bit
1650 > +line
1646 > +line
1651 > EOF
1647 > EOF
1652
1648
1653 $ cat > a <<EOF
1649 $ cat > a <<EOF
1654 > 1
1650 > 1
1655 > 2
1651 > 2
1656 > 3
1652 > 3
1657 > 4
1653 > 4
1658 > EOF
1654 > EOF
1659 $ hg ci -Am adda a
1655 $ hg ci -Am adda a
1660 $ for p in *.diff; do
1656 $ for p in *.diff; do
1661 > hg import -v --no-commit $p
1657 > hg import -v --no-commit $p
1662 > cat a
1658 > cat a
1663 > hg revert -aqC a
1659 > hg revert -aqC a
1664 > # patch -p1 < $p
1660 > # patch -p1 < $p
1665 > # cat a
1661 > # cat a
1666 > # hg revert -aC a
1662 > # hg revert -aC a
1667 > done
1663 > done
1668 applying 01-no-context-beginning-of-file.diff
1664 applying 01-no-context-beginning-of-file.diff
1669 patching file a
1665 patching file a
1670 applied to working directory
1666 applied to working directory
1671 1
1667 1
1672 line
1668 line
1673 2
1669 2
1674 3
1670 3
1675 4
1671 4
1676 applying 02-no-context-middle-of-file.diff
1672 applying 02-no-context-middle-of-file.diff
1677 patching file a
1673 patching file a
1678 Hunk #1 succeeded at 2 (offset 1 lines).
1674 Hunk #1 succeeded at 2 (offset 1 lines).
1679 Hunk #2 succeeded at 4 (offset 1 lines).
1675 Hunk #2 succeeded at 4 (offset 1 lines).
1680 applied to working directory
1676 applied to working directory
1681 1
1677 1
1682 add some skew
1678 add some skew
1683 3
1679 3
1684 line
1680 line
1685 4
1681 4
1686 applying 03-no-context-end-of-file.diff
1682 applying 03-no-context-end-of-file.diff
1687 patching file a
1683 patching file a
1688 Hunk #1 succeeded at 5 (offset -6 lines).
1684 Hunk #1 succeeded at 5 (offset -6 lines).
1689 applied to working directory
1685 applied to working directory
1690 1
1686 1
1691 2
1687 2
1692 3
1688 3
1693 4
1689 4
1694 line
1690 line
1695 applying 04-middle-of-file-completely-fuzzed.diff
1691 applying 04-middle-of-file-completely-fuzzed.diff
1696 patching file a
1692 patching file a
1697 Hunk #1 succeeded at 2 (offset 1 lines).
1693 Hunk #1 succeeded at 2 (offset 1 lines).
1698 Hunk #2 succeeded at 5 with fuzz 2 (offset 1 lines).
1694 Hunk #2 succeeded at 5 with fuzz 2 (offset 1 lines).
1699 applied to working directory
1695 applied to working directory
1700 1
1696 1
1701 add some skew
1697 add some skew
1702 3
1698 3
1703 4
1699 4
1704 line
1700 line
1705 $ cd ..
1701 $ cd ..
1706
1702
1707 Test partial application
1703 Test partial application
1708 ------------------------
1704 ------------------------
1709
1705
1710 prepare a stack of patches depending on each other
1706 prepare a stack of patches depending on each other
1711
1707
1712 $ hg init partial
1708 $ hg init partial
1713 $ cd partial
1709 $ cd partial
1714 $ cat << EOF > a
1710 $ cat << EOF > a
1715 > one
1711 > one
1716 > two
1712 > two
1717 > three
1713 > three
1718 > four
1714 > four
1719 > five
1715 > five
1720 > six
1716 > six
1721 > seven
1717 > seven
1722 > EOF
1718 > EOF
1723 $ hg add a
1719 $ hg add a
1724 $ echo 'b' > b
1720 $ echo 'b' > b
1725 $ hg add b
1721 $ hg add b
1726 $ hg commit -m 'initial' -u Babar
1722 $ hg commit -m 'initial' -u Babar
1727 $ cat << EOF > a
1723 $ cat << EOF > a
1728 > one
1724 > one
1729 > two
1725 > two
1730 > 3
1726 > 3
1731 > four
1727 > four
1732 > five
1728 > five
1733 > six
1729 > six
1734 > seven
1730 > seven
1735 > EOF
1731 > EOF
1736 $ hg commit -m 'three' -u Celeste
1732 $ hg commit -m 'three' -u Celeste
1737 $ cat << EOF > a
1733 $ cat << EOF > a
1738 > one
1734 > one
1739 > two
1735 > two
1740 > 3
1736 > 3
1741 > 4
1737 > 4
1742 > five
1738 > five
1743 > six
1739 > six
1744 > seven
1740 > seven
1745 > EOF
1741 > EOF
1746 $ hg commit -m 'four' -u Rataxes
1742 $ hg commit -m 'four' -u Rataxes
1747 $ cat << EOF > a
1743 $ cat << EOF > a
1748 > one
1744 > one
1749 > two
1745 > two
1750 > 3
1746 > 3
1751 > 4
1747 > 4
1752 > 5
1748 > 5
1753 > six
1749 > six
1754 > seven
1750 > seven
1755 > EOF
1751 > EOF
1756 $ echo bb >> b
1752 $ echo bb >> b
1757 $ hg commit -m 'five' -u Arthur
1753 $ hg commit -m 'five' -u Arthur
1758 $ echo 'Babar' > jungle
1754 $ echo 'Babar' > jungle
1759 $ hg add jungle
1755 $ hg add jungle
1760 $ hg ci -m 'jungle' -u Zephir
1756 $ hg ci -m 'jungle' -u Zephir
1761 $ echo 'Celeste' >> jungle
1757 $ echo 'Celeste' >> jungle
1762 $ hg ci -m 'extended jungle' -u Cornelius
1758 $ hg ci -m 'extended jungle' -u Cornelius
1763 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1759 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1764 @ extended jungle [Cornelius] 1: +1/-0
1760 @ extended jungle [Cornelius] 1: +1/-0
1765 |
1761 |
1766 o jungle [Zephir] 1: +1/-0
1762 o jungle [Zephir] 1: +1/-0
1767 |
1763 |
1768 o five [Arthur] 2: +2/-1
1764 o five [Arthur] 2: +2/-1
1769 |
1765 |
1770 o four [Rataxes] 1: +1/-1
1766 o four [Rataxes] 1: +1/-1
1771 |
1767 |
1772 o three [Celeste] 1: +1/-1
1768 o three [Celeste] 1: +1/-1
1773 |
1769 |
1774 o initial [Babar] 2: +8/-0
1770 o initial [Babar] 2: +8/-0
1775
1771
1776 Adding those config options should not change the output of diffstat. Bugfix #4755.
1772 Adding those config options should not change the output of diffstat. Bugfix #4755.
1777
1773
1778 $ hg log -r . --template '{diffstat}\n'
1774 $ hg log -r . --template '{diffstat}\n'
1779 1: +1/-0
1775 1: +1/-0
1780 $ hg log -r . --template '{diffstat}\n' --config diff.git=1 \
1776 $ hg log -r . --template '{diffstat}\n' --config diff.git=1 \
1781 > --config diff.noprefix=1
1777 > --config diff.noprefix=1
1782 1: +1/-0
1778 1: +1/-0
1783
1779
1784 Importing with some success and some errors:
1780 Importing with some success and some errors:
1785
1781
1786 $ hg update --rev 'desc(initial)'
1782 $ hg update --rev 'desc(initial)'
1787 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1783 2 files updated, 0 files merged, 1 files removed, 0 files unresolved
1788 $ hg export --rev 'desc(five)' | hg import --partial -
1784 $ hg export --rev 'desc(five)' | hg import --partial -
1789 applying patch from stdin
1785 applying patch from stdin
1790 patching file a
1786 patching file a
1791 Hunk #1 FAILED at 1
1787 Hunk #1 FAILED at 1
1792 1 out of 1 hunks FAILED -- saving rejects to file a.rej
1788 1 out of 1 hunks FAILED -- saving rejects to file a.rej
1793 patch applied partially
1789 patch applied partially
1794 (fix the .rej files and run `hg commit --amend`)
1790 (fix the .rej files and run `hg commit --amend`)
1795 [1]
1791 [1]
1796
1792
1797 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1793 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1798 @ five [Arthur] 1: +1/-0
1794 @ five [Arthur] 1: +1/-0
1799 |
1795 |
1800 | o extended jungle [Cornelius] 1: +1/-0
1796 | o extended jungle [Cornelius] 1: +1/-0
1801 | |
1797 | |
1802 | o jungle [Zephir] 1: +1/-0
1798 | o jungle [Zephir] 1: +1/-0
1803 | |
1799 | |
1804 | o five [Arthur] 2: +2/-1
1800 | o five [Arthur] 2: +2/-1
1805 | |
1801 | |
1806 | o four [Rataxes] 1: +1/-1
1802 | o four [Rataxes] 1: +1/-1
1807 | |
1803 | |
1808 | o three [Celeste] 1: +1/-1
1804 | o three [Celeste] 1: +1/-1
1809 |/
1805 |/
1810 o initial [Babar] 2: +8/-0
1806 o initial [Babar] 2: +8/-0
1811
1807
1812 $ hg export
1808 $ hg export
1813 # HG changeset patch
1809 # HG changeset patch
1814 # User Arthur
1810 # User Arthur
1815 # Date 0 0
1811 # Date 0 0
1816 # Thu Jan 01 00:00:00 1970 +0000
1812 # Thu Jan 01 00:00:00 1970 +0000
1817 # Node ID 26e6446bb2526e2be1037935f5fca2b2706f1509
1813 # Node ID 26e6446bb2526e2be1037935f5fca2b2706f1509
1818 # Parent 8e4f0351909eae6b9cf68c2c076cb54c42b54b2e
1814 # Parent 8e4f0351909eae6b9cf68c2c076cb54c42b54b2e
1819 five
1815 five
1820
1816
1821 diff -r 8e4f0351909e -r 26e6446bb252 b
1817 diff -r 8e4f0351909e -r 26e6446bb252 b
1822 --- a/b Thu Jan 01 00:00:00 1970 +0000
1818 --- a/b Thu Jan 01 00:00:00 1970 +0000
1823 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1819 +++ b/b Thu Jan 01 00:00:00 1970 +0000
1824 @@ -1,1 +1,2 @@
1820 @@ -1,1 +1,2 @@
1825 b
1821 b
1826 +bb
1822 +bb
1827 $ hg status -c .
1823 $ hg status -c .
1828 C a
1824 C a
1829 C b
1825 C b
1830 $ ls -A
1826 $ ls -A
1831 .hg
1827 .hg
1832 a
1828 a
1833 a.rej
1829 a.rej
1834 b
1830 b
1835
1831
1836 Importing with zero success:
1832 Importing with zero success:
1837
1833
1838 $ hg update --rev 'desc(initial)'
1834 $ hg update --rev 'desc(initial)'
1839 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1835 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1840 $ hg export --rev 'desc(four)' | hg import --partial -
1836 $ hg export --rev 'desc(four)' | hg import --partial -
1841 applying patch from stdin
1837 applying patch from stdin
1842 patching file a
1838 patching file a
1843 Hunk #1 FAILED at 0
1839 Hunk #1 FAILED at 0
1844 1 out of 1 hunks FAILED -- saving rejects to file a.rej
1840 1 out of 1 hunks FAILED -- saving rejects to file a.rej
1845 patch applied partially
1841 patch applied partially
1846 (fix the .rej files and run `hg commit --amend`)
1842 (fix the .rej files and run `hg commit --amend`)
1847 [1]
1843 [1]
1848
1844
1849 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1845 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1850 @ four [Rataxes] 0: +0/-0
1846 @ four [Rataxes] 0: +0/-0
1851 |
1847 |
1852 | o five [Arthur] 1: +1/-0
1848 | o five [Arthur] 1: +1/-0
1853 |/
1849 |/
1854 | o extended jungle [Cornelius] 1: +1/-0
1850 | o extended jungle [Cornelius] 1: +1/-0
1855 | |
1851 | |
1856 | o jungle [Zephir] 1: +1/-0
1852 | o jungle [Zephir] 1: +1/-0
1857 | |
1853 | |
1858 | o five [Arthur] 2: +2/-1
1854 | o five [Arthur] 2: +2/-1
1859 | |
1855 | |
1860 | o four [Rataxes] 1: +1/-1
1856 | o four [Rataxes] 1: +1/-1
1861 | |
1857 | |
1862 | o three [Celeste] 1: +1/-1
1858 | o three [Celeste] 1: +1/-1
1863 |/
1859 |/
1864 o initial [Babar] 2: +8/-0
1860 o initial [Babar] 2: +8/-0
1865
1861
1866 $ hg export
1862 $ hg export
1867 # HG changeset patch
1863 # HG changeset patch
1868 # User Rataxes
1864 # User Rataxes
1869 # Date 0 0
1865 # Date 0 0
1870 # Thu Jan 01 00:00:00 1970 +0000
1866 # Thu Jan 01 00:00:00 1970 +0000
1871 # Node ID cb9b1847a74d9ad52e93becaf14b98dbcc274e1e
1867 # Node ID cb9b1847a74d9ad52e93becaf14b98dbcc274e1e
1872 # Parent 8e4f0351909eae6b9cf68c2c076cb54c42b54b2e
1868 # Parent 8e4f0351909eae6b9cf68c2c076cb54c42b54b2e
1873 four
1869 four
1874
1870
1875 $ hg status -c .
1871 $ hg status -c .
1876 C a
1872 C a
1877 C b
1873 C b
1878 $ ls -A
1874 $ ls -A
1879 .hg
1875 .hg
1880 a
1876 a
1881 a.rej
1877 a.rej
1882 b
1878 b
1883
1879
1884 Importing with unknown file:
1880 Importing with unknown file:
1885
1881
1886 $ hg update --rev 'desc(initial)'
1882 $ hg update --rev 'desc(initial)'
1887 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1883 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1888 $ hg export --rev 'desc("extended jungle")' | hg import --partial -
1884 $ hg export --rev 'desc("extended jungle")' | hg import --partial -
1889 applying patch from stdin
1885 applying patch from stdin
1890 unable to find 'jungle' for patching
1886 unable to find 'jungle' for patching
1891 (use '--prefix' to apply patch relative to the current directory)
1887 (use '--prefix' to apply patch relative to the current directory)
1892 1 out of 1 hunks FAILED -- saving rejects to file jungle.rej
1888 1 out of 1 hunks FAILED -- saving rejects to file jungle.rej
1893 patch applied partially
1889 patch applied partially
1894 (fix the .rej files and run `hg commit --amend`)
1890 (fix the .rej files and run `hg commit --amend`)
1895 [1]
1891 [1]
1896
1892
1897 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1893 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1898 @ extended jungle [Cornelius] 0: +0/-0
1894 @ extended jungle [Cornelius] 0: +0/-0
1899 |
1895 |
1900 | o four [Rataxes] 0: +0/-0
1896 | o four [Rataxes] 0: +0/-0
1901 |/
1897 |/
1902 | o five [Arthur] 1: +1/-0
1898 | o five [Arthur] 1: +1/-0
1903 |/
1899 |/
1904 | o extended jungle [Cornelius] 1: +1/-0
1900 | o extended jungle [Cornelius] 1: +1/-0
1905 | |
1901 | |
1906 | o jungle [Zephir] 1: +1/-0
1902 | o jungle [Zephir] 1: +1/-0
1907 | |
1903 | |
1908 | o five [Arthur] 2: +2/-1
1904 | o five [Arthur] 2: +2/-1
1909 | |
1905 | |
1910 | o four [Rataxes] 1: +1/-1
1906 | o four [Rataxes] 1: +1/-1
1911 | |
1907 | |
1912 | o three [Celeste] 1: +1/-1
1908 | o three [Celeste] 1: +1/-1
1913 |/
1909 |/
1914 o initial [Babar] 2: +8/-0
1910 o initial [Babar] 2: +8/-0
1915
1911
1916 $ hg export
1912 $ hg export
1917 # HG changeset patch
1913 # HG changeset patch
1918 # User Cornelius
1914 # User Cornelius
1919 # Date 0 0
1915 # Date 0 0
1920 # Thu Jan 01 00:00:00 1970 +0000
1916 # Thu Jan 01 00:00:00 1970 +0000
1921 # Node ID 1fb1f86bef43c5a75918178f8d23c29fb0a7398d
1917 # Node ID 1fb1f86bef43c5a75918178f8d23c29fb0a7398d
1922 # Parent 8e4f0351909eae6b9cf68c2c076cb54c42b54b2e
1918 # Parent 8e4f0351909eae6b9cf68c2c076cb54c42b54b2e
1923 extended jungle
1919 extended jungle
1924
1920
1925 $ hg status -c .
1921 $ hg status -c .
1926 C a
1922 C a
1927 C b
1923 C b
1928 $ ls -A
1924 $ ls -A
1929 .hg
1925 .hg
1930 a
1926 a
1931 a.rej
1927 a.rej
1932 b
1928 b
1933 jungle.rej
1929 jungle.rej
1934
1930
1935 Importing multiple failing patches:
1931 Importing multiple failing patches:
1936
1932
1937 $ hg update --rev 'desc(initial)'
1933 $ hg update --rev 'desc(initial)'
1938 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1934 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
1939 $ echo 'B' > b # just to make another commit
1935 $ echo 'B' > b # just to make another commit
1940 $ hg commit -m "a new base"
1936 $ hg commit -m "a new base"
1941 created new head
1937 created new head
1942 $ hg export --rev 'desc("four") + desc("extended jungle")' | hg import --partial -
1938 $ hg export --rev 'desc("four") + desc("extended jungle")' | hg import --partial -
1943 applying patch from stdin
1939 applying patch from stdin
1944 patching file a
1940 patching file a
1945 Hunk #1 FAILED at 0
1941 Hunk #1 FAILED at 0
1946 1 out of 1 hunks FAILED -- saving rejects to file a.rej
1942 1 out of 1 hunks FAILED -- saving rejects to file a.rej
1947 patch applied partially
1943 patch applied partially
1948 (fix the .rej files and run `hg commit --amend`)
1944 (fix the .rej files and run `hg commit --amend`)
1949 [1]
1945 [1]
1950 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1946 $ hg log -G --template '{desc|firstline} [{author}] {diffstat}\n'
1951 @ four [Rataxes] 0: +0/-0
1947 @ four [Rataxes] 0: +0/-0
1952 |
1948 |
1953 o a new base [test] 1: +1/-1
1949 o a new base [test] 1: +1/-1
1954 |
1950 |
1955 | o extended jungle [Cornelius] 0: +0/-0
1951 | o extended jungle [Cornelius] 0: +0/-0
1956 |/
1952 |/
1957 | o four [Rataxes] 0: +0/-0
1953 | o four [Rataxes] 0: +0/-0
1958 |/
1954 |/
1959 | o five [Arthur] 1: +1/-0
1955 | o five [Arthur] 1: +1/-0
1960 |/
1956 |/
1961 | o extended jungle [Cornelius] 1: +1/-0
1957 | o extended jungle [Cornelius] 1: +1/-0
1962 | |
1958 | |
1963 | o jungle [Zephir] 1: +1/-0
1959 | o jungle [Zephir] 1: +1/-0
1964 | |
1960 | |
1965 | o five [Arthur] 2: +2/-1
1961 | o five [Arthur] 2: +2/-1
1966 | |
1962 | |
1967 | o four [Rataxes] 1: +1/-1
1963 | o four [Rataxes] 1: +1/-1
1968 | |
1964 | |
1969 | o three [Celeste] 1: +1/-1
1965 | o three [Celeste] 1: +1/-1
1970 |/
1966 |/
1971 o initial [Babar] 2: +8/-0
1967 o initial [Babar] 2: +8/-0
1972
1968
1973 $ hg export
1969 $ hg export
1974 # HG changeset patch
1970 # HG changeset patch
1975 # User Rataxes
1971 # User Rataxes
1976 # Date 0 0
1972 # Date 0 0
1977 # Thu Jan 01 00:00:00 1970 +0000
1973 # Thu Jan 01 00:00:00 1970 +0000
1978 # Node ID a9d7b6d0ffbb4eb12b7d5939250fcd42e8930a1d
1974 # Node ID a9d7b6d0ffbb4eb12b7d5939250fcd42e8930a1d
1979 # Parent f59f8d2e95a8ca5b1b4ca64320140da85f3b44fd
1975 # Parent f59f8d2e95a8ca5b1b4ca64320140da85f3b44fd
1980 four
1976 four
1981
1977
1982 $ hg status -c .
1978 $ hg status -c .
1983 C a
1979 C a
1984 C b
1980 C b
1985
1981
1986 Importing some extra header
1982 Importing some extra header
1987 ===========================
1983 ===========================
1988
1984
1989 $ cat > $TESTTMP/parseextra.py <<EOF
1985 $ cat > $TESTTMP/parseextra.py <<EOF
1990 > import mercurial.cmdutil
1986 > import mercurial.cmdutil
1991 > import mercurial.patch
1987 > import mercurial.patch
1992 >
1988 >
1993 > def processfoo(repo, data, extra, opts):
1989 > def processfoo(repo, data, extra, opts):
1994 > if b'foo' in data:
1990 > if b'foo' in data:
1995 > extra[b'foo'] = data[b'foo']
1991 > extra[b'foo'] = data[b'foo']
1996 > def postimport(ctx):
1992 > def postimport(ctx):
1997 > if b'foo' in ctx.extra():
1993 > if b'foo' in ctx.extra():
1998 > ctx.repo().ui.write(b'imported-foo: %s\n' % ctx.extra()[b'foo'])
1994 > ctx.repo().ui.write(b'imported-foo: %s\n' % ctx.extra()[b'foo'])
1999 >
1995 >
2000 > mercurial.patch.patchheadermap.append((b'Foo', b'foo'))
1996 > mercurial.patch.patchheadermap.append((b'Foo', b'foo'))
2001 > mercurial.cmdutil.extrapreimport.append(b'foo')
1997 > mercurial.cmdutil.extrapreimport.append(b'foo')
2002 > mercurial.cmdutil.extrapreimportmap[b'foo'] = processfoo
1998 > mercurial.cmdutil.extrapreimportmap[b'foo'] = processfoo
2003 > mercurial.cmdutil.extrapostimport.append(b'foo')
1999 > mercurial.cmdutil.extrapostimport.append(b'foo')
2004 > mercurial.cmdutil.extrapostimportmap[b'foo'] = postimport
2000 > mercurial.cmdutil.extrapostimportmap[b'foo'] = postimport
2005 > EOF
2001 > EOF
2006 $ cat >> $HGRCPATH <<EOF
2002 $ cat >> $HGRCPATH <<EOF
2007 > [extensions]
2003 > [extensions]
2008 > parseextra=$TESTTMP/parseextra.py
2004 > parseextra=$TESTTMP/parseextra.py
2009 > EOF
2005 > EOF
2010 $ hg up -C tip
2006 $ hg up -C tip
2011 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2007 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
2012 $ cat > $TESTTMP/foo.patch <<EOF
2008 $ cat > $TESTTMP/foo.patch <<EOF
2013 > # HG changeset patch
2009 > # HG changeset patch
2014 > # User Rataxes
2010 > # User Rataxes
2015 > # Date 0 0
2011 > # Date 0 0
2016 > # Thu Jan 01 00:00:00 1970 +0000
2012 > # Thu Jan 01 00:00:00 1970 +0000
2017 > # Foo bar
2013 > # Foo bar
2018 > height
2014 > height
2019 >
2015 >
2020 > --- a/a Thu Jan 01 00:00:00 1970 +0000
2016 > --- a/a Thu Jan 01 00:00:00 1970 +0000
2021 > +++ b/a Wed Oct 07 09:17:44 2015 +0000
2017 > +++ b/a Wed Oct 07 09:17:44 2015 +0000
2022 > @@ -5,3 +5,4 @@
2018 > @@ -5,3 +5,4 @@
2023 > five
2019 > five
2024 > six
2020 > six
2025 > seven
2021 > seven
2026 > +heigt
2022 > +heigt
2027 > EOF
2023 > EOF
2028 $ hg import $TESTTMP/foo.patch
2024 $ hg import $TESTTMP/foo.patch
2029 applying $TESTTMP/foo.patch
2025 applying $TESTTMP/foo.patch
2030 imported-foo: bar
2026 imported-foo: bar
2031 $ hg log --debug -r . | grep extra
2027 $ hg log --debug -r . | grep extra
2032 extra: branch=default
2028 extra: branch=default
2033 extra: foo=bar
2029 extra: foo=bar
2034
2030
2035 Warn the user that paths are relative to the root of
2031 Warn the user that paths are relative to the root of
2036 repository when file not found for patching
2032 repository when file not found for patching
2037
2033
2038 $ mkdir filedir
2034 $ mkdir filedir
2039 $ echo "file1" >> filedir/file1
2035 $ echo "file1" >> filedir/file1
2040 $ hg add filedir/file1
2036 $ hg add filedir/file1
2041 $ hg commit -m "file1"
2037 $ hg commit -m "file1"
2042 $ cd filedir
2038 $ cd filedir
2043 $ hg import -p 2 - <<EOF
2039 $ hg import -p 2 - <<EOF
2044 > # HG changeset patch
2040 > # HG changeset patch
2045 > # User test
2041 > # User test
2046 > # Date 0 0
2042 > # Date 0 0
2047 > file2
2043 > file2
2048 >
2044 >
2049 > diff --git a/filedir/file1 b/filedir/file1
2045 > diff --git a/filedir/file1 b/filedir/file1
2050 > --- a/filedir/file1
2046 > --- a/filedir/file1
2051 > +++ b/filedir/file1
2047 > +++ b/filedir/file1
2052 > @@ -1,1 +1,2 @@
2048 > @@ -1,1 +1,2 @@
2053 > file1
2049 > file1
2054 > +file2
2050 > +file2
2055 > EOF
2051 > EOF
2056 applying patch from stdin
2052 applying patch from stdin
2057 unable to find 'file1' for patching
2053 unable to find 'file1' for patching
2058 (use '--prefix' to apply patch relative to the current directory)
2054 (use '--prefix' to apply patch relative to the current directory)
2059 1 out of 1 hunks FAILED -- saving rejects to file file1.rej
2055 1 out of 1 hunks FAILED -- saving rejects to file file1.rej
2060 abort: patch failed to apply
2056 abort: patch failed to apply
2061 [255]
2057 [255]
2062
2058
2063 test import crash (issue5375)
2059 test import crash (issue5375)
2064 $ cd ..
2060 $ cd ..
2065 $ hg init repo
2061 $ hg init repo
2066 $ cd repo
2062 $ cd repo
2067 $ printf "diff --git a/a b/b\nrename from a\nrename to b" | hg import -
2063 $ printf "diff --git a/a b/b\nrename from a\nrename to b" | hg import -
2068 applying patch from stdin
2064 applying patch from stdin
2069 a not tracked!
2065 a not tracked!
2070 abort: source file 'a' does not exist
2066 abort: source file 'a' does not exist
2071 [255]
2067 [255]
2072
2068
2073 test immature end of hunk
2069 test immature end of hunk
2074
2070
2075 $ hg import - <<'EOF'
2071 $ hg import - <<'EOF'
2076 > diff --git a/foo b/foo
2072 > diff --git a/foo b/foo
2077 > --- a/foo
2073 > --- a/foo
2078 > --- b/foo
2074 > --- b/foo
2079 > @@ -0,0 +1,1 @@
2075 > @@ -0,0 +1,1 @@
2080 > EOF
2076 > EOF
2081 applying patch from stdin
2077 applying patch from stdin
2082 abort: bad hunk #1: incomplete hunk
2078 abort: bad hunk #1: incomplete hunk
2083 [255]
2079 [255]
2084
2080
2085 $ hg import - <<'EOF'
2081 $ hg import - <<'EOF'
2086 > diff --git a/foo b/foo
2082 > diff --git a/foo b/foo
2087 > --- a/foo
2083 > --- a/foo
2088 > --- b/foo
2084 > --- b/foo
2089 > @@ -0,0 +1,1 @@
2085 > @@ -0,0 +1,1 @@
2090 > \ No newline at end of file
2086 > \ No newline at end of file
2091 > EOF
2087 > EOF
2092 applying patch from stdin
2088 applying patch from stdin
2093 abort: bad hunk #1: incomplete hunk
2089 abort: bad hunk #1: incomplete hunk
2094 [255]
2090 [255]
General Comments 0
You need to be logged in to leave comments. Login now