|  | 
|  | 1 | +/* | 
|  | 2 | + * Copyright (C) the libgit2 contributors. All rights reserved. | 
|  | 3 | + * | 
|  | 4 | + * This file is part of libgit2, distributed under the GNU GPL v2 with | 
|  | 5 | + * a Linking Exception. For full terms see the included COPYING file. | 
|  | 6 | + */ | 
|  | 7 | +#ifndef INCLUDE_git_attr_h__ | 
|  | 8 | +#define INCLUDE_git_attr_h__ | 
|  | 9 | + | 
|  | 10 | +#include "common.h" | 
|  | 11 | +#include "types.h" | 
|  | 12 | + | 
|  | 13 | +/** | 
|  | 14 | + * @file git2/attr.h | 
|  | 15 | + * @brief Git attribute management routines | 
|  | 16 | + * @defgroup git_attr Git attribute management routines | 
|  | 17 | + * @ingroup Git | 
|  | 18 | + * @{ | 
|  | 19 | + */ | 
|  | 20 | +GIT_BEGIN_DECL | 
|  | 21 | + | 
|  | 22 | +/** | 
|  | 23 | + * GIT_ATTR_TRUE checks if an attribute is set on.  In core git | 
|  | 24 | + * parlance, this the value for "Set" attributes. | 
|  | 25 | + * | 
|  | 26 | + * For example, if the attribute file contains: | 
|  | 27 | + * | 
|  | 28 | + *    *.c foo | 
|  | 29 | + * | 
|  | 30 | + * Then for file `xyz.c` looking up attribute "foo" gives a value for | 
|  | 31 | + * which `GIT_ATTR_TRUE(value)` is true. | 
|  | 32 | + */ | 
|  | 33 | +#define GIT_ATTR_TRUE(attr)	(git_attr_value(attr) == GIT_ATTR_TRUE_T) | 
|  | 34 | + | 
|  | 35 | +/** | 
|  | 36 | + * GIT_ATTR_FALSE checks if an attribute is set off.  In core git | 
|  | 37 | + * parlance, this is the value for attributes that are "Unset" (not to | 
|  | 38 | + * be confused with values that a "Unspecified"). | 
|  | 39 | + * | 
|  | 40 | + * For example, if the attribute file contains: | 
|  | 41 | + * | 
|  | 42 | + *    *.h -foo | 
|  | 43 | + * | 
|  | 44 | + * Then for file `zyx.h` looking up attribute "foo" gives a value for | 
|  | 45 | + * which `GIT_ATTR_FALSE(value)` is true. | 
|  | 46 | + */ | 
|  | 47 | +#define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T) | 
|  | 48 | + | 
|  | 49 | +/** | 
|  | 50 | + * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified.  This | 
|  | 51 | + * may be due to the attribute not being mentioned at all or because | 
|  | 52 | + * the attribute was explicitly set unspecified via the `!` operator. | 
|  | 53 | + * | 
|  | 54 | + * For example, if the attribute file contains: | 
|  | 55 | + * | 
|  | 56 | + *    *.c foo | 
|  | 57 | + *    *.h -foo | 
|  | 58 | + *    onefile.c !foo | 
|  | 59 | + * | 
|  | 60 | + * Then for `onefile.c` looking up attribute "foo" yields a value with | 
|  | 61 | + * `GIT_ATTR_UNSPECIFIED(value)` of true.  Also, looking up "foo" on | 
|  | 62 | + * file `onefile.rb` or looking up "bar" on any file will all give | 
|  | 63 | + * `GIT_ATTR_UNSPECIFIED(value)` of true. | 
|  | 64 | + */ | 
|  | 65 | +#define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T) | 
|  | 66 | + | 
|  | 67 | +/** | 
|  | 68 | + * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as | 
|  | 69 | + * opposed to TRUE, FALSE or UNSPECIFIED).  This would be the case if | 
|  | 70 | + * for a file with something like: | 
|  | 71 | + * | 
|  | 72 | + *    *.txt eol=lf | 
|  | 73 | + * | 
|  | 74 | + * Given this, looking up "eol" for `onefile.txt` will give back the | 
|  | 75 | + * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true. | 
|  | 76 | + */ | 
|  | 77 | +#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T) | 
|  | 78 | + | 
|  | 79 | +typedef enum { | 
|  | 80 | +	GIT_ATTR_UNSPECIFIED_T = 0, | 
|  | 81 | +	GIT_ATTR_TRUE_T, | 
|  | 82 | +	GIT_ATTR_FALSE_T, | 
|  | 83 | +	GIT_ATTR_VALUE_T, | 
|  | 84 | +} git_attr_t; | 
|  | 85 | + | 
|  | 86 | +/* | 
|  | 87 | + *	Return the value type for a given attribute. | 
|  | 88 | + * | 
|  | 89 | + *	This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute | 
|  | 90 | + *	was not set at all), or `VALUE`, if the attribute was set to | 
|  | 91 | + *	an actual string. | 
|  | 92 | + * | 
|  | 93 | + *	If the attribute has a `VALUE` string, it can be accessed normally | 
|  | 94 | + *	as a NULL-terminated C string. | 
|  | 95 | + * | 
|  | 96 | + *	@param attr The attribute | 
|  | 97 | + *	@return the value type for the attribute | 
|  | 98 | + */ | 
|  | 99 | +GIT_EXTERN(git_attr_t) git_attr_value(const char *attr); | 
|  | 100 | + | 
|  | 101 | +/** | 
|  | 102 | + * Check attribute flags: Reading values from index and working directory. | 
|  | 103 | + * | 
|  | 104 | + * When checking attributes, it is possible to check attribute files | 
|  | 105 | + * in both the working directory (if there is one) and the index (if | 
|  | 106 | + * there is one).  You can explicitly choose where to check and in | 
|  | 107 | + * which order using the following flags. | 
|  | 108 | + * | 
|  | 109 | + * Core git usually checks the working directory then the index, | 
|  | 110 | + * except during a checkout when it checks the index first.  It will | 
|  | 111 | + * use index only for creating archives or for a bare repo (if an | 
|  | 112 | + * index has been specified for the bare repo). | 
|  | 113 | + */ | 
|  | 114 | +#define GIT_ATTR_CHECK_FILE_THEN_INDEX	0 | 
|  | 115 | +#define GIT_ATTR_CHECK_INDEX_THEN_FILE	1 | 
|  | 116 | +#define GIT_ATTR_CHECK_INDEX_ONLY		2 | 
|  | 117 | + | 
|  | 118 | +/** | 
|  | 119 | + * Check attribute flags: Using the system attributes file. | 
|  | 120 | + * | 
|  | 121 | + * Normally, attribute checks include looking in the /etc (or system | 
|  | 122 | + * equivalent) directory for a `gitattributes` file.  Passing this | 
|  | 123 | + * flag will cause attribute checks to ignore that file. | 
|  | 124 | + */ | 
|  | 125 | +#define GIT_ATTR_CHECK_NO_SYSTEM		(1 << 2) | 
|  | 126 | + | 
|  | 127 | +/** | 
|  | 128 | + * Look up the value of one git attribute for path. | 
|  | 129 | + * | 
|  | 130 | + * @param value_out Output of the value of the attribute.  Use the GIT_ATTR_... | 
|  | 131 | + *             macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just | 
|  | 132 | + *             use the string value for attributes set to a value.  You | 
|  | 133 | + *             should NOT modify or free this value. | 
|  | 134 | + * @param repo The repository containing the path. | 
|  | 135 | + * @param flags A combination of GIT_ATTR_CHECK... flags. | 
|  | 136 | + * @param path The path to check for attributes.  Relative paths are | 
|  | 137 | + *             interpreted relative to the repo root.  The file does | 
|  | 138 | + *             not have to exist, but if it does not, then it will be | 
|  | 139 | + *             treated as a plain file (not a directory). | 
|  | 140 | + * @param name The name of the attribute to look up. | 
|  | 141 | + */ | 
|  | 142 | +GIT_EXTERN(int) git_attr_get( | 
|  | 143 | +	const char **value_out, | 
|  | 144 | +	git_repository *repo, | 
|  | 145 | +	uint32_t flags, | 
|  | 146 | +	const char *path, | 
|  | 147 | +	const char *name); | 
|  | 148 | + | 
|  | 149 | +/** | 
|  | 150 | + * Look up a list of git attributes for path. | 
|  | 151 | + * | 
|  | 152 | + * Use this if you have a known list of attributes that you want to | 
|  | 153 | + * look up in a single call.  This is somewhat more efficient than | 
|  | 154 | + * calling `git_attr_get()` multiple times. | 
|  | 155 | + * | 
|  | 156 | + * For example, you might write: | 
|  | 157 | + * | 
|  | 158 | + *     const char *attrs[] = { "crlf", "diff", "foo" }; | 
|  | 159 | + *     const char **values[3]; | 
|  | 160 | + *     git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs); | 
|  | 161 | + * | 
|  | 162 | + * Then you could loop through the 3 values to get the settings for | 
|  | 163 | + * the three attributes you asked about. | 
|  | 164 | + * | 
|  | 165 | + * @param values_out An array of num_attr entries that will have string | 
|  | 166 | + *             pointers written into it for the values of the attributes. | 
|  | 167 | + *             You should not modify or free the values that are written | 
|  | 168 | + *             into this array (although of course, you should free the | 
|  | 169 | + *             array itself if you allocated it). | 
|  | 170 | + * @param repo The repository containing the path. | 
|  | 171 | + * @param flags A combination of GIT_ATTR_CHECK... flags. | 
|  | 172 | + * @param path The path inside the repo to check attributes.  This | 
|  | 173 | + *             does not have to exist, but if it does not, then | 
|  | 174 | + *             it will be treated as a plain file (i.e. not a directory). | 
|  | 175 | + * @param num_attr The number of attributes being looked up | 
|  | 176 | + * @param names An array of num_attr strings containing attribute names. | 
|  | 177 | + */ | 
|  | 178 | +GIT_EXTERN(int) git_attr_get_many( | 
|  | 179 | +	const char **values_out, | 
|  | 180 | +	git_repository *repo, | 
|  | 181 | +	uint32_t flags, | 
|  | 182 | +	const char *path, | 
|  | 183 | +	size_t num_attr, | 
|  | 184 | +	const char **names); | 
|  | 185 | + | 
|  | 186 | +typedef int (*git_attr_foreach_cb)(const char *name, const char *value, void *payload); | 
|  | 187 | + | 
|  | 188 | +/** | 
|  | 189 | + * Loop over all the git attributes for a path. | 
|  | 190 | + * | 
|  | 191 | + * @param repo The repository containing the path. | 
|  | 192 | + * @param flags A combination of GIT_ATTR_CHECK... flags. | 
|  | 193 | + * @param path Path inside the repo to check attributes.  This does not have | 
|  | 194 | + *             to exist, but if it does not, then it will be treated as a | 
|  | 195 | + *             plain file (i.e. not a directory). | 
|  | 196 | + * @param callback Function to invoke on each attribute name and value.  The | 
|  | 197 | + *             value may be NULL is the attribute is explicitly set to | 
|  | 198 | + *             UNSPECIFIED using the '!' sign.  Callback will be invoked | 
|  | 199 | + *             only once per attribute name, even if there are multiple | 
|  | 200 | + *             rules for a given file.  The highest priority rule will be | 
|  | 201 | + *             used.  Return a non-zero value from this to stop looping. | 
|  | 202 | + *             The value will be returned from `git_attr_foreach`. | 
|  | 203 | + * @param payload Passed on as extra parameter to callback function. | 
|  | 204 | + * @return 0 on success, non-zero callback return value, or error code | 
|  | 205 | + */ | 
|  | 206 | +GIT_EXTERN(int) git_attr_foreach( | 
|  | 207 | +	git_repository *repo, | 
|  | 208 | +	uint32_t flags, | 
|  | 209 | +	const char *path, | 
|  | 210 | +	git_attr_foreach_cb callback, | 
|  | 211 | +	void *payload); | 
|  | 212 | + | 
|  | 213 | +/** | 
|  | 214 | + * Flush the gitattributes cache. | 
|  | 215 | + * | 
|  | 216 | + * Call this if you have reason to believe that the attributes files on | 
|  | 217 | + * disk no longer match the cached contents of memory.  This will cause | 
|  | 218 | + * the attributes files to be reloaded the next time that an attribute | 
|  | 219 | + * access function is called. | 
|  | 220 | + */ | 
|  | 221 | +GIT_EXTERN(void) git_attr_cache_flush( | 
|  | 222 | +	git_repository *repo); | 
|  | 223 | + | 
|  | 224 | +/** | 
|  | 225 | + * Add a macro definition. | 
|  | 226 | + * | 
|  | 227 | + * Macros will automatically be loaded from the top level `.gitattributes` | 
|  | 228 | + * file of the repository (plus the build-in "binary" macro).  This | 
|  | 229 | + * function allows you to add others.  For example, to add the default | 
|  | 230 | + * macro, you would call: | 
|  | 231 | + * | 
|  | 232 | + *     git_attr_add_macro(repo, "binary", "-diff -crlf"); | 
|  | 233 | + */ | 
|  | 234 | +GIT_EXTERN(int) git_attr_add_macro( | 
|  | 235 | +	git_repository *repo, | 
|  | 236 | +	const char *name, | 
|  | 237 | +	const char *values); | 
|  | 238 | + | 
|  | 239 | +/** @} */ | 
|  | 240 | +GIT_END_DECL | 
|  | 241 | +#endif | 
|  | 242 | + | 
0 commit comments