Esempio n. 1
0
int git_clone_into(git_repository *repo, git_remote *remote, const git_checkout_opts *co_opts, const char *branch)
{
	int error = 0, old_fetchhead;
	size_t nspecs;

	assert(repo && remote);

	if (!git_repository_is_empty(repo)) {
		giterr_set(GITERR_INVALID, "the repository is not empty");
		return -1;
	}

	if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
		return error;

	old_fetchhead = git_remote_update_fetchhead(remote);
	git_remote_set_update_fetchhead(remote, 0);

	if ((error = git_remote_fetch(remote)) < 0)
		goto cleanup;

	if (branch)
		error = update_head_to_branch(repo, git_remote_name(remote), branch);
	/* Point HEAD to the same ref as the remote's head */
	else
		error = update_head_to_remote(repo, remote);

	if (!error && should_checkout(repo, git_repository_is_bare(repo), co_opts))
		error = git_checkout_head(repo, co_opts);

cleanup:
	git_remote_set_update_fetchhead(remote, old_fetchhead);
	/* Remove the tags refspec */
	nspecs = git_remote_refspec_count(remote);
	git_remote_remove_refspec(remote, nspecs);

	return error;
}
Esempio n. 2
0
static int create_and_configure_origin(
		git_remote **out,
		git_repository *repo,
		const char *url,
		const git_clone_options *options)
{
	int error;
	git_remote *origin = NULL;

	if ((error = git_remote_create(&origin, repo, options->remote_name, url)) < 0)
		goto on_error;

	git_remote_set_cred_acquire_cb(origin, options->cred_acquire_cb,
			options->cred_acquire_payload);
	git_remote_set_autotag(origin, options->remote_autotag);
	/*
	 * Don't write FETCH_HEAD, we'll check out the remote tracking
	 * branch ourselves based on the server's default.
	 */
	git_remote_set_update_fetchhead(origin, 0);

	if (options->remote_callbacks &&
	    (error = git_remote_set_callbacks(origin, options->remote_callbacks)) < 0)
		goto on_error;

	if (options->fetch_spec &&
	    (error = git_remote_set_fetchspec(origin, options->fetch_spec)) < 0)
		goto on_error;

	if (options->push_spec &&
	    (error = git_remote_set_pushspec(origin, options->push_spec)) < 0)
		goto on_error;

	if (options->pushurl &&
	    (error = git_remote_set_pushurl(origin, options->pushurl)) < 0)
		goto on_error;

	if ((error = git_remote_save(origin)) < 0)
		goto on_error;

	*out = origin;
	return 0;

on_error:
	git_remote_free(origin);
	return error;
}
Esempio n. 3
0
static int clone_into(git_repository *repo, git_remote *_remote, const git_checkout_options *co_opts, const char *branch, const git_signature *signature)
{
	int error;
	git_buf reflog_message = GIT_BUF_INIT;
	git_remote *remote;
	const git_remote_callbacks *callbacks;

	assert(repo && _remote);

	if (!git_repository_is_empty(repo)) {
		giterr_set(GITERR_INVALID, "the repository is not empty");
		return -1;
	}

	if ((error = git_remote_dup(&remote, _remote)) < 0)
		return error;

	callbacks = git_remote_get_callbacks(_remote);
	if (!giterr__check_version(callbacks, 1, "git_remote_callbacks") &&
	    (error = git_remote_set_callbacks(remote, callbacks)) < 0)
		goto cleanup;

	if ((error = git_remote_add_fetch(remote, "refs/tags/*:refs/tags/*")) < 0)
		goto cleanup;

	git_remote_set_update_fetchhead(remote, 0);
	git_buf_printf(&reflog_message, "clone: from %s", git_remote_url(remote));

	if ((error = git_remote_fetch(remote, signature, git_buf_cstr(&reflog_message))) != 0)
		goto cleanup;

	error = checkout_branch(repo, remote, co_opts, branch, signature, git_buf_cstr(&reflog_message));

cleanup:
	git_remote_free(remote);
	git_buf_free(&reflog_message);

	return error;
}
Esempio n. 4
0
static int setup_remotes_and_fetch(
		git_repository *repo,
		const char *url,
		const git_clone_options *options)
{
	int retcode = GIT_ERROR;
	git_remote *origin;

	/* Construct an origin remote */
	if (!create_and_configure_origin(&origin, repo, url, options)) {
		git_remote_set_update_fetchhead(origin, 0);

		/* Connect and download everything */
		if (!git_remote_connect(origin, GIT_DIRECTION_FETCH)) {
			if (!(retcode = git_remote_download(origin, options->fetch_progress_cb,
						options->fetch_progress_payload))) {
				/* Create "origin/foo" branches for all remote branches */
				if (!git_remote_update_tips(origin)) {
					/* Point HEAD to the requested branch */
					if (options->checkout_branch) {
						if (!update_head_to_branch(repo, options))
							retcode = 0;
					}
					/* Point HEAD to the same ref as the remote's head */
					else if (!update_head_to_remote(repo, origin)) {
						retcode = 0;
					}
				}
			}
			git_remote_disconnect(origin);
		}
		git_remote_free(origin);
	}

	return retcode;
}
Esempio n. 5
0
static int handle(KDriver const *driver, KImplementation const *impl, int requested)
{
	char const *url = k_dictionary_get(k_implementation_get_values(impl), "href");
	char const *tag = k_dictionary_get(k_implementation_get_values(impl), "tag");
	char const *path = k_dictionary_get(k_implementation_get_meta(impl), "name");

	git_repository* repo = NULL;
	git_remote* origin = NULL;

	if (git_repository_open(&repo, path) == GIT_OK)
	{
		if (git_remote_load(&origin, repo, "origin") != GIT_OK)
		{
			git_repository_free(repo);
			return -1;
		}

		if (strcmp(url, git_remote_url(origin)) != 0)
		{
			giterr_set_str(GITERR_INVALID, "different origin");
			git_repository_free(repo);
			return -1;
		}
	}
	else
	{
		if (git_repository_init(&repo, path, 0) != GIT_OK)
		{
			return -1;
		}

		if (git_remote_create(&origin, repo, "origin", url) != GIT_OK)
		{
			git_repository_free(repo);
			return -1;
		}
	}

	git_remote_set_update_fetchhead(origin, 0);
	git_remote_set_cred_acquire_cb(origin, cred_acquire, NULL);

	if (git_remote_connect(origin, GIT_DIRECTION_FETCH) != GIT_OK)
	{
		git_remote_free(origin);
		git_repository_free(repo);
		return -1;
	}

	if (git_remote_download(origin, transfer_progress, NULL) != GIT_OK)
	{
		git_remote_free(origin);
		git_repository_free(repo);
		return -1;
	}

	if (git_remote_update_tips(origin) != GIT_OK)
	{
		git_remote_free(origin);
		git_repository_free(repo);
		return -1;
	}

	git_object* object = NULL;

	if (git_revparse_single(&object, repo, tag) != GIT_OK)
	{
		git_remote_free(origin);
		git_repository_free(repo);
		return -1;
	}

	if (git_repository_set_head_detached(repo, git_object_id(object)) != GIT_OK)
	{
		git_object_free(object);
		git_remote_free(origin);
		git_repository_free(repo);
		return -1;
	}

	git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT;
	checkout_opts.version = GIT_CHECKOUT_OPTS_VERSION;
	checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
	checkout_opts.progress_cb = checkout_progress;
	checkout_opts.progress_payload = NULL;

	if (git_checkout_tree(repo, object, &checkout_opts) != GIT_OK)
	{
		git_object_free(object);
		git_remote_free(origin);
		git_repository_free(repo);
		return -1;
	}

	git_object_free(object);
	git_remote_free(origin);
	git_repository_free(repo);
	return 0;
}
Esempio n. 6
0
void download(KImplementation const *impl, int requested, KError *error, void *ctx)
  {
  KDictionary const *values = k_implementation_get_values(impl);
  char const *href = k_dictionary_lookup(values, "href");
  char const *tag = k_dictionary_lookup(values, "tag");
  char const *path = k_implementation_get_name(impl);

  git_repository *repo = NULL;
  git_remote *origin = NULL;
  git_object *object = NULL;

  struct progress_data progress_data = {{0}};
  git_checkout_opts checkout_opts = GIT_CHECKOUT_OPTS_INIT;
  checkout_opts.version = GIT_CHECKOUT_OPTS_VERSION;
  checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
  checkout_opts.progress_cb = checkout_progress;
  checkout_opts.progress_payload = &progress_data;

  if (git_repository_open(&repo, path) == GIT_OK)
    {
    if (git_remote_load(&origin, repo, "origin") != GIT_OK)
      {
      k_error_set(error, giterr_last()->message);
      goto repository_free;
      }
    if (strcmp(git_remote_url(origin), href) != 0)
      {
      k_error_set(error, "different origin");
      goto remote_free;
      }
    }
  else
    {
    if (git_repository_init(&repo, path, 0) != GIT_OK)
      {
      k_error_set(error, giterr_last()->message);
      return;
      }
    if (git_remote_create(&origin, repo, "origin", href) != GIT_OK)
      {
      k_error_set(error, giterr_last()->message);
      goto repository_free;
      }
    }
  git_remote_set_update_fetchhead(origin, 0);
  git_remote_set_cred_acquire_cb(origin, cred_acquire, NULL);
  if (git_remote_connect(origin, GIT_DIRECTION_FETCH) != GIT_OK)
    {
    k_error_set(error, giterr_last()->message);
    goto remote_free;
    }
  if (git_remote_download(origin, fetch_progress, &progress_data) != GIT_OK)
    {
    k_error_set(error, giterr_last()->message);
    goto remote_disconnect;
    }
  if (git_remote_update_tips(origin) != GIT_OK)
    {
    k_error_set(error, giterr_last()->message);
    goto remote_disconnect;
    }
  if (git_revparse_single(&object, repo, tag) != GIT_OK)
    {
    k_error_set(error, giterr_last()->message);
    goto remote_disconnect;
    }
  if (git_repository_set_head_detached(repo, git_object_id(object)) != GIT_OK)
    {
    k_error_set(error, giterr_last()->message);
    goto remote_disconnect;
    }
  if (git_checkout_tree(repo, object, &checkout_opts) != GIT_OK)
    {
    k_error_set(error, giterr_last()->message);
    }
remote_disconnect:
  git_remote_disconnect(origin);
remote_free:
  git_remote_free(origin);
repository_free:
  git_repository_free(repo);
  }