On Mon, Feb 9, 2015 at 10:59 AM, Tomaz Canabrava <[email protected]> wrote:
>
> Mock something to me and I'll create it in no time.
Here's something that does progress reporting and credentials, but
does it only to stdin/out/err, so it would need some graphical thing
(with a "cancel" thing too that returns an error).
This patch is obviously on top of the five patches I sent out yesterday.
You can test the progress reporting by giving it a crazy big git
repository that doesn't actually contain any dives, so you can do
./subsurface git://git.hohndel.org/subsurface.git[master]
or something equally insane.
The credentials currently only support username/password setup. I
suspect that to do something sane (ie ssh private key exchange) we'd
have to use some libssh2, because the libgit2 interfaces don't seem to
have anything like that.
Linus
From 4dc930c8890054b9e111df6d87066cc9a8e73336 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <[email protected]>
Date: Mon, 9 Feb 2015 13:32:40 -0800
Subject: [PATCH] git-access: stubs for progress reporting and credentials
The libgit2 credentials handling seems entirely insane. Doing things
like just setting up a private ket and having it all in your .ssh/config
per host doesn't work.
But this gets us started with simple user/password things.
Signed-off-by: Linus Torvalds <[email protected]>
---
git-access.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/git-access.c b/git-access.c
index c39e7efb3ade..8dbb7ff5850b 100644
--- a/git-access.c
+++ b/git-access.c
@@ -70,12 +70,59 @@ static int try_to_update(git_repository *rep, git_reference *local, git_referenc
return report_error("Local and remote do not match, not updating");
}
+static int fetch_sideband_cb(const char *str, int len, void *payload)
+{
+ const char *remote = payload;
+ fprintf(stderr, "remote %s: %.*s\n", remote, len, str);
+ return 0;
+}
+
+static int fetch_progress_cb(const git_transfer_progress *stats, void *payload)
+{
+ const char *remote = payload;
+ const char *state;
+ int cur, tot, percent;
+
+ state = "receiving data";
+ cur = stats->received_objects;
+ tot = stats->total_objects;
+ if (cur == tot) {
+ state = "indexing objects";
+ cur = stats->indexed_objects;
+ tot = stats->total_objects;
+ }
+ percent = tot ? 100 * cur / tot : 0;
+ fprintf(stderr, "remote %s: %s %d %%\n", remote, state, percent);
+ return 0;
+}
+
+/* libgit2 seems insane */
+static int fetch_cred_cb(git_cred **out, const char *url, const char *username_from_url, unsigned int allowed_types, void *payload)
+{
+ char username[128] = {0};
+ char password[128] = {0};
+
+ if (username_from_url) {
+ strncpy(username, username_from_url, sizeof(username)-1);
+ } else {
+ printf("Username: ");
+ scanf("%s", username);
+ }
+
+ /* Yup. Right there on your terminal. Careful where you copy/paste output. */
+ printf("Password: ");
+ scanf("%s", password);
+
+ return git_cred_userpass_plaintext_new(out, username, password);
+}
+
static git_repository *update_local_repo(const char *localdir, const char *remote, const char *branch)
{
int error;
git_repository *repo = NULL;
git_remote *origin;
git_reference *local_ref, *remote_ref;
+ git_remote_callbacks cb = GIT_REMOTE_CALLBACKS_INIT;
error = git_repository_open(&repo, localdir);
if (error) {
@@ -95,6 +142,12 @@ static git_repository *update_local_repo(const char *localdir, const char *remot
return repo;
}
+ cb.sideband_progress = fetch_sideband_cb;
+ cb.credentials = fetch_cred_cb;
+ cb.transfer_progress = fetch_progress_cb;
+ cb.payload = (void *)remote;
+ git_remote_set_callbacks(origin, &cb);
+
// NOTE! A fetch error is not fatal, we just report it
error = git_remote_fetch(origin, NULL, NULL, NULL);
git_remote_free(origin);
@@ -132,6 +185,10 @@ static git_repository *create_local_repo(const char *localdir, const char *remot
git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
opts.checkout_branch = branch;
+ opts.remote_callbacks.sideband_progress = fetch_sideband_cb;
+ opts.remote_callbacks.transfer_progress = fetch_progress_cb;
+ opts.remote_callbacks.credentials = fetch_cred_cb;
+ opts.remote_callbacks.payload = (void *)remote;
error = git_clone(&cloned_repo, remote, localdir, &opts);
if (error) {
report_error("git clone of %s failed (%s)", remote, giterr_last()->message);
--
2.3.0.rc2.2.g0d1c285
_______________________________________________
subsurface mailing list
[email protected]
http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface