Skip to content

Commit

Permalink
cli: backout: add templates.backout_description configuration
Browse files Browse the repository at this point in the history
Closes #5676.
  • Loading branch information
bnjmnt4n committed Feb 14, 2025
1 parent 23691a6 commit e021036
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 15 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
useful for making machine-readable templates by escaping problematic
characters like `\n`.

* The description of commits backed out by `jj backout` can now be configured
using `templates.backout_description`.

### Fixed bugs

* `jj status` now shows untracked files under untracked directories.
Expand Down
43 changes: 30 additions & 13 deletions cli/src/commands/backout.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use bstr::ByteVec as _;
use clap_complete::ArgValueCandidates;
use itertools::Itertools as _;
use jj_lib::object_id::ObjectId;
Expand All @@ -22,9 +23,13 @@ use crate::cli_util::CommandHelper;
use crate::cli_util::RevisionArg;
use crate::command_error::CommandError;
use crate::complete;
use crate::formatter::PlainTextFormatter;
use crate::ui::Ui;

/// Apply the reverse of a revision on top of another revision
/// Apply the reverse of given revisions on top of another revision
///
/// The description of the new revisions can be customized with the
/// `templates.backout_description` config variable.
#[derive(clap::Args, Clone, Debug)]
pub(crate) struct BackoutArgs {
/// The revision(s) to apply the reverse of
Expand Down Expand Up @@ -67,7 +72,6 @@ pub(crate) fn cmd_backout(
let destination = workspace_command.resolve_single_rev(ui, revision_str)?;
parents.push(destination);
}
let mut tx = workspace_command.start_transaction();
let transaction_description = if to_back_out.len() == 1 {
format!("back out commit {}", to_back_out[0].id().hex())
} else {
Expand All @@ -77,18 +81,31 @@ pub(crate) fn cmd_backout(
to_back_out.len() - 1
)
};
let commits_to_back_out_with_new_commit_descriptions = {
let template_text = command
.settings()
.get_string("templates.backout_description")?;
let template = workspace_command.parse_commit_template(ui, &template_text)?;

to_back_out
.into_iter()
.map(|commit| {
let mut output = Vec::new();
template
.format(&commit, &mut PlainTextFormatter::new(&mut output))
.expect("write() to vec backed formatter should never fail");
// Template output is usually UTF-8, but it can contain file content.
let commit_description = output.into_string_lossy();
(commit, commit_description)
})
.collect_vec()
};
let mut tx = workspace_command.start_transaction();
let mut new_base_tree = merge_commit_trees(tx.repo(), &parents)?;
for commit_to_back_out in to_back_out {
let commit_to_back_out_subject = commit_to_back_out
.description()
.lines()
.next()
.unwrap_or_default();
let new_commit_description = format!(
"Back out \"{}\"\n\nThis backs out commit {}.\n",
commit_to_back_out_subject,
&commit_to_back_out.id().hex()
);

for (commit_to_back_out, new_commit_description) in
commits_to_back_out_with_new_commit_descriptions
{
let old_base_tree = commit_to_back_out.parent_tree(tx.repo())?;
let old_tree = commit_to_back_out.tree()?;
let new_tree = new_base_tree.merge(&old_tree, &old_base_tree)?;
Expand Down
8 changes: 8 additions & 0 deletions cli/src/config/templates.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
[templates]
backout_description = '''
concat(
'Back out "' ++ description.first_line() ++ '"' ++ "\n",
"\n",
"This backs out commit " ++ commit_id ++ ".\n",
)
'''

bookmark_list = '''
if(remote,
if(tracked,
Expand Down
6 changes: 4 additions & 2 deletions cli/tests/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ To get started, see the tutorial at https://jj-vcs.github.io/jj/latest/tutorial/

* `abandon` — Abandon a revision
* `absorb` — Move changes from a revision into the stack of mutable revisions
* `backout` — Apply the reverse of a revision on top of another revision
* `backout` — Apply the reverse of given revisions on top of another revision
* `bookmark` — Manage bookmarks [default alias: b]
* `commit` — Update the description and create a new change on top
* `config` — Manage config options
Expand Down Expand Up @@ -259,7 +259,9 @@ The modification made by `jj absorb` can be reviewed by `jj op show -p`.

## `jj backout`

Apply the reverse of a revision on top of another revision
Apply the reverse of given revisions on top of another revision

The description of the new revisions can be customized with the `templates.backout_description` config variable.

**Usage:** `jj backout [OPTIONS]`

Expand Down
40 changes: 40 additions & 0 deletions cli/tests/test_backout_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,46 @@ fn test_backout_multiple() {
"#);
}

#[test]
fn test_backout_description_template() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
test_env.add_config(
r#"
[templates]
backout_description = '''
separate(" ",
"Revert commit",
commit_id.short(),
'"' ++ description.first_line() ++ '"',
)
'''
"#,
);
let repo_path = test_env.env_root().join("repo");
create_commit(&test_env, &repo_path, "a", &[], &[("a", "a\n")]);

// Test the setup
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r#"
@ 2443ea76b0b1 a
◆ 000000000000
"#);
let stdout = test_env.jj_cmd_success(&repo_path, &["diff", "-s"]);
insta::assert_snapshot!(stdout, @r###"
A a
"###);

// Verify that message of backed out commit follows the template
let (stdout, stderr) = test_env.jj_cmd_ok(&repo_path, &["backout", "-r", "a"]);
insta::assert_snapshot!(stdout, @"");
insta::assert_snapshot!(stderr, @"");
insta::assert_snapshot!(get_log_output(&test_env, &repo_path), @r#"
○ 1db880a5204e Revert commit 2443ea76b0b1 "a"
@ 2443ea76b0b1 a
◆ 000000000000
"#);
}

fn get_log_output(test_env: &TestEnvironment, cwd: &Path) -> String {
let template = r#"commit_id.short() ++ " " ++ description"#;
test_env.jj_cmd_success(cwd, &["log", "-T", template])
Expand Down

0 comments on commit e021036

Please sign in to comment.