Beispiel #1
0
static int show_ref(git_reference *ref, void *data)
{
        git_repository *repo = data;
        git_reference *resolved = NULL;
        char hex[GIT_OID_HEXSZ+1];
        const git_oid *oid;
        git_object *obj;

        if (git_reference_type(ref) == GIT_REF_SYMBOLIC)
                check_lg2(git_reference_resolve(&resolved, ref),
                          "Unable to resolve symbolic reference",
                          git_reference_name(ref));

        oid = git_reference_target(resolved ? resolved : ref);
        git_oid_fmt(hex, oid);
        hex[GIT_OID_HEXSZ] = 0;
        check_lg2(git_object_lookup(&obj, repo, oid, GIT_OBJ_ANY),
                  "Unable to lookup object", hex);

        printf("%s %-6s\t%s\n",
               hex,
               git_object_type2string(git_object_type(obj)),
               git_reference_name(ref));

        if (resolved)
                git_reference_free(resolved);
        return 0;
}
Beispiel #2
0
static void action_create_tag(tag_state *state)
{
	git_repository *repo = state->repo;
	tag_options *opts = state->opts;
	git_signature *tagger;
	git_oid oid;
	git_object *target;

	check(!opts->tag_name, "Name required");
	check(!opts->message, "Message required");

	if (!opts->target) opts->target = "HEAD";

	check_lg2(git_revparse_single(&target, repo, opts->target),
			"Unable to resolve spec", opts->target);

	check_lg2(git_signature_default(&tagger, repo),
			"Unable to create signature", NULL);

	check_lg2(git_tag_create(&oid, repo, opts->tag_name,
				target, tagger, opts->message, opts->force), "Unable to create tag", NULL);

	git_object_free(target);
	git_signature_free(tagger);
}
Beispiel #3
0
/** Display diff output with "--stat", "--numstat", or "--shortstat" */
static void diff_print_stats(git_diff *diff, struct opts *o)
{
	git_diff_stats *stats;
	git_buf b = GIT_BUF_INIT_CONST(NULL, 0);
	git_diff_stats_format_t format = 0;

	check_lg2(
		git_diff_get_stats(&stats, diff), "generating stats for diff", NULL);

	if (o->output & OUTPUT_STAT)
		format |= GIT_DIFF_STATS_FULL;
	if (o->output & OUTPUT_SHORTSTAT)
		format |= GIT_DIFF_STATS_SHORT;
	if (o->output & OUTPUT_NUMSTAT)
		format |= GIT_DIFF_STATS_NUMBER;
	if (o->output & OUTPUT_SUMMARY)
		format |= GIT_DIFF_STATS_INCLUDE_SUMMARY;

	check_lg2(
		git_diff_stats_to_buf(&b, stats, format, 80), "formatting stats", NULL);

	fputs(b.ptr, stdout);

	git_buf_dispose(&b);
	git_diff_stats_free(stats);
}
Beispiel #4
0
static int check_updates(){
    git_reference *before_head, *after_head;
    int retval;

    check_lg2(git_reference_lookup(&before_head, repo, "refs/remotes/origin/master"),
              "Could not lookup master branch (before)", NULL);

    fetch_updates();

    check_lg2(git_reference_lookup(&after_head, repo, "refs/remotes/origin/master"),
              "Could not lookup master branch (after)", NULL);

    // Fetch updated things
    if(git_reference_cmp(before_head, after_head)){
        puts("Update detected");
        retval = 1;
    } else {
        retval = 0;
    }

    git_reference_free(before_head);
    git_reference_free(after_head);

    return retval;
}
Beispiel #5
0
static int push_result_lib(git_oid *commit, git_remote *remote){
    git_push *push;
    int retval = 0;
    char cmd[128];

    git_oid_tostr(cmd, GIT_OID_HEXSZ+1, commit);
    strncat(cmd, ":refs/heads/master", 128);
    puts(cmd);

    check_lg2(git_push_new(&push, remote),
              "Error creating push", NULL);
    check_lg2(git_push_add_refspec(push, cmd),
              "Failed to add refspec to push", NULL);

    retval = log_lg2(git_push_finish(push),
                     "Failed to finish push", NULL);

    if(retval || !git_push_unpack_ok(push)){
        puts("Push: unpack failed!");
        retval = 1;
    } else {
        git_push_status_foreach(push, record_push_status_cb, &retval);
    }

    git_push_free(push);

    return retval;
}
Beispiel #6
0
int lg2_status(git_repository *repo, int argc, char *argv[])
{
	git_status_list *status;
	struct opts o = { GIT_STATUS_OPTIONS_INIT, "." };

	o.statusopt.show  = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
	o.statusopt.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
		GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX |
		GIT_STATUS_OPT_SORT_CASE_SENSITIVELY;

	parse_opts(&o, argc, argv);

	if (git_repository_is_bare(repo))
		fatal("Cannot report status on bare repository",
			git_repository_path(repo));

show_status:
	if (o.repeat)
		printf("\033[H\033[2J");

	/**
	 * Run status on the repository
	 *
	 * We use `git_status_list_new()` to generate a list of status
	 * information which lets us iterate over it at our
	 * convenience and extract the data we want to show out of
	 * each entry.
	 *
	 * You can use `git_status_foreach()` or
	 * `git_status_foreach_ext()` if you'd prefer to execute a
	 * callback for each entry. The latter gives you more control
	 * about what results are presented.
	 */
	check_lg2(git_status_list_new(&status, repo, &o.statusopt),
		"Could not get status", NULL);

	if (o.showbranch)
		show_branch(repo, o.format);

	if (o.showsubmod) {
		int submod_count = 0;
		check_lg2(git_submodule_foreach(repo, print_submod, &submod_count),
			"Cannot iterate submodules", o.repodir);
	}

	if (o.format == FORMAT_LONG)
		print_long(status);
	else
		print_short(repo, status);

	git_status_list_free(status);

	if (o.repeat) {
		sleep(o.repeat);
		goto show_status;
	}

	return 0;
}
Beispiel #7
0
static void init_git(git_index **index){
    git_threads_init();

    check_lg2(git_repository_open(&repo, "."),
              "No git repository", NULL);
    check_lg2(git_repository_index(index, repo),
              "Could not open repository index", NULL);
}
Beispiel #8
0
static int read_file_git(const char *repo_path, const char *name, void **out, size_t *outlen) {
    int ret, retcode = -1;

    git_repository *repo;
    ret = git_repository_open_bare(&repo, repo_path);
    if(check_lg2(ret, "opening repo"))
        goto out;

    git_object *master;
    ret = git_revparse_single(&master, repo, "master");
    if(check_lg2(ret, "getting master branch"))
        goto out_repo;

    if(git_object_type(master) != GIT_OBJ_COMMIT) {
        debug("master is not a commit");
        goto out_master;
    }

    git_tree *tree;
    ret = git_commit_tree(&tree, (git_commit*)master);
    if(check_lg2(ret, "getting tree from commit"))
        goto out_master;

    const git_tree_entry *entry = git_tree_entry_byname(tree, name);
    if(!entry) {
        debug("entry %s not found", name);
        goto out_tree;
    }

    if(git_tree_entry_type(entry) != GIT_OBJ_BLOB) {
        debug("entry is not a blob");
        goto out_tree;
    }

    git_object *file;
    ret = git_tree_entry_to_object(&file, repo, entry);
    if(check_lg2(ret, "getting file from tree entry"))
        goto out_tree;

    const void *data = git_blob_rawcontent((git_blob*)file);
    *outlen = git_blob_rawsize((git_blob*)file);

    *out = malloc(*outlen);
    memcpy(*out, data, *outlen);

    retcode = 0;

    git_object_free(file);
out_tree:
    git_tree_free(tree);
out_master:
    git_object_free(master);
out_repo:
    git_repository_free(repo);
out:
    return retcode;
}
Beispiel #9
0
int main(int argc, char **argv)
{
        struct stat st;
        struct timeval start, end;
        char filepath[1024], repodir[64];
        char *dirpath, *filename, *ref = NULL;

        if (argc != 3) {
                fprintf(stderr, "Usage: ./log dirpath filename\n");
                exit(-1);
        }

        dirpath = argv[1];
        filename = argv[2];
        strcpy(repodir, dirpath);
        strcat(repodir, "/.git");
        strcpy(filepath, dirpath);
        strcat(filepath, "/");
        strcat(filepath, filename);
        if (stat(filepath, &st) < 0) {
                fprintf(stderr, "Not valid file path: \"%s\"!\n", filepath);
                exit(-2);
        }

        memset(&s, 0, sizeof(s));
        s.sorting = GIT_SORT_TIME;
        s.hide = 0;
        s.repodir = strlen(repodir) > 0  ? repodir : "/tmp/git/.git";
        s.ref = ref ? ref : "refs/heads/master";

        /* Init libgit2 library */
        git_libgit2_init();

        /* Open repo. */
        check_lg2(git_repository_open_ext(&s.repo, s.repodir, 0, NULL),
                "Could not open repository", s.repodir);

	/* Create revwalker. */
        check_lg2(git_revwalk_new(&s.walker, s.repo),
                "Could not create revision walker", NULL);
        git_revwalk_sorting(s.walker, s.sorting);

        /* Show file's latest commit. */
        printf("filename: %s\n", filename);
        gettimeofday(&start, NULL);
        git_show_last_commit(filename);
        gettimeofday(&end, NULL);
        printf("time span: %ld(ms)\n", (end.tv_sec - start.tv_sec) * 1000 + \
                        (end.tv_usec - start.tv_usec) / 1000);

	git_revwalk_free(s.walker);
	git_repository_free(s.repo);
	git_libgit2_shutdown();

        return 0;
}
Beispiel #10
0
int main(int argc, char **argv)
{
        git_repository *repo;

        if (argc != 1 || argv[1] /* silence -Wunused-parameter */)
                fatal("Sorry, no for-each-ref options supported yet", NULL);

        check_lg2(git_repository_open(&repo, "."),
                  "Could not open repository", NULL);
        check_lg2(git_reference_foreach(repo, show_ref, repo),
                  "Could not iterate over references", NULL);
        return 0;
}
Beispiel #11
0
static void commit_result(char* msg, git_oid *commit){
    git_odb *odb;

    check_lg2(git_repository_odb(&odb, repo),
              "Could not allocate odb poiner", NULL);

    check_lg2(git_odb_write(commit, odb, &msg[PREAMBLE_LENGTH], MSG_LENGTH, GIT_OBJ_COMMIT),
              "Error writing commit", NULL);

    check_lg2(git_reference_create(NULL, repo, "refs/heads/master", commit, 1),
              "Could not update head", NULL);

    git_odb_free(odb);
}
Beispiel #12
0
static void reset_hard(){
    git_object *remote_commit;
    git_reference *remote_head;

    check_lg2(git_reference_lookup(&remote_head, repo, "refs/remotes/origin/master"),
              "Could not lookup master branch", NULL);

    check_lg2(git_reference_peel((git_object**)&remote_commit, remote_head, GIT_OBJ_COMMIT),
              "Could not peel remote commit", NULL);
    check_lg2(git_reset(repo, (git_object *)remote_commit, GIT_RESET_HARD),
              "Could not reset to remote head", NULL);

    git_object_free(remote_commit);
    git_reference_free(remote_head);
}
Beispiel #13
0
/* Helper to get the latest commit of the specified file */
int git_show_last_commit(char *filename)
{
        git_oid oid;
        git_commit *commit = NULL;

        /* Set up pathspec. */
        git_diff_options diffopts = GIT_DIFF_OPTIONS_INIT;
        diffopts.pathspec.strings = &filename;
        diffopts.pathspec.count = 1;

        /* Use the revwalker to traverse the history. */
        check_lg2(git_revwalk_push_ref(s.walker, s.ref),
                        "Could not find repository reference", NULL);

        for (; !git_revwalk_next(&oid, s.walker); git_commit_free(commit)) {
                check_lg2(git_commit_lookup(&commit, s.repo, &oid),
                                "Failed to look up commit", NULL);

                int parents = (int)git_commit_parentcount(commit);
                int unmatched = parents;
                if (parents == 0) {
                        git_tree *tree;
                        git_pathspec *ps;
                        check_lg2(git_commit_tree(&tree, commit), "Get tree", NULL);
                        check_lg2(git_pathspec_new(&ps, &diffopts.pathspec),
                                        "Building pathspec", NULL);
                        if (git_pathspec_match_tree(
                                                NULL, tree, GIT_PATHSPEC_NO_MATCH_ERROR, ps) != 0)
                                unmatched = 1;
                        git_pathspec_free(ps);
                        git_tree_free(tree);
                } else {
                        int i;
                        for (i = 0; i < parents; ++i) {
                                if (match_with_parent(commit, i, &diffopts))
                                        unmatched--;
                        }
                }
                if (unmatched > 0)
                        continue;

                print_commit(commit);
                git_commit_free(commit);
                break;
        }
        git_revwalk_reset(s.walker);
        return 0;
}
Beispiel #14
0
static int prepare_index(git_index *index, char* msg){
    git_oid index_tree;
    git_tree *head_obj;
    git_reference *head;
    char tree_str[GIT_OID_HEXSZ+1], parent_str[GIT_OID_HEXSZ+1];

    // Get the head OID
    git_repository_head(&head, repo);
    git_reference_peel((git_object**)&head_obj, head, GIT_OBJ_COMMIT);
    git_oid_tostr(parent_str, GIT_OID_HEXSZ+1,
                   git_tree_id(head_obj));

    git_reference_free(head);
    git_object_free((git_object*)head_obj);

    // Write the coin
    // TODO: Use C for this?
    system("perl -i -pe 's/(null:)(\\d+)/$1 . ($2+1)/e' LEDGER.txt");
    system("grep -q \"null\" LEDGER.txt || echo \"null:1\" >> LEDGER.txt");

    // Update the index
    check_lg2(git_index_read(index, 0),
              "Could not re-read index from disk", NULL);

    check_lg2(git_index_add_bypath(index, "LEDGER.txt"),
              "Could not add to index", "LEDGER.txt");

    // Write the index and get the tree OID
    git_index_write_tree(&index_tree, index);
    git_oid_tostr(tree_str, GIT_OID_HEXSZ+1, &index_tree);

    snprintf(msg, BUFFER_LENGTH,
             "commit %d%c"
             "tree %s\n"
             "parent %s\n"
             "author null           <*****@*****.**> %d +0000\n"
             "committer null           <*****@*****.**> %d +0000\n"
             "\n"
             "coins now"
             "\x01\x01\x01\x01"
             "\x01\x01\x01\x01"
             "\x01\x01\x01", // Align 32 bit words on GPU
             MSG_LENGTH, 0, tree_str, parent_str,
             (int)time(NULL), (int)time(NULL));
    pad_message(msg, COMMIT_LENGTH, BUFFER_LENGTH);

    return 0;
}
Beispiel #15
0
static void action_create_lighweight_tag(tag_state *state)
{
	git_repository *repo = state->repo;
	tag_options *opts = state->opts;
	git_oid oid;
	git_object *target;

	check(!opts->tag_name, "Name required");

	if (!opts->target) opts->target = "HEAD";

	check(!opts->target, "Target required");

	check_lg2(git_revparse_single(&target, repo, opts->target),
			"Unable to resolve spec", opts->target);

	check_lg2(git_tag_create_lightweight(&oid, repo, opts->tag_name,
				target, opts->force), "Unable to create tag", NULL);

	git_object_free(target);
}
Beispiel #16
0
int main (int argc, char** argv)
{
	git_index_matched_path_cb matched_cb = NULL;
	git_repository *repo = NULL;
	git_index *index;
	git_strarray array = {0};
	int options = 0, count = 0;
	struct print_payload payload = {0};

	git_threads_init();

	parse_opts(&options, &count, argc, argv);

	init_array(&array, argc-count, argv+count);

	check_lg2(git_repository_open(&repo, "."), "No git repository", NULL);
	check_lg2(git_repository_index(&index, repo), "Could not open repository index", NULL);

	if (options&VERBOSE || options&SKIP) {
		matched_cb = &print_matched_cb;
	}

	payload.options = options;
	payload.repo = repo;

	if (options&UPDATE) {
		git_index_update_all(index, &array, matched_cb, &payload);
	} else {
		git_index_add_all(index, &array, 0, matched_cb, &payload);
	}

	git_index_write(index);
	git_index_free(index);
	git_repository_free(repo);

	git_threads_shutdown();

	return 0;
}
Beispiel #17
0
static void action_delete_tag(tag_state *state)
{
	tag_options *opts = state->opts;
	git_object *obj;
	git_buf abbrev_oid = {0};

	check(!opts->tag_name, "Name required");

	check_lg2(git_revparse_single(&obj, state->repo, opts->tag_name),
			"Failed to lookup rev", opts->tag_name);

	check_lg2(git_object_short_id(&abbrev_oid, obj),
			"Unable to get abbreviated OID", opts->tag_name);

	check_lg2(git_tag_delete(state->repo, opts->tag_name),
			"Unable to delete tag", opts->tag_name);

	printf("Deleted tag '%s' (was %s)\n", opts->tag_name, abbrev_oid.ptr);

	git_buf_free(&abbrev_oid);
	git_object_free(obj);
}
Beispiel #18
0
static void do_describe_single(git_repository *repo, describe_options *opts, const char *rev)
{
	git_object *commit;
	git_describe_result *describe_result;
	git_buf buf = { 0 };
	
	if (rev) {
		check_lg2(git_revparse_single(&commit, repo, rev),
			"Failed to lookup rev", rev);

		check_lg2(git_describe_commit(&describe_result, commit, &opts->describe_options),
			"Failed to describe rev", rev);
	}
	else
		check_lg2(git_describe_workdir(&describe_result, repo, &opts->describe_options),
			"Failed to describe workdir", NULL);

	check_lg2(git_describe_format(&buf, describe_result, &opts->format_options),
			"Failed to format describe rev", rev);

	printf("%s\n", buf.ptr);
}
Beispiel #19
0
int main (int argc, char **argv)
{
	git_repository *repo;
	git_revwalk *walk;
	git_oid oid;
	char buf[GIT_OID_HEXSZ+1];

	git_libgit2_init();

	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL), "opening repository", NULL);
	check_lg2(git_revwalk_new(&walk, repo), "allocating revwalk", NULL);
	check_lg2(revwalk_parseopts(repo, walk, argc-1, argv+1), "parsing options", NULL);

	while (!git_revwalk_next(&oid, walk)) {
		git_oid_fmt(buf, &oid);
		buf[GIT_OID_HEXSZ] = '\0';
		printf("%s\n", buf);
	}

	git_libgit2_shutdown();
	return 0;
}
Beispiel #20
0
static void action_list_tags(tag_state *state)
{
	const char *pattern = state->opts->pattern;
	git_strarray tag_names = {0};
	size_t i;

	check_lg2(git_tag_list_match(&tag_names, pattern ? pattern : "*", state->repo),
			"Unable to get list of tags", NULL);

	for(i = 0; i < tag_names.count; i++) {
		each_tag(tag_names.strings[i], state);
	}

	git_strarray_free(&tag_names);
}
Beispiel #21
0
/* Helper to find how many files in a commit changed from its nth parent. */
static int match_with_parent(git_commit *commit, int i, git_diff_options *opts)
{
	git_commit *parent;
	git_tree *a, *b;
	git_diff *diff;
	int ndeltas;

	check_lg2(
		git_commit_parent(&parent, commit, (size_t)i), "Get parent", NULL);
	check_lg2(git_commit_tree(&a, parent), "Tree for parent", NULL);
	check_lg2(git_commit_tree(&b, commit), "Tree for commit", NULL);
	check_lg2(
		git_diff_tree_to_tree(&diff, git_commit_owner(commit), a, b, opts),
		"Checking diff between parent and commit", NULL);

	ndeltas = (int)git_diff_num_deltas(diff);

        git_diff_free(diff);
        git_tree_free(a);
        git_tree_free(b);
        git_commit_free(parent);

        return ndeltas > 0;
}
Beispiel #22
0
int main(int argc, char **argv)
{
	git_repository *repo;
	describe_options opts;

	git_libgit2_init();

	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL),
			"Could not open repository", NULL);

	describe_options_init(&opts);
	parse_options(&opts, argc, argv);

	do_describe(repo, &opts);

	git_repository_free(repo);
	git_libgit2_shutdown();

	return 0;
}
Beispiel #23
0
/** Tag listing: Lookup tags based on ref name and dispatch to print */
static int each_tag(const char *name, tag_state *state)
{
	git_repository *repo = state->repo;
	git_object *obj;

	check_lg2(git_revparse_single(&obj, repo, name),
			"Failed to lookup rev", name);

	switch (git_object_type(obj)) {
		case GIT_OBJ_TAG:
			print_tag((git_tag *) obj, state);
			break;
		case GIT_OBJ_COMMIT:
			print_commit((git_commit *) obj, name, state);
			break;
		default:
			print_name(name);
	}

	git_object_free(obj);
	return 0;
}
Beispiel #24
0
/**
 * If the user asked for the branch, let's show the short name of the
 * branch.
 */
static void show_branch(git_repository *repo, int format)
{
	int error = 0;
	const char *branch = NULL;
	git_reference *head = NULL;

	error = git_repository_head(&head, repo);

	if (error == GIT_EUNBORNBRANCH || error == GIT_ENOTFOUND)
		branch = NULL;
	else if (!error) {
		branch = git_reference_shorthand(head);
	} else
		check_lg2(error, "failed to get current branch", NULL);

	if (format == FORMAT_LONG)
		printf("# On branch %s\n",
			branch ? branch : "Not currently on any branch.");
	else
		printf("## %s\n", branch ? branch : "HEAD (no branch)");

	git_reference_free(head);
}
Beispiel #25
0
int main(int argc, char **argv)
{
	git_repository *repo;
	tag_options opts;
	tag_action action;
	tag_state state;

	git_threads_init();

	check_lg2(git_repository_open_ext(&repo, ".", 0, NULL),
			"Could not open repository", NULL);

	tag_options_init(&opts);
	parse_options(&action, &opts, argc, argv);

	state.repo = repo;
	state.opts = &opts;
	action(&state);

	git_repository_free(repo);
	git_threads_shutdown();

	return 0;
}
Beispiel #26
0
/** Entry point for this command */
int main(int argc, char *argv[])
{
	git_repository *repo;
	struct opts o = { ".", NULL, 0, 0 };
	git_object *obj = NULL;
	char oidstr[GIT_OID_HEXSZ + 1];

	git_libgit2_init();

	parse_opts(&o, argc, argv);

	check_lg2(git_repository_open_ext(&repo, o.dir, 0, NULL),
			"Could not open repository", NULL);
	check_lg2(git_revparse_single(&obj, repo, o.rev),
			"Could not resolve", o.rev);

	if (o.verbose) {
		char oidstr[GIT_OID_HEXSZ + 1];
		git_oid_tostr(oidstr, sizeof(oidstr), git_object_id(obj));

		printf("%s %s\n--\n",
			git_object_type2string(git_object_type(obj)), oidstr);
	}

	switch (o.action) {
	case SHOW_TYPE:
		printf("%s\n", git_object_type2string(git_object_type(obj)));
		break;
	case SHOW_SIZE: {
		git_odb *odb;
		git_odb_object *odbobj;

		check_lg2(git_repository_odb(&odb, repo), "Could not open ODB", NULL);
		check_lg2(git_odb_read(&odbobj, odb, git_object_id(obj)),
			"Could not find obj", NULL);

		printf("%ld\n", (long)git_odb_object_size(odbobj));

		git_odb_object_free(odbobj);
		git_odb_free(odb);
		}
		break;
	case SHOW_NONE:
		/* just want return result */
		break;
	case SHOW_PRETTY:

		switch (git_object_type(obj)) {
		case GIT_OBJ_BLOB:
			show_blob((const git_blob *)obj);
			break;
		case GIT_OBJ_COMMIT:
			show_commit((const git_commit *)obj);
			break;
		case GIT_OBJ_TREE:
			show_tree((const git_tree *)obj);
			break;
		case GIT_OBJ_TAG:
			show_tag((const git_tag *)obj);
			break;
		default:
			printf("unknown %s\n", oidstr);
			break;
		}
		break;
	}

	git_object_free(obj);
	git_repository_free(repo);

	git_libgit2_shutdown();

	return 0;
}
Beispiel #27
0
int lg2_diff(git_repository *repo, int argc, char *argv[])
{
	git_tree *t1 = NULL, *t2 = NULL;
	git_diff *diff;
	struct opts o = {
		GIT_DIFF_OPTIONS_INIT, GIT_DIFF_FIND_OPTIONS_INIT,
		-1, 0, 0, GIT_DIFF_FORMAT_PATCH, NULL, NULL, "."
	};

	parse_opts(&o, argc, argv);

	/**
	 * Possible argument patterns:
	 *
	 *  * &lt;sha1&gt; &lt;sha2&gt;
	 *  * &lt;sha1&gt; --cached
	 *  * &lt;sha1&gt;
	 *  * --cached
	 *  * --nocache (don't use index data in diff at all)
	 *  * nothing
	 *
	 * Currently ranged arguments like &lt;sha1&gt;..&lt;sha2&gt; and &lt;sha1&gt;...&lt;sha2&gt;
	 * are not supported in this example
	 */

	if (o.treeish1)
		treeish_to_tree(&t1, repo, o.treeish1);
	if (o.treeish2)
		treeish_to_tree(&t2, repo, o.treeish2);

	if (t1 && t2)
		check_lg2(
			git_diff_tree_to_tree(&diff, repo, t1, t2, &o.diffopts),
			"diff trees", NULL);
	else if (o.cache != CACHE_NORMAL) {
		if (!t1)
			treeish_to_tree(&t1, repo, "HEAD");

		if (o.cache == CACHE_NONE)
			check_lg2(
				git_diff_tree_to_workdir(&diff, repo, t1, &o.diffopts),
				"diff tree to working directory", NULL);
		else
			check_lg2(
				git_diff_tree_to_index(&diff, repo, t1, NULL, &o.diffopts),
				"diff tree to index", NULL);
	}
	else if (t1)
		check_lg2(
			git_diff_tree_to_workdir_with_index(&diff, repo, t1, &o.diffopts),
			"diff tree to working directory", NULL);
	else
		check_lg2(
			git_diff_index_to_workdir(&diff, repo, NULL, &o.diffopts),
			"diff index to working directory", NULL);

	/** Apply rename and copy detection if requested. */

	if ((o.findopts.flags & GIT_DIFF_FIND_ALL) != 0)
		check_lg2(
			git_diff_find_similar(diff, &o.findopts),
			"finding renames and copies", NULL);

	/** Generate simple output using libgit2 display helper. */

	if (!o.output)
		o.output = OUTPUT_DIFF;

	if (o.output != OUTPUT_DIFF)
		diff_print_stats(diff, &o);

	if ((o.output & OUTPUT_DIFF) != 0) {
		if (o.color >= 0)
			fputs(colors[0], stdout);

		check_lg2(
			git_diff_print(diff, o.format, color_printer, &o.color),
			"displaying diff", NULL);

		if (o.color >= 0)
			fputs(colors[0], stdout);
	}

	/** Cleanup before exiting. */
	git_diff_free(diff);
	git_tree_free(t1);
	git_tree_free(t2);

	return 0;
}
Beispiel #28
0
/**
 * Parse options that git's status command supports.
 */
static void parse_opts(struct opts *o, int argc, char *argv[])
{
	struct args_info args = ARGS_INFO_INIT;

	for (args.pos = 1; args.pos < argc; ++args.pos) {
		char *a = argv[args.pos];

		if (a[0] != '-') {
			if (o->npaths < MAX_PATHSPEC)
				o->pathspec[o->npaths++] = a;
			else
				fatal("Example only supports a limited pathspec", NULL);
		}
		else if (!strcmp(a, "-s") || !strcmp(a, "--short"))
			o->format = FORMAT_SHORT;
		else if (!strcmp(a, "--long"))
			o->format = FORMAT_LONG;
		else if (!strcmp(a, "--porcelain"))
			o->format = FORMAT_PORCELAIN;
		else if (!strcmp(a, "-b") || !strcmp(a, "--branch"))
			o->showbranch = 1;
		else if (!strcmp(a, "-z")) {
			o->zterm = 1;
			if (o->format == FORMAT_DEFAULT)
				o->format = FORMAT_PORCELAIN;
		}
		else if (!strcmp(a, "--ignored"))
			o->statusopt.flags |= GIT_STATUS_OPT_INCLUDE_IGNORED;
		else if (!strcmp(a, "-uno") ||
				 !strcmp(a, "--untracked-files=no"))
			o->statusopt.flags &= ~GIT_STATUS_OPT_INCLUDE_UNTRACKED;
		else if (!strcmp(a, "-unormal") ||
				 !strcmp(a, "--untracked-files=normal"))
			o->statusopt.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED;
		else if (!strcmp(a, "-uall") ||
				 !strcmp(a, "--untracked-files=all"))
			o->statusopt.flags |= GIT_STATUS_OPT_INCLUDE_UNTRACKED |
				GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS;
		else if (!strcmp(a, "--ignore-submodules=all"))
			o->statusopt.flags |= GIT_STATUS_OPT_EXCLUDE_SUBMODULES;
		else if (!strncmp(a, "--git-dir=", strlen("--git-dir=")))
			o->repodir = a + strlen("--git-dir=");
		else if (!strcmp(a, "--repeat"))
			o->repeat = 10;
		else if (match_int_arg(&o->repeat, &args, "--repeat", 0))
			/* okay */;
		else if (!strcmp(a, "--list-submodules"))
			o->showsubmod = 1;
		else
			check_lg2(-1, "Unsupported option", a);
	}

	if (o->format == FORMAT_DEFAULT)
		o->format = FORMAT_LONG;
	if (o->format == FORMAT_LONG)
		o->showbranch = 1;
	if (o->npaths > 0) {
		o->statusopt.pathspec.strings = o->pathspec;
		o->statusopt.pathspec.count   = o->npaths;
	}
}