Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.kernel.org/pub/scm/git/git.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-check-attr.txt5
-rw-r--r--Documentation/git-commit.txt12
-rw-r--r--Documentation/git-log.txt8
-rw-r--r--Documentation/git-merge.txt3
-rw-r--r--Documentation/git-rev-list.txt10
-rw-r--r--Documentation/git-shortlog.txt19
-rw-r--r--Documentation/gitattributes.txt37
-rw-r--r--builtin-commit.c62
-rw-r--r--combine-diff.c32
-rw-r--r--config.c31
-rwxr-xr-xcontrib/examples/git-revert.sh197
-rw-r--r--diff.c12
-rwxr-xr-xgit-cvsimport.perl1
-rw-r--r--quote.c16
-rw-r--r--quote.h1
-rw-r--r--revision.c6
-rwxr-xr-xt/t1300-repo-config.sh17
-rwxr-xr-xt/t4202-log.sh74
-rwxr-xr-xt/t7005-editor.sh2
-rwxr-xr-xt/t7502-commit.sh65
20 files changed, 554 insertions, 56 deletions
diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt
index 856d2af2ed..47cb1bdfa3 100644
--- a/Documentation/git-check-attr.txt
+++ b/Documentation/git-check-attr.txt
@@ -23,6 +23,11 @@ OPTIONS
be treated as an attribute.
+SEE ALSO
+--------
+gitlink:gitattributes[5].
+
+
Author
------
Written by Junio C Hamano <junkio@cox.net>
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 4261384158..96383b6543 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -11,7 +11,7 @@ SYNOPSIS
'git-commit' [-a | --interactive] [-s] [-v] [-u]
[(-c | -C) <commit> | -F <file> | -m <msg> | --amend]
[--allow-empty] [--no-verify] [-e] [--author <author>]
- [--] [[-i | -o ]<file>...]
+ [--cleanup=<mode>] [--] [[-i | -o ]<file>...]
DESCRIPTION
-----------
@@ -95,6 +95,16 @@ OPTIONS
from making such a commit. This option bypasses the safety, and
is primarily for use by foreign scm interface scripts.
+--cleanup=<mode>::
+ This option sets how the commit message is cleaned up.
+ The '<mode>' can be one of 'verbatim', 'whitespace', 'strip',
+ and 'default'. The 'default' mode will strip leading and
+ trailing empty lines and #commentary from the commit message
+ only if the message is to be edited. Otherwise only whitespace
+ removed. The 'verbatim' mode does not change message at all,
+ 'whitespace' removes just leading/trailing whitespace lines
+ and 'strip' removes both whitespace and commentary.
+
-e|--edit::
The message taken from file with `-F`, command line with
`-m`, and from file with `-C` are usually used as the
diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt
index 5920d1799a..d71e51ad46 100644
--- a/Documentation/git-log.txt
+++ b/Documentation/git-log.txt
@@ -43,8 +43,12 @@ include::diff-options.txt[]
--first-parent::
Follow only the first parent commit upon seeing a merge
- commit. This option gives a better overview of the
- evolution of a particular branch.
+ commit. This option can give a better overview when
+ viewing the evolution of a particular topic branch,
+ because merges into a topic branch tend to be only about
+ adjusting to updated upstream from time to time, and
+ this option allows you to ignore the individual commits
+ brought in to your history by such a merge.
-g, \--walk-reflogs::
Show commits as they were recorded in the reflog. The log contains
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index eabd7ef33f..1521a9ee0f 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -163,7 +163,8 @@ After seeing a conflict, you can do two things:
SEE ALSO
--------
-gitlink:git-fmt-merge-msg[1], gitlink:git-pull[1]
+gitlink:git-fmt-merge-msg[1], gitlink:git-pull[1],
+gitlink:gitattributes[5]
Author
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index a03f9fe5fa..438dae02e2 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -15,6 +15,7 @@ SYNOPSIS
[ \--min-age=timestamp ]
[ \--sparse ]
[ \--no-merges ]
+ [ \--first-parent ]
[ \--remove-empty ]
[ \--full-history ]
[ \--not ]
@@ -256,6 +257,15 @@ limiting may be applied.
Do not print commits with more than one parent.
+--first-parent::
+ Follow only the first parent commit upon seeing a merge
+ commit. This option can give a better overview when
+ viewing the evolution of a particular topic branch,
+ because merges into a topic branch tend to be only about
+ adjusting to updated upstream from time to time, and
+ this option allows you to ignore the individual commits
+ brought in to your history by such a merge.
+
--not::
Reverses the meaning of the '{caret}' prefix (or lack thereof)
diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt
index e14720b73f..36510a8451 100644
--- a/Documentation/git-shortlog.txt
+++ b/Documentation/git-shortlog.txt
@@ -38,15 +38,16 @@ OPTIONS
FILES
-----
-.mailmap::
- If this file exists, it will be used for mapping author email
- addresses to a real author name. One mapping per line, first
- the author name followed by the email address enclosed by
- '<' and '>'. Use hash '#' for comments. Example:
-
- # Keep alphabetized
- Adam Morrow <adam@localhost.localdomain>
- Eve Jones <eve@laptop.(none)>
+If the file `.mailmap` exists, it will be used for mapping author
+email addresses to a real author name. One mapping per line, first
+the author name followed by the email address enclosed by
+'<' and '>'. Use hash '#' for comments. Example:
+
+------------
+# Keep alphabetized
+Adam Morrow <adam@localhost.localdomain>
+Eve Jones <eve@laptop.(none)>
+------------
Author
------
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 71c7ad76d5..cc9c7c52c0 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -322,12 +322,43 @@ String::
requested with "binary".
+Built-in merge drivers
+^^^^^^^^^^^^^^^^^^^^^^
+
+There are a few built-in low-level merge drivers defined that
+can be asked for via the `merge` attribute.
+
+text::
+
+ Usual 3-way file level merge for text files. Conflicted
+ regions are marked with conflict markers `<<<<<<<`,
+ `=======` and `>>>>>>>`. The version from your branch
+ appears before the `=======` marker, and the version
+ from the merged branch appears after the `=======`
+ marker.
+
+binary::
+
+ Keep the version from your branch in the work tree, but
+ leave the path in the conflicted state for the user to
+ sort out.
+
+union::
+
+ Run 3-way file level merge for text files, but take
+ lines from both versions, instead of leaving conflict
+ markers. This tends to leave the added lines in the
+ resulting file in random order and the user should
+ verify the result. Do not use this if you do not
+ understand the implications.
+
+
Defining a custom merge driver
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-The definition of a merge driver is done in `gitconfig` not
-`gitattributes` file, so strictly speaking this manual page is a
-wrong place to talk about it. However...
+The definition of a merge driver is done in the `.git/config`
+file, not in the `gitattributes` file, so strictly speaking this
+manual page is a wrong place to talk about it. However...
To define a custom merge driver `filfre`, add a section to your
`$GIT_DIR/config` file (or `$HOME/.gitconfig` file) like this:
diff --git a/builtin-commit.c b/builtin-commit.c
index 96410de55d..73f1e3576a 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -47,8 +47,21 @@ static char *logfile, *force_author, *template_file;
static char *edit_message, *use_message;
static int all, edit_flag, also, interactive, only, amend, signoff;
static int quiet, verbose, untracked_files, no_verify, allow_empty;
+/*
+ * The default commit message cleanup mode will remove the lines
+ * beginning with # (shell comments) and leading and trailing
+ * whitespaces (empty lines or containing only whitespaces)
+ * if editor is used, and only the whitespaces if the message
+ * is specified explicitly.
+ */
+static enum {
+ CLEANUP_SPACE,
+ CLEANUP_NONE,
+ CLEANUP_ALL,
+} cleanup_mode;
+static char *cleanup_arg;
-static int no_edit, initial_commit, in_merge;
+static int use_editor = 1, initial_commit, in_merge;
const char *only_include_assumed;
struct strbuf message;
@@ -88,6 +101,7 @@ static struct option builtin_commit_options[] = {
OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"),
OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"),
OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"),
+ OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
OPT_END()
};
@@ -346,7 +360,8 @@ static int prepare_log_message(const char *index_file, const char *prefix)
if (fp == NULL)
die("could not open %s", git_path(commit_editmsg));
- stripspace(&sb, 0);
+ if (cleanup_mode != CLEANUP_NONE)
+ stripspace(&sb, 0);
if (signoff) {
struct strbuf sob;
@@ -372,9 +387,9 @@ static int prepare_log_message(const char *index_file, const char *prefix)
strbuf_release(&sb);
- if (no_edit) {
+ if (!use_editor) {
struct rev_info rev;
- unsigned char sha1[40];
+ unsigned char sha1[20];
const char *parent = "HEAD";
fclose(fp);
@@ -382,12 +397,12 @@ static int prepare_log_message(const char *index_file, const char *prefix)
if (!active_nr && read_cache() < 0)
die("Cannot read index");
- if (get_sha1("HEAD", sha1) != 0)
- return !!active_nr;
-
if (amend)
parent = "HEAD^1";
+ if (get_sha1(parent, sha1))
+ return !!active_nr;
+
init_revisions(&rev, "");
rev.abbrev = 0;
setup_revisions(0, NULL, &rev, parent);
@@ -398,7 +413,7 @@ static int prepare_log_message(const char *index_file, const char *prefix)
return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES);
}
- if (in_merge && !no_edit)
+ if (in_merge)
fprintf(fp,
"#\n"
"# It looks like you may be committing a MERGE.\n"
@@ -411,7 +426,12 @@ static int prepare_log_message(const char *index_file, const char *prefix)
fprintf(fp,
"\n"
"# Please enter the commit message for your changes.\n"
- "# (Comment lines starting with '#' will not be included)\n");
+ "# (Comment lines starting with '#' will ");
+ if (cleanup_mode == CLEANUP_ALL)
+ fprintf(fp, "not be included)\n");
+ else /* CLEANUP_SPACE, that is. */
+ fprintf(fp, "be kept.\n"
+ "# You can remove them yourself if you want to)\n");
if (only_include_assumed)
fprintf(fp, "# %s\n", only_include_assumed);
@@ -435,10 +455,13 @@ static int message_is_empty(struct strbuf *sb, int start)
const char *nl;
int eol, i;
+ if (cleanup_mode == CLEANUP_NONE && sb->len)
+ return 0;
+
/* See if the template is just a prefix of the message. */
strbuf_init(&tmpl, 0);
if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) {
- stripspace(&tmpl, 1);
+ stripspace(&tmpl, cleanup_mode == CLEANUP_ALL);
if (start + tmpl.len <= sb->len &&
memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0)
start += tmpl.len;
@@ -513,9 +536,9 @@ static int parse_and_validate_options(int argc, const char *argv[],
argc = parse_options(argc, argv, builtin_commit_options, usage, 0);
if (logfile || message.len || use_message)
- no_edit = 1;
+ use_editor = 0;
if (edit_flag)
- no_edit = 0;
+ use_editor = 1;
if (get_sha1("HEAD", head_sha1))
initial_commit = 1;
@@ -591,6 +614,16 @@ static int parse_and_validate_options(int argc, const char *argv[],
only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths...";
also = 0;
}
+ if (!cleanup_arg || !strcmp(cleanup_arg, "default"))
+ cleanup_mode = use_editor ? CLEANUP_ALL : CLEANUP_SPACE;
+ else if (!strcmp(cleanup_arg, "verbatim"))
+ cleanup_mode = CLEANUP_NONE;
+ else if (!strcmp(cleanup_arg, "whitespace"))
+ cleanup_mode = CLEANUP_SPACE;
+ else if (!strcmp(cleanup_arg, "strip"))
+ cleanup_mode = CLEANUP_ALL;
+ else
+ die("Invalid cleanup mode %s", cleanup_arg);
if (all && argc > 0)
die("Paths with -a does not make sense.");
@@ -796,7 +829,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
/* Get the commit message and validate it */
header_len = sb.len;
- if (!no_edit) {
+ if (use_editor) {
char index[PATH_MAX];
const char *env[2] = { index, NULL };
snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file);
@@ -817,7 +850,8 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
if (p != NULL)
strbuf_setlen(&sb, p - sb.buf + 1);
- stripspace(&sb, 1);
+ if (cleanup_mode != CLEANUP_NONE)
+ stripspace(&sb, cleanup_mode == CLEANUP_ALL);
if (sb.len < header_len || message_is_empty(&sb, header_len)) {
rollback_index_files();
die("no commit message? aborting commit.");
diff --git a/combine-diff.c b/combine-diff.c
index e22db89932..0e19cbaacc 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -646,12 +646,19 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt,
sline->p_lno[i] = sline->p_lno[j];
}
-static void dump_quoted_path(const char *prefix, const char *path,
+static void dump_quoted_path(const char *head,
+ const char *prefix,
+ const char *path,
const char *c_meta, const char *c_reset)
{
- printf("%s%s", c_meta, prefix);
- quote_c_style(path, NULL, stdout, 0);
- printf("%s\n", c_reset);
+ static struct strbuf buf = STRBUF_INIT;
+
+ strbuf_reset(&buf);
+ strbuf_addstr(&buf, c_meta);
+ strbuf_addstr(&buf, head);
+ quote_two_c_style(&buf, prefix, path, 0);
+ strbuf_addstr(&buf, c_reset);
+ puts(buf.buf);
}
static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
@@ -793,7 +800,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (rev->loginfo && !rev->no_commit_id)
show_log(rev, opt->msg_sep);
dump_quoted_path(dense ? "diff --cc " : "diff --combined ",
- elem->path, c_meta, c_reset);
+ "", elem->path, c_meta, c_reset);
printf("%sindex ", c_meta);
for (i = 0; i < num_parent; i++) {
abb = find_unique_abbrev(elem->parent[i].sha1,
@@ -829,14 +836,19 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
printf("%s\n", c_reset);
}
if (added)
- dump_quoted_path("--- /dev/", "null", c_meta, c_reset);
+ dump_quoted_path("--- ", "", "/dev/null",
+ c_meta, c_reset);
else
- dump_quoted_path("--- a/", elem->path, c_meta, c_reset);
+ dump_quoted_path("--- ", opt->a_prefix, elem->path,
+ c_meta, c_reset);
if (deleted)
- dump_quoted_path("+++ /dev/", "null", c_meta, c_reset);
+ dump_quoted_path("+++ ", "", "/dev/null",
+ c_meta, c_reset);
else
- dump_quoted_path("+++ b/", elem->path, c_meta, c_reset);
- dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF));
+ dump_quoted_path("+++ ", opt->b_prefix, elem->path,
+ c_meta, c_reset);
+ dump_sline(sline, cnt, num_parent,
+ DIFF_OPT_TST(opt, COLOR_DIFF));
}
free(result);
diff --git a/config.c b/config.c
index 9a5c5470cc..80db92990a 100644
--- a/config.c
+++ b/config.c
@@ -234,17 +234,23 @@ static int git_parse_file(config_fn_t fn)
die("bad config file line %d in %s", config_linenr, config_file_name);
}
-static unsigned long get_unit_factor(const char *end)
+static int parse_unit_factor(const char *end, unsigned long *val)
{
if (!*end)
return 1;
- else if (!strcasecmp(end, "k"))
- return 1024;
- else if (!strcasecmp(end, "m"))
- return 1024 * 1024;
- else if (!strcasecmp(end, "g"))
- return 1024 * 1024 * 1024;
- die("unknown unit: '%s'", end);
+ else if (!strcasecmp(end, "k")) {
+ *val *= 1024;
+ return 1;
+ }
+ else if (!strcasecmp(end, "m")) {
+ *val *= 1024 * 1024;
+ return 1;
+ }
+ else if (!strcasecmp(end, "g")) {
+ *val *= 1024 * 1024 * 1024;
+ return 1;
+ }
+ return 0;
}
int git_parse_long(const char *value, long *ret)
@@ -252,7 +258,10 @@ int git_parse_long(const char *value, long *ret)
if (value && *value) {
char *end;
long val = strtol(value, &end, 0);
- *ret = val * get_unit_factor(end);
+ unsigned long factor = 1;
+ if (!parse_unit_factor(end, &factor))
+ return 0;
+ *ret = val * factor;
return 1;
}
return 0;
@@ -263,7 +272,9 @@ int git_parse_ulong(const char *value, unsigned long *ret)
if (value && *value) {
char *end;
unsigned long val = strtoul(value, &end, 0);
- *ret = val * get_unit_factor(end);
+ if (!parse_unit_factor(end, &val))
+ return 0;
+ *ret = val;
return 1;
}
return 0;
diff --git a/contrib/examples/git-revert.sh b/contrib/examples/git-revert.sh
new file mode 100755
index 0000000000..49f00321b2
--- /dev/null
+++ b/contrib/examples/git-revert.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+# Copyright (c) 2005 Junio C Hamano
+#
+
+case "$0" in
+*-revert* )
+ test -t 0 && edit=-e
+ replay=
+ me=revert
+ USAGE='[--edit | --no-edit] [-n] <commit-ish>' ;;
+*-cherry-pick* )
+ replay=t
+ edit=
+ me=cherry-pick
+ USAGE='[--edit] [-n] [-r] [-x] <commit-ish>' ;;
+* )
+ echo >&2 "What are you talking about?"
+ exit 1 ;;
+esac
+
+SUBDIRECTORY_OK=Yes ;# we will cd up
+. git-sh-setup
+require_work_tree
+cd_to_toplevel
+
+no_commit=
+while case "$#" in 0) break ;; esac
+do
+ case "$1" in
+ -n|--n|--no|--no-|--no-c|--no-co|--no-com|--no-comm|\
+ --no-commi|--no-commit)
+ no_commit=t
+ ;;
+ -e|--e|--ed|--edi|--edit)
+ edit=-e
+ ;;
+ --n|--no|--no-|--no-e|--no-ed|--no-edi|--no-edit)
+ edit=
+ ;;
+ -r)
+ : no-op ;;
+ -x|--i-really-want-to-expose-my-private-commit-object-name)
+ replay=
+ ;;
+ -*)
+ usage
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+set_reflog_action "$me"
+
+test "$me,$replay" = "revert,t" && usage
+
+case "$no_commit" in
+t)
+ # We do not intend to commit immediately. We just want to
+ # merge the differences in.
+ head=$(git-write-tree) ||
+ die "Your index file is unmerged."
+ ;;
+*)
+ head=$(git-rev-parse --verify HEAD) ||
+ die "You do not have a valid HEAD"
+ files=$(git-diff-index --cached --name-only $head) || exit
+ if [ "$files" ]; then
+ die "Dirty index: cannot $me (dirty: $files)"
+ fi
+ ;;
+esac
+
+rev=$(git-rev-parse --verify "$@") &&
+commit=$(git-rev-parse --verify "$rev^0") ||
+ die "Not a single commit $@"
+prev=$(git-rev-parse --verify "$commit^1" 2>/dev/null) ||
+ die "Cannot run $me a root commit"
+git-rev-parse --verify "$commit^2" >/dev/null 2>&1 &&
+ die "Cannot run $me a multi-parent commit."
+
+encoding=$(git config i18n.commitencoding || echo UTF-8)
+
+# "commit" is an existing commit. We would want to apply
+# the difference it introduces since its first parent "prev"
+# on top of the current HEAD if we are cherry-pick. Or the
+# reverse of it if we are revert.
+
+case "$me" in
+revert)
+ git show -s --pretty=oneline --encoding="$encoding" $commit |
+ sed -e '
+ s/^[^ ]* /Revert "/
+ s/$/"/
+ '
+ echo
+ echo "This reverts commit $commit."
+ test "$rev" = "$commit" ||
+ echo "(original 'git revert' arguments: $@)"
+ base=$commit next=$prev
+ ;;
+
+cherry-pick)
+ pick_author_script='
+ /^author /{
+ s/'\''/'\''\\'\'\''/g
+ h
+ s/^author \([^<]*\) <[^>]*> .*$/\1/
+ s/'\''/'\''\'\'\''/g
+ s/.*/GIT_AUTHOR_NAME='\''&'\''/p
+
+ g
+ s/^author [^<]* <\([^>]*\)> .*$/\1/
+ s/'\''/'\''\'\'\''/g
+ s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p
+
+ g
+ s/^author [^<]* <[^>]*> \(.*\)$/\1/
+ s/'\''/'\''\'\'\''/g
+ s/.*/GIT_AUTHOR_DATE='\''&'\''/p
+
+ q
+ }'
+
+ logmsg=`git show -s --pretty=raw --encoding="$encoding" "$commit"`
+ set_author_env=`echo "$logmsg" |
+ LANG=C LC_ALL=C sed -ne "$pick_author_script"`
+ eval "$set_author_env"
+ export GIT_AUTHOR_NAME
+ export GIT_AUTHOR_EMAIL
+ export GIT_AUTHOR_DATE
+
+ echo "$logmsg" |
+ sed -e '1,/^$/d' -e 's/^ //'
+ case "$replay" in
+ '')
+ echo "(cherry picked from commit $commit)"
+ test "$rev" = "$commit" ||
+ echo "(original 'git cherry-pick' arguments: $@)"
+ ;;
+ esac
+ base=$prev next=$commit
+ ;;
+
+esac >.msg
+
+eval GITHEAD_$head=HEAD
+eval GITHEAD_$next='`git show -s \
+ --pretty=oneline --encoding="$encoding" "$commit" |
+ sed -e "s/^[^ ]* //"`'
+export GITHEAD_$head GITHEAD_$next
+
+# This three way merge is an interesting one. We are at
+# $head, and would want to apply the change between $commit
+# and $prev on top of us (when reverting), or the change between
+# $prev and $commit on top of us (when cherry-picking or replaying).
+
+git-merge-recursive $base -- $head $next &&
+result=$(git-write-tree 2>/dev/null) || {
+ mv -f .msg "$GIT_DIR/MERGE_MSG"
+ {
+ echo '
+Conflicts:
+'
+ git ls-files --unmerged |
+ sed -e 's/^[^ ]* / /' |
+ uniq
+ } >>"$GIT_DIR/MERGE_MSG"
+ echo >&2 "Automatic $me failed. After resolving the conflicts,"
+ echo >&2 "mark the corrected paths with 'git-add <paths>'"
+ echo >&2 "and commit the result."
+ case "$me" in
+ cherry-pick)
+ echo >&2 "You may choose to use the following when making"
+ echo >&2 "the commit:"
+ echo >&2 "$set_author_env"
+ esac
+ exit 1
+}
+echo >&2 "Finished one $me."
+
+# If we are cherry-pick, and if the merge did not result in
+# hand-editing, we will hit this commit and inherit the original
+# author date and name.
+# If we are revert, or if our cherry-pick results in a hand merge,
+# we had better say that the current user is responsible for that.
+
+case "$no_commit" in
+'')
+ git-commit -n -F .msg $edit
+ rm -f .msg
+ ;;
+esac
diff --git a/diff.c b/diff.c
index 61fd49236a..5bdc111378 100644
--- a/diff.c
+++ b/diff.c
@@ -300,19 +300,25 @@ static void emit_rewrite_diff(const char *name_a,
const char *old = diff_get_color(color_diff, DIFF_FILE_OLD);
const char *new = diff_get_color(color_diff, DIFF_FILE_NEW);
const char *reset = diff_get_color(color_diff, DIFF_RESET);
+ static struct strbuf a_name = STRBUF_INIT, b_name = STRBUF_INIT;
name_a += (*name_a == '/');
name_b += (*name_b == '/');
name_a_tab = strchr(name_a, ' ') ? "\t" : "";
name_b_tab = strchr(name_b, ' ') ? "\t" : "";
+ strbuf_reset(&a_name);
+ strbuf_reset(&b_name);
+ quote_two_c_style(&a_name, o->a_prefix, name_a, 0);
+ quote_two_c_style(&b_name, o->b_prefix, name_b, 0);
+
diff_populate_filespec(one, 0);
diff_populate_filespec(two, 0);
lc_a = count_lines(one->data, one->size);
lc_b = count_lines(two->data, two->size);
- printf("%s--- %s%s%s%s\n%s+++ %s%s%s%s\n%s@@ -",
- metainfo, o->a_prefix, name_a, name_a_tab, reset,
- metainfo, o->b_prefix, name_b, name_b_tab, reset, fraginfo);
+ printf("%s--- %s%s%s\n%s+++ %s%s%s\n%s@@ -",
+ metainfo, a_name.buf, name_a_tab, reset,
+ metainfo, b_name.buf, name_b_tab, reset, fraginfo);
print_line_count(lc_a);
printf(" +");
print_line_count(lc_b);
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 1fa9a22376..6d8ff93f5f 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -632,6 +632,7 @@ unless ($opt_P) {
print $cvspsfh $_;
}
close CVSPS;
+ $? == 0 or die "git-cvsimport: fatal: cvsps reported error\n";
close $cvspsfh;
} else {
$cvspsfile = $opt_P;
diff --git a/quote.c b/quote.c
index 6986b4420f..d061626c34 100644
--- a/quote.c
+++ b/quote.c
@@ -213,6 +213,22 @@ size_t quote_c_style(const char *name, struct strbuf *sb, FILE *fp, int nodq)
return quote_c_style_counted(name, -1, sb, fp, nodq);
}
+void quote_two_c_style(struct strbuf *sb, const char *prefix, const char *path, int nodq)
+{
+ if (quote_c_style(prefix, NULL, NULL, 0) ||
+ quote_c_style(path, NULL, NULL, 0)) {
+ if (!nodq)
+ strbuf_addch(sb, '"');
+ quote_c_style(prefix, sb, NULL, 1);
+ quote_c_style(path, sb, NULL, 1);
+ if (!nodq)
+ strbuf_addch(sb, '"');
+ } else {
+ strbuf_addstr(sb, prefix);
+ strbuf_addstr(sb, path);
+ }
+}
+
void write_name_quoted(const char *name, FILE *fp, int terminator)
{
if (terminator) {
diff --git a/quote.h b/quote.h
index ab7596f57b..4da110ec01 100644
--- a/quote.h
+++ b/quote.h
@@ -41,6 +41,7 @@ extern char *sq_dequote(char *);
extern int unquote_c_style(struct strbuf *, const char *quoted, const char **endp);
extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq);
+extern void quote_two_c_style(struct strbuf *, const char *, const char *, int);
extern void write_name_quoted(const char *name, FILE *, int terminator);
extern void write_name_quotedpfx(const char *pfx, size_t pfxlen,
diff --git a/revision.c b/revision.c
index 7e2f4f1eb5..6e85aaa3fb 100644
--- a/revision.c
+++ b/revision.c
@@ -1290,8 +1290,10 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
if (revs->diffopt.output_format & ~DIFF_FORMAT_NO_OUTPUT)
revs->diff = 1;
- /* Pickaxe and rename following needs diffs */
- if (revs->diffopt.pickaxe || DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
+ /* Pickaxe, diff-filter and rename following need diffs */
+ if (revs->diffopt.pickaxe ||
+ revs->diffopt.filter ||
+ DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
revs->diff = 1;
if (revs->topo_order)
diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh
index e894629e7e..42eac2a7cb 100755
--- a/t/t1300-repo-config.sh
+++ b/t/t1300-repo-config.sh
@@ -448,6 +448,23 @@ test_expect_success numbers '
test z1048576 = "z$m"
'
+cat > expect <<EOF
+fatal: bad config value for 'aninvalid.unit' in .git/config
+EOF
+
+test_expect_success 'invalid unit' '
+
+ git config aninvalid.unit "1auto" &&
+ s=$(git config aninvalid.unit) &&
+ test "z1auto" = "z$s" &&
+ if git config --int --get aninvalid.unit 2>actual
+ then
+ echo config should have failed
+ false
+ fi &&
+ cmp actual expect
+'
+
cat > expect << EOF
true
false
diff --git a/t/t4202-log.sh b/t/t4202-log.sh
new file mode 100755
index 0000000000..b53645417b
--- /dev/null
+++ b/t/t4202-log.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+test_description='git log'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ echo one >one &&
+ git add one &&
+ test_tick &&
+ git commit -m initial &&
+
+ echo ichi >one &&
+ git add one &&
+ test_tick &&
+ git commit -m second &&
+
+ mkdir a &&
+ echo ni >a/two &&
+ git add a/two &&
+ test_tick &&
+ git commit -m third &&
+
+ echo san >a/three &&
+ git add a/three &&
+ test_tick &&
+ git commit -m fourth &&
+
+ git rm a/three &&
+ test_tick &&
+ git commit -m fifth
+
+'
+
+test_expect_success 'diff-filter=A' '
+
+ actual=$(git log --pretty="format:%s" --diff-filter=A HEAD) &&
+ expect=$(echo fourth ; echo third ; echo initial) &&
+ test "$actual" = "$expect" || {
+ echo Oops
+ echo "Actual: $actual"
+ false
+ }
+
+'
+
+test_expect_success 'diff-filter=M' '
+
+ actual=$(git log --pretty="format:%s" --diff-filter=M HEAD) &&
+ expect=$(echo second) &&
+ test "$actual" = "$expect" || {
+ echo Oops
+ echo "Actual: $actual"
+ false
+ }
+
+'
+
+test_expect_success 'diff-filter=D' '
+
+ actual=$(git log --pretty="format:%s" --diff-filter=D HEAD) &&
+ expect=$(echo fifth) &&
+ test "$actual" = "$expect" || {
+ echo Oops
+ echo "Actual: $actual"
+ false
+ }
+
+'
+
+
+
+test_done \ No newline at end of file
diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh
index 44228b5ac1..c1cec55306 100755
--- a/t/t7005-editor.sh
+++ b/t/t7005-editor.sh
@@ -37,7 +37,7 @@ test_expect_success 'dumb should error out when falling back on vi' '
if git commit --amend
then
echo "Oops?"
- exit 1
+ false
else
: happy
fi
diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh
index 21ac785e3d..aaf497e6a5 100755
--- a/t/t7502-commit.sh
+++ b/t/t7502-commit.sh
@@ -89,4 +89,69 @@ test_expect_success 'verbose' '
'
+test_expect_success 'cleanup commit messages (verbatim,-t)' '
+
+ echo >>negative &&
+ { echo;echo "# text";echo; } >expect &&
+ git commit --cleanup=verbatim -t expect -a &&
+ git cat-file -p HEAD |sed -e "1,/^\$/d" |head -n 3 >actual &&
+ diff -u expect actual
+
+'
+
+test_expect_success 'cleanup commit messages (verbatim,-F)' '
+
+ echo >>negative &&
+ git commit --cleanup=verbatim -F expect -a &&
+ git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ diff -u expect actual
+
+'
+
+test_expect_success 'cleanup commit messages (verbatim,-m)' '
+
+ echo >>negative &&
+ git commit --cleanup=verbatim -m "$(cat expect)" -a &&
+ git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ diff -u expect actual
+
+'
+
+test_expect_success 'cleanup commit messages (whitespace,-F)' '
+
+ echo >>negative &&
+ { echo;echo "# text";echo; } >text &&
+ echo "# text" >expect &&
+ git commit --cleanup=whitespace -F text -a &&
+ git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ diff -u expect actual
+
+'
+
+test_expect_success 'cleanup commit messages (strip,-F)' '
+
+ echo >>negative &&
+ { echo;echo "# text";echo sample;echo; } >text &&
+ echo sample >expect &&
+ git commit --cleanup=strip -F text -a &&
+ git cat-file -p HEAD |sed -e "1,/^\$/d">actual &&
+ diff -u expect actual
+
+'
+
+echo "sample
+
+# Please enter the commit message for your changes.
+# (Comment lines starting with '#' will not be included)" >expect
+
+test_expect_success 'cleanup commit messages (strip,-F,-e)' '
+
+ echo >>negative &&
+ { echo;echo sample;echo; } >text &&
+ git commit -e -F text -a &&
+ head -n 4 .git/COMMIT_EDITMSG >actual &&
+ diff -u expect actual
+
+'
+
test_done