Skip to content

Commit

Permalink
Merge branch 'jc/shortstatus'
Browse files Browse the repository at this point in the history
* jc/shortstatus:
  git commit --dry-run -v: show diff in color when asked
  Documentation/git-commit.txt: describe --dry-run
  wt-status: collect untracked files in a separate "collect" phase
  Make git_status_config() file scope static to builtin-commit.c
  wt-status: move wt_status_colors[] into wt_status structure
  wt-status: move many global settings to wt_status structure
  commit: --dry-run
  status: show worktree status of conflicted paths separately
  wt-status.c: rework the way changes to the index and work tree are summarized
  diff-index: keep the original index intact
  diff-index: report unmerged new entries
  • Loading branch information
Junio C Hamano committed Aug 29, 2009
2 parents 42fa6df + 3fa509d commit 433233e
Show file tree
Hide file tree
Showing 6 changed files with 550 additions and 230 deletions.
20 changes: 15 additions & 5 deletions Documentation/git-commit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ git-commit - Record changes to the repository
SYNOPSIS
--------
[verse]
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend]
[(-c | -C) <commit>] [-F <file> | -m <msg>]
'git commit' [-a | --interactive] [-s] [-v] [-u<mode>] [--amend] [--dry-run]
[(-c | -C) <commit>] [-F <file> | -m <msg>] [--dry-run]
[--allow-empty] [--no-verify] [-e] [--author=<author>]
[--cleanup=<mode>] [--] [[-i | -o ]<file>...]

Expand Down Expand Up @@ -42,10 +42,9 @@ The content to be added can be specified in several ways:
by one which files should be part of the commit, before finalizing the
operation. Currently, this is done by invoking 'git-add --interactive'.

The 'git-status' command can be used to obtain a
The `--dry-run` option can be used to obtain a
summary of what is included by any of the above for the next
commit by giving the same set of parameters you would give to
this command.
commit by giving the same set of parameters (options and paths).

If you make a commit and then find a mistake immediately after
that, you can recover from it with 'git-reset'.
Expand All @@ -70,6 +69,12 @@ OPTIONS
Like '-C', but with '-c' the editor is invoked, so that
the user can further edit the commit message.

--dry-run::
Do not actually make a commit, but show the list of paths
with updates in the index, paths with changes in the work tree,
and paths that are untracked, similar to the one that is given
in the commit log editor.

-F <file>::
--file=<file>::
Take the commit message from the given file. Use '-' to
Expand Down Expand Up @@ -198,6 +203,11 @@ specified.
--quiet::
Suppress commit summary message.

--dry-run::
Do not create a commit, but show a list of paths that are
to be committed, paths with local changes that will be left
uncommitted and paths that are untracked.

\--::
Do not interpret any more arguments as options.

Expand Down
175 changes: 126 additions & 49 deletions builtin-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ static const char *template_file;
static char *edit_message, *use_message;
static char *author_name, *author_email, *author_date;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int quiet, verbose, no_verify, allow_empty;
static int quiet, verbose, no_verify, allow_empty, dry_run;
static char *untracked_files_arg;
/*
* The default commit message cleanup mode will remove the lines
Expand Down Expand Up @@ -103,6 +103,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"),
OPT_BOOLEAN('o', "only", &only, "commit only specified files"),
OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"),
OPT_BOOLEAN(0, "dry-run", &dry_run, "show what would be committed"),
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
{ OPTION_STRING, 'u', "untracked-files", &untracked_files_arg, "mode", "show untracked files, optional modes: all, normal, no. (Default: all)", PARSE_OPT_OPTARG, NULL, (intptr_t)"all" },
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
Expand Down Expand Up @@ -217,12 +218,15 @@ static void create_base_index(void)
exit(128); /* We've already reported the error, finish dying */
}

static char *prepare_index(int argc, const char **argv, const char *prefix)
static char *prepare_index(int argc, const char **argv, const char *prefix, int is_status)
{
int fd;
struct string_list partial;
const char **pathspec = NULL;
int refresh_flags = REFRESH_QUIET;

if (is_status)
refresh_flags |= REFRESH_UNMERGED;
if (interactive) {
if (interactive_add(argc, argv, prefix) != 0)
die("interactive add failed");
Expand Down Expand Up @@ -253,7 +257,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
if (all || (also && pathspec && *pathspec)) {
int fd = hold_locked_index(&index_lock, 1);
add_files_to_cache(also ? prefix : NULL, pathspec, 0);
refresh_cache(REFRESH_QUIET);
refresh_cache(refresh_flags);
if (write_cache(fd, active_cache, active_nr) ||
close_lock_file(&index_lock))
die("unable to write new_index file");
Expand All @@ -272,7 +276,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
*/
if (!pathspec || !*pathspec) {
fd = hold_locked_index(&index_lock, 1);
refresh_cache(REFRESH_QUIET);
refresh_cache(refresh_flags);
if (write_cache(fd, active_cache, active_nr) ||
commit_locked_index(&index_lock))
die("unable to write new_index file");
Expand Down Expand Up @@ -339,27 +343,24 @@ static char *prepare_index(int argc, const char **argv, const char *prefix)
return false_lock.filename;
}

static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn)
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
struct wt_status *s)
{
struct wt_status s;

wt_status_prepare(&s);
if (wt_status_relative_paths)
s.prefix = prefix;
if (s->relative_paths)
s->prefix = prefix;

if (amend) {
s.amend = 1;
s.reference = "HEAD^1";
s->amend = 1;
s->reference = "HEAD^1";
}
s.verbose = verbose;
s.untracked = (show_untracked_files == SHOW_ALL_UNTRACKED_FILES);
s.index_file = index_file;
s.fp = fp;
s.nowarn = nowarn;
s->verbose = verbose;
s->index_file = index_file;
s->fp = fp;
s->nowarn = nowarn;

wt_status_print(&s);
wt_status_print(s);

return s.commitable;
return s->commitable;
}

static int is_a_merge(const unsigned char *sha1)
Expand Down Expand Up @@ -413,7 +414,8 @@ static void determine_author_info(void)
author_date = date;
}

static int prepare_to_commit(const char *index_file, const char *prefix)
static int prepare_to_commit(const char *index_file, const char *prefix,
struct wt_status *s)
{
struct stat statbuf;
int commitable, saved_color_setting;
Expand Down Expand Up @@ -555,10 +557,10 @@ static int prepare_to_commit(const char *index_file, const char *prefix)
if (ident_shown)
fprintf(fp, "#\n");

saved_color_setting = wt_status_use_color;
wt_status_use_color = 0;
commitable = run_status(fp, index_file, prefix, 1);
wt_status_use_color = saved_color_setting;
saved_color_setting = s->use_color;
s->use_color = 0;
commitable = run_status(fp, index_file, prefix, 1, s);
s->use_color = saved_color_setting;
} else {
unsigned char sha1[20];
const char *parent = "HEAD";
Expand All @@ -579,7 +581,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix)

if (!commitable && !in_merge && !allow_empty &&
!(amend && is_a_merge(head_sha1))) {
run_status(stdout, index_file, prefix, 0);
run_status(stdout, index_file, prefix, 0, s);
return 0;
}

Expand Down Expand Up @@ -691,7 +693,8 @@ static const char *find_author_by_nickname(const char *name)

static int parse_and_validate_options(int argc, const char *argv[],
const char * const usage[],
const char *prefix)
const char *prefix,
struct wt_status *s)
{
int f = 0;

Expand Down Expand Up @@ -794,11 +797,11 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (!untracked_files_arg)
; /* default already initialized */
else if (!strcmp(untracked_files_arg, "no"))
show_untracked_files = SHOW_NO_UNTRACKED_FILES;
s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
else if (!strcmp(untracked_files_arg, "normal"))
show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
else if (!strcmp(untracked_files_arg, "all"))
show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
else
die("Invalid untracked files mode '%s'", untracked_files_arg);

Expand All @@ -810,28 +813,93 @@ static int parse_and_validate_options(int argc, const char *argv[],
return argc;
}

int cmd_status(int argc, const char **argv, const char *prefix)
static int dry_run_commit(int argc, const char **argv, const char *prefix,
struct wt_status *s)
{
const char *index_file;
int commitable;
const char *index_file;

git_config(git_status_config, NULL);
index_file = prepare_index(argc, argv, prefix, 1);
commitable = run_status(stdout, index_file, prefix, 0, s);
rollback_index_files();

if (wt_status_use_color == -1)
wt_status_use_color = git_use_color_default;
return commitable ? 0 : 1;
}

if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;
static int parse_status_slot(const char *var, int offset)
{
if (!strcasecmp(var+offset, "header"))
return WT_STATUS_HEADER;
if (!strcasecmp(var+offset, "updated")
|| !strcasecmp(var+offset, "added"))
return WT_STATUS_UPDATED;
if (!strcasecmp(var+offset, "changed"))
return WT_STATUS_CHANGED;
if (!strcasecmp(var+offset, "untracked"))
return WT_STATUS_UNTRACKED;
if (!strcasecmp(var+offset, "nobranch"))
return WT_STATUS_NOBRANCH;
if (!strcasecmp(var+offset, "unmerged"))
return WT_STATUS_UNMERGED;
die("bad config variable '%s'", var);
}

argc = parse_and_validate_options(argc, argv, builtin_status_usage, prefix);
static int git_status_config(const char *k, const char *v, void *cb)
{
struct wt_status *s = cb;

index_file = prepare_index(argc, argv, prefix);
if (!strcmp(k, "status.submodulesummary")) {
int is_bool;
s->submodule_summary = git_config_bool_or_int(k, v, &is_bool);
if (is_bool && s->submodule_summary)
s->submodule_summary = -1;
return 0;
}
if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) {
s->use_color = git_config_colorbool(k, v, -1);
return 0;
}
if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) {
int slot = parse_status_slot(k, 13);
if (!v)
return config_error_nonbool(k);
color_parse(v, k, s->color_palette[slot]);
return 0;
}
if (!strcmp(k, "status.relativepaths")) {
s->relative_paths = git_config_bool(k, v);
return 0;
}
if (!strcmp(k, "status.showuntrackedfiles")) {
if (!v)
return config_error_nonbool(k);
else if (!strcmp(v, "no"))
s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
else if (!strcmp(v, "normal"))
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
else if (!strcmp(v, "all"))
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
else
return error("Invalid untracked files mode '%s'", v);
return 0;
}
return git_diff_ui_config(k, v, NULL);
}

commitable = run_status(stdout, index_file, prefix, 0);
int cmd_status(int argc, const char **argv, const char *prefix)
{
struct wt_status s;

rollback_index_files();
wt_status_prepare(&s);
git_config(git_status_config, &s);
if (s.use_color == -1)
s.use_color = git_use_color_default;
if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;

return commitable ? 0 : 1;
argc = parse_and_validate_options(argc, argv, builtin_status_usage,
prefix, &s);
return dry_run_commit(argc, argv, prefix, &s);
}

static void print_summary(const char *prefix, const unsigned char *sha1)
Expand Down Expand Up @@ -883,10 +951,12 @@ static void print_summary(const char *prefix, const unsigned char *sha1)

static int git_commit_config(const char *k, const char *v, void *cb)
{
struct wt_status *s = cb;

if (!strcmp(k, "commit.template"))
return git_config_string(&template_file, k, v);

return git_status_config(k, v, cb);
return git_status_config(k, v, s);
}

int cmd_commit(int argc, const char **argv, const char *prefix)
Expand All @@ -899,19 +969,26 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
struct commit_list *parents = NULL, **pptr = &parents;
struct stat statbuf;
int allow_fast_forward = 1;
struct wt_status s;

git_config(git_commit_config, NULL);

if (wt_status_use_color == -1)
wt_status_use_color = git_use_color_default;
wt_status_prepare(&s);
git_config(git_commit_config, &s);

argc = parse_and_validate_options(argc, argv, builtin_commit_usage, prefix);
if (s.use_color == -1)
s.use_color = git_use_color_default;

index_file = prepare_index(argc, argv, prefix);
argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
prefix, &s);
if (dry_run) {
if (diff_use_color_default == -1)
diff_use_color_default = git_use_color_default;
return dry_run_commit(argc, argv, prefix, &s);
}
index_file = prepare_index(argc, argv, prefix, 0);

/* Set up everything for writing the commit object. This includes
running hooks, writing the trees, and interacting with the user. */
if (!prepare_to_commit(index_file, prefix)) {
if (!prepare_to_commit(index_file, prefix, &s)) {
rollback_index_files();
return 1;
}
Expand Down
22 changes: 2 additions & 20 deletions diff-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,22 +309,6 @@ static int show_modified(struct rev_info *revs,
return 0;
}

/*
* This turns all merge entries into "stage 3". That guarantees that
* when we read in the new tree (into "stage 1"), we won't lose sight
* of the fact that we had unmerged entries.
*/
static void mark_merge_entries(void)
{
int i;
for (i = 0; i < active_nr; i++) {
struct cache_entry *ce = active_cache[i];
if (!ce_stage(ce))
continue;
ce->ce_flags |= CE_STAGEMASK;
}
}

/*
* This gets a mix of an existing index and a tree, one pathname entry
* at a time. The index entry may be a single stage-0 one, but it could
Expand All @@ -350,8 +334,8 @@ static void do_oneway_diff(struct unpack_trees_options *o,
match_missing = !revs->ignore_merges;

if (cached && idx && ce_stage(idx)) {
if (tree)
diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode, idx->sha1);
diff_unmerge(&revs->diffopt, idx->name, idx->ce_mode,
idx->sha1);
return;
}

Expand Down Expand Up @@ -437,8 +421,6 @@ int run_diff_index(struct rev_info *revs, int cached)
struct unpack_trees_options opts;
struct tree_desc t;

mark_merge_entries();

ent = revs->pending.objects[0].item;
tree_name = revs->pending.objects[0].name;
tree = parse_tree_indirect(ent->sha1);
Expand Down
Loading

0 comments on commit 433233e

Please sign in to comment.