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