Skip to content

Commit

Permalink
status: collect per-file data for --porcelain=v2
Browse files Browse the repository at this point in the history
Collect extra per-file data for porcelain V2 format.

The output of `git status --porcelain` leaves out many
details about the current status that clients might like
to have.  This can force them to be less efficient as they
may need to launch secondary commands (and try to match
the logic within git) to accumulate this extra information.
For example, a GUI IDE might want the file mode to display
the correct icon for a changed item (without having to stat
it afterwards).

Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
jeffhostetler authored and gitster committed Aug 11, 2016
1 parent c4f596b commit 1ecdecc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
3 changes: 3 additions & 0 deletions builtin/commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,8 @@ static int opt_parse_porcelain(const struct option *opt, const char *arg, int un
*value = STATUS_FORMAT_PORCELAIN;
else if (!strcmp(arg, "v1") || !strcmp(arg, "1"))
*value = STATUS_FORMAT_PORCELAIN;
else if (!strcmp(arg, "v2") || !strcmp(arg, "2"))
*value = STATUS_FORMAT_PORCELAIN_V2;
else
die("unsupported porcelain version '%s'", arg);

Expand Down Expand Up @@ -1104,6 +1106,7 @@ static struct status_deferred_config {
static void finalize_deferred_config(struct wt_status *s)
{
int use_deferred_config = (status_format != STATUS_FORMAT_PORCELAIN &&
status_format != STATUS_FORMAT_PORCELAIN_V2 &&
!s->null_termination);

if (s->null_termination) {
Expand Down
64 changes: 62 additions & 2 deletions wt-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,31 @@ static void wt_status_collect_changed_cb(struct diff_queue_struct *q,
if (S_ISGITLINK(p->two->mode))
d->new_submodule_commits = !!oidcmp(&p->one->oid,
&p->two->oid);

switch (p->status) {
case DIFF_STATUS_ADDED:
die("BUG: worktree status add???");
break;

case DIFF_STATUS_DELETED:
d->mode_index = p->one->mode;
oidcpy(&d->oid_index, &p->one->oid);
/* mode_worktree is zero for a delete. */
break;

case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_TYPE_CHANGED:
case DIFF_STATUS_UNMERGED:
d->mode_index = p->one->mode;
d->mode_worktree = p->two->mode;
oidcpy(&d->oid_index, &p->one->oid);
break;

case DIFF_STATUS_UNKNOWN:
die("BUG: worktree status unknown???");
break;
}

}
}

Expand Down Expand Up @@ -479,12 +504,36 @@ static void wt_status_collect_updated_cb(struct diff_queue_struct *q,
if (!d->index_status)
d->index_status = p->status;
switch (p->status) {
case DIFF_STATUS_ADDED:
/* Leave {mode,oid}_head zero for an add. */
d->mode_index = p->two->mode;
oidcpy(&d->oid_index, &p->two->oid);
break;
case DIFF_STATUS_DELETED:
d->mode_head = p->one->mode;
oidcpy(&d->oid_head, &p->one->oid);
/* Leave {mode,oid}_index zero for a delete. */
break;

case DIFF_STATUS_COPIED:
case DIFF_STATUS_RENAMED:
d->head_path = xstrdup(p->one->path);
d->score = p->score * 100 / MAX_SCORE;
/* fallthru */
case DIFF_STATUS_MODIFIED:
case DIFF_STATUS_TYPE_CHANGED:
d->mode_head = p->one->mode;
d->mode_index = p->two->mode;
oidcpy(&d->oid_head, &p->one->oid);
oidcpy(&d->oid_index, &p->two->oid);
break;
case DIFF_STATUS_UNMERGED:
d->stagemask = unmerged_mask(p->two->path);
/*
* Don't bother setting {mode,oid}_{head,index} since the print
* code will output the stage values directly and not use the
* values in these fields.
*/
break;
}
}
Expand Down Expand Up @@ -565,9 +614,17 @@ static void wt_status_collect_changes_initial(struct wt_status *s)
if (ce_stage(ce)) {
d->index_status = DIFF_STATUS_UNMERGED;
d->stagemask |= (1 << (ce_stage(ce) - 1));
}
else
/*
* Don't bother setting {mode,oid}_{head,index} since the print
* code will output the stage values directly and not use the
* values in these fields.
*/
} else {
d->index_status = DIFF_STATUS_ADDED;
/* Leave {mode,oid}_head zero for adds. */
d->mode_index = ce->ce_mode;
hashcpy(d->oid_index.hash, ce->sha1);
}
}
}

Expand Down Expand Up @@ -1764,6 +1821,9 @@ void wt_status_print(struct wt_status *s)
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s);
break;
case STATUS_FORMAT_PORCELAIN_V2:
/* TODO */
break;
case STATUS_FORMAT_UNSPECIFIED:
die("BUG: finalize_deferred_config() should have been called");
break;
Expand Down
4 changes: 4 additions & 0 deletions wt-status.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ struct wt_status_change_data {
int worktree_status;
int index_status;
int stagemask;
int score;
int mode_head, mode_index, mode_worktree;
struct object_id oid_head, oid_index;
char *head_path;
unsigned dirty_submodule : 2;
unsigned new_submodule_commits : 1;
Expand All @@ -48,6 +51,7 @@ enum wt_status_format {
STATUS_FORMAT_LONG,
STATUS_FORMAT_SHORT,
STATUS_FORMAT_PORCELAIN,
STATUS_FORMAT_PORCELAIN_V2,

STATUS_FORMAT_UNSPECIFIED
};
Expand Down

0 comments on commit 1ecdecc

Please sign in to comment.