Esempio n. 1
0
int luagi_reference_create_matching( lua_State *L )
{
    git_repository **repo = checkrepo( L, 1 );
   const char *name = luaL_checkstring( L, 2 );
   if( git_reference_is_valid_name( name ) == 0 )
   {
      luaL_error( L, "invalid name" );
      return 0;
   }
   git_oid oid;
   if( luagi_check_oid( &oid, L, 3 ) )
   {
      ltk_error_abort( L );
   }
   git_oid curr_oid;
   if( luagi_check_oid( &curr_oid, L, 4 ) )
   {
      ltk_error_abort( L );
   }

   const char *log_message = luaL_checkstring( L, 6 );
   int force = lua_toboolean( L, 7 );

   git_reference **out = lua_newuserdata( L, sizeof( git_reference *) );
   if( git_reference_create_matching( out, *repo, name, &oid, force, &curr_oid, log_message ) )
   {
      return ltk_push_git_error( L );
   }
   ltk_setmetatable( L, LUAGI_REFERENCE_FUNCS );
   return 1;
}
Esempio n. 2
0
int git_reference_create(
	git_reference **ref_out,
	git_repository *repo,
	const char *name,
	const git_oid *id,
	int force,
	const char *log_message)
{
        return git_reference_create_matching(ref_out, repo, name, id, force, NULL, log_message);
}
Esempio n. 3
0
int git_rebase_finish(
	git_rebase *rebase,
	const git_signature *signature,
	const git_rebase_options *given_opts)
{
	git_rebase_options opts;
	git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL;
	git_commit *terminal_commit = NULL;
	git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT;
	char onto[GIT_OID_HEXSZ];
	int error;

	assert(rebase);

	GITERR_CHECK_VERSION(given_opts, GIT_REBASE_OPTIONS_VERSION, "git_rebase_options");

	if ((error = rebase_normalize_opts(rebase->repo, &opts, given_opts)) < 0)
		goto done;

	git_oid_fmt(onto, &rebase->onto_id);

	if ((error = git_buf_printf(&branch_msg, "rebase finished: %s onto %.*s",
			rebase->orig_head_name, GIT_OID_HEXSZ, onto)) < 0 ||
		(error = git_buf_printf(&head_msg, "rebase finished: returning to %s",
			rebase->orig_head_name)) < 0 ||
		(error = git_repository_head(&terminal_ref, rebase->repo)) < 0 ||
		(error = git_reference_peel((git_object **)&terminal_commit,
			terminal_ref, GIT_OBJ_COMMIT)) < 0 ||
		(error = git_reference_create_matching(&branch_ref,
			rebase->repo, rebase->orig_head_name, git_commit_id(terminal_commit), 1,
			&rebase->orig_head_id, branch_msg.ptr)) < 0 ||
		(error = git_reference_symbolic_create(&head_ref,
			rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
			head_msg.ptr)) < 0 ||
		(error = rebase_copy_notes(rebase, signature, &opts)) < 0)
		goto done;

	error = rebase_cleanup(rebase);

done:
	git_buf_free(&head_msg);
	git_buf_free(&branch_msg);
	git_commit_free(terminal_commit);
	git_reference_free(head_ref);
	git_reference_free(branch_ref);
	git_reference_free(terminal_ref);
	rebase_opts_free(&opts);

	return error;
}
Esempio n. 4
0
int git_reference_set_target(
	git_reference **out,
	git_reference *ref,
	const git_oid *id,
	const char *log_message)
{
	int error;
	git_repository *repo;

	assert(out && ref && id);

	repo = ref->db->repo;

	if ((error = ensure_is_an_updatable_direct_reference(ref)) < 0)
		return error;

	return git_reference_create_matching(out, repo, ref->name, id, 1, &ref->target.oid, log_message);
}
Esempio n. 5
0
static int return_to_orig_head(git_rebase *rebase)
{
	git_reference *terminal_ref = NULL, *branch_ref = NULL, *head_ref = NULL;
	git_commit *terminal_commit = NULL;
	git_buf branch_msg = GIT_BUF_INIT, head_msg = GIT_BUF_INIT;
	char onto[GIT_OID_HEXSZ];
	int error = 0;

	git_oid_fmt(onto, &rebase->onto_id);

	if ((error = git_buf_printf(&branch_msg,
			"rebase finished: %s onto %.*s",
			rebase->orig_head_name, GIT_OID_HEXSZ, onto)) == 0 &&
		(error = git_buf_printf(&head_msg,
			"rebase finished: returning to %s",
			rebase->orig_head_name)) == 0 &&
		(error = git_repository_head(&terminal_ref, rebase->repo)) == 0 &&
		(error = git_reference_peel((git_object **)&terminal_commit,
			terminal_ref, GIT_OBJ_COMMIT)) == 0 &&
		(error = git_reference_create_matching(&branch_ref,
			rebase->repo, rebase->orig_head_name,
			git_commit_id(terminal_commit), 1,
			&rebase->orig_head_id, branch_msg.ptr)) == 0)
		error = git_reference_symbolic_create(&head_ref,
			rebase->repo, GIT_HEAD_FILE, rebase->orig_head_name, 1,
			head_msg.ptr);

	git_buf_free(&head_msg);
	git_buf_free(&branch_msg);
	git_commit_free(terminal_commit);
	git_reference_free(head_ref);
	git_reference_free(branch_ref);
	git_reference_free(terminal_ref);

	return error;
}
Esempio n. 6
0
File: merge.c Progetto: mikeando/agb
void test_core_merge__demo_create_merge_commit(void) {

	AGBError * error;
	agb_error_new(&error);


	// Here we're going to try to use the merge iterator to create a merge commit that contains the right information.
	// Note - this version does not recurse into directories. (subtrees)
	git_treebuilder * builder;
	git_treebuilder_create(&builder, base_tree);
	AGBMergeIterator * it = agb_merge__create_iterator(head_tree, branch_tree, base_tree, agb_merge_iterator_options_NONE);

	for( ; agb_merge_iterator_is_valid(it) ; agb_merge_iterator_next(it) ) {
        AGBMergeEntry * entry = agb_merge_entry_from_iterator(it);
		int hasLocalChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_LOCAL) );
		int hasRemoteChanged = !agb_git_oid_equal( agb_merge_entry_id(entry,AGB_MERGE_BASE), agb_merge_entry_id(entry,AGB_MERGE_REMOTE) );
		printf("-- %s %d %d\n", agb_merge_entry_name(entry), hasLocalChanged, hasRemoteChanged);

		if( !hasLocalChanged && !hasRemoteChanged) {
			continue;
		}

		if( hasLocalChanged && !hasRemoteChanged) {
			//We want the head version.
			if(agb_merge_entry_id(entry,AGB_MERGE_LOCAL) == NULL) {
				//TODO: Check error message.
				printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) );
				git_treebuilder_remove(builder, agb_merge_entry_name(entry) );
				continue;
			}

			//TODO: Check for error
			printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) );
			int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_LOCAL), agb_merge_entry_filemode(entry,AGB_MERGE_LOCAL) );
            if(ok!=0) {
                printf("Error duting add/update of tree builder: %s\n", giterr_last()->message);
                abort();
            }
            continue;
		}

		if( !hasLocalChanged && hasRemoteChanged) {
			//We want the head version.
			if(agb_merge_entry_id(entry,AGB_MERGE_REMOTE) == NULL) {
				//TODO: Check error message.
				printf("REMOVING %s from tree\n", agb_merge_entry_name(entry) );
				git_treebuilder_remove(builder, agb_merge_entry_name(entry) );
				continue;
			}

			//TODO: Check for error
			printf("ADDING OR UPDATING %s to tree\n", agb_merge_entry_name(entry) );
			int ok = git_treebuilder_insert(NULL, builder, agb_merge_entry_name(entry), agb_merge_entry_id(entry,AGB_MERGE_REMOTE), agb_merge_entry_filemode(entry,AGB_MERGE_REMOTE) );
			if(ok!=0) {
                printf("Error duting add/update of tree builder: %s\n", giterr_last()->message);
                abort();
            }
            continue;
		}

			printf("CONFLICT %s in tree\n", agb_merge_entry_name(entry) );
		//TODO: CONFLICT - Handle it!

	}

	// Our tree builder should now be full...
	// Lets write it out to a tree
	//
	//TODO: Check for errors
	git_oid new_tree_oid = {};
	git_treebuilder_write(&new_tree_oid, repo, builder);

	char hexid[GIT_OID_HEXSZ+1];
	printf("Tree SHA is %s\n", git_oid_tostr(hexid,GIT_OID_HEXSZ+1, &new_tree_oid));

	git_tree * new_tree = NULL;
	git_tree_lookup(&new_tree, repo, &new_tree_oid);

	// Now we need to create the commit.
    const git_commit** parents = (const git_commit**)malloc(sizeof(git_commit*)*2);

	parents[0] = head_commit;
	parents[1] = branch_commit;


	git_signature * author_signature = NULL;

	// Time since epoch
	// TODO: Get these correctly -
	// Could use git_signature_now instead...
	{

		git_time_t author_time = time(NULL);
		int timezone_offset = 0;
		int ok;

		if((ok=git_signature_new(&author_signature,"Someone","*****@*****.**", author_time, timezone_offset))!=0) {
			agb__error_translate(error,"git_signature_new failed",ok);
			goto cleanup_error;
		}
	}



	git_oid commit_id;
	int ok = git_commit_create(
				&commit_id,
				repo,
				NULL,
				author_signature,
				author_signature,
				"UTF-8",
				"An exciting commit",
				new_tree,
			       	2, //Two parents
				parents
				);
	if(ok!=0) {
		agb__error_translate(error,"git_commit_create failed",ok);
		goto cleanup_error;
	}

	// Then update the refs.
	//TODO: Do we need to release this ref?
	git_reference * ref;
	ok = git_reference_create_matching(
			&ref,
			repo,
		   	"refs/heads/branch_c",
			&commit_id,
			1,
			NULL,
			author_signature,
			"merged by libagb");

	if(ok!=0) {
		agb__error_translate(error,"git_reference_create failed",ok);
		goto cleanup_error;
	}

	git_signature_free(author_signature);

	// Now check we got the expected files
	cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_a.txt"));
	cl_assert_equal_c('A', test_core_merge__compare_with_parents_merge_base("branch_c", "created_in_b.txt"));

	return;

cleanup_error:

	printf("ERROR: %s\n",error->message);

	if(author_signature) {
		git_signature_free(author_signature);
	}
	cl_fail(error->message);


}