Skip to content

Commit 5261fed

Browse files
committed
Update diff example to allow basic diffing of blobs.
This could be improved by adding color support, etc.
1 parent b1ebf6a commit 5261fed

File tree

1 file changed

+38
-2
lines changed

1 file changed

+38
-2
lines changed

examples/diff.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414

1515
#![deny(warnings)]
1616

17-
use git2::{Diff, DiffOptions, Error, Object, ObjectType, Repository};
18-
use git2::{DiffFindOptions, DiffFormat};
17+
use git2::{Blob, Diff, DiffOptions, Error, Object, ObjectType, Oid, Repository};
18+
use git2::{DiffDelta, DiffFindOptions, DiffFormat, DiffHunk, DiffLine};
1919
use std::str;
2020
use structopt::StructOpt;
2121

@@ -26,6 +26,9 @@ struct Args {
2626
arg_from_oid: Option<String>,
2727
#[structopt(name = "to_oid")]
2828
arg_to_oid: Option<String>,
29+
#[structopt(name = "blobs", long)]
30+
/// treat from_oid and to_oid as blob ids
31+
flag_blobs: bool,
2932
#[structopt(name = "patch", short, long)]
3033
/// show output in patch format
3134
flag_patch: bool,
@@ -137,6 +140,11 @@ enum Cache {
137140
None,
138141
}
139142

143+
fn print_diff(_delta: DiffDelta, _hunk: Option<DiffHunk>, line: DiffLine) -> bool {
144+
print!("{}{}", line.origin(), str::from_utf8(line.content()).unwrap());
145+
true
146+
}
147+
140148
fn run(args: &Args) -> Result<(), Error> {
141149
let path = args.flag_git_dir.as_ref().map(|s| &s[..]).unwrap_or(".");
142150
let repo = Repository::open(path)?;
@@ -171,6 +179,23 @@ fn run(args: &Args) -> Result<(), Error> {
171179
opts.id_abbrev(40);
172180
}
173181

182+
if args.flag_blobs {
183+
let b1 = resolve_blob(&repo, args.arg_from_oid.as_ref())?;
184+
let b2 = resolve_blob(&repo, args.arg_to_oid.as_ref())?;
185+
repo.diff_blobs(
186+
b1.as_ref(),
187+
None,
188+
b2.as_ref(),
189+
None,
190+
Some(&mut opts),
191+
None,
192+
None,
193+
None,
194+
Some(&mut print_diff),
195+
)?;
196+
return Ok(());
197+
}
198+
174199
// Prepare the diff to inspect
175200
let t1 = tree_to_treeish(&repo, args.arg_from_oid.as_ref())?;
176201
let t2 = tree_to_treeish(&repo, args.arg_to_oid.as_ref())?;
@@ -292,6 +317,17 @@ fn tree_to_treeish<'a>(
292317
Ok(Some(tree))
293318
}
294319

320+
fn resolve_blob<'a>(
321+
repo: &'a Repository,
322+
arg: Option<&String>,
323+
) -> Result<Option<Blob<'a>>, Error> {
324+
let arg = match arg {
325+
Some(s) => Oid::from_str(s)?,
326+
None => return Ok(None),
327+
};
328+
repo.find_blob(arg).map(|b| Some(b))
329+
}
330+
295331
impl Args {
296332
fn cache(&self) -> Cache {
297333
if self.flag_cached {

0 commit comments

Comments
 (0)