int nr_heads, struct ref **to_fetch)
{
struct git_transport_data *data = transport->data;
- char **heads = xmalloc(nr_heads * sizeof(*heads));
- char **origh = xmalloc(nr_heads * sizeof(*origh));
+ struct string_list sought = STRING_LIST_INIT_DUP;
const struct ref *refs;
char *dest = xstrdup(transport->url);
struct fetch_pack_args args;
args.depth = data->options.depth;
for (i = 0; i < nr_heads; i++)
- origh[i] = heads[i] = xstrdup(to_fetch[i]->name);
+ string_list_append(&sought, to_fetch[i]->name);
if (!data->got_remote_heads) {
connect_setup(transport, 0, 0);
refs = fetch_pack(&args, data->fd, data->conn,
refs_tmp ? refs_tmp : transport->remote_refs,
- dest, nr_heads, heads, &transport->pack_lockfile);
+ dest, &sought, &transport->pack_lockfile);
close(data->fd[0]);
close(data->fd[1]);
if (finish_connect(data->conn))
free_refs(refs_tmp);
- for (i = 0; i < nr_heads; i++)
- free(origh[i]);
- free(origh);
- free(heads);
+ string_list_clear(&sought, 0);
free(dest);
return (refs ? 0 : -1);
}
const char *msg;
strcpy(quickref, status_abbrev(ref->old_sha1));
- if (ref->nonfastforward) {
+ if (ref->requires_force) {
strcat(quickref, "...");
type = '+';
msg = "forced update";
print_ref_status('!', "[rejected]", ref, ref->peer_ref,
"non-fast-forward", porcelain);
break;
+ case REF_STATUS_REJECT_ALREADY_EXISTS:
+ print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+ "already exists", porcelain);
+ break;
case REF_STATUS_REMOTE_REJECT:
print_ref_status('!', "[remote rejected]", ref,
ref->deletion ? NULL : ref->peer_ref,
}
void transport_print_push_status(const char *dest, struct ref *refs,
- int verbose, int porcelain, int *nonfastforward)
+ int verbose, int porcelain, unsigned int *reject_reasons)
{
struct ref *ref;
int n = 0;
+ unsigned char head_sha1[20];
+ char *head;
+
+ head = resolve_refdup("HEAD", head_sha1, 1, NULL);
if (verbose) {
for (ref = refs; ref; ref = ref->next)
if (ref->status == REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
- *nonfastforward = 0;
+ *reject_reasons = 0;
for (ref = refs; ref; ref = ref->next) {
if (ref->status != REF_STATUS_NONE &&
ref->status != REF_STATUS_UPTODATE &&
ref->status != REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
- if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD)
- *nonfastforward = 1;
+ if (ref->status == REF_STATUS_REJECT_NONFASTFORWARD) {
+ if (!strcmp(head, ref->name))
+ *reject_reasons |= REJECT_NON_FF_HEAD;
+ else
+ *reject_reasons |= REJECT_NON_FF_OTHER;
+ } else if (ref->status == REF_STATUS_REJECT_ALREADY_EXISTS) {
+ *reject_reasons |= REJECT_ALREADY_EXISTS;
+ }
}
}
* Rules used to determine whether to report progress (processing aborts
* when a rule is satisfied):
*
- * 1. Report progress, if force_progress is 1 (ie. --progress).
- * 2. Don't report progress, if verbosity < 0 (ie. -q/--quiet ).
- * 3. Report progress if isatty(2) is 1.
+ * . Report progress, if force_progress is 1 (ie. --progress).
+ * . Don't report progress, if force_progress is 0 (ie. --no-progress).
+ * . Don't report progress, if verbosity < 0 (ie. -q/--quiet ).
+ * . Report progress if isatty(2) is 1.
**/
- transport->progress = force_progress || (verbosity >= 0 && isatty(2));
+ if (force_progress >= 0)
+ transport->progress = !!force_progress;
+ else
+ transport->progress = verbosity >= 0 && isatty(2);
}
static void die_with_unpushed_submodules(struct string_list *needs_pushing)
int transport_push(struct transport *transport,
int refspec_nr, const char **refspec, int flags,
- int *nonfastforward)
+ unsigned int *reject_reasons)
{
- *nonfastforward = 0;
+ *reject_reasons = 0;
transport_verify_remote_names(refspec_nr, refspec);
if (transport->push) {
match_flags |= MATCH_REFS_ALL;
if (flags & TRANSPORT_PUSH_MIRROR)
match_flags |= MATCH_REFS_MIRROR;
+ if (flags & TRANSPORT_PUSH_PRUNE)
+ match_flags |= MATCH_REFS_PRUNE;
if (match_push_refs(local_refs, &remote_refs,
refspec_nr, refspec, match_flags)) {
if (!quiet || err)
transport_print_push_status(transport->url, remote_refs,
verbose | porcelain, porcelain,
- nonfastforward);
+ reject_reasons);
if (flags & TRANSPORT_PUSH_SET_UPSTREAM)
set_upstreams(transport, remote_refs, pretend);
}
/*
- * Strip username (and password) from an url and return
+ * Strip username (and password) from a URL and return
* it in a newly allocated string.
*/
char *transport_anonymize_url(const char *url)