Пример #1
0
int cmd_init(git_repository *dummy, int argc, char **argv)
{
	const char *template_dir = NULL;
	char *git_dir = NULL;
	unsigned int quiet_flag = 0;
	int is_bare_repository_cfg = 0;
	git_repository *repo = NULL;
	int err = GIT_OK;
	int i;
	int rc = EXIT_FAILURE;

	dummy = dummy;

	for (i=1;i<argc;i++)
	{
		if (getarg(argc,argv,&i,"--template",&template_dir)) continue;
		if (!strcmp("--quiet",argv[i]))
		{
			quiet_flag = 1;
		} else if (!strcmp("--bare",argv[i]))
		{
			is_bare_repository_cfg = 1;
		} else if (argv[i][0] == '-')
		{
			fprintf(stderr,"Unknown option \"%s\"\n",argv[i]);
			goto out;
		} else
		{
			if (!git_dir) git_dir = argv[i];
			else
			{
				fprintf(stderr,"Only one directory can be given\n");
				goto out;
			}
		}

	}

	if (!git_dir) git_dir = ".";
	if (template_dir && !*template_dir) template_dir = ".";

	git_repository_init_options init_opts;
	memset(&init_opts,0,sizeof(init_opts));
	init_opts.version = GIT_REPOSITORY_INIT_OPTIONS_VERSION;
	init_opts.template_path = template_dir;
	init_opts.flags = (template_dir?GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE:0)|GIT_REPOSITORY_INIT_NO_REINIT|GIT_REPOSITORY_INIT_MKPATH|((is_bare_repository_cfg)?GIT_REPOSITORY_INIT_BARE:0);

	err = git_repository_init_ext(&repo, git_dir, &init_opts);
	if (err != GIT_OK) goto out;

	if (!quiet_flag)
		printf("Initialized empty Git repository in %s\n", git_repository_path(repo));

	rc = EXIT_SUCCESS;
out:
	if (repo) git_repository_free(repo);
	if (err != GIT_OK)
		libgit_error();
	return rc;
}
Пример #2
0
int cmd_read_tree(int argc, const char **argv)
{
	please_git_do_it_for_me();
	if (argc != 2)
		please_git_do_it_for_me();

	/* Find the current repository */
	repo = get_git_repository();

	/*Find the tree*/
	git_tree *tree;
	git_oid oid_tree;

	switch (git_oid_fromstr(&oid_tree, (const char *)argv[argc-1])) {
		case GIT_ENOTOID:
			please_git_do_it_for_me();
			break;
		case GIT_SUCCESS:
			break;
		default:
			libgit_error();
	}
	
	e = git_tree_lookup(&tree, repo, &oid_tree);
	if (e) {
		if (e == GIT_EINVALIDTYPE || e == GIT_ENOTFOUND) {
			error("Tree object not found");
		} else {
			libgit_error();
		}
	}

	/* Open the index */
	if (git_repository_index(&index_cur, repo) < 0)
		libgit_error();

	/* Clear the index */
	git_index_clear(index_cur);

	/* add objects of the tree to the index */
	add_tree_to_index(tree, "");

	/* write the index */
	git_index_write(index_cur);

	return EXIT_SUCCESS;
}
Пример #3
0
int cmd_write_tree(int argc, const char **argv)
{
	please_git_do_it_for_me();

	int verify_index = 1;
	if (argc == 1)
		verify_index = 1;
	else if (argc == 2 && strcmp(argv[1], "--missing-ok") == 0 )
		verify_index = 0;
	else
		please_git_do_it_for_me();
	

	char sha1buf[GIT_OID_HEXSZ + 1];

	git_repository *repo = get_git_repository();
	git_index *index_cur;
	int e = git_repository_index(&index_cur, repo);
	if(e != GIT_OK)
		libgit_error();

	/* check the index */
	if (verify_index) {
		git_odb * odb;
		git_repository_odb(&odb, repo);
		for (unsigned i = 0; i < git_index_entrycount(index_cur); i++) {
			git_index_entry *gie = git_index_get(index_cur, i);

			if (git_odb_exists(odb, &gie->oid) != 1) {
				printf("error: invalid object %06o %s for '%s'\n", gie->mode, git_oid_tostr(sha1buf, GIT_OID_HEXSZ+1, &gie->oid), gie->path);
				printf("fatal: git-write-tree: error building trees\n");
				return EXIT_FAILURE;
			}
		}
	}
	
	/* create the tree */
	git_oid oid;
	e = git_tree_create_fromindex(&oid, index_cur);
	if(e != GIT_OK)
		libgit_error();

	printf("%s\n", git_oid_tostr(sha1buf, GIT_OID_HEXSZ+1, &oid));

	return EXIT_SUCCESS;
}
Пример #4
0
int cmd_ls_files(git_repository *repo, int argc, char **argv)
{
	int i;
	int rc = EXIT_FAILURE;
	int show_cached = 1;
	int err = 0;
	char *file = NULL;
	char buf[GIT_OID_HEXSZ+1];
	git_index *idx = NULL;

	for (i=1;i<argc;i++)
	{
		if (strcmp(argv[i], "--stage") == 0 || strcmp(argv[i], "-s") == 0) show_cached = 0;
		else if (strcmp(argv[i], "--cached") == 0 || strcmp(argv[i], "-c") == 0) show_cached = 1;
		else if (argv[i][0] == '-')
		{
			fprintf(stderr,"Unknown option %s!\n",argv[i]);
			goto out;
		} else
		{
			file = argv[i];
		}
	}

	if (!file) file = "*";

	if ((err = git_repository_index(&idx, repo)) != GIT_OK)
		goto out;

	const char *prefix = "";
	size_t prefix_len = strlen(prefix);

	for (unsigned i = 0; i < git_index_entrycount(idx); i++)
	{
		const git_index_entry *gie = git_index_get_byindex(idx, i);

		if (prefixcmp(gie->path, prefix))
			continue;

		if (pathspeccmp(gie->path,file))
			continue;

		if (!show_cached)
			printf("%06o %s %i\t", gie->mode, git_oid_tostr(buf, GIT_OID_HEXSZ+1, &gie->id), git_index_entry_stage(gie));

		write_name_quoted(gie->path + prefix_len, stdout, '\n');
	}

	rc = EXIT_SUCCESS;
out:
	if (err) libgit_error();

	if (idx) git_index_free(idx);

	return rc;
}
Пример #5
0
git_repository* get_git_repository() {
	if (repository == NULL) {
		char discovered_path[PATH_MAX];
		char *repository_path = getenv(GIT_DIR_ENVIRONMENT);

		if (repository_path == NULL) {
			if (git_repository_discover(discovered_path, sizeof(discovered_path), "", 0, getenv(GIT_CEILING_DIRECTORIES_ENVIRONMENT)) < GIT_OK) {
				libgit_error();
			}

			repository_path = discovered_path;
		}

		if (git_repository_open(&repository, repository_path) < GIT_OK) {
			libgit_error();
		}
	}

	return repository;
}
Пример #6
0
int cmd_reset(git_repository *repo, int argc, char **argv)
{
	int err = GIT_OK;
	int rc = EXIT_FAILURE;

	const char *spec;
	git_object *treeobj = NULL;

	int mode = -1;
	int spec_pos;

	if (argc < 3)
	{
		fprintf (stderr, "USAGE: %s <treeish> <paths>\n", argv[0]);
		fprintf (stderr, "USAGE: %s [--soft|--mixed|--hard] <commit>\n", argv[0]);
		return -1;
	}

	if (!strcmp("--soft", argv[1])) mode = GIT_RESET_SOFT;
	else if (!strcmp("--mixed", argv[1])) mode = GIT_RESET_MIXED;
	else if (!strcmp("--hard", argv[1])) mode = GIT_RESET_HARD;

	if (mode != -1) spec_pos = 2;
	else spec_pos = 1;

	spec = argv[spec_pos];

	if ((err = git_revparse_single(&treeobj, repo, spec)))
		goto out;

	if (mode == -1)
	{
		git_strarray strarray;

		strarray.count = argc-1-spec_pos;
		strarray.strings = argv+1+spec_pos;

		if ((err = git_reset_default(repo, treeobj, &strarray)))
			goto out;
	} else
	{
		if ((err = git_reset(repo, treeobj, mode, NULL, NULL, NULL)))
			goto out;
	}
out:
	if (treeobj) git_object_free(treeobj);

	if (err != GIT_OK)
		libgit_error();
	return rc;
}
Пример #7
0
int cmd_log(git_repository *repo, int argc, char **argv)
{
	int err = 0;
	int rc;
	git_revwalk *walk;
	git_oid oid;
	git_reference *revision_ref = NULL;
	git_object *revision_obj = NULL;

	rc = EXIT_FAILURE;

	git_revwalk_new(&walk,repo);
	if (argc > 1)
	{
		if ((err = git_reference_dwim(&revision_ref, repo, argv[1])))
			goto out;

		if ((err = git_reference_peel(&revision_obj, revision_ref, GIT_OBJ_ANY)))
			goto out;

		if ((err = git_revwalk_push(walk, git_object_id(revision_obj))))
			goto out;
	} else
	{
		git_revwalk_push_head(walk);
	}

	while ((git_revwalk_next(&oid, walk)) == 0)
	{
		struct git_commit *wcommit;

		if (git_commit_lookup(&wcommit, repo, &oid) != 0)
			continue;

		print_commit(wcommit,"commit %C\nAuthor: %a\nDate:   %d\n\n%m\n");

		git_commit_free(wcommit);
	}

	git_revwalk_free(walk);

	rc = EXIT_SUCCESS;
out:
	if (err != GIT_OK)
		libgit_error();
	if (revision_obj) git_object_free(revision_obj);
	if (revision_ref) git_reference_free(revision_ref);
	return rc;
}
Пример #8
0
int cmd_ls_files(int argc, const char **argv)
{
	/* Delete the following line once git tests pass */
	please_git_do_it_for_me();

	int show_cached = 1;

	/* options parsing */
	if (argc > 1) {
		if (argc > 2)
			please_git_do_it_for_me();

		if (strcmp(argv[1], "--stage") == 0 || strcmp(argv[1], "-s") == 0)
			show_cached = 0;
		else if (strcmp(argv[1], "--cached") == 0 || strcmp(argv[1], "-c") == 0)
			show_cached = 1;
		else
			please_git_do_it_for_me();
	}


	git_repository *repo = get_git_repository();

	git_index *index_cur;
	int e = git_repository_index(&index_cur, repo);
	if (e) libgit_error();

	char buf[GIT_OID_HEXSZ+1];

	const char *prefix = get_git_prefix();
	size_t prefix_len = strlen(prefix);

	for (unsigned i = 0; i < git_index_entrycount(index_cur); i++) {
		git_index_entry *gie = git_index_get(index_cur, i);

		if (prefixcmp(gie->path, prefix))
			continue;

		if (!show_cached)
			printf("%06o %s %i\t", gie->mode, git_oid_tostr(buf, GIT_OID_HEXSZ+1, &gie->oid), git_index_entry_stage(gie));

		write_name_quoted(gie->path + prefix_len, stdout, '\n');
	}

	git_index_free(index_cur);

	return EXIT_SUCCESS;
}
Пример #9
0
void add_tree_to_index(git_tree * tree, const char * prefix) {
	for (size_t i = 0; i < git_tree_entrycount(tree); i++) {
		/* Get the tree entry */
		const git_tree_entry *tree_entry;
		tree_entry = git_tree_entry_byindex(tree,(unsigned int)i);
		
		if (tree_entry == NULL) {
			printf("Tree entry not found");
			libgit_error();
		}

		/* Get the oid of a tree entry */
		const git_oid *entry_oid = git_tree_entry_id (tree_entry);

		/* is a sub directory ? */
		git_tree * subtree;
		if (git_tree_lookup(&subtree, repo, entry_oid) == 0) {
			char * subprefix = xmalloc(sizeof(char)*1024);
			const char * dirname = git_tree_entry_name (tree_entry);
			git2__joinpath(subprefix, prefix, dirname);
			add_tree_to_index(subtree, subprefix);
			continue;
		}
		
		char * completename = xmalloc(sizeof(char)*1024);
		git2__joinpath(completename, prefix, git_tree_entry_name (tree_entry));
		git_index_entry source_entry = {
			{0,0},//git_index_time 	ctime
			{0,0},//git_index_time 	mtime
			0,//unsigned int 	dev
			0,//unsigned int 	ino
			git_tree_entry_attributes(tree_entry),//unsigned int 	mode
			0,//unsigned int 	uid
			0,//unsigned int 	gid
			0,//git_off_t 	file_size
			*entry_oid,
			0,
			0,//unsigned short 	flags_extended
			completename
		};
		
		
		git_index_append2(index_cur, &source_entry);
		
	}
}
Пример #10
0
/** Entry point for this command */
int fetch(git_repository *repo, int argc, char **argv)
{
	int err = GIT_OK;
	int rc = EXIT_FAILURE;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

	const git_transfer_progress *stats;
	git_remote *remote = NULL;

	if (argc < 2) {
		fprintf(stderr, "usage: %s fetch <repo>\n", argv[-1]);
		return EXIT_FAILURE;
	}

	// Figure out whether it's a named remote or a URL
	printf("Fetching %s for repo at %s\n", argv[1], git_repository_path(repo));
	if (git_remote_lookup(&remote, repo, argv[1]) < 0) {
		if ((err = git_remote_create_anonymous(&remote, repo, argv[1], NULL)) < 0)
			goto out;
	}

	// Set up the callbacks (only update_tips for now)
	callbacks.update_tips = &update_cb;
	callbacks.sideband_progress = &progress_cb;
	callbacks.credentials = cred_acquire_cb;
	callbacks.certificate_check = certificate_check;
	git_remote_set_callbacks(remote, &callbacks);

	stats = git_remote_stats(remote);

	if ((err = git_remote_connect(remote, GIT_DIRECTION_FETCH) < 0))
		goto out;

	// Download the packfile and index it. This function updates the
	// amount of received data and the indexer stats which lets you
	// inform the user about progress.
	if ((err = git_remote_download(remote, NULL) < 0))
		goto out;

	/**
	 * If there are local objects (we got a thin pack), then tell
	 * the user how many objects we saved from having to cross the
	 * network.
	 */
	if (stats->local_objects > 0) {
		printf("\rReceived %d/%d objects in %zu bytes (used %d local objects)\n",
		       stats->indexed_objects, stats->total_objects, stats->received_bytes, stats->local_objects);
	} else{
		printf("\rReceived %d/%d objects in %zu bytes\n",
			stats->indexed_objects, stats->total_objects, stats->received_bytes);
	}

	// Disconnect the underlying connection to prevent from idling.
	git_remote_disconnect(remote);

	// Update the references in the remote's namespace to point to the
	// right commits. This may be needed even if there was no packfile
	// to download, which can happen e.g. when the branches have been
	// changed but all the needed objects are available locally.
	if ((err = git_remote_update_tips(remote, NULL, NULL)) < 0)
		goto out;

	rc = EXIT_SUCCESS;
out:
	if (err != GIT_OK)
		libgit_error();
	if (remote) git_remote_free(remote);
	return rc;
}
Пример #11
0
int cmd_checkout(git_repository *repo, int argc, char **argv)
{
	int i, err, rc;
	char *branch;
	git_reference *branch_ref;
	git_checkout_options checkout_opts;

	branch = NULL;
	rc = EXIT_FAILURE;

	for (i=1;i<argc;i++)
	{
		if (argv[i][0] != '-')
		{
			if (!branch) branch = argv[i];
		} else
		{
		}
	}

	if (!branch)
	{
		fprintf (stderr, "USAGE: %s <branch>\n", argv[0]);
		return -1;
	}

	/* Try local branch */
	if (git_branch_lookup(&branch_ref,repo,branch,GIT_BRANCH_LOCAL) != 0)
	{
		/* No, try remote branch */
		git_reference *remote_branch_ref;
		char remote_buf[256];
		snprintf(remote_buf,sizeof(remote_buf),"%s/%s","origin",branch);
		if (git_branch_lookup(&remote_branch_ref, repo, remote_buf, GIT_BRANCH_REMOTE) == 0)
		{
			/* Exists, now try to create a local one from that reference */
			if ((err = git2_create_branch_from_ref(&branch_ref,remote_branch_ref,repo,branch)) != 0)
			{
				fprintf(stderr,"Error code %d\n",err);
				libgit_error();
				goto out;
			}
			git_reference_free(remote_branch_ref);
		} else
		{
			branch_ref = NULL;
		}
	}

	printf("Checking out %s\n",branch_ref?git_reference_name(branch_ref):branch);
	if ((err = git_repository_set_head(repo,branch_ref?git_reference_name(branch_ref):branch)) != 0)
	{
		fprintf(stderr,"Error code %d\n",err);
		libgit_error();
		goto out;
	}

	/* Default options. Note by default we perform a dry checkout */
	memset(&checkout_opts,0,sizeof(checkout_opts));
	checkout_opts.version = GIT_CHECKOUT_OPTIONS_VERSION;
	checkout_opts.notify_cb = notify_cb;

	checkout_opts.checkout_strategy = GIT_CHECKOUT_FORCE|GIT_CHECKOUT_REMOVE_UNTRACKED;//GIT_CHECKOUT_SAFE|GIT_CHECKOUT_UPDATE_UNTRACKED;
	if (git_checkout_head(repo,&checkout_opts) != 0)
	{
		libgit_error();
		goto out;
	}

	rc = EXIT_SUCCESS;
out:
	if (branch_ref)
		git_reference_free(branch_ref);

	return rc;
}
Пример #12
0
int cmd_push(git_repository *repo, int argc, char **argv)
{
	int err = GIT_OK;
	int i;
	int rc = EXIT_FAILURE;
	git_strarray refs = {NULL, 0};
	git_push_options push_options = GIT_PUSH_OPTIONS_INIT;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
	char *ref_fullname = NULL;

	git_remote *r = NULL;

	for (i=1;i<argc;i++)
	{
		if (argv[i][0] == '-')
		{
			fprintf(stderr,"Unknown option \"%s\"\n",argv[i]);
			goto out;
		}

		if (r)
		{
			git_reference *ref;

			if (refs.count) {
				fprintf(stderr, "USAGE: %s <remote> <refspec>\n", argv[0]);
				goto out;
			}

			if (!git_reference_dwim(&ref, repo, argv[i]))
			{
				ref_fullname = strdup(git_reference_name(ref));
				refs.strings = &ref_fullname;
				git_reference_free(ref);
			} else
			{
				refs.strings = &argv[i];
			}
			refs.count = 1;
		} else
		{
			if ((err = git_remote_lookup(&r,repo,argv[i])) != GIT_OK)
				goto out;
		}
	}

	if (!r)
	{
		fprintf(stderr,"No remote given!\n");
		goto out;
	}

	if (refs.count == 0)
	{
		git_strarray cfg_refs;

		if ((err = git_remote_get_push_refspecs(&cfg_refs, r)))
			goto out;

		if (!cfg_refs.count)
		{
			fprintf(stderr, "No refspec given and no refspec configured. "
					"Pushing is probably a noop.\n");
		}
		git_strarray_free(&cfg_refs);
	}
	callbacks.credentials = cred_acquire_cb;
	callbacks.push_update_reference = push_update_reference_callback;
	callbacks.certificate_check = certificate_check;
	push_options.callbacks = callbacks;

	if ((err = git_remote_push(r, &refs, &push_options)))
		goto out;

out:
	if (err != GIT_OK)
		libgit_error();
	free(ref_fullname);
	if (r) git_remote_free(r);
	return rc;
}
Пример #13
0
int cmd_cat_file(int argc, const char **argv)
{
	/* Uncomment when it passes the tests */
	please_git_do_it_for_me();

	char opt;
	if (argc != 2 && argc !=3) 
		please_git_do_it_for_me();

	if (argc == 3){
		if ((strcmp(argv[1], "blob") == 0) || (strcmp(argv[1], "tree") == 0) || (strcmp(argv[1], "commit") == 0) || (strcmp(argv[1], "tag") == 0 ))
			opt = '0';
		else
			opt = argv[1][1];
	}
	else if (argc == 2 && (strcmp(argv[1], "--batch") == 0))
		opt = 'a';
	

	
	git_repository *repo = get_git_repository();

	git_oid oid;
	if (git_oid_fromstr(&oid, (const char *)argv[argc-1]))
		please_git_do_it_for_me();

	git_odb *odb;
	git_repository_odb(&odb, repo);
	git_odb_object *odb_object;
	if(git_odb_read(&odb_object, odb, &oid) == GIT_ENOTFOUND)
		libgit_error();

	size_t size = git_odb_object_size(odb_object);
	git_otype type = git_odb_object_type(odb_object);

	const char *type_string = git_object_type2string(type);

	switch (opt) {
		case 'p':
			if (strcmp(type_string, "tree") == 0) {
				printf("vous etes là\n");

 				char ** arg = malloc(2);
 				strcpy(arg[0], "ls-tree");
 				strcpy(arg[1], argv[2]);
 				int e = cmd_ls_tree(2, (const char **)arg);
 				if (e == 0 )
 					printf("succes\n");
 				else
 					printf("echec\n");
			}
			else {
				for(int i=0; i < (int)size; i++)
					printf("%c", *((char *)git_odb_object_data(odb_object)+i));
			}
			break;
		case 't':
			printf("%s\n",type_string);
			break;
		case 's':
			printf("%zu\n",size);
			break;
		case 'e':
			if(git_odb_exists(odb, &oid) == 1) {
				return 0;
			}
			break;
		case '0' :
			if (strcmp(type_string, argv[1]) == 0) {
				for (int i=0; i < (int)size; i++)
					printf("%c", *((char *)git_odb_object_data(odb_object)+i));
			}
 			else
 				please_git_do_it_for_me();
			break;
		case 'a' :
			please_git_do_it_for_me();
// 			if (strbuf_read(&buf, 0, 4096) < 0)
// 				die_errno("could not read from stdin");
// 
// 			git_oid id;
// 			if (git_oid_mkstr(&id, buf.buf))
// 				please_git_do_it_for_me();
// 
// 			git_odb_object *odb_object1;
// 			if(git_odb_read(&odb_object1, odb, &id) == GIT_ENOTFOUND)
// 				libgit_error();
// 			size_t size1 = git_odb_object_size(odb_object1);
// 			git_otype type1 = git_odb_object_type(odb_object1);
// 
// 			printf("bla bla %s %s %zu\n",buf.buf, git_object_type2string(type1), size1);
// 			for(int i=0; i < (int)size1; i++)
// 				printf("%c", *((char *)git_odb_object_data(odb_object1)+i));
// 			fflush(stdout);
			break;
	}
	//git_odb_object_close(odb_object);
	return EXIT_SUCCESS;
}
Пример #14
0
int cmd_checkout(int argc, const char **argv) 
{
	/* Delete the following line once gits tests pass
	please_git_do_it_for_me();

	if (argc != 1)
		please_git_do_it_for_me();
	*/
	git_index *index;
	git_repository *repo;
	git_index_entry *index_entry;
	git_oid id;
	
	 /* Open the repository */
	if (git_repository_open(&repo, ".git")) {
		libgit_error();
	}

	/* Get the Index file of a Git repository */
	if (git_repository_index(&index,repo)) {
		libgit_error();
	}
	
	/* Find the first index of any entries which point to given path in the Git index */
	if (git_index_find (index, ".git")) {
		libgit_error();
	}

	int i = 0;

	/* get a pointer to one of the entries in the index */
	index_entry = git_index_get(index, i);
	if (index_entry == NULL)
		printf("Out of bound");
	else
		id = index_entry->oid;
	(void)id;
	
	git_reference *symbolic_ref;
	if (git_reference_lookup(&symbolic_ref, repo, "HEAD"))
		libgit_error();

	git_reference *direct_ref;
	if (git_reference_resolve(&direct_ref, symbolic_ref))
		libgit_error();

	const git_oid *oid;
	oid = git_reference_oid(direct_ref);
	if (oid == NULL) {
		printf("Internal error: reference is not direct\n");
		return EXIT_FAILURE;
	}
	
	git_tree *tree;
	/* Lookup a tree object from the repository */
	if (git_tree_lookup(&tree, repo, oid))
		libgit_error();
	
	/* Update the index ?? */
	if (git_index_read(index))
		libgit_error();
	
	git_index_free(index);
	git_tree_close(tree);
	
	return EXIT_SUCCESS;
}
Пример #15
0
int cmd_rev_list(git_repository *repo, int argc, char **argv)
{
	const char *commit_string = NULL;
	const char *format = NULL;
	int i = 0;
	git_oid commit_oid;
	git_oid current_oid;
	char current_oid_str[GIT_OID_HEXSZ+1];
	int err = 0;
	int rc = EXIT_FAILURE;
	git_commit *commit;
	git_revwalk *walk;

	for (i = 1; i < argc; i++)
	{
		if (*argv[i] == '-')
		{
			if (!prefixcmp(argv[i], "--pretty="))
			{
				format = argv[i] + strlen("--pretty=");
			} else
			{
				fprintf(stderr,"Unknown option \"%s\"\n",argv[i]);
				goto out;
			}
		} else
		{
			commit_string = argv[i];
		}
	}

	if (!commit_string)
	{
		fprintf(stderr,"No commit id given!\n");
		goto out;
	}

	if (format)
	{
		fprintf(stderr,"Format \"%s\" not supported!\n",format);
		goto out;
	}

	if ((err = git_oid_fromstrn(&commit_oid,commit_string,strlen(commit_string))) != GIT_OK)
		goto out;

	if ((err = git_commit_lookup_prefix(&commit,repo,&commit_oid,strlen(commit_string))) != GIT_OK)
		goto out;

	if ((err = git_revwalk_new(&walk, repo)) != GIT_OK)
		goto out;

	git_revwalk_sorting(walk, GIT_SORT_TIME);

	if ((err = git_revwalk_push(walk, &commit_oid)) != GIT_OK)
		goto out;

	while ((git_revwalk_next(&current_oid, walk)) == GIT_OK)
	{
		struct git_commit *wcommit;

		if (git_commit_lookup(&wcommit, repo, &current_oid) != 0)
			continue;

		git_oid_tostr(current_oid_str,sizeof(current_oid_str),&current_oid);
		printf("%s\n",current_oid_str);
		git_commit_free(wcommit);
	}

	git_revwalk_free(walk);
out:
	if (err) libgit_error();
	if (commit) git_commit_free(commit);
	return rc;
}
Пример #16
0
int cmd_rev_list(int argc, const char **argv)
{
    /* Doesn't pass the tests due to bug in libgit2 apparently */
    please_git_do_it_for_me();

    const char *commit_string = NULL;
    const char *format = NULL;
    int i = 0;
    git_repository *repository=NULL;
    git_oid commit_oid;
    git_oid current_oid;
    char commit_oid_string[GIT_OID_HEXSZ+1];
    size_t len;
    int e;

    /* For now, we only implement --format=oneline */
    if (argc != 3) {
        please_git_do_it_for_me();
    }

    for (i = 1; i < 3; ++i) {
        if (*argv[i] == '-') {
            if (!prefixcmp(argv[i], "--pretty=")) {
                format = argv[i] + strlen("--pretty=");
            }
        } else {
            commit_string = argv[i];
        }
    }

    if (!commit_string) {
        /* Show usage : ask git for now */
        please_git_do_it_for_me();
    }
    if (!format) {
        /* No option or not handled option */
        please_git_do_it_for_me();
    }
    if (strcmp(format, "oneline")) {
        /* Format not supported for now */
        please_git_do_it_for_me();
    }

    /* Supported object specifications are full or short oid */
    /* Create the partial oid (filled with '0's) from the given argument */
    len = strlen(commit_string);
    if (len > GIT_OID_HEXSZ) {
        /* It's not a sha1 */
        please_git_do_it_for_me();
    }
    memcpy(commit_oid_string, commit_string, len * sizeof(char));
    memset(commit_oid_string + len, '0', (GIT_OID_HEXSZ - len) * sizeof(char));
    commit_oid_string[GIT_OID_HEXSZ] = '\0';
    e = git_oid_fromstr(&commit_oid, commit_oid_string);
    if (e) {
        /* Not an OID. The object can be specified in a lot
         * of different ways (not supported by libgit2 yet).
         * Fall back to git.
         */
        please_git_do_it_for_me();
    }

    repository = get_git_repository();

    /* Lookup the commit object */
    e = git_object_lookup_prefix((git_object **)&commit, repository, &commit_oid, len, GIT_OBJ_ANY);
    if (e != GIT_OK) {
        if (e == GIT_ENOTFOUND) {
            /* Maybe the given argument is not a sha1
             * but a tag name (which looks like a sha1)
             * Fall back to git.
             */
            please_git_do_it_for_me();
        } else if (e == GIT_EAMBIGUOUS) {
            error("%s is an ambiguous prefix", commit_string);
        } else {
            libgit_error();
        }
    }
    if (git_object_type((git_object *)commit) != GIT_OBJ_COMMIT) {
        /* Not a commit : nothing to do */
        cleanup();

        return EXIT_SUCCESS;
    }

    if (git_revwalk_new(&walk, repository)) {
        cleanup();
        libgit_error();
    }

    git_revwalk_sorting(walk, GIT_SORT_TIME);

    if (git_revwalk_push(walk, &commit_oid)) {
        cleanup();
        libgit_error();
    }

    git_commit_close(commit);
    if ((git_revwalk_next(&current_oid, walk)) == GIT_OK) {
        char oid_string[GIT_OID_HEXSZ+1];
        oid_string[GIT_OID_HEXSZ] = '\0';
        const char *cmsg;

        while (1) {
            git_oid_fmt(oid_string, &current_oid);
            if (git_commit_lookup(&commit, repository, &current_oid)) {
                libgit_error();
            }

            cmsg  = git_commit_message(commit);

            git_oid_fmt(oid_string, git_commit_id(commit));
            printf("%s %s\n", oid_string, cmsg);

            if ((git_revwalk_next(&current_oid, walk)) != GIT_OK)
                break;
            git_commit_close(commit);
        }
    }

    cleanup();

    return EXIT_SUCCESS;
}
Пример #17
0
int cmd_config(git_repository *repo, int argc, char **argv)
{
	int rc = EXIT_FAILURE;
	int err = 0;

	git_config *config = NULL;

	struct cli cli = {0};

	if (!parse_cli(argc, argv, &cli, POF_VALIDATE))
	{
		return GIT_ERROR;
	}

	if (usage_cli(argv[0], &cli))
	{
		return GIT_OK;
	}

	if (repo && !cli.global)
	{
		if (!cli.value)
		{
			if ((err = git_repository_config_snapshot(&config,repo)) != GIT_OK)
				goto out;
		} else
		{
			if ((err = git_repository_config(&config,repo)) != GIT_OK)
				goto out;
		}
	} else
	{
#ifdef __amigaos4__
		FILE *f = fopen("ENVARC:gitconfig", "rb");
		if (!f)
		{
			if ((f = fopen("ENVARC:gitconfig", "wb")))
			{
				fprintf(stderr, "Created global config in ENVARC:gitconfig\n");
			} else
			{
				fprintf(stderr, "Unable to create ENVARC:gitconfig\n");
			}
		}
		if (f)
		{
			fclose(f);
		}
#endif
		if ((err = git_config_open_default(&config)))
			goto out;

		if (!cli.value)
		{
			git_config *snapshot;

			if ((err = git_config_snapshot(&snapshot, config)))
				goto out;

			git_config_free(config);
			config = snapshot;
		}
	}

	if (!cli.name)
	{
		fprintf(stderr,"Invalid or not supported command line format!\n");
		goto out;
	}

	if (cli.value)
	{
		if ((err = git_config_set_string(config, cli.name, cli.value)))
			goto out;
	} else
	{
		const char *val;

		if ((err = git_config_get_string(&val, config, cli.name)) != GIT_OK)
			goto out;
		printf("%s\n",val);
	}

	rc = EXIT_SUCCESS;
out:
	if (err) libgit_error();
	if (config) git_config_free(config);

	return rc;
}
Пример #18
0
int cmd_rebase(git_repository *repo, int argc, char **argv)
{
	int err = GIT_OK;
	int rc = EXIT_FAILURE;

	git_signature *sig = NULL;

	const char *upstream_str;
	git_reference *upstream_ref = NULL;
	git_annotated_commit *upstream = NULL;

	git_reference *branch_ref = NULL;
	git_annotated_commit *branch = NULL;

	git_rebase *rebase = NULL;

	int abort = 0;
	int cont = 0;

	if (argc < 2)
	{
		fprintf(stderr, "USAGE: %s <upstream>\n", argv[0]);
		fprintf(stderr, "USAGE: %s --abort|--continue\n", argv[0]);
		goto out;
	}

	upstream_str = argv[1];
	if (!strcmp(upstream_str, "--abort")) abort = 1;
	else if (!strcmp(upstream_str, "--continue")) cont = 1;

	if ((err = sgit_get_author_signature(repo, &sig)))
		goto out;

	if (abort)
	{
		if ((err = git_rebase_open(&rebase, repo)))
			goto out;

		if ((err = git_rebase_abort(rebase, sig)))
			goto out;
	} else
	{
		git_rebase_operation *oper;
		git_checkout_options checkout_opts = GIT_CHECKOUT_OPTIONS_INIT;
		git_rebase_options rebase_opts = GIT_REBASE_OPTIONS_INIT;

		checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;

		if (cont)
		{
			if ((err = git_rebase_open(&rebase, repo)))
				goto out;
		} else
		{
			if ((err = git_reference_dwim(&upstream_ref, repo, upstream_str)))
				goto out;
			if ((err = git_annotated_commit_from_ref(&upstream, repo, upstream_ref)))
				goto out;

			if ((err = git_repository_head(&branch_ref,repo)) < 0)
				goto out;
			if ((err = git_annotated_commit_from_ref(&branch, repo, branch_ref)))
				goto out;

			if ((err = git_rebase_init(&rebase, repo, branch, upstream, NULL, NULL, NULL)))
				goto out;
		}

		while (!(err = git_rebase_next(&oper, rebase, &checkout_opts)))
		{
			git_oid oid;
			if ((err = git_rebase_commit(&oid, rebase, NULL, sig, NULL, NULL)))
				goto out;
		}

		if (err != GIT_ITEROVER && err != GIT_OK)
			goto out;

		if ((err = git_rebase_finish(rebase, sig, &rebase_opts)))
			goto out;
	}
out:
	if (err != GIT_OK)
		libgit_error();
	if (rebase) git_rebase_free(rebase);
	if (upstream) git_annotated_commit_free(upstream);
	if (upstream_ref) git_reference_free(upstream_ref);

	if (branch) git_annotated_commit_free(branch);
	if (branch_ref) git_reference_free(branch_ref);
	if (sig) git_signature_free(sig);
	return rc;
}