#define COUNTED (1u << 2)
#define SHOWN (1u << 3)
#define TREECHANGE (1u << 4)
+#define TMP_MARK (1u << 5) /* for isolated cases; clean after use */
static const char rev_list_usage[] =
"git-rev-list [OPTION] <commit-id>... [ -- paths... ]\n"
" ordering output:\n"
" --merge-order [ --show-breaks ]\n"
" --topo-order\n"
+" --date-order\n"
" formatting output:\n"
" --parents\n"
-" --objects\n"
+" --objects | --objects-edge\n"
" --unpacked\n"
" --header | --pretty\n"
+" --abbrev=nr | --no-abbrev\n"
" special purpose:\n"
" --bisect"
;
static int tag_objects = 0;
static int tree_objects = 0;
static int blob_objects = 0;
+static int edge_hint = 0;
static int verbose_header = 0;
+static int abbrev = DEFAULT_ABBREV;
static int show_parents = 0;
static int hdr_termination = 0;
static const char *commit_prefix = "";
static int show_breaks = 0;
static int stop_traversal = 0;
static int topo_order = 0;
+static int lifo = 1;
static int no_merges = 0;
static const char **paths = NULL;
static int remove_empty_trees = 0;
if (show_parents) {
struct commit_list *parents = commit->parents;
while (parents) {
- printf(" %s", sha1_to_hex(parents->item->object.sha1));
+ struct object *o = &(parents->item->object);
parents = parents->next;
+ if (o->flags & TMP_MARK)
+ continue;
+ printf(" %s", sha1_to_hex(o->sha1));
+ o->flags |= TMP_MARK;
}
+ /* TMP_MARK is a general purpose flag that can
+ * be used locally, but the user should clean
+ * things up after it is done with them.
+ */
+ for (parents = commit->parents;
+ parents;
+ parents = parents->next)
+ parents->item->object.flags &= ~TMP_MARK;
}
if (commit_format == CMIT_FMT_ONELINE)
putchar(' ');
if (verbose_header) {
static char pretty_header[16384];
- pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), 0);
+ pretty_print_commit(commit_format, commit, ~0, pretty_header, sizeof(pretty_header), abbrev);
printf("%s%c", pretty_header, hdr_termination);
}
fflush(stdout);
die("unknown pending object %s (%s)", sha1_to_hex(obj->sha1), name);
}
while (objects) {
- /* An object with name "foo\n0000000000000000000000000000000000000000"
- * can be used confuse downstream git-pack-objects very badly.
+ /* An object with name "foo\n0000000..." can be used to
+ * confuse downstream git-pack-objects very badly.
*/
const char *ep = strchr(objects->name, '\n');
if (ep) {
return best;
}
+static void mark_edge_parents_uninteresting(struct commit *commit)
+{
+ struct commit_list *parents;
+
+ for (parents = commit->parents; parents; parents = parents->next) {
+ struct commit *parent = parents->item;
+ if (!(parent->object.flags & UNINTERESTING))
+ continue;
+ mark_tree_uninteresting(parent->tree);
+ if (edge_hint)
+ printf("-%s\n", sha1_to_hex(parent->object.sha1));
+ }
+}
+
static void mark_edges_uninteresting(struct commit_list *list)
{
for ( ; list; list = list->next) {
- struct commit_list *parents = list->item->parents;
+ struct commit *commit = list->item;
- for ( ; parents; parents = parents->next) {
- struct commit *commit = parents->item;
- if (commit->object.flags & UNINTERESTING)
- mark_tree_uninteresting(commit->tree);
+ if (commit->object.flags & UNINTERESTING) {
+ mark_tree_uninteresting(commit->tree);
+ continue;
}
+ mark_edge_parents_uninteresting(commit);
}
}
struct commit *commit;
unsigned char sha1[20];
+ /* accept -<digit>, like traditilnal "head" */
+ if ((*arg == '-') && isdigit(arg[1])) {
+ max_count = atoi(arg + 1);
+ continue;
+ }
if (!strcmp(arg, "-n")) {
if (++i >= argc)
die("-n requires an argument");
verbose_header = 1;
continue;
}
+ if (!strcmp(arg, "--no-abbrev")) {
+ abbrev = 0;
+ continue;
+ }
+ if (!strncmp(arg, "--abbrev=", 9)) {
+ abbrev = strtoul(arg + 9, NULL, 10);
+ if (abbrev && abbrev < MINIMUM_ABBREV)
+ abbrev = MINIMUM_ABBREV;
+ else if (40 < abbrev)
+ abbrev = 40;
+ continue;
+ }
if (!strncmp(arg, "--pretty", 8)) {
commit_format = get_commit_format(arg+8);
verbose_header = 1;
blob_objects = 1;
continue;
}
+ if (!strcmp(arg, "--objects-edge")) {
+ tag_objects = 1;
+ tree_objects = 1;
+ blob_objects = 1;
+ edge_hint = 1;
+ continue;
+ }
if (!strcmp(arg, "--unpacked")) {
unpacked = 1;
limited = 1;
}
if (!strcmp(arg, "--topo-order")) {
topo_order = 1;
+ lifo = 1;
+ limited = 1;
+ continue;
+ }
+ if (!strcmp(arg, "--date-order")) {
+ topo_order = 1;
+ lifo = 0;
limited = 1;
continue;
}
if (limited)
list = limit_list(list);
if (topo_order)
- sort_in_topological_order(&list);
+ sort_in_topological_order(&list, lifo);
show_commit_list(list);
} else {
#ifndef NO_OPENSSL