diff --git a/src/egit-pathspec.c b/src/egit-pathspec.c index 798146b1..864ddeef 100644 --- a/src/egit-pathspec.c +++ b/src/egit-pathspec.c @@ -263,3 +263,42 @@ emacs_value egit_pathspec_match_tree(emacs_env *env, return egit_wrap(env, EGIT_PATHSPEC_MATCH_LIST, match_list, NULL); } + +EGIT_DOC(pathspec_match_diff, "DIFF FLAGS PATHSPEC", + "Match a PATHSPEC against a DIFF.\n" + "\n" + "FLAGS should be nil or a list with the following symbols:\n" + " - ignore-case: forces match to ignore case\n" + " - use-case: forces case sensitive match\n" + " - no-glob: disables glob patterns and just uses simple string " + "comparison for matching\n" + " - no-match-error: signal an error if no matches are found; " + "otherwise no matches is still success, but " + "`libgit-pathspec-match-list-entrycount' will indicate 0 matches.\n" + " - find-failures: means that the `libgit-pathspec-match-list' object " + "should track which patterns matched which files so that at the end of " + "the match we can identify patterns that did not match any files.\n" + " - failures-only: means that the `libgit-pathspec-match-list' object " + "does not need to keep the actual matching filenames. Use this to " + "just test if there were any matches at all or in combination with " + "`find-failures' to validate a pathspec."); +emacs_value egit_pathspec_match_diff(emacs_env *env, + emacs_value _diff, + emacs_value _flags, + emacs_value _pathspec) +{ + EGIT_ASSERT_DIFF(_diff); + EGIT_ASSERT_PATHSPEC(_pathspec); + + git_diff *diff = EGIT_EXTRACT(_diff); + git_pathspec *pathspec = EGIT_EXTRACT(_pathspec); + int32_t flags = 0; + extract_flags(&flags, env, _flags); + + git_pathspec_match_list *match_list; + int retval = git_pathspec_match_diff(&match_list, diff, flags, + pathspec); + EGIT_CHECK_ERROR(retval); + + return egit_wrap(env, EGIT_PATHSPEC_MATCH_LIST, match_list, NULL); +} diff --git a/src/egit-pathspec.h b/src/egit-pathspec.h index b46e4a86..b4dab621 100644 --- a/src/egit-pathspec.h +++ b/src/egit-pathspec.h @@ -43,4 +43,9 @@ EGIT_DEFUN(pathspec_match_tree, emacs_value _flags, emacs_value _pathspec); +EGIT_DEFUN(pathspec_match_diff, + emacs_value _diff, + emacs_value _flags, + emacs_value _pathspec); + #endif /* EGIT_REFSPEC_H */ diff --git a/src/egit.c b/src/egit.c index fa4b5552..1a454628 100644 --- a/src/egit.c +++ b/src/egit.c @@ -625,6 +625,7 @@ void egit_init(emacs_env *env) DEFUN("libgit-pathspec-match-workdir", pathspec_match_workdir, 3, 3); DEFUN("libgit-pathspec-match-index", pathspec_match_index, 3, 3); DEFUN("libgit-pathspec-match-tree", pathspec_match_tree, 3, 3); + DEFUN("libgit-pathspec-match-diff", pathspec_match_diff, 3, 3); // Reference DEFUN("libgit-reference-create", reference_create, 3, 5); diff --git a/test/pathspec-test.el b/test/pathspec-test.el index 28f2a676..8c84d575 100644 --- a/test/pathspec-test.el +++ b/test/pathspec-test.el @@ -141,3 +141,32 @@ (should (string= "file-a" (libgit-pathspec-match-list-failed-entry match-list-child 0)))))) + +(ert-deftest pathspec-match-diff () + (with-temp-dir path + (init) + (commit-change "file-a" "content-a") + (commit-change "file-b" "content-b") + (commit-change "file-b" "content-b-changed") + + (let* ((repo (libgit-repository-open path)) + (new-tree (libgit-revparse-single repo "HEAD^{tree}")) + (old-tree (libgit-revparse-single repo "HEAD~1^{tree}")) + (diff (libgit-diff-tree-to-tree repo old-tree new-tree)) + (pathspec (libgit-pathspec-new '("file-a" "file-b"))) + (match-list (libgit-pathspec-match-diff diff '(find-failures) + pathspec))) + (should match-list) + + ;; Find matched files + (should (= 1 (libgit-pathspec-match-list-entrycount match-list))) + (should (not (libgit-pathspec-match-list-entry match-list 0))) + (let ((diff-delta (libgit-pathspec-match-list-diff-entry match-list 0))) + (should (string= "file-b" (libgit-diff-delta-file-path diff-delta nil))) + (should (string= "file-b" (libgit-diff-delta-file-path diff-delta t)))) + + ;; Find all pathspecs that have no matches + (should (= 1 (libgit-pathspec-match-list-failed-entrycount match-list))) + (should (string= "file-a" + (libgit-pathspec-match-list-failed-entry + match-list 0))))))