Skip to content

Commit 711484d

Browse files
committed
log: add --count flag
Inspired by @indirect's talk at JJ Con (https://www.youtube.com/watch?v=ZnTNFIMjDwg)
1 parent a1c9c3d commit 711484d

File tree

4 files changed

+61
-1
lines changed

4 files changed

+61
-1
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ should not be broken.
101101
* Added `join()` template function. This is different from `separate()` in that
102102
it adds a separator between all arguments, even if empty.
103103

104+
* `jj log` now supports a `--count` flag to print the number of commits instead
105+
of displaying them.
106+
104107
### Fixed bugs
105108

106109
* `jj fix` now prints a warning if a tool failed to run on a file.

cli/src/commands/log.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
use std::cmp::min;
16+
1517
use clap_complete::ArgValueCandidates;
1618
use clap_complete::ArgValueCompleter;
1719
use itertools::Itertools as _;
@@ -116,6 +118,9 @@ pub(crate) struct LogArgs {
116118
/// Show patch
117119
#[arg(long, short = 'p')]
118120
patch: bool,
121+
/// Print the number of commits instead of showing them
122+
#[arg(long, conflicts_with_all = ["DiffFormatArgs", "no_graph", "patch", "reversed", "template"])]
123+
count: bool,
119124
#[command(flatten)]
120125
diff_format: DiffFormatArgs,
121126
}
@@ -150,12 +155,32 @@ pub(crate) fn cmd_log(
150155
}
151156
expression
152157
};
158+
159+
let revset = revset_expression.evaluate()?;
160+
161+
if args.count {
162+
let (lower, upper) = revset.count_estimate()?;
163+
let limit = args.limit.unwrap_or(usize::MAX);
164+
let count = if limit <= lower {
165+
limit
166+
} else if upper == Some(lower) {
167+
min(lower, limit)
168+
} else {
169+
revset
170+
.iter()
171+
.take(limit)
172+
.process_results(|iter| iter.count())?
173+
};
174+
let mut formatter = ui.stdout_formatter();
175+
writeln!(formatter, "{count}")?;
176+
return Ok(());
177+
}
178+
153179
let prio_revset = settings.get_string("revsets.log-graph-prioritize")?;
154180
let prio_revset = workspace_command.parse_revset(ui, &RevisionArg::from(prio_revset))?;
155181

156182
let repo = workspace_command.repo();
157183
let matcher = fileset_expression.to_matcher();
158-
let revset = revset_expression.evaluate()?;
159184

160185
let store = repo.store();
161186
let diff_renderer = workspace_command.diff_renderer_for_log(&args.diff_format, args.patch)?;

cli/tests/cli-reference@.md.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1763,6 +1763,7 @@ The working-copy commit is indicated by a `@` symbol in the graph. [Immutable re
17631763

17641764
[`jj help -k templates`]: https://docs.jj-vcs.dev/latest/templates/
17651765
* `-p`, `--patch` — Show patch
1766+
* `--count` — Print the number of commits instead of showing them
17661767
* `-s`, `--summary` — For each path, show only whether it was modified, added, or deleted
17671768
* `--stat` — Show a histogram of the changes
17681769
* `--types` — For each path, show only its type before and after

cli/tests/test_log_command.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1757,3 +1757,34 @@ fn test_log_anonymize() {
17571757
[EOF]
17581758
");
17591759
}
1760+
1761+
#[test]
1762+
fn test_log_count() {
1763+
let test_env = TestEnvironment::default();
1764+
test_env.run_jj_in(".", ["git", "init", "repo"]).success();
1765+
let work_dir = test_env.work_dir("repo");
1766+
1767+
work_dir.write_file("file1", "foo\n");
1768+
work_dir.run_jj(["describe", "-m", "first"]).success();
1769+
work_dir.run_jj(["new", "-m", "second"]).success();
1770+
work_dir.write_file("file2", "bar\n");
1771+
work_dir.run_jj(["new", "-m", "third"]).success();
1772+
1773+
let output = work_dir.run_jj(["log", "--count"]);
1774+
insta::assert_snapshot!(output, @r"
1775+
4
1776+
[EOF]
1777+
");
1778+
1779+
let output = work_dir.run_jj(["log", "--count", "-r", "all() ~ root()"]);
1780+
insta::assert_snapshot!(output, @r"
1781+
3
1782+
[EOF]
1783+
");
1784+
1785+
let output = work_dir.run_jj(["log", "--count", "--limit", "2"]);
1786+
insta::assert_snapshot!(output, @r"
1787+
2
1788+
[EOF]
1789+
");
1790+
}

0 commit comments

Comments
 (0)