Update local tracking refs when pushing
authorDaniel Barkalow <barkalow@iabervon.org>
Wed, 16 May 2007 02:50:19 +0000 (22:50 -0400)
committerJunio C Hamano <junkio@cox.net>
Mon, 21 May 2007 04:32:57 +0000 (21:32 -0700)
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>
builtin-push.c
send-pack.c

index 0e602f3bf211d68a217c5aa1817469e514fa21a5..6084899b2b58c32f85f40d7ae487dbfbac460520 100644 (file)
@@ -178,8 +178,13 @@ static int do_push(const char *repo)
                if (!prefixcmp(dest, "http://") ||
                    !prefixcmp(dest, "https://"))
                        sender = "http-push";
-               else if (thin)
-                       argv[dest_argc++] = "--thin";
+               else {
+                       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[dest_argc++] = dest;
                while (dest_refspec_nr--)
index 3fe696cddc8d86fa6ed1dbbcc7817045547cc23a..2c0b19ba34d8103c0db09ed8fa2f556636c7fcaa 100644 (file)
@@ -177,7 +177,7 @@ static int receive_status(int in)
        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;
        int new_refs;
@@ -214,18 +214,19 @@ static int send_pack(int in, int out, int nr_refspec, char **refspec)
        new_refs = 0;
        for (ref = remote_refs; ref; ref = ref->next) {
                char old_hex[60], *new_hex;
-               int delete_ref;
+               int will_delete_ref;
 
                if (!ref->peer_ref)
                        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");
                        ret = -2;
                        continue;
                }
-               if (!delete_ref &&
+               if (!will_delete_ref &&
                    !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
                        if (verbose)
                                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 &&
-                   !delete_ref &&
+                   !will_delete_ref &&
                    !is_null_sha1(ref->old_sha1) &&
                    !ref->force) {
                        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);
-               if (!delete_ref)
+               if (!will_delete_ref)
                        new_refs++;
                strcpy(old_hex, sha1_to_hex(ref->old_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
                        packet_write(out, "%s %s %s",
                                     old_hex, new_hex, ref->name);
-               if (delete_ref)
+               if (will_delete_ref)
                        fprintf(stderr, "deleting '%s'\n", ref->name);
                else {
                        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",
                                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);
@@ -345,6 +368,8 @@ int main(int argc, char **argv)
        char **heads = NULL;
        int fd[2], ret;
        pid_t pid;
+       char *remote_name = NULL;
+       struct remote *remote = NULL;
 
        setup_git_directory();
        git_config(git_default_config);
@@ -362,6 +387,10 @@ int main(int argc, char **argv)
                                receivepack = arg + 7;
                                continue;
                        }
+                       if (!prefixcmp(arg, "--remote=")) {
+                               remote_name = arg + 9;
+                               continue;
+                       }
                        if (!strcmp(arg, "--all")) {
                                send_all = 1;
                                continue;
@@ -394,10 +423,18 @@ int main(int argc, char **argv)
                usage(send_pack_usage);
        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);
        if (pid < 0)
                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[1]);
        ret |= finish_connect(pid);