summaryrefslogtreecommitdiff
path: root/send-pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'send-pack.c')
-rw-r--r--send-pack.c57
1 files changed, 48 insertions, 9 deletions
diff --git a/send-pack.c b/send-pack.c
index 83ee87dcf8..fecbda981b 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -4,6 +4,7 @@
#include "refs.h"
#include "pkt-line.h"
#include "run-command.h"
+#include "remote.h"
static const char send_pack_usage[] =
"git-send-pack [--all] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
@@ -176,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;
@@ -213,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);
@@ -251,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) ||
@@ -275,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);
@@ -290,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);
@@ -300,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);
@@ -330,6 +354,7 @@ static void verify_remote_names(int nr_heads, char **heads)
case -2: /* ok but a single level -- that is fine for
* a match pattern.
*/
+ case -3: /* ok but ends with a pattern-match character */
continue;
}
die("remote part of refspec is not a valid name in %s",
@@ -344,6 +369,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);
@@ -361,6 +388,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;
@@ -393,10 +424,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);