]> git.proxmox.com Git - libgit2.git/commitdiff
Add index API to remove all files in a directory
authorRussell Belfer <rb@github.com>
Thu, 3 Jan 2013 23:48:52 +0000 (15:48 -0800)
committerRussell Belfer <rb@github.com>
Fri, 4 Jan 2013 23:47:44 +0000 (15:47 -0800)
This adds the git_index_remove_directory API plus tests.

include/git2/index.h
src/index.c
tests-clar/index/tests.c

index fa9a1978587ecc122045637ca6f5c61ae6aa2a20..1d21403adc5933172454e9a03f27a93c02ef5ab3 100644 (file)
@@ -312,6 +312,17 @@ GIT_EXTERN(const git_index_entry *) git_index_get_bypath(
  */
 GIT_EXTERN(int) git_index_remove(git_index *index, const char *path, int stage);
 
+/**
+ * Remove all entries from the index under a given directory
+ *
+ * @param index an existing index object
+ * @param dir container directory path
+ * @param stage stage to search
+ * @return 0 or an error code
+ */
+GIT_EXTERN(int) git_index_remove_directory(
+       git_index *index, const char *dir, int stage);
+
 /**
  * Add or update an index entry from an in-memory struct
  *
index 9f2012b3a2411e3a1a2d3b559d7efbd8882c233e..ce902c5efa5b96adf5c9ec5f8457ccd74638546d 100644 (file)
@@ -794,6 +794,44 @@ int git_index_remove(git_index *index, const char *path, int stage)
        return error;
 }
 
+int git_index_remove_directory(git_index *index, const char *dir, int stage)
+{
+       git_buf pfx = GIT_BUF_INIT;
+       int error = 0;
+       size_t pos;
+       git_index_entry *entry;
+
+       if (git_buf_sets(&pfx, dir) < 0 || git_path_to_dir(&pfx) < 0)
+               return -1;
+
+       git_vector_sort(&index->entries);
+
+       pos = git_index__prefix_position(index, pfx.ptr);
+
+       while (1) {
+               entry = git_vector_get(&index->entries, pos);
+               if (!entry || git__prefixcmp(entry->path, pfx.ptr) != 0)
+                       break;
+
+               if (index_entry_stage(entry) != stage) {
+                       ++pos;
+                       continue;
+               }
+
+               git_tree_cache_invalidate_path(index->tree, entry->path);
+
+               if ((error = git_vector_remove(&index->entries, pos)) < 0)
+                       break;
+               index_entry_free(entry);
+
+               /* removed entry at 'pos' so we don't need to increment it */
+       }
+
+       git_buf_free(&pfx);
+
+       return error;
+}
+
 static int index_find(git_index *index, const char *path, int stage)
 {
        struct entry_srch_key srch_key;
index 989734c1b1fc3a679e0aecb11436da2084b11441..5c3d4cf41f2e9f00baddcf83c7bca7715bd8cbad 100644 (file)
@@ -290,3 +290,86 @@ void test_index_tests__write_invalid_filename(void)
 
        cl_fixture_cleanup("read_tree");
 }
+
+void test_index_tests__remove_entry(void)
+{
+       git_repository *repo;
+       git_index *index;
+
+       p_mkdir("index_test", 0770);
+
+       cl_git_pass(git_repository_init(&repo, "index_test", 0));
+       cl_git_pass(git_repository_index(&index, repo));
+       cl_assert(git_index_entrycount(index) == 0);
+
+       cl_git_mkfile("index_test/hello", NULL);
+       cl_git_pass(git_index_add_from_workdir(index, "hello"));
+       cl_git_pass(git_index_write(index));
+
+       cl_git_pass(git_index_read(index)); /* reload */
+       cl_assert(git_index_entrycount(index) == 1);
+       cl_assert(git_index_get_bypath(index, "hello", 0) != NULL);
+
+       cl_git_pass(git_index_remove(index, "hello", 0));
+       cl_git_pass(git_index_write(index));
+
+       cl_git_pass(git_index_read(index)); /* reload */
+       cl_assert(git_index_entrycount(index) == 0);
+       cl_assert(git_index_get_bypath(index, "hello", 0) == NULL);
+
+       git_index_free(index);
+       git_repository_free(repo);
+       cl_fixture_cleanup("index_test");
+}
+
+void test_index_tests__remove_directory(void)
+{
+       git_repository *repo;
+       git_index *index;
+
+       p_mkdir("index_test", 0770);
+
+       cl_git_pass(git_repository_init(&repo, "index_test", 0));
+       cl_git_pass(git_repository_index(&index, repo));
+       cl_assert_equal_i(0, (int)git_index_entrycount(index));
+
+       p_mkdir("index_test/a", 0770);
+       cl_git_mkfile("index_test/a/1.txt", NULL);
+       cl_git_mkfile("index_test/a/2.txt", NULL);
+       cl_git_mkfile("index_test/a/3.txt", NULL);
+       cl_git_mkfile("index_test/b.txt", NULL);
+
+       cl_git_pass(git_index_add_from_workdir(index, "a/1.txt"));
+       cl_git_pass(git_index_add_from_workdir(index, "a/2.txt"));
+       cl_git_pass(git_index_add_from_workdir(index, "a/3.txt"));
+       cl_git_pass(git_index_add_from_workdir(index, "b.txt"));
+       cl_git_pass(git_index_write(index));
+
+       cl_git_pass(git_index_read(index)); /* reload */
+       cl_assert_equal_i(4, (int)git_index_entrycount(index));
+       cl_assert(git_index_get_bypath(index, "a/1.txt", 0) != NULL);
+       cl_assert(git_index_get_bypath(index, "a/2.txt", 0) != NULL);
+       cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
+
+       cl_git_pass(git_index_remove(index, "a/1.txt", 0));
+       cl_git_pass(git_index_write(index));
+
+       cl_git_pass(git_index_read(index)); /* reload */
+       cl_assert_equal_i(3, (int)git_index_entrycount(index));
+       cl_assert(git_index_get_bypath(index, "a/1.txt", 0) == NULL);
+       cl_assert(git_index_get_bypath(index, "a/2.txt", 0) != NULL);
+       cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
+
+       cl_git_pass(git_index_remove_directory(index, "a", 0));
+       cl_git_pass(git_index_write(index));
+
+       cl_git_pass(git_index_read(index)); /* reload */
+       cl_assert_equal_i(1, (int)git_index_entrycount(index));
+       cl_assert(git_index_get_bypath(index, "a/1.txt", 0) == NULL);
+       cl_assert(git_index_get_bypath(index, "a/2.txt", 0) == NULL);
+       cl_assert(git_index_get_bypath(index, "b.txt", 0) != NULL);
+
+       git_index_free(index);
+       git_repository_free(repo);
+       cl_fixture_cleanup("index_test");
+}