* [PATCH v4 05/12] sequencer.c: recognize "(cherry picked from ..." as part of s-o-b footer
From: Brandon Casey @ 2013-02-12 10:17 UTC (permalink / raw)
To: git; +Cc: gitster, pclouds, jrnieder, Brandon Casey, Brandon Casey
In-Reply-To: <1360664260-11803-1-git-send-email-drafnel@gmail.com>
When 'cherry-pick -s' is used to append a signed-off-by line to a cherry
picked commit, it does not currently detect the "(cherry picked from..."
that may have been appended by a previous 'cherry-pick -x' as part of the
s-o-b footer and it will insert a blank line before appending a new s-o-b.
Let's detect "(cherry picked from...)" as part of the footer so that we
will produce this:
Signed-off-by: A U Thor <author@example.com>
(cherry picked from da39a3ee5e6b4b0d3255bfef95601890afd80709)
Signed-off-by: C O Mmitter <committer@example.com>
instead of this:
Signed-off-by: A U Thor <author@example.com>
(cherry picked from da39a3ee5e6b4b0d3255bfef95601890afd80709)
Signed-off-by: C O Mmitter <committer@example.com>
[with improvements from Jonathan Nieder]
Signed-off-by: Brandon Casey <bcasey@nvidia.com>
Acked-by: Jonathan Nieder <jrnieder@gmail.com>
---
sequencer.c | 51 ++++++++++++++++++++++++++++++++------------
t/t3511-cherry-pick-x.sh | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 92 insertions(+), 14 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index aa2cb8e..93495b0 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -18,6 +18,7 @@
#define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION"
const char sign_off_header[] = "Signed-off-by: ";
+static const char cherry_picked_prefix[] = "(cherry picked from commit ";
static void remove_sequencer_state(void)
{
@@ -496,7 +497,7 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts)
}
if (opts->record_origin) {
- strbuf_addstr(&msgbuf, "(cherry picked from commit ");
+ strbuf_addstr(&msgbuf, cherry_picked_prefix);
strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1));
strbuf_addstr(&msgbuf, ")\n");
}
@@ -1021,16 +1022,44 @@ int sequencer_pick_revisions(struct replay_opts *opts)
return pick_commits(todo_list, opts);
}
-static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
+static int is_rfc2822_line(const char *buf, int len)
{
- char ch, prev;
- int i, j, k;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int ch = buf[i];
+ if (ch == ':')
+ return 1;
+ if (!isalnum(ch) && ch != '-')
+ break;
+ }
+
+ return 0;
+}
+
+static int is_cherry_picked_from_line(const char *buf, int len)
+{
+ /*
+ * We only care that it looks roughly like (cherry picked from ...)
+ */
+ return len > strlen(cherry_picked_prefix) + 1 &&
+ !prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')';
+}
+
+static int has_conforming_footer(struct strbuf *sb, int ignore_footer)
+{
+ char prev;
+ int i, k;
int len = sb->len - ignore_footer;
const char *buf = sb->buf;
+ /* footer must end with newline */
+ if (!len || buf[len - 1] != '\n')
+ return 0;
+
prev = '\0';
for (i = len - 1; i > 0; i--) {
- ch = buf[i];
+ char ch = buf[i];
if (prev == '\n' && ch == '\n') /* paragraph break */
break;
prev = ch;
@@ -1045,15 +1074,9 @@ static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
; /* do nothing */
k++;
- for (j = 0; i + j < len; j++) {
- ch = buf[i + j];
- if (ch == ':')
- break;
- if (isalnum(ch) ||
- (ch == '-'))
- continue;
+ if (!is_rfc2822_line(buf + i, k - i - 1) &&
+ !is_cherry_picked_from_line(buf + i, k - i - 1))
return 0;
- }
}
return 1;
}
@@ -1070,7 +1093,7 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer)
for (i = msgbuf->len - 1 - ignore_footer; i > 0 && msgbuf->buf[i - 1] != '\n'; i--)
; /* do nothing */
if (prefixcmp(msgbuf->buf + i, sob.buf)) {
- if (!i || !ends_rfc2822_footer(msgbuf, ignore_footer))
+ if (!i || !has_conforming_footer(msgbuf, ignore_footer))
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, "\n", 1);
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, sob.buf, sob.len);
}
diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh
index 2a040b7..73da182 100755
--- a/t/t3511-cherry-pick-x.sh
+++ b/t/t3511-cherry-pick-x.sh
@@ -32,6 +32,10 @@ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
mesg_with_footer_sob="$mesg_with_footer
Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+mesg_with_cherry_footer="$mesg_with_footer_sob
+(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709)
+Tested-by: C.U. Thor <cuthor@example.com>"
+
test_expect_success setup '
git config advice.detachedhead false &&
@@ -47,6 +51,8 @@ test_expect_success setup '
test_commit "$mesg_with_footer" foo b mesg-with-footer &&
git reset --hard initial &&
test_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob &&
+ git reset --hard initial &&
+ test_commit "$mesg_with_cherry_footer" foo b mesg-with-cherry-footer &&
pristine_detach initial &&
test_commit conflicting unrelated
'
@@ -98,6 +104,19 @@ test_expect_success 'cherry-pick -s adds sob when last sob doesnt match committe
test_cmp expect actual
'
+test_expect_success 'cherry-pick -x -s adds sob when last sob doesnt match committer' '
+ pristine_detach initial &&
+ sha1=`git rev-parse mesg-with-footer^0` &&
+ git cherry-pick -x -s mesg-with-footer &&
+ cat <<-EOF >expect &&
+ $mesg_with_footer
+ (cherry picked from commit $sha1)
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob' '
pristine_detach initial &&
git cherry-pick -s mesg-with-footer-sob &&
@@ -108,4 +127,40 @@ test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob'
test_cmp expect actual
'
+test_expect_success 'cherry-pick -x -s adds sob even when trailing sob exists for committer' '
+ pristine_detach initial &&
+ sha1=`git rev-parse mesg-with-footer-sob^0` &&
+ git cherry-pick -x -s mesg-with-footer-sob &&
+ cat <<-EOF >expect &&
+ $mesg_with_footer_sob
+ (cherry picked from commit $sha1)
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick -x treats "(cherry picked from..." line as part of footer' '
+ pristine_detach initial &&
+ sha1=`git rev-parse mesg-with-cherry-footer^0` &&
+ git cherry-pick -x mesg-with-cherry-footer &&
+ cat <<-EOF >expect &&
+ $mesg_with_cherry_footer
+ (cherry picked from commit $sha1)
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick -s treats "(cherry picked from..." line as part of footer' '
+ pristine_detach initial &&
+ git cherry-pick -s mesg-with-cherry-footer &&
+ cat <<-EOF >expect &&
+ $mesg_with_cherry_footer
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
test_done
--
1.8.1.3.579.gd9af3b6
^ permalink raw reply related
* [PATCH v4 04/12] t/t3511: add some tests of 'cherry-pick -s' functionality
From: Brandon Casey @ 2013-02-12 10:17 UTC (permalink / raw)
To: git; +Cc: gitster, pclouds, jrnieder, Brandon Casey, Brandon Casey
In-Reply-To: <1360664260-11803-1-git-send-email-drafnel@gmail.com>
Add some tests to ensure that 'cherry-pick -s' operates in the following
manner:
* Inserts a blank line before appending a s-o-b to a commit message that
does not contain a s-o-b footer
* Does not mistake first line "subject: description" as a s-o-b footer
* Does not mistake single word message body as conforming to rfc2822
* Appends a s-o-b when last s-o-b in footer does not match committer
s-o-b, even when committer's s-o-b exists elsewhere in footer.
* Does not append a s-o-b when last s-o-b matches committer s-o-b
* Correctly detects a non-conforming footer containing a mix of s-o-b
like elements and s-o-b elements. (marked "expect failure")
Signed-off-by: Brandon Casey <bcasey@nvidia.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
---
t/t3511-cherry-pick-x.sh | 111 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 111 insertions(+)
create mode 100755 t/t3511-cherry-pick-x.sh
diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh
new file mode 100755
index 0000000..2a040b7
--- /dev/null
+++ b/t/t3511-cherry-pick-x.sh
@@ -0,0 +1,111 @@
+#!/bin/sh
+
+test_description='Test cherry-pick -x and -s'
+
+. ./test-lib.sh
+
+pristine_detach () {
+ git cherry-pick --quit &&
+ git checkout -f "$1^0" &&
+ git read-tree -u --reset HEAD &&
+ git clean -d -f -f -q -x
+}
+
+mesg_one_line='base: commit message'
+
+mesg_no_footer="$mesg_one_line
+
+OneWordBodyThatsNotA-S-o-B"
+
+mesg_with_footer="$mesg_no_footer
+
+Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+Signed-off-by: A.U. Thor <author@example.com>
+Signed-off-by: B.U. Thor <buthor@example.com>"
+
+mesg_broken_footer="$mesg_no_footer
+
+The signed-off-by string should begin with the words Signed-off-by followed
+by a colon and space, and then the signers name and email address. e.g.
+Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+
+mesg_with_footer_sob="$mesg_with_footer
+Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>"
+
+
+test_expect_success setup '
+ git config advice.detachedhead false &&
+ echo unrelated >unrelated &&
+ git add unrelated &&
+ test_commit initial foo a &&
+ test_commit "$mesg_one_line" foo b mesg-one-line &&
+ git reset --hard initial &&
+ test_commit "$mesg_no_footer" foo b mesg-no-footer &&
+ git reset --hard initial &&
+ test_commit "$mesg_broken_footer" foo b mesg-broken-footer &&
+ git reset --hard initial &&
+ test_commit "$mesg_with_footer" foo b mesg-with-footer &&
+ git reset --hard initial &&
+ test_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob &&
+ pristine_detach initial &&
+ test_commit conflicting unrelated
+'
+
+test_expect_success 'cherry-pick -s inserts blank line after one line subject' '
+ pristine_detach initial &&
+ git cherry-pick -s mesg-one-line &&
+ cat <<-EOF >expect &&
+ $mesg_one_line
+
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_expect_failure 'cherry-pick -s inserts blank line after non-conforming footer' '
+ pristine_detach initial &&
+ git cherry-pick -s mesg-broken-footer &&
+ cat <<-EOF >expect &&
+ $mesg_broken_footer
+
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick -s inserts blank line when conforming footer not found' '
+ pristine_detach initial &&
+ git cherry-pick -s mesg-no-footer &&
+ cat <<-EOF >expect &&
+ $mesg_no_footer
+
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick -s adds sob when last sob doesnt match committer' '
+ pristine_detach initial &&
+ git cherry-pick -s mesg-with-footer &&
+ cat <<-EOF >expect &&
+ $mesg_with_footer
+ Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob' '
+ pristine_detach initial &&
+ git cherry-pick -s mesg-with-footer-sob &&
+ cat <<-EOF >expect &&
+ $mesg_with_footer_sob
+ EOF
+ git log -1 --pretty=format:%B >actual &&
+ test_cmp expect actual
+'
+
+test_done
--
1.8.1.3.579.gd9af3b6
^ permalink raw reply related
* [PATCH v4 03/12] t/test-lib-functions.sh: allow to specify the tag name to test_commit
From: Brandon Casey @ 2013-02-12 10:17 UTC (permalink / raw)
To: git; +Cc: gitster, pclouds, jrnieder, Brandon Casey, Brandon Casey
In-Reply-To: <1360664260-11803-1-git-send-email-drafnel@gmail.com>
The <message> part of test_commit() may not be appropriate for a tag name.
So let's allow test_commit to accept a fourth argument to specify the tag
name.
Signed-off-by: Brandon Casey <bcasey@nvidia.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
---
t/test-lib-functions.sh | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh
index fa62d01..61d0804 100644
--- a/t/test-lib-functions.sh
+++ b/t/test-lib-functions.sh
@@ -135,12 +135,12 @@ test_pause () {
fi
}
-# Call test_commit with the arguments "<message> [<file> [<contents>]]"
+# Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]"
#
# This will commit a file with the given contents and the given commit
-# message. It will also add a tag with <message> as name.
+# message, and tag the resulting commit with the given tag name.
#
-# Both <file> and <contents> default to <message>.
+# <file>, <contents>, and <tag> all default to <message>.
test_commit () {
notick= &&
@@ -168,7 +168,7 @@ test_commit () {
test_tick
fi &&
git commit $signoff -m "$1" &&
- git tag "$1"
+ git tag "${4:-$1}"
}
# Call test_merge with the arguments "<message> <commit>", where <commit>
--
1.8.1.3.579.gd9af3b6
^ permalink raw reply related
* [PATCH v4 02/12] commit, cherry-pick -s: remove broken support for multiline rfc2822 fields
From: Brandon Casey @ 2013-02-12 10:17 UTC (permalink / raw)
To: git; +Cc: gitster, pclouds, jrnieder, Brandon Casey, Brandon Casey
In-Reply-To: <1360664260-11803-1-git-send-email-drafnel@gmail.com>
Starting with c1e01b0c (commit: More generous accepting of RFC-2822 footer
lines, 2009-10-28), "git commit -s" carefully parses the last paragraph of
each commit message to check if it consists only of RFC2822-style headers,
in which case the signoff will be added as a new line in the same list:
Reported-by: Reporter <reporter@example.com>
Signed-off-by: Author <author@example.com>
Acked-by: Lieutenant <lt@example.com>
It even included support for accepting indented continuation lines for
multiline fields. Unfortunately the multiline field support is broken
because it checks whether buf[k] (the first character of the *next* line)
instead of buf[i] is a whitespace character. The result is that any footer
with a continuation line is not accepted, since the last continuation line
neither starts with an RFC2822 field name nor is followed by a continuation
line.
That this has remained broken for so long is good evidence that nobody
actually needed multiline fields. Rip out the broken continuation support.
There should be no functional change.
[Thanks to Jonathan Nieder for the excellent commit message]
Signed-off-by: Brandon Casey <bcasey@nvidia.com>
Reviewed-by: Jonathan Nieder <jrnieder@gmail.com>
---
sequencer.c | 6 ------
1 file changed, 6 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index dbeff01..aa2cb8e 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1026,7 +1026,6 @@ static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
char ch, prev;
int i, j, k;
int len = sb->len - ignore_footer;
- int first = 1;
const char *buf = sb->buf;
prev = '\0';
@@ -1046,11 +1045,6 @@ static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
; /* do nothing */
k++;
- if ((buf[k] == ' ' || buf[k] == '\t') && !first)
- continue;
-
- first = 0;
-
for (j = 0; i + j < len; j++) {
ch = buf[i + j];
if (ch == ':')
--
1.8.1.3.579.gd9af3b6
^ permalink raw reply related
* [PATCH v4 01/12] sequencer.c: rework search for start of footer to improve clarity
From: Brandon Casey @ 2013-02-12 10:17 UTC (permalink / raw)
To: git; +Cc: gitster, pclouds, jrnieder, Brandon Casey
In-Reply-To: <1360664260-11803-1-git-send-email-drafnel@gmail.com>
From: Jonathan Nieder <jrnieder@gmail.com>
This code sequence is somewhat difficult to read. Let's rewrite it and add
some comments to improve clarity.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
sequencer.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/sequencer.c b/sequencer.c
index aef5e8a..dbeff01 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -1023,19 +1023,21 @@ int sequencer_pick_revisions(struct replay_opts *opts)
static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer)
{
- int ch;
- int hit = 0;
+ char ch, prev;
int i, j, k;
int len = sb->len - ignore_footer;
int first = 1;
const char *buf = sb->buf;
+ prev = '\0';
for (i = len - 1; i > 0; i--) {
- if (hit && buf[i] == '\n')
+ ch = buf[i];
+ if (prev == '\n' && ch == '\n') /* paragraph break */
break;
- hit = (buf[i] == '\n');
+ prev = ch;
}
+ /* advance to start of last paragraph */
while (i < len - 1 && buf[i] == '\n')
i++;
--
1.8.1.3.579.gd9af3b6
^ permalink raw reply related
* [PATCH v4 00/12] unify appending of sob
From: Brandon Casey @ 2013-02-12 10:17 UTC (permalink / raw)
To: git; +Cc: gitster, pclouds, jrnieder, Brandon Casey
Round 4.
Interdiff against round 3 follows the diff stat.
-Brandon
Brandon Casey (9):
commit, cherry-pick -s: remove broken support for multiline rfc2822
fields
t/test-lib-functions.sh: allow to specify the tag name to test_commit
t/t3511: add some tests of 'cherry-pick -s' functionality
sequencer.c: recognize "(cherry picked from ..." as part of s-o-b
footer
sequencer.c: require a conforming footer to be preceded by a blank
line
sequencer.c: always separate "(cherry picked from" from commit body
sequencer.c: teach append_signoff how to detect duplicate s-o-b
sequencer.c: teach append_signoff to avoid adding a duplicate newline
Unify appending signoff in format-patch, commit and sequencer
Jonathan Nieder (1):
sequencer.c: rework search for start of footer to improve clarity
Nguyễn Thái Ngọc Duy (2):
t4014: more tests about appending s-o-b lines
format-patch: update append_signoff prototype
builtin/commit.c | 2 +-
builtin/log.c | 13 +--
log-tree.c | 92 ++---------------
revision.h | 2 +-
sequencer.c | 168 +++++++++++++++++++++---------
sequencer.h | 4 +-
t/t3511-cherry-pick-x.sh | 219 +++++++++++++++++++++++++++++++++++++++
t/t4014-format-patch.sh | 262 +++++++++++++++++++++++++++++++++++++++++++++++
t/test-lib-functions.sh | 8 +-
9 files changed, 614 insertions(+), 156 deletions(-)
create mode 100755 t/t3511-cherry-pick-x.sh
--
1.8.1.3.579.gd9af3b6
diff --git a/sequencer.c b/sequencer.c
index 404b786..3c63e3a 100644
--- a/sequencer.c
+++ b/sequencer.c
@@ -27,13 +27,12 @@ static int is_rfc2822_line(const char *buf, int len)
for (i = 0; i < len; i++) {
int ch = buf[i];
if (ch == ':')
+ return 1;
+ if (!isalnum(ch) && ch != '-')
break;
- if (isalnum(ch) || (ch == '-'))
- continue;
- return 0;
}
- return 1;
+ return 0;
}
static int is_cherry_picked_from_line(const char *buf, int len)
@@ -41,9 +40,8 @@ static int is_cherry_picked_from_line(const char *buf, int len)
/*
* We only care that it looks roughly like (cherry picked from ...)
*/
- return !prefixcmp(buf, cherry_picked_prefix) &&
- (buf[len - 1] == ')' ||
- (buf[len - 1] == '\n' && buf[len - 2] == ')'));
+ return len > strlen(cherry_picked_prefix) + 1 &&
+ !prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')';
}
/*
@@ -55,25 +53,29 @@ static int is_cherry_picked_from_line(const char *buf, int len)
static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
int ignore_footer)
{
- int last_char_was_nl, this_char_is_nl;
+ char prev;
int i, k;
int len = sb->len - ignore_footer;
const char *buf = sb->buf;
int found_sob = 0;
- /* find start of last paragraph */
- last_char_was_nl = 0;
+ /* footer must end with newline */
+ if (!len || buf[len - 1] != '\n')
+ return 0;
+
+ prev = '\0';
for (i = len - 1; i > 0; i--) {
- this_char_is_nl = (buf[i] == '\n');
- if (last_char_was_nl && this_char_is_nl)
+ char ch = buf[i];
+ if (prev == '\n' && ch == '\n') /* paragraph break */
break;
- last_char_was_nl = this_char_is_nl;
+ prev = ch;
}
/* require at least one blank line */
- if (!last_char_was_nl || buf[i] != '\n')
+ if (prev != '\n' || buf[i] != '\n')
return 0;
+ /* advance to start of last paragraph */
while (i < len - 1 && buf[i] == '\n')
i++;
@@ -84,13 +86,13 @@ static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
; /* do nothing */
k++;
- found_rfc2822 = is_rfc2822_line(buf + i, k - i);
+ found_rfc2822 = is_rfc2822_line(buf + i, k - i - 1);
if (found_rfc2822 && sob &&
- !strncmp(buf + i, sob->buf, sob->len))
+ !strncmp(buf + i, sob->buf, sob->len))
found_sob = k;
if (!(found_rfc2822 ||
- is_cherry_picked_from_line(buf + i, k - i)))
+ is_cherry_picked_from_line(buf + i, k - i - 1)))
return 0;
}
if (found_sob == i)
@@ -1108,26 +1110,36 @@ void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag)
{
unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP;
struct strbuf sob = STRBUF_INIT;
- int has_footer = 0;
- int i;
+ const char *append_newlines = NULL;
+ int has_footer;
strbuf_addstr(&sob, sign_off_header);
strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"),
getenv("GIT_COMMITTER_EMAIL")));
strbuf_addch(&sob, '\n');
- for (i = msgbuf->len - 1 - ignore_footer; i > 0 && msgbuf->buf[i - 1] != '\n'; i--)
- ; /* do nothing */
- if (msgbuf->buf[i] != '\n') {
- if (i)
- has_footer = has_conforming_footer(msgbuf, &sob,
- ignore_footer);
-
- if (!has_footer)
- strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
- "\n", 1);
+ /*
+ * If the whole message buffer is equal to the sob, pretend that we
+ * found a conforming footer with a matching sob
+ */
+ if (msgbuf->len - ignore_footer == sob.len &&
+ !strncmp(msgbuf->buf, sob.buf, sob.len))
+ has_footer = 3;
+ else
+ has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer);
+
+ if (!has_footer) {
+ size_t len = msgbuf->len - ignore_footer;
+ if (len && msgbuf->buf[len - 1] != '\n')
+ append_newlines = "\n\n";
+ else if (len > 1 && msgbuf->buf[len - 2] != '\n')
+ append_newlines = "\n";
}
+ if (append_newlines)
+ strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
+ append_newlines, strlen(append_newlines));
+
if (has_footer != 3 && (!no_dup_sob || has_footer != 2))
strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0,
sob.buf, sob.len);
diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh
index d0ec097..97fde9e 100755
--- a/t/t4014-format-patch.sh
+++ b/t/t4014-format-patch.sh
@@ -1023,11 +1023,10 @@ test_expect_success 'cover letter using branch description (6)' '
append_signoff()
{
- C=`git commit-tree HEAD^^{tree} -p HEAD` &&
- git format-patch --stdout --signoff ${C}^..${C} |
- tee append_signoff.patch |
- sed -n "1,/^---$/p" |
- grep -n -E "^Subject|Sign|^$"
+ C=$(git commit-tree HEAD^^{tree} -p HEAD) &&
+ git format-patch --stdout --signoff $C^..$C >append_signoff.patch &&
+ sed -n -e "1,/^---$/p" append_signoff.patch |
+ egrep -n "^Subject|Sign|^$"
}
test_expect_success 'signoff: commit with no body' '
^ permalink raw reply related
* Re: [PATCH v2] rebase -i: respect core.commentchar
From: John Keeping @ 2013-02-12 9:53 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Ralf Thielow
In-Reply-To: <7vehgmjsno.fsf@alter.siamese.dyndns.org>
On Mon, Feb 11, 2013 at 04:13:31PM -0800, Junio C Hamano wrote:
> John Keeping <john@keeping.me.uk> writes:
>
> > @@ -179,7 +182,9 @@ die_abort () {
> > }
> >
> > has_action () {
> > - sane_grep '^[^#]' "$1" >/dev/null
> > + echo "space stripped actions:" >&2
> > + git stripspace --strip-comments <"$1" >&2
> > + test -n "$(git stripspace --strip-comments <"$1")"
> > }
>
> I'll remove the debugging remnants while queuing.
Thanks. I don't think I was fully awake when I finished this last
night - the following fixup is also needed to avoid relying on the shell
emitting a literal backslash when a backslash isn't followed by a known
escape character.
-- >8 --
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index cbe36bf..84bd525 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -947,7 +947,7 @@ test_expect_success 'rebase -i respects core.commentchar' '
test_when_finished "git config --unset core.commentchar" &&
cat >comment-lines.sh <<EOF &&
#!$SHELL_PATH
-sed -e "2,\$ s/^/\\\\\\/" "\$1" >"\$1".tmp
+sed -e "2,\$ s/^/\\\\\\\\/" "\$1" >"\$1".tmp
mv "\$1".tmp "\$1"
EOF
chmod a+x comment-lines.sh &&
-- >8 --
> > @@ -942,20 +948,18 @@ test -s "$todo" || echo noop >> "$todo"
> > test -n "$autosquash" && rearrange_squash "$todo"
> > test -n "$cmd" && add_exec_commands "$todo"
> >
> > -cat >> "$todo" << EOF
> > -
> > -# Rebase $shortrevisions onto $shortonto
> > -EOF
> > +echo >>"$todo"
> > +printf '%s\n' "$comment_char Rebase $shortrevisions onto $shortonto" >>"$todo"
>
> I think you can still do
>
> cat >>"$todo" <<EOF
>
> $comment_char Rebase $shortrevisions onto...
> EOF
>
> here with any funny comment character. Doing this with two separate
> I/O does not hurt very much, but the resulting code may be easier to
> scan if left as here-text with a single cat.
>
> Please eyeball what is in 'pu' (I have a separate squashable fixup
> on top of your patch) and let me know if I made mistakes.
The fixup commit looks good to me.
John
^ permalink raw reply related
* [PATCH v3 0/4] count-objects improvements
From: Nguyễn Thái Ngọc Duy @ 2013-02-12 9:27 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Ramsay Jones,
Nguyễn Thái Ngọc Duy
Compared to v2 [1], this version
- fixes sparse warning
- restructures 2/3 (now 3/4) to make it easier to read
- report "path too long" instead of "garbage found" in
.git/path/too/long/pack-xxx.pack case
- changes output prefix "error:" to "warning:"
[1] http://thread.gmane.org/gmane.comp.version-control.git/215378/focus=215744
Nguyễn Thái Ngọc Duy (4):
git-count-objects.txt: describe each line in -v output
sha1_file: reorder code in prepare_packed_git_one()
count-objects: report garbage files in pack directory too
count-objects: report how much disk space taken by garbage files
Documentation/git-count-objects.txt | 22 ++++++--
builtin/count-objects.c | 43 +++++++++++---
cache.h | 3 +
sha1_file.c | 108 +++++++++++++++++++++++++++++++-----
4 files changed, 148 insertions(+), 28 deletions(-)
--
1.8.1.2.536.gf441e6d
^ permalink raw reply
* [PATCH v3 4/4] count-objects: report how much disk space taken by garbage files
From: Nguyễn Thái Ngọc Duy @ 2013-02-12 9:27 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Ramsay Jones,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1360661277-17273-1-git-send-email-pclouds@gmail.com>
Also issue warnings on loose garbages instead of errors as a result of
using report_garbage() function in count_objects()
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-count-objects.txt | 2 ++
builtin/count-objects.c | 21 +++++++++++++--------
2 files changed, 15 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index 1611d7c..da6e72e 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -35,6 +35,8 @@ the packs. These objects could be pruned using `git prune-packed`.
+
garbage: the number of files in object database that are not valid
loose objects nor valid packs
++
+size-garbage: disk space consumed by garbage files, in KiB
GIT
---
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 639c9a5..75feee5 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -10,12 +10,15 @@
#include "parse-options.h"
static unsigned long garbage;
+static off_t size_garbage;
static void real_report_garbage(const char *desc,
const char *path, int len,
const char *name)
{
struct strbuf sb = STRBUF_INIT;
+ struct stat st;
+
if (len && name)
strbuf_addf(&sb, "%.*s/%s", len, path, name);
else if (!len && name)
@@ -23,6 +26,10 @@ static void real_report_garbage(const char *desc,
else
strbuf_addf(&sb, "%s", path);
warning("%s: %s", desc, sb.buf);
+
+ if (!stat(sb.buf, &st))
+ size_garbage += st.st_size;
+
garbage++;
strbuf_release(&sb);
}
@@ -30,8 +37,7 @@ static void real_report_garbage(const char *desc,
static void count_objects(DIR *d, char *path, int len, int verbose,
unsigned long *loose,
off_t *loose_size,
- unsigned long *packed_loose,
- unsigned long *garbage)
+ unsigned long *packed_loose)
{
struct dirent *ent;
while ((ent = readdir(d)) != NULL) {
@@ -63,11 +69,9 @@ static void count_objects(DIR *d, char *path, int len, int verbose,
(*loose_size) += xsize_t(on_disk_bytes(st));
}
if (bad) {
- if (verbose) {
- error("garbage found: %.*s/%s",
- len + 2, path, ent->d_name);
- (*garbage)++;
- }
+ if (verbose)
+ report_garbage("garbage found",
+ path, len + 2, ent->d_name);
continue;
}
(*loose)++;
@@ -117,7 +121,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
if (!d)
continue;
count_objects(d, path, len, verbose,
- &loose, &loose_size, &packed_loose, &garbage);
+ &loose, &loose_size, &packed_loose);
closedir(d);
}
if (verbose) {
@@ -142,6 +146,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
printf("size-pack: %lu\n", (unsigned long) (size_pack / 1024));
printf("prune-packable: %lu\n", packed_loose);
printf("garbage: %lu\n", garbage);
+ printf("size-garbage: %lu\n", (unsigned long) (size_garbage / 1024));
}
else
printf("%lu objects, %lu kilobytes\n",
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 3/4] count-objects: report garbage files in pack directory too
From: Nguyễn Thái Ngọc Duy @ 2013-02-12 9:27 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Ramsay Jones,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1360661277-17273-1-git-send-email-pclouds@gmail.com>
prepare_packed_git_one() is modified to allow count-objects to hook a
report function to so we don't need to duplicate the pack searching
logic in count-objects.c. When report_pack_garbage is NULL, the
overhead is insignificant.
The garbage is reported with warning() instead of error() in packed
garbage case because it's not an error to have garbage. Loose garbage
is still reported as errors and will be converted to warnings later.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-count-objects.txt | 4 +-
builtin/count-objects.c | 22 +++++++++-
cache.h | 3 ++
sha1_file.c | 83 ++++++++++++++++++++++++++++++++++++-
4 files changed, 107 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index e816823..1611d7c 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -33,8 +33,8 @@ size-pack: disk space consumed by the packs, in KiB
prune-packable: the number of loose objects that are also present in
the packs. These objects could be pruned using `git prune-packed`.
+
-garbage: the number of files in loose object database that are not
-valid loose objects
+garbage: the number of files in object database that are not valid
+loose objects nor valid packs
GIT
---
diff --git a/builtin/count-objects.c b/builtin/count-objects.c
index 9afaa88..639c9a5 100644
--- a/builtin/count-objects.c
+++ b/builtin/count-objects.c
@@ -9,6 +9,24 @@
#include "builtin.h"
#include "parse-options.h"
+static unsigned long garbage;
+
+static void real_report_garbage(const char *desc,
+ const char *path, int len,
+ const char *name)
+{
+ struct strbuf sb = STRBUF_INIT;
+ if (len && name)
+ strbuf_addf(&sb, "%.*s/%s", len, path, name);
+ else if (!len && name)
+ strbuf_addf(&sb, "%s%s", path, name);
+ else
+ strbuf_addf(&sb, "%s", path);
+ warning("%s: %s", desc, sb.buf);
+ garbage++;
+ strbuf_release(&sb);
+}
+
static void count_objects(DIR *d, char *path, int len, int verbose,
unsigned long *loose,
off_t *loose_size,
@@ -76,7 +94,7 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
const char *objdir = get_object_directory();
int len = strlen(objdir);
char *path = xmalloc(len + 50);
- unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0;
+ unsigned long loose = 0, packed = 0, packed_loose = 0;
off_t loose_size = 0;
struct option opts[] = {
OPT__VERBOSE(&verbose, N_("be verbose")),
@@ -87,6 +105,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix)
/* we do not take arguments other than flags for now */
if (argc)
usage_with_options(count_objects_usage, opts);
+ if (verbose)
+ report_garbage = real_report_garbage;
memcpy(path, objdir, len);
if (len && objdir[len-1] != '/')
path[len++] = '/';
diff --git a/cache.h b/cache.h
index 7339f21..e486499 100644
--- a/cache.h
+++ b/cache.h
@@ -1051,6 +1051,9 @@ extern const char *parse_feature_value(const char *feature_list, const char *fea
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
+/* A hook for count-objects to report invalid files in pack directory */
+extern void (*report_garbage)(const char *desc, const char *path, int len, const char *name);
+
extern void prepare_packed_git(void);
extern void reprepare_packed_git(void);
extern void install_packed_git(struct packed_git *pack);
diff --git a/sha1_file.c b/sha1_file.c
index 8d7da1d..290e348 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -21,6 +21,7 @@
#include "sha1-lookup.h"
#include "bulk-checkin.h"
#include "streaming.h"
+#include "dir.h"
#ifndef O_NOATIME
#if defined(__linux__) && (defined(__i386__) || defined(__PPC__))
@@ -1000,6 +1001,52 @@ void install_packed_git(struct packed_git *pack)
packed_git = pack;
}
+void (*report_garbage)(const char *desc, const char *path,
+ int len, const char *name);
+
+static void report_pack_garbage(struct string_list *list)
+{
+ struct strbuf sb = STRBUF_INIT;
+ struct packed_git *p;
+ int i;
+
+ if (!report_garbage)
+ return;
+
+ sort_string_list(list);
+
+ for (p = packed_git; p; p = p->next) {
+ struct string_list_item *item;
+ if (!p->pack_local)
+ continue;
+ strbuf_reset(&sb);
+ strbuf_add(&sb, p->pack_name,
+ strlen(p->pack_name) - 5); /* ".pack" */
+ item = string_list_lookup(list, sb.buf);
+ if (!item)
+ continue;
+ /*
+ * string_list_lookup does not guarantee to return the
+ * first matched string if it's duplicated.
+ */
+ while (item - list->items &&
+ !strcmp(item[-1].string, item->string))
+ item--;
+ while (item - list->items < list->nr &&
+ !strcmp(item->string, sb.buf)) {
+ item->util = NULL; /* non-garbage mark */
+ item++;
+ }
+ }
+ for (i = 0; i < list->nr; i++) {
+ struct string_list_item *item = list->items + i;
+ if (!item->util)
+ continue;
+ report_garbage("garbage found", item->string, 0, item->util);
+ }
+ strbuf_release(&sb);
+}
+
static void prepare_packed_git_one(char *objdir, int local)
{
/* Ensure that this buffer is large enough so that we can
@@ -1009,6 +1056,7 @@ static void prepare_packed_git_one(char *objdir, int local)
int len;
DIR *dir;
struct dirent *de;
+ struct string_list garbage = STRING_LIST_INIT_DUP;
sprintf(path, "%s/pack", objdir);
len = strlen(path);
@@ -1024,7 +1072,14 @@ static void prepare_packed_git_one(char *objdir, int local)
int namelen = strlen(de->d_name);
struct packed_git *p;
- if (len + namelen + 1 > sizeof(path))
+ if (len + namelen + 1 > sizeof(path)) {
+ if (report_garbage)
+ report_garbage("path too long",
+ path, len - 1, de->d_name);
+ continue;
+ }
+
+ if (is_dot_or_dotdot(de->d_name))
continue;
strcpy(path + len, de->d_name);
@@ -1045,9 +1100,33 @@ static void prepare_packed_git_one(char *objdir, int local)
if (!p)
continue;
install_packed_git(p);
- }
+ } else if (!report_garbage) {
+ /*
+ * the rest of this if-chain requires
+ * report_garbage != NULL. Stop the chain if
+ * report_garbage is NULL.
+ */
+ ;
+ } else if (has_extension(de->d_name, ".pack")) {
+ struct string_list_item *item;
+ int n = strlen(path) - 5;
+ item = string_list_append_nodup(&garbage,
+ xstrndup(path, n));
+ item->util = ".pack";
+ continue;
+ } else if (has_extension(de->d_name, ".idx")) {
+ struct string_list_item *item;
+ int n = strlen(path) - 4;
+ item = string_list_append_nodup(&garbage,
+ xstrndup(path, n));
+ item->util = ".idx";
+ continue;
+ } else
+ report_garbage("garbage found", path, 0, NULL);
}
closedir(dir);
+ report_pack_garbage(&garbage);
+ string_list_clear(&garbage, 0);
}
static int sort_pack(const void *a_, const void *b_)
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 2/4] sha1_file: reorder code in prepare_packed_git_one()
From: Nguyễn Thái Ngọc Duy @ 2013-02-12 9:27 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Ramsay Jones,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1360661277-17273-1-git-send-email-pclouds@gmail.com>
The current loop does
while (...) {
if (!not .idx file)
continue;
process .idx file;
}
and is reordered to
while (...) {
if (!.idx file) {
process .idx file;
}
}
This makes it easier to add new extension file processing.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
sha1_file.c | 33 +++++++++++++++++----------------
1 file changed, 17 insertions(+), 16 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index 40b2329..8d7da1d 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1024,27 +1024,28 @@ static void prepare_packed_git_one(char *objdir, int local)
int namelen = strlen(de->d_name);
struct packed_git *p;
- if (!has_extension(de->d_name, ".idx"))
- continue;
-
if (len + namelen + 1 > sizeof(path))
continue;
- /* Don't reopen a pack we already have. */
strcpy(path + len, de->d_name);
- for (p = packed_git; p; p = p->next) {
- if (!memcmp(path, p->pack_name, len + namelen - 4))
- break;
+
+ if (has_extension(de->d_name, ".idx")) {
+ /* Don't reopen a pack we already have. */
+ for (p = packed_git; p; p = p->next) {
+ if (!memcmp(path, p->pack_name, len + namelen - 4))
+ break;
+ }
+ if (p)
+ continue;
+ /*
+ * See if it really is a valid .idx file with
+ * corresponding .pack file that we can map.
+ */
+ p = add_packed_git(path, len + namelen, local);
+ if (!p)
+ continue;
+ install_packed_git(p);
}
- if (p)
- continue;
- /* See if it really is a valid .idx file with corresponding
- * .pack file that we can map.
- */
- p = add_packed_git(path, len + namelen, local);
- if (!p)
- continue;
- install_packed_git(p);
}
closedir(dir);
}
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [PATCH v3 1/4] git-count-objects.txt: describe each line in -v output
From: Nguyễn Thái Ngọc Duy @ 2013-02-12 9:27 UTC (permalink / raw)
To: git; +Cc: Junio C Hamano, Ramsay Jones,
Nguyễn Thái Ngọc Duy
In-Reply-To: <1360661277-17273-1-git-send-email-pclouds@gmail.com>
The current description requires a bit of guessing (what clause
corresponds to what printed line?) and lacks information, such as
the unit of size and size-pack.
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
Documentation/git-count-objects.txt | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt
index 23c80ce..e816823 100644
--- a/Documentation/git-count-objects.txt
+++ b/Documentation/git-count-objects.txt
@@ -20,11 +20,21 @@ OPTIONS
-------
-v::
--verbose::
- In addition to the number of loose objects and disk
- space consumed, it reports the number of in-pack
- objects, number of packs, disk space consumed by those packs,
- and number of objects that can be removed by running
- `git prune-packed`.
+ Report in more detail:
++
+count: the number of loose objects
++
+size: disk space consumed by loose objects, in KiB
++
+in-pack: the number of in-pack objects
++
+size-pack: disk space consumed by the packs, in KiB
++
+prune-packable: the number of loose objects that are also present in
+the packs. These objects could be pruned using `git prune-packed`.
++
+garbage: the number of files in loose object database that are not
+valid loose objects
GIT
---
--
1.8.1.2.536.gf441e6d
^ permalink raw reply related
* [RFC/PATCH] Replace filepattern with pathspec for consistency
From: Matthieu Moy @ 2013-02-12 9:24 UTC (permalink / raw)
To: git, gitster; +Cc: Matthieu Moy
pathspec is the most widely used term, and is the one defined in
gitglossary.txt. <filepattern> was used only in the synopsys for git-add
and git-commit, and in git-add.txt. Get rid of it.
This patch is obtained with by running:
perl -pi -e 's/filepattern/pathspec/' `git grep -l filepattern`
Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>
---
I'm a bit unsure about the changes to the .po files, but I guess doing
the substitution there too does the right thing.
Documentation/git-add.txt | 12 ++++++------
builtin/add.c | 2 +-
builtin/commit.c | 4 ++--
po/de.po | 6 +++---
po/git.pot | 6 +++---
po/sv.po | 6 +++---
po/vi.po | 6 +++---
po/zh_CN.po | 6 +++---
8 files changed, 24 insertions(+), 24 deletions(-)
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 5333559..388a225 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -11,7 +11,7 @@ SYNOPSIS
'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p]
[--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N]
[--refresh] [--ignore-errors] [--ignore-missing] [--]
- [<filepattern>...]
+ [<pathspec>...]
DESCRIPTION
-----------
@@ -49,7 +49,7 @@ commit.
OPTIONS
-------
-<filepattern>...::
+<pathspec>...::
Files to add content from. Fileglobs (e.g. `*.c`) can
be given to add all matching files. Also a
leading directory name (e.g. `dir` to add `dir/file1`
@@ -100,21 +100,21 @@ apply to the index. See EDITING PATCHES below.
-u::
--update::
- Only match <filepattern> against already tracked files in
+ Only match <pathspec> against already tracked files in
the index rather than the working tree. That means that it
will never stage new files, but that it will stage modified
new contents of tracked files and that it will remove files
from the index if the corresponding files in the working tree
have been removed.
+
-If no <filepattern> is given, the current version of Git defaults to
+If no <pathspec> is given, the current version of Git defaults to
"."; in other words, update all tracked files in the current directory
and its subdirectories. This default will change in a future version
-of Git, hence the form without <filepattern> should not be used.
+of Git, hence the form without <pathspec> should not be used.
-A::
--all::
- Like `-u`, but match <filepattern> against files in the
+ Like `-u`, but match <pathspec> against files in the
working tree in addition to the index. That means that it
will find new files as well as staging modified content and
removing files that are no longer in the working tree.
diff --git a/builtin/add.c b/builtin/add.c
index 7738025..0dd014e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -17,7 +17,7 @@
#include "bulk-checkin.h"
static const char * const builtin_add_usage[] = {
- N_("git add [options] [--] <filepattern>..."),
+ N_("git add [options] [--] <pathspec>..."),
NULL
};
static int patch_interactive, add_interactive, edit_interactive;
diff --git a/builtin/commit.c b/builtin/commit.c
index 1a0e5f1..3348aa1 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -31,12 +31,12 @@
#include "sequencer.h"
static const char * const builtin_commit_usage[] = {
- N_("git commit [options] [--] <filepattern>..."),
+ N_("git commit [options] [--] <pathspec>..."),
NULL
};
static const char * const builtin_status_usage[] = {
- N_("git status [options] [--] <filepattern>..."),
+ N_("git status [options] [--] <pathspec>..."),
NULL
};
diff --git a/po/de.po b/po/de.po
index c8ad2f0..0183c28 100644
--- a/po/de.po
+++ b/po/de.po
@@ -1410,7 +1410,7 @@ msgid "failed to unlink '%s'"
msgstr "Konnte '%s' nicht entfernen"
#: builtin/add.c:19
-msgid "git add [options] [--] <filepattern>..."
+msgid "git add [options] [--] <pathspec>..."
msgstr "git add [Optionen] [--] [<Dateimuster>...]"
#: builtin/add.c:62
@@ -3296,11 +3296,11 @@ msgid "--command must be the first argument"
msgstr "Option --command muss zuerst angegeben werden"
#: builtin/commit.c:34
-msgid "git commit [options] [--] <filepattern>..."
+msgid "git commit [options] [--] <pathspec>..."
msgstr "git commit [Optionen] [--] <Dateimuster>..."
#: builtin/commit.c:39
-msgid "git status [options] [--] <filepattern>..."
+msgid "git status [options] [--] <pathspec>..."
msgstr "git status [Optionen] [--] <Dateimuster>..."
#: builtin/commit.c:44
diff --git a/po/git.pot b/po/git.pot
index 430d033..4941fd7 100644
--- a/po/git.pot
+++ b/po/git.pot
@@ -1328,7 +1328,7 @@ msgid "failed to unlink '%s'"
msgstr ""
#: builtin/add.c:19
-msgid "git add [options] [--] <filepattern>..."
+msgid "git add [options] [--] <pathspec>..."
msgstr ""
#: builtin/add.c:62
@@ -3128,11 +3128,11 @@ msgid "--command must be the first argument"
msgstr ""
#: builtin/commit.c:34
-msgid "git commit [options] [--] <filepattern>..."
+msgid "git commit [options] [--] <pathspec>..."
msgstr ""
#: builtin/commit.c:39
-msgid "git status [options] [--] <filepattern>..."
+msgid "git status [options] [--] <pathspec>..."
msgstr ""
#: builtin/commit.c:44
diff --git a/po/sv.po b/po/sv.po
index ee6b0fc..c0ef050 100644
--- a/po/sv.po
+++ b/po/sv.po
@@ -1379,7 +1379,7 @@ msgid "failed to unlink '%s'"
msgstr "misslyckades ta bort länken \"%s\""
#: builtin/add.c:19
-msgid "git add [options] [--] <filepattern>..."
+msgid "git add [options] [--] <pathspec>..."
msgstr "git add [flaggor] [--] <filmönster>..."
#: builtin/add.c:62
@@ -3223,11 +3223,11 @@ msgid "--command must be the first argument"
msgstr "--command måste vara första argument"
#: builtin/commit.c:34
-msgid "git commit [options] [--] <filepattern>..."
+msgid "git commit [options] [--] <pathspec>..."
msgstr "git commit [flaggor] [--] <filmöster>..."
#: builtin/commit.c:39
-msgid "git status [options] [--] <filepattern>..."
+msgid "git status [options] [--] <pathspec>..."
msgstr "git status [flaggor] [--] <filmönster>..."
#: builtin/commit.c:44
diff --git a/po/vi.po b/po/vi.po
index 2ccdf86..78c6326 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -1412,7 +1412,7 @@ msgid "failed to unlink '%s'"
msgstr "bỏ liên kết (unlink) %s không thành công"
#: builtin/add.c:19
-msgid "git add [options] [--] <filepattern>..."
+msgid "git add [options] [--] <pathspec>..."
msgstr "git add [các-tùy-chọn] [--] <mẫu-tập-tin>..."
#: builtin/add.c:62
@@ -3281,11 +3281,11 @@ msgid "--command must be the first argument"
msgstr "--command phải là đối số đầu tiên"
#: builtin/commit.c:34
-msgid "git commit [options] [--] <filepattern>..."
+msgid "git commit [options] [--] <pathspec>..."
msgstr "git commit [các-tùy-chọn] [--] <mẫu-tập-tin>..."
#: builtin/commit.c:39
-msgid "git status [options] [--] <filepattern>..."
+msgid "git status [options] [--] <pathspec>..."
msgstr "git status [các-tùy-chọn] [--] <mẫu-tập-tin>..."
#: builtin/commit.c:44
diff --git a/po/zh_CN.po b/po/zh_CN.po
index 46d158f..79cce0e 100644
--- a/po/zh_CN.po
+++ b/po/zh_CN.po
@@ -1405,7 +1405,7 @@ msgstr "无法删除 '%s'"
#: builtin/add.c:19
#, fuzzy
-msgid "git add [options] [--] <filepattern>..."
+msgid "git add [options] [--] <pathspec>..."
msgstr "git apply [选项] [<补丁>...]"
#: builtin/add.c:62
@@ -3278,12 +3278,12 @@ msgstr "--command 必须是第一个参数"
#: builtin/commit.c:33
#, fuzzy
-msgid "git commit [options] [--] <filepattern>..."
+msgid "git commit [options] [--] <pathspec>..."
msgstr "git apply [选项] [<补丁>...]"
#: builtin/commit.c:38
#, fuzzy
-msgid "git status [options] [--] <filepattern>..."
+msgid "git status [options] [--] <pathspec>..."
msgstr "git apply [选项] [<补丁>...]"
#: builtin/commit.c:43
--
1.8.1.2.548.g956380a.dirty
^ permalink raw reply related
* Re: A good Git technique for referring back to original files
From: Matthieu Moy @ 2013-02-12 8:56 UTC (permalink / raw)
To: MikeW; +Cc: git
In-Reply-To: <loom.20130212T085620-989@post.gmane.org>
MikeW <mw_phil@yahoo.co.uk> writes:
> Since git is so good at tracking file content, I wondered whether there was any
> technique using git that would simplify the back-referencing task.
I'm not sure I understand the question, but if you want to add meta-data
to Git commits (e.g. "this Git commit is revision 42 in CVS repository
foo"), then have a look at git-notes. It won't give you directly
"reference to other VCS", but at least can be used as a storage
mechanism to store these references.
--
Matthieu Moy
http://www-verimag.imag.fr/~moy/
^ permalink raw reply
* A good Git technique for referring back to original files
From: MikeW @ 2013-02-12 8:11 UTC (permalink / raw)
To: git
Hi,
I have a client with an SDK product. Normally the SDK is used in its unpackaged
form by the end-user, and that is the directory structure and set of files in
which development work on the SDK functionality is performed.
However the SDK directory and content is generated from a packager which first
runs on numerous other version controlled projects (currently CVS projects -
this is unlikely to change).
This means that once changes to the unpackaged SDK have been tested, they have
to be cross-referred back to the original projects and the changes ported back.
I have found it most convenient to control my in-SDK changes with git.
However it's still a royal pain to cross-refer and diff the changes back to the
originals, especially since duplicate file names exist across the original
projects which get filtered down to one relevant instance by the packager.
Since git is so good at tracking file content, I wondered whether there was any
technique using git that would simplify the back-referencing task.
Failing a method using git 'normally', perhaps building a script on top of the
git file system might be a possibility - if that is feasible ...
Thanks,
MikeW
^ permalink raw reply
* [PATCH] completion: recognize "--local" as a config file source
From: Jeff King @ 2013-02-12 5:49 UTC (permalink / raw)
To: Dasa Paddock; +Cc: git@vger.kernel.org, Junio C Hamano
In-Reply-To: <20130211210455.GB32740@sigill.intra.peff.net>
When we are trying to show the list of config variables in a
file, we recognize "--system", "--global", and "--file" as
specifying a particular file. This list misses "--local",
which performs a similar function.
Without this patch, completing:
git config --get --local
shows items from all config files, not just the local one.
Noticed-by: Dasa Paddock <dpaddock@esri.com>
Signed-off-by: Jeff King <peff@peff.net>
---
contrib/completion/git-completion.bash | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index c8452fb..0b7b659 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1779,7 +1779,7 @@ __git_config_get_set_variables ()
while [ $c -gt 1 ]; do
word="${words[c]}"
case "$word" in
- --global|--system|--file=*)
+ --global|--system|--local|--file=*)
config_file="$word"
break
;;
--
1.8.1.2.11.g1a2f572
^ permalink raw reply related
* [BUG/TEST 1/2] t3501: Expose bug with cherry-pick into dirty trees w/ renames
From: Stephen Boyd @ 2013-02-12 4:27 UTC (permalink / raw)
To: git
In-Reply-To: <1360643262-1472-1-git-send-email-sboyd@codeaurora.org>
I encountered this bug while doing some cherry-picking into a
dirty tree. In this case, the working tree was dirty with some
changes to a file that had been renamed. The change I wanted to
cherry-pick was made along another branch before the rename and
it matched a subset of my working tree modulo the file rename.
When I cherry-picked the change from the other branch without the
rename to my current branch with the rename, the change applied
cleanly and the dirty bits were committed but the other dirty
bits in the file were lost. Make this into a test to expose this
bug.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
t/t3501-revert-cherry-pick.sh | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index 6f489e2..eef4d8c 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -109,4 +109,32 @@ test_expect_success 'chery-pick on unborn branch' '
! test_cmp_rev initial HEAD
'
+test_expect_success 'cherry-pick on dirty rename should stay dirty' '
+ git checkout initial &&
+
+ for l in b c d e f g h i j k l m n o
+ do
+ echo $l$l$l$l$l$l$l$l$l
+ done >oops &&
+
+ test_tick &&
+ git add oops &&
+ git commit -m drop &&
+ git tag drop &&
+
+ git checkout initial &&
+ test_tick &&
+ git mv oops spoo &&
+ git commit -m rename3 &&
+ git tag rename3 &&
+
+ for l in b c d e f g h i j k m n o
+ do
+ echo $l$l$l$l$l$l$l$l$l
+ done >spoo &&
+
+ git cherry-pick drop &&
+ ! git diff --quiet
+'
+
test_done
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* [BUG/TEST 0/2] bugs with cherry-pick renames
From: Stephen Boyd @ 2013-02-12 4:27 UTC (permalink / raw)
To: git
I ran into these bugs the other day and didn't have time to
investigate further. So I wrote test cases for them instead.
Stephen Boyd (2):
t3501: Expose bug with cherry-pick into dirty trees w/ renames
t3501: Expose addinfo_cache error message in cherry-pick
t/t3501-revert-cherry-pick.sh | 60 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply
* [BUG/TEST 2/2] t3501: Expose addinfo_cache error message in cherry-pick
From: Stephen Boyd @ 2013-02-12 4:27 UTC (permalink / raw)
To: git
In-Reply-To: <1360643262-1472-1-git-send-email-sboyd@codeaurora.org>
I encountered a mysterious error message while doing some
cherry-picking into a dirty tree. In this case, the working tree
was dirty with changes to two files that had been renamed, we'll
call them 'file and 'otherfile'. The change I wanted to
cherry-pick was made along a branch before the rename to 'file'.
When I cherry-picked the change from the other branch without the
rename to my current branch with the rename, the change applied
cleanly and the dirty bits were committed but a mysterious error
message was printed indicating something went wrong with the file
that was still dirty after the cherry-pick.
error: addinfo_cache failed for path 'otherfile'
I suspect this error message shouldn't be printed, so recreate
the problem in t3501 so that it can be fixed.
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
t/t3501-revert-cherry-pick.sh | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/t/t3501-revert-cherry-pick.sh b/t/t3501-revert-cherry-pick.sh
index eef4d8c..522a9fd 100755
--- a/t/t3501-revert-cherry-pick.sh
+++ b/t/t3501-revert-cherry-pick.sh
@@ -137,4 +137,36 @@ test_expect_success 'cherry-pick on dirty rename should stay dirty' '
! git diff --quiet
'
+test_expect_success 'cherry-pick on dirty rename should not complain' '
+ git checkout initial &&
+
+ test_commit file1
+
+ for l in b c d e f g h i j k l m n o
+ do
+ echo $l$l$l$l$l$l$l$l$l
+ done >oops &&
+
+ test_tick &&
+ git add oops &&
+ git commit -m drop2 &&
+ git tag drop2 &&
+
+ git checkout file1 &&
+ test_tick &&
+ git mv oops spoo &&
+ git mv file1.t file2.t &&
+ git commit -m rename4 &&
+ git tag rename4 &&
+
+ echo file2 > file2.t &&
+ for l in b c d e f g h i j k m n o
+ do
+ echo $l$l$l$l$l$l$l$l$l
+ done >spoo &&
+
+ git cherry-pick drop2 2> errors &&
+ ! test -s errors
+'
+
test_done
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation
^ permalink raw reply related
* Re: git-diff(1) appears to contradict itself
From: Reuben Thomas @ 2013-02-12 3:09 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git
In-Reply-To: <7v1ucmjl6x.fsf@alter.siamese.dyndns.org>
On 12 February 2013 02:54, Junio C Hamano <gitster@pobox.com> wrote:
> Reuben Thomas <rrt@sc3d.org> writes:
>
>> Under the --color=<when> option, it says:
>>
>> Show colored diff. The value must be always (the default for <when>),
>> never, or auto. The default value is never.
>
> I think it wants to say this:
>
> You can say "diff --color" without saying "when". That is the
> same as saying "diff --color=always".
>
> If you do not say "--color" at all, that is exactly the same as
> saying "diff --color=never".
>
> Patches welcome.
Thanks for the explanation. Something like this, then:
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index 7a87473..9a02992 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -174,9 +174,9 @@ any of those replacements occurred.
`diff.submodule` configuration variable.
--color[=<when>]::
- Show colored diff.
- The value must be `always` (the default for `<when>`), `never`, or `auto`.
- The default value is `never`.
+ Show colored diff (off by default).
+ The value must be `always`, `never`, or `auto`.
+ `--color` is the same as `--color=always`.
ifdef::git-diff[]
It can be changed by the `color.ui` and `color.diff`
configuration settings.
? I guess other commands that work the same, such as git-grep, could
do with a similar patch (indeed, I based my wording on that in the
git-grep page, but that has different problems.) Or you could use the
same fragment twice if that is possible in your system?
--
http://rrt.sc3d.org
^ permalink raw reply related
* Re: git-diff(1) appears to contradict itself
From: Junio C Hamano @ 2013-02-12 2:54 UTC (permalink / raw)
To: Reuben Thomas; +Cc: git
In-Reply-To: <CAOnWdojOT61XOY6JxL-3sR4W8N0katShsSLsOsuJ0-PuM9Vemg@mail.gmail.com>
Reuben Thomas <rrt@sc3d.org> writes:
> Under the --color=<when> option, it says:
>
> Show colored diff. The value must be always (the default for <when>),
> never, or auto. The default value is never.
I think it wants to say this:
You can say "diff --color" without saying "when". That is the
same as saying "diff --color=always".
If you do not say "--color" at all, that is exactly the same as
saying "diff --color=never".
Patches welcome.
^ permalink raw reply
* git-diff(1) appears to contradict itself
From: Reuben Thomas @ 2013-02-12 2:49 UTC (permalink / raw)
To: git
Under the --color=<when> option, it says:
Show colored diff. The value must be always (the default for <when>),
never, or auto. The default value is never.
That seems to imply that the default is both always and never. If I'm
right, I suggest removing the parenthesis, and putting the correct
default value at the end of the sentence. If I'm wrong, I suggest
clarification!
--
http://rrt.sc3d.org
^ permalink raw reply
* Re: [PATCHv2] parse-options: report uncorrupted multi-byte options
From: Duy Nguyen @ 2013-02-12 2:30 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Erik Faye-Lund, git, peff, matthieu.moy, tboegi
In-Reply-To: <7va9rajn99.fsf@alter.siamese.dyndns.org>
On Tue, Feb 12, 2013 at 9:10 AM, Junio C Hamano <gitster@pobox.com> wrote:
>> Similar cases:
>>
>> config.c:git_default_core_config() assumes core.commentchar is ascii.
>> We should catch and report non-ascii chars, or simply accept it as a
>> string.
>
> That one is just an uninterpreted byte. core.commentString might be
> a nice extension to the concept, but it is an entirely different
> category.
My point is not to output broken utf-8 if we can. If someone
accidentally puts a UTF-8 character in core.commentChar, it will
produce broken utf-8 templates that editors might react, but hard to
see by eye. Something like this may give sufficient protection:
diff --git a/config.c b/config.c
index aefd80b..b6f73e0 100644
--- a/config.c
+++ b/config.c
@@ -726,8 +726,11 @@ static int git_default_core_config(const char
*var, const char *value)
if (!strcmp(var, "core.commentchar")) {
const char *comment;
int ret = git_config_string(&comment, var, value);
- if (!ret)
+ if (!ret) {
+ if (comment[1])
+ return error("core.commentchar must be
one ASCII character");
comment_line_char = comment[0];
+ }
return ret;
}
--
Duy
^ permalink raw reply related
* Re: Fetch and -t
From: Junio C Hamano @ 2013-02-12 2:24 UTC (permalink / raw)
To: Olsen, Alan R; +Cc: git@vger.kernel.org
In-Reply-To: <4B2793BF110AAB47AB0EE7B9089703854FEE40B6@fmsmsx110.amr.corp.intel.com>
"Olsen, Alan R" <alan.r.olsen@intel.com> writes:
> I have found that if I add a remote and do a "git fetch -t -f
> remote_name" that it *only* pulls tags.
>
> Reading the man page it seems like it should pull all the remotes
> and all the tags and the commits only reachable by tags.
This is what appears in the documentation we ship these days.
-t::
--tags::
This is a short-hand for giving "refs/tags/*:refs/tags/*"
refspec from the command line, to ask all tags to be fetched
and stored locally. Because this acts as an explicit
refspec, the default refspecs (configured with the
remote.$name.fetch variable) are overridden and not used.
http://git-htmldocs.googlecode.com/git/git-fetch.html
Previous discussion:
http://thread.gmane.org/gmane.comp.version-control.git/180636
A more recent one:
http://thread.gmane.org/gmane.comp.version-control.git/211439/focus=211464
^ permalink raw reply
* Re: [PATCHv2] parse-options: report uncorrupted multi-byte options
From: Junio C Hamano @ 2013-02-12 2:10 UTC (permalink / raw)
To: Duy Nguyen; +Cc: Erik Faye-Lund, git, peff, matthieu.moy, tboegi
In-Reply-To: <CACsJy8BByNnEhhE3TieM_kOy65t75rmB45ZzjJJ8AtL2N4-UFA@mail.gmail.com>
Duy Nguyen <pclouds@gmail.com> writes:
> On Tue, Feb 12, 2013 at 6:13 AM, Erik Faye-Lund <kusmabite@gmail.com> wrote:
>> Because our command-line parser considers only one byte at the time
>> for short-options, we incorrectly report only the first byte when
>> multi-byte input was provided. This makes user-erros slightly
>> awkward to diagnose for instance under UTF-8 locale and non-English
>> keyboard layouts.
>>
>> Make the reporting code report the whole argument-string when a
>> non-ASCII short-option is detected.
>
> Similar cases:
>
> config.c:git_default_core_config() assumes core.commentchar is ascii.
> We should catch and report non-ascii chars, or simply accept it as a
> string.
That one is just an uninterpreted byte. core.commentString might be
a nice extension to the concept, but it is an entirely different
category.
> builtin/update-index.c:cmd_update_index(): error("unknown switch
> '%c'", *ctx.opt);
This one is in the same category as this topic.
> builtin/apply.c:apply_one_fragment(): error(_("invalid start of line:
> '%c'"), first); where 'first' may be a part of utf-8 from a broken
> patch.
This is where the patch is expected to have either " ", "-" or "+",
again, anything else is an uninterpreted byte. It is more like
reporting the file we found an error in, whose filename is not
encoded in UTF-8 to the user's terminal.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox