summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/push.c6
-rw-r--r--builtin/send-pack.c4
-rw-r--r--send-pack.h1
-rwxr-xr-xt/t5516-fetch-push.sh50
-rw-r--r--transport.c15
5 files changed, 67 insertions, 9 deletions
diff --git a/builtin/push.c b/builtin/push.c
index f7bc2b2..235ca12 100644
--- a/builtin/push.c
+++ b/builtin/push.c
@@ -124,9 +124,9 @@ static int push_with_options(struct transport *transport, int flags)
return 0;
if (nonfastforward && advice_push_nonfastforward) {
- printf("To prevent you from losing history, non-fast-forward updates were rejected\n"
- "Merge the remote changes before pushing again. See the 'Note about\n"
- "fast-forwards' section of 'git push --help' for details.\n");
+ fprintf(stderr, "To prevent you from losing history, non-fast-forward updates were rejected\n"
+ "Merge the remote changes before pushing again. See the 'Note about\n"
+ "fast-forwards' section of 'git push --help' for details.\n");
}
return 1;
diff --git a/builtin/send-pack.c b/builtin/send-pack.c
index 6019eac..481602d 100644
--- a/builtin/send-pack.c
+++ b/builtin/send-pack.c
@@ -361,6 +361,10 @@ int send_pack(struct send_pack_args *args,
if (ret < 0)
return ret;
+
+ if (args->porcelain)
+ return 0;
+
for (ref = remote_refs; ref; ref = ref->next) {
switch (ref->status) {
case REF_STATUS_NONE:
diff --git a/send-pack.h b/send-pack.h
index 28141ac..60b4ba6 100644
--- a/send-pack.h
+++ b/send-pack.h
@@ -4,6 +4,7 @@
struct send_pack_args {
unsigned verbose:1,
quiet:1,
+ porcelain:1,
send_mirror:1,
force_update:1,
use_thin_pack:1,
diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh
index 0f04b2e..2de98e6 100755
--- a/t/t5516-fetch-push.sh
+++ b/t/t5516-fetch-push.sh
@@ -660,4 +660,54 @@ test_expect_success 'push with branches containing #' '
git checkout master
'
+test_expect_success 'push --porcelain' '
+ mk_empty &&
+ echo >.git/foo "To testrepo" &&
+ echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new branch]" &&
+ echo >>.git/foo "Done" &&
+ git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master &&
+ (
+ cd testrepo &&
+ r=$(git show-ref -s --verify refs/remotes/origin/master) &&
+ test "z$r" = "z$the_commit" &&
+ test 1 = $(git for-each-ref refs/remotes/origin | wc -l)
+ ) &&
+ test_cmp .git/foo .git/bar
+'
+
+test_expect_success 'push --porcelain bad url' '
+ mk_empty &&
+ test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master &&
+ test_must_fail grep -q Done .git/bar
+'
+
+test_expect_success 'push --porcelain rejected' '
+ mk_empty &&
+ git push testrepo refs/heads/master:refs/remotes/origin/master &&
+ (cd testrepo &&
+ git reset --hard origin/master^
+ git config receive.denyCurrentBranch true) &&
+
+ echo >.git/foo "To testrepo" &&
+ echo >>.git/foo "! refs/heads/master:refs/heads/master [remote rejected] (branch is currently checked out)" &&
+
+ test_must_fail git push >.git/bar --porcelain testrepo refs/heads/master:refs/heads/master &&
+ test_cmp .git/foo .git/bar
+'
+
+test_expect_success 'push --porcelain --dry-run rejected' '
+ mk_empty &&
+ git push testrepo refs/heads/master:refs/remotes/origin/master &&
+ (cd testrepo &&
+ git reset --hard origin/master
+ git config receive.denyCurrentBranch true) &&
+
+ echo >.git/foo "To testrepo" &&
+ echo >>.git/foo "! refs/heads/master^:refs/heads/master [rejected] (non-fast-forward)" &&
+ echo >>.git/foo "Done" &&
+
+ test_must_fail git push >.git/bar --porcelain --dry-run testrepo refs/heads/master^:refs/heads/master &&
+ test_cmp .git/foo .git/bar
+'
+
test_done
diff --git a/transport.c b/transport.c
index f07bd33..825be94 100644
--- a/transport.c
+++ b/transport.c
@@ -673,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:
@@ -789,6 +789,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re
args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
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);
@@ -1049,7 +1050,7 @@ int transport_push(struct transport *transport,
int quiet = flags & TRANSPORT_PUSH_QUIET;
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;
@@ -1065,10 +1066,9 @@ 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)
transport_print_push_status(transport->url, remote_refs,
@@ -1084,8 +1084,11 @@ int transport_push(struct transport *transport,
transport_update_tracking_ref(transport->remote, ref, verbose);
}
- if (!quiet && !ret && !transport_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;