1

I'm using the git2 crate which wraps libgit2.

I'm adding files to the index whether or not they are changed to stage them for committing.

If there are no files changed in the repo, when I commit, I get an empty commit, that I'd like to avoid. I thought calling index.is_empty() would indicate no changes, but I have a count returned from index.len().

I'd be fine resetting the index or avoid adding files to the index if they are unchanged.

How can I avoid inserting an empty commit? I know the git CLI has support for this, and can disable it with --allow-empty.

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445

1 Answers1

1

I can iterate through the index entries and look for ones that have not changed by calling status_file against the Repository

let repo: Repository = ...;
let index: Index = ...;
let changed_files = index
    .iter()
    .flat_map(|e| String::from_utf8(e.path))
    .map(|e| PathBuf::from(OsString::from(e)))
    .flat_map(|p| repo.status_file(&p))
    .any(|s| s != Status::CURRENT);
Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
  • Does `status_file` really perform a status? (Meaning diffing both the working directory with the index _and_ the index with `HEAD`.) If so, you'll get false positives for unstaged changes in the working directory. In addition, it's inefficient since you're calling status for each file. I would recommend instead doing a diff of the index with `HEAD`; if the diff is empty then there are no changes to commit. – Edward Thomson Apr 25 '22 at 13:24
  • @EdwardThomson an example of that would be amazing – Daniel A. White Apr 25 '22 at 13:32
  • I'm afraid that I'm not super familiar with the git2 rust bindings. But you'll want to get the repository's [head](https://cmsd2.github.io/rust-docs/codelauf/git2/struct.Repository.html#method.head), [peel](https://cmsd2.github.io/rust-docs/codelauf/git2/struct.Reference.html#method.peel) that to a commit, get the commit's [tree](https://cmsd2.github.io/rust-docs/codelauf/git2/struct.Commit.html#method.tree), and then call [Diff::tree_to_index](https://cmsd2.github.io/rust-docs/codelauf/git2/struct.Diff.html#method.tree_to_index), passing the repository's head's tree as the old tree. – Edward Thomson Apr 25 '22 at 14:45