From: Junio C Hamano Date: Tue, 27 Dec 2016 08:11:40 +0000 (-0800) Subject: Merge branch 'va/i18n-perl-scripts' X-Git-Tag: v2.12.0-rc0~106 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/1d73f8e86d7b4d95e0b7ce53eec2a5f8114722ac?ds=inline;hp=-c Merge branch 'va/i18n-perl-scripts' Porcelain scripts written in Perl are getting internationalized. * va/i18n-perl-scripts: i18n: difftool: mark warnings for translation i18n: send-email: mark composing message for translation i18n: send-email: mark string with interpolation for translation i18n: send-email: mark warnings and errors for translation i18n: send-email: mark strings for translation i18n: add--interactive: mark status words for translation i18n: add--interactive: remove %patch_modes entries i18n: add--interactive: mark edit_hunk_manually message for translation i18n: add--interactive: i18n of help_patch_cmd i18n: add--interactive: mark patch prompt for translation i18n: add--interactive: mark plural strings i18n: clean.c: match string with git-add--interactive.perl i18n: add--interactive: mark strings with interpolation for translation i18n: add--interactive: mark simple here-documents for translation i18n: add--interactive: mark strings for translation Git.pm: add subroutines for commenting lines --- 1d73f8e86d7b4d95e0b7ce53eec2a5f8114722ac diff --combined Makefile index 05a35ad3b5,c79aceb42d..d861bd9985 --- a/Makefile +++ b/Makefile @@@ -301,8 -301,7 +301,8 @@@ all: # crashes due to allocation and free working on different 'heaps'. # It's defined automatically if USE_NED_ALLOCATOR is set. # -# Define NO_REGEX if you have no or inferior regex support in your C library. +# Define NO_REGEX if your C library lacks regex support with REG_STARTEND +# feature. # # Define HAVE_DEV_TTY if your system can open /dev/tty to interact with the # user. @@@ -338,6 -337,11 +338,6 @@@ # # Define NATIVE_CRLF if your platform uses CRLF for line endings. # -# Define XDL_FAST_HASH to use an alternative line-hashing method in -# the diff algorithm. It gives a nice speedup if your processor has -# fast unaligned word loads. Does NOT work on big-endian systems! -# Enabled by default on x86_64. -# # Define GIT_USER_AGENT if you want to change how git identifies itself during # network interactions. The default is "git/$(GIT_VERSION)". # @@@ -457,12 -461,10 +457,12 @@@ CURL_CONFIG = curl-confi PTHREAD_LIBS = -lpthread PTHREAD_CFLAGS = GCOV = gcov +SPATCH = spatch export TCL_PATH TCLTK_PATH SPARSE_FLAGS = +SPATCH_FLAGS = --all-includes @@@ -827,7 -829,6 +827,7 @@@ LIB_OBJS += submodule-config. LIB_OBJS += symlinks.o LIB_OBJS += tag.o LIB_OBJS += tempfile.o +LIB_OBJS += tmp-objdir.o LIB_OBJS += trace.o LIB_OBJS += trailer.o LIB_OBJS += transport.o @@@ -1042,7 -1043,6 +1042,7 @@@ ifeq ($(uname_S),Darwin endif endif ifndef NO_APPLE_COMMON_CRYPTO + NO_OPENSSL = YesPlease APPLE_COMMON_CRYPTO = YesPlease COMPAT_CFLAGS += -DAPPLE_COMMON_CRYPTO endif @@@ -1480,6 -1480,10 +1480,6 @@@ ifndef NO_MSGFMT_EXTENDED_OPTION MSGFMT += --check --statistics endif -ifneq (,$(XDL_FAST_HASH)) - BASIC_CFLAGS += -DXDL_FAST_HASH -endif - ifdef GMTIME_UNRELIABLE_ERRORS COMPAT_OBJS += compat/gmtime.o BASIC_CFLAGS += -DGMTIME_UNRELIABLE_ERRORS @@@ -2105,7 -2109,8 +2105,8 @@@ XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) -- --keyword=_ --keyword=N_ --keyword="Q_:1,2" XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \ --keyword=gettextln --keyword=eval_gettextln - XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl + XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \ + --keyword=__ --keyword=N__ --keyword="__n:1,2" LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) LOCALIZED_SH = $(SCRIPT_SH) LOCALIZED_SH += git-parse-remote.sh @@@ -2140,22 -2145,9 +2141,22 @@@ endi po/build/locale/%/LC_MESSAGES/git.mo: po/%.po $(QUIET_MSGFMT)mkdir -p $(dir $@) && $(MSGFMT) -o $@ $< -FIND_SOURCE_FILES = ( git ls-files '*.[hcS]' 2>/dev/null || \ - $(FIND) . \( -name .git -type d -prune \) \ - -o \( -name '*.[hcS]' -type f -print \) ) +FIND_SOURCE_FILES = ( \ + git ls-files \ + '*.[hcS]' \ + '*.sh' \ + ':!*[tp][0-9][0-9][0-9][0-9]*' \ + ':!contrib' \ + 2>/dev/null || \ + $(FIND) . \ + \( -name .git -type d -prune \) \ + -o \( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \) \ + -o \( -name contrib -type d -prune \) \ + -o \( -name build -type d -prune \) \ + -o \( -name 'trash*' -type d -prune \) \ + -o \( -name '*.[hcS]' -type f -print \) \ + -o \( -name '*.sh' -type f -print \) \ + ) $(ETAGS_TARGET): FORCE $(RM) $(ETAGS_TARGET) @@@ -2317,18 -2309,6 +2318,18 @@@ check: common-cmds. exit 1; \ fi +C_SOURCES = $(patsubst %.o,%.c,$(C_OBJ)) +%.cocci.patch: %.cocci $(C_SOURCES) + @echo ' ' SPATCH $<; \ + for f in $(C_SOURCES); do \ + $(SPATCH) --sp-file $< $$f $(SPATCH_FLAGS); \ + done >$@ 2>$@.log; \ + if test -s $@; \ + then \ + echo ' ' SPATCH result: $@; \ + fi +coccicheck: $(patsubst %.cocci,%.cocci.patch,$(wildcard contrib/coccinelle/*.cocci)) + ### Installation rules ifneq ($(filter /%,$(firstword $(template_dir))),) @@@ -2520,7 -2500,6 +2521,7 @@@ clean: profile-clean coverage-clea $(RM) -r $(GIT_TARNAME) .doc-tmp-dir $(RM) $(GIT_TARNAME).tar.gz git-core_$(GIT_VERSION)-*.tar.gz $(RM) $(htmldocs).tar.gz $(manpages).tar.gz + $(RM) contrib/coccinelle/*.cocci.patch* $(MAKE) -C Documentation/ clean ifndef NO_PERL $(MAKE) -C gitweb clean diff --combined git-add--interactive.perl index ee3d812695,46dfc5276c..4e0ab5a9bc --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@@ -4,6 -4,7 +4,7 @@@ use 5.008 use strict; use warnings; use Git; + use Git::I18N; binmode(STDOUT, ":raw"); @@@ -45,7 -46,6 +46,7 @@@ my ($diff_new_color) my $normal_color = $repo->get_color("", "reset"); my $diff_algorithm = $repo->config('diff.algorithm'); +my $diff_indent_heuristic = $repo->config_bool('diff.indentheuristic'); my $diff_compaction_heuristic = $repo->config_bool('diff.compactionheuristic'); my $diff_filter = $repo->config('interactive.difffilter'); @@@ -92,6 -92,7 +93,7 @@@ sub colored } # command line options + my $cmd; my $patch_mode; my $patch_mode_revision; @@@ -104,9 -105,6 +106,6 @@@ my %patch_modes = DIFF => 'diff-files -p', APPLY => sub { apply_patch 'apply --cached', @_; }, APPLY_CHECK => 'apply --cached', - VERB => 'Stage', - TARGET => '', - PARTICIPLE => 'staging', FILTER => 'file-only', IS_REVERSE => 0, }, @@@ -114,9 -112,6 +113,6 @@@ DIFF => 'diff-index -p HEAD', APPLY => sub { apply_patch 'apply --cached', @_; }, APPLY_CHECK => 'apply --cached', - VERB => 'Stash', - TARGET => '', - PARTICIPLE => 'stashing', FILTER => undef, IS_REVERSE => 0, }, @@@ -124,9 -119,6 +120,6 @@@ DIFF => 'diff-index -p --cached', APPLY => sub { apply_patch 'apply -R --cached', @_; }, APPLY_CHECK => 'apply -R --cached', - VERB => 'Unstage', - TARGET => '', - PARTICIPLE => 'unstaging', FILTER => 'index-only', IS_REVERSE => 1, }, @@@ -134,9 -126,6 +127,6 @@@ DIFF => 'diff-index -R -p --cached', APPLY => sub { apply_patch 'apply --cached', @_; }, APPLY_CHECK => 'apply --cached', - VERB => 'Apply', - TARGET => ' to index', - PARTICIPLE => 'applying', FILTER => 'index-only', IS_REVERSE => 0, }, @@@ -144,9 -133,6 +134,6 @@@ DIFF => 'diff-files -p', APPLY => sub { apply_patch 'apply -R', @_; }, APPLY_CHECK => 'apply -R', - VERB => 'Discard', - TARGET => ' from worktree', - PARTICIPLE => 'discarding', FILTER => 'file-only', IS_REVERSE => 1, }, @@@ -154,9 -140,6 +141,6 @@@ DIFF => 'diff-index -p', APPLY => sub { apply_patch_for_checkout_commit '-R', @_ }, APPLY_CHECK => 'apply -R', - VERB => 'Discard', - TARGET => ' from index and worktree', - PARTICIPLE => 'discarding', FILTER => undef, IS_REVERSE => 1, }, @@@ -164,15 -147,13 +148,13 @@@ DIFF => 'diff-index -R -p', APPLY => sub { apply_patch_for_checkout_commit '', @_ }, APPLY_CHECK => 'apply', - VERB => 'Apply', - TARGET => ' to index and worktree', - PARTICIPLE => 'applying', FILTER => undef, IS_REVERSE => 0, }, ); - my %patch_mode_flavour = %{$patch_modes{stage}}; + $patch_mode = 'stage'; + my %patch_mode_flavour = %{$patch_modes{$patch_mode}}; sub run_cmd_pipe { if ($^O eq 'MSWin32') { @@@ -253,8 -234,9 +235,9 @@@ sub list_untracked run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @ARGV); } - my $status_fmt = '%12s %12s %s'; - my $status_head = sprintf($status_fmt, 'staged', 'unstaged', 'path'); + # TRANSLATORS: you can adjust this to align "git add -i" status menu + my $status_fmt = __('%12s %12s %s'); + my $status_head = sprintf($status_fmt, __('staged'), __('unstaged'), __('path')); { my $initial; @@@ -312,7 -294,7 +295,7 @@@ sub list_modified my ($change, $bin); $file = unquote_path($file); if ($add eq '-' && $del eq '-') { - $change = 'binary'; + $change = __('binary'); $bin = 1; } else { @@@ -321,7 -303,7 +304,7 @@@ $data{$file} = { INDEX => $change, BINARY => $bin, - FILE => 'nothing', + FILE => __('nothing'), } } elsif (($adddel, $file) = @@@ -337,7 -319,7 +320,7 @@@ $file = unquote_path($file); my ($change, $bin); if ($add eq '-' && $del eq '-') { - $change = 'binary'; + $change = __('binary'); $bin = 1; } else { @@@ -357,7 -339,7 +340,7 @@@ $file = unquote_path($2); if (!exists $data{$file}) { $data{$file} = +{ - INDEX => 'unchanged', + INDEX => __('unchanged'), BINARY => 0, }; } @@@ -372,10 -354,10 +355,10 @@@ if ($only) { if ($only eq 'index-only') { - next if ($it->{INDEX} eq 'unchanged'); + next if ($it->{INDEX} eq __('unchanged')); } if ($only eq 'file-only') { - next if ($it->{FILE} eq 'nothing'); + next if ($it->{FILE} eq __('nothing')); } } push @return, +{ @@@ -613,12 -595,12 +596,12 @@@ sub list_and_choose else { $bottom = $top = find_unique($choice, @stuff); if (!defined $bottom) { - error_msg "Huh ($choice)?\n"; + error_msg sprintf(__("Huh (%s)?\n"), $choice); next TOPLOOP; } } if ($opts->{SINGLETON} && $bottom != $top) { - error_msg "Huh ($choice)?\n"; + error_msg sprintf(__("Huh (%s)?\n"), $choice); next TOPLOOP; } for ($i = $bottom-1; $i <= $top-1; $i++) { @@@ -637,7 -619,7 +620,7 @@@ } sub singleton_prompt_help_cmd { - print colored $help_color, <<\EOF ; + print colored $help_color, __ <<'EOF' ; Prompt help: 1 - select a numbered item foo - select item based on unique prefix @@@ -646,7 -628,7 +629,7 @@@ EO } sub prompt_help_cmd { - print colored $help_color, <<\EOF ; + print colored $help_color, __ <<'EOF' ; Prompt help: 1 - select a single item 3-5 - select a range of items @@@ -667,12 -649,18 +650,18 @@@ sub status_cmd sub say_n_paths { my $did = shift @_; my $cnt = scalar @_; - print "$did "; - if (1 < $cnt) { - print "$cnt paths\n"; - } - else { - print "one path\n"; + if ($did eq 'added') { + printf(__n("added %d path\n", "added %d paths\n", + $cnt), $cnt); + } elsif ($did eq 'updated') { + printf(__n("updated %d path\n", "updated %d paths\n", + $cnt), $cnt); + } elsif ($did eq 'reverted') { + printf(__n("reverted %d path\n", "reverted %d paths\n", + $cnt), $cnt); + } else { + printf(__n("touched %d path\n", "touched %d paths\n", + $cnt), $cnt); } } @@@ -680,7 -668,7 +669,7 @@@ sub update_cmd my @mods = list_modified('file-only'); return if (!@mods); - my @update = list_and_choose({ PROMPT => 'Update', + my @update = list_and_choose({ PROMPT => __('Update'), HEADER => $status_head, }, @mods); if (@update) { @@@ -692,7 -680,7 +681,7 @@@ } sub revert_cmd { - my @update = list_and_choose({ PROMPT => 'Revert', + my @update = list_and_choose({ PROMPT => __('Revert'), HEADER => $status_head, }, list_modified()); if (@update) { @@@ -715,7 -703,7 +704,7 @@@ $_->{INDEX_ADDDEL} eq 'create') { system(qw(git update-index --force-remove --), $_->{VALUE}); - print "note: $_->{VALUE} is untracked now.\n"; + printf(__("note: %s is untracked now.\n"), $_->{VALUE}); } } } @@@ -726,13 -714,13 +715,13 @@@ } sub add_untracked_cmd { - my @add = list_and_choose({ PROMPT => 'Add untracked' }, + my @add = list_and_choose({ PROMPT => __('Add untracked') }, list_untracked()); if (@add) { system(qw(git update-index --add --), @add); say_n_paths('added', @add); } else { - print "No untracked files.\n"; + print __("No untracked files.\n"); } print "\n"; } @@@ -751,9 -739,7 +740,9 @@@ sub parse_diff if (defined $diff_algorithm) { splice @diff_cmd, 1, 0, "--diff-algorithm=${diff_algorithm}"; } - if ($diff_compaction_heuristic) { + if ($diff_indent_heuristic) { + splice @diff_cmd, 1, 0, "--indent-heuristic"; + } elsif ($diff_compaction_heuristic) { splice @diff_cmd, 1, 0, "--compaction-heuristic"; } if (defined $patch_mode_revision) { @@@ -1048,29 -1034,55 +1037,55 @@@ sub color_diff } @_; } + my %edit_hunk_manually_modes = ( + stage => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for staging."), + stash => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for stashing."), + reset_head => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for unstaging."), + reset_nothead => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for applying."), + checkout_index => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for discarding"), + checkout_head => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for discarding."), + checkout_nothead => N__( + "If the patch applies cleanly, the edited hunk will immediately be + marked for applying."), + ); + sub edit_hunk_manually { my ($oldtext) = @_; my $hunkfile = $repo->repo_path . "/addp-hunk-edit.diff"; my $fh; open $fh, '>', $hunkfile - or die "failed to open hunk edit file for writing: " . $!; - print $fh "# Manual hunk edit mode -- see bottom for a quick guide\n"; + or die sprintf(__("failed to open hunk edit file for writing: %s"), $!); + print $fh Git::comment_lines __("Manual hunk edit mode -- see bottom for a quick guide.\n"); print $fh @$oldtext; - my $participle = $patch_mode_flavour{PARTICIPLE}; my $is_reverse = $patch_mode_flavour{IS_REVERSE}; my ($remove_plus, $remove_minus) = $is_reverse ? ('-', '+') : ('+', '-'); - print $fh <; + or die sprintf(__("failed to open hunk edit file for reading: %s"), $!); + my @newtext = grep { !/^$comment_line_char/ } <$fh>; close $fh; unlink $hunkfile; @@@ -1166,22 -1178,66 +1181,66 @@@ sub edit_hunk_loop } else { prompt_yesno( - 'Your edited hunk does not apply. Edit again ' - . '(saying "no" discards!) [y/n]? ' + # TRANSLATORS: do not translate [y/n] + # The program will only accept that input + # at this point. + # Consider translating (saying "no" discards!) as + # (saying "n" for "no" discards!) if the translation + # of the word "no" does not start with n. + __('Your edited hunk does not apply. Edit again ' + . '(saying "no" discards!) [y/n]? ') ) or return undef; } } } + my %help_patch_modes = ( + stage => N__( + "y - stage this hunk + n - do not stage this hunk + q - quit; do not stage this hunk or any of the remaining ones + a - stage this hunk and all later hunks in the file + d - do not stage this hunk or any of the later hunks in the file"), + stash => N__( + "y - stash this hunk + n - do not stash this hunk + q - quit; do not stash this hunk or any of the remaining ones + a - stash this hunk and all later hunks in the file + d - do not stash this hunk or any of the later hunks in the file"), + reset_head => N__( + "y - unstage this hunk + n - do not unstage this hunk + q - quit; do not unstage this hunk or any of the remaining ones + a - unstage this hunk and all later hunks in the file + d - do not unstage this hunk or any of the later hunks in the file"), + reset_nothead => N__( + "y - apply this hunk to index + n - do not apply this hunk to index + q - quit; do not apply this hunk or any of the remaining ones + a - apply this hunk and all later hunks in the file + d - do not apply this hunk or any of the later hunks in the file"), + checkout_index => N__( + "y - discard this hunk from worktree + n - do not discard this hunk from worktree + q - quit; do not discard this hunk or any of the remaining ones + a - discard this hunk and all later hunks in the file + d - do not discard this hunk or any of the later hunks in the file"), + checkout_head => N__( + "y - discard this hunk from index and worktree + n - do not discard this hunk from index and worktree + q - quit; do not discard this hunk or any of the remaining ones + a - discard this hunk and all later hunks in the file + d - do not discard this hunk or any of the later hunks in the file"), + checkout_nothead => N__( + "y - apply this hunk to index and worktree + n - do not apply this hunk to index and worktree + q - quit; do not apply this hunk or any of the remaining ones + a - apply this hunk and all later hunks in the file + d - do not apply this hunk or any of the later hunks in the file"), + ); + sub help_patch_cmd { - my $verb = lc $patch_mode_flavour{VERB}; - my $target = $patch_mode_flavour{TARGET}; - print colored $help_color, <{VALUE}\n" + error_msg sprintf(__("ignoring unmerged: %s\n"), $_->{VALUE}) for grep { $_->{UNMERGED} } @all_mods; @all_mods = grep { !$_->{UNMERGED} } @all_mods; @@@ -1237,9 -1293,9 +1296,9 @@@ if (!@mods) { if (@all_mods) { - print STDERR "Only binary files changed.\n"; + print STDERR __("Only binary files changed.\n"); } else { - print STDERR "No changes.\n"; + print STDERR __("No changes.\n"); } return 0; } @@@ -1247,7 -1303,7 +1306,7 @@@ @them = @mods; } else { - @them = list_and_choose({ PROMPT => 'Patch update', + @them = list_and_choose({ PROMPT => __('Patch update'), HEADER => $status_head, }, @mods); } @@@ -1297,6 -1353,44 +1356,44 @@@ sub display_hunks return $i; } + my %patch_update_prompt_modes = ( + stage => { + mode => N__("Stage mode change [y,n,q,a,d,/%s,?]? "), + deletion => N__("Stage deletion [y,n,q,a,d,/%s,?]? "), + hunk => N__("Stage this hunk [y,n,q,a,d,/%s,?]? "), + }, + stash => { + mode => N__("Stash mode change [y,n,q,a,d,/%s,?]? "), + deletion => N__("Stash deletion [y,n,q,a,d,/%s,?]? "), + hunk => N__("Stash this hunk [y,n,q,a,d,/%s,?]? "), + }, + reset_head => { + mode => N__("Unstage mode change [y,n,q,a,d,/%s,?]? "), + deletion => N__("Unstage deletion [y,n,q,a,d,/%s,?]? "), + hunk => N__("Unstage this hunk [y,n,q,a,d,/%s,?]? "), + }, + reset_nothead => { + mode => N__("Apply mode change to index [y,n,q,a,d,/%s,?]? "), + deletion => N__("Apply deletion to index [y,n,q,a,d,/%s,?]? "), + hunk => N__("Apply this hunk to index [y,n,q,a,d,/%s,?]? "), + }, + checkout_index => { + mode => N__("Discard mode change from worktree [y,n,q,a,d,/%s,?]? "), + deletion => N__("Discard deletion from worktree [y,n,q,a,d,/%s,?]? "), + hunk => N__("Discard this hunk from worktree [y,n,q,a,d,/%s,?]? "), + }, + checkout_head => { + mode => N__("Discard mode change from index and worktree [y,n,q,a,d,/%s,?]? "), + deletion => N__("Discard deletion from index and worktree [y,n,q,a,d,/%s,?]? "), + hunk => N__("Discard this hunk from index and worktree [y,n,q,a,d,/%s,?]? "), + }, + checkout_nothead => { + mode => N__("Apply mode change to index and worktree [y,n,q,a,d,/%s,?]? "), + deletion => N__("Apply deletion to index and worktree [y,n,q,a,d,/%s,?]? "), + hunk => N__("Apply this hunk to index and worktree [y,n,q,a,d,/%s,?]? "), + }, + ); + sub patch_update_file { my $quit = 0; my ($ix, $num); @@@ -1369,12 -1463,9 +1466,9 @@@ for (@{$hunk[$ix]{DISPLAY}}) { print; } - print colored $prompt_color, $patch_mode_flavour{VERB}, - ($hunk[$ix]{TYPE} eq 'mode' ? ' mode change' : - $hunk[$ix]{TYPE} eq 'deletion' ? ' deletion' : - ' this hunk'), - $patch_mode_flavour{TARGET}, - " [y,n,q,a,d,/$other,?]? "; + print colored $prompt_color, + sprintf(__($patch_update_prompt_modes{$patch_mode}{$hunk[$ix]{TYPE}}), $other); + my $line = prompt_single_character; last unless defined $line; if ($line) { @@@ -1397,12 -1488,12 +1491,12 @@@ my $response = $1; my $no = $ix > 10 ? $ix - 10 : 0; while ($response eq '') { - my $extra = ""; $no = display_hunks(\@hunk, $no); if ($no < $num) { - $extra = " ( to see more)"; + print __("go to which hunk ( to see more)? "); + } else { + print __("go to which hunk? "); } - print "go to which hunk$extra? "; $response = ; if (!defined $response) { $response = ''; @@@ -1410,11 -1501,13 +1504,13 @@@ chomp $response; } if ($response !~ /^\s*\d+\s*$/) { - error_msg "Invalid number: '$response'\n"; + error_msg sprintf(__("Invalid number: '%s'\n"), + $response); } elsif (0 < $response && $response <= $num) { $ix = $response - 1; } else { - error_msg "Sorry, only $num hunks available.\n"; + error_msg sprintf(__n("Sorry, only %d hunk available.\n", + "Sorry, only %d hunks available.\n", $num), $num); } next; } @@@ -1439,7 -1532,7 +1535,7 @@@ elsif ($line =~ m|^/(.*)|) { my $regex = $1; if ($1 eq "") { - print colored $prompt_color, "search for regex? "; + print colored $prompt_color, __("search for regex? "); $regex = ; if (defined $regex) { chomp $regex; @@@ -1452,7 -1545,7 +1548,7 @@@ if ($@) { my ($err,$exp) = ($@, $1); $err =~ s/ at .*git-add--interactive line \d+, line \d+.*$//; - error_msg "Malformed search regexp $exp: $err\n"; + error_msg sprintf(__("Malformed search regexp %s: %s\n"), $exp, $err); next; } my $iy = $ix; @@@ -1462,7 -1555,7 +1558,7 @@@ $iy++; $iy = 0 if ($iy >= $num); if ($ix == $iy) { - error_msg "No hunk matches the given pattern\n"; + error_msg __("No hunk matches the given pattern\n"); last; } } @@@ -1474,7 -1567,7 +1570,7 @@@ $ix--; } else { - error_msg "No previous hunk\n"; + error_msg __("No previous hunk\n"); } next; } @@@ -1483,7 -1576,7 +1579,7 @@@ $ix++; } else { - error_msg "No next hunk\n"; + error_msg __("No next hunk\n"); } next; } @@@ -1496,21 -1589,23 +1592,23 @@@ } } else { - error_msg "No previous hunk\n"; + error_msg __("No previous hunk\n"); } next; } elsif ($line =~ /^j/) { if ($other !~ /j/) { - error_msg "No next hunk\n"; + error_msg __("No next hunk\n"); next; } } elsif ($other =~ /s/ && $line =~ /^s/) { my @split = split_hunk($hunk[$ix]{TEXT}, $hunk[$ix]{DISPLAY}); if (1 < @split) { - print colored $header_color, "Split into ", - scalar(@split), " hunks.\n"; + print colored $header_color, sprintf( + __n("Split into %d hunk.\n", + "Split into %d hunks.\n", + scalar(@split)), scalar(@split)); } splice (@hunk, $ix, 1, @split); $num = scalar @hunk; @@@ -1560,23 -1655,25 +1658,25 @@@ sub diff_cmd my @mods = list_modified('index-only'); @mods = grep { !($_->{BINARY}) } @mods; return if (!@mods); - my (@them) = list_and_choose({ PROMPT => 'Review diff', + my (@them) = list_and_choose({ PROMPT => __('Review diff'), IMMEDIATE => 1, HEADER => $status_head, }, @mods); return if (!@them); - my $reference = is_initial_commit() ? get_empty_tree() : 'HEAD'; + my $reference = (is_initial_commit()) ? get_empty_tree() : 'HEAD'; system(qw(git diff -p --cached), $reference, '--', map { $_->{VALUE} } @them); } sub quit_cmd { - print "Bye.\n"; + print __("Bye.\n"); exit(0); } sub help_cmd { - print colored $help_color, <<\EOF ; + # TRANSLATORS: please do not translate the command names + # 'status', 'update', 'revert', etc. + print colored $help_color, __ <<'EOF' ; status - show paths with changes update - add working tree state to the staged set of changes revert - revert staged set of changes back to the HEAD version @@@ -1594,39 -1691,40 +1694,40 @@@ sub process_args if ($1 eq 'reset') { $patch_mode = 'reset_head'; $patch_mode_revision = 'HEAD'; - $arg = shift @ARGV or die "missing --"; + $arg = shift @ARGV or die __("missing --"); if ($arg ne '--') { $patch_mode_revision = $arg; $patch_mode = ($arg eq 'HEAD' ? 'reset_head' : 'reset_nothead'); - $arg = shift @ARGV or die "missing --"; + $arg = shift @ARGV or die __("missing --"); } } elsif ($1 eq 'checkout') { - $arg = shift @ARGV or die "missing --"; + $arg = shift @ARGV or die __("missing --"); if ($arg eq '--') { $patch_mode = 'checkout_index'; } else { $patch_mode_revision = $arg; $patch_mode = ($arg eq 'HEAD' ? 'checkout_head' : 'checkout_nothead'); - $arg = shift @ARGV or die "missing --"; + $arg = shift @ARGV or die __("missing --"); } } elsif ($1 eq 'stage' or $1 eq 'stash') { $patch_mode = $1; - $arg = shift @ARGV or die "missing --"; + $arg = shift @ARGV or die __("missing --"); } else { - die "unknown --patch mode: $1"; + die sprintf(__("unknown --patch mode: %s"), $1); } } else { $patch_mode = 'stage'; - $arg = shift @ARGV or die "missing --"; + $arg = shift @ARGV or die __("missing --"); } - die "invalid argument $arg, expecting --" - unless $arg eq "--"; + die sprintf(__("invalid argument %s, expecting --"), + $arg) unless $arg eq "--"; %patch_mode_flavour = %{$patch_modes{$patch_mode}}; + $cmd = 1; } elsif ($arg ne "--") { - die "invalid argument $arg, expecting --"; + die sprintf(__("invalid argument %s, expecting --"), $arg); } } @@@ -1641,10 -1739,10 +1742,10 @@@ sub main_loop [ 'help', \&help_cmd, ], ); while (1) { - my ($it) = list_and_choose({ PROMPT => 'What now', + my ($it) = list_and_choose({ PROMPT => __('What now'), SINGLETON => 1, LIST_FLAT => 4, - HEADER => '*** Commands ***', + HEADER => __('*** Commands ***'), ON_EOF => \&quit_cmd, IMMEDIATE => 1 }, @cmd); if ($it) { @@@ -1660,7 -1758,7 +1761,7 @@@ process_args(); refresh(); - if ($patch_mode) { + if ($cmd) { patch_update_cmd(); } else { diff --combined git-difftool.perl index 959822d5f3,8d3632e556..674828de39 --- a/git-difftool.perl +++ b/git-difftool.perl @@@ -22,6 -22,7 +22,7 @@@ use File::Path qw(mkpath rmtree) use File::Temp qw(tempdir); use Getopt::Long qw(:config pass_through); use Git; + use Git::I18N; sub usage { @@@ -122,7 -123,7 +123,7 @@@ sub setup_dir_dif my $i = 0; while ($i < $#rawdiff) { if ($rawdiff[$i] =~ /^::/) { - warn << 'EOF'; + warn __ <<'EOF'; Combined diff formats ('-c' and '--cc') are not supported in directory diff mode ('-d' and '--dir-diff'). EOF @@@ -182,10 -183,6 +183,10 @@@ } } + # Go to the root of the worktree so that the left index files + # are properly setup -- the index is toplevel-relative. + chdir($workdir); + # Setup temp directories my $tmpdir = tempdir('git-difftool.XXXXX', CLEANUP => 0, TMPDIR => 1); my $ldir = "$tmpdir/left"; @@@ -342,7 -339,7 +343,7 @@@ sub mai if (length($opts{difftool_cmd}) > 0) { $ENV{GIT_DIFF_TOOL} = $opts{difftool_cmd}; } else { - print "No given for --tool=\n"; + print __("No given for --tool=\n"); usage(1); } } @@@ -350,7 -347,7 +351,7 @@@ if (length($opts{extcmd}) > 0) { $ENV{GIT_DIFFTOOL_EXTCMD} = $opts{extcmd}; } else { - print "No given for --extcmd=\n"; + print __("No given for --extcmd=\n"); usage(1); } } @@@ -423,11 -420,11 +424,11 @@@ sub dir_dif } if (exists $wt_modified{$file} and exists $tmp_modified{$file}) { - my $errmsg = "warning: Both files modified: "; - $errmsg .= "'$workdir/$file' and '$b/$file'.\n"; - $errmsg .= "warning: Working tree file has been left.\n"; - $errmsg .= "warning:\n"; - warn $errmsg; + warn sprintf(__( + "warning: Both files modified:\n" . + "'%s/%s' and '%s/%s'.\n" . + "warning: Working tree file has been left.\n" . + "warning:\n"), $workdir, $file, $b, $file); $error = 1; } elsif (exists $tmp_modified{$file}) { my $mode = stat("$b/$file")->mode; @@@ -439,8 -436,9 +440,9 @@@ } } if ($error) { - warn "warning: Temporary files exist in '$tmpdir'.\n"; - warn "warning: You may want to cleanup or recover these.\n"; + warn sprintf(__( + "warning: Temporary files exist in '%s'.\n" . + "warning: You may want to cleanup or recover these.\n"), $tmpdir); exit(1); } else { exit_cleanup($tmpdir, $rc); diff --combined perl/Git.pm index b2732822af,f699fee9a1..bfce1f795d --- a/perl/Git.pm +++ b/perl/Git.pm @@@ -59,7 -59,7 +59,7 @@@ require Exporter command_bidi_pipe command_close_bidi_pipe version exec_path html_path hash_object git_cmd_try remote_refs prompt - get_tz_offset + get_tz_offset get_record credential credential_read credential_write temp_acquire temp_is_locked temp_release temp_reset temp_path); @@@ -538,20 -538,6 +538,20 @@@ sub get_tz_offset return sprintf("%s%02d%02d", $sign, (gmtime(abs($t - $gm)))[2,1]); } +=item get_record ( FILEHANDLE, INPUT_RECORD_SEPARATOR ) + +Read one record from FILEHANDLE delimited by INPUT_RECORD_SEPARATOR, +removing any trailing INPUT_RECORD_SEPARATOR. + +=cut + +sub get_record { + my ($fh, $rs) = @_; + local $/ = $rs; + my $rec = <$fh>; + chomp $rec if defined $rs; + $rec; +} =item prompt ( PROMPT , ISPASSWORD ) @@@ -885,8 -871,6 +885,8 @@@ Return an array of mailboxes extracted =cut +# Very close to Mail::Address's parser, but we still have minor +# differences in some cases (see t9000 for examples). sub parse_mailboxes { my $re_comment = qr/\((?:[^)]*)\)/; my $re_quote = qr/"(?:[^\"\\]|\\.)*"/; @@@ -895,7 -879,6 +895,7 @@@ # divide the string in tokens of the above form my $re_token = qr/(?:$re_quote|$re_word|$re_comment|\S)/; my @tokens = map { $_ =~ /\s*($re_token)\s*/g } @_; + my $end_of_addr_seen = 0; # add a delimiter to simplify treatment for the last mailbox push @tokens, ","; @@@ -905,10 -888,10 +905,10 @@@ if ($token =~ /^[,;]$/) { # if buffer still contains undeterminated strings # append it at the end of @address or @phrase - if (@address) { - push @address, @buffer; - } else { + if ($end_of_addr_seen) { push @phrase, @buffer; + } else { + push @address, @buffer; } my $str_phrase = join ' ', @phrase; @@@ -932,16 -915,16 +932,16 @@@ push @addr_list, $str_mailbox if ($str_mailbox); @phrase = @address = @comment = @buffer = (); + $end_of_addr_seen = 0; } elsif ($token =~ /^\(/) { push @comment, $token; } elsif ($token eq "<") { push @phrase, (splice @address), (splice @buffer); } elsif ($token eq ">") { + $end_of_addr_seen = 1; push @address, (splice @buffer); - } elsif ($token eq "@") { + } elsif ($token eq "@" && !$end_of_addr_seen) { push @address, (splice @buffer), "@"; - } elsif ($token eq ".") { - push @address, (splice @buffer), "."; } else { push @buffer, $token; } @@@ -1438,6 -1421,44 +1438,44 @@@ sub END } # %TEMP_* Lexical Context + =item prefix_lines ( PREFIX, STRING [, STRING... ]) + + Prefixes lines in C with C. + + =cut + + sub prefix_lines { + my $prefix = shift; + my $string = join("\n", @_); + $string =~ s/^/$prefix/mg; + return $string; + } + + =item get_comment_line_char ( ) + + Gets the core.commentchar configuration value. + The value falls-back to '#' if core.commentchar is set to 'auto'. + + =cut + + sub get_comment_line_char { + my $comment_line_char = config("core.commentchar") || '#'; + $comment_line_char = '#' if ($comment_line_char eq 'auto'); + $comment_line_char = '#' if (length($comment_line_char) != 1); + return $comment_line_char; + } + + =item comment_lines ( STRING [, STRING... ]) + + Comments lines following core.commentchar configuration. + + =cut + + sub comment_lines { + my $comment_line_char = get_comment_line_char; + return prefix_lines("$comment_line_char ", @_); + } + =back =head1 ERROR HANDLING