Ejemplo n.º 1
0
void test_online_fetch__fetch_twice(void)
{
	git_remote *remote;
	cl_git_pass(git_remote_create(&remote, _repo, "test", "git://github.com/libgit2/TestGitRepository.git"));
    	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
    	cl_git_pass(git_remote_download(remote));
    	git_remote_disconnect(remote);
    	
    	git_remote_connect(remote, GIT_DIRECTION_FETCH);
	cl_git_pass(git_remote_download(remote));
	git_remote_disconnect(remote);
	
	git_remote_free(remote);
}
Ejemplo n.º 2
0
static int setup_remotes_and_fetch(
		git_repository *repo,
		const char *origin_url,
		git_transfer_progress_callback progress_cb,
		void *progress_payload)
{
	int retcode = GIT_ERROR;
	git_remote *origin = NULL;

	/* Create the "origin" remote */
	if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) {
		/* Connect and download everything */
		if (!git_remote_connect(origin, GIT_DIR_FETCH)) {
			if (!git_remote_download(origin, progress_cb, progress_payload)) {
				/* Create "origin/foo" branches for all remote branches */
				if (!git_remote_update_tips(origin)) {
					/* Point HEAD to the same ref as the remote's head */
					if (!update_head_to_remote(repo, origin)) {
						retcode = 0;
					}
				}
			}
			git_remote_disconnect(origin);
		}
		git_remote_free(origin);
	}

	return retcode;
}
Ejemplo n.º 3
0
static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
{
	git_remote *remote;
	git_buf fetchhead_buf = GIT_BUF_INIT;
	int equals = 0;

	cl_git_pass(git_remote_load(&remote, g_repo, "origin"));
	git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);

	if(fetchspec != NULL) {
		git_remote_clear_refspecs(remote);
		git_remote_add_fetch(remote, fetchspec);
	}

	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(remote));
	cl_git_pass(git_remote_update_tips(remote, NULL, NULL));
	git_remote_disconnect(remote);
	git_remote_free(remote);

	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));

	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);

	git_buf_free(&fetchhead_buf);

	cl_assert(equals);
}
Ejemplo n.º 4
0
static void fetchhead_test_fetch(const char *fetchspec, const char *expected_fetchhead)
{
	git_remote *remote;
	git_buf fetchhead_buf = GIT_BUF_INIT;
	int equals = 0;
	git_strarray array, *active_refs = NULL;

	cl_git_pass(git_remote_lookup(&remote, g_repo, "origin"));
	git_remote_set_autotag(remote, GIT_REMOTE_DOWNLOAD_TAGS_AUTO);

	if(fetchspec != NULL) {
		array.count = 1;
		array.strings = (char **) &fetchspec;
		active_refs = &array;
	}

	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(remote, active_refs));
	cl_git_pass(git_remote_update_tips(remote, NULL));
	git_remote_disconnect(remote);
	git_remote_free(remote);

	cl_git_pass(git_futils_readbuffer(&fetchhead_buf, "./foo/.git/FETCH_HEAD"));

	equals = (strcmp(fetchhead_buf.ptr, expected_fetchhead) == 0);

	git_buf_free(&fetchhead_buf);

	cl_assert(equals);
}
Ejemplo n.º 5
0
Archivo: fetch.c Proyecto: bxio/.atom
static void *download(void *ptr)
{
	struct dl_data *data = (struct dl_data *)ptr;

	// Connect to the remote end specifying that we want to fetch
	// information from it.
	if (git_remote_connect(data->remote, GIT_DIRECTION_FETCH) < 0) {
		data->ret = -1;
		goto exit;
	}

	// 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 (git_remote_download(data->remote, NULL, NULL) < 0) {
		data->ret = -1;
		goto exit;
	}

	data->ret = 0;

exit:
	data->finished = 1;
	return &data->ret;
}
Ejemplo n.º 6
0
PyObject *
Remote_fetch(Remote *self, PyObject *args)
{
    PyObject* py_stats = NULL;
    const git_transfer_progress *stats;
    int err;

    err = git_remote_connect(self->remote, GIT_DIRECTION_FETCH);
    if (err == GIT_OK) {
        err = git_remote_download(self->remote);
        if (err == GIT_OK) {
            stats = git_remote_stats(self->remote);
            py_stats = Py_BuildValue("{s:I,s:I,s:n}",
                "indexed_objects", stats->indexed_objects,
                "received_objects", stats->received_objects,
                "received_bytes", stats->received_bytes);

            err = git_remote_update_tips(self->remote);
        }
        git_remote_disconnect(self->remote);
    }

    if (err < 0)
        return Error_set(err);

    return (PyObject*) py_stats;
}
Ejemplo n.º 7
0
void test_network_fetchlocal__partial(void)
{
	git_repository *repo = cl_git_sandbox_init("partial-testrepo");
	git_remote *origin;
	int callcount = 0;
	git_strarray refnames = {0};
	const char *url;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

	callbacks.transfer_progress = transfer_cb;
	callbacks.payload = &callcount;

	cl_set_cleanup(&cleanup_sandbox, NULL);
	cl_git_pass(git_reference_list(&refnames, repo));
	cl_assert_equal_i(1, (int)refnames.count);

	url = cl_git_fixture_url("testrepo.git");
	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
	git_remote_set_callbacks(origin, &callbacks);
	cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(origin));
	cl_git_pass(git_remote_update_tips(origin, NULL, NULL));

	git_strarray_free(&refnames);

	cl_git_pass(git_reference_list(&refnames, repo));
	cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */
	cl_assert(callcount > 0);

	git_strarray_free(&refnames);
	git_remote_free(origin);
}
Ejemplo n.º 8
0
void test_online_fetch__doesnt_retrieve_a_pack_when_the_repository_is_up_to_date(void)
{
	git_repository *_repository;
	bool invoked = false;
	git_remote *remote;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
	git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
	opts.bare = true;

	cl_git_pass(git_clone(&_repository, "https://github.com/libgit2/TestGitRepository.git",
				"./fetch/lg2", &opts));
	git_repository_free(_repository);

	cl_git_pass(git_repository_open(&_repository, "./fetch/lg2"));

	cl_git_pass(git_remote_load(&remote, _repository, "origin"));
	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));

	cl_assert_equal_i(false, invoked);

	callbacks.transfer_progress = &transferProgressCallback;
	callbacks.payload = &invoked;
	git_remote_set_callbacks(remote, &callbacks);
	cl_git_pass(git_remote_download(remote));

	cl_assert_equal_i(false, invoked);

	cl_git_pass(git_remote_update_tips(remote, NULL, NULL));
	git_remote_disconnect(remote);

	git_remote_free(remote);
	git_repository_free(_repository);
}
Ejemplo n.º 9
0
/**
 * ggit_remote_download:
 * @remote: a #GgitRemote.
 * @specs: (array zero-terminated=1) (allow-none): the ref specs.
 * @fetch_options: a #GgitFetchOptions.
 * @error: a #GError for error reporting, or %NULL.
 *
 * Connect to the remote if not yet connected, negotiate with the remote
 * about which objects are missing and download the resulting packfile and
 * its index.
 *
 * Returns: %TRUE if successful, %FALSE otherwise.
 */
gboolean
ggit_remote_download (GgitRemote           *remote,
                      const gchar * const  *specs,
                      GgitFetchOptions     *fetch_options,
                      GError              **error)
{
	gint ret;
	git_strarray gspecs;

	g_return_val_if_fail (GGIT_IS_REMOTE (remote), FALSE);
	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

	ggit_utils_get_git_strarray_from_str_array (specs, &gspecs);

	ret = git_remote_download (_ggit_native_get (remote), &gspecs,
	                           _ggit_fetch_options_get_fetch_options (fetch_options));

	if (ret != GIT_OK)
	{
		_ggit_error_set (error, ret);
		return FALSE;
	}

	return TRUE;
}
Ejemplo n.º 10
0
void test_online_fetch__can_cancel(void)
{
	git_remote *remote;
	size_t bytes_received = 0;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

	cl_git_pass(git_remote_create(&remote, _repo, "test",
				"http://github.com/libgit2/TestGitRepository.git"));

	callbacks.transfer_progress = cancel_at_half;
	callbacks.payload = &bytes_received;
	git_remote_set_callbacks(remote, &callbacks);

	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_fail_with(git_remote_download(remote), -4321);
	git_remote_disconnect(remote);
	git_remote_free(remote);
}
Ejemplo n.º 11
0
static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n)
{
	git_remote *remote;
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
	size_t bytes_received = 0;

	callbacks.transfer_progress = progress;
	callbacks.update_tips = update_tips;
	callbacks.payload = &bytes_received;
	counter = 0;

	cl_git_pass(git_remote_create(&remote, _repo, "test", url));
	git_remote_set_callbacks(remote, &callbacks);
	git_remote_set_autotag(remote, flag);
	cl_git_pass(git_remote_connect(remote, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(remote));
	cl_git_pass(git_remote_update_tips(remote, NULL, NULL));
	git_remote_disconnect(remote);
	cl_assert_equal_i(counter, n);
	cl_assert(bytes_received > 0);

	git_remote_free(remote);
}
Ejemplo n.º 12
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
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);
  }
Ejemplo n.º 15
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;
}
Ejemplo n.º 16
0
void test_network_fetchlocal__prune(void)
{
	git_repository *repo;
	git_remote *origin;
	int callcount = 0;
	git_strarray refnames = {0};
	git_reference *ref;
	git_repository *remote_repo = cl_git_sandbox_init("testrepo.git");
	const char *url = cl_git_path_url(git_repository_path(remote_repo));
	git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;

	callbacks.transfer_progress = transfer_cb;
	callbacks.payload = &callcount;

	cl_set_cleanup(&cleanup_local_repo, "foo");
	cl_git_pass(git_repository_init(&repo, "foo", true));

	cl_git_pass(git_remote_create(&origin, repo, GIT_REMOTE_ORIGIN, url));
	git_remote_set_callbacks(origin, &callbacks);
	cl_git_pass(git_remote_fetch(origin, NULL, NULL, NULL));

	cl_git_pass(git_reference_list(&refnames, repo));
	cl_assert_equal_i(19, (int)refnames.count);
	cl_assert(callcount > 0);
	git_strarray_free(&refnames);
	git_remote_free(origin);

	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/br2"));
	cl_git_pass(git_reference_delete(ref));
	git_reference_free(ref);

	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
	git_remote_set_callbacks(origin, &callbacks);
	cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(origin, NULL));
	cl_git_pass(git_remote_prune(origin));
	cl_git_pass(git_remote_update_tips(origin, NULL, NULL));

	cl_git_pass(git_reference_list(&refnames, repo));
	cl_assert_equal_i(18, (int)refnames.count);
	git_strarray_free(&refnames);
	git_remote_free(origin);

	cl_git_pass(git_reference_lookup(&ref, remote_repo, "refs/heads/packed"));
	cl_git_pass(git_reference_delete(ref));
	git_reference_free(ref);

	cl_git_pass(git_remote_lookup(&origin, repo, GIT_REMOTE_ORIGIN));
	git_remote_set_callbacks(origin, &callbacks);
	cl_git_pass(git_remote_connect(origin, GIT_DIRECTION_FETCH));
	cl_git_pass(git_remote_download(origin, NULL));
	cl_git_pass(git_remote_prune(origin));
	cl_git_pass(git_remote_update_tips(origin, NULL, NULL));

	cl_git_pass(git_reference_list(&refnames, repo));
	cl_assert_equal_i(17, (int)refnames.count);
	git_strarray_free(&refnames);
	git_remote_free(origin);

	git_repository_free(repo);
}
Ejemplo n.º 17
0
// Clone the module currently highlighted in the QListWidget.
void RTXIWizard::Panel::cloneModule(void)
{
	cloneButton->setEnabled(false);
	availableListWidget->setDisabled(true);
	installedListWidget->setDisabled(true);

	QString name;
	switch(button_mode)
	{
		case DOWNLOAD:
			name = availableListWidget->currentItem()->text();
			break;

		case UPDATE:
			name = installedListWidget->currentItem()->text();
			break;

		default:
			std::cout<<"ERROR: default in switch block in cloneModule()"<<std::endl;
			break;
	}

	/*
	 * Two QByteArray variables are needed due to the way Qt stores binary data.
	 * Calling module->getCloneUrl().toString().toLatin1().data() will produce
	 * an error.
	 */

	QByteArray temp = modules[name].clone_url.toString().toLatin1();
	const char *url = temp.data();
	QByteArray temp2 = modules[name].location.toString().toLatin1();
	const char *path = temp2.data();

	int error = 0;

	// If the repo already exists, pull from master. If not, clone it.
	if ( (QDir(modules[name].location.toString())).exists() )
	{
		git_repository *repo = NULL;
		git_remote *remote = NULL;

		git_repository_open(&repo, path);
#if LIBGIT2_SOVERSION >= 22
		printGitError(git_remote_lookup(&remote, repo, "origin"));
#else
		printGitError(git_remote_load(&remote, repo, "origin"));
#endif

#if LIBGIT2_SOVERSION >= 24
		printGitError(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL, NULL));
		//printGitError(git_remote_connect(remote, GIT_DIRECTION_FETCH, NULL, NULL));
#else
		printGitError(git_remote_connect(remote, GIT_DIRECTION_FETCH));
#endif

#if LIBGIT2_SOVERSION >= 24
		printGitError(git_remote_download(remote, NULL, NULL));
#elif LIBGIT2_SOVERSION >= 22
		printGitError(git_remote_download(remote, NULL));
#elif LIBGIT2_SOVERSION >= 21
		printGitError(git_remote_download(remote));
#else
		printGitError(git_remote_download(remote, NULL, NULL));
#endif

		git_remote_disconnect(remote);
		git_remote_free(remote);
		git_repository_free(repo);
	}
	else
	{
		git_repository *repo = NULL;
		printGitError(git_clone(&repo, url, path, NULL));
		git_repository_free(repo);
	}

	if (error)
	{
		std::cout<<"git ERROR"<<std::endl;
	}
	else
	{
		// Add module to list of already installed modules.
		modules[name].installed = true;

		// Define the commands to be run.
		QString make_cmd = "/usr/bin/make -j2 -C " + modules[name].location.toString();
		QString make_install_cmd;

		// If RTXI is root, no need to call gksudo.
		if (getuid()) make_install_cmd = "gksudo \"/usr/bin/make install -C" + modules[name].location.toString() + "\"";
		else make_install_cmd = "/usr/bin/make install -C" + modules[name].location.toString();

		// Compile and instal handled by QProcess.
		QProcess *make = new QProcess();
		QProcess *make_install = new QProcess();
		make->start(make_cmd);

		if (!make->waitForFinished())
		{
			std::cout<<"make -C "<<path<<" failed"<<std::endl;
		}
		else
		{
			make_install->start(make_install_cmd);
			if (!make_install->waitForFinished())
			{
				std::cout<<"make install -C"<<path<<" failed..."<<std::endl;
				std::cout<<"...despite make -C succeeding."<<std::endl;
			}
		}

		make->close();
		make_install->close();
	}

	// Re-enable buttons only after compilation is done. Otherwise you get race
	// conditions if buttons are pressed before modules are done compiling.
	cloneButton->setEnabled(true);
	rebuildListWidgets();
	availableListWidget->setDisabled(false);
	installedListWidget->setDisabled(false);
}