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 8 #ifndef INCLUDE_git_blame_h__ 9 #define INCLUDE_git_blame_h__ 10 11 #include "common.h" 12 #include "oid.h" 13 14 /** 15 * @file git2/blame.h 16 * @brief Git blame routines 17 * @defgroup git_blame Git blame routines 18 * @ingroup Git 19 * @{ 20 */ 21 GIT_BEGIN_DECL 22 23 /** 24 * Flags for indicating option behavior for git_blame APIs. 25 */ 26 typedef enum { 27 /** Normal blame, the default */ 28 GIT_BLAME_NORMAL = 0, 29 30 /** 31 * Track lines that have moved within a file (like `git blame -M`). 32 * 33 * This is not yet implemented and reserved for future use. 34 */ 35 GIT_BLAME_TRACK_COPIES_SAME_FILE = (1<<0), 36 37 /** 38 * Track lines that have moved across files in the same commit 39 * (like `git blame -C`). 40 * 41 * This is not yet implemented and reserved for future use. 42 */ 43 GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES = (1<<1), 44 45 /** 46 * Track lines that have been copied from another file that exists 47 * in the same commit (like `git blame -CC`). Implies SAME_FILE. 48 * 49 * This is not yet implemented and reserved for future use. 50 */ 51 GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES = (1<<2), 52 53 /** 54 * Track lines that have been copied from another file that exists in 55 * *any* commit (like `git blame -CCC`). Implies SAME_COMMIT_COPIES. 56 * 57 * This is not yet implemented and reserved for future use. 58 */ 59 GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES = (1<<3), 60 61 /** 62 * Restrict the search of commits to those reachable following only 63 * the first parents. 64 */ 65 GIT_BLAME_FIRST_PARENT = (1<<4), 66 67 /** 68 * Use mailmap file to map author and committer names and email 69 * addresses to canonical real names and email addresses. The 70 * mailmap will be read from the working directory, or HEAD in a 71 * bare repository. 72 */ 73 GIT_BLAME_USE_MAILMAP = (1<<5), 74 75 /** Ignore whitespace differences */ 76 GIT_BLAME_IGNORE_WHITESPACE = (1<<6), 77 } git_blame_flag_t; 78 79 /** 80 * Blame options structure 81 * 82 * Initialize with `GIT_BLAME_OPTIONS_INIT`. Alternatively, you can 83 * use `git_blame_options_init`. 84 * 85 */ 86 typedef struct git_blame_options { 87 unsigned int version; 88 89 /** A combination of `git_blame_flag_t` */ 90 uint32_t flags; 91 92 /** 93 * The lower bound on the number of alphanumeric characters that 94 * must be detected as moving/copying within a file for it to 95 * associate those lines with the parent commit. The default value 96 * is 20. 97 * 98 * This value only takes effect if any of the `GIT_BLAME_TRACK_COPIES_*` 99 * flags are specified. 100 */ 101 uint16_t min_match_characters; 102 103 /** The id of the newest commit to consider. The default is HEAD. */ 104 git_oid newest_commit; 105 106 /** 107 * The id of the oldest commit to consider. 108 * The default is the first commit encountered with a NULL parent. 109 */ 110 git_oid oldest_commit; 111 112 /** 113 * The first line in the file to blame. 114 * The default is 1 (line numbers start with 1). 115 */ 116 size_t min_line; 117 118 /** 119 * The last line in the file to blame. 120 * The default is the last line of the file. 121 */ 122 size_t max_line; 123 } git_blame_options; 124 125 #define GIT_BLAME_OPTIONS_VERSION 1 126 #define GIT_BLAME_OPTIONS_INIT {GIT_BLAME_OPTIONS_VERSION} 127 128 /** 129 * Initialize git_blame_options structure 130 * 131 * Initializes a `git_blame_options` with default values. Equivalent to creating 132 * an instance with GIT_BLAME_OPTIONS_INIT. 133 * 134 * @param opts The `git_blame_options` struct to initialize. 135 * @param version The struct version; pass `GIT_BLAME_OPTIONS_VERSION`. 136 * @return Zero on success; -1 on failure. 137 */ 138 GIT_EXTERN(int) git_blame_options_init( 139 git_blame_options *opts, 140 unsigned int version); 141 142 /** 143 * Structure that represents a blame hunk. 144 */ 145 typedef struct git_blame_hunk { 146 /** 147 * The number of lines in this hunk. 148 */ 149 size_t lines_in_hunk; 150 151 /** 152 * The OID of the commit where this line was last changed. 153 */ 154 git_oid final_commit_id; 155 156 /** 157 * The 1-based line number where this hunk begins, in the final version 158 * of the file. 159 */ 160 size_t final_start_line_number; 161 162 /** 163 * The author of `final_commit_id`. If `GIT_BLAME_USE_MAILMAP` has been 164 * specified, it will contain the canonical real name and email address. 165 */ 166 git_signature *final_signature; 167 168 /** 169 * The OID of the commit where this hunk was found. 170 * This will usually be the same as `final_commit_id`, except when 171 * `GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES` has been specified. 172 */ 173 git_oid orig_commit_id; 174 175 /** 176 * The path to the file where this hunk originated, as of the commit 177 * specified by `orig_commit_id`. 178 */ 179 const char *orig_path; 180 181 /** 182 * The 1-based line number where this hunk begins in the file named by 183 * `orig_path` in the commit specified by `orig_commit_id`. 184 */ 185 size_t orig_start_line_number; 186 187 /** 188 * The author of `orig_commit_id`. If `GIT_BLAME_USE_MAILMAP` has been 189 * specified, it will contain the canonical real name and email address. 190 */ 191 git_signature *orig_signature; 192 193 /** 194 * The 1 iff the hunk has been tracked to a boundary commit (the root, 195 * or the commit specified in git_blame_options.oldest_commit) 196 */ 197 char boundary; 198 } git_blame_hunk; 199 200 201 /** Opaque structure to hold blame results */ 202 typedef struct git_blame git_blame; 203 204 /** 205 * Gets the number of hunks that exist in the blame structure. 206 */ 207 GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame); 208 209 /** 210 * Gets the blame hunk at the given index. 211 * 212 * @param blame the blame structure to query 213 * @param index index of the hunk to retrieve 214 * @return the hunk at the given index, or NULL on error 215 */ 216 GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byindex( 217 git_blame *blame, 218 uint32_t index); 219 220 /** 221 * Gets the hunk that relates to the given line number in the newest commit. 222 * 223 * @param blame the blame structure to query 224 * @param lineno the (1-based) line number to find a hunk for 225 * @return the hunk that contains the given line, or NULL on error 226 */ 227 GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byline( 228 git_blame *blame, 229 size_t lineno); 230 231 /** 232 * Get the blame for a single file. 233 * 234 * @param out pointer that will receive the blame object 235 * @param repo repository whose history is to be walked 236 * @param path path to file to consider 237 * @param options options for the blame operation. If NULL, this is treated as 238 * though GIT_BLAME_OPTIONS_INIT were passed. 239 * @return 0 on success, or an error code. (use git_error_last for information 240 * about the error.) 241 */ 242 GIT_EXTERN(int) git_blame_file( 243 git_blame **out, 244 git_repository *repo, 245 const char *path, 246 git_blame_options *options); 247 248 249 /** 250 * Get blame data for a file that has been modified in memory. The `reference` 251 * parameter is a pre-calculated blame for the in-odb history of the file. This 252 * means that once a file blame is completed (which can be expensive), updating 253 * the buffer blame is very fast. 254 * 255 * Lines that differ between the buffer and the committed version are marked as 256 * having a zero OID for their final_commit_id. 257 * 258 * @param out pointer that will receive the resulting blame data 259 * @param reference cached blame from the history of the file (usually the output 260 * from git_blame_file) 261 * @param buffer the (possibly) modified contents of the file 262 * @param buffer_len number of valid bytes in the buffer 263 * @return 0 on success, or an error code. (use git_error_last for information 264 * about the error) 265 */ 266 GIT_EXTERN(int) git_blame_buffer( 267 git_blame **out, 268 git_blame *reference, 269 const char *buffer, 270 size_t buffer_len); 271 272 /** 273 * Free memory allocated by git_blame_file or git_blame_buffer. 274 * 275 * @param blame the blame structure to free 276 */ 277 GIT_EXTERN(void) git_blame_free(git_blame *blame); 278 279 /** @} */ 280 GIT_END_DECL 281 #endif 282 283