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_IS_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_TRUE) 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_IS_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_FALSE) 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_IS_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_UNSPECIFIED) 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_STRING) 78 79 /** 80 * Possible states for an attribute 81 */ 82 typedef enum { 83 GIT_ATTR_VALUE_UNSPECIFIED = 0, /**< The attribute has been left unspecified */ 84 GIT_ATTR_VALUE_TRUE, /**< The attribute has been set */ 85 GIT_ATTR_VALUE_FALSE, /**< The attribute has been unset */ 86 GIT_ATTR_VALUE_STRING, /**< This attribute has a value */ 87 } git_attr_value_t; 88 89 /** 90 * Return the value type for a given attribute. 91 * 92 * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute 93 * was not set at all), or `VALUE`, if the attribute was set to an 94 * actual string. 95 * 96 * If the attribute has a `VALUE` string, it can be accessed normally 97 * as a NULL-terminated C string. 98 * 99 * @param attr The attribute 100 * @return the value type for the attribute 101 */ 102 GIT_EXTERN(git_attr_value_t) git_attr_value(const char *attr); 103 104 /** 105 * Check attribute flags: Reading values from index and working directory. 106 * 107 * When checking attributes, it is possible to check attribute files 108 * in both the working directory (if there is one) and the index (if 109 * there is one). You can explicitly choose where to check and in 110 * which order using the following flags. 111 * 112 * Core git usually checks the working directory then the index, 113 * except during a checkout when it checks the index first. It will 114 * use index only for creating archives or for a bare repo (if an 115 * index has been specified for the bare repo). 116 */ 117 #define GIT_ATTR_CHECK_FILE_THEN_INDEX 0 118 #define GIT_ATTR_CHECK_INDEX_THEN_FILE 1 119 #define GIT_ATTR_CHECK_INDEX_ONLY 2 120 121 /** 122 * Check attribute flags: controlling extended attribute behavior. 123 * 124 * Normally, attribute checks include looking in the /etc (or system 125 * equivalent) directory for a `gitattributes` file. Passing this 126 * flag will cause attribute checks to ignore that file. 127 * equivalent) directory for a `gitattributes` file. Passing the 128 * `GIT_ATTR_CHECK_NO_SYSTEM` flag will cause attribute checks to 129 * ignore that file. 130 * 131 * Passing the `GIT_ATTR_CHECK_INCLUDE_HEAD` flag will use attributes 132 * 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. 136 */ 137 #define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2) 138 #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 #ifdef GIT_DEPRECATE_HARD 151 void *reserved; 152 #else 153 git_oid *commit_id; 154 #endif 155 156 /** 157 * The commit to load attributes from, when 158 * `GIT_ATTR_CHECK_INCLUDE_COMMIT` is specified. 159 */ 160 git_oid attr_commit_id; 161 } git_attr_options; 162 163 #define GIT_ATTR_OPTIONS_VERSION 1 164 #define GIT_ATTR_OPTIONS_INIT {GIT_ATTR_OPTIONS_VERSION} 165 166 /** 167 * Look up the value of one git attribute for path. 168 * 169 * @param value_out Output of the value of the attribute. Use the GIT_ATTR_... 170 * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just 171 * use the string value for attributes set to a value. You 172 * should NOT modify or free this value. 173 * @param repo The repository containing the path. 174 * @param flags A combination of GIT_ATTR_CHECK... flags. 175 * @param path The path to check for attributes. Relative paths are 176 * interpreted relative to the repo root. The file does 177 * not have to exist, but if it does not, then it will be 178 * treated as a plain file (not a directory). 179 * @param name The name of the attribute to look up. 180 */ 181 GIT_EXTERN(int) git_attr_get( 182 const char **value_out, 183 git_repository *repo, 184 uint32_t flags, 185 const char *path, 186 const char *name); 187 188 /** 189 * Look up the value of one git attribute for path with extended options. 190 * 191 * @param value_out Output of the value of the attribute. Use the GIT_ATTR_... 192 * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just 193 * use the string value for attributes set to a value. You 194 * should NOT modify or free this value. 195 * @param repo The repository containing the path. 196 * @param opts The `git_attr_options` to use when querying these attributes. 197 * @param path The path to check for attributes. Relative paths are 198 * interpreted relative to the repo root. The file does 199 * not have to exist, but if it does not, then it will be 200 * treated as a plain file (not a directory). 201 * @param name The name of the attribute to look up. 202 */ 203 GIT_EXTERN(int) git_attr_get_ext( 204 const char **value_out, 205 git_repository *repo, 206 git_attr_options *opts, 207 const char *path, 208 const char *name); 209 210 /** 211 * Look up a list of git attributes for path. 212 * 213 * Use this if you have a known list of attributes that you want to 214 * look up in a single call. This is somewhat more efficient than 215 * calling `git_attr_get()` multiple times. 216 * 217 * For example, you might write: 218 * 219 * const char *attrs[] = { "crlf", "diff", "foo" }; 220 * const char **values[3]; 221 * git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs); 222 * 223 * Then you could loop through the 3 values to get the settings for 224 * the three attributes you asked about. 225 * 226 * @param values_out An array of num_attr entries that will have string 227 * pointers written into it for the values of the attributes. 228 * You should not modify or free the values that are written 229 * into this array (although of course, you should free the 230 * array itself if you allocated it). 231 * @param repo The repository containing the path. 232 * @param flags A combination of GIT_ATTR_CHECK... flags. 233 * @param path The path inside the repo to check attributes. This 234 * does not have to exist, but if it does not, then 235 * it will be treated as a plain file (i.e. not a directory). 236 * @param num_attr The number of attributes being looked up 237 * @param names An array of num_attr strings containing attribute names. 238 */ 239 GIT_EXTERN(int) git_attr_get_many( 240 const char **values_out, 241 git_repository *repo, 242 uint32_t flags, 243 const char *path, 244 size_t num_attr, 245 const char **names); 246 247 /** 248 * Look up a list of git attributes for path with extended options. 249 * 250 * @param values_out An array of num_attr entries that will have string 251 * pointers written into it for the values of the attributes. 252 * You should not modify or free the values that are written 253 * into this array (although of course, you should free the 254 * array itself if you allocated it). 255 * @param repo The repository containing the path. 256 * @param opts The `git_attr_options` to use when querying these attributes. 257 * @param path The path inside the repo to check attributes. This 258 * does not have to exist, but if it does not, then 259 * it will be treated as a plain file (i.e. not a directory). 260 * @param num_attr The number of attributes being looked up 261 * @param names An array of num_attr strings containing attribute names. 262 */ 263 GIT_EXTERN(int) git_attr_get_many_ext( 264 const char **values_out, 265 git_repository *repo, 266 git_attr_options *opts, 267 const char *path, 268 size_t num_attr, 269 const char **names); 270 271 /** 272 * The callback used with git_attr_foreach. 273 * 274 * This callback will be invoked only once per attribute name, even if there 275 * are multiple rules for a given file. The highest priority rule will be 276 * used. 277 * 278 * @see git_attr_foreach. 279 * 280 * @param name The attribute name. 281 * @param value The attribute value. May be NULL if the attribute is explicitly 282 * set to UNSPECIFIED using the '!' sign. 283 * @param payload A user-specified pointer. 284 * @return 0 to continue looping, non-zero to stop. This value will be returned 285 * from git_attr_foreach. 286 */ 287 typedef int GIT_CALLBACK(git_attr_foreach_cb)(const char *name, const char *value, void *payload); 288 289 /** 290 * Loop over all the git attributes for a path. 291 * 292 * @param repo The repository containing the path. 293 * @param flags A combination of GIT_ATTR_CHECK... flags. 294 * @param path Path inside the repo to check attributes. This does not have 295 * to exist, but if it does not, then it will be treated as a 296 * plain file (i.e. not a directory). 297 * @param callback Function to invoke on each attribute name and value. 298 * See git_attr_foreach_cb. 299 * @param payload Passed on as extra parameter to callback function. 300 * @return 0 on success, non-zero callback return value, or error code 301 */ 302 GIT_EXTERN(int) git_attr_foreach( 303 git_repository *repo, 304 uint32_t flags, 305 const char *path, 306 git_attr_foreach_cb callback, 307 void *payload); 308 309 /** 310 * Loop over all the git attributes for a path with extended options. 311 * 312 * @param repo The repository containing the path. 313 * @param opts The `git_attr_options` to use when querying these attributes. 314 * @param path Path inside the repo to check attributes. This does not have 315 * to exist, but if it does not, then it will be treated as a 316 * plain file (i.e. not a directory). 317 * @param callback Function to invoke on each attribute name and value. 318 * See git_attr_foreach_cb. 319 * @param payload Passed on as extra parameter to callback function. 320 * @return 0 on success, non-zero callback return value, or error code 321 */ 322 GIT_EXTERN(int) git_attr_foreach_ext( 323 git_repository *repo, 324 git_attr_options *opts, 325 const char *path, 326 git_attr_foreach_cb callback, 327 void *payload); 328 329 /** 330 * Flush the gitattributes cache. 331 * 332 * Call this if you have reason to believe that the attributes files on 333 * disk no longer match the cached contents of memory. This will cause 334 * the attributes files to be reloaded the next time that an attribute 335 * access function is called. 336 * 337 * @param repo The repository containing the gitattributes cache 338 * @return 0 on success, or an error code 339 */ 340 GIT_EXTERN(int) git_attr_cache_flush( 341 git_repository *repo); 342 343 /** 344 * Add a macro definition. 345 * 346 * Macros will automatically be loaded from the top level `.gitattributes` 347 * file of the repository (plus the build-in "binary" macro). This 348 * function allows you to add others. For example, to add the default 349 * macro, you would call: 350 * 351 * git_attr_add_macro(repo, "binary", "-diff -crlf"); 352 */ 353 GIT_EXTERN(int) git_attr_add_macro( 354 git_repository *repo, 355 const char *name, 356 const char *values); 357 358 /** @} */ 359 GIT_END_DECL 360 #endif 361 362