summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/network/Makefile2
-rw-r--r--examples/network/fetch.c21
-rw-r--r--include/git2/remote.h6
-rw-r--r--src/remote.c26
4 files changed, 46 insertions, 9 deletions
diff --git a/examples/network/Makefile b/examples/network/Makefile
index ed0c2099f..c21869ac9 100644
--- a/examples/network/Makefile
+++ b/examples/network/Makefile
@@ -2,7 +2,7 @@ default: all
CC = gcc
CFLAGS += -g
-CFLAGS += -I../../include -L../../ -lgit2
+CFLAGS += -I../../include -L../../ -lgit2 -lpthread
OBJECTS = \
git2.o \
diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index f7a60640e..d4a39746f 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -39,6 +39,25 @@ exit:
pthread_exit(&data->ret);
}
+int update_cb(const char *refname, const git_oid *a, const git_oid *b)
+{
+ const char *action;
+ char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1];
+
+ git_oid_fmt(b_str, b);
+ b_str[GIT_OID_HEXSZ] = '\0';
+
+ if (git_oid_iszero(a)) {
+ printf("[new] %.20s %s\n", b_str, refname);
+ } else {
+ git_oid_fmt(a_str, a);
+ a_str[GIT_OID_HEXSZ] = '\0';
+ printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname);
+ }
+
+ return 0;
+}
+
int fetch(git_repository *repo, int argc, char **argv)
{
git_remote *remote = NULL;
@@ -78,7 +97,7 @@ int fetch(git_repository *repo, int argc, char **argv)
// 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 neede objects are available locally.
- if (git_remote_update_tips(remote) < 0)
+ if (git_remote_update_tips(remote, update_cb) < 0)
return -1;
git_remote_free(remote);
diff --git a/include/git2/remote.h b/include/git2/remote.h
index 8f49fddf1..09b927e28 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -183,12 +183,10 @@ GIT_EXTERN(void) git_remote_free(git_remote *remote);
/**
* Update the tips to the new state
*
- * Make sure that you only call this once you've successfully indexed
- * or expanded the packfile.
- *
* @param remote the remote to update
+ * @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value
*/
-GIT_EXTERN(int) git_remote_update_tips(git_remote *remote);
+GIT_EXTERN(int) git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b));
/**
* Return whether a string is a valid remote URL
diff --git a/src/remote.c b/src/remote.c
index bbb491dd8..e1937df85 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -309,11 +309,12 @@ int git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats
return git_fetch_download_pack(remote, bytes, stats);
}
-int git_remote_update_tips(git_remote *remote)
+int git_remote_update_tips(git_remote *remote, int (*cb)(const char *refname, const git_oid *a, const git_oid *b))
{
int error = 0;
unsigned int i = 0;
git_buf refname = GIT_BUF_INIT;
+ git_oid old;
git_vector *refs = &remote->refs;
git_remote_head *head;
git_reference *ref;
@@ -338,17 +339,36 @@ int git_remote_update_tips(git_remote *remote)
head = refs->contents[i];
if (git_refspec_transform_r(&refname, spec, head->name) < 0)
- break;
+ goto on_error;
+
+ error = git_reference_name_to_oid(&old, remote->repo, refname.ptr);
+ if (error < 0 && error != GIT_ENOTFOUND)
+ goto on_error;
+
+ if (error == GIT_ENOTFOUND)
+ memset(&old, 0, GIT_OID_RAWSZ);
+
+ if (!git_oid_cmp(&old, &head->oid))
+ continue;
if (git_reference_create_oid(&ref, remote->repo, refname.ptr, &head->oid, 1) < 0)
break;
git_reference_free(ref);
+
+ if (cb != NULL) {
+ if (cb(refname.ptr, &old, &head->oid) < 0)
+ goto on_error;
+ }
}
git_buf_free(&refname);
+ return 0;
+
+on_error:
+ git_buf_free(&refname);
+ return -1;
- return error;
}
int git_remote_connected(git_remote *remote)