зеркало из https://github.com/microsoft/git.git
Teach "git describe" --dirty option
With the --dirty option, git describe works on HEAD but append s"-dirty" iff the contents of the work tree differs from HEAD. E.g. $ git describe --dirty v1.6.5-15-gc274db7 $ echo >> Makefile $ git describe --dirty v1.6.5-15-gc274db7-dirty The --dirty option can also be used to specify what is appended, instead of the default string "-dirty". $ git describe --dirty=.mod v1.6.5-15-gc274db7.mod Many build scripts use `git describe` to produce a version number based on the description of HEAD (on which the work tree is based) + saying that if the build contains uncommitted changes. This patch helps the writing of such scripts since `git describe --dirty` does directly the intended thing. Three possiblities were considered while discussing this new feature: 1. Describe the work tree by default and describe HEAD only if "HEAD" is explicitly specified Pro: does the right thing by default (both for users and for scripts) Pro: other git commands that works on the work tree by default Con: breaks existing scripts used by the Linux kernel and other projects 2. Use --worktree instead of --dirty Pro: does what it says: "git describe --worktree" describes the work tree Con: other commands do not require a --worktree option when working on the work tree (it often is the default mode for them) Con: unusable with an optional value: "git describe --worktree=.mod" is quite unintuitive. 3. Use --dirty as in this patch Pro: makes sense to specify an optional value (what the dirty mark is) Pro: does not have any of the big cons of previous alternatives * does not break scripts * is not inconsistent with other git commands This patch takes the third approach. Signed-off-by: Jean Privat <jean@pryen.org> Acked-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
78d553b7d7
Коммит
9f67d2e827
|
@ -9,6 +9,7 @@ git-describe - Show the most recent tag that is reachable from a commit
|
|||
SYNOPSIS
|
||||
--------
|
||||
'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] <committish>...
|
||||
'git describe' [--all] [--tags] [--contains] [--abbrev=<n>] --dirty[=<mark>]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -27,6 +28,11 @@ OPTIONS
|
|||
<committish>...::
|
||||
Committish object names to describe.
|
||||
|
||||
--dirty[=<mark>]::
|
||||
Describe the working tree.
|
||||
It means describe HEAD and appends <mark> (`-dirty` by
|
||||
default) if the working tree is dirty.
|
||||
|
||||
--all::
|
||||
Instead of using only the annotated tags, use any ref
|
||||
found in `.git/refs/`. This option enables matching
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
#include "builtin.h"
|
||||
#include "exec_cmd.h"
|
||||
#include "parse-options.h"
|
||||
#include "diff.h"
|
||||
|
||||
#define SEEN (1u<<0)
|
||||
#define MAX_TAGS (FLAG_BITS - 1)
|
||||
|
||||
static const char * const describe_usage[] = {
|
||||
"git describe [options] <committish>*",
|
||||
"git describe [options] --dirty",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -23,6 +25,13 @@ static int max_candidates = 10;
|
|||
static int found_names;
|
||||
static const char *pattern;
|
||||
static int always;
|
||||
static const char *dirty;
|
||||
|
||||
/* diff-index command arguments to check if working tree is dirty. */
|
||||
static const char *diff_index_args[] = {
|
||||
"diff-index", "--quiet", "HEAD", "--", NULL
|
||||
};
|
||||
|
||||
|
||||
struct commit_name {
|
||||
struct tag *tag;
|
||||
|
@ -208,6 +217,8 @@ static void describe(const char *arg, int last_one)
|
|||
display_name(n);
|
||||
if (longformat)
|
||||
show_suffix(0, n->tag ? n->tag->tagged->sha1 : sha1);
|
||||
if (dirty)
|
||||
printf("%s", dirty);
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
@ -265,7 +276,10 @@ static void describe(const char *arg, int last_one)
|
|||
if (!match_cnt) {
|
||||
const unsigned char *sha1 = cmit->object.sha1;
|
||||
if (always) {
|
||||
printf("%s\n", find_unique_abbrev(sha1, abbrev));
|
||||
printf("%s", find_unique_abbrev(sha1, abbrev));
|
||||
if (dirty)
|
||||
printf("%s", dirty);
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
die("cannot describe '%s'", sha1_to_hex(sha1));
|
||||
|
@ -300,6 +314,8 @@ static void describe(const char *arg, int last_one)
|
|||
display_name(all_matches[0].name);
|
||||
if (abbrev)
|
||||
show_suffix(all_matches[0].depth, cmit->object.sha1);
|
||||
if (dirty)
|
||||
printf("%s", dirty);
|
||||
printf("\n");
|
||||
|
||||
if (!last_one)
|
||||
|
@ -324,6 +340,9 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
|
|||
"only consider tags matching <pattern>"),
|
||||
OPT_BOOLEAN(0, "always", &always,
|
||||
"show abbreviated commit object as fallback"),
|
||||
{OPTION_STRING, 0, "dirty", &dirty, "mark",
|
||||
"append <mark> on dirty working tree (default: \"-dirty\")",
|
||||
PARSE_OPT_OPTARG, NULL, (intptr_t) "-dirty"},
|
||||
OPT_END(),
|
||||
};
|
||||
|
||||
|
@ -360,7 +379,11 @@ int cmd_describe(int argc, const char **argv, const char *prefix)
|
|||
}
|
||||
|
||||
if (argc == 0) {
|
||||
if (dirty && !cmd_diff_index(ARRAY_SIZE(diff_index_args) - 1, diff_index_args, prefix))
|
||||
dirty = NULL;
|
||||
describe("HEAD", 1);
|
||||
} else if (dirty) {
|
||||
die("--dirty is incompatible with committishes");
|
||||
} else {
|
||||
while (argc-- > 0) {
|
||||
describe(*argv++, argc == 0);
|
||||
|
|
|
@ -123,6 +123,20 @@ test_expect_success 'rename tag Q back to A' '
|
|||
test_expect_success 'pack tag refs' 'git pack-refs'
|
||||
check_describe A-* HEAD
|
||||
|
||||
check_describe "A-*[0-9a-f]" --dirty
|
||||
|
||||
test_expect_success 'set-up dirty work tree' '
|
||||
echo >>file
|
||||
'
|
||||
|
||||
check_describe "A-*[0-9a-f]-dirty" --dirty
|
||||
|
||||
check_describe "A-*[0-9a-f].mod" --dirty=.mod
|
||||
|
||||
test_expect_success 'describe --dirty HEAD' '
|
||||
test_must_fail git describe --dirty HEAD
|
||||
'
|
||||
|
||||
test_expect_success 'set-up matching pattern tests' '
|
||||
git tag -a -m test-annotated test-annotated &&
|
||||
echo >>file &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче