Skip to content

Commit 003a1df

Browse files
authored
Merge pull request libgit2#5952 from libgit2/ethomson/attrs_from_commit
Support reading attributes from a specific commit
2 parents f313b38 + 1439b9f commit 003a1df

24 files changed

+588
-193
lines changed

include/git2/attr.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,9 +130,32 @@ GIT_EXTERN(git_attr_value_t) git_attr_value(const char *attr);
130130
*
131131
* Passing the `GIT_ATTR_CHECK_INCLUDE_HEAD` flag will use attributes
132132
* from a `.gitattributes` file in the repository at the HEAD revision.
133+
*
134+
* Passing the `GIT_ATTR_CHECK_INCLUDE_COMMIT` flag will use attributes
135+
* from a `.gitattributes` file in a specific commit.
133136
*/
134137
#define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2)
135138
#define GIT_ATTR_CHECK_INCLUDE_HEAD (1 << 3)
139+
#define GIT_ATTR_CHECK_INCLUDE_COMMIT (1 << 4)
140+
141+
/**
142+
* An options structure for querying attributes.
143+
*/
144+
typedef struct {
145+
unsigned int version;
146+
147+
/** A combination of GIT_ATTR_CHECK flags */
148+
unsigned int flags;
149+
150+
/**
151+
* The commit to load attributes from, when
152+
* `GIT_ATTR_CHECK_INCLUDE_COMMIT` is specified.
153+
*/
154+
git_oid *commit_id;
155+
} git_attr_options;
156+
157+
#define GIT_ATTR_OPTIONS_VERSION 1
158+
#define GIT_ATTR_OPTIONS_INIT {GIT_ATTR_OPTIONS_VERSION}
136159

137160
/**
138161
* Look up the value of one git attribute for path.
@@ -156,6 +179,28 @@ GIT_EXTERN(int) git_attr_get(
156179
const char *path,
157180
const char *name);
158181

182+
/**
183+
* Look up the value of one git attribute for path with extended options.
184+
*
185+
* @param value_out Output of the value of the attribute. Use the GIT_ATTR_...
186+
* macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just
187+
* use the string value for attributes set to a value. You
188+
* should NOT modify or free this value.
189+
* @param repo The repository containing the path.
190+
* @param opts The `git_attr_options` to use when querying these attributes.
191+
* @param path The path to check for attributes. Relative paths are
192+
* interpreted relative to the repo root. The file does
193+
* not have to exist, but if it does not, then it will be
194+
* treated as a plain file (not a directory).
195+
* @param name The name of the attribute to look up.
196+
*/
197+
GIT_EXTERN(int) git_attr_get_ext(
198+
const char **value_out,
199+
git_repository *repo,
200+
git_attr_options *opts,
201+
const char *path,
202+
const char *name);
203+
159204
/**
160205
* Look up a list of git attributes for path.
161206
*
@@ -193,6 +238,30 @@ GIT_EXTERN(int) git_attr_get_many(
193238
size_t num_attr,
194239
const char **names);
195240

241+
/**
242+
* Look up a list of git attributes for path with extended options.
243+
*
244+
* @param values_out An array of num_attr entries that will have string
245+
* pointers written into it for the values of the attributes.
246+
* You should not modify or free the values that are written
247+
* into this array (although of course, you should free the
248+
* array itself if you allocated it).
249+
* @param repo The repository containing the path.
250+
* @param opts The `git_attr_options` to use when querying these attributes.
251+
* @param path The path inside the repo to check attributes. This
252+
* does not have to exist, but if it does not, then
253+
* it will be treated as a plain file (i.e. not a directory).
254+
* @param num_attr The number of attributes being looked up
255+
* @param names An array of num_attr strings containing attribute names.
256+
*/
257+
GIT_EXTERN(int) git_attr_get_many_ext(
258+
const char **values_out,
259+
git_repository *repo,
260+
git_attr_options *opts,
261+
const char *path,
262+
size_t num_attr,
263+
const char **names);
264+
196265
/**
197266
* The callback used with git_attr_foreach.
198267
*
@@ -231,6 +300,26 @@ GIT_EXTERN(int) git_attr_foreach(
231300
git_attr_foreach_cb callback,
232301
void *payload);
233302

303+
/**
304+
* Loop over all the git attributes for a path with extended options.
305+
*
306+
* @param repo The repository containing the path.
307+
* @param opts The `git_attr_options` to use when querying these attributes.
308+
* @param path Path inside the repo to check attributes. This does not have
309+
* to exist, but if it does not, then it will be treated as a
310+
* plain file (i.e. not a directory).
311+
* @param callback Function to invoke on each attribute name and value.
312+
* See git_attr_foreach_cb.
313+
* @param payload Passed on as extra parameter to callback function.
314+
* @return 0 on success, non-zero callback return value, or error code
315+
*/
316+
GIT_EXTERN(int) git_attr_foreach_ext(
317+
git_repository *repo,
318+
git_attr_options *opts,
319+
const char *path,
320+
git_attr_foreach_cb callback,
321+
void *payload);
322+
234323
/**
235324
* Flush the gitattributes cache.
236325
*

include/git2/blob.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ typedef enum {
114114
* in the HEAD commit.
115115
*/
116116
GIT_BLOB_FILTER_ATTRIBUTES_FROM_HEAD = (1 << 2),
117+
118+
/**
119+
* When set, filters will be loaded from a `.gitattributes` file
120+
* in the specified commit.
121+
*/
122+
GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT = (1 << 3),
117123
} git_blob_filter_flag_t;
118124

119125
/**
@@ -128,6 +134,12 @@ typedef struct {
128134

129135
/** Flags to control the filtering process, see `git_blob_filter_flag_t` above */
130136
uint32_t flags;
137+
138+
/**
139+
* The commit to load attributes from, when
140+
* `GIT_BLOB_FILTER_ATTRIBUTES_FROM_COMMIT` is specified.
141+
*/
142+
git_oid *commit_id;
131143
} git_blob_filter_options;
132144

133145
#define GIT_BLOB_FILTER_OPTIONS_VERSION 1

include/git2/filter.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,33 @@ typedef enum {
4949

5050
/** Load attributes from `.gitattributes` in the root of HEAD */
5151
GIT_FILTER_ATTRIBUTES_FROM_HEAD = (1u << 2),
52+
53+
/**
54+
* Load attributes from `.gitattributes` in a given commit.
55+
* This can only be specified in a `git_filter_options`.
56+
*/
57+
GIT_FILTER_ATTRIBUTES_FROM_COMMIT = (1u << 3),
5258
} git_filter_flag_t;
5359

60+
/**
61+
* Filtering options
62+
*/
63+
typedef struct {
64+
unsigned int version;
65+
66+
/** See `git_filter_flag_t` above */
67+
uint32_t flags;
68+
69+
/**
70+
* The commit to load attributes from, when
71+
* `GIT_FILTER_ATTRIBUTES_FROM_COMMIT` is specified.
72+
*/
73+
git_oid *commit_id;
74+
} git_filter_options;
75+
76+
#define GIT_FILTER_OPTIONS_VERSION 1
77+
#define GIT_FILTER_OPTIONS_INIT {GIT_FILTER_OPTIONS_VERSION}
78+
5479
/**
5580
* A filter that can transform file data
5681
*
@@ -103,6 +128,29 @@ GIT_EXTERN(int) git_filter_list_load(
103128
git_filter_mode_t mode,
104129
uint32_t flags);
105130

131+
/**
132+
* Load the filter list for a given path.
133+
*
134+
* This will return 0 (success) but set the output git_filter_list to NULL
135+
* if no filters are requested for the given file.
136+
*
137+
* @param filters Output newly created git_filter_list (or NULL)
138+
* @param repo Repository object that contains `path`
139+
* @param blob The blob to which the filter will be applied (if known)
140+
* @param path Relative path of the file to be filtered
141+
* @param mode Filtering direction (WT->ODB or ODB->WT)
142+
* @param opts The `git_filter_options` to use when loading filters
143+
* @return 0 on success (which could still return NULL if no filters are
144+
* needed for the requested file), <0 on error
145+
*/
146+
GIT_EXTERN(int) git_filter_list_load_ext(
147+
git_filter_list **filters,
148+
git_repository *repo,
149+
git_blob *blob,
150+
const char *path,
151+
git_filter_mode_t mode,
152+
git_filter_options *opts);
153+
106154
/**
107155
* Query the filter list to see if a given filter (by name) will run.
108156
* The built-in filters "crlf" and "ident" can be queried, otherwise this

0 commit comments

Comments
 (0)