mirror of
https://github.com/martinvonz/jj.git
synced 2025-01-12 07:14:38 +00:00
cli: add a command for untracking already tracked paths
Especially when working on a new-to-you project, it's common to end up with unwanted files automatically tracked before you realize that you should have added them to the `.gitignore`. Even after adding them to the `.gitignore`, it's not trivial to make them no longer tracked (you need to move them away, run e.g. `jj st`, then move them back). This patch adds `jj untrack` to simplify that (without actually moving the files). Closes #14.
This commit is contained in:
parent
287602966e
commit
32018da423
1 changed files with 52 additions and 0 deletions
|
@ -628,6 +628,9 @@ fn get_app<'a, 'b>() -> App<'a, 'b> {
|
|||
.required(true)
|
||||
.help("The revision to update to"),
|
||||
);
|
||||
let untrack_command = SubCommand::with_name("untrack")
|
||||
.about("Stop tracking specified paths in the working copy")
|
||||
.arg(paths_arg());
|
||||
let files_command = SubCommand::with_name("files")
|
||||
.about("List files in a revision")
|
||||
.arg(rev_arg().help("The revision to list files in"));
|
||||
|
@ -1291,6 +1294,7 @@ It is possible to mutating commands when loading the repo at an earlier operatio
|
|||
for subcommand in [
|
||||
init_command,
|
||||
checkout_command,
|
||||
untrack_command,
|
||||
files_command,
|
||||
diff_command,
|
||||
status_command,
|
||||
|
@ -1390,6 +1394,52 @@ fn cmd_checkout(
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_untrack(
|
||||
ui: &mut Ui,
|
||||
command: &CommandHelper,
|
||||
args: &ArgMatches,
|
||||
) -> Result<(), CommandError> {
|
||||
// TODO: We should probably check that the repo was loaded at head.
|
||||
let mut repo_command = command.repo_helper(ui)?;
|
||||
repo_command.maybe_commit_working_copy(ui)?;
|
||||
let base_repo = repo_command.repo().clone();
|
||||
let matcher = matcher_from_values(
|
||||
ui,
|
||||
repo_command.repo().working_copy_path(),
|
||||
args.values_of("paths"),
|
||||
)?;
|
||||
let mut tx = repo_command.start_transaction("untrack paths");
|
||||
let locked_working_copy = base_repo.working_copy_locked();
|
||||
let old_commit = locked_working_copy.current_commit();
|
||||
let unfinished_write = locked_working_copy
|
||||
.untrack(matcher.as_ref())
|
||||
.map_err(|err| CommandError::InternalError(format!("Failed to untrack paths: {}", err)))?;
|
||||
let new_tree_id = unfinished_write.new_tree_id();
|
||||
let new_commit = CommitBuilder::for_rewrite_from(ui.settings(), base_repo.store(), &old_commit)
|
||||
.set_tree(new_tree_id)
|
||||
.write_to_repo(tx.mut_repo());
|
||||
tx.mut_repo().set_checkout(new_commit.id().clone());
|
||||
let repo = tx.commit();
|
||||
unfinished_write.finish(new_commit);
|
||||
drop(locked_working_copy);
|
||||
repo_command.repo_mut().reload_at(repo.operation());
|
||||
|
||||
// TODO: Is it better to have WorkingCopy::untrack() report if any matching
|
||||
// files exist on disk? That would make the command have no effect rather
|
||||
// than partially succeeding, for better or worse.
|
||||
repo_command.maybe_commit_working_copy(ui)?;
|
||||
let new_commit = repo_command.repo().working_copy_locked().current_commit();
|
||||
if let Some((path, _value)) = new_commit.tree().entries_matching(matcher.as_ref()).next() {
|
||||
let ui_path = ui.format_file_path(base_repo.working_copy_path(), &path);
|
||||
return Err(CommandError::UserError(format!(
|
||||
"At least '{}' was added back because it is not ignored. Make sure it's ignored, then \
|
||||
try again.",
|
||||
ui_path
|
||||
)));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cmd_files(ui: &mut Ui, command: &CommandHelper, args: &ArgMatches) -> Result<(), CommandError> {
|
||||
let mut repo_command = command.repo_helper(ui)?;
|
||||
let commit = repo_command.resolve_revision_arg(ui, args)?;
|
||||
|
@ -3869,6 +3919,8 @@ where
|
|||
cmd_init(&mut ui, &command_helper, sub_args)
|
||||
} else if let Some(sub_args) = matches.subcommand_matches("checkout") {
|
||||
cmd_checkout(&mut ui, &command_helper, sub_args)
|
||||
} else if let Some(sub_args) = matches.subcommand_matches("untrack") {
|
||||
cmd_untrack(&mut ui, &command_helper, sub_args)
|
||||
} else if let Some(sub_args) = matches.subcommand_matches("files") {
|
||||
cmd_files(&mut ui, &command_helper, sub_args)
|
||||
} else if let Some(sub_args) = matches.subcommand_matches("diff") {
|
||||
|
|
Loading…
Reference in a new issue