Beispiel #1
0
GitStatus::GitStatus(bool * pbCanceled)
	: status(NULL)
{
#if 0
	m_pool = git_pool_create (NULL);
	
	git_error_clear(git_client_create_context(&ctx, m_pool));
	
	if (pbCanceled)
	{
		ctx->cancel_func = cancel;
		ctx->cancel_baton = pbCanceled;
	}

#ifdef _MFC_VER
	git_error_clear(git_config_ensure(NULL, m_pool));
	
	// set up authentication
	m_prompt.Init(m_pool, ctx);

	// set up the configuration
	m_err = git_config_get_config (&(ctx->config), g_pConfigDir, m_pool);

	if (m_err)
	{
		::MessageBox(NULL, this->GetLastErrorMsg(), _T("TortoiseGit"), MB_ICONERROR);
		git_error_clear(m_err);
		git_pool_destroy (m_pool);					// free the allocated memory
		exit(-1);
	}

	// set up the Git_SSH param
	CString tgit_ssh = CRegString(_T("Software\\TortoiseGit\\SSH"));
	if (tgit_ssh.IsEmpty())
		tgit_ssh = CPathUtils::GetAppDirectory() + _T("TortoisePlink.exe");
	tgit_ssh.Replace('\\', '/');
	if (!tgit_ssh.IsEmpty())
	{
		git_config_t * cfg = (git_config_t *)apr_hash_get ((apr_hash_t *)ctx->config, Git_CONFIG_CATEGORY_CONFIG,
			APR_HASH_KEY_STRING);
		git_config_set(cfg, Git_CONFIG_SECTION_TUNNELS, "ssh", CUnicodeUtils::GetUTF8(tgit_ssh));
	}
#else
	git_error_clear(git_config_ensure(NULL, m_pool));

	// set up the configuration
	m_err = git_config_get_config (&(ctx->config), g_pConfigDir, m_pool);

#endif
#endif
}
Beispiel #2
0
static int notes_ref_lookup(git_buf *out, git_rebase *rebase)
{
	git_config *config = NULL;
	int do_rewrite, error;

	if (rebase->options.rewrite_notes_ref) {
		git_buf_attach_notowned(out,
			rebase->options.rewrite_notes_ref,
			strlen(rebase->options.rewrite_notes_ref));
		return 0;
	}

	if ((error = git_repository_config(&config, rebase->repo)) < 0 ||
		(error = git_config_get_bool(&do_rewrite, config, "notes.rewrite.rebase")) < 0) {

		if (error != GIT_ENOTFOUND)
			goto done;

		git_error_clear();
		do_rewrite = 1;
	}

	error = do_rewrite ?
		git_config_get_string_buf(out, config, "notes.rewriteref") :
		GIT_ENOTFOUND;

done:
	git_config_free(config);
	return error;
}
Beispiel #3
0
GitStatus::~GitStatus(void)
{
#if 0
	git_error_clear(m_err);
	git_pool_destroy (m_pool);					// free the allocated memory
#endif
}
Beispiel #4
0
static void *iterate_refs(void *arg)
{
	struct th_data *data = (struct th_data *) arg;
	git_reference_iterator *i;
	git_reference *ref;
	int count = 0, error;
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));
	do {
		error = git_reference_iterator_new(&i, repo);
	} while (error == GIT_ELOCKED);
	cl_git_thread_pass(data, error);

	for (count = 0; !git_reference_next(&ref, i); ++count) {
		cl_assert(ref != NULL);
		git_reference_free(ref);
	}

	if (g_expected > 0)
		cl_assert_equal_i(g_expected, count);

	git_reference_iterator_free(i);

	git_repository_free(repo);
	git_error_clear();
	return arg;
}
Beispiel #5
0
int git_error_state_capture(git_error_state *state, int error_code)
{
	git_error *error = GIT_GLOBAL->last_error;
	git_buf *error_buf = &GIT_GLOBAL->error_buf;

	memset(state, 0, sizeof(git_error_state));

	if (!error_code)
		return 0;

	state->error_code = error_code;
	state->oom = (error == &g_git_oom_error);

	if (error) {
		state->error_msg.klass = error->klass;

		if (state->oom)
			state->error_msg.message = g_git_oom_error.message;
		else
			state->error_msg.message = git_buf_detach(error_buf);
	}

	git_error_clear();
	return error_code;
}
Beispiel #6
0
static void *run_index_diffs_with_modifier(void *arg)
{
	int thread = *(int *)arg;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff *diff = NULL;
	git_index *idx = NULL;
	git_repository *repo;

	cl_git_pass(git_repository_open(&repo, git_repository_path(_repo)));
	cl_git_pass(git_repository_index(&idx, repo));

	/* have first thread altering the index as we go */
	if (thread == 0) {
		int i;

		for (i = 0; i < 300; ++i) {
			switch (i & 0x03) {
			case 0: (void)git_index_add_bypath(idx, "new_file"); break;
			case 1: (void)git_index_remove_bypath(idx, "modified_file"); break;
			case 2: (void)git_index_remove_bypath(idx, "new_file"); break;
			case 3: (void)git_index_add_bypath(idx, "modified_file"); break;
			}
			git_thread_yield();
		}

		goto done;
	}

	/* only use explicit index in this test to prevent reloading */

	switch (thread & 0x03) {
	case 0: /* diff index to workdir */;
		cl_git_pass(git_diff_index_to_workdir(&diff, repo, idx, &opts));
		break;
	case 1: /* diff tree 'a' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, repo, _a, idx, &opts));
		break;
	case 2: /* diff tree 'b' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, repo, _b, idx, &opts));
		break;
	case 3: /* diff index to workdir reversed */;
		opts.flags |= GIT_DIFF_REVERSE;
		cl_git_pass(git_diff_index_to_workdir(&diff, repo, idx, &opts));
		break;
	}

	/* results will be unpredictable with index modifier thread running */

	git_diff_free(diff);

done:
	git_index_free(idx);
	git_repository_free(repo);
	git_error_clear();

	return arg;
}
Beispiel #7
0
int cl_repo_get_bool(git_repository *repo, const char *cfg)
{
	int val = 0;
	git_config *config;
	cl_git_pass(git_repository_config(&config, repo));
	if (git_config_get_bool(&val, config, cfg) < 0)
		git_error_clear();
	git_config_free(config);
	return val;
}
Beispiel #8
0
static int rebase_copy_note(
	git_rebase *rebase,
	const char *notes_ref,
	git_oid *from,
	git_oid *to,
	const git_signature *committer)
{
	git_note *note = NULL;
	git_oid note_id;
	git_signature *who = NULL;
	int error;

	if ((error = git_note_read(&note, rebase->repo, notes_ref, from)) < 0) {
		if (error == GIT_ENOTFOUND) {
			git_error_clear();
			error = 0;
		}

		goto done;
	}

	if (!committer) {
		if((error = git_signature_default(&who, rebase->repo)) < 0) {
			if (error != GIT_ENOTFOUND ||
				(error = git_signature_now(&who, "unknown", "unknown")) < 0)
				goto done;

			git_error_clear();
		}

		committer = who;
	}

	error = git_note_create(&note_id, rebase->repo, notes_ref,
		git_note_author(note), committer, to, git_note_message(note), 0);

done:
	git_note_free(note);
	git_signature_free(who);

	return error;
}
Beispiel #9
0
int git_error_state_restore(git_error_state *state)
{
	int ret = 0;

	git_error_clear();

	if (state && state->error_msg.message) {
		if (state->oom)
			git_error_set_oom();
		else
			set_error(state->error_msg.klass, state->error_msg.message);

		ret = state->error_code;
		memset(state, 0, sizeof(git_error_state));
	}

	return ret;
}
Beispiel #10
0
static void *create_refs(void *arg)
{
	int i, error;
	struct th_data *data = (struct th_data *) arg;
	git_oid head;
	char name[128];
	git_reference *ref[NREFS];
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));

	do {
		error = git_reference_name_to_id(&head, repo, "HEAD");
	} while (error == GIT_ELOCKED);
	cl_git_thread_pass(data, error);

	for (i = 0; i < NREFS; ++i) {
		p_snprintf(name, sizeof(name), "refs/heads/thread-%03d-%02d", data->id, i);
		do {
			error = git_reference_create(&ref[i], repo, name, &head, 0, NULL);
		} while (error == GIT_ELOCKED);
		cl_git_thread_pass(data, error);

		if (concurrent_compress && i == NREFS/2) {
			git_refdb *refdb;
			cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
			do {
				error = git_refdb_compress(refdb);
			} while (error == GIT_ELOCKED);
			cl_git_thread_pass(data, error);
			git_refdb_free(refdb);
		}
	}

	for (i = 0; i < NREFS; ++i)
		git_reference_free(ref[i]);

	git_repository_free(repo);

	git_error_clear();
	return arg;
}
Beispiel #11
0
static void *delete_refs(void *arg)
{
	int i, error;
	struct th_data *data = (struct th_data *) arg;
	git_reference *ref;
	char name[128];
	git_repository *repo;

	cl_git_thread_pass(data, git_repository_open(&repo, data->path));

	for (i = 0; i < NREFS; ++i) {
		p_snprintf(
			name, sizeof(name), "refs/heads/thread-%03d-%02d", (data->id) & ~0x3, i);

		if (!git_reference_lookup(&ref, repo, name)) {
			do {
				error = git_reference_delete(ref);
			} while (error == GIT_ELOCKED);
			/* Sometimes we race with other deleter threads */
			if (error == GIT_ENOTFOUND)
				error = 0;

			cl_git_thread_pass(data, error);
			git_reference_free(ref);
		}

		if (concurrent_compress && i == NREFS/2) {
			git_refdb *refdb;
			cl_git_thread_pass(data, git_repository_refdb(&refdb, repo));
			do {
				error = git_refdb_compress(refdb);
			} while (error == GIT_ELOCKED);
			cl_git_thread_pass(data, error);
			git_refdb_free(refdb);
		}
	}

	git_repository_free(repo);
	git_error_clear();
	return arg;
}
Beispiel #12
0
int git_diff_from_buffer(
	git_diff **out,
	const char *content,
	size_t content_len)
{
	git_diff_parsed *diff;
	git_patch *patch;
	git_patch_parse_ctx *ctx = NULL;
	int error = 0;

	*out = NULL;

	diff = diff_parsed_alloc();
	GIT_ERROR_CHECK_ALLOC(diff);

	ctx = git_patch_parse_ctx_init(content, content_len, NULL);
	GIT_ERROR_CHECK_ALLOC(ctx);

	while (ctx->parse_ctx.remain_len) {
		if ((error = git_patch_parse(&patch, ctx)) < 0)
			break;

		git_vector_insert(&diff->patches, patch);
		git_vector_insert(&diff->base.deltas, patch->delta);
	}

	if (error == GIT_ENOTFOUND && git_vector_length(&diff->patches) > 0) {
		git_error_clear();
		error = 0;
	}

	git_patch_parse_ctx_free(ctx);

	if (error < 0)
		git_diff_free(&diff->base);
	else
		*out = &diff->base;

	return error;
}
Beispiel #13
0
git_wc_status2_t * GitStatus::GetFirstFileStatus(const CTGitPath& path, CTGitPath& retPath, bool update, git_depth_t depth, bool bNoIgnore /* = true */, bool bNoExternals /* = false */)
{
	static git_wc_status2 st;
/*
	m_fileCache.Reset();

	m_fileCache.Init( CStringA( path.GetWinPathString().GetString() ) );
MessageBox(NULL, path.GetWinPathString(), _T("GetFirstFile"), MB_OK);
	m_fileCache.m_pFileIter = m_fileCache.m_pFiles;
	st.text_status = git_wc_status_none;

	if (m_fileCache.m_pFileIter)
	{
		switch(m_fileCache.m_pFileIter->nStatus)
		{
		case WGFS_Normal: st.text_status = git_wc_status_normal; break;
		case WGFS_Modified: st.text_status = git_wc_status_modified; break;
		case WGFS_Deleted: st.text_status = git_wc_status_deleted; break;
		}

		//retPath.SetFromGit((const char*)item->key);

		m_fileCache.m_pFileIter = m_fileCache.m_pFileIter->pNext;
	}

	return &st;
*/
#if 0
	const sort_item*			item;

	git_error_clear(m_err);
	m_statushash = apr_hash_make(m_pool);
	m_externalhash = apr_hash_make(m_pool);
	headrev = Git_INVALID_REVNUM;
	git_opt_revision_t rev;
	rev.kind = git_opt_revision_unspecified;
	struct hashbaton_t hashbaton;
	hashbaton.hash = m_statushash;
	hashbaton.exthash = m_externalhash;
	hashbaton.pThis = this;
	m_statushashindex = 0;
	m_err = git_client_status4 (&headrev,
							path.GetGitApiPath(m_pool),
							&rev,
							getstatushash,
							&hashbaton,
							depth,
							TRUE,		//getall
							update,		//update
							bNoIgnore,	//noignore
							bNoExternals,		//noexternals
							NULL,
							ctx,
							m_pool);


	// Error present if function is not under version control
	if ((m_err != NULL) || (apr_hash_count(m_statushash) == 0))
	{
		return NULL;	
	}

	// Convert the unordered hash to an ordered, sorted array
	m_statusarray = sort_hash (m_statushash,
								sort_compare_items_as_paths,
								m_pool);

	// only the first entry is needed (no recurse)
	m_statushashindex = 0;
	item = &APR_ARRAY_IDX (m_statusarray, m_statushashindex, const sort_item);
	retPath.SetFromGit((const char*)item->key);
	return (git_wc_status2_t *) item->value;
#endif

	return 0;
}
Beispiel #14
0
stdstring GitStatus::GetLastErrorMsg() const
{

	stdstring msg;
#if 0
	char errbuf[256];

	if (m_err != NULL)
	{
		git_error_t * ErrPtr = m_err;
		if (ErrPtr->message)
		{
			msg = CUnicodeUtils::StdGetUnicode(ErrPtr->message);
		}
		else
		{
			/* Is this a Subversion-specific error code? */
			if ((ErrPtr->apr_err > APR_OS_START_USEERR)
				&& (ErrPtr->apr_err <= APR_OS_START_CANONERR))
				msg = CUnicodeUtils::StdGetUnicode(git_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf)));
			/* Otherwise, this must be an APR error code. */
			else
			{
				git_error_t *temp_err = NULL;
				const char * err_string = NULL;
				temp_err = git_utf_cstring_to_utf8(&err_string, apr_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf)-1), ErrPtr->pool);
				if (temp_err)
				{
					git_error_clear (temp_err);
					msg = _T("Can't recode error string from APR");
				}
				else
				{
					msg = CUnicodeUtils::StdGetUnicode(err_string);
				}
			}

		}

		while (ErrPtr->child)
		{
			ErrPtr = ErrPtr->child;
			msg += _T("\n");
			if (ErrPtr->message)
			{
				msg += CUnicodeUtils::StdGetUnicode(ErrPtr->message);
			}
			else
			{
				/* Is this a Subversion-specific error code? */
				if ((ErrPtr->apr_err > APR_OS_START_USEERR)
					&& (ErrPtr->apr_err <= APR_OS_START_CANONERR))
					msg += CUnicodeUtils::StdGetUnicode(git_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf)));
				/* Otherwise, this must be an APR error code. */
				else
				{
					git_error_t *temp_err = NULL;
					const char * err_string = NULL;
					temp_err = git_utf_cstring_to_utf8(&err_string, apr_strerror (ErrPtr->apr_err, errbuf, sizeof (errbuf)-1), ErrPtr->pool);
					if (temp_err)
					{
						git_error_clear (temp_err);
						msg += _T("Can't recode error string from APR");
					}
					else
					{
						msg += CUnicodeUtils::StdGetUnicode(err_string);
					}
				}

			}
		}
		return msg;
	} // if (m_err != NULL)
#endif
	return msg;
}
Beispiel #15
0
static void *run_index_diffs(void *arg)
{
	int thread = *(int *)arg;
	git_repository *repo;
	git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
	git_diff *diff = NULL;
	size_t i;
	int exp[4] = { 0, 0, 0, 0 };

	cl_git_pass(git_repository_open(&repo, git_repository_path(_repo)));

	switch (thread & 0x03) {
	case 0: /* diff index to workdir */;
		cl_git_pass(git_diff_index_to_workdir(&diff, repo, NULL, &opts));
		break;
	case 1: /* diff tree 'a' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, repo, _a, NULL, &opts));
		break;
	case 2: /* diff tree 'b' to index */;
		cl_git_pass(git_diff_tree_to_index(&diff, repo, _b, NULL, &opts));
		break;
	case 3: /* diff index to workdir (explicit index) */;
		{
			git_index *idx;
			cl_git_pass(git_repository_index(&idx, repo));
			cl_git_pass(git_diff_index_to_workdir(&diff, repo, idx, &opts));
			git_index_free(idx);
			break;
		}
	}

	/* keep some diff stats to make sure results are as expected */

	i = git_diff_num_deltas(diff);
	git_atomic_add(&_counts[0], (int32_t)i);
	exp[0] = (int)i;

	while (i > 0) {
		switch (git_diff_get_delta(diff, --i)->status) {
		case GIT_DELTA_MODIFIED: exp[1]++; git_atomic_inc(&_counts[1]); break;
		case GIT_DELTA_ADDED:    exp[2]++; git_atomic_inc(&_counts[2]); break;
		case GIT_DELTA_DELETED:  exp[3]++; git_atomic_inc(&_counts[3]); break;
		default: break;
		}
	}

	switch (thread & 0x03) {
	case 0: case 3:
		cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(4, exp[1]);
		cl_assert_equal_i(0, exp[2]); cl_assert_equal_i(4, exp[3]);
		break;
	case 1:
		cl_assert_equal_i(12, exp[0]); cl_assert_equal_i(3, exp[1]);
		cl_assert_equal_i(7, exp[2]); cl_assert_equal_i(2, exp[3]);
		break;
	case 2:
		cl_assert_equal_i(8, exp[0]); cl_assert_equal_i(3, exp[1]);
		cl_assert_equal_i(3, exp[2]); cl_assert_equal_i(2, exp[3]);
		break;
	}

	git_diff_free(diff);
	git_repository_free(repo);
	git_error_clear();

	return arg;
}
Beispiel #16
0
static int rebase_copy_notes(
	git_rebase *rebase,
	const git_signature *committer)
{
	git_buf path = GIT_BUF_INIT, rewritten = GIT_BUF_INIT, notes_ref = GIT_BUF_INIT;
	char *pair_list, *fromstr, *tostr, *end;
	git_oid from, to;
	unsigned int linenum = 1;
	int error = 0;

	if ((error = notes_ref_lookup(&notes_ref, rebase)) < 0) {
		if (error == GIT_ENOTFOUND) {
			git_error_clear();
			error = 0;
		}

		goto done;
	}

	if ((error = git_buf_joinpath(&path, rebase->state_path, REWRITTEN_FILE)) < 0 ||
		(error = git_futils_readbuffer(&rewritten, path.ptr)) < 0)
		goto done;

	pair_list = rewritten.ptr;

	while (*pair_list) {
		fromstr = pair_list;

		if ((end = strchr(fromstr, '\n')) == NULL)
			goto on_error;

		pair_list = end+1;
		*end = '\0';

		if ((end = strchr(fromstr, ' ')) == NULL)
			goto on_error;

		tostr = end+1;
		*end = '\0';

		if (strlen(fromstr) != GIT_OID_HEXSZ ||
			strlen(tostr) != GIT_OID_HEXSZ ||
			git_oid_fromstr(&from, fromstr) < 0 ||
			git_oid_fromstr(&to, tostr) < 0)
			goto on_error;

		if ((error = rebase_copy_note(rebase, notes_ref.ptr, &from, &to, committer)) < 0)
			goto done;

		linenum++;
	}

	goto done;

on_error:
	git_error_set(GIT_ERROR_REBASE, "invalid rewritten file at line %d", linenum);
	error = -1;

done:
	git_buf_dispose(&rewritten);
	git_buf_dispose(&path);
	git_buf_dispose(&notes_ref);

	return error;
}
Beispiel #17
0
void giterr_clear(void)
{
	git_error_clear();
}