- snprintf(command, sizeof(command), "%s %s", exec, path);
- if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
- die("unable to create pipe pair for communication");
- if (!fork()) {
- dup2(pipefd[1][0], 0);
- dup2(pipefd[0][1], 1);
- close(pipefd[0][0]);
- close(pipefd[0][1]);
- close(pipefd[1][0]);
- close(pipefd[1][1]);
- if (host)
- execlp("ssh", "ssh", host, command, NULL);
- else
- execlp(host, command, NULL);
- die("exec failed");
- }
- fd[0] = pipefd[0][0];
- fd[1] = pipefd[1][1];
- close(pipefd[0][1]);
- close(pipefd[1][0]);
+
+ len = strlen(refname)+1;
+ ref = xmalloc(sizeof(*ref) + len);
+ memset(ref->old_sha1, 0, 20);
+ memcpy(ref->new_sha1, sha1, 20);
+ memcpy(ref->name, refname, len);
+ ref->next = NULL;
+ *local_last_ref = ref;
+ local_last_ref = &ref->next;
+ return 0;
+}
+
+static int send_pack(int in, int out, int nr_match, char **match)
+{
+ struct ref *ref_list, **last_ref;
+ struct ref *ref;
+ int new_refs;
+
+ /* First we get all heads, whether matching or not.. */
+ last_ref = get_remote_heads(in, &ref_list, 0, NULL);
+
+ /*
+ * Go through the refs, see if we want to update
+ * any of them..
+ */
+ for (ref = ref_list; ref; ref = ref->next) {
+ unsigned char new_sha1[20];
+ char *name = ref->name;
+
+ if (nr_match && !path_match(name, nr_match, match))
+ continue;
+
+ if (read_ref(name, new_sha1) < 0)
+ continue;
+
+ if (!memcmp(ref->old_sha1, new_sha1, 20)) {
+ fprintf(stderr, "'%s' unchanged\n", name);
+ continue;
+ }
+
+ if (!ref_newer(new_sha1, ref->old_sha1)) {
+ error("remote '%s' isn't a strict parent of local", name);
+ continue;
+ }
+
+ /* Ok, mark it for update */
+ memcpy(ref->new_sha1, new_sha1, 20);
+ }
+
+ /*
+ * See if we have any refs that the other end didn't have
+ */
+ if (nr_match) {
+ local_ref_nr_match = nr_match;
+ local_ref_match = match;
+ local_ref_list = ref_list;
+ local_last_ref = last_ref;
+ for_each_ref(try_to_match);
+ }
+
+ /*
+ * Finally, tell the other end!
+ */
+ new_refs = 0;
+ for (ref = ref_list; ref; ref = ref->next) {
+ char old_hex[60], *new_hex;
+ if (is_zero_sha1(ref->new_sha1))
+ continue;
+ new_refs++;
+ strcpy(old_hex, sha1_to_hex(ref->old_sha1));
+ new_hex = sha1_to_hex(ref->new_sha1);
+ packet_write(out, "%s %s %s", old_hex, new_hex, ref->name);
+ fprintf(stderr, "'%s': updating from %s to %s\n", ref->name, old_hex, new_hex);
+ }
+
+ packet_flush(out);
+ if (new_refs)
+ pack_objects(out, ref_list);
+ close(out);