Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@ Or only for the current repository:
$ git config changed.defaultBranch development
#+end_src

The value can be any revision. If your local ~main~ is older than the remote one, the tool also lists the files that changed on ~main~ after your local copy. To compare with the remote branch, set:

#+begin_src bash
$ git config changed.defaultBranch origin/main
#+end_src

*** Filtering files with glob pattern

#+begin_src bash
Expand Down
18 changes: 8 additions & 10 deletions src/git.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use git2::Commit;
use git2::DiffDelta;
use git2::ErrorCode;
use git2::Oid;
Expand Down Expand Up @@ -70,15 +71,15 @@ fn default_branch(repo: &Repository) -> Result<String> {
}

fn committed_changes(repo: &Repository, base: &str) -> Result<Vec<String>> {
let base_oid = find_commit_oid(repo, base)?;
let head_oid = find_commit_oid(repo, "HEAD")?;
let base_commit = find_commit(repo, base)?;
let head_commit = find_commit(repo, "HEAD")?;

let merge_base_oid = repo
.merge_base(base_oid, head_oid)
.merge_base(base_commit.id(), head_commit.id())
.with_context(|| format!("Cannot find a merge base of {base} and HEAD"))?;

let old_tree = find_tree(repo, merge_base_oid)?;
let new_tree = find_tree(repo, head_oid)?;
let new_tree = head_commit.tree().context("Cannot find the tree of HEAD")?;

let diff = repo
.diff_tree_to_tree(Some(&old_tree), Some(&new_tree), None)
Expand All @@ -87,13 +88,10 @@ fn committed_changes(repo: &Repository, base: &str) -> Result<Vec<String>> {
diff.deltas().map(changed_path).collect()
}

fn find_commit_oid(repo: &Repository, revision: &str) -> Result<Oid> {
let commit = repo
.revparse_single(revision)
fn find_commit<'repo>(repo: &'repo Repository, revision: &str) -> Result<Commit<'repo>> {
repo.revparse_single(revision)
.and_then(|object| object.peel_to_commit())
.with_context(|| format!("Cannot find the commit of {revision}"))?;

Ok(commit.id())
.with_context(|| format!("Cannot find the commit of {revision}"))
}

fn find_tree(repo: &Repository, oid: Oid) -> Result<Tree<'_>> {
Expand Down
9 changes: 8 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use self::cli::Options;
use anyhow::Context;
use anyhow::Result;
use glob::MatchOptions;
use std::env;
use std::io;
use std::io::Write;
Expand All @@ -12,6 +13,12 @@ use std::process;
mod cli;
mod git;

const SHELL_MATCH_OPTIONS: MatchOptions = MatchOptions {
case_sensitive: true,
require_literal_separator: true,
require_literal_leading_dot: false,
};

fn main() {
let options = cli::get_options();

Expand Down Expand Up @@ -62,7 +69,7 @@ fn relative_path(file: &Path, directory: &Path) -> PathBuf {
}

fn is_selected(file: &Path, options: &Options) -> bool {
if !options.glob.matches_path(file) {
if !options.glob.matches_path_with(file, SHELL_MATCH_OPTIONS) {
return false;
}

Expand Down
6 changes: 6 additions & 0 deletions tests/features/subdirectory.feature
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ Feature: Run the tool in a subdirectory
main.rs
"""

Scenario: It does not match a file in another directory with a star
When the user executes the tool in "src" like: "git-changed *.md"
Then it succeeds with the following output
"""
"""

Scenario: It finds the existing files from the subdirectory
When the user executes the tool in "src" like: "git-changed -e ../*.md"
Then it succeeds with the following output
Expand Down
Loading