Update local tracking refs when pushing

This also adds a --remote option to send-pack, which specifies the
configured remote being used. It is provided automatically by
git-push, and must match the url (which is still needed, since there
could be multiple urls).

Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
maint
Daniel Barkalow 2007-05-15 22:50:19 -04:00 committed by Junio C Hamano
parent 5d46c9d41f
commit b516968ff6
2 changed files with 53 additions and 11 deletions

View File

@ -178,8 +178,13 @@ static int do_push(const char *repo)
if (!prefixcmp(dest, "http://") || if (!prefixcmp(dest, "http://") ||
!prefixcmp(dest, "https://")) !prefixcmp(dest, "https://"))
sender = "http-push"; sender = "http-push";
else if (thin) else {
argv[dest_argc++] = "--thin"; char *rem = xmalloc(strlen(remote->name) + 10);
sprintf(rem, "--remote=%s", remote->name);
argv[dest_argc++] = rem;
if (thin)
argv[dest_argc++] = "--thin";
}
argv[0] = sender; argv[0] = sender;
argv[dest_argc++] = dest; argv[dest_argc++] = dest;
while (dest_refspec_nr--) while (dest_refspec_nr--)

View File

@ -177,7 +177,7 @@ static int receive_status(int in)
return ret; return ret;
} }


static int send_pack(int in, int out, int nr_refspec, char **refspec) static int send_pack(int in, int out, struct remote *remote, int nr_refspec, char **refspec)
{ {
struct ref *ref; struct ref *ref;
int new_refs; int new_refs;
@ -214,18 +214,19 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
new_refs = 0; new_refs = 0;
for (ref = remote_refs; ref; ref = ref->next) { for (ref = remote_refs; ref; ref = ref->next) {
char old_hex[60], *new_hex; char old_hex[60], *new_hex;
int delete_ref; int will_delete_ref;


if (!ref->peer_ref) if (!ref->peer_ref)
continue; continue;


delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
if (delete_ref && !allow_deleting_refs) { will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
if (will_delete_ref && !allow_deleting_refs) {
error("remote does not support deleting refs"); error("remote does not support deleting refs");
ret = -2; ret = -2;
continue; continue;
} }
if (!delete_ref && if (!will_delete_ref &&
!hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) { !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
if (verbose) if (verbose)
fprintf(stderr, "'%s': up-to-date\n", ref->name); fprintf(stderr, "'%s': up-to-date\n", ref->name);
@ -252,7 +253,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
*/ */


if (!force_update && if (!force_update &&
!delete_ref && !will_delete_ref &&
!is_null_sha1(ref->old_sha1) && !is_null_sha1(ref->old_sha1) &&
!ref->force) { !ref->force) {
if (!has_sha1_file(ref->old_sha1) || if (!has_sha1_file(ref->old_sha1) ||
@ -276,7 +277,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
} }
} }
hashcpy(ref->new_sha1, ref->peer_ref->new_sha1); hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
if (!delete_ref) if (!will_delete_ref)
new_refs++; new_refs++;
strcpy(old_hex, sha1_to_hex(ref->old_sha1)); strcpy(old_hex, sha1_to_hex(ref->old_sha1));
new_hex = sha1_to_hex(ref->new_sha1); new_hex = sha1_to_hex(ref->new_sha1);
@ -291,7 +292,7 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
else else
packet_write(out, "%s %s %s", packet_write(out, "%s %s %s",
old_hex, new_hex, ref->name); old_hex, new_hex, ref->name);
if (delete_ref) if (will_delete_ref)
fprintf(stderr, "deleting '%s'\n", ref->name); fprintf(stderr, "deleting '%s'\n", ref->name);
else { else {
fprintf(stderr, "updating '%s'", ref->name); fprintf(stderr, "updating '%s'", ref->name);
@ -301,6 +302,28 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
fprintf(stderr, "\n from %s\n to %s\n", fprintf(stderr, "\n from %s\n to %s\n",
old_hex, new_hex); old_hex, new_hex);
} }
if (remote) {
struct refspec rs;
rs.src = ref->name;
remote_find_tracking(remote, &rs);
if (rs.dst) {
struct ref_lock *lock;
fprintf(stderr, " Also local %s\n", rs.dst);
if (will_delete_ref) {
if (delete_ref(rs.dst, NULL)) {
error("Failed to delete");
}
} else {
lock = lock_any_ref_for_update(rs.dst, NULL, 0);
if (!lock)
error("Failed to lock");
else
write_ref_sha1(lock, ref->new_sha1,
"update by push");
}
free(rs.dst);
}
}
} }


packet_flush(out); packet_flush(out);
@ -345,6 +368,8 @@ int main(int argc, char **argv)
char **heads = NULL; char **heads = NULL;
int fd[2], ret; int fd[2], ret;
pid_t pid; pid_t pid;
char *remote_name = NULL;
struct remote *remote = NULL;


setup_git_directory(); setup_git_directory();
git_config(git_default_config); git_config(git_default_config);
@ -362,6 +387,10 @@ int main(int argc, char **argv)
receivepack = arg + 7; receivepack = arg + 7;
continue; continue;
} }
if (!prefixcmp(arg, "--remote=")) {
remote_name = arg + 9;
continue;
}
if (!strcmp(arg, "--all")) { if (!strcmp(arg, "--all")) {
send_all = 1; send_all = 1;
continue; continue;
@ -394,10 +423,18 @@ int main(int argc, char **argv)
usage(send_pack_usage); usage(send_pack_usage);
verify_remote_names(nr_heads, heads); verify_remote_names(nr_heads, heads);


if (remote_name) {
remote = remote_get(remote_name);
if (!remote_has_uri(remote, dest)) {
die("Destination %s is not a uri for %s",
dest, remote_name);
}
}

pid = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0); pid = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
if (pid < 0) if (pid < 0)
return 1; return 1;
ret = send_pack(fd[0], fd[1], nr_heads, heads); ret = send_pack(fd[0], fd[1], remote, nr_heads, heads);
close(fd[0]); close(fd[0]);
close(fd[1]); close(fd[1]);
ret |= finish_connect(pid); ret |= finish_connect(pid);