Skip to main content

DiffOptions

Struct DiffOptions 

Source
pub struct DiffOptions { /* private fields */ }
Expand description

Structure describing options about how the diff should be executed.

Implementations§

Source§

impl DiffOptions

Source

pub fn new() -> DiffOptions

Creates a new set of empty diff options.

All flags and other options are defaulted to false or their otherwise zero equivalents.

Examples found in repository?
examples/git-log.rs (line 120)
78fn run(args: &Args) -> Result<(), Error> {
79    let path = args.flag_git_dir.as_ref().map(|s| &s[..]).unwrap_or(".");
80    let repo = Repository::open(path)?;
81    let mut revwalk = repo.revwalk()?;
82
83    // Prepare the revwalk based on CLI parameters
84    let base = if args.flag_reverse { git2::Sort::REVERSE } else { git2::Sort::NONE };
85    revwalk.set_sorting(
86        base | if args.flag_topo_order {
87            git2::Sort::TOPOLOGICAL
88        } else if args.flag_date_order {
89            git2::Sort::TIME
90        } else {
91            git2::Sort::NONE
92        },
93    )?;
94    for commit in &args.arg_commit {
95        if commit.starts_with('^') {
96            let obj = repo.revparse_single(&commit[1..])?;
97            revwalk.hide(obj.id())?;
98            continue;
99        }
100        let revspec = repo.revparse(commit)?;
101        if revspec.mode().contains(git2::RevparseMode::SINGLE) {
102            revwalk.push(revspec.from().unwrap().id())?;
103        } else {
104            let from = revspec.from().unwrap().id();
105            let to = revspec.to().unwrap().id();
106            revwalk.push(to)?;
107            if revspec.mode().contains(git2::RevparseMode::MERGE_BASE) {
108                let base = repo.merge_base(from, to)?;
109                let o = repo.find_object(base, Some(ObjectType::Commit))?;
110                revwalk.push(o.id())?;
111            }
112            revwalk.hide(from)?;
113        }
114    }
115    if args.arg_commit.is_empty() {
116        revwalk.push_head()?;
117    }
118
119    // Prepare our diff options and pathspec matcher
120    let (mut diffopts, mut diffopts2) = (DiffOptions::new(), DiffOptions::new());
121    for spec in &args.arg_spec {
122        diffopts.pathspec(spec);
123        diffopts2.pathspec(spec);
124    }
125    let ps = Pathspec::new(args.arg_spec.iter())?;
126
127    // Filter our revwalk based on the CLI parameters
128    macro_rules! filter_try {
129        ($e:expr) => {
130            match $e {
131                Ok(t) => t,
132                Err(e) => return Some(Err(e)),
133            }
134        };
135    }
136    let revwalk = revwalk
137        .filter_map(|id| {
138            let id = filter_try!(id);
139            let commit = filter_try!(repo.find_commit(id));
140            let parents = commit.parents().len();
141            if parents < args.min_parents() {
142                return None;
143            }
144            if let Some(n) = args.max_parents() {
145                if parents >= n {
146                    return None;
147                }
148            }
149            if !args.arg_spec.is_empty() {
150                match commit.parents().len() {
151                    0 => {
152                        let tree = filter_try!(commit.tree());
153                        let flags = git2::PathspecFlags::NO_MATCH_ERROR;
154                        if ps.match_tree(&tree, flags).is_err() {
155                            return None;
156                        }
157                    }
158                    _ => {
159                        let m = commit
160                            .parents()
161                            .all(|parent| match_with_parent(&repo, &commit, &parent, &mut diffopts).unwrap_or(false));
162                        if !m {
163                            return None;
164                        }
165                    }
166                }
167            }
168            if !sig_matches(&commit.author(), &args.flag_author) {
169                return None;
170            }
171            if !sig_matches(&commit.committer(), &args.flag_committer) {
172                return None;
173            }
174            if !log_message_matches(commit.message(), &args.flag_grep) {
175                return None;
176            }
177            Some(Ok(commit))
178        })
179        .skip(args.flag_skip.unwrap_or(0))
180        .take(args.flag_max_count.unwrap_or(!0));
181
182    // print!
183    for commit in revwalk {
184        let commit = commit?;
185        print_commit(&commit);
186        if !args.flag_patch || commit.parents().len() > 1 {
187            continue;
188        }
189        let a = if commit.parents().len() == 1 {
190            let parent = commit.parent(0)?;
191            Some(parent.tree()?)
192        } else {
193            None
194        };
195        let b = commit.tree()?;
196        let diff = repo.diff_tree_to_tree(a.as_ref(), Some(&b), Some(&mut diffopts2))?;
197        diff.print(DiffFormat::Patch, |_delta, _hunk, line| {
198            match line.origin() {
199                ' ' | '+' | '-' => print!("{}", line.origin()),
200                _ => {}
201            }
202            print!("{}", str::from_utf8(line.content()).unwrap());
203            true
204        })?;
205    }
206
207    Ok(())
208}
Source

pub fn reverse(&mut self, reverse: bool) -> &mut DiffOptions

Flag indicating whether the sides of the diff will be reversed.

Source

pub fn include_ignored(&mut self, include: bool) -> &mut DiffOptions

Flag indicating whether ignored files are included.

Source

pub fn recurse_ignored_dirs(&mut self, recurse: bool) -> &mut DiffOptions

Flag indicating whether ignored directories are traversed deeply or not.

Source

pub fn include_untracked(&mut self, include: bool) -> &mut DiffOptions

Flag indicating whether untracked files are in the diff

Source

pub fn recurse_untracked_dirs(&mut self, recurse: bool) -> &mut DiffOptions

Flag indicating whether untracked directories are traversed deeply or not.

Source

pub fn include_unmodified(&mut self, include: bool) -> &mut DiffOptions

Flag indicating whether unmodified files are in the diff.

Source

pub fn include_typechange(&mut self, include: bool) -> &mut DiffOptions

If enabled, then Typechange delta records are generated.

Source

pub fn include_typechange_trees(&mut self, include: bool) -> &mut DiffOptions

Event with include_typechange, the tree returned generally shows a deleted blob. This flag correctly labels the tree transitions as a typechange record with the new_file’s mode set to tree.

Note that the tree SHA will not be available.

Source

pub fn ignore_filemode(&mut self, ignore: bool) -> &mut DiffOptions

Flag indicating whether file mode changes are ignored.

Source

pub fn ignore_submodules(&mut self, ignore: bool) -> &mut DiffOptions

Flag indicating whether all submodules should be treated as unmodified.

Source

pub fn ignore_case(&mut self, ignore: bool) -> &mut DiffOptions

Flag indicating whether case insensitive filenames should be used.

Source

pub fn disable_pathspec_match(&mut self, disable: bool) -> &mut DiffOptions

If pathspecs are specified, this flag means that they should be applied as an exact match instead of a fnmatch pattern.

Source

pub fn skip_binary_check(&mut self, skip: bool) -> &mut DiffOptions

Disable updating the binary flag in delta records. This is useful when iterating over a diff if you don’t need hunk and data callbacks and want to avoid having to load a file completely.

Source

pub fn enable_fast_untracked_dirs(&mut self, enable: bool) -> &mut DiffOptions

When diff finds an untracked directory, to match the behavior of core Git, it scans the contents for ignored and untracked files. If all contents are ignored, then the directory is ignored; if any contents are not ignored, then the directory is untracked. This is extra work that may not matter in many cases.

This flag turns off that scan and immediately labels an untracked directory as untracked (changing the behavior to not match core git).

Source

pub fn update_index(&mut self, update: bool) -> &mut DiffOptions

When diff finds a file in the working directory with stat information different from the index, but the OID ends up being the same, write the correct stat information into the index. Note: without this flag, diff will always leave the index untouched.

Source

pub fn include_unreadable(&mut self, include: bool) -> &mut DiffOptions

Include unreadable files in the diff

Source

pub fn include_unreadable_as_untracked( &mut self, include: bool, ) -> &mut DiffOptions

Include unreadable files in the diff as untracked files

Source

pub fn force_text(&mut self, force: bool) -> &mut DiffOptions

Treat all files as text, disabling binary attributes and detection.

Source

pub fn force_binary(&mut self, force: bool) -> &mut DiffOptions

Treat all files as binary, disabling text diffs

Source

pub fn ignore_whitespace(&mut self, ignore: bool) -> &mut DiffOptions

Ignore all whitespace

Source

pub fn ignore_whitespace_change(&mut self, ignore: bool) -> &mut DiffOptions

Ignore changes in the amount of whitespace

Source

pub fn ignore_whitespace_eol(&mut self, ignore: bool) -> &mut DiffOptions

Ignore whitespace at the end of line

Source

pub fn ignore_blank_lines(&mut self, ignore: bool) -> &mut DiffOptions

Ignore blank lines

Source

pub fn show_untracked_content(&mut self, show: bool) -> &mut DiffOptions

When generating patch text, include the content of untracked files.

This automatically turns on include_untracked but it does not turn on recurse_untracked_dirs. Add that flag if you want the content of every single untracked file.

Source

pub fn show_unmodified(&mut self, show: bool) -> &mut DiffOptions

When generating output, include the names of unmodified files if they are included in the Diff. Normally these are skipped in the formats that list files (e.g. name-only, name-status, raw). Even with this these will not be included in the patch format.

Source

pub fn patience(&mut self, patience: bool) -> &mut DiffOptions

Use the “patience diff” algorithm

Source

pub fn minimal(&mut self, minimal: bool) -> &mut DiffOptions

Take extra time to find the minimal diff

Source

pub fn show_binary(&mut self, show: bool) -> &mut DiffOptions

Include the necessary deflate/delta information so that git-apply can apply given diff information to binary files.

Source

pub fn indent_heuristic(&mut self, heuristic: bool) -> &mut DiffOptions

Use a heuristic that takes indentation and whitespace into account which generally can produce better diffs when dealing with ambiguous diff hunks.

Source

pub fn context_lines(&mut self, lines: u32) -> &mut DiffOptions

Set the number of unchanged lines that define the boundary of a hunk (and to display before and after).

The default value for this is 3.

Source

pub fn interhunk_lines(&mut self, lines: u32) -> &mut DiffOptions

Set the maximum number of unchanged lines between hunk boundaries before the hunks will be merged into one.

The default value for this is 0.

Source

pub fn id_abbrev(&mut self, abbrev: u16) -> &mut DiffOptions

The default value for this is core.abbrev or 7 if unset.

Source

pub fn max_size(&mut self, size: i64) -> &mut DiffOptions

Maximum size (in bytes) above which a blob will be marked as binary automatically.

A negative value will disable this entirely.

The default value for this is 512MB.

Source

pub fn old_prefix<T>(&mut self, t: T) -> &mut DiffOptions
where T: IntoCString,

The virtual “directory” to prefix old file names with in hunk headers.

The default value for this is “a”.

Source

pub fn new_prefix<T>(&mut self, t: T) -> &mut DiffOptions
where T: IntoCString,

The virtual “directory” to prefix new file names with in hunk headers.

The default value for this is “b”.

Source

pub fn pathspec<T>(&mut self, pathspec: T) -> &mut DiffOptions
where T: IntoCString,

Add to the array of paths/fnmatch patterns to constrain the diff.

Examples found in repository?
examples/git-log.rs (line 122)
78fn run(args: &Args) -> Result<(), Error> {
79    let path = args.flag_git_dir.as_ref().map(|s| &s[..]).unwrap_or(".");
80    let repo = Repository::open(path)?;
81    let mut revwalk = repo.revwalk()?;
82
83    // Prepare the revwalk based on CLI parameters
84    let base = if args.flag_reverse { git2::Sort::REVERSE } else { git2::Sort::NONE };
85    revwalk.set_sorting(
86        base | if args.flag_topo_order {
87            git2::Sort::TOPOLOGICAL
88        } else if args.flag_date_order {
89            git2::Sort::TIME
90        } else {
91            git2::Sort::NONE
92        },
93    )?;
94    for commit in &args.arg_commit {
95        if commit.starts_with('^') {
96            let obj = repo.revparse_single(&commit[1..])?;
97            revwalk.hide(obj.id())?;
98            continue;
99        }
100        let revspec = repo.revparse(commit)?;
101        if revspec.mode().contains(git2::RevparseMode::SINGLE) {
102            revwalk.push(revspec.from().unwrap().id())?;
103        } else {
104            let from = revspec.from().unwrap().id();
105            let to = revspec.to().unwrap().id();
106            revwalk.push(to)?;
107            if revspec.mode().contains(git2::RevparseMode::MERGE_BASE) {
108                let base = repo.merge_base(from, to)?;
109                let o = repo.find_object(base, Some(ObjectType::Commit))?;
110                revwalk.push(o.id())?;
111            }
112            revwalk.hide(from)?;
113        }
114    }
115    if args.arg_commit.is_empty() {
116        revwalk.push_head()?;
117    }
118
119    // Prepare our diff options and pathspec matcher
120    let (mut diffopts, mut diffopts2) = (DiffOptions::new(), DiffOptions::new());
121    for spec in &args.arg_spec {
122        diffopts.pathspec(spec);
123        diffopts2.pathspec(spec);
124    }
125    let ps = Pathspec::new(args.arg_spec.iter())?;
126
127    // Filter our revwalk based on the CLI parameters
128    macro_rules! filter_try {
129        ($e:expr) => {
130            match $e {
131                Ok(t) => t,
132                Err(e) => return Some(Err(e)),
133            }
134        };
135    }
136    let revwalk = revwalk
137        .filter_map(|id| {
138            let id = filter_try!(id);
139            let commit = filter_try!(repo.find_commit(id));
140            let parents = commit.parents().len();
141            if parents < args.min_parents() {
142                return None;
143            }
144            if let Some(n) = args.max_parents() {
145                if parents >= n {
146                    return None;
147                }
148            }
149            if !args.arg_spec.is_empty() {
150                match commit.parents().len() {
151                    0 => {
152                        let tree = filter_try!(commit.tree());
153                        let flags = git2::PathspecFlags::NO_MATCH_ERROR;
154                        if ps.match_tree(&tree, flags).is_err() {
155                            return None;
156                        }
157                    }
158                    _ => {
159                        let m = commit
160                            .parents()
161                            .all(|parent| match_with_parent(&repo, &commit, &parent, &mut diffopts).unwrap_or(false));
162                        if !m {
163                            return None;
164                        }
165                    }
166                }
167            }
168            if !sig_matches(&commit.author(), &args.flag_author) {
169                return None;
170            }
171            if !sig_matches(&commit.committer(), &args.flag_committer) {
172                return None;
173            }
174            if !log_message_matches(commit.message(), &args.flag_grep) {
175                return None;
176            }
177            Some(Ok(commit))
178        })
179        .skip(args.flag_skip.unwrap_or(0))
180        .take(args.flag_max_count.unwrap_or(!0));
181
182    // print!
183    for commit in revwalk {
184        let commit = commit?;
185        print_commit(&commit);
186        if !args.flag_patch || commit.parents().len() > 1 {
187            continue;
188        }
189        let a = if commit.parents().len() == 1 {
190            let parent = commit.parent(0)?;
191            Some(parent.tree()?)
192        } else {
193            None
194        };
195        let b = commit.tree()?;
196        let diff = repo.diff_tree_to_tree(a.as_ref(), Some(&b), Some(&mut diffopts2))?;
197        diff.print(DiffFormat::Patch, |_delta, _hunk, line| {
198            match line.origin() {
199                ' ' | '+' | '-' => print!("{}", line.origin()),
200                _ => {}
201            }
202            print!("{}", str::from_utf8(line.content()).unwrap());
203            true
204        })?;
205    }
206
207    Ok(())
208}
Source

pub unsafe fn raw(&mut self) -> *const git_diff_options

Acquire a pointer to the underlying raw options.

This function is unsafe as the pointer is only valid so long as this structure is not moved, modified, or used elsewhere.

Trait Implementations§

Source§

impl Default for DiffOptions

Source§

fn default() -> DiffOptions

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more