Skip to content

Commit

Permalink
cli: teach log flag to show commits in reverse order
Browse files Browse the repository at this point in the history
This adds a `--reversed` flag to `jj log` to show commits with later
commits further down. It works both with and without the graph.

Since the graph-drawing code is already independent of the
relationship between commits, it doesn't need any updating.
  • Loading branch information
martinvonz committed May 15, 2022
1 parent 0747da0 commit 6c83eb6
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 4 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Aliases can now call other aliases.

* `jj log` now accepts a `--reversed` option, which will show older commits
first.

### Fixed bugs

* When rebasing a conflict where one side modified a file and the other side
Expand Down
18 changes: 18 additions & 0 deletions lib/src/revset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,6 +833,12 @@ impl<'revset, 'repo> RevsetIterator<'revset, 'repo> {
}
}

pub fn reversed(self) -> ReverseRevsetIterator<'repo> {
ReverseRevsetIterator {
entries: self.into_iter().collect_vec(),
}
}

pub fn graph(self) -> RevsetGraphIterator<'revset, 'repo> {
RevsetGraphIterator::new(self)
}
Expand Down Expand Up @@ -873,6 +879,18 @@ impl Iterator for RevsetCommitIterator<'_, '_> {
}
}

pub struct ReverseRevsetIterator<'repo> {
entries: Vec<IndexEntry<'repo>>,
}

impl<'repo> Iterator for ReverseRevsetIterator<'repo> {
type Item = IndexEntry<'repo>;

fn next(&mut self) -> Option<Self::Item> {
self.entries.pop()
}
}

struct EagerRevset<'repo> {
index_entries: Vec<IndexEntry<'repo>>,
}
Expand Down
21 changes: 17 additions & 4 deletions src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ use jujutsu_lib::diff::{Diff, DiffHunk};
use jujutsu_lib::files::DiffLine;
use jujutsu_lib::git::{GitExportError, GitFetchError, GitImportError, GitRefUpdate};
use jujutsu_lib::gitignore::GitIgnoreFile;
use jujutsu_lib::index::HexPrefix;
use jujutsu_lib::index::{HexPrefix, IndexEntry};
use jujutsu_lib::matchers::{EverythingMatcher, Matcher, PrefixMatcher, Visit};
use jujutsu_lib::op_heads_store::{OpHeadResolutionError, OpHeads, OpHeadsStore};
use jujutsu_lib::op_store::{OpStore, OpStoreError, OperationId, RefTarget, WorkspaceId};
Expand All @@ -51,7 +51,7 @@ use jujutsu_lib::refs::{classify_branch_push_action, BranchPushAction, BranchPus
use jujutsu_lib::repo::{MutableRepo, ReadonlyRepo, RepoRef};
use jujutsu_lib::repo_path::RepoPath;
use jujutsu_lib::revset::{RevsetError, RevsetExpression, RevsetParseError};
use jujutsu_lib::revset_graph_iterator::RevsetGraphEdgeType;
use jujutsu_lib::revset_graph_iterator::{RevsetGraphEdge, RevsetGraphEdgeType};
use jujutsu_lib::rewrite::{back_out_commit, merge_commit_trees, rebase_commit, DescendantRebaser};
use jujutsu_lib::settings::UserSettings;
use jujutsu_lib::store::Store;
Expand Down Expand Up @@ -1280,6 +1280,9 @@ struct LogArgs {
default_value = "remote_branches().. | (remote_branches()..)-"
)]
revisions: String,
/// Show revisions in the opposite order (older revisions first)
#[clap(long)]
reversed: bool,
/// Don't show the graph, show a flat list of revisions
#[clap(long)]
no_graph: bool,
Expand Down Expand Up @@ -3016,7 +3019,12 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C

if !args.no_graph {
let mut graph = AsciiGraphDrawer::new(&mut formatter);
for (index_entry, edges) in revset.iter().graph() {
let iter: Box<dyn Iterator<Item = (IndexEntry, Vec<RevsetGraphEdge>)>> = if args.reversed {
Box::new(revset.iter().graph().reversed())
} else {
Box::new(revset.iter().graph())
};
for (index_entry, edges) in iter {
let mut graphlog_edges = vec![];
// TODO: Should we update RevsetGraphIterator to yield this flag instead of all
// the missing edges since we don't care about where they point here
Expand Down Expand Up @@ -3072,7 +3080,12 @@ fn cmd_log(ui: &mut Ui, command: &CommandHelper, args: &LogArgs) -> Result<(), C
)?;
}
} else {
for index_entry in revset.iter() {
let iter: Box<dyn Iterator<Item = IndexEntry>> = if args.reversed {
Box::new(revset.iter().reversed())
} else {
Box::new(revset.iter())
};
for index_entry in iter {
let commit = store.get_commit(&index_entry.commit_id())?;
template.format(&commit, formatter)?;
if let Some(diff_format) = diff_format {
Expand Down
27 changes: 27 additions & 0 deletions tests/test_log_command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,30 @@ fn test_log_with_or_without_diff() {
+bar
"###);
}

#[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###"
o
o first
@ second
"###);

let stdout = test_env.jj_cmd_success(
&repo_path,
&["log", "-T", "description", "--reversed", "--no-graph"],
);
insta::assert_snapshot!(stdout, @r###"
first
second
"###);
}

0 comments on commit 6c83eb6

Please sign in to comment.