-
Notifications
You must be signed in to change notification settings - Fork 71
Expand file tree
/
Copy pathdiff.rs
More file actions
90 lines (81 loc) · 3 KB
/
diff.rs
File metadata and controls
90 lines (81 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
// SPDX-License-Identifier: GPL-2.0-only
//! `stg diff` implementation.
use std::path::PathBuf;
use anyhow::Result;
use clap::{Arg, ArgMatches, ValueHint};
use crate::{
argset,
ext::RepositoryExtended,
patch::{RangeRevisionSpec, StGitBoundaryRevisions},
stack::Stack,
stupid::Stupid,
};
pub(super) const STGIT_COMMAND: super::StGitCommand = super::StGitCommand {
name: "diff",
category: super::CommandCategory::PatchInspection,
make,
run,
};
fn make() -> clap::Command {
clap::Command::new(STGIT_COMMAND.name)
.about("Show diff between revisions, a patch, or the working tree")
.long_about(
"Show diff between revisions, a patch, or the working tree.\n\
\n\
Display the diff (default) or diffstat comparing the current working \
directory or a tree-ish object against another tree-ish object (defaulting \
to HEAD). File paths can be specified to limit the diff output to the \
specified files. Tree-ish objects use the format accepted by 'stg id'.",
)
.arg(
Arg::new("pathspecs")
.help("Limit diff to files matching path(s)")
.value_name("path")
.num_args(1..)
.value_parser(clap::value_parser!(PathBuf))
.value_hint(ValueHint::AnyPath),
)
.arg(
Arg::new("range")
.long("range")
.short('r')
.help("Show the diff between specified revisions")
.long_help(
"Show diff between specified revisions. \
Revisions ranges are specified as 'rev1[..[rev2]]'. \
The revisions may be standard Git revision specifiers or \
patches.",
)
.value_name("revspec")
.value_parser(clap::value_parser!(RangeRevisionSpec))
.allow_hyphen_values(true),
)
.arg(
Arg::new("stat")
.long("stat")
.short('s')
.help("Show the stat instead of the diff")
.action(clap::ArgAction::SetTrue),
)
.arg(argset::diff_opts_arg())
}
fn run(matches: &ArgMatches) -> Result<()> {
let repo = gix::Repository::open()?;
let revspec = if let Some(range_spec) = matches.get_one::<RangeRevisionSpec>("range") {
match range_spec.resolve_revisions(&repo, None::<&Stack>, true)? {
StGitBoundaryRevisions::Single(rev) => rev.commit.id.to_string(),
StGitBoundaryRevisions::Bounds((rev0, rev1)) => {
format!("{}..{}", rev0.commit.id, rev1.commit.id)
}
}
} else {
"HEAD".to_string()
};
repo.stupid().diff(
&revspec,
matches.get_many::<PathBuf>("pathspecs"),
matches.get_flag("stat"),
crate::color::use_color(matches),
argset::get_diff_opts(matches, &repo.config_snapshot(), false, false),
)
}