#include "common.h"
-#ifdef _MSC_VER
-#define snprintf sprintf_s
-#define strcasecmp strcmpi
-#endif
-
/**
* This example demonstrates how to invoke the libgit2 blame API to roughly
* simulate the output of `git blame` and a few of its command line arguments.
*/
-struct opts {
+struct blame_opts {
char *path;
char *commitspec;
int C;
int end_line;
int F;
};
-static void parse_opts(struct opts *o, int argc, char *argv[]);
+static void parse_opts(struct blame_opts *o, int argc, char *argv[]);
-int main(int argc, char *argv[])
+int lg2_blame(git_repository *repo, int argc, char *argv[])
{
- int i, line, break_on_null_hunk;
+ int line, break_on_null_hunk;
+ git_object_size_t i, rawsize;
char spec[1024] = {0};
- struct opts o = {0};
+ struct blame_opts o = {0};
const char *rawdata;
- git_repository *repo = NULL;
git_revspec revspec = {0};
git_blame_options blameopts = GIT_BLAME_OPTIONS_INIT;
git_blame *blame = NULL;
git_blob *blob;
git_object *obj;
- git_threads_init();
-
parse_opts(&o, argc, argv);
if (o.M) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES;
if (o.C) blameopts.flags |= GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES;
if (o.F) blameopts.flags |= GIT_BLAME_FIRST_PARENT;
- /** Open the repository. */
- check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "Couldn't open repository", NULL);
-
/**
* The commit range comes in "commitish" form. Use the rev-parse API to
* nail down the end points.
*/
if (o.commitspec) {
check_lg2(git_revparse(&revspec, repo, o.commitspec), "Couldn't parse commit spec", NULL);
- if (revspec.flags & GIT_REVPARSE_SINGLE) {
+ if (revspec.flags & GIT_REVSPEC_SINGLE) {
git_oid_cpy(&blameopts.newest_commit, git_object_id(revspec.from));
git_object_free(revspec.from);
} else {
* Get the raw data inside the blob for output. We use the
* `commitish:path/to/file.txt` format to find it.
*/
- if (git_oid_iszero(&blameopts.newest_commit))
+ if (git_oid_is_zero(&blameopts.newest_commit))
strcpy(spec, "HEAD");
else
git_oid_tostr(spec, sizeof(spec), &blameopts.newest_commit);
git_object_free(obj);
rawdata = git_blob_rawcontent(blob);
+ rawsize = git_blob_rawsize(blob);
/** Produce the output. */
line = 1;
i = 0;
break_on_null_hunk = 0;
- while (i < git_blob_rawsize(blob)) {
- const char *eol = strchr(rawdata+i, '\n');
+ while (i < rawsize) {
+ const char *eol = memchr(rawdata + i, '\n', (size_t)(rawsize - i));
char oid[10] = {0};
const git_blame_hunk *hunk = git_blame_get_hunk_byline(blame, line);
- if (break_on_null_hunk && !hunk) break;
+ if (break_on_null_hunk && !hunk)
+ break;
if (hunk) {
- break_on_null_hunk = 1;
char sig[128] = {0};
+ break_on_null_hunk = 1;
git_oid_tostr(oid, 10, &hunk->final_commit_id);
snprintf(sig, 30, "%s <%s>", hunk->final_signature->name, hunk->final_signature->email);
oid,
sig,
line,
- (int)(eol-rawdata-i),
- rawdata+i);
+ (int)(eol - rawdata - i),
+ rawdata + i);
}
i = (int)(eol - rawdata + 1);
/** Cleanup. */
git_blob_free(blob);
git_blame_free(blame);
- git_repository_free(repo);
-
- git_threads_shutdown();
return 0;
}
}
/** Parse the arguments. */
-static void parse_opts(struct opts *o, int argc, char *argv[])
+static void parse_opts(struct blame_opts *o, int argc, char *argv[])
{
int i;
char *bare_args[3] = {0};