@ -280,9 +280,9 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt,
@@ -280,9 +280,9 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt,
static int prepare_submodule_summary(struct rev_info *rev, const char *path,
struct commit *left, struct commit *right,
int *fast_forward, int *fast_backward)
struct commit_list *merge_bases)
{
struct commit_list *merge_bases, *list;
struct commit_list *list;
init_revisions(rev, NULL);
setup_revisions(0, NULL, rev, NULL);
@ -291,13 +291,6 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
@@ -291,13 +291,6 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path,
left->object.flags |= SYMMETRIC_LEFT;
add_pending_object(rev, &left->object, path);
add_pending_object(rev, &right->object, path);
merge_bases = get_merge_bases(left, right);
if (merge_bases) {
if (merge_bases->item == left)
*fast_forward = 1;
else if (merge_bases->item == right)
*fast_backward = 1;
}
for (list = merge_bases; list; list = list->next) {
list->item->object.flags |= UNINTERESTING;
add_pending_object(rev, &list->item->object,
@ -335,31 +328,23 @@ static void print_submodule_summary(struct rev_info *rev, FILE *f,
@@ -335,31 +328,23 @@ static void print_submodule_summary(struct rev_info *rev, FILE *f,
strbuf_release(&sb);
}
void show_submodule_summary(FILE *f, const char *path,
/* Helper function to display the submodule header line prior to the full
* summary output. If it can locate the submodule objects directory it will
* attempt to lookup both the left and right commits and put them into the
* left and right pointers.
*/
static void show_submodule_header(FILE *f, const char *path,
const char *line_prefix,
struct object_id *one, struct object_id *two,
unsigned dirty_submodule, const char *meta,
const char *del, const char *add, const char *reset)
const char *reset,
struct commit **left, struct commit **right,
struct commit_list **merge_bases)
{
struct rev_info rev;
struct commit *left = NULL, *right = NULL;
const char *message = NULL;
struct strbuf sb = STRBUF_INIT;
int fast_forward = 0, fast_backward = 0;
if (is_null_oid(two))
message = "(submodule deleted)";
else if (add_submodule_odb(path))
message = "(not initialized)";
else if (is_null_oid(one))
message = "(new submodule)";
else if (!(left = lookup_commit_reference(one->hash)) ||
!(right = lookup_commit_reference(two->hash)))
message = "(commits not present)";
else if (prepare_submodule_summary(&rev, path, left, right,
&fast_forward, &fast_backward))
message = "(revision walker failed)";
if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED)
fprintf(f, "%sSubmodule %s contains untracked content\n",
line_prefix, path);
@ -367,11 +352,46 @@ void show_submodule_summary(FILE *f, const char *path,
@@ -367,11 +352,46 @@ void show_submodule_summary(FILE *f, const char *path,
fprintf(f, "%sSubmodule %s contains modified content\n",
line_prefix, path);
if (is_null_oid(one))
message = "(new submodule)";
else if (is_null_oid(two))
message = "(submodule deleted)";
if (add_submodule_odb(path)) {
if (!message)
message = "(not initialized)";
goto output_header;
}
/*
* Attempt to lookup the commit references, and determine if this is
* a fast forward or fast backwards update.
*/
*left = lookup_commit_reference(one->hash);
*right = lookup_commit_reference(two->hash);
/*
* Warn about missing commits in the submodule project, but only if
* they aren't null.
*/
if ((!is_null_oid(one) && !*left) ||
(!is_null_oid(two) && !*right))
message = "(commits not present)";
*merge_bases = get_merge_bases(*left, *right);
if (*merge_bases) {
if ((*merge_bases)->item == *left)
fast_forward = 1;
else if ((*merge_bases)->item == *right)
fast_backward = 1;
}
if (!oidcmp(one, two)) {
strbuf_release(&sb);
return;
}
output_header:
strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path,
find_unique_abbrev(one->hash, DEFAULT_ABBREV));
if (!fast_backward && !fast_forward)
@ -383,16 +403,45 @@ void show_submodule_summary(FILE *f, const char *path,
@@ -383,16 +403,45 @@ void show_submodule_summary(FILE *f, const char *path,
strbuf_addf(&sb, "%s:%s\n", fast_backward ? " (rewind)" : "", reset);
fwrite(sb.buf, sb.len, 1, f);
if (!message) /* only NULL if we succeeded in setting up the walk */
print_submodule_summary(&rev, f, line_prefix, del, add, reset);
if (left)
clear_commit_marks(left, ~0);
if (right)
clear_commit_marks(right, ~0);
strbuf_release(&sb);
}
void show_submodule_summary(FILE *f, const char *path,
const char *line_prefix,
struct object_id *one, struct object_id *two,
unsigned dirty_submodule, const char *meta,
const char *del, const char *add, const char *reset)
{
struct rev_info rev;
struct commit *left = NULL, *right = NULL;
struct commit_list *merge_bases = NULL;
show_submodule_header(f, path, line_prefix, one, two, dirty_submodule,
meta, reset, &left, &right, &merge_bases);
/*
* If we don't have both a left and a right pointer, there is no
* reason to try and display a summary. The header line should contain
* all the information the user needs.
*/
if (!left || !right)
goto out;
/* Treat revision walker failure the same as missing commits */
if (prepare_submodule_summary(&rev, path, left, right, merge_bases)) {
fprintf(f, "%s(revision walker failed)\n", line_prefix);
goto out;
}
print_submodule_summary(&rev, f, line_prefix, del, add, reset);
out:
if (merge_bases)
free_commit_list(merge_bases);
clear_commit_marks(left, ~0);
clear_commit_marks(right, ~0);
}
void set_config_fetch_recurse_submodules(int value)
{
config_fetch_recurse_submodules = value;