Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -1483,6 +1483,10 @@ static int git_status_config(const char *k, const char *v,
s->show_stash = git_config_bool(k, v);
return 0;
}
if (!strcmp(k, "status.showdiffstat")) {
s->show_diffstat = git_config_bool(k, v);
return 0;
}
if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
s->use_color = git_config_colorbool(k, v);
return 0;
Expand Down
47 changes: 47 additions & 0 deletions t/t7508-status.sh
Original file line number Diff line number Diff line change
Expand Up @@ -1785,4 +1785,51 @@ test_expect_success EXPENSIVE 'status does not re-read unchanged 4 or 8 GiB file
)
'

test_expect_success 'status shows diffstat for modified files' '
(
mkdir diffstat-test &&
cd diffstat-test &&
git init &&
echo "line1" >file.txt &&
echo "line2" >>file.txt &&
git add file.txt &&
git commit -m "initial" &&
echo "line3" >>file.txt &&
git status >output &&
grep "+1" output
)
'

test_expect_success 'status shows only additions for new staged files' '
(
cd diffstat-test &&
echo "new content" >newfile.txt &&
echo "more content" >>newfile.txt &&
git add newfile.txt &&
git status >output &&
grep "+2" output &&
! grep "| -" output
)
'

test_expect_success 'status shows only deletions for deleted staged files' '
(
cd diffstat-test &&
git checkout file.txt &&
git rm -f file.txt &&
git status >output &&
grep "\-2" output
)
'

test_expect_success 'status.showDiffstat=false hides line counts' '
(
cd diffstat-test &&
git reset HEAD &&
echo "modified" >>file.txt &&
git -c status.showDiffstat=false status >output &&
! grep "+1" output
)
'

test_done
85 changes: 83 additions & 2 deletions wt-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ void wt_status_prepare(struct repository *r, struct wt_status *s)
s->ignored.strdup_strings = 1;
s->show_branch = -1; /* unspecified */
s->show_stash = 0;
s->show_diffstat = 1;
s->ahead_behind_flags = AHEAD_BEHIND_UNSPECIFIED;
s->display_comment_prefix = 0;
s->detect_rename = -1;
Expand Down Expand Up @@ -441,6 +442,38 @@ static void wt_longstatus_print_change_data(struct wt_status *s,
status_printf_more(s, color(WT_STATUS_HEADER, s), "%s", extra.buf);
strbuf_release(&extra);
}

if (s->show_diffstat) {
unsigned long added, deleted;
int is_binary;

if (change_type == WT_STATUS_UPDATED) {
added = d->index_added;
deleted = d->index_deleted;
is_binary = d->index_is_binary;
} else {
added = d->worktree_added;
deleted = d->worktree_deleted;
is_binary = d->worktree_is_binary;
}

if (is_binary) {
status_printf_more(s, color(WT_STATUS_HEADER, s),
" (binary)");
} else if (added && !deleted) {
status_printf_more(s, color(WT_STATUS_HEADER, s), " ");
status_printf_more(s, GIT_COLOR_GREEN, "+%lu", added);
} else if (!added && deleted) {
status_printf_more(s, color(WT_STATUS_HEADER, s), " ");
status_printf_more(s, GIT_COLOR_RED, "-%lu", deleted);
} else if (added && deleted) {
status_printf_more(s, color(WT_STATUS_HEADER, s), " ");
status_printf_more(s, GIT_COLOR_GREEN, "+%lu", added);
status_printf_more(s, color(WT_STATUS_HEADER, s), " | ");
status_printf_more(s, GIT_COLOR_RED, "-%lu", deleted);
}
}

status_printf_more(s, GIT_COLOR_NORMAL, "\n");
strbuf_release(&onebuf);
strbuf_release(&twobuf);
Expand All @@ -458,7 +491,7 @@ static char short_submodule_status(struct wt_status_change_data *d)
}

static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
struct diff_options *options UNUSED,
struct diff_options *options,
void *data)
{
struct wt_status *s = data;
Expand Down Expand Up @@ -522,6 +555,30 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
}

}

if (s->show_diffstat &&
s->status_format != STATUS_FORMAT_SHORT &&
s->status_format != STATUS_FORMAT_PORCELAIN &&
s->status_format != STATUS_FORMAT_PORCELAIN_V2) {
struct diffstat_t diffstat = { 0 };
compute_diffstat(options, &diffstat, q);
for (i = 0; i < diffstat.nr; i++) {
struct diffstat_file *file = diffstat.files[i];
struct string_list_item *it;
struct wt_status_change_data *d;

it = string_list_lookup(&s->change, file->name);
if (!it)
continue;
d = it->util;
if (!d)
continue;
d->worktree_added = file->added;
d->worktree_deleted = file->deleted;
d->worktree_is_binary = file->is_binary;
}
free_diffstat_info(&diffstat);
}
}

static int unmerged_mask(struct index_state *istate, const char *path)
Expand All @@ -545,7 +602,7 @@ static int unmerged_mask(struct index_state *istate, const char *path)
}

static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
struct diff_options *options UNUSED,
struct diff_options *options,
void *data)
{
struct wt_status *s = data;
Expand Down Expand Up @@ -610,6 +667,30 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
break;
}
}

if (s->show_diffstat &&
s->status_format != STATUS_FORMAT_SHORT &&
s->status_format != STATUS_FORMAT_PORCELAIN &&
s->status_format != STATUS_FORMAT_PORCELAIN_V2) {
struct diffstat_t diffstat = { 0 };
compute_diffstat(options, &diffstat, q);
for (i = 0; i < diffstat.nr; i++) {
struct diffstat_file *file = diffstat.files[i];
struct string_list_item *it;
struct wt_status_change_data *d;

it = string_list_lookup(&s->change, file->name);
if (!it)
continue;
d = it->util;
if (!d)
continue;
d->index_added = file->added;
d->index_deleted = file->deleted;
d->index_is_binary = file->is_binary;
}
free_diffstat_info(&diffstat);
}
}

static void wt_status_collect_changes_worktree(struct wt_status *s)
Expand Down
7 changes: 7 additions & 0 deletions wt-status.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ struct wt_status_change_data {
char *rename_source;
unsigned dirty_submodule : 2;
unsigned new_submodule_commits : 1;
unsigned long worktree_added;
unsigned long worktree_deleted;
unsigned long index_added;
unsigned long index_deleted;
unsigned worktree_is_binary : 1;
unsigned index_is_binary : 1;
};

enum wt_status_format {
Expand Down Expand Up @@ -131,6 +137,7 @@ struct wt_status {
int rename_score;
int rename_limit;
enum wt_status_format status_format;
int show_diffstat;
unsigned char added_cut_line; /* boolean */
struct wt_status_state state;
struct object_id oid_commit; /* when not Initial */
Expand Down
Loading