aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2008-08-29 00:16:39 -0700
committerJunio C Hamano <gitster@pobox.com>2008-08-29 00:16:39 -0700
commit445cac18c015809a7fcb4a570d3c6571b1ddaf7d (patch)
tree89eeb8e6618d9eb582ea5bd1a2cf781625ebc001
parente990501312e22cfa910d88dc7143bc4eb3632ae1 (diff)
parent53d1589ff6bd336e3ece39e0a963a3d2a537cf96 (diff)
downloadgit-445cac18c015809a7fcb4a570d3c6571b1ddaf7d.tar.gz
git-445cac18c015809a7fcb4a570d3c6571b1ddaf7d.tar.xz
Merge branch 'maint'
* maint: tutorial: gentler illustration of Alice/Bob workflow using gitk pretty=format: respect date format options make git-shell paranoid about closed stdin/stdout/stderr Document gitk --argscmd flag. Fix '--dirstat' with cross-directory renaming for-each-ref: Allow a trailing slash in the patterns
-rw-r--r--Documentation/gitk.txt7
-rw-r--r--Documentation/gittutorial.txt29
-rw-r--r--Documentation/pretty-formats.txt2
-rw-r--r--archive.c2
-rw-r--r--builtin-commit.c2
-rw-r--r--builtin-for-each-ref.c3
-rw-r--r--commit.h3
-rw-r--r--diff.c8
-rw-r--r--pretty.c17
-rw-r--r--shell.c13
-rwxr-xr-xt/t6006-rev-list-format.sh6
11 files changed, 80 insertions, 12 deletions
diff --git a/Documentation/gitk.txt b/Documentation/gitk.txt
index 6e827cd11..ae29a00d5 100644
--- a/Documentation/gitk.txt
+++ b/Documentation/gitk.txt
@@ -49,6 +49,13 @@ frequently used options.
the history between two branches (i.e. the HEAD and the MERGE_HEAD)
that modify the conflicted files.
+--argscmd=<command>::
+ Command to be run each time gitk has to determine the list of
+ <revs> to show. The command is expected to print on its standard
+ output a list of additional revs to be shown, one per line.
+ Use this instead of explicitly specifying <revs> if the set of
+ commits to show may vary between refreshes.
+
<revs>::
Limit the revisions to show. This can be either a single revision
diff --git a/Documentation/gittutorial.txt b/Documentation/gittutorial.txt
index 48d1454a9..384972cb9 100644
--- a/Documentation/gittutorial.txt
+++ b/Documentation/gittutorial.txt
@@ -321,10 +321,37 @@ pulling, like this:
------------------------------------------------
alice$ git fetch /home/bob/myrepo master
-alice$ git log -p ..FETCH_HEAD
+alice$ git log -p HEAD..FETCH_HEAD
------------------------------------------------
This operation is safe even if Alice has uncommitted local changes.
+The range notation HEAD..FETCH_HEAD" means "show everything that is reachable
+from the FETCH_HEAD but exclude anything that is reachable from HEAD.
+Alice already knows everything that leads to her current state (HEAD),
+and reviewing what Bob has in his state (FETCH_HEAD) that she has not
+seen with this command
+
+If Alice wants to visualize what Bob did since their histories forked
+she can issue the following command:
+
+------------------------------------------------
+$ gitk HEAD..FETCH_HEAD
+------------------------------------------------
+
+This uses the same two-dot range notation we saw earlier with 'git log'.
+
+Alice may want to view what both of them did since they forked.
+She can use three-dot form instead of the two-dot form:
+
+------------------------------------------------
+$ gitk HEAD...FETCH_HEAD
+------------------------------------------------
+
+This means "show everything that is reachable from either one, but
+exclude anything that is reachable from both of them".
+
+Please note that these range notation can be used with both gitk
+and "git log".
After inspecting what Bob did, if there is nothing urgent, Alice may
decide to continue working without pulling from Bob. If Bob's history
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index c11d49577..388d4925e 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -103,7 +103,7 @@ The placeholders are:
- '%an': author name
- '%aN': author name (respecting .mailmap)
- '%ae': author email
-- '%ad': author date
+- '%ad': author date (format respects --date= option)
- '%aD': author date, RFC2822 style
- '%ar': author date, relative
- '%at': author date, UNIX timestamp
diff --git a/archive.c b/archive.c
index 5b40e261f..e2280df56 100644
--- a/archive.c
+++ b/archive.c
@@ -48,7 +48,7 @@ static void format_subst(const struct commit *commit,
strbuf_add(&fmt, b + 8, c - b - 8);
strbuf_add(buf, src, b - src);
- format_commit_message(commit, fmt.buf, buf);
+ format_commit_message(commit, fmt.buf, buf, DATE_NORMAL);
len -= c + 1 - src;
src = c + 1;
}
diff --git a/builtin-commit.c b/builtin-commit.c
index 649c8beb3..c870037b0 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -882,7 +882,7 @@ static void print_summary(const char *prefix, const unsigned char *sha1)
if (!log_tree_commit(&rev, commit)) {
struct strbuf buf = STRBUF_INIT;
- format_commit_message(commit, "%h: %s", &buf);
+ format_commit_message(commit, "%h: %s", &buf, DATE_NORMAL);
printf("%s\n", buf.buf);
strbuf_release(&buf);
}
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index 4d25ec51d..21e92bbcb 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -652,7 +652,8 @@ static int grab_single_ref(const char *refname, const unsigned char *sha1, int f
if ((plen <= namelen) &&
!strncmp(refname, p, plen) &&
(refname[plen] == '\0' ||
- refname[plen] == '/'))
+ refname[plen] == '/' ||
+ p[plen-1] == '/'))
break;
if (!fnmatch(p, refname, FNM_PATHNAME))
break;
diff --git a/commit.h b/commit.h
index d163c7487..de15f4d71 100644
--- a/commit.h
+++ b/commit.h
@@ -67,7 +67,8 @@ extern int non_ascii(int);
struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */
extern void get_commit_format(const char *arg, struct rev_info *);
extern void format_commit_message(const struct commit *commit,
- const void *format, struct strbuf *sb);
+ const void *format, struct strbuf *sb,
+ enum date_mode dmode);
extern void pretty_print_commit(enum cmit_fmt fmt, const struct commit*,
struct strbuf *,
int abbrev, const char *subject,
diff --git a/diff.c b/diff.c
index 18fa7a712..135dec459 100644
--- a/diff.c
+++ b/diff.c
@@ -1060,6 +1060,13 @@ static long gather_dirstat(FILE *file, struct dirstat_dir *dir, unsigned long ch
return this_dir;
}
+static int dirstat_compare(const void *_a, const void *_b)
+{
+ const struct dirstat_file *a = _a;
+ const struct dirstat_file *b = _b;
+ return strcmp(a->name, b->name);
+}
+
static void show_dirstat(struct diff_options *options)
{
int i;
@@ -1119,6 +1126,7 @@ static void show_dirstat(struct diff_options *options)
return;
/* Show all directories with more than x% of the changes */
+ qsort(dir.files, dir.nr, sizeof(dir.files[0]), dirstat_compare);
gather_dirstat(options->file, &dir, changed, "", 0);
}
diff --git a/pretty.c b/pretty.c
index 33ef34a41..a29c29000 100644
--- a/pretty.c
+++ b/pretty.c
@@ -310,7 +310,7 @@ static int mailmap_name(struct strbuf *sb, const char *email)
}
static size_t format_person_part(struct strbuf *sb, char part,
- const char *msg, int len)
+ const char *msg, int len, enum date_mode dmode)
{
/* currently all placeholders have same length */
const int placeholder_len = 2;
@@ -377,7 +377,7 @@ static size_t format_person_part(struct strbuf *sb, char part,
switch (part) {
case 'd': /* date */
- strbuf_addstr(sb, show_date(date, tz, DATE_NORMAL));
+ strbuf_addstr(sb, show_date(date, tz, dmode));
return placeholder_len;
case 'D': /* date, RFC2822 style */
strbuf_addstr(sb, show_date(date, tz, DATE_RFC2822));
@@ -409,6 +409,7 @@ struct chunk {
struct format_commit_context {
const struct commit *commit;
+ enum date_mode dmode;
/* These offsets are relative to the start of the commit message. */
int commit_header_parsed;
@@ -584,10 +585,12 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
return 1;
case 'a': /* author ... */
return format_person_part(sb, placeholder[1],
- msg + c->author.off, c->author.len);
+ msg + c->author.off, c->author.len,
+ c->dmode);
case 'c': /* committer ... */
return format_person_part(sb, placeholder[1],
- msg + c->committer.off, c->committer.len);
+ msg + c->committer.off, c->committer.len,
+ c->dmode);
case 'e': /* encoding */
strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
return 1;
@@ -599,12 +602,14 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder,
}
void format_commit_message(const struct commit *commit,
- const void *format, struct strbuf *sb)
+ const void *format, struct strbuf *sb,
+ enum date_mode dmode)
{
struct format_commit_context context;
memset(&context, 0, sizeof(context));
context.commit = commit;
+ context.dmode = dmode;
strbuf_expand(sb, format, format_commit_item, &context);
}
@@ -770,7 +775,7 @@ void pretty_print_commit(enum cmit_fmt fmt, const struct commit *commit,
const char *encoding;
if (fmt == CMIT_FMT_USERFORMAT) {
- format_commit_message(commit, user_format, sb);
+ format_commit_message(commit, user_format, sb, dmode);
return;
}
diff --git a/shell.c b/shell.c
index 0f6a727a8..e3393690d 100644
--- a/shell.c
+++ b/shell.c
@@ -48,6 +48,19 @@ int main(int argc, char **argv)
{
char *prog;
struct commands *cmd;
+ int devnull_fd;
+
+ /*
+ * Always open file descriptors 0/1/2 to avoid clobbering files
+ * in die(). It also avoids not messing up when the pipes are
+ * dup'ed onto stdin/stdout/stderr in the child processes we spawn.
+ */
+ devnull_fd = open("/dev/null", O_RDWR);
+ while (devnull_fd >= 0 && devnull_fd <= 2)
+ devnull_fd = dup(devnull_fd);
+ if (devnull_fd == -1)
+ die("opening /dev/null failed (%s)", strerror(errno));
+ close (devnull_fd);
/*
* Special hack to pretend to be a CVS server
diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh
index 9176484db..485ad4d44 100755
--- a/t/t6006-rev-list-format.sh
+++ b/t/t6006-rev-list-format.sh
@@ -139,6 +139,12 @@ commit 131a310eb913d107dd3c09a65d1651175898735d
commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873
EOF
+test_expect_success '%ad respects --date=' '
+ echo 2005-04-07 >expect.ad-short &&
+ git log -1 --date=short --pretty=tformat:%ad >output.ad-short master &&
+ test_cmp expect.ad-short output.ad-short
+'
+
test_expect_success 'empty email' '
test_tick &&
C=$(GIT_AUTHOR_EMAIL= git commit-tree HEAD^{tree} </dev/null) &&