Use customized color for 'git-add --interactive'
output. `<slot>` may be `prompt`, `header`, `help` or `error`, for
four distinct types of normal output from interactive
- programs. The values of these variables may be specified as
+ commands. The values of these variables may be specified as
in color.branch.<slot>.
color.pager::
linkgit:git-instaweb[1].
interactive.singlekey::
- In interactive programs, allow the user to provide one-letter
+ In interactive commands, allow the user to provide one-letter
input with a single key (i.e., without hitting enter).
Currently this is used only by the `\--patch` mode of
linkgit:git-add[1]. Note that this setting is silently
pack.deltaCacheSize::
The maximum memory in bytes used for caching deltas in
- linkgit:git-pack-objects[1].
- A value of 0 means no limit. Defaults to 0.
+ linkgit:git-pack-objects[1] before writing them out to a pack.
+ This cache is used to speed up the writing object phase by not
+ having to recompute the final delta result once the best match
+ for all objects is found. Repacking large repositories on machines
+ which are tight with memory might be badly impacted by this though,
+ especially if this cache pushes the system into swapping.
+ A value of 0 means no limit. The smallest size of 1 byte may be
+ used to virtually disable this cache. Defaults to 256 MiB.
pack.deltaCacheLimit::
The maximum size of a delta, that is cached in
- linkgit:git-pack-objects[1]. Defaults to 1000.
+ linkgit:git-pack-objects[1]. This cache is used to speed up the
+ writing object phase by not having to recompute the final delta
+ result once the best match for all objects is found. Defaults to 1000.
pack.threads::
Specifies the number of threads to spawn when searching for best
DESCRIPTION
-----------
-Lists commit objects in reverse chronological order starting at the
-given commit(s), taking ancestry relationship into account. This is
-useful to produce human-readable log output.
+List commits that are reachable by following the `parent` links from the
+given commit(s), but exclude commits that are reachable from the one(s)
+given with a '{caret}' in front of them. The output is given in reverse
+chronological order by default.
-Commits which are stated with a preceding '{caret}' cause listing to
-stop at that point. Their parents are implied. Thus the following
-command:
+You can think of this as a set operation. Commits given on the command
+line form a set of commits that are reachable from any of them, and then
+commits reachable from any of the ones given with '{caret}' in front are
+subtracted from that set. The remaining commits are what comes out in the
+command's output. Various other options and paths parameters can be used
+to further limit the result.
+
+Thus, the following command:
-----------------------------------------------------------------------
$ git rev-list foo bar ^baz
-----------------------------------------------------------------------
-means "list all the commits which are included in 'foo' and 'bar', but
-not in 'baz'".
+means "list all the commits which are reachable from 'foo' or 'bar', but
+not from 'baz'".
A special notation "'<commit1>'..'<commit2>'" can be used as a
short-hand for "{caret}'<commit1>' '<commit2>'". For example, either of
$ git rev-list A...B
-----------------------------------------------------------------------
- 'git-rev-list' is a very essential git program, since it
+ 'rev-list' is a very essential git command, since it
provides the ability to build and traverse commit ancestry graphs. For
this reason, it has a lot of different options that enables it to be
used by commands as different as 'git-bisect' and
struct transport *transport =
transport_get(remote, url[i]);
int err;
+ int nonfastforward;
if (receivepack)
transport_set_option(transport,
TRANS_OPT_RECEIVEPACK, receivepack);
if (flags & TRANSPORT_PUSH_VERBOSE)
fprintf(stderr, "Pushing to %s\n", url[i]);
- err = transport_push(transport, refspec_nr, refspec, flags);
+ err = transport_push(transport, refspec_nr, refspec, flags,
+ &nonfastforward);
err |= transport_disconnect(transport);
if (!err)
continue;
error("failed to push some refs to '%s'", url[i]);
+ if (nonfastforward) {
+ printf("To prevent you from losing history, non-fast-forward updates were rejected.\n"
+ "Merge the remote changes before pushing again.\n"
+ "See 'non-fast forward' section of 'git push --help' for details.\n");
+ }
errs++;
}
return !!errs;
const char *repo = NULL; /* default repository */
struct option options[] = {
+ OPT_BIT('q', "quiet", &flags, "be quiet", TRANSPORT_PUSH_QUIET),
OPT_BIT('v', "verbose", &flags, "be verbose", TRANSPORT_PUSH_VERBOSE),
OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
OPT_BIT( 0 , "all", &flags, "push all refs", TRANSPORT_PUSH_ALL),
{
const char **argv;
int argc;
- int err;
if (flags & TRANSPORT_PUSH_MIRROR)
return error("http transport does not support mirror mode");
while (refspec_nr--)
argv[argc++] = *refspec++;
argv[argc] = NULL;
- err = run_command_v_opt(argv, RUN_GIT_CMD);
- switch (err) {
- case -ERR_RUN_COMMAND_FORK:
- error("unable to fork for %s", argv[0]);
- case -ERR_RUN_COMMAND_EXEC:
- error("unable to exec %s", argv[0]);
- break;
- case -ERR_RUN_COMMAND_WAITPID:
- case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
- case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
- case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
- error("%s died with strange error", argv[0]);
- }
- return !!err;
+ return !!run_command_v_opt(argv, RUN_GIT_CMD);
}
static struct ref *get_refs_via_curl(struct transport *transport, int for_push)
return (refs ? 0 : -1);
}
+static int push_had_errors(struct ref *ref)
+{
+ for (; ref; ref = ref->next) {
+ switch (ref->status) {
+ case REF_STATUS_NONE:
+ case REF_STATUS_UPTODATE:
+ case REF_STATUS_OK:
+ break;
+ default:
+ return 1;
+ }
+ }
+ return 0;
+}
+
static int refs_pushed(struct ref *ref)
{
for (; ref; ref = ref->next) {
}
static void print_push_status(const char *dest, struct ref *refs,
- int verbose, int porcelain)
+ int verbose, int porcelain, int * nonfastforward)
{
struct ref *ref;
int n = 0;
if (ref->status == REF_STATUS_OK)
n += print_one_push_status(ref, dest, n, porcelain);
+ *nonfastforward = 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;
}
}
args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
args.use_thin_pack = data->thin;
args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
+ args.quiet = !!(flags & TRANSPORT_PUSH_QUIET);
args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
ret = send_pack(&args, data->fd, data->conn, remote_refs,
}
int transport_push(struct transport *transport,
- int refspec_nr, const char **refspec, int flags)
+ int refspec_nr, const char **refspec, int flags,
+ int * nonfastforward)
{
verify_remote_names(refspec_nr, refspec);
struct ref *local_refs = get_local_heads();
int match_flags = MATCH_REFS_NONE;
int verbose = flags & TRANSPORT_PUSH_VERBOSE;
+ int quiet = flags & TRANSPORT_PUSH_QUIET;
int porcelain = flags & TRANSPORT_PUSH_PORCELAIN;
int ret;
ret = transport->push_refs(transport, remote_refs, flags);
- print_push_status(transport->url, remote_refs, verbose | porcelain, porcelain, nonfastforward);
+ if (!quiet || push_had_errors(remote_refs))
+ print_push_status(transport->url, remote_refs,
- verbose | porcelain, porcelain);
++ verbose | porcelain, porcelain,
++ nonfastforward);
if (!(flags & TRANSPORT_PUSH_DRY_RUN)) {
struct ref *ref;
#define TRANSPORT_PUSH_MIRROR 8
#define TRANSPORT_PUSH_VERBOSE 16
#define TRANSPORT_PUSH_PORCELAIN 32
+#define TRANSPORT_PUSH_QUIET 64
/* Returns a transport suitable for the url */
struct transport *transport_get(struct remote *, const char *);
const char *value);
int transport_push(struct transport *connection,
- int refspec_nr, const char **refspec, int flags);
+ int refspec_nr, const char **refspec, int flags,
+ int * nonfastforward);
const struct ref *transport_get_remote_refs(struct transport *transport);