Skip to content
This repository has been archived by the owner on Nov 9, 2017. It is now read-only.

Commit

Permalink
Merge branch 'jk/1.7.0-status'
Browse files Browse the repository at this point in the history
* jk/1.7.0-status:
  status/commit: do not suggest "reset HEAD <path>" while merging
  commit/status: "git add <path>" is not necessarily how to resolve
  commit/status: check $GIT_DIR/MERGE_HEAD only once
  t7508-status: test all modes with color
  t7508-status: status --porcelain ignores relative paths setting
  status: reduce duplicated setup code
  status: disable color for porcelain format
  status -s: obey color.status
  builtin-commit: refactor short-status code into wt-status.c
  t7508-status.sh: Add tests for status -s
  status -s: respect the status.relativePaths option
  docs: note that status configuration affects only long format
  commit: support alternate status formats
  status: add --porcelain output format
  status: refactor format option parsing
  status: refactor short-mode printing to its own function
  status: typo fix in usage
  git status: not "commit --dry-run" anymore
  git stat -s: short status output
  git stat: the beginning of "status that is not a dry-run of commit"

Conflicts:
	t/t4034-diff-words.sh
	wt-status.c
  • Loading branch information
gitster committed Dec 28, 2009
2 parents 67834b9 + 3c58845 commit c2ff10c
Show file tree
Hide file tree
Showing 11 changed files with 672 additions and 95 deletions.
14 changes: 14 additions & 0 deletions Documentation/git-commit.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ OPTIONS
authorship of the resulting commit now belongs of the committer.
This also renews the author timestamp.

--short::
When doing a dry-run, give the output in the short-format. See
linkgit:git-status[1] for details. Implies `--dry-run`.

--porcelain::
When doing a dry-run, give the output in a porcelain-ready
format. See linkgit:git-status[1] for details. Implies
`--dry-run`.

-z::
When showing `short` or `porcelain` status output, terminate
entries in the status output with NUL, instead of LF. If no
format is given, implies the `--porcelain` output format.

-F <file>::
--file=<file>::
Take the commit message from the given file. Use '-' to
Expand Down
90 changes: 77 additions & 13 deletions Documentation/git-status.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ git-status - Show the working tree status

SYNOPSIS
--------
'git status' <options>...
'git status' [<options>...] [--] [<pathspec>...]

DESCRIPTION
-----------
Expand All @@ -20,25 +20,90 @@ are what you _would_ commit by running `git commit`; the second and
third are what you _could_ commit by running 'git-add' before running
`git commit`.

The command takes the same set of options as 'git-commit'; it
shows what would be committed if the same options are given to
'git-commit'.

If there is no path that is different between the index file and
the current HEAD commit (i.e., there is nothing to commit by running
`git commit`), the command exits with non-zero status.
OPTIONS
-------

-s::
--short::
Give the output in the short-format.

--porcelain::
Give the output in a stable, easy-to-parse format for scripts.
Currently this is identical to --short output, but is guaranteed
not to change in the future, making it safe for scripts.

-u[<mode>]::
--untracked-files[=<mode>]::
Show untracked files (Default: 'all').
+
The mode parameter is optional, and is used to specify
the handling of untracked files. The possible options are:
+
--
- 'no' - Show no untracked files
- 'normal' - Shows untracked files and directories
- 'all' - Also shows individual files in untracked directories.
--
+
See linkgit:git-config[1] for configuration variable
used to change the default for when the option is not
specified.

-z::
Terminate entries with NUL, instead of LF. This implies
the `--porcelain` output format if no other format is given.


OUTPUT
------
The output from this command is designed to be used as a commit
template comment, and all the output lines are prefixed with '#'.
The default, long format, is designed to be human readable,
verbose and descriptive. They are subject to change in any time.

The paths mentioned in the output, unlike many other git commands, are
made relative to the current directory if you are working in a
subdirectory (this is on purpose, to help cutting and pasting). See
the status.relativePaths config option below.

In short-format, the status of each path is shown as

XY PATH1 -> PATH2

where `PATH1` is the path in the `HEAD`, and ` -> PATH2` part is
shown only when `PATH1` corresponds to a different path in the
index/worktree (i.e. renamed).

For unmerged entries, `X` shows the status of stage #2 (i.e. ours) and `Y`
shows the status of stage #3 (i.e. theirs).

For entries that do not have conflicts, `X` shows the status of the index,
and `Y` shows the status of the work tree. For untracked paths, `XY` are
`??`.

X Y Meaning
-------------------------------------------------
[MD] not updated
M [ MD] updated in index
A [ MD] added to index
D [ MD] deleted from index
R [ MD] renamed in index
C [ MD] copied in index
[MARC] index and work tree matches
[ MARC] M work tree changed since index
[ MARC] D deleted in work tree
-------------------------------------------------
D D unmerged, both deleted
A U unmerged, added by us
U D unmerged, deleted by them
U A unmerged, added by them
D U unmerged, deleted by us
A A unmerged, both added
U U unmerged, both modified
-------------------------------------------------
? ? untracked
-------------------------------------------------


CONFIGURATION
-------------
Expand All @@ -53,18 +118,17 @@ paths shown are relative to the repository root, not to the current
directory.

If `status.submodulesummary` is set to a non zero number or true (identical
to -1 or an unlimited number), the submodule summary will be enabled and a
summary of commits for modified submodules will be shown (see --summary-limit
option of linkgit:git-submodule[1]).
to -1 or an unlimited number), the submodule summary will be enabled for
the long format and a summary of commits for modified submodules will be
shown (see --summary-limit option of linkgit:git-submodule[1]).

SEE ALSO
--------
linkgit:gitignore[5]

Author
------
Written by Linus Torvalds <torvalds@osdl.org> and
Junio C Hamano <gitster@pobox.com>.
Written by Junio C Hamano <gitster@pobox.com>.

Documentation
--------------
Expand Down
124 changes: 104 additions & 20 deletions builtin-commit.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "string-list.h"
#include "rerere.h"
#include "unpack-trees.h"
#include "quote.h"

static const char * const builtin_commit_usage[] = {
"git commit [options] [--] <filepattern>...",
Expand All @@ -35,7 +36,7 @@ static const char * const builtin_status_usage[] = {
NULL
};

static unsigned char head_sha1[20], merge_head_sha1[20];
static unsigned char head_sha1[20];
static char *use_message_buffer;
static const char commit_editmsg[] = "COMMIT_EDITMSG";
static struct lock_file index_lock; /* real index */
Expand Down Expand Up @@ -71,6 +72,13 @@ static int use_editor = 1, initial_commit, in_merge;
static const char *only_include_assumed;
static struct strbuf message;

static int null_termination;
static enum {
STATUS_FORMAT_LONG,
STATUS_FORMAT_SHORT,
STATUS_FORMAT_PORCELAIN,
} status_format = STATUS_FORMAT_LONG;

static int opt_parse_m(const struct option *opt, const char *arg, int unset)
{
struct strbuf *buf = opt->value;
Expand Down Expand Up @@ -105,6 +113,12 @@ static struct option builtin_commit_options[] = {
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_SET_INT(0, "short", &status_format, "show status concisely",
STATUS_FORMAT_SHORT),
OPT_SET_INT(0, "porcelain", &status_format,
"show porcelain output format", STATUS_FORMAT_PORCELAIN),
OPT_BOOLEAN('z', "null", &null_termination,
"terminate entries with NUL"),
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 @@ -306,7 +320,7 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
*/
commit_style = COMMIT_PARTIAL;

if (file_exists(git_path("MERGE_HEAD")))
if (in_merge)
die("cannot do a partial commit during a merge.");

memset(&partial, 0, sizeof(partial));
Expand Down Expand Up @@ -347,6 +361,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix, int
static int run_status(FILE *fp, const char *index_file, const char *prefix, int nowarn,
struct wt_status *s)
{
unsigned char sha1[20];

if (s->relative_paths)
s->prefix = prefix;

Expand All @@ -358,8 +374,21 @@ static int run_status(FILE *fp, const char *index_file, const char *prefix, int
s->index_file = index_file;
s->fp = fp;
s->nowarn = nowarn;
s->is_initial = get_sha1(s->reference, sha1) ? 1 : 0;

wt_status_print(s);
wt_status_collect(s);

switch (status_format) {
case STATUS_FORMAT_SHORT:
wt_shortstatus_print(s, null_termination);
break;
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(s, null_termination);
break;
case STATUS_FORMAT_LONG:
wt_status_print(s);
break;
}

return s->commitable;
}
Expand Down Expand Up @@ -735,6 +764,21 @@ static const char *find_author_by_nickname(const char *name)
die("No existing author found with '%s'", name);
}


static void handle_untracked_files_arg(struct wt_status *s)
{
if (!untracked_files_arg)
; /* default already initialized */
else if (!strcmp(untracked_files_arg, "no"))
s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
else if (!strcmp(untracked_files_arg, "normal"))
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
else if (!strcmp(untracked_files_arg, "all"))
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
else
die("Invalid untracked files mode '%s'", untracked_files_arg);
}

static int parse_and_validate_options(int argc, const char *argv[],
const char * const usage[],
const char *prefix,
Expand All @@ -761,9 +805,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (get_sha1("HEAD", head_sha1))
initial_commit = 1;

if (!get_sha1("MERGE_HEAD", merge_head_sha1))
in_merge = 1;

/* Sanity check options */
if (amend && initial_commit)
die("You have nothing to amend.");
Expand Down Expand Up @@ -843,22 +884,18 @@ static int parse_and_validate_options(int argc, const char *argv[],
else
die("Invalid cleanup mode %s", cleanup_arg);

if (!untracked_files_arg)
; /* default already initialized */
else if (!strcmp(untracked_files_arg, "no"))
s->show_untracked_files = SHOW_NO_UNTRACKED_FILES;
else if (!strcmp(untracked_files_arg, "normal"))
s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES;
else if (!strcmp(untracked_files_arg, "all"))
s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES;
else
die("Invalid untracked files mode '%s'", untracked_files_arg);
handle_untracked_files_arg(s);

if (all && argc > 0)
die("Paths with -a does not make sense.");
else if (interactive && argc > 0)
die("Paths with --interactive does not make sense.");

if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;
if (status_format != STATUS_FORMAT_LONG)
dry_run = 1;

return argc;
}

Expand Down Expand Up @@ -940,17 +977,63 @@ static int git_status_config(const char *k, const char *v, void *cb)
int cmd_status(int argc, const char **argv, const char *prefix)
{
struct wt_status s;
unsigned char sha1[20];
static struct option builtin_status_options[] = {
OPT__VERBOSE(&verbose),
OPT_SET_INT('s', "short", &status_format,
"show status concisely", STATUS_FORMAT_SHORT),
OPT_SET_INT(0, "porcelain", &status_format,
"show porcelain output format",
STATUS_FORMAT_PORCELAIN),
OPT_BOOLEAN('z', "null", &null_termination,
"terminate entries with NUL"),
{ 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_END(),
};

if (null_termination && status_format == STATUS_FORMAT_LONG)
status_format = STATUS_FORMAT_PORCELAIN;

wt_status_prepare(&s);
git_config(git_status_config, &s);
in_merge = file_exists(git_path("MERGE_HEAD"));
argc = parse_options(argc, argv, prefix,
builtin_status_options,
builtin_status_usage, 0);
handle_untracked_files_arg(&s);

if (*argv)
s.pathspec = get_pathspec(prefix, argv);

read_cache();
refresh_cache(REFRESH_QUIET|REFRESH_UNMERGED);
s.is_initial = get_sha1(s.reference, sha1) ? 1 : 0;
s.in_merge = in_merge;
wt_status_collect(&s);

if (s.relative_paths)
s.prefix = prefix;
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;

argc = parse_and_validate_options(argc, argv, builtin_status_usage,
prefix, &s);
return dry_run_commit(argc, argv, prefix, &s);
switch (status_format) {
case STATUS_FORMAT_SHORT:
wt_shortstatus_print(&s, null_termination);
break;
case STATUS_FORMAT_PORCELAIN:
wt_porcelain_print(&s, null_termination);
break;
case STATUS_FORMAT_LONG:
s.verbose = verbose;
wt_status_print(&s);
break;
}
return 0;
}

static void print_summary(const char *prefix, const unsigned char *sha1)
Expand Down Expand Up @@ -1026,10 +1109,11 @@ int cmd_commit(int argc, const char **argv, const char *prefix)

wt_status_prepare(&s);
git_config(git_commit_config, &s);
in_merge = file_exists(git_path("MERGE_HEAD"));
s.in_merge = in_merge;

if (s.use_color == -1)
s.use_color = git_use_color_default;

argc = parse_and_validate_options(argc, argv, builtin_commit_usage,
prefix, &s);
if (dry_run) {
Expand Down
Loading

0 comments on commit c2ff10c

Please sign in to comment.