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