summaryrefslogtreecommitdiff
path: root/transport.c
diff options
context:
space:
mode:
Diffstat (limited to 'transport.c')
-rw-r--r--transport.c59
1 files changed, 39 insertions, 20 deletions
diff --git a/transport.c b/transport.c
index e2cfabd..8ce3936 100644
--- a/transport.c
+++ b/transport.c
@@ -573,7 +573,7 @@ static int push_had_errors(struct ref *ref)
return 0;
}
-static int refs_pushed(struct ref *ref)
+int transport_refs_pushed(struct ref *ref)
{
for (; ref; ref = ref->next) {
switch(ref->status) {
@@ -587,7 +587,7 @@ static int refs_pushed(struct ref *ref)
return 0;
}
-static void update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
+void transport_update_tracking_ref(struct remote *remote, struct ref *ref, int verbose)
{
struct refspec rs;
@@ -609,8 +609,6 @@ static void update_tracking_ref(struct remote *remote, struct ref *ref, int verb
}
}
-#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
-
static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg, int porcelain)
{
if (porcelain) {
@@ -623,7 +621,7 @@ static void print_ref_status(char flag, const char *summary, struct ref *to, str
else
fprintf(stdout, "%s\n", summary);
} else {
- fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
+ fprintf(stderr, " %c %-*s ", flag, TRANSPORT_SUMMARY_WIDTH, summary);
if (from)
fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
else
@@ -675,7 +673,7 @@ static void print_ok_ref_status(struct ref *ref, int porcelain)
static int print_one_push_status(struct ref *ref, const char *dest, int count, int porcelain)
{
if (!count)
- fprintf(stderr, "To %s\n", dest);
+ fprintf(porcelain ? stdout : stderr, "To %s\n", dest);
switch(ref->status) {
case REF_STATUS_NONE:
@@ -711,8 +709,8 @@ static int print_one_push_status(struct ref *ref, const char *dest, int count, i
return 1;
}
-static void print_push_status(const char *dest, struct ref *refs,
- int verbose, int porcelain, int * nonfastforward)
+void transport_print_push_status(const char *dest, struct ref *refs,
+ int verbose, int porcelain, int *nonfastforward)
{
struct ref *ref;
int n = 0;
@@ -738,7 +736,7 @@ static void print_push_status(const char *dest, struct ref *refs,
}
}
-static void verify_remote_names(int nr_heads, const char **heads)
+void transport_verify_remote_names(int nr_heads, const char **heads)
{
int i;
@@ -791,6 +789,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
args.verbose = (transport->verbose > 0);
args.quiet = (transport->verbose < 0);
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
+ args.porcelain = !!(flags & TRANSPORT_PUSH_PORCELAIN);
ret = send_pack(&args, data->fd, data->conn, remote_refs,
&data->extra_have);
@@ -872,6 +871,21 @@ static int is_file(const char *url)
return S_ISREG(buf.st_mode);
}
+static int isurlschemechar(int first_flag, int ch)
+{
+ /*
+ * The set of valid URL schemes, as per STD66 (RFC3986) is
+ * '[A-Za-z][A-Za-z0-9+.-]*'. But use sightly looser check
+ * of '[A-Za-z0-9][A-Za-z0-9+.-]*' because earlier version
+ * of check used '[A-Za-z0-9]+' so not to break any remote
+ * helpers.
+ */
+ int alphanumeric, special;
+ alphanumeric = ch > 0 && isalnum(ch);
+ special = ch == '+' || ch == '-' || ch == '.';
+ return alphanumeric || (!first_flag && special);
+}
+
static int is_url(const char *url)
{
const char *url2, *first_slash;
@@ -896,7 +910,7 @@ static int is_url(const char *url)
*/
url2 = url;
while (url2 < first_slash - 1) {
- if (!isalnum((unsigned char)*url2))
+ if (!isurlschemechar(url2 == url, (unsigned char)*url2))
return 0;
url2++;
}
@@ -920,6 +934,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
if (!remote)
die("No remote provided to transport_get()");
+ ret->got_remote_refs = 0;
ret->remote = remote;
helper = remote->foreign_vcs;
@@ -931,7 +946,7 @@ struct transport *transport_get(struct remote *remote, const char *url)
if (url) {
const char *p = url;
- while (isalnum(*p))
+ while (isurlschemechar(p == url, *p))
p++;
if (!prefixcmp(p, "::"))
helper = xstrndup(url, p - url);
@@ -1039,7 +1054,7 @@ int transport_push(struct transport *transport,
int *nonfastforward)
{
*nonfastforward = 0;
- verify_remote_names(refspec_nr, refspec);
+ transport_verify_remote_names(refspec_nr, refspec);
if (transport->push) {
/* Maybe FIXME. But no important transport uses this case. */
@@ -1056,7 +1071,7 @@ int transport_push(struct transport *transport,
int quiet = (transport->verbose < 0);
int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
int pretend = flags & TRANSPORT_PUSH_DRY_RUN;
- int ret, err;
+ int push_ret, ret, err;
if (flags & TRANSPORT_PUSH_ALL)
match_flags |= MATCH_REFS_ALL;
@@ -1072,13 +1087,12 @@ int transport_push(struct transport *transport,
flags & TRANSPORT_PUSH_MIRROR,
flags & TRANSPORT_PUSH_FORCE);
- ret = transport->push_refs(transport, remote_refs, flags);
+ push_ret = transport->push_refs(transport, remote_refs, flags);
err = push_had_errors(remote_refs);
-
- ret |= err;
+ ret = push_ret | err;
if (!quiet || err)
- print_push_status(transport->url, remote_refs,
+ transport_print_push_status(transport->url, remote_refs,
verbose | porcelain, porcelain,
nonfastforward);
@@ -1088,11 +1102,14 @@ int transport_push(struct transport *transport,
if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
struct ref *ref;
for (ref = remote_refs; ref; ref = ref->next)
- update_tracking_ref(transport->remote, ref, verbose);
+ transport_update_tracking_ref(transport->remote, ref, verbose);
}
- if (!quiet && !ret && !refs_pushed(remote_refs))
+ if (porcelain && !push_ret)
+ puts("Done");
+ else if (!quiet && !ret && !transport_refs_pushed(remote_refs))
fprintf(stderr, "Everything up-to-date\n");
+
return ret;
}
return 1;
@@ -1100,8 +1117,10 @@ int transport_push(struct transport *transport,
const struct ref *transport_get_remote_refs(struct transport *transport)
{
- if (!transport->remote_refs)
+ if (!transport->got_remote_refs) {
transport->remote_refs = transport->get_refs_list(transport, 0);
+ transport->got_remote_refs = 1;
+ }
return transport->remote_refs;
}