From e66191f4837f2d18bb70ceaf3cad4eb52cc4000c Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Sat, 13 Jan 2007 02:47:53 -0800 Subject: [PATCH 1/4] git-svn: fix tests to work with older svn Some of the recent changes and shortcuts to the tests broke things for people using older versions of svn: t9104-git-svn-follow-parent.sh: v1.2.3 (from SuSE 10.0 as reported by riddochc on #git (thanks!)) required an extra 'svn up'. I was also able to reproduce this with v1.1.4 (Debian Sarge). lib-git-svn.sh: SVN::Repos bindings in versions up to and including 1.1.4 (Sarge again) do not pass fs-config options to the underlying library. BerkeleyDB repositories also seem completely broken on all my Sarge machines; so not using FSFS does not seem to be an option for most people. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- t/lib-git-svn.sh | 5 +++-- t/t9104-git-svn-follow-parent.sh | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index af42ccc8d1..a0f2814083 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -25,14 +25,15 @@ perl -w -e " use SVN::Core; use SVN::Repos; \$SVN::Core::VERSION gt '1.1.0' or exit(42); -SVN::Repos::create('$svnrepo', undef, undef, undef, - { 'fs-config' => 'fsfs'}); +system(qw/svnadmin create --fs-type fsfs/, '$svnrepo') == 0 or exit(41); " x=$? if test $x -ne 0 then if test $x -eq 42; then err='Perl SVN libraries must be >= 1.1.0' + elif test $x -eq 41; then + err='svnadmin failed to create fsfs repository' else err='Perl SVN libraries not found or unusable, skipping test' fi diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index 400c21cd49..8d2e2fec39 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -17,6 +17,7 @@ test_expect_success 'initialize repo' " cd wc && echo world >> trunk/readme && svn commit -m 'another commit' && + svn up && svn mv -m 'rename to thunk' trunk thunk && svn up && echo goodbye >> thunk/readme && From c03f77573ac4db7f549948c4c0de4fa3c9eb545c Mon Sep 17 00:00:00 2001 From: Quy Tonthat Date: Sat, 13 Jan 2007 22:55:21 +1100 Subject: [PATCH 2/4] git-remote: no longer silent on unknown commands. Signed-off-by: Quy Tonthat Signed-off-by: Junio C Hamano --- git-remote.perl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/git-remote.perl b/git-remote.perl index 059c141b68..fc055b6d95 100755 --- a/git-remote.perl +++ b/git-remote.perl @@ -274,4 +274,9 @@ elsif ($ARGV[0] eq 'add') { } add_remote($ARGV[1], $ARGV[2]); } - +else { + print STDERR "Usage: git remote\n"; + print STDERR " git remote add \n"; + print STDERR " git remote show \n"; + exit(1); +} From f7e68b2967182f14547125d1369f37ad4d83187e Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 12 Jan 2007 17:32:38 -0800 Subject: [PATCH 3/4] Use log output encoding in --pretty=email headers. Private functions add_rfc2047() and pretty_print_commit() assumed they are only emitting UTF-8. Signed-off-by: Junio C Hamano --- commit.c | 84 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/commit.c b/commit.c index 496d37aa02..9b2b842e7d 100644 --- a/commit.c +++ b/commit.c @@ -464,20 +464,29 @@ static int get_one_line(const char *msg, unsigned long len) return ret; } -static int is_rfc2047_special(char ch) +/* High bit set, or ISO-2022-INT */ +static int non_ascii(int ch) { - return ((ch & 0x80) || (ch == '=') || (ch == '?') || (ch == '_')); + ch = (ch & 0xff); + return ((ch & 0x80) || (ch == 0x1b)); } -static int add_rfc2047(char *buf, const char *line, int len) +static int is_rfc2047_special(char ch) +{ + return (non_ascii(ch) || (ch == '=') || (ch == '?') || (ch == '_')); +} + +static int add_rfc2047(char *buf, const char *line, int len, + const char *encoding) { char *bp = buf; int i, needquote; - static const char q_utf8[] = "=?utf-8?q?"; + char q_encoding[128]; + const char *q_encoding_fmt = "=?%s?q?"; for (i = needquote = 0; !needquote && i < len; i++) { - unsigned ch = line[i]; - if (ch & 0x80) + int ch = line[i]; + if (non_ascii(ch)) needquote++; if ((i + 1 < len) && (ch == '=' && line[i+1] == '?')) @@ -486,8 +495,11 @@ static int add_rfc2047(char *buf, const char *line, int len) if (!needquote) return sprintf(buf, "%.*s", len, line); - memcpy(bp, q_utf8, sizeof(q_utf8)-1); - bp += sizeof(q_utf8)-1; + i = snprintf(q_encoding, sizeof(q_encoding), q_encoding_fmt, encoding); + if (sizeof(q_encoding) < i) + die("Insanely long encoding name %s", encoding); + memcpy(bp, q_encoding, i); + bp += i; for (i = 0; i < len; i++) { unsigned ch = line[i] & 0xFF; if (is_rfc2047_special(ch)) { @@ -505,7 +517,8 @@ static int add_rfc2047(char *buf, const char *line, int len) } static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, - const char *line, int relative_date) + const char *line, int relative_date, + const char *encoding) { char *date; int namelen; @@ -533,7 +546,8 @@ static int add_user_info(const char *what, enum cmit_fmt fmt, char *buf, filler = ""; strcpy(buf, "From: "); ret = strlen(buf); - ret += add_rfc2047(buf + ret, line, display_name_length); + ret += add_rfc2047(buf + ret, line, display_name_length, + encoding); memcpy(buf + ret, name_tail, namelen - display_name_length); ret += namelen - display_name_length; buf[ret++] = '\n'; @@ -668,21 +682,18 @@ static char *replace_encoding_header(char *buf, char *encoding) return buf; } -static char *logmsg_reencode(const struct commit *commit) +static char *logmsg_reencode(const struct commit *commit, + char *output_encoding) { char *encoding; char *out; - char *output_encoding = (git_log_output_encoding - ? git_log_output_encoding - : git_commit_encoding); + char *utf8 = "utf-8"; - if (!output_encoding) - output_encoding = "utf-8"; - else if (!*output_encoding) + if (!*output_encoding) return NULL; encoding = get_header(commit, "encoding"); if (!encoding) - return NULL; + encoding = utf8; if (!strcmp(encoding, output_encoding)) out = strdup(commit->buffer); else @@ -691,7 +702,8 @@ static char *logmsg_reencode(const struct commit *commit) if (out) out = replace_encoding_header(out, output_encoding); - free(encoding); + if (encoding != utf8) + free(encoding); if (!out) return NULL; return out; @@ -711,8 +723,15 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, int parents_shown = 0; const char *msg = commit->buffer; int plain_non_ascii = 0; - char *reencoded = logmsg_reencode(commit); + char *reencoded; + char *encoding; + encoding = (git_log_output_encoding + ? git_log_output_encoding + : git_commit_encoding); + if (!encoding) + encoding = "utf-8"; + reencoded = logmsg_reencode(commit, encoding); if (reencoded) msg = reencoded; @@ -738,7 +757,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, i + 1 < len && msg[i+1] == '\n') in_body = 1; } - else if (ch & 0x80) { + else if (non_ascii(ch)) { plain_non_ascii = 1; break; } @@ -797,13 +816,15 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, offset += add_user_info("Author", fmt, buf + offset, line + 7, - relative_date); + relative_date, + encoding); if (!memcmp(line, "committer ", 10) && (fmt == CMIT_FMT_FULL || fmt == CMIT_FMT_FULLER)) offset += add_user_info("Commit", fmt, buf + offset, line + 10, - relative_date); + relative_date, + encoding); continue; } @@ -826,7 +847,8 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, int slen = strlen(subject); memcpy(buf + offset, subject, slen); offset += slen; - offset += add_rfc2047(buf + offset, line, linelen); + offset += add_rfc2047(buf + offset, line, linelen, + encoding); } else { memset(buf + offset, ' ', indent); @@ -837,11 +859,17 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt, if (fmt == CMIT_FMT_ONELINE) break; if (subject && plain_non_ascii) { - static const char header[] = - "Content-Type: text/plain; charset=UTF-8\n" + int sz; + char header[512]; + const char *header_fmt = + "Content-Type: text/plain; charset=%s\n" "Content-Transfer-Encoding: 8bit\n"; - memcpy(buf + offset, header, sizeof(header)-1); - offset += sizeof(header)-1; + sz = snprintf(header, sizeof(header), header_fmt, + encoding); + if (sizeof(header) < sz) + die("Encoding name %s too long", encoding); + memcpy(buf + offset, header, sz); + offset += sz; } if (after_subject) { int slen = strlen(after_subject); From a731ec5eb827767e0f054641ab1eacc632113c59 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 13 Jan 2007 01:20:53 -0800 Subject: [PATCH 4/4] t3901: test "format-patch | am" pipe with i18n This checks combinations of i18n.commitencoding (declares what encoding you are feeding commit-tree to make commits) and i18n.logoutputencoding (instructs what encoding to emit the commit message out to log output, including e-mail format) to make sure the "format-patch | am" pipe used in git-rebase works correctly. I suspect "git cherry-pick" and "git rebase --merge" may fail similar tests. We'll see. Signed-off-by: Junio C Hamano --- t/t3901-8859-1.txt | 4 ++ t/t3901-i18n-patch.sh | 154 ++++++++++++++++++++++++++++++++++++++++++ t/t3901-utf8.txt | 4 ++ 3 files changed, 162 insertions(+) create mode 100755 t/t3901-8859-1.txt create mode 100755 t/t3901-i18n-patch.sh create mode 100755 t/t3901-utf8.txt diff --git a/t/t3901-8859-1.txt b/t/t3901-8859-1.txt new file mode 100755 index 0000000000..38c21a6a7f --- /dev/null +++ b/t/t3901-8859-1.txt @@ -0,0 +1,4 @@ +: to be sourced in t3901 -- this is latin-1 +GIT_AUTHOR_NAME="Αιν σϊ" && +GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME && +export GIT_AUTHOR_NAME GIT_COMMITTER_NAME diff --git a/t/t3901-i18n-patch.sh b/t/t3901-i18n-patch.sh new file mode 100755 index 0000000000..7fecfe98d2 --- /dev/null +++ b/t/t3901-i18n-patch.sh @@ -0,0 +1,154 @@ +#!/bin/sh +# +# Copyright (c) 2006 Junio C Hamano +# + +test_description='i18n settings and format-patch | am pipe' + +. ./test-lib.sh + +test_expect_success setup ' + git-repo-config i18n.commitencoding UTF-8 && + + # use UTF-8 in author and committer name to match the + # i18n.commitencoding settings + . ../t3901-utf8.txt && + + test_tick && + echo "$GIT_AUTHOR_NAME" >mine && + git add mine && + git commit -s -m "Initial commit" && + + test_tick && + echo Hello world >mine && + git add mine && + git commit -s -m "Second on main" && + + # the first commit on the side branch is UTF-8 + test_tick && + git checkout -b side master^ && + echo Another file >yours && + git add yours && + git commit -s -m "Second on side" && + + # the second one on the side branch is ISO-8859-1 + git-repo-config i18n.commitencoding ISO-8859-1 && + # use author and committer name in ISO-8859-1 to match it. + . ../t3901-8859-1.txt && + test_tick && + echo Yet another >theirs && + git add theirs && + git commit -s -m "Third on side" && + + # Back to default + git-repo-config i18n.commitencoding UTF-8 +' + +test_expect_success 'format-patch output (ISO-8859-1)' ' + git-repo-config i18n.logoutputencoding ISO-8859-1 && + + git format-patch --stdout master..HEAD^ >out-l1 && + git format-patch --stdout HEAD^ >out-l2 && + grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l1 && + grep "^From: =?ISO-8859-1?q?=C1=E9=ED_=F3=FA?=" out-l1 && + grep "^Content-Type: text/plain; charset=ISO-8859-1" out-l2 && + grep "^From: =?ISO-8859-1?q?=C1=E9=ED_=F3=FA?=" out-l2 +' + +test_expect_success 'format-patch output (UTF-8)' ' + git repo-config i18n.logoutputencoding UTF-8 && + + git format-patch --stdout master..HEAD^ >out-u1 && + git format-patch --stdout HEAD^ >out-u2 && + grep "^Content-Type: text/plain; charset=UTF-8" out-u1 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-u1 && + grep "^Content-Type: text/plain; charset=UTF-8" out-u2 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-u2 +' + +test_expect_success 'rebase (UTF-8)' ' + # We want the result of rebase in UTF-8 + git-repo-config i18n.commitencoding UTF-8 && + + # The test is about logoutputencoding not affecting the + # final outcome -- it is used internally to generate the + # patch and the log. + + git repo-config i18n.logoutputencoding UTF-8 && + + # The result will be committed by GIT_COMMITTER_NAME -- + # we want UTF-8 encoded name. + . ../t3901-utf8.txt && + git checkout -b test && + git-rebase master && + + # Check the results. + git format-patch --stdout HEAD~2..HEAD^ >out-r1 && + git format-patch --stdout HEAD^ >out-r2 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r1 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r2 + + ! git-cat-file commit HEAD | grep "^encoding ISO-8859-1" && + ! git-cat-file commit HEAD^ | grep "^encoding ISO-8859-1" +' + +test_expect_success 'rebase (ISO-8859-1)' ' + git-repo-config i18n.commitencoding UTF-8 && + git repo-config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-utf8.txt && + + git reset --hard side && + git-rebase master && + + git repo-config i18n.logoutputencoding UTF-8 && + git format-patch --stdout HEAD~2..HEAD^ >out-r1 && + git format-patch --stdout HEAD^ >out-r2 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r1 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r2 && + + ! git-cat-file commit HEAD | grep "^encoding ISO-8859-1" && + ! git-cat-file commit HEAD^ | grep "^encoding ISO-8859-1" +' + +test_expect_success 'rebase (ISO-8859-1)' ' + # In this test we want ISO-8859-1 encoded commits as the result + git-repo-config i18n.commitencoding ISO-8859-1 && + git repo-config i18n.logoutputencoding ISO-8859-1 && + . ../t3901-8859-1.txt && + + git reset --hard side && + git-rebase master && + + # Make sure characters are not corrupted. + git repo-config i18n.logoutputencoding UTF-8 && + git format-patch --stdout HEAD~2..HEAD^ >out-r1 && + git format-patch --stdout HEAD^ >out-r2 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r1 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r2 && + + git-cat-file commit HEAD | grep "^encoding ISO-8859-1" && + git-cat-file commit HEAD^ | grep "^encoding ISO-8859-1" +' + +test_expect_success 'rebase (UTF-8)' ' + # This is pathological -- use UTF-8 as intermediate form + # to get ISO-8859-1 results. + git-repo-config i18n.commitencoding ISO-8859-1 && + git repo-config i18n.logoutputencoding UTF-8 && + . ../t3901-8859-1.txt && + + git reset --hard side && + git-rebase master && + + # Make sure characters are not corrupted. + git repo-config i18n.logoutputencoding UTF-8 && + git format-patch --stdout HEAD~2..HEAD^ >out-r1 && + git format-patch --stdout HEAD^ >out-r2 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r1 && + grep "^From: =?UTF-8?q?=C3=81=C3=A9=C3=AD_=C3=B3=C3=BA?=" out-r2 && + + git-cat-file commit HEAD | grep "^encoding ISO-8859-1" && + git-cat-file commit HEAD^ | grep "^encoding ISO-8859-1" +' + +test_done diff --git a/t/t3901-utf8.txt b/t/t3901-utf8.txt new file mode 100755 index 0000000000..5f5205cd02 --- /dev/null +++ b/t/t3901-utf8.txt @@ -0,0 +1,4 @@ +: to be sourced in t3901 -- this is utf8 +GIT_AUTHOR_NAME="Áéí Γ³ΓΊ" && +GIT_COMMITTER_NAME=$GIT_AUTHOR_NAME && +export GIT_AUTHOR_NAME GIT_COMMITTER_NAME