Commit 1439b9ff by Edward Thomson

filter: introduce GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT

Provide a mechanism to filter using attribute data from a specific
commit (making use of `GIT_ATTR_CHECK_INCLUDE_COMMIT`).
parent 0bd547a8
......@@ -114,6 +114,12 @@ typedef enum {
* in the HEAD commit.
*/
GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD = (1 << 2),
/**
* When set, filters will be loaded from a `.gitattributes` file
* in the specified commit.
*/
GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT = (1 << 3),
} git_blob_filter_flag_t;
/**
......@@ -128,6 +134,12 @@ typedef struct {
/** Flags to control the filtering process, see `git_blob_filter_flag_t` above */
uint32_t flags;
/**
* The commit to load attributes from, when
* `GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT` is specified.
*/
git_oid *commit_id;
} git_blob_filter_options;
#define GIT_BLOB_FILTER_OPTIONS_VERSION 1
......
......@@ -49,6 +49,12 @@ typedef enum {
/** Load attributes from `.gitattributes` in the root of HEAD */
GIT_FILTER_ATTRIBUTES_FROM_HEAD = (1u << 2),
/**
* Load attributes from `.gitattributes` in a given commit.
* This can only be specified in a `git_filter_options`.
*/
GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3),
} git_filter_flag_t;
/**
......@@ -59,6 +65,12 @@ typedef struct {
/** See `git_filter_flag_t` above */
uint32_t flags;
/**
* The commit to load attributes from, when
* `GIT_FILTER_ATTRIBUTES_FROM_COMMIT` is specified.
*/
git_oid *commit_id;
} git_filter_options;
#define GIT_FILTER_OPTIONS_VERSION 1
......
......@@ -421,7 +421,7 @@ int git_blob_filter(
int error = 0;
git_filter_list *fl = NULL;
git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
git_filter_flag_t flags = GIT_FILTER_DEFAULT;
git_filter_options filter_opts = GIT_FILTER_OPTIONS_INIT;
GIT_ASSERT_ARG(blob);
GIT_ASSERT_ARG(path);
......@@ -441,14 +441,19 @@ int git_blob_filter(
return 0;
if ((opts.flags & GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES) != 0)
flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES;
filter_opts.flags |= GIT_FILTER_NO_SYSTEM_ATTRIBUTES;
if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD) != 0)
flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD;
filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_HEAD;
if (!(error = git_filter_list_load(
if ((opts.flags & GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) {
filter_opts.flags |= GIT_FILTER_ATTRIBUTES_FROM_COMMIT;
filter_opts.commit_id = opts.commit_id;
}
if (!(error = git_filter_list_load_ext(
&fl, git_blob_owner(blob), blob, path,
GIT_FILTER_TO_WORKTREE, flags))) {
GIT_FILTER_TO_WORKTREE, &filter_opts))) {
error = git_filter_list_apply_to_blob(out, fl, blob);
......
......@@ -443,6 +443,11 @@ static int filter_list_check_attributes(
if ((src->options.flags & GIT_FILTER_ATTRIBUTES_FROM_HEAD) != 0)
attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_HEAD;
if ((src->options.flags & GIT_FILTER_ATTRIBUTES_FROM_COMMIT) != 0) {
attr_opts.flags |= GIT_ATTR_CHECK_INCLUDE_COMMIT;
attr_opts.commit_id = src->options.commit_id;
}
error = git_attr_get_many_with_session(
strs, repo, filter_session->attr_session, &attr_opts, src->path, fdef->nattrs, fdef->attrs);
......
......@@ -132,3 +132,63 @@ void test_filter_bare__sanitizes(void)
git_blob_free(blob);
}
void test_filter_bare__from_specific_commit_one(void)
{
git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
git_blob *blob;
git_buf buf = { 0 };
git_oid commit_id;
cl_git_pass(git_oid_fromstr(&commit_id, "b8986fec0f7bde90f78ac72706e782d82f24f2f0"));
opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES;
opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT;
opts.commit_id = &commit_id;
cl_git_pass(git_revparse_single(
(git_object **)&blob, g_repo, "055c872")); /* ident */
cl_assert_equal_s("$Id$\n", git_blob_rawcontent(blob));
cl_git_pass(git_blob_filter(&buf, blob, "ident.bin", &opts));
cl_assert_equal_s("$Id$\n", buf.ptr);
cl_git_pass(git_blob_filter(&buf, blob, "ident.identlf", &opts));
cl_assert_equal_s("$Id: 055c8729cdcc372500a08db659c045e16c4409fb $\n", buf.ptr);
git_buf_dispose(&buf);
git_blob_free(blob);
}
void test_filter_bare__from_specific_commit_with_no_attributes_file(void)
{
git_blob_filter_options opts = GIT_BLOB_FILTER_OPTIONS_INIT;
git_blob *blob;
git_buf buf = { 0 };
git_oid commit_id;
cl_git_pass(git_oid_fromstr(&commit_id, "5afb6a14a864e30787857dd92af837e8cdd2cb1b"));
opts.flags |= GIT_BLOB_FILTER_NO_SYSTEM_ATTRIBUTES;
opts.flags |= GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT;
opts.commit_id = &commit_id;
cl_git_pass(git_revparse_single(
(git_object **)&blob, g_repo, "799770d")); /* all-lf */
cl_assert_equal_s(ALL_LF_TEXT_RAW, git_blob_rawcontent(blob));
cl_git_pass(git_blob_filter(&buf, blob, "file.bin", &opts));
cl_assert_equal_s(ALL_LF_TEXT_RAW, buf.ptr);
/* we never convert CRLF -> LF on platforms that have LF */
cl_git_pass(git_blob_filter(&buf, blob, "file.lf", &opts));
cl_assert_equal_s(ALL_LF_TEXT_RAW, buf.ptr);
/* we never convert CRLF -> LF on platforms that have LF */
cl_git_pass(git_blob_filter(&buf, blob, "file.crlf", &opts));
cl_assert_equal_s(ALL_LF_TEXT_RAW, buf.ptr);
git_buf_dispose(&buf);
git_blob_free(blob);
}
b8986fec0f7bde90f78ac72706e782d82f24f2f0
1ec507638b806aba45d6142082885f2a9e88322d
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment