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