commit - 28315671b93d195163b0468fcb3879e29b25759c
commit + e27a7222faaa171dcb086ea0b566dc7bebb74a0b
blob - 39623c468e733ee08abb50eafe29202b2b0a04ef
blob + 6075cadbd177e1802679c7353515bf4ceebb51d0
--- include/got_blame.h
+++ include/got_blame.h
*/
/*
- * Write an annotated version of a file at a given in-repository path,
- * as found in the commit specified by ID, to the specified output file.
- */
-const struct got_error *got_blame(const char *, struct got_object_id *,
- struct got_repository *, FILE *);
-
-/*
- * Like got_blame() but instead of generating an output file invoke
+ * Blame the blob at the specified path in the specified commit and invoke
* a callback whenever an annotation has been computed for a line.
*
* The callback receives the provided void * argument, the total number
blob - 93f2913aab432dfc47a0e6bc7af1016b5e89ed80
blob + 87b1810be0ffe85d28132828f6ba556ebda2d7bd
--- lib/blame.c
+++ lib/blame.c
*blamep = blame;
return err;
-}
-
-static const struct got_error *
-blame_line(struct got_object_id **id, struct got_blame *blame, int lineno)
-{
- if (lineno < 1 || lineno > blame->nlines) {
- *id = NULL;
- return got_error(GOT_ERR_RANGE);
- }
- *id = &blame->lines[lineno - 1].id;
- return NULL;
-}
-
-static char *
-parse_next_line(FILE *f, size_t *len)
-{
- char *line;
- size_t linelen;
- size_t lineno;
- const char delim[3] = { '\0', '\0', '\0'};
-
- line = fparseln(f, &linelen, &lineno, delim, 0);
- if (len)
- *len = linelen;
- return line;
-}
-
-const struct got_error *
-got_blame(const char *path, struct got_object_id *start_commit_id,
- struct got_repository *repo, FILE *outfile)
-{
- const struct got_error *err = NULL, *close_err = NULL;
- struct got_blame *blame;
- int lineno;
- char *abspath;
-
- if (asprintf(&abspath, "%s%s", path[0] == '/' ? "" : "/", path) == -1)
- return got_error_from_errno2("asprintf", path);
-
- err = blame_open(&blame, abspath, start_commit_id, repo, NULL, NULL);
- if (err) {
- free(abspath);
- return err;
- }
-
- for (lineno = 1; lineno <= blame->nlines; lineno++) {
- struct got_object_id *id = NULL;
- char *line, *id_str;
-
- line = parse_next_line(blame->f, NULL);
- if (line == NULL)
- break;
-
- err = blame_line(&id, blame, lineno);
- if (err) {
- free(line);
- break;
- }
-
- err = got_object_id_str(&id_str, id);
- /* Do not free id; It points into blame->lines. */
- if (err) {
- free(line);
- break;
- }
-
- fprintf(outfile, "%.8s %s\n", id_str, line);
- free(line);
- free(id_str);
- }
-
- close_err = blame_close(blame);
- free(abspath);
- return err ? err : close_err;
}
const struct got_error *