cli/diff: Use clap
The implementation of the *deprecated* command is removed, it now directly invokes `git diff`.
This commit is contained in:
parent
532e5a0de0
commit
72cf3d1919
|
|
@ -32,76 +32,74 @@ $ git commit -m "Make changes"
|
||||||
|
|
||||||
```
|
```
|
||||||
$ rad diff HEAD^ HEAD
|
$ rad diff HEAD^ HEAD
|
||||||
╭────────────────────────────────────────────╮
|
diff --git a/README b/README.md
|
||||||
│ README -> README.md ❲moved❳ │
|
similarity index 100%
|
||||||
╰────────────────────────────────────────────╯
|
rename from README
|
||||||
|
rename to README.md
|
||||||
╭────────────────────────────────────────────╮
|
diff --git a/main.c b/main.c
|
||||||
│ main.c +6 ❲created❳ │
|
new file mode 100644
|
||||||
├────────────────────────────────────────────┤
|
index 0000000..aae4e0e
|
||||||
│ @@ -0,0 +1,6 @@ │
|
--- /dev/null
|
||||||
│ 1 + #include <stdio.h> │
|
+++ b/main.c
|
||||||
│ 2 + │
|
@@ -0,0 +1,6 @@
|
||||||
│ 3 + int main(void) { │
|
+#include <stdio.h>
|
||||||
│ 4 + printf("Hello World!/n"); │
|
+
|
||||||
│ 5 + return 0; │
|
+int main(void) {
|
||||||
│ 6 + } │
|
+ printf("Hello World!/n");
|
||||||
╰────────────────────────────────────────────╯
|
+ return 0;
|
||||||
|
+}
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
$ sed -i 's/Hello World/Hello Radicle/' main.c
|
$ sed -i 's/Hello World/Hello Radicle/' main.c
|
||||||
$ rad diff
|
$ rad diff
|
||||||
╭──────────────────────────────────────────────╮
|
diff --git a/main.c b/main.c
|
||||||
│ main.c -1 +1 │
|
index aae4e0e..a3ed869 100644
|
||||||
├──────────────────────────────────────────────┤
|
--- a/main.c
|
||||||
│ @@ -1,6 +1,6 @@ │
|
+++ b/main.c
|
||||||
│ 1 1 #include <stdio.h> │
|
@@ -1,6 +1,6 @@
|
||||||
│ 2 2 │
|
#include <stdio.h>
|
||||||
│ 3 3 int main(void) { │
|
|
||||||
│ 4 - printf("Hello World!/n"); │
|
int main(void) {
|
||||||
│ 4 + printf("Hello Radicle!/n"); │
|
- printf("Hello World!/n");
|
||||||
│ 5 5 return 0; │
|
+ printf("Hello Radicle!/n");
|
||||||
│ 6 6 } │
|
return 0;
|
||||||
╰──────────────────────────────────────────────╯
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git add main.c
|
$ git add main.c
|
||||||
$ rad diff
|
$ rad diff
|
||||||
$ rad diff --staged
|
$ rad diff --staged
|
||||||
╭──────────────────────────────────────────────╮
|
diff --git a/main.c b/main.c
|
||||||
│ main.c -1 +1 │
|
index aae4e0e..a3ed869 100644
|
||||||
├──────────────────────────────────────────────┤
|
--- a/main.c
|
||||||
│ @@ -1,6 +1,6 @@ │
|
+++ b/main.c
|
||||||
│ 1 1 #include <stdio.h> │
|
@@ -1,6 +1,6 @@
|
||||||
│ 2 2 │
|
#include <stdio.h>
|
||||||
│ 3 3 int main(void) { │
|
|
||||||
│ 4 - printf("Hello World!/n"); │
|
int main(void) {
|
||||||
│ 4 + printf("Hello Radicle!/n"); │
|
- printf("Hello World!/n");
|
||||||
│ 5 5 return 0; │
|
+ printf("Hello Radicle!/n");
|
||||||
│ 6 6 } │
|
return 0;
|
||||||
╰──────────────────────────────────────────────╯
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```
|
```
|
||||||
$ git rm -f -q main.c
|
$ git rm -f -q main.c
|
||||||
$ rad diff --staged
|
$ rad diff --staged
|
||||||
╭────────────────────────────────────────────╮
|
diff --git a/main.c b/main.c
|
||||||
│ main.c -6 ❲deleted❳ │
|
deleted file mode 100644
|
||||||
├────────────────────────────────────────────┤
|
index aae4e0e..0000000
|
||||||
│ @@ -1,6 +0,0 @@ │
|
--- a/main.c
|
||||||
│ 1 - #include <stdio.h> │
|
+++ /dev/null
|
||||||
│ 2 - │
|
@@ -1,6 +0,0 @@
|
||||||
│ 3 - int main(void) { │
|
-#include <stdio.h>
|
||||||
│ 4 - printf("Hello World!/n"); │
|
-
|
||||||
│ 5 - return 0; │
|
-int main(void) {
|
||||||
│ 6 - } │
|
- printf("Hello World!/n");
|
||||||
╰────────────────────────────────────────────╯
|
- return 0;
|
||||||
|
-}
|
||||||
```
|
```
|
||||||
|
|
||||||
For now, copies are not detected.
|
For now, copies are not detected.
|
||||||
|
|
@ -112,13 +110,13 @@ $ mkdir docs
|
||||||
$ cp README.md docs/README.md
|
$ cp README.md docs/README.md
|
||||||
$ git add docs
|
$ git add docs
|
||||||
$ rad diff --staged
|
$ rad diff --staged
|
||||||
╭─────────────────────────────╮
|
diff --git a/docs/README.md b/docs/README.md
|
||||||
│ docs/README.md +1 ❲created❳ │
|
new file mode 100644
|
||||||
├─────────────────────────────┤
|
index 0000000..980a0d5
|
||||||
│ @@ -0,0 +1,1 @@ │
|
--- /dev/null
|
||||||
│ 1 + Hello World! │
|
+++ b/docs/README.md
|
||||||
╰─────────────────────────────╯
|
@@ -0,0 +1 @@
|
||||||
|
+Hello World!
|
||||||
$ git reset
|
$ git reset
|
||||||
$ git checkout .
|
$ git checkout .
|
||||||
```
|
```
|
||||||
|
|
@ -129,10 +127,9 @@ Empty file.
|
||||||
$ touch EMPTY
|
$ touch EMPTY
|
||||||
$ git add EMPTY
|
$ git add EMPTY
|
||||||
$ rad diff --staged
|
$ rad diff --staged
|
||||||
╭─────────────────╮
|
diff --git a/EMPTY b/EMPTY
|
||||||
│ EMPTY ❲created❳ │
|
new file mode 100644
|
||||||
╰─────────────────╯
|
index 0000000..e69de29
|
||||||
|
|
||||||
$ git reset
|
$ git reset
|
||||||
$ git checkout .
|
$ git checkout .
|
||||||
```
|
```
|
||||||
|
|
@ -142,10 +139,9 @@ File mode change.
|
||||||
```
|
```
|
||||||
$ chmod +x README.md
|
$ chmod +x README.md
|
||||||
$ rad diff
|
$ rad diff
|
||||||
╭───────────────────────────────────────────╮
|
diff --git a/README.md b/README.md
|
||||||
│ README.md 100644 -> 100755 ❲mode changed❳ │
|
old mode 100644
|
||||||
╰───────────────────────────────────────────╯
|
new mode 100755
|
||||||
|
|
||||||
$ git reset -q
|
$ git reset -q
|
||||||
$ git checkout .
|
$ git checkout .
|
||||||
```
|
```
|
||||||
|
|
@ -157,8 +153,8 @@ $ touch file.bin
|
||||||
$ truncate -s 8 file.bin
|
$ truncate -s 8 file.bin
|
||||||
$ git add file.bin
|
$ git add file.bin
|
||||||
$ rad diff --staged
|
$ rad diff --staged
|
||||||
╭─────────────────────────────╮
|
diff --git a/file.bin b/file.bin
|
||||||
│ file.bin ❲binary❳ ❲created❳ │
|
new file mode 100644
|
||||||
╰─────────────────────────────╯
|
index 0000000..1b1cb4d
|
||||||
|
Binary files /dev/null and b/file.bin differ
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -11,13 +11,13 @@ $ git push rad HEAD:refs/patches
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
$ rad patch diff 147309e
|
$ rad patch diff 147309e
|
||||||
╭───────────────────────────╮
|
diff --git a/README.md b/README.md
|
||||||
│ README.md +1 ❲created❳ │
|
new file mode 100644
|
||||||
├───────────────────────────┤
|
index 0000000..980a0d5
|
||||||
│ @@ -0,0 +1,1 @@ │
|
--- /dev/null
|
||||||
│ 1 + Hello World! │
|
+++ b/README.md
|
||||||
╰───────────────────────────╯
|
@@ -0,0 +1 @@
|
||||||
|
+Hello World!
|
||||||
```
|
```
|
||||||
|
|
||||||
If we add another file and update the patch, we can see it in the diff.
|
If we add another file and update the patch, we can see it in the diff.
|
||||||
|
|
@ -32,20 +32,20 @@ $ git push -f
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
$ rad patch diff 147309e
|
$ rad patch diff 147309e
|
||||||
╭─────────────────────────────╮
|
diff --git a/RADICLE.md b/RADICLE.md
|
||||||
│ RADICLE.md +1 ❲created❳ │
|
new file mode 100644
|
||||||
├─────────────────────────────┤
|
index 0000000..e517184
|
||||||
│ @@ -0,0 +1,1 @@ │
|
--- /dev/null
|
||||||
│ 1 + Hello Radicle! │
|
+++ b/RADICLE.md
|
||||||
╰─────────────────────────────╯
|
@@ -0,0 +1 @@
|
||||||
|
+Hello Radicle!
|
||||||
╭─────────────────────────────╮
|
diff --git a/README.md b/README.md
|
||||||
│ README.md +1 ❲created❳ │
|
new file mode 100644
|
||||||
├─────────────────────────────┤
|
index 0000000..980a0d5
|
||||||
│ @@ -0,0 +1,1 @@ │
|
--- /dev/null
|
||||||
│ 1 + Hello World! │
|
+++ b/README.md
|
||||||
╰─────────────────────────────╯
|
@@ -0,0 +1 @@
|
||||||
|
+Hello World!
|
||||||
```
|
```
|
||||||
|
|
||||||
Buf if we only want to see the changes from the first revision, we can do that
|
Buf if we only want to see the changes from the first revision, we can do that
|
||||||
|
|
@ -53,11 +53,11 @@ too.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ rad patch diff 147309e --revision 147309e
|
$ rad patch diff 147309e --revision 147309e
|
||||||
╭───────────────────────────╮
|
diff --git a/README.md b/README.md
|
||||||
│ README.md +1 ❲created❳ │
|
new file mode 100644
|
||||||
├───────────────────────────┤
|
index 0000000..980a0d5
|
||||||
│ @@ -0,0 +1,1 @@ │
|
--- /dev/null
|
||||||
│ 1 + Hello World! │
|
+++ b/README.md
|
||||||
╰───────────────────────────╯
|
@@ -0,0 +1 @@
|
||||||
|
+Hello World!
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -1,153 +1,14 @@
|
||||||
use std::ffi::OsString;
|
use std::{ffi::OsString, process};
|
||||||
|
|
||||||
use anyhow::anyhow;
|
pub fn run(args: Vec<OsString>) -> anyhow::Result<()> {
|
||||||
|
|
||||||
use radicle::git;
|
|
||||||
use radicle::rad;
|
|
||||||
use radicle_surf as surf;
|
|
||||||
|
|
||||||
use crate::git::pretty_diff::ToPretty as _;
|
|
||||||
use crate::git::Rev;
|
|
||||||
use crate::terminal as term;
|
|
||||||
use crate::terminal::args::{Args, Error, Help};
|
|
||||||
use crate::terminal::highlight::Highlighter;
|
|
||||||
|
|
||||||
pub const HELP: Help = Help {
|
|
||||||
name: "diff",
|
|
||||||
description: "Show changes between commits",
|
|
||||||
version: env!("RADICLE_VERSION"),
|
|
||||||
usage: r#"
|
|
||||||
Usage
|
|
||||||
|
|
||||||
rad diff [<commit>] [--staged] [<option>...]
|
|
||||||
rad diff <commit> [<commit>] [<option>...]
|
|
||||||
|
|
||||||
This command is meant to operate as closely as possible to `git diff`,
|
|
||||||
except its output is optimized for human-readability.
|
|
||||||
|
|
||||||
Options
|
|
||||||
|
|
||||||
--unified, -U Context lines to show (default: 5)
|
|
||||||
--staged View staged changes
|
|
||||||
--color Force color output
|
|
||||||
--help Print help
|
|
||||||
"#,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub struct Options {
|
|
||||||
pub commits: Vec<Rev>,
|
|
||||||
pub staged: bool,
|
|
||||||
pub unified: usize,
|
|
||||||
pub color: bool,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Args for Options {
|
|
||||||
fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
|
|
||||||
use lexopt::prelude::*;
|
|
||||||
|
|
||||||
let mut parser = lexopt::Parser::from_args(args);
|
|
||||||
let mut commits = Vec::new();
|
|
||||||
let mut staged = false;
|
|
||||||
let mut unified = 5;
|
|
||||||
let mut color = false;
|
|
||||||
|
|
||||||
while let Some(arg) = parser.next()? {
|
|
||||||
match arg {
|
|
||||||
Long("unified") | Short('U') => {
|
|
||||||
let val = parser.value()?;
|
|
||||||
unified = term::args::number(&val)?;
|
|
||||||
}
|
|
||||||
Long("staged") | Long("cached") => staged = true,
|
|
||||||
Long("color") => color = true,
|
|
||||||
Long("help") | Short('h') => return Err(Error::Help.into()),
|
|
||||||
Value(val) => {
|
|
||||||
let rev = term::args::rev(&val)?;
|
|
||||||
|
|
||||||
commits.push(rev);
|
|
||||||
}
|
|
||||||
_ => anyhow::bail!(arg.unexpected()),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok((
|
|
||||||
Options {
|
|
||||||
commits,
|
|
||||||
staged,
|
|
||||||
unified,
|
|
||||||
color,
|
|
||||||
},
|
|
||||||
vec![],
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn run(options: Options, _ctx: impl term::Context) -> anyhow::Result<()> {
|
|
||||||
crate::warning::deprecated("rad diff", "git diff");
|
crate::warning::deprecated("rad diff", "git diff");
|
||||||
|
|
||||||
let repo = rad::repo()?;
|
let mut child = process::Command::new("git")
|
||||||
let oids = options
|
.arg("diff")
|
||||||
.commits
|
.args(args)
|
||||||
.into_iter()
|
.spawn()?;
|
||||||
.map(|rev| {
|
|
||||||
repo.revparse_single(rev.as_str())
|
|
||||||
.map_err(|e| anyhow!("unknown object {rev}: {e}"))
|
|
||||||
.and_then(|o| {
|
|
||||||
o.into_commit()
|
|
||||||
.map_err(|_| anyhow!("object {rev} is not a commit"))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
|
||||||
|
|
||||||
let mut opts = git::raw::DiffOptions::new();
|
let exit_status = child.wait()?;
|
||||||
opts.patience(true)
|
|
||||||
.minimal(true)
|
|
||||||
.context_lines(options.unified as u32);
|
|
||||||
|
|
||||||
let mut find_opts = git::raw::DiffFindOptions::new();
|
process::exit(exit_status.code().unwrap_or(1));
|
||||||
find_opts.exact_match_only(true);
|
|
||||||
find_opts.all(true);
|
|
||||||
|
|
||||||
let mut diff = match oids.as_slice() {
|
|
||||||
[] => {
|
|
||||||
if options.staged {
|
|
||||||
let head = repo.head()?.peel_to_tree()?;
|
|
||||||
// HEAD vs. index.
|
|
||||||
repo.diff_tree_to_index(Some(&head), None, Some(&mut opts))
|
|
||||||
} else {
|
|
||||||
// Working tree vs. index.
|
|
||||||
repo.diff_index_to_workdir(None, None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[commit] => {
|
|
||||||
let commit = commit.tree()?;
|
|
||||||
if options.staged {
|
|
||||||
// Commit vs. index.
|
|
||||||
repo.diff_tree_to_index(Some(&commit), None, Some(&mut opts))
|
|
||||||
} else {
|
|
||||||
// Commit vs. working tree.
|
|
||||||
repo.diff_tree_to_workdir(Some(&commit), Some(&mut opts))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
[left, right] => {
|
|
||||||
// Commit vs. commit.
|
|
||||||
let left = left.tree()?;
|
|
||||||
let right = right.tree()?;
|
|
||||||
|
|
||||||
repo.diff_tree_to_tree(Some(&left), Some(&right), Some(&mut opts))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
anyhow::bail!("Too many commits given. See `rad diff --help` for usage.");
|
|
||||||
}
|
|
||||||
}?;
|
|
||||||
diff.find_similar(Some(&mut find_opts))?;
|
|
||||||
|
|
||||||
term::Paint::force(options.color);
|
|
||||||
|
|
||||||
let diff = surf::diff::Diff::try_from(diff)?;
|
|
||||||
let mut hi = Highlighter::default();
|
|
||||||
let pretty = diff.pretty(&mut hi, &(), &repo);
|
|
||||||
|
|
||||||
crate::pager::run(pretty)?;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,18 @@ enum Commands {
|
||||||
Clean(clean::Args),
|
Clean(clean::Args),
|
||||||
Clone(clone::Args),
|
Clone(clone::Args),
|
||||||
Debug(debug::Args),
|
Debug(debug::Args),
|
||||||
|
|
||||||
|
/// This command is deprecated and delegates to `git diff`.
|
||||||
|
/// Even before it was deprecated, it was not printed by
|
||||||
|
/// `rad -h`, so it is also hidden.
|
||||||
|
///
|
||||||
|
/// Since it is hidden, it makes no sense to add `about`
|
||||||
|
/// for the command listing, and since it is external,
|
||||||
|
/// `--help` will delegate to `git diff --help` it makes
|
||||||
|
/// no sense to add `long_about` for `rad diff --help`.
|
||||||
|
#[command(external_subcommand, hide = true)]
|
||||||
|
Diff(Vec<OsString>),
|
||||||
|
|
||||||
Fork(fork::Args),
|
Fork(fork::Args),
|
||||||
Init(init::Args),
|
Init(init::Args),
|
||||||
Issue(issue::Args),
|
Issue(issue::Args),
|
||||||
|
|
@ -212,7 +224,11 @@ pub(crate) fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option<anyho
|
||||||
term::run_command_args::<config::Options, _>(config::HELP, config::run, args.to_vec());
|
term::run_command_args::<config::Options, _>(config::HELP, config::run, args.to_vec());
|
||||||
}
|
}
|
||||||
"diff" => {
|
"diff" => {
|
||||||
term::run_command_args::<diff::Options, _>(diff::HELP, diff::run, args.to_vec());
|
if let Some(Commands::Diff(mut args)) = CliArgs::parse().command {
|
||||||
|
debug_assert_eq!(args[0], "diff");
|
||||||
|
args.remove(0);
|
||||||
|
return diff::run(args).map_err(Some);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"debug" => {
|
"debug" => {
|
||||||
if let Some(Commands::Debug(args)) = CliArgs::parse().command {
|
if let Some(Commands::Debug(args)) = CliArgs::parse().command {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue