From a9e7c9bffc647eba8258a28a2192e8a663806407 Mon Sep 17 00:00:00 2001 From: Ilya Grigoriev Date: Mon, 16 Jan 2023 11:22:10 -0800 Subject: [PATCH] Make `jj undo` work after `jj duplicate` Fixes https://github.com/martinvonz/jj/issues/1050 Thanks to Martin for suggesting the exact fix. The tests go into the new tests/test_duplicate_command.rs, which will be expanded shortly with other tests depending on this bugfix. --- CHANGELOG.md | 2 + lib/src/repo.rs | 4 +- tests/test_duplicate_command.rs | 73 +++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tests/test_duplicate_command.rs diff --git a/CHANGELOG.md b/CHANGELOG.md index 34e618ba5..f8a34919f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed handling of escaped characters in .gitignore (only keep trailing spaces if escaped properly). +* `jj undo` now works after `jj duplicate`. + ### Contributors Thanks to the people who made this release happen! diff --git a/lib/src/repo.rs b/lib/src/repo.rs index 1ab90e058..41f979e19 100644 --- a/lib/src/repo.rs +++ b/lib/src/repo.rs @@ -610,7 +610,9 @@ impl MutableRepo { } pub fn has_changes(&self) -> bool { - self.view() != &self.base_repo.view + !(self.abandoned_commits.is_empty() + && self.rewritten_commits.is_empty() + && self.view() == &self.base_repo.view) } pub fn consume(self) -> (MutableIndex, View) { diff --git a/tests/test_duplicate_command.rs b/tests/test_duplicate_command.rs new file mode 100644 index 000000000..ef0400fe6 --- /dev/null +++ b/tests/test_duplicate_command.rs @@ -0,0 +1,73 @@ +// Copyright 2023 The Jujutsu Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use std::path::Path; + +use crate::common::TestEnvironment; + +pub mod common; + +fn create_commit(test_env: &TestEnvironment, repo_path: &Path, name: &str, parents: &[&str]) { + if parents.is_empty() { + test_env.jj_cmd_success(repo_path, &["new", "root", "-m", name]); + } else { + let mut args = vec!["new", "-m", name]; + args.extend(parents); + test_env.jj_cmd_success(repo_path, &args); + } + std::fs::write(repo_path.join(name), format!("{name}\n")).unwrap(); + test_env.jj_cmd_success(repo_path, &["branch", "create", name]); +} + +// https://github.com/martinvonz/jj/issues/1050 +#[test] +fn test_undo_after_duplicate() { + let test_env = TestEnvironment::default(); + test_env.jj_cmd_success(test_env.env_root(), &["init", "repo", "--git"]); + let repo_path = test_env.env_root().join("repo"); + + create_commit(&test_env, &repo_path, "a", &[]); + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + @ 2443ea76b0b1 a + o 000000000000 (no description set) + "###); + + let stdout = test_env.jj_cmd_success(&repo_path, &["duplicate", "a"]); + insta::assert_snapshot!(stdout, @r###" + Created: f5cefcbb65a4 a + "###); + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + o f5cefcbb65a4 a + | @ 2443ea76b0b1 a + |/ + o 000000000000 (no description set) + "###); + + insta::assert_snapshot!(test_env.jj_cmd_success(&repo_path, &["undo"]), @""); + insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r###" + @ 2443ea76b0b1 a + o 000000000000 (no description set) + "###); +} + +fn get_log_output(test_env: &TestEnvironment, repo_path: &Path) -> String { + test_env.jj_cmd_success( + repo_path, + &[ + "log", + "-T", + r#"commit_id.short() " " description.first_line()"#, + ], + ) +}