Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --reversed flag to evolog #5170

Merged
merged 1 commit into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### New features

* `jj evolog` now accepts `--reversed`.

### Fixed bugs

## [0.25.0] - 2025-01-01
Expand Down
48 changes: 40 additions & 8 deletions cli/src/commands/evolog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use std::convert::Infallible;

use clap_complete::ArgValueCandidates;
use itertools::Itertools;
use jj_lib::backend::BackendError;
use jj_lib::backend::CommitId;
use jj_lib::commit::Commit;
use jj_lib::dag_walk::topo_order_reverse_ok;
use jj_lib::graph::reverse_graph;
use jj_lib::graph::GraphEdge;
use jj_lib::graph::GraphNode;
use jj_lib::matchers::EverythingMatcher;
use tracing::instrument;

Expand All @@ -28,6 +35,7 @@ use crate::command_error::CommandError;
use crate::commit_templater::CommitTemplateLanguage;
use crate::complete;
use crate::diff_util::DiffFormatArgs;
use crate::graphlog::convert_edge_type;
use crate::graphlog::get_graphlog;
use crate::graphlog::Edge;
use crate::graphlog::GraphStyle;
Expand Down Expand Up @@ -57,6 +65,9 @@ pub(crate) struct EvologArgs {
value_name = "LIMIT"
)]
deprecated_limit: Option<usize>,
/// Show revisions in the opposite order (older revisions first)
#[arg(long)]
reversed: bool,
/// Don't show the graph, show a flat list of revisions
#[arg(long)]
no_graph: bool,
Expand Down Expand Up @@ -151,14 +162,31 @@ pub(crate) fn cmd_evolog(
if !args.no_graph {
let mut raw_output = formatter.raw()?;
let mut graph = get_graphlog(graph_style, raw_output.as_mut());
for commit in commits {
let edges = commit
.predecessor_ids()
.iter()
.map(|id| Edge::Direct(id.clone()))
.collect_vec();

let commit_dag: Vec<GraphNode<Commit>> = commits
.into_iter()
.map(|c| -> Result<_, BackendError> {
let edges = c.predecessors().map_ok(GraphEdge::direct).try_collect()?;
Ok((c, edges))
})
.try_collect()?;

let iter_nodes = if args.reversed {
JDSeiler marked this conversation as resolved.
Show resolved Hide resolved
reverse_graph(commit_dag.into_iter().map(Result::<_, Infallible>::Ok)).unwrap()
} else {
commit_dag
};

for node in iter_nodes {
let (commit, edges) = node;
JDSeiler marked this conversation as resolved.
Show resolved Hide resolved
// Slightly different edge type used for display.
let graphlog_edges: Vec<Edge<CommitId>> = edges
.into_iter()
.map(|e| convert_edge_type(e).map(|e| e.id().clone()))
.collect();
let mut buffer = vec![];
let within_graph = with_content_format.sub_width(graph.width(commit.id(), &edges));
let within_graph =
with_content_format.sub_width(graph.width(commit.id(), &graphlog_edges));
within_graph.write(ui.new_formatter(&mut buffer).as_mut(), |formatter| {
template.format(&commit, formatter)
})?;
Expand All @@ -180,12 +208,16 @@ pub(crate) fn cmd_evolog(
let node_symbol = format_template(ui, &Some(commit.clone()), &node_template);
graph.add_node(
commit.id(),
&edges,
&graphlog_edges,
&node_symbol,
&String::from_utf8_lossy(&buffer),
)?;
}
} else {
if args.reversed {
commits.reverse();
}

for commit in commits {
with_content_format
.write(formatter, |formatter| template.format(&commit, formatter))?;
Expand Down
24 changes: 24 additions & 0 deletions cli/src/graphlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ use std::io::Write;

use itertools::Itertools;
use jj_lib::config::ConfigGetError;
use jj_lib::graph::GraphEdge;
use jj_lib::graph::GraphEdgeType;
use jj_lib::settings::UserSettings;
use renderdag::Ancestor;
use renderdag::GraphRowRenderer;
Expand All @@ -31,6 +33,28 @@ pub enum Edge<T> {
Missing,
}

impl<T> Edge<T> {
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Edge<U> {
match self {
Edge::Direct(inner) => Edge::Direct(f(inner)),
Edge::Indirect(inner) => Edge::Indirect(f(inner)),
Edge::Missing => Edge::Missing,
}
}
}

/// Used to convert a jj_lib GraphEdge into a graphlog Edge.
pub fn convert_edge_type<N>(e: GraphEdge<N>) -> Edge<N> {
// TODO: Is it possible for the ClI to use the GraphEdge type directly?
// These two types seem to correspond exactly, only differing in minor
// implementation details.
JDSeiler marked this conversation as resolved.
Show resolved Hide resolved
match e.edge_type {
GraphEdgeType::Missing => Edge::Missing,
GraphEdgeType::Direct => Edge::Direct(e.target),
GraphEdgeType::Indirect => Edge::Indirect(e.target),
}
}

pub trait GraphLog<K: Clone + Eq + Hash> {
fn add_node(
&mut self,
Expand Down
1 change: 1 addition & 0 deletions cli/tests/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ Lists the previous commits which a change has pointed to. The current commit of

Default value: `@`
* `-n`, `--limit <LIMIT>` — Limit number of revisions to show
* `--reversed` — Show revisions in the opposite order (older revisions first)
* `--no-graph` — Don't show the graph, show a flat list of revisions
* `-T`, `--template <TEMPLATE>` — Render each revision using the given template

Expand Down
67 changes: 67 additions & 0 deletions cli/tests/test_evolog_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,70 @@ fn test_evolog_with_no_template() {
- name_placeholder
"#);
}

#[test]
fn test_evolog_reversed_no_graph() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let repo_path = test_env.env_root().join("repo");

test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "a"]);
test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "b"]);
test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "c"]);
let stdout = test_env.jj_cmd_success(&repo_path, &["evolog", "--reversed", "--no-graph"]);
insta::assert_snapshot!(stdout, @r"
qpvuntsm hidden [email protected] 2001-02-03 08:05:07 230dd059
(empty) (no description set)
qpvuntsm hidden [email protected] 2001-02-03 08:05:08 d8d5f980
(empty) a
qpvuntsm hidden [email protected] 2001-02-03 08:05:09 b4584f54
(empty) b
qpvuntsm [email protected] 2001-02-03 08:05:10 5cb22a87
(empty) c
");
}

#[test]
fn test_evolog_reverse_with_graph() {
let test_env = TestEnvironment::default();
test_env.jj_cmd_ok(test_env.env_root(), &["git", "init", "repo"]);
let repo_path = test_env.env_root().join("repo");

test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "a"]);
test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "b"]);
test_env.jj_cmd_ok(&repo_path, &["describe", "-m", "c"]);
test_env.jj_cmd_ok(&repo_path, &["new", "-r", "description(c)", "-m", "d"]);
test_env.jj_cmd_ok(&repo_path, &["new", "-r", "description(c)", "-m", "e"]);
test_env.jj_cmd_ok(
&repo_path,
&[
"squash",
"--from",
"description(d)|description(e)",
"--to",
"description(c)",
"-m",
"c+d+e",
],
);
let stdout = test_env.jj_cmd_success(
&repo_path,
&["evolog", "-r", "description(c+d+e)", "--reversed"],
);
insta::assert_snapshot!(stdout, @r"
○ qpvuntsm hidden [email protected] 2001-02-03 08:05:07 230dd059
│ (empty) (no description set)
○ qpvuntsm hidden [email protected] 2001-02-03 08:05:08 d8d5f980
│ (empty) a
○ qpvuntsm hidden [email protected] 2001-02-03 08:05:09 b4584f54
│ (empty) b
○ qpvuntsm hidden [email protected] 2001-02-03 08:05:10 5cb22a87
│ (empty) c
│ ○ mzvwutvl hidden [email protected] 2001-02-03 08:05:11 280cbb6e
├─╯ (empty) d
│ ○ royxmykx hidden [email protected] 2001-02-03 08:05:12 031df638
├─╯ (empty) e
○ qpvuntsm [email protected] 2001-02-03 08:05:13 a177c2f2
(empty) c+d+e
");
}
Loading