Skip to content
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased] - Next Date

### Changed

- Renamed CLI option `--reverse` to `--rotate` (`-r`). `--reverse` remains available as a hidden alias.
Comment thread
peso marked this conversation as resolved.
Resolved


## [0.8.3] - 2026-10-29

Expand Down
1 change: 1 addition & 0 deletions docs/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ FLAGS:
automatically (e.g. when piping to a file).
Overrides option '--color'
--no-pager Use no pager (print everything at once without prompt).
-r, --rotate Rotate the graph 180 degrees.
-S, --sparse Print a less compact graph: merge lines point to target lines
rather than merge commits.
--svg Render graph as SVG instead of text-based.
Expand Down
162 changes: 100 additions & 62 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ fn from_args() -> Result<(), String> {
)
}

fn match_args() -> ArgMatches {
fn build_cli() -> Command {
Comment thread
peso marked this conversation as resolved.
Resolved
// Declare command line argument interface for clap
let app = Command::new("git-graph").version(crate_version!()).about(
"Structured Git graphs for your branching model.\n \
Expand All @@ -87,71 +87,73 @@ fn match_args() -> ArgMatches {
let app = add_wrap_args(app);
let app = add_format_args(app);

let app = app
.arg(
Arg::new("reverse")
.long("reverse")
.short('r')
.help("Reverse the order of commits.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("local")
.long("local")
.short('l')
.help("Show only local branches, no remotes.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("svg")
.long("svg")
.help("Render graph as SVG instead of text-based.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("debug")
.long("debug")
.short('d')
.help("Additional debug output and graphics.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("sparse")
.long("sparse")
.short('S')
.help(
"Print a less compact graph: merge lines point to target lines\n\
app.arg(
Arg::new("rotate")
.long("rotate")
.short('r')
.alias("reverse")
.help("Rotate the graph 180 degrees.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("local")
.long("local")
.short('l')
.help("Show only local branches, no remotes.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("svg")
.long("svg")
.help("Render graph as SVG instead of text-based.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("debug")
.long("debug")
.short('d')
.help("Additional debug output and graphics.")
.required(false)
.num_args(0),
)
.arg(
Arg::new("sparse")
.long("sparse")
.short('S')
.help(
"Print a less compact graph: merge lines point to target lines\n\
rather than merge commits.",
)
.required(false)
.num_args(0),
)
.arg(
Arg::new("style")
.long("style")
.short('s')
.help(
"Output style. One of [normal/thin|round|bold|double|ascii].\n \
)
.required(false)
.num_args(0),
)
.arg(
Arg::new("style")
.long("style")
.short('s')
.help(
"Output style. One of [normal/thin|round|bold|double|ascii].\n \
(First character can be used as abbreviation, e.g. '-s r')",
)
.required(false)
.num_args(1),
)
.arg(
Arg::new("refspecs")
.help(
"Branch names or refspecs to show.\n \
)
.required(false)
.num_args(1),
)
.arg(
Arg::new("refspecs")
.help(
"Branch names or refspecs to show.\n \
Only the subgraph between the merge-base and the tips is displayed.",
)
.num_args(1..),
);
)
.num_args(1..),
)
}

fn match_args() -> ArgMatches {
// Return match of declared arguments with what is present on command line
app.get_matches()
build_cli().get_matches()
}

/// Return true if session should continue, false if it should exit now
Expand All @@ -173,7 +175,7 @@ fn configure_session(ses: &mut Session, matches: &ArgMatches) -> Result<bool, St

let include_remote = !matches.get_flag("local");

let reverse_commit_order = matches.get_flag("reverse");
let reverse_commit_order = matches.get_flag("rotate");

ses.svg = matches.get_flag("svg");
let compact = !matches.get_flag("sparse");
Expand Down Expand Up @@ -708,3 +710,39 @@ fn io_err_to_string(result: Result<(), io::Error>) -> Result<(), String> {
}
})
}

#[cfg(test)]
mod cli_tests {
use super::build_cli;

#[test]
fn rotate_flag_sets_rotate() {
let matches = build_cli()
.try_get_matches_from(["git-graph", "--rotate"])
.unwrap();
assert!(matches.get_flag("rotate"));
}

#[test]
fn rotate_short_flag_sets_rotate() {
let matches = build_cli()
.try_get_matches_from(["git-graph", "-r"])
.unwrap();
assert!(matches.get_flag("rotate"));
}

#[test]
fn reverse_alias_sets_rotate() {
let matches = build_cli()
.try_get_matches_from(["git-graph", "--reverse"])
.unwrap();
assert!(matches.get_flag("rotate"));
}

#[test]
fn help_lists_rotate_not_reverse() {
let help = build_cli().render_help().to_string();
assert!(help.contains("--rotate"));
assert!(!help.contains("--reverse"));
}
}
Loading