Skip to content

Commit 99e0d2a

Browse files
authored
Merge pull request libgit2#6907 from libgit2/ethomson/blame_cmd
Introduce a blame command
2 parents 215aafb + 2cfb83b commit 99e0d2a

File tree

15 files changed

+611
-89
lines changed

15 files changed

+611
-89
lines changed

examples/blame.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ int lg2_blame(git_repository *repo, int argc, char *argv[])
9797
while (i < rawsize) {
9898
const char *eol = memchr(rawdata + i, '\n', (size_t)(rawsize - i));
9999
char oid[10] = {0};
100-
const git_blame_hunk *hunk = git_blame_get_hunk_byline(blame, line);
100+
const git_blame_hunk *hunk = git_blame_hunk_byline(blame, line);
101101

102102
if (break_on_null_hunk && !hunk)
103103
break;

include/git2/blame.h

Lines changed: 124 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ typedef struct git_blame_options {
8787
unsigned int version;
8888

8989
/** A combination of `git_blame_flag_t` */
90-
uint32_t flags;
90+
unsigned int flags;
9191

9292
/**
9393
* The lower bound on the number of alphanumeric characters that
@@ -165,6 +165,13 @@ typedef struct git_blame_hunk {
165165
*/
166166
git_signature *final_signature;
167167

168+
/**
169+
* The committer of `final_commit_id`. If `GIT_BLAME_USE_MAILMAP` has
170+
* been specified, it will contain the canonical real name and email
171+
* address.
172+
*/
173+
git_signature *final_committer;
174+
168175
/**
169176
* The OID of the commit where this hunk was found.
170177
* This will usually be the same as `final_commit_id`, except when
@@ -190,23 +197,94 @@ typedef struct git_blame_hunk {
190197
*/
191198
git_signature *orig_signature;
192199

200+
/**
201+
* The committer of `orig_commit_id`. If `GIT_BLAME_USE_MAILMAP` has
202+
* been specified, it will contain the canonical real name and email
203+
* address.
204+
*/
205+
git_signature *orig_committer;
206+
207+
/*
208+
* The summary of the commit.
209+
*/
210+
const char *summary;
211+
193212
/**
194213
* The 1 iff the hunk has been tracked to a boundary commit (the root,
195214
* or the commit specified in git_blame_options.oldest_commit)
196215
*/
197216
char boundary;
198217
} git_blame_hunk;
199218

219+
/**
220+
* Structure that represents a line in a blamed file.
221+
*/
222+
typedef struct git_blame_line {
223+
const char *ptr;
224+
size_t len;
225+
} git_blame_line;
200226

201227
/** Opaque structure to hold blame results */
202228
typedef struct git_blame git_blame;
203229

230+
/**
231+
* Gets the number of lines that exist in the blame structure.
232+
*
233+
* @param blame The blame structure to query.
234+
* @return The number of line.
235+
*/
236+
GIT_EXTERN(size_t) git_blame_linecount(git_blame *blame);
237+
204238
/**
205239
* Gets the number of hunks that exist in the blame structure.
206240
*
207241
* @param blame The blame structure to query.
208242
* @return The number of hunks.
209243
*/
244+
GIT_EXTERN(size_t) git_blame_hunkcount(git_blame *blame);
245+
246+
/**
247+
* Gets the blame hunk at the given index.
248+
*
249+
* @param blame the blame structure to query
250+
* @param index index of the hunk to retrieve
251+
* @return the hunk at the given index, or NULL on error
252+
*/
253+
GIT_EXTERN(const git_blame_hunk *) git_blame_hunk_byindex(
254+
git_blame *blame,
255+
size_t index);
256+
257+
/**
258+
* Gets the hunk that relates to the given line number in the newest
259+
* commit.
260+
*
261+
* @param blame the blame structure to query
262+
* @param lineno the (1-based) line number to find a hunk for
263+
* @return the hunk that contains the given line, or NULL on error
264+
*/
265+
GIT_EXTERN(const git_blame_hunk *) git_blame_hunk_byline(
266+
git_blame *blame,
267+
size_t lineno);
268+
269+
/**
270+
* Gets the information about the line in the blame.
271+
*
272+
* @param blame the blame structure to query
273+
* @param idx the (1-based) line number
274+
* @return the blamed line, or NULL on error
275+
*/
276+
GIT_EXTERN(const git_blame_line *) git_blame_line_byindex(
277+
git_blame *blame,
278+
size_t idx);
279+
280+
#ifndef GIT_DEPRECATE_HARD
281+
/**
282+
* Gets the number of hunks that exist in the blame structure.
283+
*
284+
* @param blame The blame structure to query.
285+
* @return The number of hunks.
286+
*/
287+
210288
GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame);
211289

212290
/**
@@ -216,9 +294,9 @@ GIT_EXTERN(uint32_t) git_blame_get_hunk_count(git_blame *blame);
216294
* @param index index of the hunk to retrieve
217295
* @return the hunk at the given index, or NULL on error
218296
*/
219-
GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byindex(
220-
git_blame *blame,
221-
uint32_t index);
297+
GIT_EXTERN(const git_blame_hunk *) git_blame_get_hunk_byindex(
298+
git_blame *blame,
299+
uint32_t index);
222300

223301
/**
224302
* Gets the hunk that relates to the given line number in the newest commit.
@@ -227,50 +305,69 @@ GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byindex(
227305
* @param lineno the (1-based) line number to find a hunk for
228306
* @return the hunk that contains the given line, or NULL on error
229307
*/
230-
GIT_EXTERN(const git_blame_hunk*) git_blame_get_hunk_byline(
231-
git_blame *blame,
232-
size_t lineno);
308+
GIT_EXTERN(const git_blame_hunk *) git_blame_get_hunk_byline(
309+
git_blame *blame,
310+
size_t lineno);
311+
#endif
233312

234313
/**
235-
* Get the blame for a single file.
314+
* Get the blame for a single file in the repository.
236315
*
237316
* @param out pointer that will receive the blame object
238317
* @param repo repository whose history is to be walked
239318
* @param path path to file to consider
240-
* @param options options for the blame operation. If NULL, this is treated as
241-
* though GIT_BLAME_OPTIONS_INIT were passed.
242-
* @return 0 on success, or an error code. (use git_error_last for information
243-
* about the error.)
319+
* @param options options for the blame operation or NULL
320+
* @return 0 on success, or an error code
244321
*/
245322
GIT_EXTERN(int) git_blame_file(
246-
git_blame **out,
247-
git_repository *repo,
248-
const char *path,
249-
git_blame_options *options);
323+
git_blame **out,
324+
git_repository *repo,
325+
const char *path,
326+
git_blame_options *options);
250327

328+
/**
329+
* Get the blame for a single file in the repository, using the specified
330+
* buffer contents as the uncommitted changes of the file (the working
331+
* directory contents).
332+
*
333+
* @param out pointer that will receive the blame object
334+
* @param repo repository whose history is to be walked
335+
* @param path path to file to consider
336+
* @param contents the uncommitted changes
337+
* @param contents_len the length of the changes buffer
338+
* @param options options for the blame operation or NULL
339+
* @return 0 on success, or an error code
340+
*/
341+
GIT_EXTERN(int) git_blame_file_from_buffer(
342+
git_blame **out,
343+
git_repository *repo,
344+
const char *path,
345+
const char *contents,
346+
size_t contents_len,
347+
git_blame_options *options);
251348

252349
/**
253-
* Get blame data for a file that has been modified in memory. The `reference`
254-
* parameter is a pre-calculated blame for the in-odb history of the file. This
255-
* means that once a file blame is completed (which can be expensive), updating
256-
* the buffer blame is very fast.
350+
* Get blame data for a file that has been modified in memory. The `blame`
351+
* parameter is a pre-calculated blame for the in-odb history of the file.
352+
* This means that once a file blame is completed (which can be expensive),
353+
* updating the buffer blame is very fast.
257354
*
258-
* Lines that differ between the buffer and the committed version are marked as
259-
* having a zero OID for their final_commit_id.
355+
* Lines that differ between the buffer and the committed version are
356+
* marked as having a zero OID for their final_commit_id.
260357
*
261358
* @param out pointer that will receive the resulting blame data
262-
* @param reference cached blame from the history of the file (usually the output
359+
* @param base cached blame from the history of the file (usually the output
263360
* from git_blame_file)
264361
* @param buffer the (possibly) modified contents of the file
265362
* @param buffer_len number of valid bytes in the buffer
266363
* @return 0 on success, or an error code. (use git_error_last for information
267364
* about the error)
268365
*/
269366
GIT_EXTERN(int) git_blame_buffer(
270-
git_blame **out,
271-
git_blame *reference,
272-
const char *buffer,
273-
size_t buffer_len);
367+
git_blame **out,
368+
git_blame *base,
369+
const char *buffer,
370+
size_t buffer_len);
274371

275372
/**
276373
* Free memory allocated by git_blame_file or git_blame_buffer.

src/cli/cmd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ extern const cli_cmd_spec cli_cmds[];
2525
extern const cli_cmd_spec *cli_cmd_spec_byname(const char *name);
2626

2727
/* Commands */
28+
extern int cmd_blame(int argc, char **argv);
2829
extern int cmd_cat_file(int argc, char **argv);
2930
extern int cmd_clone(int argc, char **argv);
3031
extern int cmd_config(int argc, char **argv);

0 commit comments

Comments
 (0)