remote: run a callback when updating the branch tips

This allows the caller to update an internal structure or update the
user output with the tips that were updated.

While in the area, only try to update the ref if the value is
different from its old one.
This commit is contained in:
Carlos Martín Nieto 2012-04-25 12:13:20 +02:00
parent 2e3a0055d1
commit f184836bd2
4 changed files with 46 additions and 9 deletions

View File

@ -2,7 +2,7 @@ default: all
CC = gcc
CFLAGS += -g
CFLAGS += -I../../include -L../../ -lgit2
CFLAGS += -I../../include -L../../ -lgit2 -lpthread
OBJECTS = \
git2.o \

View File

@ -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);

View File

@ -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

View File

@ -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)