#include "pkt-line.h"
#include "quote.h"
#include "refs.h"
-#include <sys/wait.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <signal.h>
+#include "run-command.h"
static char *server_capabilities;
line[--len] = 0;
if (!strcmp(line, "NAK"))
return 0;
- if (!strncmp(line, "ACK ", 4)) {
+ if (!prefixcmp(line, "ACK ")) {
if (!get_sha1_hex(line+4, result_sha1)) {
if (strstr(line+45, "continue"))
return 2;
* +A:B means overwrite remote B with local A.
* +A is a shorthand for +A:A.
* A is a shorthand for A:A.
+ * :B means delete remote B.
*/
static struct refspec *parse_ref_spec(int nr_refspec, char **refspec)
{
*/
if (namelen != patlen &&
patlen != namelen - 5 &&
- strncmp(name, "refs/heads/", 11) &&
- strncmp(name, "refs/tags/", 10)) {
+ prefixcmp(name, "refs/heads/") &&
+ prefixcmp(name, "refs/tags/")) {
/* We want to catch the case where only weak
* matches are found and there are multiple
* matches, and where more than one strong
unsigned char sha1[20];
struct ref *ref;
int len;
+
+ if (!*name) {
+ ref = xcalloc(1, sizeof(*ref) + 20);
+ strcpy(ref->name, "(delete)");
+ hashclr(ref->new_sha1);
+ return ref;
+ }
if (get_sha1(name, sha1))
return NULL;
len = strlen(name) + 1;
break;
case 0:
/* The source could be in the get_sha1() format
- * not a reference name.
+ * not a reference name. :refs/other is a
+ * way to delete 'other' ref at the remote end.
*/
matched_src = try_explicit_object_name(rs[i].src);
if (matched_src)
if (colon) {
*colon = 0;
port = colon + 1;
+ if (!*port)
+ port = "<none>";
}
memset(&hints, 0, sizeof(hints));
gai = getaddrinfo(host, port, &hints, &ai);
if (gai)
- die("Unable to look up %s (%s)", host, gai_strerror(gai));
+ die("Unable to look up %s (port %s) (%s)", host, port, gai_strerror(gai));
for (ai0 = ai; ai; ai = ai->ai_next) {
sockfd = socket(ai->ai_family,
int sockfd = git_tcp_connect_sock(host);
fd[0] = sockfd;
- fd[1] = sockfd;
+ fd[1] = dup(sockfd);
}
{
const char *port = STR(DEFAULT_GIT_PORT);
char *colon, *end;
- int pipefd[2][2];
- pid_t pid;
+ const char *argv[4];
+ struct child_process proxy;
if (host[0] == '[') {
end = strchr(host + 1, ']');
port = colon + 1;
}
- if (pipe(pipefd[0]) < 0 || pipe(pipefd[1]) < 0)
- die("unable to create pipe pair for communication");
- pid = fork();
- if (!pid) {
- 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]);
- execlp(git_proxy_command, git_proxy_command, host, port, NULL);
- die("exec failed");
- }
- if (pid < 0)
- die("fork failed");
- fd[0] = pipefd[0][0];
- fd[1] = pipefd[1][1];
- close(pipefd[0][1]);
- close(pipefd[1][0]);
+ argv[0] = git_proxy_command;
+ argv[1] = host;
+ argv[2] = port;
+ argv[3] = NULL;
+ memset(&proxy, 0, sizeof(proxy));
+ proxy.argv = argv;
+ proxy.in = -1;
+ proxy.out = -1;
+ if (start_command(&proxy))
+ die("cannot start proxy %s", argv[0]);
+ fd[0] = proxy.out; /* read from proxy stdout */
+ fd[1] = proxy.in; /* write to proxy stdin */
}
#define MAX_CMD_LEN 1024