mirror of
https://github.com/martinvonz/jj.git
synced 2024-12-23 20:43:56 +00:00
0e2579ee6a
This follows up on 5c703aeb03
.
The only reason for this change is that, subjectively, the result looks better to me. I'm not sure why, but I couldn't get used to the old symbol in spite of its seeming reasonableness. It felt really bold and heavy.
If people agree, we can wait until we need to update the screenshots for some other reason before merging this. Sorry I didn't figure this out while the discussion about the referenced commit was going on.
I'm not 100% certain how many fonts support each symbol. Please try it out and let me know if it doesn't work for you.
Compare after:
![image](https://user-images.githubusercontent.com/4123047/229251383-563b889d-7233-42e2-a3c5-bf9368a4d1fd.png)
and before:
![image](https://user-images.githubusercontent.com/4123047/229251695-7fd0ff2c-2832-4262-ade5-5120288cccdf.png)
1098 lines
34 KiB
Rust
1098 lines
34 KiB
Rust
// Copyright 2022 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 common::{get_stderr_string, get_stdout_string, TestEnvironment};
|
||
|
||
pub mod common;
|
||
|
||
#[test]
|
||
fn test_log_with_empty_revision() {
|
||
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");
|
||
|
||
let stderr = test_env.jj_cmd_cli_error(&repo_path, &["log", "-r="]);
|
||
insta::assert_snapshot!(stderr, @r###"
|
||
error: a value is required for '--revisions <REVISIONS>' but none was supplied
|
||
|
||
For more information, try '--help'.
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_with_or_without_diff() {
|
||
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");
|
||
|
||
std::fs::write(repo_path.join("file1"), "foo\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "add a file"]);
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "a new commit"]);
|
||
std::fs::write(repo_path.join("file1"), "foo\nbar\n").unwrap();
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
◉ add a file
|
||
◉
|
||
"###);
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "-p"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ Modified regular file file1:
|
||
│ 1 1: foo
|
||
│ 2: bar
|
||
◉ add a file
|
||
│ Added regular file file1:
|
||
│ 1: foo
|
||
◉
|
||
"###);
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "--no-graph"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
a new commit
|
||
add a file
|
||
"###);
|
||
|
||
// `-p` for default diff output, `-s` for summary
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "-p", "-s"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ M file1
|
||
│ Modified regular file file1:
|
||
│ 1 1: foo
|
||
│ 2: bar
|
||
◉ add a file
|
||
│ A file1
|
||
│ Added regular file file1:
|
||
│ 1: foo
|
||
◉
|
||
"###);
|
||
|
||
// `-s` for summary, `--git` for git diff (which implies `-p`)
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "-s", "--git"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ M file1
|
||
│ diff --git a/file1 b/file1
|
||
│ index 257cc5642c...3bd1f0e297 100644
|
||
│ --- a/file1
|
||
│ +++ b/file1
|
||
│ @@ -1,1 +1,2 @@
|
||
│ foo
|
||
│ +bar
|
||
◉ add a file
|
||
│ A file1
|
||
│ diff --git a/file1 b/file1
|
||
│ new file mode 100644
|
||
│ index 0000000000..257cc5642c
|
||
│ --- /dev/null
|
||
│ +++ b/file1
|
||
│ @@ -1,0 +1,1 @@
|
||
│ +foo
|
||
◉
|
||
"###);
|
||
|
||
// `-p` enables default "summary" output, so `-s` is noop
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"log",
|
||
"-T",
|
||
"description",
|
||
"-p",
|
||
"-s",
|
||
"--config-toml=ui.diff.format='summary'",
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ M file1
|
||
◉ add a file
|
||
│ A file1
|
||
◉
|
||
"###);
|
||
|
||
// `-p` enables default "color-words" diff output, so `--color-words` is noop
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "-p", "--color-words"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ Modified regular file file1:
|
||
│ 1 1: foo
|
||
│ 2: bar
|
||
◉ add a file
|
||
│ Added regular file file1:
|
||
│ 1: foo
|
||
◉
|
||
"###);
|
||
|
||
// `--git` enables git diff, so `-p` is noop
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "--no-graph", "-p", "--git"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
a new commit
|
||
diff --git a/file1 b/file1
|
||
index 257cc5642c...3bd1f0e297 100644
|
||
--- a/file1
|
||
+++ b/file1
|
||
@@ -1,1 +1,2 @@
|
||
foo
|
||
+bar
|
||
add a file
|
||
diff --git a/file1 b/file1
|
||
new file mode 100644
|
||
index 0000000000..257cc5642c
|
||
--- /dev/null
|
||
+++ b/file1
|
||
@@ -1,0 +1,1 @@
|
||
+foo
|
||
"###);
|
||
|
||
// Cannot use both `--git` and `--color-words`
|
||
let stderr = test_env.jj_cmd_cli_error(
|
||
&repo_path,
|
||
&[
|
||
"log",
|
||
"-T",
|
||
"description",
|
||
"--no-graph",
|
||
"-p",
|
||
"--git",
|
||
"--color-words",
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stderr, @r###"
|
||
error: the argument '--git' cannot be used with '--color-words'
|
||
|
||
Usage: jj log --template <TEMPLATE> --no-graph --patch --git [PATHS]...
|
||
|
||
For more information, try '--help'.
|
||
"###);
|
||
|
||
// `-s` with or without graph
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "-s"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ M file1
|
||
◉ add a file
|
||
│ A file1
|
||
◉
|
||
"###);
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "--no-graph", "-s"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
a new commit
|
||
M file1
|
||
add a file
|
||
A file1
|
||
"###);
|
||
|
||
// `--git` implies `-p`, with or without graph
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "-r", "@", "--git"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ diff --git a/file1 b/file1
|
||
~ index 257cc5642c...3bd1f0e297 100644
|
||
--- a/file1
|
||
+++ b/file1
|
||
@@ -1,1 +1,2 @@
|
||
foo
|
||
+bar
|
||
"###);
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "-r", "@", "--no-graph", "--git"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
a new commit
|
||
diff --git a/file1 b/file1
|
||
index 257cc5642c...3bd1f0e297 100644
|
||
--- a/file1
|
||
+++ b/file1
|
||
@@ -1,1 +1,2 @@
|
||
foo
|
||
+bar
|
||
"###);
|
||
|
||
// `--color-words` implies `-p`, with or without graph
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "-r", "@", "--color-words"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ a new commit
|
||
│ Modified regular file file1:
|
||
~ 1 1: foo
|
||
2: bar
|
||
"###);
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"log",
|
||
"-T",
|
||
"description",
|
||
"-r",
|
||
"@",
|
||
"--no-graph",
|
||
"--color-words",
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
a new commit
|
||
Modified regular file file1:
|
||
1 1: foo
|
||
2: bar
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_shortest_accessors() {
|
||
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");
|
||
let render = |rev, template| {
|
||
test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "--no-graph", "-r", rev, "-T", template],
|
||
)
|
||
};
|
||
test_env.add_config(
|
||
r###"
|
||
[template-aliases]
|
||
'format_id(id)' = 'id.shortest(12).prefix() ++ "[" ++ id.shortest(12).rest() ++ "]"'
|
||
"###,
|
||
);
|
||
|
||
std::fs::write(repo_path.join("file"), "original file\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "initial"]);
|
||
test_env.jj_cmd_success(&repo_path, &["branch", "c", "original"]);
|
||
insta::assert_snapshot!(
|
||
render("original", r#"format_id(change_id) ++ " " ++ format_id(commit_id)"#),
|
||
@"q[pvuntsmwlqt] b[a1a30916d29]");
|
||
|
||
// Create a chain of 10 commits
|
||
for i in 1..10 {
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", &format!("commit{i}")]);
|
||
std::fs::write(repo_path.join("file"), format!("file {i}\n")).unwrap();
|
||
}
|
||
// Create 2^3 duplicates of the chain
|
||
for _ in 0..3 {
|
||
test_env.jj_cmd_success(&repo_path, &["duplicate", "description(commit)"]);
|
||
}
|
||
|
||
insta::assert_snapshot!(
|
||
render("original", r#"format_id(change_id) ++ " " ++ format_id(commit_id)"#),
|
||
@"qpv[untsmwlqt] ba1[a30916d29]");
|
||
|
||
insta::assert_snapshot!(
|
||
render(":@", r#"change_id.shortest() ++ " " ++ commit_id.shortest() ++ "\n""#),
|
||
@r###"
|
||
wq 03
|
||
km f7
|
||
kp e7
|
||
zn 38
|
||
yo 0cf
|
||
vr 9e
|
||
yq 06f
|
||
ro 1f
|
||
mz 7b
|
||
qpv ba1
|
||
zzz 00
|
||
"###);
|
||
|
||
insta::assert_snapshot!(
|
||
render(":@", r#"format_id(change_id) ++ " " ++ format_id(commit_id) ++ "\n""#),
|
||
@r###"
|
||
wq[nwkozpkust] 03[f51310b83e]
|
||
km[kuslswpqwq] f7[7fb1909080]
|
||
kp[qxywonksrl] e7[15ad5db646]
|
||
zn[kkpsqqskkl] 38[622e54e2e5]
|
||
yo[stqsxwqrlt] 0cf[42f60199c]
|
||
vr[uxwmqvtpmx] 9e[6015e4e622]
|
||
yq[osqzytrlsw] 06f[34d9b1475]
|
||
ro[yxmykxtrkr] 1f[99a5e19891]
|
||
mz[vwutvlkqwt] 7b[1f7dee65b4]
|
||
qpv[untsmwlqt] ba1[a30916d29]
|
||
zzz[zzzzzzzzz] 00[0000000000]
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_prefix_highlight_styled() {
|
||
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");
|
||
|
||
fn prefix_format(len: Option<usize>) -> String {
|
||
format!(
|
||
r###"
|
||
separate(" ",
|
||
"Change",
|
||
change_id.shortest({0}),
|
||
description.first_line(),
|
||
commit_id.shortest({0}),
|
||
branches,
|
||
)
|
||
"###,
|
||
len.map(|l| l.to_string()).unwrap_or(String::default())
|
||
)
|
||
}
|
||
|
||
std::fs::write(repo_path.join("file"), "original file\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "initial"]);
|
||
test_env.jj_cmd_success(&repo_path, &["branch", "c", "original"]);
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-r", "original", "-T", &prefix_format(Some(12))]),
|
||
@r###"
|
||
@ Change qpvuntsmwlqt initial ba1a30916d29 original
|
||
│
|
||
~
|
||
"###
|
||
);
|
||
|
||
// Create a chain of 10 commits
|
||
for i in 1..10 {
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", &format!("commit{i}")]);
|
||
std::fs::write(repo_path.join("file"), format!("file {i}\n")).unwrap();
|
||
}
|
||
// Create 2^3 duplicates of the chain
|
||
for _ in 0..3 {
|
||
test_env.jj_cmd_success(&repo_path, &["duplicate", "description(commit)"]);
|
||
}
|
||
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-r", "original", "-T", &prefix_format(Some(12))]),
|
||
@r###"
|
||
◉ Change qpvuntsmwlqt initial ba1a30916d29 original
|
||
│
|
||
~
|
||
"###
|
||
);
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"--color=always",
|
||
"log",
|
||
"-r",
|
||
"@-----------..@",
|
||
"-T",
|
||
&prefix_format(Some(12)),
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stdout,
|
||
@r###"
|
||
@ Change [1m[38;5;5mwq[0m[38;5;8mnwkozpkust[39m commit9 [1m[38;5;4m03[0m[38;5;8mf51310b83e[39m
|
||
◉ Change [1m[38;5;5mkm[0m[38;5;8mkuslswpqwq[39m commit8 [1m[38;5;4mf7[0m[38;5;8m7fb1909080[39m
|
||
◉ Change [1m[38;5;5mkp[0m[38;5;8mqxywonksrl[39m commit7 [1m[38;5;4me7[0m[38;5;8m15ad5db646[39m
|
||
◉ Change [1m[38;5;5mzn[0m[38;5;8mkkpsqqskkl[39m commit6 [1m[38;5;4m38[0m[38;5;8m622e54e2e5[39m
|
||
◉ Change [1m[38;5;5myo[0m[38;5;8mstqsxwqrlt[39m commit5 [1m[38;5;4m0cf[0m[38;5;8m42f60199c[39m
|
||
◉ Change [1m[38;5;5mvr[0m[38;5;8muxwmqvtpmx[39m commit4 [1m[38;5;4m9e[0m[38;5;8m6015e4e622[39m
|
||
◉ Change [1m[38;5;5myq[0m[38;5;8mosqzytrlsw[39m commit3 [1m[38;5;4m06f[0m[38;5;8m34d9b1475[39m
|
||
◉ Change [1m[38;5;5mro[0m[38;5;8myxmykxtrkr[39m commit2 [1m[38;5;4m1f[0m[38;5;8m99a5e19891[39m
|
||
◉ Change [1m[38;5;5mmz[0m[38;5;8mvwutvlkqwt[39m commit1 [1m[38;5;4m7b[0m[38;5;8m1f7dee65b4[39m
|
||
◉ Change [1m[38;5;5mqpv[0m[38;5;8muntsmwlqt[39m initial [1m[38;5;4mba1[0m[38;5;8ma30916d29[39m [38;5;5moriginal[39m
|
||
◉ Change [1m[38;5;5mzzz[0m[38;5;8mzzzzzzzzz[39m [1m[38;5;4m00[0m[38;5;8m0000000000[39m
|
||
"###
|
||
);
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"--color=always",
|
||
"log",
|
||
"-r",
|
||
"@-----------..@",
|
||
"-T",
|
||
&prefix_format(Some(3)),
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stdout,
|
||
@r###"
|
||
@ Change [1m[38;5;5mwq[0m[38;5;8mn[39m commit9 [1m[38;5;4m03[0m[38;5;8mf[39m
|
||
◉ Change [1m[38;5;5mkm[0m[38;5;8mk[39m commit8 [1m[38;5;4mf7[0m[38;5;8m7[39m
|
||
◉ Change [1m[38;5;5mkp[0m[38;5;8mq[39m commit7 [1m[38;5;4me7[0m[38;5;8m1[39m
|
||
◉ Change [1m[38;5;5mzn[0m[38;5;8mk[39m commit6 [1m[38;5;4m38[0m[38;5;8m6[39m
|
||
◉ Change [1m[38;5;5myo[0m[38;5;8ms[39m commit5 [1m[38;5;4m0cf[0m
|
||
◉ Change [1m[38;5;5mvr[0m[38;5;8mu[39m commit4 [1m[38;5;4m9e[0m[38;5;8m6[39m
|
||
◉ Change [1m[38;5;5myq[0m[38;5;8mo[39m commit3 [1m[38;5;4m06f[0m
|
||
◉ Change [1m[38;5;5mro[0m[38;5;8my[39m commit2 [1m[38;5;4m1f[0m[38;5;8m9[39m
|
||
◉ Change [1m[38;5;5mmz[0m[38;5;8mv[39m commit1 [1m[38;5;4m7b[0m[38;5;8m1[39m
|
||
◉ Change [1m[38;5;5mqpv[0m initial [1m[38;5;4mba1[0m [38;5;5moriginal[39m
|
||
◉ Change [1m[38;5;5mzzz[0m [1m[38;5;4m00[0m[38;5;8m0[39m
|
||
"###
|
||
);
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"--color=always",
|
||
"log",
|
||
"-r",
|
||
"@-----------..@",
|
||
"-T",
|
||
&prefix_format(None),
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stdout,
|
||
@r###"
|
||
@ Change [1m[38;5;5mwq[0m commit9 [1m[38;5;4m03[0m
|
||
◉ Change [1m[38;5;5mkm[0m commit8 [1m[38;5;4mf7[0m
|
||
◉ Change [1m[38;5;5mkp[0m commit7 [1m[38;5;4me7[0m
|
||
◉ Change [1m[38;5;5mzn[0m commit6 [1m[38;5;4m38[0m
|
||
◉ Change [1m[38;5;5myo[0m commit5 [1m[38;5;4m0cf[0m
|
||
◉ Change [1m[38;5;5mvr[0m commit4 [1m[38;5;4m9e[0m
|
||
◉ Change [1m[38;5;5myq[0m commit3 [1m[38;5;4m06f[0m
|
||
◉ Change [1m[38;5;5mro[0m commit2 [1m[38;5;4m1f[0m
|
||
◉ Change [1m[38;5;5mmz[0m commit1 [1m[38;5;4m7b[0m
|
||
◉ Change [1m[38;5;5mqpv[0m initial [1m[38;5;4mba1[0m [38;5;5moriginal[39m
|
||
◉ Change [1m[38;5;5mzzz[0m [1m[38;5;4m00[0m
|
||
"###
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_prefix_highlight_counts_hidden_commits() {
|
||
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");
|
||
test_env.add_config(
|
||
r###"
|
||
[template-aliases]
|
||
'format_id(id)' = 'id.shortest(12).prefix() ++ "[" ++ id.shortest(12).rest() ++ "]"'
|
||
"###,
|
||
);
|
||
|
||
let prefix_format = r###"
|
||
separate(" ",
|
||
"Change",
|
||
format_id(change_id),
|
||
description.first_line(),
|
||
format_id(commit_id),
|
||
branches,
|
||
)
|
||
"###;
|
||
|
||
std::fs::write(repo_path.join("file"), "original file\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "initial"]);
|
||
test_env.jj_cmd_success(&repo_path, &["branch", "c", "original"]);
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-r", "all()", "-T", prefix_format]),
|
||
@r###"
|
||
@ Change q[pvuntsmwlqt] initial b[a1a30916d29] original
|
||
◉ Change z[zzzzzzzzzzz] 0[00000000000]
|
||
"###
|
||
);
|
||
|
||
// Create 2^7 hidden commits
|
||
test_env.jj_cmd_success(&repo_path, &["new", "root", "-m", "extra"]);
|
||
for _ in 0..7 {
|
||
test_env.jj_cmd_success(&repo_path, &["duplicate", "description(extra)"]);
|
||
}
|
||
test_env.jj_cmd_success(&repo_path, &["abandon", "description(extra)"]);
|
||
|
||
// The first commit's unique prefix became longer.
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-T", prefix_format]),
|
||
@r###"
|
||
@ Change w[qnwkozpkust] 44[4c3c5066d3]
|
||
│ ◉ Change q[pvuntsmwlqt] initial ba[1a30916d29] original
|
||
├─╯
|
||
◉ Change z[zzzzzzzzzzz] 00[0000000000]
|
||
"###
|
||
);
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_failure(&repo_path, &["log", "-r", "d", "-T", prefix_format]),
|
||
@r###"
|
||
Error: Commit or change id prefix "d" is ambiguous
|
||
"###
|
||
);
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-r", "d0", "-T", prefix_format]),
|
||
@r###"
|
||
◉ Change p[szsrknsmxqw] extra d0[947f34cec4]
|
||
│
|
||
~
|
||
"###
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_shortest_length_parameter() {
|
||
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");
|
||
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-T", "commit_id.shortest(0)"]), @r###"
|
||
@ 2
|
||
◉ 0
|
||
"###);
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "-T", "commit_id.shortest(100)"]), @r###"
|
||
@ 230dd059e1b059aefc0da06a2e5a7dbf22362f22
|
||
◉ 0000000000000000000000000000000000000000
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_author_format() {
|
||
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");
|
||
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(&repo_path, &["log", "--revisions=@"]),
|
||
@r###"
|
||
@ qpvuntsmwlqt test.user@example.com 2001-02-03 04:05:07.000 +07:00 230dd059e1b0
|
||
│ (empty) (no description set)
|
||
~
|
||
"###
|
||
);
|
||
|
||
let decl = "template-aliases.'format_short_signature(signature)'";
|
||
insta::assert_snapshot!(
|
||
test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"--config-toml",
|
||
&format!("{decl}='signature.username()'"),
|
||
"log",
|
||
"--revisions=@",
|
||
],
|
||
),
|
||
@r###"
|
||
@ qpvuntsmwlqt test.user 2001-02-03 04:05:07.000 +07:00 230dd059e1b0
|
||
│ (empty) (no description set)
|
||
~
|
||
"###
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_divergence() {
|
||
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");
|
||
let template = r#"description.first_line() ++ if(divergent, " !divergence!")"#;
|
||
|
||
std::fs::write(repo_path.join("file"), "foo\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "description 1"]);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", template]);
|
||
// No divergence
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ description 1
|
||
◉
|
||
"###);
|
||
|
||
// Create divergence
|
||
test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["describe", "-m", "description 2", "--at-operation", "@-"],
|
||
);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", template]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
Concurrent modification detected, resolving automatically.
|
||
◉ description 2 !divergence!
|
||
│ @ description 1 !divergence!
|
||
├─╯
|
||
◉
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_reversed() {
|
||
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");
|
||
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "first"]);
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "second"]);
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "--reversed"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
◉
|
||
◉ first
|
||
@ second
|
||
"###);
|
||
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "--reversed", "--no-graph"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
first
|
||
second
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_filtered_by_path() {
|
||
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");
|
||
|
||
std::fs::write(repo_path.join("file1"), "foo\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "first"]);
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "second"]);
|
||
std::fs::write(repo_path.join("file1"), "foo\nbar\n").unwrap();
|
||
std::fs::write(repo_path.join("file2"), "baz\n").unwrap();
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "file1"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ second
|
||
◉ first
|
||
│
|
||
~
|
||
"###);
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "file2"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ second
|
||
│
|
||
~
|
||
"###);
|
||
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", "description", "-s", "file1"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ second
|
||
│ M file1
|
||
◉ first
|
||
│ A file1
|
||
~
|
||
"###);
|
||
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["log", "-T", "description", "-s", "file2", "--no-graph"],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
second
|
||
A file2
|
||
"###);
|
||
|
||
// file() revset doesn't filter the diff.
|
||
let stdout = test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&[
|
||
"log",
|
||
"-T",
|
||
"description",
|
||
"-s",
|
||
"-rfile(file2)",
|
||
"--no-graph",
|
||
],
|
||
);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
second
|
||
M file1
|
||
A file2
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_warn_path_might_be_revset() {
|
||
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");
|
||
|
||
std::fs::write(repo_path.join("file1"), "foo\n").unwrap();
|
||
|
||
// Don't warn if the file actually exists.
|
||
let assert = test_env
|
||
.jj_cmd(&repo_path, &["log", "file1", "-T", "description"])
|
||
.assert()
|
||
.success();
|
||
insta::assert_snapshot!(get_stdout_string(&assert), @r###"
|
||
@
|
||
│
|
||
~
|
||
"###);
|
||
insta::assert_snapshot!(get_stderr_string(&assert), @"");
|
||
|
||
// Warn for `jj log .` specifically, for former Mercurial users.
|
||
let assert = test_env
|
||
.jj_cmd(&repo_path, &["log", ".", "-T", "description"])
|
||
.assert()
|
||
.success();
|
||
insta::assert_snapshot!(get_stdout_string(&assert), @r###"
|
||
@
|
||
│
|
||
~
|
||
"###);
|
||
insta::assert_snapshot!(get_stderr_string(&assert), @r###"warning: The argument "." is being interpreted as a path, but this is often not useful because all non-empty commits touch '.'. If you meant to show the working copy commit, pass -r '@' instead."###);
|
||
|
||
// ...but checking `jj log .` makes sense in a subdirectory.
|
||
let subdir = repo_path.join("dir");
|
||
std::fs::create_dir_all(&subdir).unwrap();
|
||
let assert = test_env.jj_cmd(&subdir, &["log", "."]).assert().success();
|
||
insta::assert_snapshot!(get_stdout_string(&assert), @"");
|
||
insta::assert_snapshot!(get_stderr_string(&assert), @"");
|
||
|
||
// Warn for `jj log @` instead of `jj log -r @`.
|
||
let assert = test_env
|
||
.jj_cmd(&repo_path, &["log", "@", "-T", "description"])
|
||
.assert()
|
||
.success();
|
||
insta::assert_snapshot!(get_stdout_string(&assert), @"");
|
||
insta::assert_snapshot!(get_stderr_string(&assert), @r###"
|
||
warning: The argument "@" is being interpreted as a path. To specify a revset, pass -r "@" instead.
|
||
"###);
|
||
|
||
// Warn when there's no path with the provided name.
|
||
let assert = test_env
|
||
.jj_cmd(&repo_path, &["log", "file2", "-T", "description"])
|
||
.assert()
|
||
.success();
|
||
insta::assert_snapshot!(get_stdout_string(&assert), @"");
|
||
insta::assert_snapshot!(get_stderr_string(&assert), @r###"
|
||
warning: The argument "file2" is being interpreted as a path. To specify a revset, pass -r "file2" instead.
|
||
"###);
|
||
|
||
// If an explicit revision is provided, then suppress the warning.
|
||
let assert = test_env
|
||
.jj_cmd(&repo_path, &["log", "@", "-r", "@", "-T", "description"])
|
||
.assert()
|
||
.success();
|
||
insta::assert_snapshot!(get_stdout_string(&assert), @"");
|
||
insta::assert_snapshot!(get_stderr_string(&assert), @r###"
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_default_revset() {
|
||
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");
|
||
|
||
std::fs::write(repo_path.join("file1"), "foo\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "add a file"]);
|
||
|
||
// Set configuration to only show the root commit.
|
||
test_env.add_config(r#"ui.default-revset = "root""#);
|
||
|
||
// Log should only contain one line (for the root commit), and not show the
|
||
// commit created above.
|
||
assert_eq!(
|
||
1,
|
||
test_env
|
||
.jj_cmd_success(&repo_path, &["log", "-T", "commit_id"])
|
||
.lines()
|
||
.count()
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_default_revset_per_repo() {
|
||
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");
|
||
|
||
std::fs::write(repo_path.join("file1"), "foo\n").unwrap();
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "add a file"]);
|
||
|
||
// Set configuration to only show the root commit.
|
||
std::fs::write(
|
||
repo_path.join(".jj/repo/config.toml"),
|
||
r#"ui.default-revset = "root""#,
|
||
)
|
||
.unwrap();
|
||
|
||
// Log should only contain one line (for the root commit), and not show the
|
||
// commit created above.
|
||
assert_eq!(
|
||
1,
|
||
test_env
|
||
.jj_cmd_success(&repo_path, &["log", "-T", "commit_id"])
|
||
.lines()
|
||
.count()
|
||
);
|
||
}
|
||
|
||
#[test]
|
||
fn test_graph_template_color() {
|
||
// Test that color codes from a multi-line template don't span the graph lines.
|
||
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");
|
||
|
||
test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["describe", "-m", "first line\nsecond line\nthird line"],
|
||
);
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "single line"]);
|
||
|
||
test_env.add_config(
|
||
r#"[colors]
|
||
description = "red"
|
||
"working_copy description" = "green"
|
||
"#,
|
||
);
|
||
|
||
// First test without color for comparison
|
||
let template = r#"label(if(current_working_copy, "working_copy"), description)"#;
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T", template]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ single line
|
||
◉ first line
|
||
│ second line
|
||
│ third line
|
||
◉
|
||
"###);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["--color=always", "log", "-T", template]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ [1m[38;5;2msingle line[0m
|
||
◉ [38;5;1mfirst line[39m
|
||
│ [38;5;1msecond line[39m
|
||
│ [38;5;1mthird line[39m
|
||
◉
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_graph_styles() {
|
||
// Test that different graph styles are available.
|
||
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");
|
||
|
||
test_env.jj_cmd_success(&repo_path, &["commit", "-m", "initial"]);
|
||
test_env.jj_cmd_success(&repo_path, &["commit", "-m", "main branch 1"]);
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "main branch 2"]);
|
||
test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["new", "-m", "side branch\nwith\nlong\ndescription"],
|
||
);
|
||
test_env.jj_cmd_success(
|
||
&repo_path,
|
||
&["new", "-m", "merge", r#"description("main branch 1")"#, "@"],
|
||
);
|
||
|
||
// Default (legacy) style
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T=description"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ merge
|
||
├─╮
|
||
◉ │ side branch
|
||
│ │ with
|
||
│ │ long
|
||
│ │ description
|
||
◉ │ main branch 2
|
||
├─╯
|
||
◉ main branch 1
|
||
◉ initial
|
||
◉
|
||
"###);
|
||
|
||
// ASCII style
|
||
test_env.add_config(r#"ui.graph.style = "ascii""#);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T=description"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ merge
|
||
|\
|
||
o | side branch
|
||
| | with
|
||
| | long
|
||
| | description
|
||
o | main branch 2
|
||
|/
|
||
o main branch 1
|
||
o initial
|
||
o
|
||
"###);
|
||
|
||
// Large ASCII style
|
||
test_env.add_config(r#"ui.graph.style = "ascii-large""#);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T=description"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ merge
|
||
|\
|
||
| \
|
||
o | side branch
|
||
| | with
|
||
| | long
|
||
| | description
|
||
o | main branch 2
|
||
| /
|
||
|/
|
||
o main branch 1
|
||
o initial
|
||
o
|
||
"###);
|
||
|
||
// Curved style
|
||
test_env.add_config(r#"ui.graph.style = "curved""#);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T=description"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ merge
|
||
├─╮
|
||
◉ │ side branch
|
||
│ │ with
|
||
│ │ long
|
||
│ │ description
|
||
◉ │ main branch 2
|
||
├─╯
|
||
◉ main branch 1
|
||
◉ initial
|
||
◉
|
||
"###);
|
||
|
||
// Square style
|
||
test_env.add_config(r#"ui.graph.style = "square""#);
|
||
let stdout = test_env.jj_cmd_success(&repo_path, &["log", "-T=description"]);
|
||
insta::assert_snapshot!(stdout, @r###"
|
||
@ merge
|
||
├─┐
|
||
◉ │ side branch
|
||
│ │ with
|
||
│ │ long
|
||
│ │ description
|
||
◉ │ main branch 2
|
||
├─┘
|
||
◉ main branch 1
|
||
◉ initial
|
||
◉
|
||
"###);
|
||
}
|
||
|
||
#[test]
|
||
fn test_log_word_wrap() {
|
||
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");
|
||
let render = |args: &[&str], columns: u32, word_wrap: bool| {
|
||
let mut args = args.to_vec();
|
||
if word_wrap {
|
||
args.push("--config-toml=ui.log-word-wrap=true");
|
||
}
|
||
let assert = test_env
|
||
.jj_cmd(&repo_path, &args)
|
||
.env("COLUMNS", columns.to_string())
|
||
.assert()
|
||
.success()
|
||
.stderr("");
|
||
get_stdout_string(&assert)
|
||
};
|
||
|
||
test_env.jj_cmd_success(&repo_path, &["commit", "-m", "main branch 1"]);
|
||
test_env.jj_cmd_success(&repo_path, &["describe", "-m", "main branch 2"]);
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "side"]);
|
||
test_env.jj_cmd_success(&repo_path, &["new", "-m", "merge", "@--", "@"]);
|
||
|
||
// ui.log-word-wrap option applies to both graph/no-graph outputs
|
||
insta::assert_snapshot!(render(&["log", "-r@"], 40, false), @r###"
|
||
@ mzvwutvlkqwt test.user@example.com 2001-02-03 04:05:11.000 +07:00 68518a7e6c9e
|
||
│ (empty) merge
|
||
~
|
||
"###);
|
||
insta::assert_snapshot!(render(&["log", "-r@"], 40, true), @r###"
|
||
@ mzvwutvlkqwt test.user@example.com
|
||
│ 2001-02-03 04:05:11.000 +07:00
|
||
~ 68518a7e6c9e
|
||
(empty) merge
|
||
"###);
|
||
insta::assert_snapshot!(render(&["log", "--no-graph", "-r@"], 40, false), @r###"
|
||
mzvwutvlkqwt test.user@example.com 2001-02-03 04:05:11.000 +07:00 68518a7e6c9e
|
||
(empty) merge
|
||
"###);
|
||
insta::assert_snapshot!(render(&["log", "--no-graph", "-r@"], 40, true), @r###"
|
||
mzvwutvlkqwt test.user@example.com
|
||
2001-02-03 04:05:11.000 +07:00
|
||
68518a7e6c9e
|
||
(empty) merge
|
||
"###);
|
||
|
||
// Color labels should be preserved
|
||
insta::assert_snapshot!(render(&["log", "-r@", "--color=always"], 40, true), @r###"
|
||
@ [1m[38;5;13mm[38;5;8mzvwutvlkqwt[39m [38;5;3mtest.user@example.com[39m[0m
|
||
│ [1m[38;5;14m2001-02-03 04:05:11.000 +07:00[39m[0m
|
||
~ [1m[38;5;12m6[38;5;8m8518a7e6c9e[39m[0m
|
||
[1m[38;5;10m(empty)[39m merge[0m
|
||
"###);
|
||
|
||
// Graph width should be subtracted from the term width
|
||
let template = r#""0 1 2 3 4 5 6 7 8 9""#;
|
||
insta::assert_snapshot!(render(&["log", "-T", template], 10, true), @r###"
|
||
@ 0 1 2
|
||
├─╮ 3 4 5
|
||
│ │ 6 7 8
|
||
│ │ 9
|
||
◉ │ 0 1 2
|
||
│ │ 3 4 5
|
||
│ │ 6 7 8
|
||
│ │ 9
|
||
◉ │ 0 1 2
|
||
├─╯ 3 4 5
|
||
│ 6 7 8
|
||
│ 9
|
||
◉ 0 1 2 3
|
||
│ 4 5 6 7
|
||
│ 8 9
|
||
◉ 0 1 2 3
|
||
4 5 6 7
|
||
8 9
|
||
"###);
|
||
insta::assert_snapshot!(
|
||
render(&["log", "-T", template, "--config-toml=ui.graph.style='legacy'"], 9, true),
|
||
@r###"
|
||
@ 0 1 2
|
||
|\ 3 4 5
|
||
| | 6 7 8
|
||
| | 9
|
||
o | 0 1 2
|
||
| | 3 4 5
|
||
| | 6 7 8
|
||
| | 9
|
||
o | 0 1 2
|
||
|/ 3 4 5
|
||
| 6 7 8
|
||
| 9
|
||
o 0 1 2 3
|
||
| 4 5 6 7
|
||
| 8 9
|
||
o 0 1 2 3
|
||
4 5 6 7
|
||
8 9
|
||
"###);
|
||
|
||
// Shouldn't panic with $COLUMNS < graph_width
|
||
insta::assert_snapshot!(render(&["log", "-r@"], 0, true), @r###"
|
||
@ mzvwutvlkqwt
|
||
│ test.user@example.com
|
||
~ 2001-02-03
|
||
04:05:11.000
|
||
+07:00
|
||
68518a7e6c9e
|
||
(empty)
|
||
merge
|
||
"###);
|
||
insta::assert_snapshot!(render(&["log", "-r@"], 1, true), @r###"
|
||
@ mzvwutvlkqwt
|
||
│ test.user@example.com
|
||
~ 2001-02-03
|
||
04:05:11.000
|
||
+07:00
|
||
68518a7e6c9e
|
||
(empty)
|
||
merge
|
||
"###);
|
||
}
|