diff options
author | Junio C Hamano <gitster@pobox.com> | 2007-12-10 01:22:42 -0800 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2007-12-10 01:22:42 -0800 |
commit | 7be2b6e02b4f2a1b4812764f65b12cafb11a934e (patch) | |
tree | c94ad7eb3a4d478a1c71eb6ef0aaf1c0f7348660 | |
parent | c07a07c588fea82c2426d795a75324b3035c0a71 (diff) | |
parent | 591aa2536fdbc4090ba8d4ca512d4ee7df4bf05d (diff) | |
download | git-7be2b6e02b4f2a1b4812764f65b12cafb11a934e.tar.gz |
Merge branch 'master' into cc/help
This is to primarily pull in MANPATH tweak and help.txt formatting fix
from the master branch.
116 files changed, 5116 insertions, 2054 deletions
diff --git a/.gitignore b/.gitignore index 916fabc6c5..bac60ce31a 100644 --- a/.gitignore +++ b/.gitignore @@ -110,7 +110,6 @@ git-rev-list git-rev-parse git-revert git-rm -git-runstatus git-send-email git-send-pack git-sh-setup @@ -6,6 +6,7 @@ # Aneesh Kumar K.V <aneesh.kumar@gmail.com> +Brian M. Carlson <sandals@crustytoothpaste.ath.cx> Chris Shoemaker <c.shoemaker@cox.net> Dana L. How <danahow@gmail.com> Dana L. How <how@deathvalley.cswitch.com> diff --git a/Documentation/Makefile b/Documentation/Makefile index f0df0b0d28..9f0f9d70f6 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -46,6 +46,9 @@ infodir?=$(prefix)/share/info MAKEINFO=makeinfo INSTALL_INFO=install-info DOCBOOK2X_TEXI=docbook2x-texi +ifndef PERL_PATH + PERL_PATH = /usr/bin/perl +endif -include ../config.mak.autogen -include ../config.mak @@ -80,16 +83,16 @@ man7: $(DOC_MAN7) info: git.info install: man - $(INSTALL) -d -m755 $(DESTDIR)$(man1dir) - $(INSTALL) -d -m755 $(DESTDIR)$(man5dir) - $(INSTALL) -d -m755 $(DESTDIR)$(man7dir) - $(INSTALL) -m644 $(DOC_MAN1) $(DESTDIR)$(man1dir) - $(INSTALL) -m644 $(DOC_MAN5) $(DESTDIR)$(man5dir) - $(INSTALL) -m644 $(DOC_MAN7) $(DESTDIR)$(man7dir) + $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) + $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir) + $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir) + $(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir) + $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir) + $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) install-info: info - $(INSTALL) -d -m755 $(DESTDIR)$(infodir) - $(INSTALL) -m644 git.info $(DESTDIR)$(infodir) + $(INSTALL) -d -m 755 $(DESTDIR)$(infodir) + $(INSTALL) -m 644 git.info $(DESTDIR)$(infodir) if test -r $(DESTDIR)$(infodir)/dir; then \ $(INSTALL_INFO) --info-dir=$(DESTDIR)$(infodir) git.info ;\ else \ @@ -109,7 +112,7 @@ install-html: html # doc.dep : $(wildcard *.txt) build-docdep.perl $(RM) $@+ $@ - perl ./build-docdep.perl >$@+ + $(PERL_PATH) ./build-docdep.perl >$@+ mv $@+ $@ -include doc.dep @@ -128,7 +131,7 @@ $(cmds_txt): cmd-list.made cmd-list.made: cmd-list.perl ../command-list.txt $(MAN1_TXT) $(RM) $@ - perl ./cmd-list.perl ../command-list.txt + $(PERL_PATH) ./cmd-list.perl ../command-list.txt date >$@ git.7 git.html: git.txt @@ -165,7 +168,7 @@ user-manual.html: user-manual.xml git.info: user-manual.xml $(RM) $@ $*.texi $*.texi+ $(DOCBOOK2X_TEXI) user-manual.xml --to-stdout >$*.texi+ - perl fix-texi.perl <$*.texi+ >$*.texi + $(PERL_PATH) fix-texi.perl <$*.texi+ >$*.texi $(MAKEINFO) --no-split $*.texi $(RM) $*.texi $*.texi+ diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt index 44f5043ce7..7386e66dc9 100644 --- a/Documentation/RelNotes-1.5.4.txt +++ b/Documentation/RelNotes-1.5.4.txt @@ -4,7 +4,8 @@ GIT v1.5.4 Release Notes Removal ------- - * "git svnimport" was removed in favor of "git svn". + * "git svnimport" was removed in favor of "git svn". It is still there + in the source tree (contrib/examples) but unsupported. Deprecation notices @@ -48,7 +49,10 @@ Updates since v1.5.3 * Comes with much improved gitk. - * Comes with "git gui" 0.9.0 with i18n. + * Comes with "git gui" 0.9.1 with i18n. + + * gitk is now merged as a subdirectory of git.git project, in + preparation for its i18n. * progress display from many commands are a lot nicer to the eye. Transfer commands show throughput data. @@ -66,6 +70,21 @@ Updates since v1.5.3 pairing. Earlier if more than one identical rename sources were found in the preimage, they were picked pretty much at random. + * Value "true" for color.diff and color.status configuration used to + mean "always" (even when the output is not going to a terminal). + This has been corrected to mean the same thing as "auto". + + * HTTP proxy can be specified per remote repository using + remote.*.httpproxy configuration, or global http.proxy configuration + variable. + + * Various Perforce importer updates. + + * Example update and post-receive hooks have been improved. + + * Any command that wants to take a commit object name can now use + ":/string" syntax to name a commit. + * "git reset" is now built-in and its output can be squelched with -q. * "git send-email" can optionally talk over ssmtp and use SMTP-AUTH. @@ -77,6 +96,15 @@ Updates since v1.5.3 --skip" without first running "git reset --hard", as the command now runs it for you. + * "git rebase --interactive" mode can now work on detached HEAD. + + * "git rebase" now detaches head during its operation, so after a + successful "git rebase" operation, the reflog entry branch@{1} for + the current branch points at the commit before the rebase was + started. + + * "git rebase -i" also triggers rerere to help your repeated merges. + * "git merge" can call the "post-merge" hook. * "git pack-objects" can optionally run deltification with multiple @@ -97,12 +125,16 @@ Updates since v1.5.3 than the usual one) after the user accumulates too many loose objects. + * "git clean" has been rewritten in C. + * You need to explicitly set clean.requireForce to "false" to allow "git clean" without -f to do any damage (lack of the configuration variable used to mean "do not require -f option to lose untracked files", but we now use the safer default). - * "git clean" has been rewritten in C. + * The kinds of whitespace errors "git diff" and "git apply" notice (and + fix) can be controlled via 'core.whitespace' configuration variable + and 'whitespace' attribute in .gitattributes file. * "git push" learned --dry-run option to show what would happen if a push is run. @@ -114,6 +146,9 @@ Updates since v1.5.3 one-to-one to the remote, and deletes refs from the remote that do not exist anymore in the repository on the pushing side. + * "git push" can remove a corrupt ref at the remote site with the usual + ":ref" refspec. + * "git remote" knows --mirror mode. This is to set up configuration to push into a remote repository to store local branch heads to the same branch on the remote side, and remove branch heads locally removed @@ -122,22 +157,59 @@ Updates since v1.5.3 * "git remote" learned "rm" subcommand. - * "git rebase --interactive" mode can now work on detached HEAD. - * "git cvsserver" can be run via "git shell". + * "git cvsserver" acts more like receive-pack by running post-receive + and post-update hooks. + * "git am" and "git rebase" are far less verbose. * "git pull" learned to pass --[no-]ff option to underlying "git merge". - * Various Perforce importer updates. + * "git pull --rebase" is a different way to integrate what you fetched + into your current branch. + + * "git fast-export" produces datastream that can be fed to fast-import + to reproduce the history recorded in a git repository. + + * "git add -i" takes pathspecs to limit the set of files to work on. + + * "git add -p" is a short-hand to go directly to the selective patch + subcommand in the interactive command loop and to exit when done. + + * "git add -i" UI has been colorized. + + * "git commit --allow-empty" allows you to create a single-parent + commit that records the same tree as its parent, overriding the usual + safety valve. + + * "git commit --amend" can amend a merge that does not change the tree + from its first parent. + + * "git commit" has been rewritten in C. + + * "git stash random-text" does not create a new stash anymore. It was + a UI mistake. Use "git stash save random-text", or "git stash" + (without extra args) for that. + + * "git prune --expire <time>" can exempt young loose objects from + getting pruned. + + * "git branch --contains <commit>" can list branches that are + descendants of a given commit. * "git log" learned --early-output option to help interactive GUI implementations. * "git bisect" learned "skip" action to mark untestable commits. + * "git bisect visualize" learned a shorter synonym "git bisect view". + + * "git bisect visualize" runs "git log" in a non-windowed + environments. It also can be told what command to run (e.g. "git + bisect visualize tig"). + * "git format-patch" learned "format.numbered" configuration variable to automatically turn --numbered option on when more than one commits are formatted. @@ -145,11 +217,6 @@ Updates since v1.5.3 * "git ls-files" learned "--exclude-standard" to use the canned set of exclude files. - * "git rebase" now detaches head during its operation, so after a - successful "git rebase" operation, the reflog entry branch@{1} for - the current branch points at the commit before the rebase was - started. - * "git tag -a -f existing" begins the editor session using the existing annotation message. @@ -163,6 +230,9 @@ Updates since v1.5.3 * "git checkout" from a subdirectory learned to use "../path" to allow checking out a path outside the current directory without cd'ing up. + * "git checkout" from and to detached HEAD leaves a bit more + information in the reflog. + * "git send-email --dry-run" shows full headers for easier diagnosis. * "git merge-ours" is now built-in. @@ -176,19 +246,11 @@ Updates since v1.5.3 descriptive name from From: and Signed-off-by: lines in the commit message. - * "git status" from a subdirectory now shows relative paths which makes - copy-and-pasting for git-checkout/git-add/git-rm easier. - - * "git checkout" from and to detached HEAD leaves a bit more - information in the reflog. - - * "git branch" learned --contains option, to show only branches that - can reach a given commit. - - * Example update and post-receive hooks have been improved. - - * "git push" can remove a corrupt ref at the remote site with the usual - ":ref" refspec. + * "git status" from a subdirectory now shows relative paths, which + makes copy-and-pasting for git-checkout/git-add/git-rm easier. The + traditional behaviour to show the full path relative to the top of + the work tree can be had by setting status.relativepaths + configuration variable to true. * In addition there are quite a few internal clean-ups. Notably @@ -212,8 +274,11 @@ series. * "git svn" talking with the SVN over http will correctly quote branch and project names. + * "git config" did not work correctly on platforms that define + REG_NOMATCH to an even number. + -- exec >/var/tmp/1 -O=v1.5.3.7-966-g6bda21b +O=v1.5.3.7-1148-gcf7e147 echo O=`git describe refs/heads/master` git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 83bf54c7ac..de08d094e3 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -10,7 +10,7 @@ Checklist (and a short version for the impatient): - the first line of the commit message should be a short description and should skip the full stop - if you want your work included in git.git, add a - "Signed-off-by: Your Name <your@email.com>" line to the + "Signed-off-by: Your Name <you@example.com>" line to the commit message (or just use the option "-s" when committing) to confirm that you agree to the Developer's Certificate of Origin diff --git a/Documentation/config.txt b/Documentation/config.txt index 4124ad2970..fabe7f859f 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -295,6 +295,20 @@ core.pager:: The command that git will use to paginate output. Can be overridden with the `GIT_PAGER` environment variable. +core.whitespace:: + A comma separated list of common whitespace problems to + notice. `git diff` will use `color.diff.whitespace` to + highlight them, and `git apply --whitespace=error` will + consider them as errors: ++ +* `trailing-space` treats trailing whitespaces at the end of the line + as an error (enabled by default). +* `space-before-tab` treats a space character that appears immediately + before a tab character in the initial indent part of the line as an + error (enabled by default). +* `indent-with-non-tab` treats a line that is indented with 8 or more + space characters that can be replaced with tab characters. + alias.*:: Command aliases for the gitlink:git[1] command wrapper - e.g. after defining "alias.last = cat-file commit HEAD", the invocation @@ -359,8 +373,8 @@ clean.requireForce:: color.branch:: A boolean to enable/disable color in the output of - gitlink:git-branch[1]. May be set to `true` (or `always`), - `false` (or `never`) or `auto`, in which case colors are used + gitlink:git-branch[1]. May be set to `always`, + `false` (or `never`) or `auto` (or `true`), in which case colors are used only when the output is to a terminal. Defaults to false. color.branch.<slot>:: @@ -378,17 +392,29 @@ second is the background. The position of the attribute, if any, doesn't matter. color.diff:: - When true (or `always`), always use colors in patch. - When false (or `never`), never. When set to `auto`, use - colors only when the output is to the terminal. + When set to `always`, always use colors in patch. + When false (or `never`), never. When set to `true` or `auto`, use + colors only when the output is to the terminal. Defaults to false. color.diff.<slot>:: Use customized color for diff colorization. `<slot>` specifies which part of the patch to use the specified color, and is one of `plain` (context text), `meta` (metainformation), `frag` (hunk header), `old` (removed lines), `new` (added lines), - `commit` (commit headers), or `whitespace` (highlighting dubious - whitespace). The values of these variables may be specified as + `commit` (commit headers), or `whitespace` (highlighting + whitespace errors). The values of these variables may be specified as + in color.branch.<slot>. + +color.interactive:: + When set to `always`, always use colors in `git add --interactive`. + When false (or `never`), never. When set to `true` or `auto`, use + colors only when the output is to the terminal. Defaults to false. + +color.interactive.<slot>:: + Use customized color for `git add --interactive` + output. `<slot>` may be `prompt`, `header`, or `help`, for + three distinct types of normal output from interactive + programs. The values of these variables may be specified as in color.branch.<slot>. color.pager:: @@ -397,8 +423,8 @@ color.pager:: color.status:: A boolean to enable/disable color in the output of - gitlink:git-status[1]. May be set to `true` (or `always`), - `false` (or `never`) or `auto`, in which case colors are used + gitlink:git-status[1]. May be set to `always`, + `false` (or `never`) or `auto` (or `true`), in which case colors are used only when the output is to a terminal. Defaults to false. color.status.<slot>:: @@ -507,7 +533,9 @@ gc.rerereunresolved:: rerere.enabled:: Activate recording of resolved conflicts, so that identical conflict hunks can be resolved automatically, should they - be encountered again. See gitlink:git-rerere[1]. + be encountered again. gitlink:git-rerere[1] command is by + default enabled, but can be disabled by setting this option to + false. gitcvs.enabled:: Whether the CVS server interface is enabled for this repository. @@ -550,6 +578,11 @@ specified as 'gitcvs.<access_method>.<varname>' (where 'access_method' is one of "ext" and "pserver") to make them apply only for the given access method. +http.proxy:: + Override the HTTP proxy, normally configured using the 'http_proxy' + environment variable (see gitlink:curl[1]). This can be overridden + on a per-remote basis; see remote.<name>.proxy + http.sslVerify:: Whether to verify the SSL certificate when fetching or pushing over HTTPS. Can be overridden by the 'GIT_SSL_NO_VERIFY' environment @@ -698,6 +731,11 @@ remote.<name>.url:: The URL of a remote repository. See gitlink:git-fetch[1] or gitlink:git-push[1]. +remote.<name>.proxy:: + For remotes that require curl (http, https and ftp), the URL to + the proxy to use for that remote. Set to the empty string to + disable proxying for that remote. + remote.<name>.fetch:: The default set of "refspec" for gitlink:git-fetch[1]. See gitlink:git-fetch[1]. @@ -738,6 +776,12 @@ showbranch.default:: The default set of branches for gitlink:git-show-branch[1]. See gitlink:git-show-branch[1]. +status.relativePaths:: + By default, gitlink:git-status[1] shows paths relative to the + current directory. Setting this variable to `false` shows paths + relative to the repository root (this was the default for git + prior to v1.5.4). + tar.umask:: This variable can be used to restrict the permission bits of tar archive entries. The default is 0002, which turns off the diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index 9709c35c98..2c3a4c433b 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -83,161 +83,4 @@ Note that 'combined diff' lists only files which were modified from all parents. -Generating patches with -p --------------------------- - -When "git-diff-index", "git-diff-tree", or "git-diff-files" are run -with a '-p' option, or "git diff" without the '--raw' option, they -do not produce the output described above; instead they produce a -patch file. You can customize the creation of such patches via the -GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables. - -What the -p option produces is slightly different from the traditional -diff format. - -1. It is preceded with a "git diff" header, that looks like - this: - - diff --git a/file1 b/file2 -+ -The `a/` and `b/` filenames are the same unless rename/copy is -involved. Especially, even for a creation or a deletion, -`/dev/null` is _not_ used in place of `a/` or `b/` filenames. -+ -When rename/copy is involved, `file1` and `file2` show the -name of the source file of the rename/copy and the name of -the file that rename/copy produces, respectively. - -2. It is followed by one or more extended header lines: - - old mode <mode> - new mode <mode> - deleted file mode <mode> - new file mode <mode> - copy from <path> - copy to <path> - rename from <path> - rename to <path> - similarity index <number> - dissimilarity index <number> - index <hash>..<hash> <mode> - -3. TAB, LF, double quote and backslash characters in pathnames - are represented as `\t`, `\n`, `\"` and `\\`, respectively. - If there is need for such substitution then the whole - pathname is put in double quotes. - -The similarity index is the percentage of unchanged lines, and -the dissimilarity index is the percentage of changed lines. It -is a rounded down integer, followed by a percent sign. The -similarity index value of 100% is thus reserved for two equal -files, while 100% dissimilarity means that no line from the old -file made it into the new one. - - -combined diff format --------------------- - -"git-diff-tree", "git-diff-files" and "git-diff" can take '-c' or -'--cc' option to produce 'combined diff', which looks like this: - ------------- -diff --combined describe.c -index fabadb8,cc95eb0..4866510 ---- a/describe.c -+++ b/describe.c -@@@ -98,20 -98,12 +98,20 @@@ - return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; - } - -- static void describe(char *arg) - -static void describe(struct commit *cmit, int last_one) -++static void describe(char *arg, int last_one) - { - + unsigned char sha1[20]; - + struct commit *cmit; - struct commit_list *list; - static int initialized = 0; - struct commit_name *n; - - + if (get_sha1(arg, sha1) < 0) - + usage(describe_usage); - + cmit = lookup_commit_reference(sha1); - + if (!cmit) - + usage(describe_usage); - + - if (!initialized) { - initialized = 1; - for_each_ref(get_name); ------------- - -1. It is preceded with a "git diff" header, that looks like - this (when '-c' option is used): - - diff --combined file -+ -or like this (when '--cc' option is used): - - diff --c file - -2. It is followed by one or more extended header lines - (this example shows a merge with two parents): - - index <hash>,<hash>..<hash> - mode <mode>,<mode>..<mode> - new file mode <mode> - deleted file mode <mode>,<mode> -+ -The `mode <mode>,<mode>..<mode>` line appears only if at least one of -the <mode> is different from the rest. Extended headers with -information about detected contents movement (renames and -copying detection) are designed to work with diff of two -<tree-ish> and are not used by combined diff format. - -3. It is followed by two-line from-file/to-file header - - --- a/file - +++ b/file -+ -Similar to two-line header for traditional 'unified' diff -format, `/dev/null` is used to signal created or deleted -files. - -4. Chunk header format is modified to prevent people from - accidentally feeding it to `patch -p1`. Combined diff format - was created for review of merge commit changes, and was not - meant for apply. The change is similar to the change in the - extended 'index' header: - - @@@ <from-file-range> <from-file-range> <to-file-range> @@@ -+ -There are (number of parents + 1) `@` characters in the chunk -header for combined diff format. - -Unlike the traditional 'unified' diff format, which shows two -files A and B with a single column that has `-` (minus -- -appears in A but removed in B), `+` (plus -- missing in A but -added to B), or `" "` (space -- unchanged) prefix, this format -compares two or more files file1, file2,... with one file X, and -shows how X differs from each of fileN. One column for each of -fileN is prepended to the output line to note how X's line is -different from it. - -A `-` character in the column N means that the line appears in -fileN but it does not appear in the result. A `+` character -in the column N means that the line appears in the last file, -and fileN does not have that line (in other words, the line was -added, from the point of view of that parent). - -In the above example output, the function signature was changed -from both files (hence two `-` removals from both file1 and -file2, plus `++` to mean one line that was added does not appear -in either file1 nor file2). Also two other lines are the same -from file1 but do not appear in file2 (hence prefixed with ` +`). - -When shown by `git diff-tree -c`, it compares the parents of a -merge commit with the merge result (i.e. file1..fileN are the -parents). When shown by `git diff-files -c`, it compares the -two unresolved merge parents with the working tree file -(i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka -"their version"). +include::diff-generate-patch.txt[] diff --git a/Documentation/diff-generate-patch.txt b/Documentation/diff-generate-patch.txt new file mode 100644 index 0000000000..029c5f2b82 --- /dev/null +++ b/Documentation/diff-generate-patch.txt @@ -0,0 +1,161 @@ +Generating patches with -p +-------------------------- + +When "git-diff-index", "git-diff-tree", or "git-diff-files" are run +with a '-p' option, "git diff" without the '--raw' option, or +"git log" with the "-p" option, they +do not produce the output described above; instead they produce a +patch file. You can customize the creation of such patches via the +GIT_EXTERNAL_DIFF and the GIT_DIFF_OPTS environment variables. + +What the -p option produces is slightly different from the traditional +diff format. + +1. It is preceded with a "git diff" header, that looks like + this: + + diff --git a/file1 b/file2 ++ +The `a/` and `b/` filenames are the same unless rename/copy is +involved. Especially, even for a creation or a deletion, +`/dev/null` is _not_ used in place of `a/` or `b/` filenames. ++ +When rename/copy is involved, `file1` and `file2` show the +name of the source file of the rename/copy and the name of +the file that rename/copy produces, respectively. + +2. It is followed by one or more extended header lines: + + old mode <mode> + new mode <mode> + deleted file mode <mode> + new file mode <mode> + copy from <path> + copy to <path> + rename from <path> + rename to <path> + similarity index <number> + dissimilarity index <number> + index <hash>..<hash> <mode> + +3. TAB, LF, double quote and backslash characters in pathnames + are represented as `\t`, `\n`, `\"` and `\\`, respectively. + If there is need for such substitution then the whole + pathname is put in double quotes. + +The similarity index is the percentage of unchanged lines, and +the dissimilarity index is the percentage of changed lines. It +is a rounded down integer, followed by a percent sign. The +similarity index value of 100% is thus reserved for two equal +files, while 100% dissimilarity means that no line from the old +file made it into the new one. + + +combined diff format +-------------------- + +"git-diff-tree", "git-diff-files" and "git-diff" can take '-c' or +'--cc' option to produce 'combined diff'. For showing a merge commit +with "git log -p", this is the default format. +A 'combined diff' format looks like this: + +------------ +diff --combined describe.c +index fabadb8,cc95eb0..4866510 +--- a/describe.c ++++ b/describe.c +@@@ -98,20 -98,12 +98,20 @@@ + return (a_date > b_date) ? -1 : (a_date == b_date) ? 0 : 1; + } + +- static void describe(char *arg) + -static void describe(struct commit *cmit, int last_one) +++static void describe(char *arg, int last_one) + { + + unsigned char sha1[20]; + + struct commit *cmit; + struct commit_list *list; + static int initialized = 0; + struct commit_name *n; + + + if (get_sha1(arg, sha1) < 0) + + usage(describe_usage); + + cmit = lookup_commit_reference(sha1); + + if (!cmit) + + usage(describe_usage); + + + if (!initialized) { + initialized = 1; + for_each_ref(get_name); +------------ + +1. It is preceded with a "git diff" header, that looks like + this (when '-c' option is used): + + diff --combined file ++ +or like this (when '--cc' option is used): + + diff --c file + +2. It is followed by one or more extended header lines + (this example shows a merge with two parents): + + index <hash>,<hash>..<hash> + mode <mode>,<mode>..<mode> + new file mode <mode> + deleted file mode <mode>,<mode> ++ +The `mode <mode>,<mode>..<mode>` line appears only if at least one of +the <mode> is different from the rest. Extended headers with +information about detected contents movement (renames and +copying detection) are designed to work with diff of two +<tree-ish> and are not used by combined diff format. + +3. It is followed by two-line from-file/to-file header + + --- a/file + +++ b/file ++ +Similar to two-line header for traditional 'unified' diff +format, `/dev/null` is used to signal created or deleted +files. + +4. Chunk header format is modified to prevent people from + accidentally feeding it to `patch -p1`. Combined diff format + was created for review of merge commit changes, and was not + meant for apply. The change is similar to the change in the + extended 'index' header: + + @@@ <from-file-range> <from-file-range> <to-file-range> @@@ ++ +There are (number of parents + 1) `@` characters in the chunk +header for combined diff format. + +Unlike the traditional 'unified' diff format, which shows two +files A and B with a single column that has `-` (minus -- +appears in A but removed in B), `+` (plus -- missing in A but +added to B), or `" "` (space -- unchanged) prefix, this format +compares two or more files file1, file2,... with one file X, and +shows how X differs from each of fileN. One column for each of +fileN is prepended to the output line to note how X's line is +different from it. + +A `-` character in the column N means that the line appears in +fileN but it does not appear in the result. A `+` character +in the column N means that the line appears in the last file, +and fileN does not have that line (in other words, the line was +added, from the point of view of that parent). + +In the above example output, the function signature was changed +from both files (hence two `-` removals from both file1 and +file2, plus `++` to mean one line that was added does not appear +in either file1 nor file2). Also two other lines are the same +from file1 but do not appear in file2 (hence prefixed with ` +`). + +When shown by `git diff-tree -c`, it compares the parents of a +merge commit with the merge result (i.e. file1..fileN are the +parents). When shown by `git diff-files -c`, it compares the +two unresolved merge parents with the working tree file +(i.e. file1 is stage 2 aka "our version", file2 is stage 3 aka +"their version"). diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index e4af393515..d0154bbc0a 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -6,7 +6,9 @@ ifndef::git-format-patch[] ifndef::git-diff[] +ifndef::git-log[] :git-diff-core: 1 +endif::git-log[] endif::git-diff[] endif::git-format-patch[] diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index 63829d93cc..bf94cd43bd 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -8,7 +8,7 @@ git-add - Add file contents to the index SYNOPSIS -------- [verse] -'git-add' [-n] [-v] [-f] [--interactive | -i] [-u] [--refresh] +'git-add' [-n] [-v] [-f] [--interactive | -i] [--patch | -p] [-u] [--refresh] [--] <filepattern>... DESCRIPTION @@ -61,7 +61,14 @@ OPTIONS -i, \--interactive:: Add modified contents in the working tree interactively to - the index. + the index. Optional path arguments may be supplied to limit + operation to a subset of the working tree. See ``Interactive + mode'' for details. + +-p, \--patch: + Similar to Interactive mode but the initial command loop is + bypassed and the 'patch' subcommand is invoked using each of + the specified filepatterns before exiting. -u:: Update only files that git already knows about. This is similar @@ -210,6 +217,8 @@ patch:: k - do not decide on this hunk now, and view the previous undecided hunk K - do not decide on this hunk now, and view the previous hunk + s - split the current hunk into smaller hunks + ? - print help + After deciding the fate for all hunks, if there is any hunk that was chosen, the index is updated with the selected hunks. diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt index c1c54bfe0b..bae3e7b909 100644 --- a/Documentation/git-apply.txt +++ b/Documentation/git-apply.txt @@ -13,7 +13,7 @@ SYNOPSIS [--apply] [--no-add] [--build-fake-ancestor <file>] [-R | --reverse] [--allow-binary-replacement | --binary] [--reject] [-z] [-pNUM] [-CNUM] [--inaccurate-eof] [--cached] - [--whitespace=<nowarn|warn|error|error-all|strip>] + [--whitespace=<nowarn|warn|fix|error|error-all>] [--exclude=PATH] [--verbose] [<patch>...] DESCRIPTION @@ -135,25 +135,32 @@ discouraged. be useful when importing patchsets, where you want to exclude certain files or directories. ---whitespace=<option>:: - When applying a patch, detect a new or modified line - that ends with trailing whitespaces (this includes a - line that solely consists of whitespaces). By default, - the command outputs warning messages and applies the - patch. - When gitlink:git-apply[1] is used for statistics and not applying a - patch, it defaults to `nowarn`. - You can use different `<option>` to control this - behavior: +--whitespace=<action>:: + When applying a patch, detect a new or modified line that has + whitespace errors. What are considered whitespace errors is + controlled by `core.whitespace` configuration. By default, + trailing whitespaces (including lines that solely consist of + whitespaces) and a space character that is immediately followed + by a tab character inside the initial indent of the line are + considered whitespace errors. ++ +By default, the command outputs warning messages but applies the patch. +When gitlink:git-apply[1] is used for statistics and not applying a +patch, it defaults to `nowarn`. ++ +You can use different `<action>` to control this +behavior: + * `nowarn` turns off the trailing whitespace warning. * `warn` outputs warnings for a few such errors, but applies the - patch (default). + patch as-is (default). +* `fix` outputs warnings for a few such errors, and applies the + patch after fixing them (`strip` is a synonym --- the tool + used to consider only trailing whitespaces as errors, and the + fix involved 'stripping' them, but modern gits do more). * `error` outputs warnings for a few such errors, and refuses to apply the patch. * `error-all` is similar to `error` but shows all errors. -* `strip` outputs warnings for a few such errors, strips out the - trailing whitespaces and applies the patch. --inaccurate-eof:: Under certain circumstances, some versions of diff do not correctly diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt index 4795349c10..8b9d61a8a4 100644 --- a/Documentation/git-bisect.txt +++ b/Documentation/git-bisect.txt @@ -92,7 +92,16 @@ During the bisection process, you can say $ git bisect visualize ------------ -to see the currently remaining suspects in `gitk`. +to see the currently remaining suspects in `gitk`. `visualize` is a bit +too long to type and `view` is provided as a synonym. + +If `DISPLAY` environment variable is not set, `git log` is used +instead. You can even give command line options such as `-p` and +`--stat`. + +------------ +$ git bisect view --stat +------------ Bisect log and bisect replay ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 4bb2791550..4261384158 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -86,7 +86,7 @@ OPTIONS Add Signed-off-by line at the end of the commit message. --no-verify:: - This option bypasses the pre-commit hook. + This option bypasses the pre-commit and commit-msg hooks. See also link:hooks.html[hooks]. --allow-empty:: diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 7640450787..98509b4f44 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -21,6 +21,7 @@ SYNOPSIS 'git-config' [<file-option>] --remove-section name 'git-config' [<file-option>] [-z|--null] -l | --list 'git-config' [<file-option>] --get-color name [default] +'git-config' [<file-option>] --get-colorbool name [stdout-is-tty] DESCRIPTION ----------- @@ -135,6 +136,15 @@ See also <<FILES>>. output without getting confused e.g. by values that contain line breaks. +--get-colorbool name [stdout-is-tty]:: + + Find the color setting for `name` (e.g. `color.diff`) and output + "true" or "false". `stdout-is-tty` should be either "true" or + "false", and is taken into account when configuration says + "auto". If `stdout-is-tty` is missing, then checks the standard + output of the command itself, and exits with status 0 if color + is to be used, or exits with status 1 otherwise. + --get-color name default:: Find the color configured for `name` (e.g. `color.diff.new`) and diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index 073ff7f123..fd3d571464 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -26,14 +26,14 @@ OPTIONS Insert 'progress' statements every <n> objects, to be shown by gitlink:git-fast-import[1] during import. ---signed-tags=(ignore|warn|strip|abort):: +--signed-tags=(verbatim|warn|strip|abort):: Specify how to handle signed tags. Since any transformation after the export can change the tag names (which can also happen when excluding revisions) the signatures will not match. + When asking to 'abort' (which is the default), this program will die when encountering a signed tag. With 'strip', the tags will be made -unsigned, with 'ignore', they will be silently ignored (i.e. not exported) +unsigned, with 'verbatim', they will be silently exported and with 'warn', they will be exported, but you will see a warning. diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index 0e873fde28..ac9e15d774 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -1,5 +1,5 @@ git-help(1) -====== +=========== NAME ---- diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 5ec547cc0c..5920d1799a 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -27,6 +27,9 @@ OPTIONS include::pretty-options.txt[] +:git-log: 1 +include::diff-options.txt[] + -<n>:: Limits the number of commits to show. @@ -43,9 +46,6 @@ include::pretty-options.txt[] commit. This option gives a better overview of the evolution of a particular branch. --p:: - Show the change the commit introduces in a patch form. - -g, \--walk-reflogs:: Show commits as they were recorded in the reflog. The log contains a record about how the tip of a reference was changed. @@ -78,6 +78,7 @@ include::pretty-options.txt[] include::pretty-formats.txt[] +include::diff-generate-patch.txt[] Examples -------- diff --git a/Documentation/git-rerere.txt b/Documentation/git-rerere.txt index c4d4263238..8ce492c8f2 100644 --- a/Documentation/git-rerere.txt +++ b/Documentation/git-rerere.txt @@ -22,10 +22,6 @@ automerge results and corresponding hand-resolve results on the initial manual merge, and later by noticing the same automerge results and applying the previously recorded hand resolution. -[NOTE] -You need to set the config variable rerere.enabled to enable this -command. - COMMANDS -------- diff --git a/Documentation/git-send-pack.txt b/Documentation/git-send-pack.txt index 2fa01d4a3c..a2d9cb61be 100644 --- a/Documentation/git-send-pack.txt +++ b/Documentation/git-send-pack.txt @@ -85,7 +85,9 @@ Each pattern pair consists of the source side (before the colon) and the destination side (after the colon). The ref to be pushed is determined by finding a match that matches the source side, and where it is pushed is determined by using the -destination side. +destination side. The rules used to match a ref are the same +rules used by gitlink:git-rev-parse[1] to resolve a symbolic ref +name. - It is an error if <src> does not match exactly one of the local refs. diff --git a/Documentation/git-status.txt b/Documentation/git-status.txt index 8fd0fc6236..5c5a480ec4 100644 --- a/Documentation/git-status.txt +++ b/Documentation/git-status.txt @@ -12,33 +12,32 @@ SYNOPSIS DESCRIPTION ----------- -Examines paths in the working tree that has changes unrecorded -to the index file, and changes between the index file and the -current HEAD commit. The former paths are what you _could_ -commit by running 'git add' before running 'git -commit', and the latter paths are what you _would_ commit by -running 'git commit'. - -If there is no path that is different between the index file and -the current HEAD commit, the command exits with non-zero -status. +Displays paths that have differences between the index file and the +current HEAD commit, paths that have differences between the working +tree and the index file, and paths in the working tree that are not +tracked by git (and are not ignored by gitlink:gitignore[5]). The first +are what you _would_ commit by running `git commit`; the second and +third are what you _could_ commit by running `git add` before running +`git commit`. The command takes the same set of options as `git-commit`; it shows what would be committed if the same options are given to `git-commit`. -If any paths have been touched in the working tree (that is, -their modification times have changed) but their contents and -permissions are identical to those in the index file, the command -updates the index file. Running `git-status` can thus speed up -subsequent operations such as `git-diff` if the working tree -contains many paths that have been touched but not modified. +If there is no path that is different between the index file and +the current HEAD commit (i.e., there is nothing to commit by running +`git-commit`), the command exits with non-zero status. OUTPUT ------ The output from this command is designed to be used as a commit -template comments, and all the output lines are prefixed with '#'. +template comment, and all the output lines are prefixed with '#'. + +The paths mentioned in the output, unlike many other git commands, are +made relative to the current directory if you are working in a +subdirectory (this is on purpose, to help cutting and pasting). See +the status.relativePaths config option below. CONFIGURATION @@ -49,6 +48,10 @@ mean the same thing and the latter is kept for backward compatibility) and `color.status.<slot>` configuration variables to colorize its output. +If the config variable `status.relativePaths` is set to false, then all +paths shown are relative to the repository root, not to the current +directory. + See Also -------- gitlink:gitignore[5] diff --git a/Documentation/git.txt b/Documentation/git.txt index c4e4d24ea4..a29b634e7a 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -541,7 +541,7 @@ Authors ------- * git's founding father is Linus Torvalds <torvalds@osdl.org>. * The current git nurse is Junio C Hamano <gitster@pobox.com>. -* The git potty was written by Andres Ericsson <ae@op5.se>. +* The git potty was written by Andreas Ericsson <ae@op5.se>. * General upbringing is handled by the git-list <git@vger.kernel.org>. Documentation diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 19bd25f299..71c7ad76d5 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -361,6 +361,37 @@ When left unspecified, the driver itself is used for both internal merge and the final merge. +Checking whitespace errors +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`whitespace` +^^^^^^^^^^^^ + +The `core.whitespace` configuration variable allows you to define what +`diff` and `apply` should consider whitespace errors for all paths in +the project (See gitlink:git-config[1]). This attribute gives you finer +control per path. + +Set:: + + Notice all types of potential whitespace errors known to git. + +Unset:: + + Do not notice anything as error. + +Unspecified:: + + Use the value of `core.whitespace` configuration variable to + decide what to notice as error. + +String:: + + Specify a comma separate list of common whitespace problems to + notice in the same format as `core.whitespace` configuration + variable. + + EXAMPLE ------- @@ -154,6 +154,7 @@ STRIP ?= strip prefix = $(HOME) bindir = $(prefix)/bin +mandir = $(prefix)/share/man gitexecdir = $(bindir) sharedir = $(prefix)/share template_dir = $(sharedir)/git-core/templates @@ -214,7 +215,7 @@ BASIC_LDFLAGS = SCRIPT_SH = \ git-bisect.sh git-checkout.sh \ - git-clone.sh git-commit.sh \ + git-clone.sh \ git-merge-one-file.sh git-mergetool.sh git-parse-remote.sh \ git-pull.sh git-rebase.sh git-rebase--interactive.sh \ git-repack.sh git-request-pull.sh \ @@ -235,7 +236,7 @@ SCRIPT_PERL = \ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) \ $(patsubst %.perl,%,$(SCRIPT_PERL)) \ - git-status git-instaweb + git-instaweb # ... and all the rest that could be moved out of bindir to gitexecdir PROGRAMS = \ @@ -261,7 +262,7 @@ EXTRA_PROGRAMS = BUILT_INS = \ git-format-patch$X git-show$X git-whatchanged$X git-cherry$X \ git-get-tar-commit-id$X git-init$X git-repo-config$X \ - git-fsck-objects$X git-cherry-pick$X git-peek-remote$X \ + git-fsck-objects$X git-cherry-pick$X git-peek-remote$X git-status$X \ $(patsubst builtin-%.o,git-%$X,$(BUILTIN_OBJS)) # what 'all' will build and 'install' will install, in gitexecdir @@ -314,7 +315,7 @@ LIB_OBJS = \ alloc.o merge-file.o path-list.o help.o unpack-trees.o $(DIFF_OBJS) \ color.o wt-status.o archive-zip.o archive-tar.o shallow.o utf8.o \ convert.o attr.o decorate.o progress.o mailmap.o symlinks.o remote.o \ - transport.o bundle.o walker.o parse-options.o + transport.o bundle.o walker.o parse-options.o ws.o BUILTIN_OBJS = \ builtin-add.o \ @@ -329,6 +330,7 @@ BUILTIN_OBJS = \ builtin-checkout-index.o \ builtin-check-ref-format.o \ builtin-clean.o \ + builtin-commit.o \ builtin-commit-tree.o \ builtin-count-objects.o \ builtin-describe.o \ @@ -371,7 +373,6 @@ BUILTIN_OBJS = \ builtin-rev-parse.o \ builtin-revert.o \ builtin-rm.o \ - builtin-runstatus.o \ builtin-shortlog.o \ builtin-show-branch.o \ builtin-stripspace.o \ @@ -408,7 +409,9 @@ endif ifeq ($(uname_S),Darwin) NEEDS_SSL_WITH_CRYPTO = YesPlease NEEDS_LIBICONV = YesPlease - OLD_ICONV = UnfortunatelyYes + ifneq ($(shell expr "$(uname_R)" : '9\.'),2) + OLD_ICONV = UnfortunatelyYes + endif NO_STRLCPY = YesPlease NO_MEMMEM = YesPlease endif @@ -446,6 +449,7 @@ ifeq ($(uname_O),Cygwin) NEEDS_LIBICONV = YesPlease NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes NO_TRUSTABLE_FILEMODE = UnfortunatelyYes + OLD_ICONV = UnfortunatelyYes # There are conflicting reports about this. # On some boxes NO_MMAP is needed, and not so elsewhere. # Try commenting this out if you suspect MMAP is more efficient @@ -745,6 +749,7 @@ ETC_GITCONFIG_SQ = $(subst ','\'',$(ETC_GITCONFIG)) DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) bindir_SQ = $(subst ','\'',$(bindir)) +mandir_SQ = $(subst ','\'',$(mandir)) gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) template_dir_SQ = $(subst ','\'',$(template_dir)) htmldir_SQ = $(subst ','\'',$(htmldir)) @@ -792,7 +797,8 @@ git$X: git.o $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ $(BUILTIN_OBJS) $(ALL_LDFLAGS) $(LIBS) -help.o: common-cmds.h +help.o: help.c common-cmds.h GIT-CFLAGS + $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) '-DGIT_MAN_PATH="$(mandir_SQ)"' $< git-merge-subtree$X: git-merge-recursive$X $(QUIET_BUILT_IN)$(RM) $@ && ln git-merge-recursive$X $@ @@ -837,9 +843,6 @@ $(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl chmod +x $@+ && \ mv $@+ $@ -git-status: git-commit - $(QUIET_GEN)cp $< $@+ && mv $@+ $@ - gitweb/gitweb.cgi: gitweb/gitweb.perl $(QUIET_GEN)$(RM) $@ $@+ && \ sed -e '1s|#!.*perl|#!$(PERL_PATH_SQ)|' \ @@ -1021,8 +1024,8 @@ remove-dashes: ### Installation rules install: all - $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(bindir_SQ)' - $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(gitexecdir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) $(ALL_PROGRAMS) '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) git$X '$(DESTDIR_SQ)$(bindir_SQ)' $(MAKE) -C templates DESTDIR='$(DESTDIR_SQ)' install diff --git a/builtin-add.c b/builtin-add.c index cf815a0b8e..5c29cc2f3f 100644 --- a/builtin-add.c +++ b/builtin-add.c @@ -19,7 +19,7 @@ static const char * const builtin_add_usage[] = { "git-add [options] [--] <filepattern>...", NULL }; - +static int patch_interactive = 0, add_interactive = 0; static int take_worktree_changes; static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix) @@ -105,12 +105,12 @@ static void update_callback(struct diff_queue_struct *q, } } -void add_files_to_cache(int verbose, const char *prefix, const char **files) +void add_files_to_cache(int verbose, const char *prefix, const char **pathspec) { struct rev_info rev; init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); - rev.prune_data = get_pathspec(prefix, files); + rev.prune_data = pathspec; rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = update_callback; rev.diffopt.format_callback_data = &verbose; @@ -135,11 +135,40 @@ static void refresh(int verbose, const char **pathspec) free(seen); } -int interactive_add(void) +static const char **validate_pathspec(int argc, const char **argv, const char *prefix) { - const char *argv[2] = { "add--interactive", NULL }; + const char **pathspec = get_pathspec(prefix, argv); - return run_command_v_opt(argv, RUN_GIT_CMD); + return pathspec; +} + +int interactive_add(int argc, const char **argv, const char *prefix) +{ + int status, ac; + const char **args; + const char **pathspec = NULL; + + if (argc) { + pathspec = validate_pathspec(argc, argv, prefix); + if (!pathspec) + return -1; + } + + args = xcalloc(sizeof(const char *), (argc + 4)); + ac = 0; + args[ac++] = "add--interactive"; + if (patch_interactive) + args[ac++] = "--patch"; + args[ac++] = "--"; + if (argc) { + memcpy(&(args[ac]), pathspec, sizeof(const char *) * argc); + ac += argc; + } + args[ac] = NULL; + + status = run_command_v_opt(args, RUN_GIT_CMD); + free(args); + return status; } static struct lock_file lock_file; @@ -148,13 +177,13 @@ static const char ignore_error[] = "The following paths are ignored by one of your .gitignore files:\n"; static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0; -static int add_interactive = 0; static struct option builtin_add_options[] = { OPT__DRY_RUN(&show_only), OPT__VERBOSE(&verbose), OPT_GROUP(""), OPT_BOOLEAN('i', "interactive", &add_interactive, "interactive picking"), + OPT_BOOLEAN('p', "patch", &patch_interactive, "interactive patching"), OPT_BOOLEAN('f', NULL, &ignored_too, "allow adding otherwise ignored files"), OPT_BOOLEAN('u', NULL, &take_worktree_changes, "update tracked files"), OPT_BOOLEAN( 0 , "refresh", &refresh_only, "don't add, only refresh the index"), @@ -163,26 +192,27 @@ static struct option builtin_add_options[] = { int cmd_add(int argc, const char **argv, const char *prefix) { - int i, newfd, orig_argc = argc; + int i, newfd; const char **pathspec; struct dir_struct dir; argc = parse_options(argc, argv, builtin_add_options, builtin_add_usage, 0); - if (add_interactive) { - if (add_interactive != 1 || orig_argc != 2) - die("add --interactive does not take any parameters"); - exit(interactive_add()); - } + if (patch_interactive) + add_interactive = 1; + if (add_interactive) + exit(interactive_add(argc, argv, prefix)); git_config(git_default_config); newfd = hold_locked_index(&lock_file, 1); if (take_worktree_changes) { + const char **pathspec; if (read_cache() < 0) die("index file corrupt"); - add_files_to_cache(verbose, prefix, argv); + pathspec = get_pathspec(prefix, argv); + add_files_to_cache(verbose, prefix, pathspec); goto finish; } diff --git a/builtin-apply.c b/builtin-apply.c index 91f8752ff7..f2e9a332ca 100644 --- a/builtin-apply.c +++ b/builtin-apply.c @@ -45,14 +45,14 @@ static const char *fake_ancestor; static int line_termination = '\n'; static unsigned long p_context = ULONG_MAX; static const char apply_usage[] = -"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|error|error-all|strip>] <patch>..."; - -static enum whitespace_eol { - nowarn_whitespace, - warn_on_whitespace, - error_on_whitespace, - strip_whitespace, -} new_whitespace = warn_on_whitespace; +"git-apply [--stat] [--numstat] [--summary] [--check] [--index] [--cached] [--apply] [--no-add] [--index-info] [--allow-binary-replacement] [--reverse] [--reject] [--verbose] [-z] [-pNUM] [-CNUM] [--whitespace=<nowarn|warn|fix|error|error-all>] <patch>..."; + +static enum ws_error_action { + nowarn_ws_error, + warn_on_ws_error, + die_on_ws_error, + correct_ws_error, +} ws_error_action = warn_on_ws_error; static int whitespace_error; static int squelch_whitespace_errors = 5; static int applied_after_fixing_ws; @@ -61,28 +61,28 @@ static const char *patch_input_file; static void parse_whitespace_option(const char *option) { if (!option) { - new_whitespace = warn_on_whitespace; + ws_error_action = warn_on_ws_error; return; } if (!strcmp(option, "warn")) { - new_whitespace = warn_on_whitespace; + ws_error_action = warn_on_ws_error; return; } if (!strcmp(option, "nowarn")) { - new_whitespace = nowarn_whitespace; + ws_error_action = nowarn_ws_error; return; } if (!strcmp(option, "error")) { - new_whitespace = error_on_whitespace; + ws_error_action = die_on_ws_error; return; } if (!strcmp(option, "error-all")) { - new_whitespace = error_on_whitespace; + ws_error_action = die_on_ws_error; squelch_whitespace_errors = 0; return; } - if (!strcmp(option, "strip")) { - new_whitespace = strip_whitespace; + if (!strcmp(option, "strip") || !strcmp(option, "fix")) { + ws_error_action = correct_ws_error; return; } die("unrecognized whitespace option '%s'", option); @@ -90,11 +90,8 @@ static void parse_whitespace_option(const char *option) static void set_default_whitespace_mode(const char *whitespace_option) { - if (!whitespace_option && !apply_default_whitespace) { - new_whitespace = (apply - ? warn_on_whitespace - : nowarn_whitespace); - } + if (!whitespace_option && !apply_default_whitespace) + ws_error_action = (apply ? warn_on_ws_error : nowarn_ws_error); } /* @@ -137,11 +134,17 @@ struct fragment { #define BINARY_DELTA_DEFLATED 1 #define BINARY_LITERAL_DEFLATED 2 +/* + * This represents a "patch" to a file, both metainfo changes + * such as creation/deletion, filemode and content changes represented + * as a series of fragments. + */ struct patch { char *new_name, *old_name, *def_name; unsigned int old_mode, new_mode; int is_new, is_delete; /* -1 = unknown, 0 = false, 1 = true */ int rejected; + unsigned ws_rule; unsigned long deflate_origlen; int lines_added, lines_deleted; int score; @@ -158,7 +161,8 @@ struct patch { struct patch *next; }; -static void say_patch_name(FILE *output, const char *pre, struct patch *patch, const char *post) +static void say_patch_name(FILE *output, const char *pre, + struct patch *patch, const char *post) { fputs(pre, output); if (patch->old_name && patch->new_name && @@ -229,7 +233,8 @@ static char *find_name(const char *line, char *def, int p_value, int terminate) if (*line == '"') { struct strbuf name; - /* Proposed "new-style" GNU patch/diff format; see + /* + * Proposed "new-style" GNU patch/diff format; see * http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 */ strbuf_init(&name, 0); @@ -499,7 +504,8 @@ static int gitdiff_dissimilarity(const char *line, struct patch *patch) static int gitdiff_index(const char *line, struct patch *patch) { - /* index line is N hexadecimal, "..", N hexadecimal, + /* + * index line is N hexadecimal, "..", N hexadecimal, * and optional space with octal mode. */ const char *ptr, *eol; @@ -550,7 +556,8 @@ static const char *stop_at_slash(const char *line, int llen) return NULL; } -/* This is to extract the same name that appears on "diff --git" +/* + * This is to extract the same name that appears on "diff --git" * line. We do not find and return anything if it is a rename * patch, and it is OK because we will find the name elsewhere. * We need to reliably find name only when it is mode-change only, @@ -584,7 +591,8 @@ static char *git_header_name(char *line, int llen) goto free_and_fail1; strbuf_remove(&first, 0, cp + 1 - first.buf); - /* second points at one past closing dq of name. + /* + * second points at one past closing dq of name. * find the second name. */ while ((second < line + llen) && isspace(*second)) @@ -627,7 +635,8 @@ static char *git_header_name(char *line, int llen) return NULL; name++; - /* since the first name is unquoted, a dq if exists must be + /* + * since the first name is unquoted, a dq if exists must be * the beginning of the second name. */ for (second = name; second < line + llen; second++) { @@ -758,7 +767,7 @@ static int parse_num(const char *line, unsigned long *p) } static int parse_range(const char *line, int len, int offset, const char *expect, - unsigned long *p1, unsigned long *p2) + unsigned long *p1, unsigned long *p2) { int digits, ex; @@ -867,14 +876,14 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc return offset; } - /** --- followed by +++ ? */ + /* --- followed by +++ ? */ if (memcmp("--- ", line, 4) || memcmp("+++ ", line + len, 4)) continue; /* * We only accept unified patches, so we want it to * at least have "@@ -a,b +c,d @@\n", which is 14 chars - * minimum + * minimum ("@@ -0,0 +1 @@\n" is the shortest). */ nextlen = linelen(line + len, size - len); if (size < nextlen + 14 || memcmp("@@ -", line + len + nextlen, 4)) @@ -889,7 +898,7 @@ static int find_header(char *line, unsigned long size, int *hdrsize, struct patc return -1; } -static void check_whitespace(const char *line, int len) +static void check_whitespace(const char *line, int len, unsigned ws_rule) { const char *err = "Adds trailing whitespace"; int seen_space = 0; @@ -901,23 +910,35 @@ static void check_whitespace(const char *line, int len) * this function. That is, an addition of an empty line would * check the '+' here. Sneaky... */ - if (isspace(line[len-2])) + if ((ws_rule & WS_TRAILING_SPACE) && isspace(line[len-2])) goto error; /* * Make sure that there is no space followed by a tab in * indentation. */ - err = "Space in indent is followed by a tab"; - for (i = 1; i < len; i++) { - if (line[i] == '\t') { - if (seen_space) - goto error; - } - else if (line[i] == ' ') - seen_space = 1; - else - break; + if (ws_rule & WS_SPACE_BEFORE_TAB) { + err = "Space in indent is followed by a tab"; + for (i = 1; i < len; i++) { + if (line[i] == '\t') { + if (seen_space) + goto error; + } + else if (line[i] == ' ') + seen_space = 1; + else + break; + } + } + + /* + * Make sure that the indentation does not contain more than + * 8 spaces. + */ + if ((ws_rule & WS_INDENT_WITH_NON_TAB) && + (8 < len) && !strncmp("+ ", line, 9)) { + err = "Indent more than 8 places with spaces"; + goto error; } return; @@ -931,14 +952,14 @@ static void check_whitespace(const char *line, int len) err, patch_input_file, linenr, len-2, line+1); } - /* * Parse a unified diff. Note that this really needs to parse each * fragment separately, since the only way to know the difference * between a "---" that is part of a patch, and a "---" that starts * the next patch is to look at the line counts.. */ -static int parse_fragment(char *line, unsigned long size, struct patch *patch, struct fragment *fragment) +static int parse_fragment(char *line, unsigned long size, + struct patch *patch, struct fragment *fragment) { int added, deleted; int len = linelen(line, size), offset; @@ -979,22 +1000,23 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s break; case '-': if (apply_in_reverse && - new_whitespace != nowarn_whitespace) - check_whitespace(line, len); + ws_error_action != nowarn_ws_error) + check_whitespace(line, len, patch->ws_rule); deleted++; oldlines--; trailing = 0; break; case '+': if (!apply_in_reverse && - new_whitespace != nowarn_whitespace) - check_whitespace(line, len); + ws_error_action != nowarn_ws_error) + check_whitespace(line, len, patch->ws_rule); added++; newlines--; trailing = 0; break; - /* We allow "\ No newline at end of file". Depending + /* + * We allow "\ No newline at end of file". Depending * on locale settings when the patch was produced we * don't know what this line looks like. The only * thing we do know is that it begins with "\ ". @@ -1012,7 +1034,8 @@ static int parse_fragment(char *line, unsigned long size, struct patch *patch, s fragment->leading = leading; fragment->trailing = trailing; - /* If a fragment ends with an incomplete line, we failed to include + /* + * If a fragment ends with an incomplete line, we failed to include * it in the above loop because we hit oldlines == newlines == 0 * before seeing it. */ @@ -1140,7 +1163,8 @@ static struct fragment *parse_binary_hunk(char **buf_p, int *status_p, int *used_p) { - /* Expect a line that begins with binary patch method ("literal" + /* + * Expect a line that begins with binary patch method ("literal" * or "delta"), followed by the length of data before deflating. * a sequence of 'length-byte' followed by base-85 encoded data * should follow, terminated by a newline. @@ -1189,7 +1213,8 @@ static struct fragment *parse_binary_hunk(char **buf_p, size--; break; } - /* Minimum line is "A00000\n" which is 7-byte long, + /* + * Minimum line is "A00000\n" which is 7-byte long, * and the line length must be multiple of 5 plus 2. */ if ((llen < 7) || (llen-2) % 5) @@ -1240,7 +1265,8 @@ static struct fragment *parse_binary_hunk(char **buf_p, static int parse_binary(char *buffer, unsigned long size, struct patch *patch) { - /* We have read "GIT binary patch\n"; what follows is a line + /* + * We have read "GIT binary patch\n"; what follows is a line * that says the patch method (currently, either "literal" or * "delta") and the length of data before deflating; a * sequence of 'length-byte' followed by base-85 encoded data @@ -1270,7 +1296,8 @@ static int parse_binary(char *buffer, unsigned long size, struct patch *patch) if (reverse) used += used_1; else if (status) { - /* not having reverse hunk is not an error, but having + /* + * Not having reverse hunk is not an error, but having * a corrupt reverse hunk is. */ free((void*) forward->patch); @@ -1291,7 +1318,12 @@ static int parse_chunk(char *buffer, unsigned long size, struct patch *patch) if (offset < 0) return offset; - patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch); + patch->ws_rule = whitespace_rule(patch->new_name + ? patch->new_name + : patch->old_name); + + patchsize = parse_single_patch(buffer + offset + hdrsize, + size - offset - hdrsize, patch); if (!patchsize) { static const char *binhdr[] = { @@ -1367,8 +1399,10 @@ static void reverse_patches(struct patch *p) } } -static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; -static const char minuses[]= "----------------------------------------------------------------------"; +static const char pluses[] = +"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"; +static const char minuses[]= +"----------------------------------------------------------------------"; static void show_stats(struct patch *patch) { @@ -1437,7 +1471,9 @@ static int read_old_data(struct stat *st, const char *path, struct strbuf *buf) } } -static int find_offset(const char *buf, unsigned long size, const char *fragment, unsigned long fragsize, int line, int *lines) +static int find_offset(const char *buf, unsigned long size, + const char *fragment, unsigned long fragsize, + int line, int *lines) { int i; unsigned long start, backwards, forwards; @@ -1536,9 +1572,11 @@ static void remove_last_line(const char **rbuf, int *rsize) *rsize = offset + 1; } -static int apply_line(char *output, const char *patch, int plen) +static int apply_line(char *output, const char *patch, int plen, + unsigned ws_rule) { - /* plen is number of bytes to be copied from patch, + /* + * plen is number of bytes to be copied from patch, * starting at patch+1 (patch[0] is '+'). Typically * patch[plen] is '\n', unless this is the incomplete * last line. @@ -1551,13 +1589,17 @@ static int apply_line(char *output, const char *patch, int plen) int need_fix_leading_space = 0; char *buf; - if ((new_whitespace != strip_whitespace) || !whitespace_error || + if ((ws_error_action != correct_ws_error) || !whitespace_error || *patch != '+') { memcpy(output, patch + 1, plen); return plen; } - if (1 < plen && isspace(patch[plen-1])) { + /* + * Strip trailing whitespace + */ + if ((ws_rule & WS_TRAILING_SPACE) && + (1 < plen && isspace(patch[plen-1]))) { if (patch[plen] == '\n') add_nl_to_tail = 1; plen--; @@ -1566,15 +1608,23 @@ static int apply_line(char *output, const char *patch, int plen) fixed = 1; } + /* + * Check leading whitespaces (indent) + */ for (i = 1; i < plen; i++) { char ch = patch[i]; if (ch == '\t') { last_tab_in_indent = i; - if (0 <= last_space_in_indent) + if ((ws_rule & WS_SPACE_BEFORE_TAB) && + 0 <= last_space_in_indent) + need_fix_leading_space = 1; + } else if (ch == ' ') { + last_space_in_indent = i; + if ((ws_rule & WS_INDENT_WITH_NON_TAB) && + last_tab_in_indent < 0 && + 8 <= i) need_fix_leading_space = 1; } - else if (ch == ' ') - last_space_in_indent = i; else break; } @@ -1582,10 +1632,21 @@ static int apply_line(char *output, const char *patch, int plen) buf = output; if (need_fix_leading_space) { int consecutive_spaces = 0; - /* between patch[1..last_tab_in_indent] strip the - * funny spaces, updating them to tab as needed. + int last = last_tab_in_indent + 1; + + if (ws_rule & WS_INDENT_WITH_NON_TAB) { + /* have "last" point at one past the indent */ + if (last_tab_in_indent < last_space_in_indent) + last = last_space_in_indent + 1; + else + last = last_tab_in_indent + 1; + } + + /* + * between patch[1..last], strip the funny spaces, + * updating them to tab as needed. */ - for (i = 1; i < last_tab_in_indent; i++, plen--) { + for (i = 1; i < last; i++, plen--) { char ch = patch[i]; if (ch != ' ') { consecutive_spaces = 0; @@ -1598,8 +1659,10 @@ static int apply_line(char *output, const char *patch, int plen) } } } + while (0 < consecutive_spaces--) + *output++ = ' '; fixed = 1; - i = last_tab_in_indent; + i = last; } else i = 1; @@ -1612,7 +1675,8 @@ static int apply_line(char *output, const char *patch, int plen) return output + plen - buf; } -static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int inaccurate_eof) +static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, + int inaccurate_eof, unsigned ws_rule) { int match_beginning, match_end; const char *patch = frag->patch; @@ -1671,7 +1735,7 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int ina case '+': if (first != '+' || !no_add) { int added = apply_line(new + newsize, patch, - plen); + plen, ws_rule); newsize += added; if (first == '+' && added == 1 && new[newsize-1] == '\n') @@ -1694,8 +1758,9 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int ina size -= len; } - if (inaccurate_eof && oldsize > 0 && old[oldsize - 1] == '\n' && - newsize > 0 && new[newsize - 1] == '\n') { + if (inaccurate_eof && + oldsize > 0 && old[oldsize - 1] == '\n' && + newsize > 0 && new[newsize - 1] == '\n') { oldsize--; newsize--; } @@ -1732,7 +1797,7 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int ina if (match_beginning && offset) offset = -1; if (offset >= 0) { - if (new_whitespace == strip_whitespace && + if (ws_error_action == correct_ws_error && (buf->len - oldsize - offset == 0)) /* end of file? */ newsize -= new_blank_lines_at_end; @@ -1757,9 +1822,10 @@ static int apply_one_fragment(struct strbuf *buf, struct fragment *frag, int ina match_beginning = match_end = 0; continue; } - /* Reduce the number of context lines - * Reduce both leading and trailing if they are equal - * otherwise just reduce the larger context. + /* + * Reduce the number of context lines; reduce both + * leading and trailing if they are equal otherwise + * just reduce the larger context. */ if (leading >= trailing) { remove_first_line(&oldlines, &oldsize); @@ -1819,7 +1885,8 @@ static int apply_binary(struct strbuf *buf, struct patch *patch) const char *name = patch->old_name ? patch->old_name : patch->new_name; unsigned char sha1[20]; - /* For safety, we require patch index line to contain + /* + * For safety, we require patch index line to contain * full 40-byte textual SHA1 for old and new, at least for now. */ if (strlen(patch->old_sha1_prefix) != 40 || @@ -1830,7 +1897,8 @@ static int apply_binary(struct strbuf *buf, struct patch *patch) "without full index line", name); if (patch->old_name) { - /* See if the old one matches what the patch + /* + * See if the old one matches what the patch * applies to. */ hash_sha1_file(buf->buf, buf->len, blob_type, sha1); @@ -1867,7 +1935,8 @@ static int apply_binary(struct strbuf *buf, struct patch *patch) /* XXX read_sha1_file NUL-terminates */ strbuf_attach(buf, result, size, size + 1); } else { - /* We have verified buf matches the preimage; + /* + * We have verified buf matches the preimage; * apply the patch data to it, which is stored * in the patch->fragments->{patch,size}. */ @@ -1889,12 +1958,14 @@ static int apply_fragments(struct strbuf *buf, struct patch *patch) { struct fragment *frag = patch->fragments; const char *name = patch->old_name ? patch->old_name : patch->new_name; + unsigned ws_rule = patch->ws_rule; + unsigned inaccurate_eof = patch->inaccurate_eof; if (patch->is_binary) return apply_binary(buf, patch); while (frag) { - if (apply_one_fragment(buf, frag, patch->inaccurate_eof)) { + if (apply_one_fragment(buf, frag, inaccurate_eof, ws_rule)) { error("patch failed: %s:%ld", name, frag->oldpos); if (!apply_with_reject) return -1; @@ -2066,7 +2137,8 @@ static int check_patch(struct patch *patch, struct patch *prev_patch) if (new_name && prev_patch && 0 < prev_patch->is_delete && !strcmp(prev_patch->old_name, new_name)) - /* A type-change diff is always split into a patch to + /* + * A type-change diff is always split into a patch to * delete old, immediately followed by a patch to * create new (see diff.c::run_diff()); in such a case * it is Ok that the entry to be deleted by the @@ -2670,7 +2742,7 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof) offset += nr; } - if (whitespace_error && (new_whitespace == error_on_whitespace)) + if (whitespace_error && (ws_error_action == die_on_ws_error)) apply = 0; update_index = check_index && apply; @@ -2865,7 +2937,7 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix) squelched, squelched == 1 ? "" : "s"); } - if (new_whitespace == error_on_whitespace) + if (ws_error_action == die_on_ws_error) die("%d line%s add%s whitespace errors.", whitespace_error, whitespace_error == 1 ? "" : "s", diff --git a/builtin-branch.c b/builtin-branch.c index c64768beb2..089cae5929 100644 --- a/builtin-branch.c +++ b/builtin-branch.c @@ -65,7 +65,7 @@ static int parse_branch_color_slot(const char *var, int ofs) static int git_branch_config(const char *var, const char *value) { if (!strcmp(var, "color.branch")) { - branch_use_color = git_config_colorbool(var, value); + branch_use_color = git_config_colorbool(var, value, -1); return 0; } if (!prefixcmp(var, "color.branch.")) { diff --git a/builtin-clean.c b/builtin-clean.c index 56ae4eb9bb..ae30d4e76c 100644 --- a/builtin-clean.c +++ b/builtin-clean.c @@ -27,13 +27,14 @@ static int git_clean_config(const char *var, const char *value) int cmd_clean(int argc, const char **argv, const char *prefix) { - int j; + int i; int show_only = 0, remove_directories = 0, quiet = 0, ignored = 0; int ignored_only = 0, baselen = 0, config_set = 0; struct strbuf directory; struct dir_struct dir; const char *path, *base; static const char **pathspec; + char *seen = NULL; struct option options[] = { OPT__QUIET(&quiet), OPT__DRY_RUN(&show_only), @@ -85,12 +86,14 @@ int cmd_clean(int argc, const char **argv, const char *prefix) read_directory(&dir, path, base, baselen, pathspec); strbuf_init(&directory, 0); - for (j = 0; j < dir.nr; ++j) { - struct dir_entry *ent = dir.entries[j]; - int len, pos, specs; + if (pathspec) + seen = xmalloc(argc); + + for (i = 0; i < dir.nr; i++) { + struct dir_entry *ent = dir.entries[i]; + int len, pos, matches; struct cache_entry *ce; struct stat st; - char *seen; /* * Remove the '/' at the end that directory @@ -110,25 +113,29 @@ int cmd_clean(int argc, const char **argv, const char *prefix) continue; /* Yup, this one exists unmerged */ } - if (!lstat(ent->name, &st) && (S_ISDIR(st.st_mode))) { - int matched_path = 0; + /* + * we might have removed this as part of earlier + * recursive directory removal, so lstat() here could + * fail with ENOENT. + */ + if (lstat(ent->name, &st)) + continue; + + if (pathspec) { + memset(seen, 0, argc); + matches = match_pathspec(pathspec, ent->name, ent->len, + baselen, seen); + } else { + matches = 0; + } + + if (S_ISDIR(st.st_mode)) { strbuf_addstr(&directory, ent->name); - if (pathspec) { - for (specs =0; pathspec[specs]; ++specs) - /* nothing */; - seen = xcalloc(specs, 1); - /* Check if directory was explictly passed as - * pathspec. If so we want to remove it */ - if (match_pathspec(pathspec, ent->name, ent->len, - baselen, seen)) - matched_path = 1; - free(seen); - } - if (show_only && (remove_directories || matched_path)) { + if (show_only && (remove_directories || matches)) { printf("Would remove %s\n", directory.buf); - } else if (quiet && (remove_directories || matched_path)) { + } else if (quiet && (remove_directories || matches)) { remove_dir_recursively(&directory, 0); - } else if (remove_directories || matched_path) { + } else if (remove_directories || matches) { printf("Removing %s\n", directory.buf); remove_dir_recursively(&directory, 0); } else if (show_only) { @@ -138,6 +145,8 @@ int cmd_clean(int argc, const char **argv, const char *prefix) } strbuf_reset(&directory); } else { + if (pathspec && !matches) + continue; if (show_only) { printf("Would remove %s\n", ent->name); continue; @@ -147,6 +156,7 @@ int cmd_clean(int argc, const char **argv, const char *prefix) unlink(ent->name); } } + free(seen); strbuf_release(&directory); return 0; diff --git a/builtin-commit-tree.c b/builtin-commit-tree.c index 88b0ab36eb..6610d18358 100644 --- a/builtin-commit-tree.c +++ b/builtin-commit-tree.c @@ -98,8 +98,8 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix) strbuf_addf(&buffer, "parent %s\n", sha1_to_hex(parent_sha1[i])); /* Person/date information */ - strbuf_addf(&buffer, "author %s\n", git_author_info(1)); - strbuf_addf(&buffer, "committer %s\n", git_committer_info(1)); + strbuf_addf(&buffer, "author %s\n", git_author_info(IDENT_ERROR_ON_NO_NAME)); + strbuf_addf(&buffer, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); if (!encoding_is_utf8) strbuf_addf(&buffer, "encoding %s\n", git_commit_encoding); strbuf_addch(&buffer, '\n'); diff --git a/builtin-commit.c b/builtin-commit.c new file mode 100644 index 0000000000..b6b81d531d --- /dev/null +++ b/builtin-commit.c @@ -0,0 +1,854 @@ +/* + * Builtin "git commit" + * + * Copyright (c) 2007 Kristian Høgsberg <krh@redhat.com> + * Based on git-commit.sh by Junio C Hamano and Linus Torvalds + */ + +#include "cache.h" +#include "cache-tree.h" +#include "dir.h" +#include "builtin.h" +#include "diff.h" +#include "diffcore.h" +#include "commit.h" +#include "revision.h" +#include "wt-status.h" +#include "run-command.h" +#include "refs.h" +#include "log-tree.h" +#include "strbuf.h" +#include "utf8.h" +#include "parse-options.h" +#include "path-list.h" + +static const char * const builtin_commit_usage[] = { + "git-commit [options] [--] <filepattern>...", + NULL +}; + +static const char * const builtin_status_usage[] = { + "git-status [options] [--] <filepattern>...", + NULL +}; + +static unsigned char head_sha1[20], merge_head_sha1[20]; +static char *use_message_buffer; +static const char commit_editmsg[] = "COMMIT_EDITMSG"; +static struct lock_file index_lock; /* real index */ +static struct lock_file false_lock; /* used only for partial commits */ +static enum { + COMMIT_AS_IS = 1, + COMMIT_NORMAL, + COMMIT_PARTIAL, +} commit_style; + +static char *logfile, *force_author, *template_file; +static char *edit_message, *use_message; +static int all, edit_flag, also, interactive, only, amend, signoff; +static int quiet, verbose, untracked_files, no_verify, allow_empty; + +static int no_edit, initial_commit, in_merge; +const char *only_include_assumed; +struct strbuf message; + +static int opt_parse_m(const struct option *opt, const char *arg, int unset) +{ + struct strbuf *buf = opt->value; + if (unset) + strbuf_setlen(buf, 0); + else { + strbuf_addstr(buf, arg); + strbuf_addch(buf, '\n'); + strbuf_addch(buf, '\n'); + } + return 0; +} + +static struct option builtin_commit_options[] = { + OPT__QUIET(&quiet), + OPT__VERBOSE(&verbose), + OPT_GROUP("Commit message options"), + + OPT_STRING('F', "file", &logfile, "FILE", "read log from file"), + OPT_STRING(0, "author", &force_author, "AUTHOR", "override author for commit"), + OPT_CALLBACK('m', "message", &message, "MESSAGE", "specify commit message", opt_parse_m), + OPT_STRING('c', "reedit-message", &edit_message, "COMMIT", "reuse and edit message from specified commit "), + OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"), + OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by: header"), + OPT_STRING('t', "template", &template_file, "FILE", "use specified template file"), + OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"), + + OPT_GROUP("Commit contents options"), + OPT_BOOLEAN('a', "all", &all, "commit all changed files"), + OPT_BOOLEAN('i', "include", &also, "add specified files to index for commit"), + OPT_BOOLEAN(0, "interactive", &interactive, "interactively add files"), + OPT_BOOLEAN('o', "only", &only, ""), + OPT_BOOLEAN('n', "no-verify", &no_verify, "bypass pre-commit hook"), + OPT_BOOLEAN(0, "amend", &amend, "amend previous commit"), + OPT_BOOLEAN(0, "untracked-files", &untracked_files, "show all untracked files"), + OPT_BOOLEAN(0, "allow-empty", &allow_empty, "ok to record an empty change"), + + OPT_END() +}; + +static void rollback_index_files(void) +{ + switch (commit_style) { + case COMMIT_AS_IS: + break; /* nothing to do */ + case COMMIT_NORMAL: + rollback_lock_file(&index_lock); + break; + case COMMIT_PARTIAL: + rollback_lock_file(&index_lock); + rollback_lock_file(&false_lock); + break; + } +} + +static void commit_index_files(void) +{ + switch (commit_style) { + case COMMIT_AS_IS: + break; /* nothing to do */ + case COMMIT_NORMAL: + commit_lock_file(&index_lock); + break; + case COMMIT_PARTIAL: + commit_lock_file(&index_lock); + rollback_lock_file(&false_lock); + break; + } +} + +/* + * Take a union of paths in the index and the named tree (typically, "HEAD"), + * and return the paths that match the given pattern in list. + */ +static int list_paths(struct path_list *list, const char *with_tree, + const char *prefix, const char **pattern) +{ + int i; + char *m; + + for (i = 0; pattern[i]; i++) + ; + m = xcalloc(1, i); + + if (with_tree) + overlay_tree_on_cache(with_tree, prefix); + + for (i = 0; i < active_nr; i++) { + struct cache_entry *ce = active_cache[i]; + if (ce->ce_flags & htons(CE_UPDATE)) + continue; + if (!pathspec_match(pattern, m, ce->name, 0)) + continue; + path_list_insert(ce->name, list); + } + + return report_path_error(m, pattern, prefix ? strlen(prefix) : 0); +} + +static void add_remove_files(struct path_list *list) +{ + int i; + for (i = 0; i < list->nr; i++) { + struct path_list_item *p = &(list->items[i]); + if (file_exists(p->path)) + add_file_to_cache(p->path, 0); + else + remove_file_from_cache(p->path); + } +} + +static char *prepare_index(int argc, const char **argv, const char *prefix) +{ + int fd; + struct tree *tree; + struct path_list partial; + const char **pathspec = NULL; + + if (interactive) { + interactive_add(argc, argv, prefix); + commit_style = COMMIT_AS_IS; + return get_index_file(); + } + + if (read_cache() < 0) + die("index file corrupt"); + + if (*argv) + pathspec = get_pathspec(prefix, argv); + + /* + * Non partial, non as-is commit. + * + * (1) get the real index; + * (2) update the_index as necessary; + * (3) write the_index out to the real index (still locked); + * (4) return the name of the locked index file. + * + * The caller should run hooks on the locked real index, and + * (A) if all goes well, commit the real index; + * (B) on failure, rollback the real index. + */ + if (all || (also && pathspec && *pathspec)) { + int fd = hold_locked_index(&index_lock, 1); + add_files_to_cache(0, also ? prefix : NULL, pathspec); + refresh_cache(REFRESH_QUIET); + if (write_cache(fd, active_cache, active_nr) || close(fd)) + die("unable to write new_index file"); + commit_style = COMMIT_NORMAL; + return index_lock.filename; + } + + /* + * As-is commit. + * + * (1) return the name of the real index file. + * + * The caller should run hooks on the real index, and run + * hooks on the real index, and create commit from the_index. + * We still need to refresh the index here. + */ + if (!pathspec || !*pathspec) { + fd = hold_locked_index(&index_lock, 1); + refresh_cache(REFRESH_QUIET); + if (write_cache(fd, active_cache, active_nr) || + close(fd) || commit_locked_index(&index_lock)) + die("unable to write new_index file"); + commit_style = COMMIT_AS_IS; + return get_index_file(); + } + + /* + * A partial commit. + * + * (0) find the set of affected paths; + * (1) get lock on the real index file; + * (2) update the_index with the given paths; + * (3) write the_index out to the real index (still locked); + * (4) get lock on the false index file; + * (5) reset the_index from HEAD; + * (6) update the_index the same way as (2); + * (7) write the_index out to the false index file; + * (8) return the name of the false index file (still locked); + * + * The caller should run hooks on the locked false index, and + * create commit from it. Then + * (A) if all goes well, commit the real index; + * (B) on failure, rollback the real index; + * In either case, rollback the false index. + */ + commit_style = COMMIT_PARTIAL; + + if (file_exists(git_path("MERGE_HEAD"))) + die("cannot do a partial commit during a merge."); + + memset(&partial, 0, sizeof(partial)); + partial.strdup_paths = 1; + if (list_paths(&partial, initial_commit ? NULL : "HEAD", prefix, pathspec)) + exit(1); + + discard_cache(); + if (read_cache() < 0) + die("cannot read the index"); + + fd = hold_locked_index(&index_lock, 1); + add_remove_files(&partial); + refresh_cache(REFRESH_QUIET); + if (write_cache(fd, active_cache, active_nr) || close(fd)) + die("unable to write new_index file"); + + fd = hold_lock_file_for_update(&false_lock, + git_path("next-index-%d", getpid()), 1); + discard_cache(); + if (!initial_commit) { + tree = parse_tree_indirect(head_sha1); + if (!tree) + die("failed to unpack HEAD tree object"); + if (read_tree(tree, 0, NULL)) + die("failed to read HEAD tree object"); + } + add_remove_files(&partial); + refresh_cache(REFRESH_QUIET); + + if (write_cache(fd, active_cache, active_nr) || close(fd)) + die("unable to write temporary index file"); + return false_lock.filename; +} + +static int run_status(FILE *fp, const char *index_file, const char *prefix) +{ + struct wt_status s; + + wt_status_prepare(&s); + if (wt_status_relative_paths) + s.prefix = prefix; + + if (amend) { + s.amend = 1; + s.reference = "HEAD^1"; + } + s.verbose = verbose; + s.untracked = untracked_files; + s.index_file = index_file; + s.fp = fp; + + wt_status_print(&s); + + return s.commitable; +} + +static const char sign_off_header[] = "Signed-off-by: "; + +static int prepare_log_message(const char *index_file, const char *prefix) +{ + struct stat statbuf; + int commitable, saved_color_setting; + struct strbuf sb; + char *buffer; + FILE *fp; + + strbuf_init(&sb, 0); + if (message.len) { + strbuf_addbuf(&sb, &message); + } else if (logfile && !strcmp(logfile, "-")) { + if (isatty(0)) + fprintf(stderr, "(reading log message from standard input)\n"); + if (strbuf_read(&sb, 0, 0) < 0) + die("could not read log from standard input"); + } else if (logfile) { + if (strbuf_read_file(&sb, logfile, 0) < 0) + die("could not read log file '%s': %s", + logfile, strerror(errno)); + } else if (use_message) { + buffer = strstr(use_message_buffer, "\n\n"); + if (!buffer || buffer[2] == '\0') + die("commit has empty message"); + strbuf_add(&sb, buffer + 2, strlen(buffer + 2)); + } else if (!stat(git_path("MERGE_MSG"), &statbuf)) { + if (strbuf_read_file(&sb, git_path("MERGE_MSG"), 0) < 0) + die("could not read MERGE_MSG: %s", strerror(errno)); + } else if (!stat(git_path("SQUASH_MSG"), &statbuf)) { + if (strbuf_read_file(&sb, git_path("SQUASH_MSG"), 0) < 0) + die("could not read SQUASH_MSG: %s", strerror(errno)); + } else if (template_file && !stat(template_file, &statbuf)) { + if (strbuf_read_file(&sb, template_file, 0) < 0) + die("could not read %s: %s", + template_file, strerror(errno)); + } + + fp = fopen(git_path(commit_editmsg), "w"); + if (fp == NULL) + die("could not open %s", git_path(commit_editmsg)); + + stripspace(&sb, 0); + + if (signoff) { + struct strbuf sob; + int i; + + strbuf_init(&sob, 0); + 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 = sb.len - 1; i > 0 && sb.buf[i - 1] != '\n'; i--) + ; /* do nothing */ + if (prefixcmp(sb.buf + i, sob.buf)) { + if (prefixcmp(sb.buf + i, sign_off_header)) + strbuf_addch(&sb, '\n'); + strbuf_addbuf(&sb, &sob); + } + strbuf_release(&sob); + } + + if (fwrite(sb.buf, 1, sb.len, fp) < sb.len) + die("could not write commit template: %s", strerror(errno)); + + strbuf_release(&sb); + + if (no_edit) { + struct rev_info rev; + unsigned char sha1[40]; + + fclose(fp); + + if (!active_nr && read_cache() < 0) + die("Cannot read index"); + + if (get_sha1("HEAD", sha1) != 0) + return !!active_nr; + + init_revisions(&rev, ""); + rev.abbrev = 0; + setup_revisions(0, NULL, &rev, "HEAD"); + DIFF_OPT_SET(&rev.diffopt, QUIET); + DIFF_OPT_SET(&rev.diffopt, EXIT_WITH_STATUS); + run_diff_index(&rev, 1 /* cached */); + + return !!DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES); + } + + if (in_merge && !no_edit) + fprintf(fp, + "#\n" + "# It looks like you may be committing a MERGE.\n" + "# If this is not correct, please remove the file\n" + "# %s\n" + "# and try again.\n" + "#\n", + git_path("MERGE_HEAD")); + + fprintf(fp, + "\n" + "# Please enter the commit message for your changes.\n" + "# (Comment lines starting with '#' will not be included)\n"); + if (only_include_assumed) + fprintf(fp, "# %s\n", only_include_assumed); + + saved_color_setting = wt_status_use_color; + wt_status_use_color = 0; + commitable = run_status(fp, index_file, prefix); + wt_status_use_color = saved_color_setting; + + fclose(fp); + + return commitable; +} + +/* + * Find out if the message starting at position 'start' in the strbuf + * contains only whitespace and Signed-off-by lines. + */ +static int message_is_empty(struct strbuf *sb, int start) +{ + struct strbuf tmpl; + const char *nl; + int eol, i; + + /* See if the template is just a prefix of the message. */ + strbuf_init(&tmpl, 0); + if (template_file && strbuf_read_file(&tmpl, template_file, 0) > 0) { + stripspace(&tmpl, 1); + if (start + tmpl.len <= sb->len && + memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0) + start += tmpl.len; + } + strbuf_release(&tmpl); + + /* Check if the rest is just whitespace and Signed-of-by's. */ + for (i = start; i < sb->len; i++) { + nl = memchr(sb->buf + i, '\n', sb->len - i); + if (nl) + eol = nl - sb->buf; + else + eol = sb->len; + + if (strlen(sign_off_header) <= eol - i && + !prefixcmp(sb->buf + i, sign_off_header)) { + i = eol; + continue; + } + while (i < eol) + if (!isspace(sb->buf[i++])) + return 0; + } + + return 1; +} + +static void determine_author_info(struct strbuf *sb) +{ + char *name, *email, *date; + + name = getenv("GIT_AUTHOR_NAME"); + email = getenv("GIT_AUTHOR_EMAIL"); + date = getenv("GIT_AUTHOR_DATE"); + + if (use_message) { + const char *a, *lb, *rb, *eol; + + a = strstr(use_message_buffer, "\nauthor "); + if (!a) + die("invalid commit: %s", use_message); + + lb = strstr(a + 8, " <"); + rb = strstr(a + 8, "> "); + eol = strchr(a + 8, '\n'); + if (!lb || !rb || !eol) + die("invalid commit: %s", use_message); + + name = xstrndup(a + 8, lb - (a + 8)); + email = xstrndup(lb + 2, rb - (lb + 2)); + date = xstrndup(rb + 2, eol - (rb + 2)); + } + + if (force_author) { + const char *lb = strstr(force_author, " <"); + const char *rb = strchr(force_author, '>'); + + if (!lb || !rb) + die("malformed --author parameter"); + name = xstrndup(force_author, lb - force_author); + email = xstrndup(lb + 2, rb - (lb + 2)); + } + + strbuf_addf(sb, "author %s\n", fmt_ident(name, email, date, IDENT_ERROR_ON_NO_NAME)); +} + +static int parse_and_validate_options(int argc, const char *argv[], + const char * const usage[]) +{ + int f = 0; + + argc = parse_options(argc, argv, builtin_commit_options, usage, 0); + + if (logfile || message.len || use_message) + no_edit = 1; + if (edit_flag) + no_edit = 0; + + if (get_sha1("HEAD", head_sha1)) + initial_commit = 1; + + if (!get_sha1("MERGE_HEAD", merge_head_sha1)) + in_merge = 1; + + /* Sanity check options */ + if (amend && initial_commit) + die("You have nothing to amend."); + if (amend && in_merge) + die("You are in the middle of a merge -- cannot amend."); + + if (use_message) + f++; + if (edit_message) + f++; + if (logfile) + f++; + if (f > 1) + die("Only one of -c/-C/-F can be used."); + if (message.len && f > 0) + die("Option -m cannot be combined with -c/-C/-F."); + if (edit_message) + use_message = edit_message; + if (amend) + use_message = "HEAD"; + if (use_message) { + unsigned char sha1[20]; + static char utf8[] = "UTF-8"; + const char *out_enc; + char *enc, *end; + struct commit *commit; + + if (get_sha1(use_message, sha1)) + die("could not lookup commit %s", use_message); + commit = lookup_commit(sha1); + if (!commit || parse_commit(commit)) + die("could not parse commit %s", use_message); + + enc = strstr(commit->buffer, "\nencoding"); + if (enc) { + end = strchr(enc + 10, '\n'); + enc = xstrndup(enc + 10, end - (enc + 10)); + } else { + enc = utf8; + } + out_enc = git_commit_encoding ? git_commit_encoding : utf8; + + if (strcmp(out_enc, enc)) + use_message_buffer = + reencode_string(commit->buffer, out_enc, enc); + + /* + * If we failed to reencode the buffer, just copy it + * byte for byte so the user can try to fix it up. + * This also handles the case where input and output + * encodings are identical. + */ + if (use_message_buffer == NULL) + use_message_buffer = xstrdup(commit->buffer); + if (enc != utf8) + free(enc); + } + + if (!!also + !!only + !!all + !!interactive > 1) + die("Only one of --include/--only/--all/--interactive can be used."); + if (argc == 0 && (also || (only && !amend))) + die("No paths with --include/--only does not make sense."); + if (argc == 0 && only && amend) + only_include_assumed = "Clever... amending the last one with dirty index."; + if (argc > 0 && !also && !only) { + only_include_assumed = "Explicit paths specified without -i nor -o; assuming --only paths..."; + also = 0; + } + + if (all && argc > 0) + die("Paths with -a does not make sense."); + else if (interactive && argc > 0) + die("Paths with --interactive does not make sense."); + + return argc; +} + +int cmd_status(int argc, const char **argv, const char *prefix) +{ + const char *index_file; + int commitable; + + git_config(git_status_config); + + argc = parse_and_validate_options(argc, argv, builtin_status_usage); + + index_file = prepare_index(argc, argv, prefix); + + commitable = run_status(stdout, index_file, prefix); + + rollback_index_files(); + + return commitable ? 0 : 1; +} + +static int run_hook(const char *index_file, const char *name, const char *arg) +{ + struct child_process hook; + const char *argv[3], *env[2]; + char index[PATH_MAX]; + + argv[0] = git_path("hooks/%s", name); + argv[1] = arg; + argv[2] = NULL; + snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); + env[0] = index; + env[1] = NULL; + + if (access(argv[0], X_OK) < 0) + return 0; + + memset(&hook, 0, sizeof(hook)); + hook.argv = argv; + hook.no_stdin = 1; + hook.stdout_to_stderr = 1; + hook.env = env; + + return run_command(&hook); +} + +static void print_summary(const char *prefix, const unsigned char *sha1) +{ + struct rev_info rev; + struct commit *commit; + + commit = lookup_commit(sha1); + if (!commit) + die("couldn't look up newly created commit"); + if (!commit || parse_commit(commit)) + die("could not parse newly created commit"); + + init_revisions(&rev, prefix); + setup_revisions(0, NULL, &rev, NULL); + + rev.abbrev = 0; + rev.diff = 1; + rev.diffopt.output_format = + DIFF_FORMAT_SHORTSTAT | DIFF_FORMAT_SUMMARY; + + rev.verbose_header = 1; + rev.show_root_diff = 1; + rev.commit_format = get_commit_format("format:%h: %s"); + rev.always_show_header = 1; + + printf("Created %scommit ", initial_commit ? "initial " : ""); + + log_tree_commit(&rev, commit); + printf("\n"); +} + +int git_commit_config(const char *k, const char *v) +{ + if (!strcmp(k, "commit.template")) { + template_file = xstrdup(v); + return 0; + } + + return git_status_config(k, v); +} + +static int is_a_merge(const unsigned char *sha1) +{ + struct commit *commit = lookup_commit(sha1); + if (!commit || parse_commit(commit)) + die("could not parse HEAD commit"); + return !!(commit->parents && commit->parents->next); +} + +static const char commit_utf8_warn[] = +"Warning: commit message does not conform to UTF-8.\n" +"You may want to amend it after fixing the message, or set the config\n" +"variable i18n.commitencoding to the encoding your project uses.\n"; + +int cmd_commit(int argc, const char **argv, const char *prefix) +{ + int header_len; + struct strbuf sb; + const char *index_file, *reflog_msg; + char *nl, *p; + unsigned char commit_sha1[20]; + struct ref_lock *ref_lock; + + git_config(git_commit_config); + + argc = parse_and_validate_options(argc, argv, builtin_commit_usage); + + index_file = prepare_index(argc, argv, prefix); + + if (!no_verify && run_hook(index_file, "pre-commit", NULL)) { + rollback_index_files(); + return 1; + } + + if (!prepare_log_message(index_file, prefix) && !in_merge && + !allow_empty && !(amend && is_a_merge(head_sha1))) { + run_status(stdout, index_file, prefix); + rollback_index_files(); + unlink(commit_editmsg); + return 1; + } + + /* + * Re-read the index as pre-commit hook could have updated it, + * and write it out as a tree. + */ + discard_cache(); + read_cache_from(index_file); + if (!active_cache_tree) + active_cache_tree = cache_tree(); + if (cache_tree_update(active_cache_tree, + active_cache, active_nr, 0, 0) < 0) { + rollback_index_files(); + die("Error building trees"); + } + + /* + * The commit object + */ + strbuf_init(&sb, 0); + strbuf_addf(&sb, "tree %s\n", + sha1_to_hex(active_cache_tree->sha1)); + + /* Determine parents */ + if (initial_commit) { + reflog_msg = "commit (initial)"; + } else if (amend) { + struct commit_list *c; + struct commit *commit; + + reflog_msg = "commit (amend)"; + commit = lookup_commit(head_sha1); + if (!commit || parse_commit(commit)) + die("could not parse HEAD commit"); + + for (c = commit->parents; c; c = c->next) + strbuf_addf(&sb, "parent %s\n", + sha1_to_hex(c->item->object.sha1)); + } else if (in_merge) { + struct strbuf m; + FILE *fp; + + reflog_msg = "commit (merge)"; + strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1)); + strbuf_init(&m, 0); + fp = fopen(git_path("MERGE_HEAD"), "r"); + if (fp == NULL) + die("could not open %s for reading: %s", + git_path("MERGE_HEAD"), strerror(errno)); + while (strbuf_getline(&m, fp, '\n') != EOF) + strbuf_addf(&sb, "parent %s\n", m.buf); + fclose(fp); + strbuf_release(&m); + } else { + reflog_msg = "commit"; + strbuf_addf(&sb, "parent %s\n", sha1_to_hex(head_sha1)); + } + + determine_author_info(&sb); + strbuf_addf(&sb, "committer %s\n", git_committer_info(IDENT_ERROR_ON_NO_NAME)); + if (!is_encoding_utf8(git_commit_encoding)) + strbuf_addf(&sb, "encoding %s\n", git_commit_encoding); + strbuf_addch(&sb, '\n'); + + /* Get the commit message and validate it */ + header_len = sb.len; + if (!no_edit) { + char index[PATH_MAX]; + const char *env[2] = { index, NULL }; + snprintf(index, sizeof(index), "GIT_INDEX_FILE=%s", index_file); + launch_editor(git_path(commit_editmsg), NULL, env); + } + if (!no_verify && + run_hook(index_file, "commit-msg", git_path(commit_editmsg))) { + rollback_index_files(); + exit(1); + } + if (strbuf_read_file(&sb, git_path(commit_editmsg), 0) < 0) { + rollback_index_files(); + die("could not read commit message"); + } + + /* Truncate the message just before the diff, if any. */ + p = strstr(sb.buf, "\ndiff --git a/"); + if (p != NULL) + strbuf_setlen(&sb, p - sb.buf + 1); + + stripspace(&sb, 1); + if (sb.len < header_len || message_is_empty(&sb, header_len)) { + rollback_index_files(); + die("no commit message? aborting commit."); + } + strbuf_addch(&sb, '\0'); + if (is_encoding_utf8(git_commit_encoding) && !is_utf8(sb.buf)) + fprintf(stderr, commit_utf8_warn); + + if (write_sha1_file(sb.buf, sb.len - 1, commit_type, commit_sha1)) { + rollback_index_files(); + die("failed to write commit object"); + } + + ref_lock = lock_any_ref_for_update("HEAD", + initial_commit ? NULL : head_sha1, + 0); + + nl = strchr(sb.buf + header_len, '\n'); + if (nl) + strbuf_setlen(&sb, nl + 1 - sb.buf); + else + strbuf_addch(&sb, '\n'); + strbuf_remove(&sb, 0, header_len); + strbuf_insert(&sb, 0, reflog_msg, strlen(reflog_msg)); + strbuf_insert(&sb, strlen(reflog_msg), ": ", 2); + + if (!ref_lock) { + rollback_index_files(); + die("cannot lock HEAD ref"); + } + if (write_ref_sha1(ref_lock, commit_sha1, sb.buf) < 0) { + rollback_index_files(); + die("cannot update HEAD ref"); + } + + unlink(git_path("MERGE_HEAD")); + unlink(git_path("MERGE_MSG")); + + commit_index_files(); + + rerere(); + run_hook(get_index_file(), "post-commit", NULL); + if (!quiet) + print_summary(prefix, commit_sha1); + + return 0; +} diff --git a/builtin-config.c b/builtin-config.c index 4c9ded3b1a..e4a12e3166 100644 --- a/builtin-config.c +++ b/builtin-config.c @@ -3,7 +3,7 @@ #include "color.h" static const char git_config_set_usage[] = -"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default]"; +"git-config [ --global | --system | [ -f | --file ] config-file ] [ --bool | --int ] [ -z | --null ] [--get | --get-all | --get-regexp | --replace-all | --add | --unset | --unset-all] name [value [value_regex]] | --rename-section old_name new_name | --remove-section name | --list | --get-color var [default] | --get-colorbool name [stdout-is-tty]"; static char *key; static regex_t *key_regexp; @@ -38,8 +38,7 @@ static int show_config(const char* key_, const char* value_) if (use_key_regexp && regexec(key_regexp, key_, 0, NULL, 0)) return 0; if (regexp != NULL && - (do_not_match ^ - regexec(regexp, (value_?value_:""), 0, NULL, 0))) + (do_not_match ^ !!regexec(regexp, (value_?value_:""), 0, NULL, 0))) return 0; if (show_keys) { @@ -209,6 +208,57 @@ static int get_color(int argc, const char **argv) return 0; } +static int stdout_is_tty; +static int get_colorbool_found; +static int get_diff_color_found; +static int git_get_colorbool_config(const char *var, const char *value) +{ + if (!strcmp(var, get_color_slot)) { + get_colorbool_found = + git_config_colorbool(var, value, stdout_is_tty); + } + if (!strcmp(var, "diff.color")) { + get_diff_color_found = + git_config_colorbool(var, value, stdout_is_tty); + } + return 0; +} + +static int get_colorbool(int argc, const char **argv) +{ + /* + * git config --get-colorbool <slot> [<stdout-is-tty>] + * + * returns "true" or "false" depending on how <slot> + * is configured. + */ + + if (argc == 2) + stdout_is_tty = git_config_bool("command line", argv[1]); + else if (argc == 1) + stdout_is_tty = isatty(1); + else + usage(git_config_set_usage); + get_colorbool_found = -1; + get_diff_color_found = -1; + get_color_slot = argv[0]; + git_config(git_get_colorbool_config); + + if (get_colorbool_found < 0) { + if (!strcmp(get_color_slot, "color.diff")) + get_colorbool_found = get_diff_color_found; + if (get_colorbool_found < 0) + get_colorbool_found = 0; + } + + if (argc == 1) { + return get_colorbool_found ? 0 : 1; + } else { + printf("%s\n", get_colorbool_found ? "true" : "false"); + return 0; + } +} + int cmd_config(int argc, const char **argv, const char *prefix) { int nongit = 0; @@ -284,6 +334,8 @@ int cmd_config(int argc, const char **argv, const char *prefix) return 0; } else if (!strcmp(argv[1], "--get-color")) { return get_color(argc-2, argv+2); + } else if (!strcmp(argv[1], "--get-colorbool")) { + return get_colorbool(argc-2, argv+2); } else break; argc--; diff --git a/builtin-fast-export.c b/builtin-fast-export.c index 72be45db46..2136aadfd7 100755 --- a/builtin-fast-export.c +++ b/builtin-fast-export.c @@ -23,15 +23,15 @@ static const char *fast_export_usage[] = { }; static int progress; -static enum { IGNORE, WARN, STRIP, ABORT } signed_tag_mode = ABORT; +static enum { VERBATIM, WARN, STRIP, ABORT } signed_tag_mode = ABORT; static int parse_opt_signed_tag_mode(const struct option *opt, const char *arg, int unset) { if (unset || !strcmp(arg, "abort")) signed_tag_mode = ABORT; - else if (!strcmp(arg, "ignore")) - signed_tag_mode = IGNORE; + else if (!strcmp(arg, "verbatim") || !strcmp(arg, "ignore")) + signed_tag_mode = VERBATIM; else if (!strcmp(arg, "warn")) signed_tag_mode = WARN; else if (!strcmp(arg, "strip")) @@ -270,7 +270,7 @@ static void handle_tag(const char *name, struct tag *tag) warning ("Exporting signed tag %s", sha1_to_hex(tag->object.sha1)); /* fallthru */ - case IGNORE: + case VERBATIM: break; case STRIP: message_size = signature + 1 - message; diff --git a/builtin-fetch.c b/builtin-fetch.c index de9947e7ac..320e235682 100644 --- a/builtin-fetch.c +++ b/builtin-fetch.c @@ -9,14 +9,45 @@ #include "remote.h" #include "transport.h" #include "run-command.h" +#include "parse-options.h" -static const char fetch_usage[] = "git-fetch [-a | --append] [--upload-pack <upload-pack>] [-f | --force] [--no-tags] [-t | --tags] [-k | --keep] [-u | --update-head-ok] [--depth <depth>] [-v | --verbose] [<repository> <refspec>...]"; +static const char * const builtin_fetch_usage[] = { + "git-fetch [options] [<repository> <refspec>...]", + NULL +}; -static int append, force, tags, no_tags, update_head_ok, verbose, quiet; +enum { + TAGS_UNSET = 0, + TAGS_DEFAULT = 1, + TAGS_SET = 2 +}; + +static int append, force, keep, update_head_ok, verbose, quiet; +static int tags = TAGS_DEFAULT; static const char *depth; -static char *default_rla = NULL; +static const char *upload_pack; +static struct strbuf default_rla = STRBUF_INIT; static struct transport *transport; +static struct option builtin_fetch_options[] = { + OPT__QUIET(&quiet), + OPT__VERBOSE(&verbose), + OPT_BOOLEAN('a', "append", &append, + "append to .git/FETCH_HEAD instead of overwriting"), + OPT_STRING(0, "upload-pack", &upload_pack, "PATH", + "path to upload pack on remote end"), + OPT_BOOLEAN('f', "force", &force, + "force overwrite of local branch"), + OPT_SET_INT('t', "tags", &tags, + "fetch all tags and associated objects", TAGS_SET), + OPT_BOOLEAN('k', "keep", &keep, "keep downloaded pack"), + OPT_BOOLEAN('u', "update-head-ok", &update_head_ok, + "allow updating of HEAD ref"), + OPT_STRING(0, "depth", &depth, "DEPTH", + "deepen history of shallow clone"), + OPT_END() +}; + static void unlock_pack(void) { if (transport) @@ -81,7 +112,7 @@ static struct ref *get_ref_map(struct transport *transport, const struct ref *remote_refs = transport_get_remote_refs(transport); - if (ref_count || tags) { + if (ref_count || tags == TAGS_SET) { for (i = 0; i < ref_count; i++) { get_fetch_map(remote_refs, &refs[i], &tail, 0); if (refs[i].dst && refs[i].dst[0]) @@ -90,7 +121,7 @@ static struct ref *get_ref_map(struct transport *transport, /* Merge everything on the command line, but not --tags */ for (rm = ref_map; rm; rm = rm->next) rm->merge = 1; - if (tags) { + if (tags == TAGS_SET) { struct refspec refspec; refspec.src = "refs/tags/"; refspec.dst = "refs/tags/"; @@ -142,7 +173,7 @@ static int s_update_ref(const char *action, static struct ref_lock *lock; if (!rla) - rla = default_rla; + rla = default_rla.buf; snprintf(msg, sizeof(msg), "%s: %s", rla, action); lock = lock_any_ref_for_update(ref->name, check_old ? ref->old_sha1 : NULL, 0); @@ -482,10 +513,10 @@ static int do_fetch(struct transport *transport, struct ref *ref_map, *fetch_map; struct ref *rm; int autotags = (transport->remote->fetch_tags == 1); - if (transport->remote->fetch_tags == 2 && !no_tags) - tags = 1; + if (transport->remote->fetch_tags == 2 && tags != TAGS_UNSET) + tags = TAGS_SET; if (transport->remote->fetch_tags == -1) - no_tags = 1; + tags = TAGS_UNSET; if (!transport->get_refs_list || !transport->fetch) die("Don't know how to fetch from %s", transport->url); @@ -515,7 +546,7 @@ static int do_fetch(struct transport *transport, /* if neither --no-tags nor --tags was specified, do automated tag * following ... */ - if (!(tags || no_tags) && autotags) { + if (tags == TAGS_DEFAULT && autotags) { ref_map = find_non_local_tags(transport, fetch_map); if (ref_map) { transport_set_option(transport, TRANS_OPT_DEPTH, "0"); @@ -543,91 +574,22 @@ static void set_option(const char *name, const char *value) int cmd_fetch(int argc, const char **argv, const char *prefix) { struct remote *remote; - int i, j, rla_offset; + int i; static const char **refs = NULL; int ref_nr = 0; - int cmd_len = 0; - const char *upload_pack = NULL; - int keep = 0; - - for (i = 1; i < argc; i++) { - const char *arg = argv[i]; - cmd_len += strlen(arg); - - if (arg[0] != '-') - break; - if (!strcmp(arg, "--append") || !strcmp(arg, "-a")) { - append = 1; - continue; - } - if (!prefixcmp(arg, "--upload-pack=")) { - upload_pack = arg + 14; - continue; - } - if (!strcmp(arg, "--upload-pack")) { - i++; - if (i == argc) - usage(fetch_usage); - upload_pack = argv[i]; - continue; - } - if (!strcmp(arg, "--force") || !strcmp(arg, "-f")) { - force = 1; - continue; - } - if (!strcmp(arg, "--no-tags")) { - no_tags = 1; - continue; - } - if (!strcmp(arg, "--tags") || !strcmp(arg, "-t")) { - tags = 1; - continue; - } - if (!strcmp(arg, "--keep") || !strcmp(arg, "-k")) { - keep = 1; - continue; - } - if (!strcmp(arg, "--update-head-ok") || !strcmp(arg, "-u")) { - update_head_ok = 1; - continue; - } - if (!prefixcmp(arg, "--depth=")) { - depth = arg + 8; - continue; - } - if (!strcmp(arg, "--depth")) { - i++; - if (i == argc) - usage(fetch_usage); - depth = argv[i]; - continue; - } - if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) { - quiet = 1; - continue; - } - if (!strcmp(arg, "--verbose") || !strcmp(arg, "-v")) { - verbose++; - continue; - } - usage(fetch_usage); - } - for (j = i; j < argc; j++) - cmd_len += strlen(argv[j]); + /* Record the command line for the reflog */ + strbuf_addstr(&default_rla, "fetch"); + for (i = 1; i < argc; i++) + strbuf_addf(&default_rla, " %s", argv[i]); - default_rla = xmalloc(cmd_len + 5 + argc + 1); - sprintf(default_rla, "fetch"); - rla_offset = strlen(default_rla); - for (j = 1; j < argc; j++) { - sprintf(default_rla + rla_offset, " %s", argv[j]); - rla_offset += strlen(argv[j]) + 1; - } + argc = parse_options(argc, argv, + builtin_fetch_options, builtin_fetch_usage, 0); - if (i == argc) + if (argc == 0) remote = remote_get(NULL); else - remote = remote_get(argv[i++]); + remote = remote_get(argv[0]); transport = transport_get(remote, remote->url[0]); if (verbose >= 2) @@ -644,10 +606,10 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) if (!transport->url) die("Where do you want to fetch from today?"); - if (i < argc) { + if (argc > 1) { int j = 0; - refs = xcalloc(argc - i + 1, sizeof(const char *)); - while (i < argc) { + refs = xcalloc(argc + 1, sizeof(const char *)); + for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "tag")) { char *ref; i++; @@ -659,7 +621,6 @@ int cmd_fetch(int argc, const char **argv, const char *prefix) refs[j++] = ref; } else refs[j++] = argv[i]; - i++; } refs[j] = NULL; ref_nr = j; diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c index daf3a08165..f36a43c264 100644 --- a/builtin-for-each-ref.c +++ b/builtin-for-each-ref.c @@ -13,8 +13,8 @@ #define QUOTE_NONE 0 #define QUOTE_SHELL 1 #define QUOTE_PERL 2 -#define QUOTE_PYTHON 3 -#define QUOTE_TCL 4 +#define QUOTE_PYTHON 4 +#define QUOTE_TCL 8 typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type; @@ -861,7 +861,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix) usage_with_options(for_each_ref_usage, opts); } if (HAS_MULTI_BITS(quote_style)) { - error("more than one quoting style ?"); + error("more than one quoting style?"); usage_with_options(for_each_ref_usage, opts); } if (verify_format(format)) diff --git a/builtin-grep.c b/builtin-grep.c index bbf747fc7b..f1ff8dc556 100644 --- a/builtin-grep.c +++ b/builtin-grep.c @@ -343,12 +343,12 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached) memcpy(name + 2, ce->name, len + 1); } argv[argc++] = name; - if (argc < MAXARGS) - continue; - status = flush_grep(opt, argc, nr, argv, &kept); - if (0 < status) - hit = 1; - argc = nr + kept; + if (MAXARGS <= argc) { + status = flush_grep(opt, argc, nr, argv, &kept); + if (0 < status) + hit = 1; + argc = nr + kept; + } if (ce_stage(ce)) { do { i++; diff --git a/builtin-log.c b/builtin-log.c index e1f1cf6714..b6a11220e2 100644 --- a/builtin-log.c +++ b/builtin-log.c @@ -557,7 +557,7 @@ static void get_patch_ids(struct rev_info *rev, struct patch_ids *ids, const cha static void gen_message_id(char *dest, unsigned int length, char *base) { - const char *committer = git_committer_info(-1); + const char *committer = git_committer_info(IDENT_WARN_ON_NO_NAME); const char *email_start = strrchr(committer, '<'); const char *email_end = strrchr(committer, '>'); if(!email_start || !email_end || email_start > email_end - 1) @@ -665,7 +665,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) !strcmp(argv[i], "-s")) { const char *committer; const char *endpos; - committer = git_committer_info(1); + committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) die("bogos committer info %s\n", committer); diff --git a/builtin-ls-files.c b/builtin-ls-files.c index 7f60709830..0f0ab2da16 100644 --- a/builtin-ls-files.c +++ b/builtin-ls-files.c @@ -38,28 +38,28 @@ static const char *tag_modified = ""; /* - * Match a pathspec against a filename. The first "len" characters + * Match a pathspec against a filename. The first "skiplen" characters * are the common prefix */ -static int match(const char **spec, char *ps_matched, - const char *filename, int len) +int pathspec_match(const char **spec, char *ps_matched, + const char *filename, int skiplen) { const char *m; while ((m = *spec++) != NULL) { - int matchlen = strlen(m + len); + int matchlen = strlen(m + skiplen); if (!matchlen) goto matched; - if (!strncmp(m + len, filename + len, matchlen)) { - if (m[len + matchlen - 1] == '/') + if (!strncmp(m + skiplen, filename + skiplen, matchlen)) { + if (m[skiplen + matchlen - 1] == '/') goto matched; - switch (filename[len + matchlen]) { + switch (filename[skiplen + matchlen]) { case '/': case '\0': goto matched; } } - if (!fnmatch(m + len, filename + len, 0)) + if (!fnmatch(m + skiplen, filename + skiplen, 0)) goto matched; if (ps_matched) ps_matched++; @@ -80,7 +80,7 @@ static void show_dir_entry(const char *tag, struct dir_entry *ent) if (len >= ent->len) die("git-ls-files: internal error - directory entry not superset of prefix"); - if (pathspec && !match(pathspec, ps_matched, ent->name, len)) + if (pathspec && !pathspec_match(pathspec, ps_matched, ent->name, len)) return; fputs(tag, stdout); @@ -185,7 +185,7 @@ static void show_ce_entry(const char *tag, struct cache_entry *ce) if (len >= ce_namelen(ce)) die("git-ls-files: internal error - cache entry not superset of prefix"); - if (pathspec && !match(pathspec, ps_matched, ce->name, len)) + if (pathspec && !pathspec_match(pathspec, ps_matched, ce->name, len)) return; if (tag && *tag && show_valid_bit && @@ -331,7 +331,7 @@ static const char *verify_pathspec(const char *prefix) * that were given from the command line. We are not * going to write this index out. */ -static void overlay_tree(const char *tree_name, const char *prefix) +void overlay_tree_on_cache(const char *tree_name, const char *prefix) { struct tree *tree; unsigned char sha1[20]; @@ -384,6 +384,42 @@ static void overlay_tree(const char *tree_name, const char *prefix) } } +int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset) +{ + /* + * Make sure all pathspec matched; otherwise it is an error. + */ + int num, errors = 0; + for (num = 0; pathspec[num]; num++) { + int other, found_dup; + + if (ps_matched[num]) + continue; + /* + * The caller might have fed identical pathspec + * twice. Do not barf on such a mistake. + */ + for (found_dup = other = 0; + !found_dup && pathspec[other]; + other++) { + if (other == num || !ps_matched[other]) + continue; + if (!strcmp(pathspec[other], pathspec[num])) + /* + * Ok, we have a match already. + */ + found_dup = 1; + } + if (found_dup) + continue; + + error("pathspec '%s' did not match any file(s) known to git.", + pathspec[num] + prefix_offset); + errors++; + } + return errors; +} + static const char ls_files_usage[] = "git-ls-files [-z] [-t] [-v] (--[cached|deleted|others|stage|unmerged|killed|modified])* " "[ --ignored ] [--exclude=<pattern>] [--exclude-from=<file>] " @@ -568,47 +604,17 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix) */ if (show_stage || show_unmerged) die("ls-files --with-tree is incompatible with -s or -u"); - overlay_tree(with_tree, prefix); + overlay_tree_on_cache(with_tree, prefix); } show_files(&dir, prefix); if (ps_matched) { - /* We need to make sure all pathspec matched otherwise - * it is an error. - */ - int num, errors = 0; - for (num = 0; pathspec[num]; num++) { - int other, found_dup; - - if (ps_matched[num]) - continue; - /* - * The caller might have fed identical pathspec - * twice. Do not barf on such a mistake. - */ - for (found_dup = other = 0; - !found_dup && pathspec[other]; - other++) { - if (other == num || !ps_matched[other]) - continue; - if (!strcmp(pathspec[other], pathspec[num])) - /* - * Ok, we have a match already. - */ - found_dup = 1; - } - if (found_dup) - continue; - - error("pathspec '%s' did not match any file(s) known to git.", - pathspec[num] + prefix_offset); - errors++; - } - - if (errors) + int bad; + bad = report_path_error(ps_matched, pathspec, prefix_offset); + if (bad) fprintf(stderr, "Did you forget to 'git add'?\n"); - return errors ? 1 : 0; + return bad ? 1 : 0; } return 0; diff --git a/builtin-ls-remote.c b/builtin-ls-remote.c index 56f3f88023..c2caeeabe2 100644 --- a/builtin-ls-remote.c +++ b/builtin-ls-remote.c @@ -6,6 +6,27 @@ static const char ls_remote_usage[] = "git-ls-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>"; +/* + * Is there one among the list of patterns that match the tail part + * of the path? + */ +static int tail_match(const char **pattern, const char *path) +{ + const char *p; + char pathbuf[PATH_MAX]; + + if (!pattern) + return 1; /* no restriction */ + + if (snprintf(pathbuf, sizeof(pathbuf), "/%s", path) > sizeof(pathbuf)) + return error("insanely long ref %.*s...", 20, path); + while ((p = *(pattern++)) != NULL) { + if (!fnmatch(p, pathbuf, 0)) + return 1; + } + return 0; +} + int cmd_ls_remote(int argc, const char **argv, const char *prefix) { int i; @@ -13,6 +34,7 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) int nongit = 0; unsigned flags = 0; const char *uploadpack = NULL; + const char **pattern = NULL; struct remote *remote; struct transport *transport; @@ -47,12 +69,23 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) usage(ls_remote_usage); } dest = arg; + i++; break; } - if (!dest || i != argc - 1) + if (!dest) usage(ls_remote_usage); + if (argv[i]) { + int j; + pattern = xcalloc(sizeof(const char *), argc - i + 1); + for (j = i; j < argc; j++) { + int len = strlen(argv[j]); + char *p = xmalloc(len + 3); + sprintf(p, "*/%s", argv[j]); + pattern[j - i] = p; + } + } remote = nongit ? NULL : remote_get(dest); if (remote && !remote->url_nr) die("remote %s has no configured URL", dest); @@ -65,10 +98,12 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix) if (!ref) return 1; - while (ref) { - if (check_ref_type(ref, flags)) - printf("%s %s\n", sha1_to_hex(ref->old_sha1), ref->name); - ref = ref->next; + for ( ; ref; ref = ref->next) { + if (!check_ref_type(ref, flags)) + continue; + if (!tail_match(pattern, ref->name)) + continue; + printf("%s %s\n", sha1_to_hex(ref->old_sha1), ref->name); } return 0; } diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c index 4f446588ac..250dc56ab5 100644 --- a/builtin-pack-objects.c +++ b/builtin-pack-objects.c @@ -1245,28 +1245,37 @@ static void get_object_details(void) free(sorted_by_offset); } +/* + * We search for deltas in a list sorted by type, by filename hash, and then + * by size, so that we see progressively smaller and smaller files. + * That's because we prefer deltas to be from the bigger file + * to the smaller -- deletes are potentially cheaper, but perhaps + * more importantly, the bigger file is likely the more recent + * one. The deepest deltas are therefore the oldest objects which are + * less susceptible to be accessed often. + */ static int type_size_sort(const void *_a, const void *_b) { const struct object_entry *a = *(struct object_entry **)_a; const struct object_entry *b = *(struct object_entry **)_b; - if (a->type < b->type) - return -1; if (a->type > b->type) - return 1; - if (a->hash < b->hash) return -1; - if (a->hash > b->hash) + if (a->type < b->type) return 1; - if (a->preferred_base < b->preferred_base) + if (a->hash > b->hash) return -1; - if (a->preferred_base > b->preferred_base) + if (a->hash < b->hash) return 1; - if (a->size < b->size) + if (a->preferred_base > b->preferred_base) return -1; + if (a->preferred_base < b->preferred_base) + return 1; if (a->size > b->size) + return -1; + if (a->size < b->size) return 1; - return a > b ? -1 : (a < b); /* newest last */ + return a < b ? -1 : (a > b); /* newest first */ } struct unpacked { @@ -1317,14 +1326,6 @@ static pthread_mutex_t progress_mutex = PTHREAD_MUTEX_INITIALIZER; #endif -/* - * We search for deltas _backwards_ in a list sorted by type and - * by size, so that we see progressively smaller and smaller files. - * That's because we prefer deltas to be from the bigger file - * to the smaller - deletes are potentially cheaper, but perhaps - * more importantly, the bigger file is likely the more recent - * one. - */ static int try_delta(struct unpacked *trg, struct unpacked *src, unsigned max_depth, unsigned long *mem_usage) { @@ -1422,10 +1423,6 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, } } - trg_entry->delta = src_entry; - trg_entry->delta_size = delta_size; - trg->depth = src->depth + 1; - /* * Handle memory allocation outside of the cache * accounting lock. Compiler will optimize the strangeness @@ -1439,7 +1436,7 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, trg_entry->delta_data = NULL; } if (delta_cacheable(src_size, trg_size, delta_size)) { - delta_cache_size += trg_entry->delta_size; + delta_cache_size += delta_size; cache_unlock(); trg_entry->delta_data = xrealloc(delta_buf, delta_size); } else { @@ -1447,6 +1444,10 @@ static int try_delta(struct unpacked *trg, struct unpacked *src, free(delta_buf); } + trg_entry->delta = src_entry; + trg_entry->delta_size = delta_size; + trg->depth = src->depth + 1; + return 1; } @@ -1478,10 +1479,10 @@ static unsigned long free_unpacked(struct unpacked *n) return freed_mem; } -static void find_deltas(struct object_entry **list, unsigned list_size, +static void find_deltas(struct object_entry **list, unsigned *list_size, int window, int depth, unsigned *processed) { - uint32_t i = list_size, idx = 0, count = 0; + uint32_t i, idx = 0, count = 0; unsigned int array_size = window * sizeof(struct unpacked); struct unpacked *array; unsigned long mem_usage = 0; @@ -1489,11 +1490,23 @@ static void find_deltas(struct object_entry **list, unsigned list_size, array = xmalloc(array_size); memset(array, 0, array_size); - do { - struct object_entry *entry = list[--i]; + for (;;) { + struct object_entry *entry = *list++; struct unpacked *n = array + idx; int j, max_depth, best_base = -1; + progress_lock(); + if (!*list_size) { + progress_unlock(); + break; + } + (*list_size)--; + if (!entry->preferred_base) { + (*processed)++; + display_progress(progress_state, *processed); + } + progress_unlock(); + mem_usage -= free_unpacked(n); n->entry = entry; @@ -1511,11 +1524,6 @@ static void find_deltas(struct object_entry **list, unsigned list_size, if (entry->preferred_base) goto next; - progress_lock(); - (*processed)++; - display_progress(progress_state, *processed); - progress_unlock(); - /* * If the current object is at pack edge, take the depth the * objects that depend on the current object into account @@ -1575,7 +1583,7 @@ static void find_deltas(struct object_entry **list, unsigned list_size, count++; if (idx >= window) idx = 0; - } while (i > 0); + } for (i = 0; i < window; ++i) { free_delta_index(array[i].index); @@ -1590,6 +1598,7 @@ struct thread_params { pthread_t thread; struct object_entry **list; unsigned list_size; + unsigned remaining; int window; int depth; unsigned *processed; @@ -1611,10 +1620,10 @@ static void *threaded_find_deltas(void *arg) pthread_mutex_lock(&data_ready); pthread_mutex_unlock(&data_request); - if (!me->list_size) + if (!me->remaining) return NULL; - find_deltas(me->list, me->list_size, + find_deltas(me->list, &me->remaining, me->window, me->depth, me->processed); } } @@ -1623,57 +1632,102 @@ static void ll_find_deltas(struct object_entry **list, unsigned list_size, int window, int depth, unsigned *processed) { struct thread_params *target, p[delta_search_threads]; - int i, ret; - unsigned chunk_size; + int i, ret, active_threads = 0; if (delta_search_threads <= 1) { - find_deltas(list, list_size, window, depth, processed); + find_deltas(list, &list_size, window, depth, processed); return; } pthread_mutex_lock(&data_provider); pthread_mutex_lock(&data_ready); + /* Start work threads. */ for (i = 0; i < delta_search_threads; i++) { p[i].window = window; p[i].depth = depth; p[i].processed = processed; + p[i].remaining = 0; ret = pthread_create(&p[i].thread, NULL, threaded_find_deltas, &p[i]); if (ret) die("unable to create thread: %s", strerror(ret)); + active_threads++; } - /* this should be auto-tuned somehow */ - chunk_size = window * 1000; + /* Then partition the work amongst them. */ + for (i = 0; i < delta_search_threads; i++) { + unsigned sub_size = list_size / (delta_search_threads - i); - do { - unsigned sublist_size = chunk_size; - if (sublist_size > list_size) - sublist_size = list_size; + pthread_mutex_lock(&data_provider); + target = data_requester; + if (!sub_size) { + pthread_mutex_unlock(&data_ready); + pthread_join(target->thread, NULL); + active_threads--; + continue; + } /* try to split chunks on "path" boundaries */ - while (sublist_size < list_size && list[sublist_size]->hash && - list[sublist_size]->hash == list[sublist_size-1]->hash) - sublist_size++; + while (sub_size < list_size && list[sub_size]->hash && + list[sub_size]->hash == list[sub_size-1]->hash) + sub_size++; + + target->list = list; + target->list_size = sub_size; + target->remaining = sub_size; + pthread_mutex_unlock(&data_ready); + list += sub_size; + list_size -= sub_size; + } + + /* + * Now let's wait for work completion. Each time a thread is done + * with its work, we steal half of the remaining work from the + * thread with the largest number of unprocessed objects and give + * it to that newly idle thread. This ensure good load balancing + * until the remaining object list segments are simply too short + * to be worth splitting anymore. + */ + do { + struct thread_params *victim = NULL; + unsigned sub_size = 0; pthread_mutex_lock(&data_provider); target = data_requester; - target->list = list; - target->list_size = sublist_size; + + progress_lock(); + for (i = 0; i < delta_search_threads; i++) + if (p[i].remaining > 2*window && + (!victim || victim->remaining < p[i].remaining)) + victim = &p[i]; + if (victim) { + sub_size = victim->remaining / 2; + list = victim->list + victim->list_size - sub_size; + while (sub_size && list[0]->hash && + list[0]->hash == list[-1]->hash) { + list++; + sub_size--; + } + target->list = list; + victim->list_size -= sub_size; + victim->remaining -= sub_size; + } + progress_unlock(); + + target->list_size = sub_size; + target->remaining = sub_size; pthread_mutex_unlock(&data_ready); - list += sublist_size; - list_size -= sublist_size; - if (!sublist_size) { + if (!sub_size) { pthread_join(target->thread, NULL); - i--; + active_threads--; } - } while (i); + } while (active_threads); } #else -#define ll_find_deltas find_deltas +#define ll_find_deltas(l, s, w, d, p) find_deltas(l, &s, w, d, p) #endif static void prepare_pack(int window, int depth) diff --git a/builtin-push.c b/builtin-push.c index 41df717f84..c8cb63e238 100644 --- a/builtin-push.c +++ b/builtin-push.c @@ -44,6 +44,15 @@ static void set_refspecs(const char **refs, int nr) strcat(tag, refs[i]); ref = tag; } + if (!strcmp("HEAD", ref)) { + unsigned char sha1_dummy[20]; + ref = resolve_ref(ref, sha1_dummy, 1, NULL); + if (!ref) + die("HEAD cannot be resolved."); + if (prefixcmp(ref, "refs/heads/")) + die("HEAD cannot be resolved to branch."); + ref = xstrdup(ref + 11); + } add_refspec(ref); } } diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c index d1038a0e66..20d1789e01 100644 --- a/builtin-rev-parse.c +++ b/builtin-rev-parse.c @@ -327,7 +327,7 @@ static int cmd_parseopt(int argc, const char **argv, const char *prefix) keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0); strbuf_addf(&parsed, " --"); - sq_quote_argv(&parsed, argv, argc, 0); + sq_quote_argv(&parsed, argv, 0); puts(parsed.buf); return 0; } diff --git a/builtin-runstatus.c b/builtin-runstatus.c index 2db25c88bf..8d167a9674 100644 --- a/builtin-runstatus.c +++ b/builtin-runstatus.c @@ -14,6 +14,7 @@ int cmd_runstatus(int argc, const char **argv, const char *prefix) git_config(git_status_config); wt_status_prepare(&s); + s.prefix = prefix; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "--color")) diff --git a/builtin-shortlog.c b/builtin-shortlog.c index 3fe754677d..b9cc134443 100644 --- a/builtin-shortlog.c +++ b/builtin-shortlog.c @@ -27,45 +27,60 @@ static int compare_by_number(const void *a1, const void *a2) static struct path_list mailmap = {NULL, 0, 0, 0}; -static void insert_author_oneline(struct path_list *list, - const char *author, int authorlen, - const char *oneline, int onelinelen) +static void insert_one_record(struct path_list *list, + const char *author, + const char *oneline) { const char *dot3 = common_repo_prefix; char *buffer, *p; struct path_list_item *item; struct path_list *onelines; + char namebuf[1024]; + size_t len; + const char *eol; + const char *boemail, *eoemail; + + boemail = strchr(author, '<'); + if (!boemail) + return; + eoemail = strchr(boemail, '>'); + if (!eoemail) + return; + if (!map_email(&mailmap, boemail+1, namebuf, sizeof(namebuf))) { + while (author < boemail && isspace(*author)) + author++; + for (len = 0; + len < sizeof(namebuf) - 1 && author + len < boemail; + len++) + namebuf[len] = author[len]; + while (0 < len && isspace(namebuf[len-1])) + len--; + namebuf[len] = '\0'; + } - while (authorlen > 0 && isspace(author[authorlen - 1])) - authorlen--; - - buffer = xmemdupz(author, authorlen); + buffer = xstrdup(namebuf); item = path_list_insert(buffer, list); if (item->util == NULL) item->util = xcalloc(1, sizeof(struct path_list)); else free(buffer); + eol = strchr(oneline, '\n'); + if (!eol) + eol = oneline + strlen(oneline); + while (*oneline && isspace(*oneline) && *oneline != '\n') + oneline++; if (!prefixcmp(oneline, "[PATCH")) { char *eob = strchr(oneline, ']'); - - if (eob) { - while (isspace(eob[1]) && eob[1] != '\n') - eob++; - if (eob - oneline < onelinelen) { - onelinelen -= eob - oneline; - oneline = eob; - } - } + if (eob && (!eol || eob < eol)) + oneline = eob + 1; } - - while (onelinelen > 0 && isspace(oneline[0])) { + while (*oneline && isspace(*oneline) && *oneline != '\n') oneline++; - onelinelen--; - } - while (onelinelen > 0 && isspace(oneline[onelinelen - 1])) - onelinelen--; - buffer = xmemdupz(oneline, onelinelen); + len = eol - oneline; + while (len && isspace(oneline[len-1])) + len--; + buffer = xmemdupz(oneline, len); if (dot3) { int dot3len = strlen(dot3); @@ -92,55 +107,32 @@ static void insert_author_oneline(struct path_list *list, static void read_from_stdin(struct path_list *list) { - char buffer[1024]; - - while (fgets(buffer, sizeof(buffer), stdin) != NULL) { - char *bob; - if ((buffer[0] == 'A' || buffer[0] == 'a') && - !prefixcmp(buffer + 1, "uthor: ") && - (bob = strchr(buffer + 7, '<')) != NULL) { - char buffer2[1024], offset = 0; - - if (map_email(&mailmap, bob + 1, buffer, sizeof(buffer))) - bob = buffer + strlen(buffer); - else { - offset = 8; - while (buffer + offset < bob && - isspace(bob[-1])) - bob--; - } - - while (fgets(buffer2, sizeof(buffer2), stdin) && - buffer2[0] != '\n') - ; /* chomp input */ - if (fgets(buffer2, sizeof(buffer2), stdin)) { - int l2 = strlen(buffer2); - int i; - for (i = 0; i < l2; i++) - if (!isspace(buffer2[i])) - break; - insert_author_oneline(list, - buffer + offset, - bob - buffer - offset, - buffer2 + i, l2 - i); - } - } + char author[1024], oneline[1024]; + + while (fgets(author, sizeof(author), stdin) != NULL) { + if (!(author[0] == 'A' || author[0] == 'a') || + prefixcmp(author + 1, "uthor: ")) + continue; + while (fgets(oneline, sizeof(oneline), stdin) && + oneline[0] != '\n') + ; /* discard headers */ + while (fgets(oneline, sizeof(oneline), stdin) && + oneline[0] == '\n') + ; /* discard blanks */ + insert_one_record(list, author + 8, oneline); } } static void get_from_rev(struct rev_info *rev, struct path_list *list) { - char scratch[1024]; struct commit *commit; prepare_revision_walk(rev); while ((commit = get_revision(rev)) != NULL) { - const char *author = NULL, *oneline, *buffer; - int authorlen = authorlen, onelinelen; + const char *author = NULL, *buffer; - /* get author and oneline */ - for (buffer = commit->buffer; buffer && *buffer != '\0' && - *buffer != '\n'; ) { + buffer = commit->buffer; + while (*buffer && *buffer != '\n') { const char *eol = strchr(buffer, '\n'); if (eol == NULL) @@ -148,50 +140,17 @@ static void get_from_rev(struct rev_info *rev, struct path_list *list) else eol++; - if (!prefixcmp(buffer, "author ")) { - char *bracket = strchr(buffer, '<'); - - if (bracket == NULL || bracket > eol) - die("Invalid commit buffer: %s", - sha1_to_hex(commit->object.sha1)); - - if (map_email(&mailmap, bracket + 1, scratch, - sizeof(scratch))) { - author = scratch; - authorlen = strlen(scratch); - } else { - if (bracket[-1] == ' ') - bracket--; - - author = buffer + 7; - authorlen = bracket - buffer - 7; - } - } + if (!prefixcmp(buffer, "author ")) + author = buffer + 7; buffer = eol; } - - if (author == NULL) - die ("Missing author: %s", - sha1_to_hex(commit->object.sha1)); - - if (buffer == NULL || *buffer == '\0') { - oneline = "<none>"; - onelinelen = sizeof(oneline) + 1; - } else { - char *eol; - - oneline = buffer + 1; - eol = strchr(oneline, '\n'); - if (eol == NULL) - onelinelen = strlen(oneline); - else - onelinelen = eol - oneline; - } - - insert_author_oneline(list, - author, authorlen, oneline, onelinelen); + if (!author) + die("Missing author: %s", + sha1_to_hex(commit->object.sha1)); + if (*buffer) + buffer++; + insert_one_record(list, author, !*buffer ? "<none>" : buffer); } - } static int parse_uint(char const **arg, int comma) diff --git a/builtin-tag.c b/builtin-tag.c index 114c684d24..517419fd3d 100644 --- a/builtin-tag.c +++ b/builtin-tag.c @@ -23,11 +23,9 @@ static const char * const git_tag_usage[] = { static char signingkey[1000]; -static void launch_editor(const char *path, struct strbuf *buffer) +void launch_editor(const char *path, struct strbuf *buffer, const char *const *env) { const char *editor, *terminal; - struct child_process child; - const char *args[3]; editor = getenv("GIT_EDITOR"); if (!editor && editor_program) @@ -48,15 +46,15 @@ static void launch_editor(const char *path, struct strbuf *buffer) if (!editor) editor = "vi"; - memset(&child, 0, sizeof(child)); - child.argv = args; - args[0] = editor; - args[1] = path; - args[2] = NULL; + if (strcmp(editor, ":")) { + const char *args[] = { editor, path, NULL }; - if (run_command(&child)) - die("There was a problem with the editor %s.", editor); + if (run_command_v_opt_cd_env(args, 0, NULL, env)) + die("There was a problem with the editor %s.", editor); + } + if (!buffer) + return; if (strbuf_read_file(buffer, path, 0) < 0) die("could not read message file '%s': %s", path, strerror(errno)); @@ -190,7 +188,7 @@ static int do_sign(struct strbuf *buffer) int len; if (!*signingkey) { - if (strlcpy(signingkey, git_committer_info(1), + if (strlcpy(signingkey, git_committer_info(IDENT_ERROR_ON_NO_NAME), sizeof(signingkey)) > sizeof(signingkey) - 1) return error("committer info too long."); bracket = strchr(signingkey, '>'); @@ -300,7 +298,7 @@ static void create_tag(const unsigned char *object, const char *tag, sha1_to_hex(object), typename(type), tag, - git_committer_info(1)); + git_committer_info(IDENT_ERROR_ON_NO_NAME)); if (header_len > sizeof(header_buf) - 1) die("tag header too big."); @@ -322,7 +320,7 @@ static void create_tag(const unsigned char *object, const char *tag, write_or_die(fd, tag_template, strlen(tag_template)); close(fd); - launch_editor(path, buf); + launch_editor(path, buf, NULL); unlink(path); free(path); @@ -25,6 +25,7 @@ extern int cmd_check_ref_format(int argc, const char **argv, const char *prefix) extern int cmd_cherry(int argc, const char **argv, const char *prefix); extern int cmd_cherry_pick(int argc, const char **argv, const char *prefix); extern int cmd_clean(int argc, const char **argv, const char *prefix); +extern int cmd_commit(int argc, const char **argv, const char *prefix); extern int cmd_commit_tree(int argc, const char **argv, const char *prefix); extern int cmd_count_objects(int argc, const char **argv, const char *prefix); extern int cmd_describe(int argc, const char **argv, const char *prefix); @@ -72,11 +73,11 @@ extern int cmd_rev_list(int argc, const char **argv, const char *prefix); extern int cmd_rev_parse(int argc, const char **argv, const char *prefix); extern int cmd_revert(int argc, const char **argv, const char *prefix); extern int cmd_rm(int argc, const char **argv, const char *prefix); -extern int cmd_runstatus(int argc, const char **argv, const char *prefix); extern int cmd_send_pack(int argc, const char **argv, const char *prefix); extern int cmd_shortlog(int argc, const char **argv, const char *prefix); extern int cmd_show(int argc, const char **argv, const char *prefix); extern int cmd_show_branch(int argc, const char **argv, const char *prefix); +extern int cmd_status(int argc, const char **argv, const char *prefix); extern int cmd_stripspace(int argc, const char **argv, const char *prefix); extern int cmd_symbolic_ref(int argc, const char **argv, const char *prefix); extern int cmd_tag(int argc, const char **argv, const char *prefix); @@ -423,6 +423,10 @@ extern const char *resolve_ref(const char *path, unsigned char *sha1, int, int * extern int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref); extern int dwim_log(const char *str, int len, unsigned char *sha1, char **ref); +extern int refname_match(const char *abbrev_name, const char *full_name, const char **rules); +extern const char *ref_rev_parse_rules[]; +extern const char *ref_fetch_rules[]; + extern int create_symref(const char *ref, const char *refs_heads_master, const char *logmsg); extern int validate_headref(const char *ref); @@ -449,9 +453,13 @@ void datestamp(char *buf, int bufsize); unsigned long approxidate(const char *); enum date_mode parse_date_format(const char *format); +#define IDENT_WARN_ON_NO_NAME 1 +#define IDENT_ERROR_ON_NO_NAME 2 +#define IDENT_NO_DATE 4 extern const char *git_author_info(int); extern const char *git_committer_info(int); extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int); +extern const char *fmt_name(const char *name, const char *email); struct checkout { const char *base_dir; @@ -620,17 +628,37 @@ extern void alloc_report(void); /* trace.c */ extern void trace_printf(const char *format, ...); -extern void trace_argv_printf(const char **argv, int count, const char *format, ...); +extern void trace_argv_printf(const char **argv, const char *format, ...); /* convert.c */ /* returns 1 if *dst was used */ extern int convert_to_git(const char *path, const char *src, size_t len, struct strbuf *dst); extern int convert_to_working_tree(const char *path, const char *src, size_t len, struct strbuf *dst); +/* add */ +void add_files_to_cache(int verbose, const char *prefix, const char **pathspec); + /* diff.c */ extern int diff_auto_refresh_index; /* match-trees.c */ void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int); +/* + * whitespace rules. + * used by both diff and apply + */ +#define WS_TRAILING_SPACE 01 +#define WS_SPACE_BEFORE_TAB 02 +#define WS_INDENT_WITH_NON_TAB 04 +#define WS_DEFAULT_RULE (WS_TRAILING_SPACE|WS_SPACE_BEFORE_TAB) +extern unsigned whitespace_rule_cfg; +extern unsigned whitespace_rule(const char *); +extern unsigned parse_whitespace_rule(const char *); + +/* ls-files */ +int pathspec_match(const char **spec, char *matched, const char *filename, int skiplen); +int report_path_error(const char *ps_matched, const char **pathspec, int prefix_offset); +void overlay_tree_on_cache(const char *tree_name, const char *prefix); + #endif /* CACHE_H */ @@ -116,7 +116,7 @@ bad: die("bad config value '%s' for variable '%s'", value, var); } -int git_config_colorbool(const char *var, const char *value) +int git_config_colorbool(const char *var, const char *value, int stdout_is_tty) { if (value) { if (!strcasecmp(value, "never")) @@ -133,7 +133,9 @@ int git_config_colorbool(const char *var, const char *value) /* any normal truth value defaults to 'auto' */ auto_color: - if (isatty(1) || (pager_in_use && pager_use_color)) { + if (stdout_is_tty < 0) + stdout_is_tty = isatty(1); + if (stdout_is_tty || (pager_in_use && pager_use_color)) { char *term = getenv("TERM"); if (term && strcmp(term, "dumb")) return 1; @@ -4,7 +4,7 @@ /* "\033[1;38;5;2xx;48;5;2xxm\0" is 23 bytes */ #define COLOR_MAXLEN 24 -int git_config_colorbool(const char *var, const char *value); +int git_config_colorbool(const char *var, const char *value, int stdout_is_tty); void color_parse(const char *var, const char *value, char *dst); int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); diff --git a/command-list.txt b/command-list.txt index 49506a411e..28342da959 100644 --- a/command-list.txt +++ b/command-list.txt @@ -33,6 +33,7 @@ git-diff mainporcelain common git-diff-files plumbinginterrogators git-diff-index plumbinginterrogators git-diff-tree plumbinginterrogators +git-fast-export ancillarymanipulators git-fast-import ancillarymanipulators git-fetch mainporcelain common git-fetch-pack synchingrepositories @@ -113,8 +113,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads, int in_merge_bases(struct commit *, struct commit **, int); -extern int interactive_add(void); -extern void add_files_to_cache(int verbose, const char *prefix, const char **files); +extern int interactive_add(int argc, const char **argv, const char *prefix); extern int rerere(void); static inline int single_parent(struct commit *commit) @@ -439,6 +439,11 @@ int git_default_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.whitespace")) { + whitespace_rule_cfg = parse_whitespace_rule(value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } @@ -646,13 +651,19 @@ static int store_write_pair(int fd, const char* key, const char* value) int length = strlen(key+store.baselen+1); int quote = 0; - /* Check to see if the value needs to be quoted. */ + /* + * Check to see if the value needs to be surrounded with a dq pair. + * Note that problematic characters are always backslash-quoted; this + * check is about not losing leading or trailing SP and strings that + * follow beginning-of-comment characters (i.e. ';' and '#') by the + * configuration parser. + */ if (value[0] == ' ') quote = 1; for (i = 0; value[i]; i++) if (value[i] == ';' || value[i] == '#') quote = 1; - if (value[i-1] == ' ') + if (i && value[i-1] == ' ') quote = 1; if (write_in_full(fd, "\t", 1) != 1 || diff --git a/config.mak.in b/config.mak.in index 11d256e9cf..7d5df9bf3c 100644 --- a/config.mak.in +++ b/config.mak.in @@ -41,4 +41,5 @@ NO_STRTOUMAX=@NO_STRTOUMAX@ NO_SETENV=@NO_SETENV@ NO_MKDTEMP=@NO_MKDTEMP@ NO_ICONV=@NO_ICONV@ +OLD_ICONV=@OLD_ICONV@ NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@ diff --git a/configure.ac b/configure.ac index 5f8a15b9f9..dd4b4eb982 100644 --- a/configure.ac +++ b/configure.ac @@ -212,6 +212,28 @@ test -n "$NEEDS_SOCKET" && LIBS="$LIBS -lsocket" ## Checks for header files. +AC_MSG_NOTICE([CHECKS for header files]) +# +# Define OLD_ICONV if your library has an old iconv(), where the second +# (input buffer pointer) parameter is declared with type (const char **). +AC_DEFUN([OLDICONVTEST_SRC], [[ +#include <iconv.h> + +extern size_t iconv(iconv_t cd, + char **inbuf, size_t *inbytesleft, + char **outbuf, size_t *outbytesleft); + +int main(void) +{ + return 0; +} +]]) +AC_MSG_CHECKING([for old iconv()]) +AC_COMPILE_IFELSE(OLDICONVTEST_SRC, + [AC_MSG_RESULT([no])], + [AC_MSG_RESULT([yes]) + OLD_ICONV=UnfortunatelyYes]) +AC_SUBST(OLD_ICONV) ## Checks for typedefs, structures, and compiler characteristics. diff --git a/git-commit.sh b/contrib/examples/git-commit.sh index 2c4a4062a5..2c4a4062a5 100755 --- a/git-commit.sh +++ b/contrib/examples/git-commit.sh diff --git a/contrib/hg-to-git/hg-to-git.py b/contrib/hg-to-git/hg-to-git.py index 7a1c3e497f..9befb92c41 100755 --- a/contrib/hg-to-git/hg-to-git.py +++ b/contrib/hg-to-git/hg-to-git.py @@ -211,7 +211,7 @@ for cset in range(int(tip) + 1): os.system('git-ls-files -x .hg --deleted | git-update-index --remove --stdin') # commit - os.system(getgitenv(user, date) + 'git-commit -a -F %s' % filecomment) + os.system(getgitenv(user, date) + 'git commit --allow-empty -a -F %s' % filecomment) os.unlink(filecomment) # tag diff --git a/contrib/remotes2config.sh b/contrib/remotes2config.sh index 5838b3ab05..1cda19f66a 100644..100755 --- a/contrib/remotes2config.sh +++ b/contrib/remotes2config.sh @@ -11,11 +11,11 @@ if [ -d "$GIT_DIR"/remotes ]; then { cd "$GIT_DIR"/remotes ls | while read f; do - name=$(printf "$f" | tr -c "A-Za-z0-9" ".") + name=$(printf "$f" | tr -c "A-Za-z0-9-" ".") sed -n \ - -e "s/^URL: \(.*\)$/remote.$name.url \1 ./p" \ - -e "s/^Pull: \(.*\)$/remote.$name.fetch \1 ^$ /p" \ - -e "s/^Push: \(.*\)$/remote.$name.push \1 ^$ /p" \ + -e "s/^URL:[ ]*\(.*\)$/remote.$name.url \1 ./p" \ + -e "s/^Pull:[ ]*\(.*\)$/remote.$name.fetch \1 ^$ /p" \ + -e "s/^Push:[ ]*\(.*\)$/remote.$name.push \1 ^$ /p" \ < "$f" done echo done @@ -146,7 +146,7 @@ int git_diff_ui_config(const char *var, const char *value) return 0; } if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) { - diff_use_color_default = git_config_colorbool(var, value); + diff_use_color_default = git_config_colorbool(var, value, -1); return 0; } if (!strcmp(var, "diff.renames")) { @@ -454,6 +454,7 @@ static void diff_words_show(struct diff_words_data *diff_words) struct emit_callback { struct xdiff_emit_state xm; int nparents, color_diff; + unsigned ws_rule; const char **label_path; struct diff_words_data *diff_words; int *found_changesp; @@ -493,8 +494,8 @@ static void emit_line(const char *set, const char *reset, const char *line, int } static void emit_line_with_ws(int nparents, - const char *set, const char *reset, const char *ws, - const char *line, int len) + const char *set, const char *reset, const char *ws, + const char *line, int len, unsigned ws_rule) { int col0 = nparents; int last_tab_in_indent = -1; @@ -502,13 +503,17 @@ static void emit_line_with_ws(int nparents, int i; int tail = len; int need_highlight_leading_space = 0; - /* The line is a newly added line. Does it have funny leading - * whitespaces? In indent, SP should never precede a TAB. + /* + * The line is a newly added line. Does it have funny leading + * whitespaces? In indent, SP should never precede a TAB. In + * addition, under "indent with non tab" rule, there should not + * be more than 8 consecutive spaces. */ for (i = col0; i < len; i++) { if (line[i] == '\t') { last_tab_in_indent = i; - if (0 <= last_space_in_indent) + if ((ws_rule & WS_SPACE_BEFORE_TAB) && + 0 <= last_space_in_indent) need_highlight_leading_space = 1; } else if (line[i] == ' ') @@ -516,6 +521,13 @@ static void emit_line_with_ws(int nparents, else break; } + if ((ws_rule & WS_INDENT_WITH_NON_TAB) && + 0 <= last_space_in_indent && + last_tab_in_indent < 0 && + 8 <= (i - col0)) { + last_tab_in_indent = i; + need_highlight_leading_space = 1; + } fputs(set, stdout); fwrite(line, col0, 1, stdout); fputs(reset, stdout); @@ -540,10 +552,12 @@ static void emit_line_with_ws(int nparents, tail = len - 1; if (line[tail] == '\n' && i < tail) tail--; - while (i < tail) { - if (!isspace(line[tail])) - break; - tail--; + if (ws_rule & WS_TRAILING_SPACE) { + while (i < tail) { + if (!isspace(line[tail])) + break; + tail--; + } } if ((i < tail && line[tail + 1] != '\n')) { /* This has whitespace between tail+1..len */ @@ -565,7 +579,7 @@ static void emit_add_line(const char *reset, struct emit_callback *ecbdata, cons emit_line(set, reset, line, len); else emit_line_with_ws(ecbdata->nparents, set, reset, ws, - line, len); + line, len, ecbdata->ws_rule); } static void fn_out_consume(void *priv, char *line, unsigned long len) @@ -981,6 +995,7 @@ struct checkdiff_t { struct xdiff_emit_state xm; const char *filename; int lineno, color_diff; + unsigned ws_rule; }; static void checkdiff_consume(void *priv, char *line, unsigned long len) @@ -1016,7 +1031,8 @@ static void checkdiff_consume(void *priv, char *line, unsigned long len) if (white_space_at_end) printf("white space at end"); printf(":%s ", reset); - emit_line_with_ws(1, set, reset, ws, line, len); + emit_line_with_ws(1, set, reset, ws, line, len, + data->ws_rule); } data->lineno++; @@ -1317,6 +1333,7 @@ static void builtin_diff(const char *name_a, ecbdata.label_path = lbl; ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF); ecbdata.found_changesp = &o->found_changes; + ecbdata.ws_rule = whitespace_rule(name_b ? name_b : name_a); xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts; xecfg.ctxlen = o->context; xecfg.flags = XDL_EMIT_FUNCNAMES; @@ -1410,6 +1427,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b, data.filename = name_b ? name_b : name_a; data.lineno = 0; data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF); + data.ws_rule = whitespace_rule(data.filename); if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0) die("unable to read files to diff"); @@ -692,7 +692,7 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i int file_exists(const char *f) { struct stat sb; - return stat(f, &sb) == 0; + return lstat(f, &sb) == 0; } /* diff --git a/environment.c b/environment.c index 1dab72ec15..f3e3d4138d 100644 --- a/environment.c +++ b/environment.c @@ -36,6 +36,7 @@ int pager_use_color = 1; char *editor_program; char *excludes_file; int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */ +unsigned whitespace_rule_cfg = WS_DEFAULT_RULE; /* This is set by setup_git_dir_gently() and/or git_default_config() */ char *git_work_tree_cfg; diff --git a/exec_cmd.c b/exec_cmd.c index 2d0a758512..e189caca62 100644 --- a/exec_cmd.c +++ b/exec_cmd.c @@ -80,7 +80,7 @@ int execv_git_cmd(const char **argv) tmp = argv[0]; argv[0] = cmd.buf; - trace_argv_printf(argv, -1, "trace: exec:"); + trace_argv_printf(argv, "trace: exec:"); /* execvp() can only ever return if it fails */ execvp(cmd.buf, (char **)argv); diff --git a/git-add--interactive.perl b/git-add--interactive.perl index fb1e92a766..0cdd80073b 100755 --- a/git-add--interactive.perl +++ b/git-add--interactive.perl @@ -1,6 +1,58 @@ #!/usr/bin/perl -w use strict; +use Git; + +# Prompt colors: +my ($prompt_color, $header_color, $help_color, $normal_color); +# Diff colors: +my ($new_color, $old_color, $fraginfo_color, $metainfo_color, $whitespace_color); + +my ($use_color, $diff_use_color); +my $repo = Git->repository(); + +$use_color = $repo->get_colorbool('color.interactive'); + +if ($use_color) { + # Set interactive colors: + + # Grab the 3 main colors in git color string format, with sane + # (visible) defaults: + $prompt_color = $repo->get_color("color.interactive.prompt", "bold blue"); + $header_color = $repo->get_color("color.interactive.header", "bold"); + $help_color = $repo->get_color("color.interactive.help", "red bold"); + $normal_color = $repo->get_color("", "reset"); + + # Do we also set diff colors? + $diff_use_color = $repo->get_colorbool('color.diff'); + if ($diff_use_color) { + $new_color = $repo->get_color("color.diff.new", "green"); + $old_color = $repo->get_color("color.diff.old", "red"); + $fraginfo_color = $repo->get_color("color.diff.frag", "cyan"); + $metainfo_color = $repo->get_color("color.diff.meta", "bold"); + $whitespace_color = $repo->get_color("color.diff.whitespace", "normal red"); + } +} + +sub colored { + my $color = shift; + my $string = join("", @_); + + if ($use_color) { + # Put a color code at the beginning of each line, a reset at the end + # color after newlines that are not at the end of the string + $string =~ s/(\n+)(.)/$1$color$2/g; + # reset before newlines + $string =~ s/(\n+)/$normal_color$1/g; + # codes at beginning and end (if necessary): + $string =~ s/^/$color/; + $string =~ s/$/$normal_color/ unless $string =~ /\n$/; + } + return $string; +} + +# command line options +my $patch_mode; sub run_cmd_pipe { if ($^O eq 'MSWin32') { @@ -37,14 +89,13 @@ sub list_untracked { chomp $_; $_; } - run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @_); + 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'); # Returns list of hashes, contents of each of which are: -# PRINT: print message # VALUE: pathname # BINARY: is a binary path # INDEX: is index different from HEAD? @@ -56,9 +107,17 @@ sub list_modified { my ($only) = @_; my (%data, @return); my ($add, $del, $adddel, $file); + my @tracked = (); + + if (@ARGV) { + @tracked = map { + chomp $_; $_; + } run_cmd_pipe(qw(git ls-files --exclude-standard --), @ARGV); + return if (!@tracked); + } for (run_cmd_pipe(qw(git diff-index --cached - --numstat --summary HEAD))) { + --numstat --summary HEAD --), @tracked)) { if (($add, $del, $file) = /^([-\d]+) ([-\d]+) (.*)/) { my ($change, $bin); @@ -81,7 +140,7 @@ sub list_modified { } } - for (run_cmd_pipe(qw(git diff-files --numstat --summary))) { + for (run_cmd_pipe(qw(git diff-files --numstat --summary --), @tracked)) { if (($add, $del, $file) = /^([-\d]+) ([-\d]+) (.*)/) { if (!exists $data{$file}) { @@ -122,8 +181,6 @@ sub list_modified { } push @return, +{ VALUE => $_, - PRINT => (sprintf $status_fmt, - $it->{INDEX}, $it->{FILE}, $_), %$it, }; } @@ -159,10 +216,106 @@ sub find_unique { return $found; } +# inserts string into trie and updates count for each character +sub update_trie { + my ($trie, $string) = @_; + foreach (split //, $string) { + $trie = $trie->{$_} ||= {COUNT => 0}; + $trie->{COUNT}++; + } +} + +# returns an array of tuples (prefix, remainder) +sub find_unique_prefixes { + my @stuff = @_; + my @return = (); + + # any single prefix exceeding the soft limit is omitted + # if any prefix exceeds the hard limit all are omitted + # 0 indicates no limit + my $soft_limit = 0; + my $hard_limit = 3; + + # build a trie modelling all possible options + my %trie; + foreach my $print (@stuff) { + if ((ref $print) eq 'ARRAY') { + $print = $print->[0]; + } + elsif ((ref $print) eq 'HASH') { + $print = $print->{VALUE}; + } + update_trie(\%trie, $print); + push @return, $print; + } + + # use the trie to find the unique prefixes + for (my $i = 0; $i < @return; $i++) { + my $ret = $return[$i]; + my @letters = split //, $ret; + my %search = %trie; + my ($prefix, $remainder); + my $j; + for ($j = 0; $j < @letters; $j++) { + my $letter = $letters[$j]; + if ($search{$letter}{COUNT} == 1) { + $prefix = substr $ret, 0, $j + 1; + $remainder = substr $ret, $j + 1; + last; + } + else { + my $prefix = substr $ret, 0, $j; + return () + if ($hard_limit && $j + 1 > $hard_limit); + } + %search = %{$search{$letter}}; + } + if ($soft_limit && $j + 1 > $soft_limit) { + $prefix = undef; + $remainder = $ret; + } + $return[$i] = [$prefix, $remainder]; + } + return @return; +} + +# filters out prefixes which have special meaning to list_and_choose() +sub is_valid_prefix { + my $prefix = shift; + return (defined $prefix) && + !($prefix =~ /[\s,]/) && # separators + !($prefix =~ /^-/) && # deselection + !($prefix =~ /^\d+/) && # selection + ($prefix ne '*') && # "all" wildcard + ($prefix ne '?'); # prompt help +} + +# given a prefix/remainder tuple return a string with the prefix highlighted +# for now use square brackets; later might use ANSI colors (underline, bold) +sub highlight_prefix { + my $prefix = shift; + my $remainder = shift; + + if (!defined $prefix) { + return $remainder; + } + + if (!is_valid_prefix($prefix)) { + return "$prefix$remainder"; + } + + if (!$use_color) { + return "[$prefix]$remainder"; + } + + return "$prompt_color$prefix$normal_color$remainder"; +} + sub list_and_choose { my ($opts, @stuff) = @_; my (@chosen, @return); my $i; + my @prefixes = find_unique_prefixes(@stuff) unless $opts->{LIST_ONLY}; TOPLOOP: while (1) { @@ -172,18 +325,26 @@ sub list_and_choose { if (!$opts->{LIST_FLAT}) { print " "; } - print "$opts->{HEADER}\n"; + print colored $header_color, "$opts->{HEADER}\n"; } for ($i = 0; $i < @stuff; $i++) { my $chosen = $chosen[$i] ? '*' : ' '; my $print = $stuff[$i]; - if (ref $print) { - if ((ref $print) eq 'ARRAY') { - $print = $print->[0]; - } - else { - $print = $print->{PRINT}; - } + my $ref = ref $print; + my $highlighted = highlight_prefix(@{$prefixes[$i]}) + if @prefixes; + if ($ref eq 'ARRAY') { + $print = $highlighted || $print->[0]; + } + elsif ($ref eq 'HASH') { + my $value = $highlighted || $print->{VALUE}; + $print = sprintf($status_fmt, + $print->{INDEX}, + $print->{FILE}, + $value); + } + else { + $print = $highlighted || $print; } printf("%s%2d: %s", $chosen, $i+1, $print); if (($opts->{LIST_FLAT}) && @@ -202,7 +363,7 @@ sub list_and_choose { return if ($opts->{LIST_ONLY}); - print $opts->{PROMPT}; + print colored $prompt_color, $opts->{PROMPT}; if ($opts->{SINGLETON}) { print "> "; } @@ -217,6 +378,12 @@ sub list_and_choose { } chomp $line; last if $line eq ''; + if ($line eq '?') { + $opts->{SINGLETON} ? + singleton_prompt_help_cmd() : + prompt_help_cmd(); + next TOPLOOP; + } for my $choice (split(/[\s,]+/, $line)) { my $choose = 1; my ($bottom, $top); @@ -252,7 +419,7 @@ sub list_and_choose { $chosen[$i] = $choose; } } - last if ($opts->{IMMEDIATE}); + last if ($opts->{IMMEDIATE} || $line eq '*'); } for ($i = 0; $i < @stuff; $i++) { if ($chosen[$i]) { @@ -262,6 +429,28 @@ sub list_and_choose { return @return; } +sub singleton_prompt_help_cmd { + print colored $help_color, <<\EOF ; +Prompt help: +1 - select a numbered item +foo - select item based on unique prefix + - (empty) select nothing +EOF +} + +sub prompt_help_cmd { + print colored $help_color, <<\EOF ; +Prompt help: +1 - select a single item +3-5 - select a range of items +2-3,6-9 - select multiple ranges +foo - select item based on unique prefix +-... - unselect specified items +* - choose all items + - (empty) finish selecting +EOF +} + sub status_cmd { list_and_choose({ LIST_ONLY => 1, HEADER => $status_head }, list_modified()); @@ -336,13 +525,19 @@ sub add_untracked_cmd { sub parse_diff { my ($path) = @_; my @diff = run_cmd_pipe(qw(git diff-files -p --), $path); - my (@hunk) = { TEXT => [] }; + my @colored = (); + if ($diff_use_color) { + @colored = run_cmd_pipe(qw(git diff-files -p --color --), $path); + } + my (@hunk) = { TEXT => [], DISPLAY => [] }; - for (@diff) { - if (/^@@ /) { - push @hunk, { TEXT => [] }; + for (my $i = 0; $i < @diff; $i++) { + if ($diff[$i] =~ /^@@ /) { + push @hunk, { TEXT => [], DISPLAY => [] }; } - push @{$hunk[-1]{TEXT}}, $_; + push @{$hunk[-1]{TEXT}}, $diff[$i]; + push @{$hunk[-1]{DISPLAY}}, + ($diff_use_color ? $colored[$i] : $diff[$i]); } return @hunk; } @@ -364,9 +559,11 @@ sub parse_hunk_header { } sub split_hunk { - my ($text) = @_; + my ($text, $display) = @_; my @split = (); - + if (!defined $display) { + $display = $text; + } # If there are context lines in the middle of a hunk, # it can be split, but we would need to take care of # overlaps later. @@ -380,16 +577,19 @@ sub split_hunk { my $i = $hunk_start - 1; my $this = +{ TEXT => [], + DISPLAY => [], OLD => $o_ofs, NEW => $n_ofs, OCNT => 0, NCNT => 0, ADDDEL => 0, POSTCTX => 0, + USE => undef, }; while (++$i < @$text) { my $line = $text->[$i]; + my $display = $display->[$i]; if ($line =~ /^ /) { if ($this->{ADDDEL} && !defined $next_hunk_start) { @@ -401,6 +601,7 @@ sub split_hunk { $next_hunk_start = $i; } push @{$this->{TEXT}}, $line; + push @{$this->{DISPLAY}}, $display; $this->{OCNT}++; $this->{NCNT}++; if (defined $next_hunk_start) { @@ -423,6 +624,7 @@ sub split_hunk { redo OUTER; } push @{$this->{TEXT}}, $line; + push @{$this->{DISPLAY}}, $display; $this->{ADDDEL}++; if ($line =~ /^-/) { $this->{OCNT}++; @@ -447,9 +649,14 @@ sub split_hunk { " +$n_ofs" . (($n_cnt != 1) ? ",$n_cnt" : '') . " @@\n"); + my $display_head = $head; unshift @{$hunk->{TEXT}}, $head; + if ($diff_use_color) { + $display_head = colored($fraginfo_color, $head); + } + unshift @{$hunk->{DISPLAY}}, $display_head; } - return map { $_->{TEXT} } @split; + return @split; } sub find_last_o_ctx { @@ -541,37 +748,46 @@ sub coalesce_overlapping_hunks { } sub help_patch_cmd { - print <<\EOF ; + print colored $help_color, <<\EOF ; y - stage this hunk n - do not stage this hunk -a - stage this and all the remaining hunks -d - do not stage this hunk nor any of the remaining hunks +a - stage this and all the remaining hunks in the file +d - do not stage this hunk nor any of the remaining hunks in the file j - leave this hunk undecided, see next undecided hunk J - leave this hunk undecided, see next hunk k - leave this hunk undecided, see previous undecided hunk K - leave this hunk undecided, see previous hunk s - split the current hunk into smaller hunks +? - print help EOF } sub patch_update_cmd { - my @mods = list_modified('file-only'); - @mods = grep { !($_->{BINARY}) } @mods; - return if (!@mods); + my @mods = grep { !($_->{BINARY}) } list_modified('file-only'); + my @them; - my ($it) = list_and_choose({ PROMPT => 'Patch update', - SINGLETON => 1, - IMMEDIATE => 1, - HEADER => $status_head, }, - @mods); - patch_update_file($it->{VALUE}) if ($it); + if (!@mods) { + print STDERR "No changes.\n"; + return 0; + } + if ($patch_mode) { + @them = @mods; + } + else { + @them = list_and_choose({ PROMPT => 'Patch update', + HEADER => $status_head, }, + @mods); + } + for (@them) { + patch_update_file($_->{VALUE}); + } } sub patch_update_file { my ($ix, $num); my $path = shift; my ($head, @hunk) = parse_diff($path); - for (@{$head->{TEXT}}) { + for (@{$head->{DISPLAY}}) { print; } $num = scalar @hunk; @@ -615,10 +831,10 @@ sub patch_update_file { if (hunk_splittable($hunk[$ix]{TEXT})) { $other .= '/s'; } - for (@{$hunk[$ix]{TEXT}}) { + for (@{$hunk[$ix]{DISPLAY}}) { print; } - print "Stage this hunk [y/n/a/d$other/?]? "; + print colored $prompt_color, "Stage this hunk [y/n/a/d$other/?]? "; my $line = <STDIN>; if ($line) { if ($line =~ /^y/i) { @@ -670,14 +886,12 @@ sub patch_update_file { next; } elsif ($other =~ /s/ && $line =~ /^s/) { - my @split = split_hunk($hunk[$ix]{TEXT}); + my @split = split_hunk($hunk[$ix]{TEXT}, $hunk[$ix]{DISPLAY}); if (1 < @split) { - print "Split into ", + print colored $header_color, "Split into ", scalar(@split), " hunks.\n"; } - splice(@hunk, $ix, 1, - map { +{ TEXT => $_, USE => undef } } - @split); + splice (@hunk, $ix, 1, @split); $num = scalar @hunk; next; } @@ -755,8 +969,7 @@ sub diff_cmd { HEADER => $status_head, }, @mods); return if (!@them); - system(qw(git diff-index -p --cached HEAD --), - map { $_->{VALUE} } @them); + system(qw(git diff -p --cached HEAD --), map { $_->{VALUE} } @them); } sub quit_cmd { @@ -765,7 +978,7 @@ sub quit_cmd { } sub help_cmd { - print <<\EOF ; + 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 @@ -775,6 +988,20 @@ add untracked - add contents of untracked files to the staged set of changes EOF } +sub process_args { + return unless @ARGV; + my $arg = shift @ARGV; + if ($arg eq "--patch") { + $patch_mode = 1; + $arg = shift @ARGV or die "missing --"; + die "invalid argument $arg, expecting --" + unless $arg eq "--"; + } + elsif ($arg ne "--") { + die "invalid argument $arg, expecting --"; + } +} + sub main_loop { my @cmd = ([ 'status', \&status_cmd, ], [ 'update', \&update_cmd, ], @@ -803,6 +1030,12 @@ sub main_loop { } } +process_args(); refresh(); -status_cmd(); -main_loop(); +if ($patch_mode) { + patch_update_cmd(); +} +else { + status_cmd(); + main_loop(); +} @@ -117,6 +117,10 @@ It does not apply to blobs recorded in its index." unset GITHEAD_$his_tree } +reread_subject () { + git stripspace <"$1" | sed -e 1q +} + prec=4 dotest=.dotest sign= utf8=t keep= skip= interactive= resolved= binary= resolvemsg= resume= @@ -307,9 +311,9 @@ do GIT_AUTHOR_EMAIL="$(sed -n '/^Email/ s/Email: //p' "$dotest/info")" GIT_AUTHOR_DATE="$(sed -n '/^Date/ s/Date: //p' "$dotest/info")" - if test -z "$GIT_AUTHOR_EMAIL" || test -z "$GIT_AUTHOR_DATE" + if test -z "$GIT_AUTHOR_EMAIL" then - echo "Patch does not have valid authorship information." + echo "Patch does not have a valid e-mail address." stop_here $this fi @@ -376,6 +380,7 @@ do [aA]*) action=yes interactive= ;; [nN]*) action=skip ;; [eE]*) git_editor "$dotest/final-commit" + SUBJECT=$(reread_subject "$dotest/final-commit") action=again ;; [vV]*) action=again LESS=-S ${PAGER:-less} "$dotest/patch" ;; diff --git a/git-bisect.sh b/git-bisect.sh index 7a6521ec3c..5385249890 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -324,8 +324,23 @@ bisect_next() { bisect_visualize() { bisect_next_check fail + + if test $# = 0 + then + case "${DISPLAY+set}" in + '') set git log ;; + set) set gitk ;; + esac + else + case "$1" in + git*|tig) ;; + -*) set git log "$@" ;; + *) set git "$@" ;; + esac + fi + not=$(git for-each-ref --format='%(refname)' "refs/bisect/good-*") - eval gitk refs/bisect/bad --not $not -- $(cat "$GIT_DIR/BISECT_NAMES") + eval '"$@"' refs/bisect/bad --not $not -- $(cat "$GIT_DIR/BISECT_NAMES") } bisect_reset() { @@ -449,7 +464,7 @@ case "$#" in next) # Not sure we want "next" at the UI level anymore. bisect_next "$@" ;; - visualize) + visualize|view) bisect_visualize "$@" ;; reset) bisect_reset "$@" ;; diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 0d55fec04f..ecded3b9cb 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -1211,13 +1211,13 @@ sub req_ci chdir $tmpdir; - # populate the temporary index based + # populate the temporary index system("git-read-tree", $parenthash); unless ($? == 0) { die "Error running git-read-tree $state->{module} $file_index $!"; } - $log->info("Created index '$file_index' with for head $state->{module} - exit status $?"); + $log->info("Created index '$file_index' for head $state->{module} - exit status $?"); my @committedfiles = (); my %oldmeta; @@ -1237,7 +1237,7 @@ sub req_ci my ( $filepart, $dirpart ) = filenamesplit($filename); - # do a checkout of the file if it part of this tree + # do a checkout of the file if it is part of this tree if ($wrev) { system('git-checkout-index', '-f', '-u', $filename); unless ($? == 0) { @@ -1324,11 +1324,11 @@ sub req_ci exit; } - # Check that this is allowed, just as we would with a receive-pack - my @cmd = ( $ENV{GIT_DIR}.'hooks/update', "refs/heads/$state->{module}", + ### Emulate git-receive-pack by running hooks/update + my @hook = ( $ENV{GIT_DIR}.'hooks/update', "refs/heads/$state->{module}", $parenthash, $commithash ); - if( -x $cmd[0] ) { - unless( system( @cmd ) == 0 ) + if( -x $hook[0] ) { + unless( system( @hook ) == 0 ) { $log->warn("Commit failed (update hook declined to update ref)"); print "error 1 Commit failed (update hook declined)\n"; @@ -1337,6 +1337,7 @@ sub req_ci } } + ### Update the ref if (system(qw(git update-ref -m), "cvsserver ci", "refs/heads/$state->{module}", $commithash, $parenthash)) { $log->warn("update-ref for $state->{module} failed."); @@ -1344,6 +1345,24 @@ sub req_ci exit; } + ### Emulate git-receive-pack by running hooks/post-receive + my $hook = $ENV{GIT_DIR}.'hooks/post-receive'; + if( -x $hook ) { + open(my $pipe, "| $hook") || die "can't fork $!"; + + local $SIG{PIPE} = sub { die 'pipe broke' }; + + print $pipe "$parenthash $commithash refs/heads/$state->{module}\n"; + + close $pipe || die "bad pipe: $! $?"; + } + + ### Then hooks/post-update + $hook = $ENV{GIT_DIR}.'hooks/post-update'; + if (-x $hook) { + system($hook, "refs/heads/$state->{module}"); + } + $updater->update(); # foreach file specified on the command line ... diff --git a/git-gui/Makefile b/git-gui/Makefile index e860319278..26ac4b6bb0 100644 --- a/git-gui/Makefile +++ b/git-gui/Makefile @@ -43,11 +43,11 @@ endif RM_RF ?= rm -rf RMDIR ?= rmdir -INSTALL_D0 = $(INSTALL) -d -m755 # space is required here +INSTALL_D0 = $(INSTALL) -d -m 755 # space is required here INSTALL_D1 = -INSTALL_R0 = $(INSTALL) -m644 # space is required here +INSTALL_R0 = $(INSTALL) -m 644 # space is required here INSTALL_R1 = -INSTALL_X0 = $(INSTALL) -m755 # space is required here +INSTALL_X0 = $(INSTALL) -m 755 # space is required here INSTALL_X1 = INSTALL_A0 = find # space is required here INSTALL_A1 = | cpio -pud @@ -71,11 +71,11 @@ ifndef V QUIET_2DEVNULL = 2>/dev/null INSTALL_D0 = dir= - INSTALL_D1 = && echo ' ' DEST $$dir && $(INSTALL) -d -m755 "$$dir" + INSTALL_D1 = && echo ' ' DEST $$dir && $(INSTALL) -d -m 755 "$$dir" INSTALL_R0 = src= - INSTALL_R1 = && echo ' ' INSTALL 644 `basename $$src` && $(INSTALL) -m644 $$src + INSTALL_R1 = && echo ' ' INSTALL 644 `basename $$src` && $(INSTALL) -m 644 $$src INSTALL_X0 = src= - INSTALL_X1 = && echo ' ' INSTALL 755 `basename $$src` && $(INSTALL) -m755 $$src + INSTALL_X1 = && echo ' ' INSTALL 755 `basename $$src` && $(INSTALL) -m 755 $$src INSTALL_A0 = src= INSTALL_A1 = && echo ' ' INSTALL ' ' `basename "$$src"` && find "$$src" | cpio -pud @@ -212,7 +212,7 @@ $(PO_TEMPLATE): $(SCRIPT_SH) $(ALL_LIBFILES) update-po:: $(PO_TEMPLATE) $(foreach p, $(ALL_POFILES), echo Updating $p ; msgmerge -U $p $(PO_TEMPLATE) ; ) $(ALL_MSGFILES): %.msg : %.po - $(QUIET_MSGFMT0)$(MSGFMT) --statistics --tcl $< -l $(basename $(notdir $<)) -d $(dir $@) $(QUIET_MSGFMT1) + $(QUIET_MSGFMT0)$(MSGFMT) --statistics --tcl -l $(basename $(notdir $<)) -d $(dir $@) $< $(QUIET_MSGFMT1) lib/tclIndex: $(ALL_LIBFILES) GIT-GUI-VARS $(QUIET_INDEX)if echo \ diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 10b0430f54..b2d2d53086 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -184,7 +184,7 @@ You must stage at least 1 file before you can commit. A good commit message has the following format: -- First line: Describe in one sentance what you did. +- First line: Describe in one sentence what you did. - Second line: Blank - Remaining lines: Describe why this change is good. "] diff --git a/git-gui/lib/git-gui.ico b/git-gui/lib/git-gui.ico Binary files differindex 563dd66238..334cfa5a1a 100644 --- a/git-gui/lib/git-gui.ico +++ b/git-gui/lib/git-gui.ico diff --git a/git-gui/po/de.po b/git-gui/po/de.po index 3df30edb87..ac8ae0a205 100644 --- a/git-gui/po/de.po +++ b/git-gui/po/de.po @@ -7,41 +7,41 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-19 21:10+0200\n" -"PO-Revision-Date: 2007-10-20 15:28+0200\n" +"POT-Creation-Date: 2007-11-24 10:36+0100\n" +"PO-Revision-Date: 2007-11-24 10:55+0100\n" "Last-Translator: Christian Stimming <stimming@tuhh.de>\n" "Language-Team: German\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: git-gui.sh:41 git-gui.sh:590 git-gui.sh:604 git-gui.sh:617 git-gui.sh:700 -#: git-gui.sh:719 +#: git-gui.sh:41 git-gui.sh:604 git-gui.sh:618 git-gui.sh:631 git-gui.sh:714 +#: git-gui.sh:733 msgid "git-gui: fatal error" msgstr "git-gui: Programmfehler" -#: git-gui.sh:551 +#: git-gui.sh:565 #, tcl-format msgid "Invalid font specified in %s:" msgstr "Ungültige Zeichensatz-Angabe in %s:" -#: git-gui.sh:576 +#: git-gui.sh:590 msgid "Main Font" msgstr "Programmschriftart" -#: git-gui.sh:577 +#: git-gui.sh:591 msgid "Diff/Console Font" msgstr "Vergleich-Schriftart" -#: git-gui.sh:591 +#: git-gui.sh:605 msgid "Cannot find git in PATH." msgstr "Git kann im PATH nicht gefunden werden." -#: git-gui.sh:618 +#: git-gui.sh:632 msgid "Cannot parse Git version string:" msgstr "Git Versionsangabe kann nicht erkannt werden:" -#: git-gui.sh:636 +#: git-gui.sh:650 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -60,81 +60,81 @@ msgstr "" "\n" "Soll angenommen werden, »%s« sei Version 1.5.0?\n" -#: git-gui.sh:874 +#: git-gui.sh:888 msgid "Git directory not found:" msgstr "Git-Verzeichnis nicht gefunden:" -#: git-gui.sh:881 +#: git-gui.sh:895 msgid "Cannot move to top of working directory:" msgstr "" "Es konnte nicht in das oberste Verzeichnis der Arbeitskopie gewechselt " "werden:" -#: git-gui.sh:888 +#: git-gui.sh:902 msgid "Cannot use funny .git directory:" msgstr "Unerwartete Struktur des .git Verzeichnis:" -#: git-gui.sh:893 +#: git-gui.sh:907 msgid "No working directory" msgstr "Kein Arbeitsverzeichnis" -#: git-gui.sh:1040 +#: git-gui.sh:1054 msgid "Refreshing file status..." msgstr "Dateistatus aktualisieren..." -#: git-gui.sh:1105 +#: git-gui.sh:1119 msgid "Scanning for modified files ..." msgstr "Nach geänderten Dateien suchen..." -#: git-gui.sh:1280 lib/browser.tcl:245 +#: git-gui.sh:1294 lib/browser.tcl:245 msgid "Ready." msgstr "Bereit." -#: git-gui.sh:1546 +#: git-gui.sh:1560 msgid "Unmodified" msgstr "Unverändert" -#: git-gui.sh:1548 +#: git-gui.sh:1562 msgid "Modified, not staged" msgstr "Verändert, nicht bereitgestellt" -#: git-gui.sh:1549 git-gui.sh:1554 +#: git-gui.sh:1563 git-gui.sh:1568 msgid "Staged for commit" msgstr "Bereitgestellt zum Eintragen" -#: git-gui.sh:1550 git-gui.sh:1555 +#: git-gui.sh:1564 git-gui.sh:1569 msgid "Portions staged for commit" msgstr "Teilweise bereitgestellt zum Eintragen" -#: git-gui.sh:1551 git-gui.sh:1556 +#: git-gui.sh:1565 git-gui.sh:1570 msgid "Staged for commit, missing" msgstr "Bereitgestellt zum Eintragen, fehlend" -#: git-gui.sh:1553 +#: git-gui.sh:1567 msgid "Untracked, not staged" msgstr "Nicht unter Versionskontrolle, nicht bereitgestellt" -#: git-gui.sh:1558 +#: git-gui.sh:1572 msgid "Missing" msgstr "Fehlend" -#: git-gui.sh:1559 +#: git-gui.sh:1573 msgid "Staged for removal" msgstr "Bereitgestellt zum Löschen" -#: git-gui.sh:1560 +#: git-gui.sh:1574 msgid "Staged for removal, still present" msgstr "Bereitgestellt zum Löschen, trotzdem vorhanden" -#: git-gui.sh:1562 git-gui.sh:1563 git-gui.sh:1564 git-gui.sh:1565 +#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579 msgid "Requires merge resolution" msgstr "Konfliktauflösung nötig" -#: git-gui.sh:1600 +#: git-gui.sh:1614 msgid "Starting gitk... please wait..." msgstr "Gitk wird gestartet... bitte warten." -#: git-gui.sh:1609 +#: git-gui.sh:1623 #, tcl-format msgid "" "Unable to start gitk:\n" @@ -145,295 +145,295 @@ msgstr "" "\n" "%s existiert nicht" -#: git-gui.sh:1809 lib/choose_repository.tcl:35 +#: git-gui.sh:1823 lib/choose_repository.tcl:35 msgid "Repository" msgstr "Projektarchiv" -#: git-gui.sh:1810 +#: git-gui.sh:1824 msgid "Edit" msgstr "Bearbeiten" -#: git-gui.sh:1812 lib/choose_rev.tcl:560 +#: git-gui.sh:1826 lib/choose_rev.tcl:560 msgid "Branch" msgstr "Zweig" -#: git-gui.sh:1815 lib/choose_rev.tcl:547 +#: git-gui.sh:1829 lib/choose_rev.tcl:547 msgid "Commit@@noun" msgstr "Version" -#: git-gui.sh:1818 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +#: git-gui.sh:1832 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 msgid "Merge" msgstr "Zusammenführen" -#: git-gui.sh:1819 lib/choose_rev.tcl:556 +#: git-gui.sh:1833 lib/choose_rev.tcl:556 msgid "Remote" msgstr "Andere Archive" -#: git-gui.sh:1828 +#: git-gui.sh:1842 msgid "Browse Current Branch's Files" msgstr "Aktuellen Zweig durchblättern" -#: git-gui.sh:1832 +#: git-gui.sh:1846 msgid "Browse Branch Files..." msgstr "Einen Zweig durchblättern..." -#: git-gui.sh:1837 +#: git-gui.sh:1851 msgid "Visualize Current Branch's History" msgstr "Aktuellen Zweig darstellen" -#: git-gui.sh:1841 +#: git-gui.sh:1855 msgid "Visualize All Branch History" msgstr "Alle Zweige darstellen" -#: git-gui.sh:1848 +#: git-gui.sh:1862 #, tcl-format msgid "Browse %s's Files" msgstr "Zweig »%s« durchblättern" -#: git-gui.sh:1850 +#: git-gui.sh:1864 #, tcl-format msgid "Visualize %s's History" msgstr "Historie von »%s« darstellen" -#: git-gui.sh:1855 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:1869 lib/database.tcl:27 lib/database.tcl:67 msgid "Database Statistics" msgstr "Datenbankstatistik" -#: git-gui.sh:1858 lib/database.tcl:34 +#: git-gui.sh:1872 lib/database.tcl:34 msgid "Compress Database" msgstr "Datenbank komprimieren" -#: git-gui.sh:1861 +#: git-gui.sh:1875 msgid "Verify Database" msgstr "Datenbank überprüfen" -#: git-gui.sh:1868 git-gui.sh:1872 git-gui.sh:1876 lib/shortcut.tcl:7 +#: git-gui.sh:1882 git-gui.sh:1886 git-gui.sh:1890 lib/shortcut.tcl:7 #: lib/shortcut.tcl:39 lib/shortcut.tcl:71 msgid "Create Desktop Icon" msgstr "Desktop-Icon erstellen" -#: git-gui.sh:1881 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184 +#: git-gui.sh:1895 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184 msgid "Quit" msgstr "Beenden" -#: git-gui.sh:1888 +#: git-gui.sh:1902 msgid "Undo" msgstr "Rückgängig" -#: git-gui.sh:1891 +#: git-gui.sh:1905 msgid "Redo" msgstr "Wiederholen" -#: git-gui.sh:1895 git-gui.sh:2388 +#: git-gui.sh:1909 git-gui.sh:2403 msgid "Cut" msgstr "Ausschneiden" -#: git-gui.sh:1898 git-gui.sh:2391 git-gui.sh:2462 git-gui.sh:2534 +#: git-gui.sh:1912 git-gui.sh:2406 git-gui.sh:2477 git-gui.sh:2549 #: lib/console.tcl:67 msgid "Copy" msgstr "Kopieren" -#: git-gui.sh:1901 git-gui.sh:2394 +#: git-gui.sh:1915 git-gui.sh:2409 msgid "Paste" msgstr "Einfügen" -#: git-gui.sh:1904 git-gui.sh:2397 lib/branch_delete.tcl:26 +#: git-gui.sh:1918 git-gui.sh:2412 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Löschen" -#: git-gui.sh:1908 git-gui.sh:2401 git-gui.sh:2538 lib/console.tcl:69 +#: git-gui.sh:1922 git-gui.sh:2416 git-gui.sh:2553 lib/console.tcl:69 msgid "Select All" msgstr "Alle auswählen" -#: git-gui.sh:1917 +#: git-gui.sh:1931 msgid "Create..." msgstr "Erstellen..." -#: git-gui.sh:1923 +#: git-gui.sh:1937 msgid "Checkout..." msgstr "Umstellen..." -#: git-gui.sh:1929 +#: git-gui.sh:1943 msgid "Rename..." msgstr "Umbenennen..." -#: git-gui.sh:1934 git-gui.sh:2033 +#: git-gui.sh:1948 git-gui.sh:2048 msgid "Delete..." msgstr "Löschen..." -#: git-gui.sh:1939 +#: git-gui.sh:1953 msgid "Reset..." msgstr "Zurücksetzen..." -#: git-gui.sh:1951 git-gui.sh:2335 +#: git-gui.sh:1965 git-gui.sh:2350 msgid "New Commit" msgstr "Neue Version" -#: git-gui.sh:1959 git-gui.sh:2342 +#: git-gui.sh:1973 git-gui.sh:2357 msgid "Amend Last Commit" msgstr "Letzte Version nachbessern" -#: git-gui.sh:1968 git-gui.sh:2302 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "Neu laden" -#: git-gui.sh:1974 +#: git-gui.sh:1988 msgid "Stage To Commit" msgstr "Zum Eintragen bereitstellen" -#: git-gui.sh:1979 +#: git-gui.sh:1994 msgid "Stage Changed Files To Commit" msgstr "Geänderte Dateien zum Eintragen bereitstellen" -#: git-gui.sh:1985 +#: git-gui.sh:2000 msgid "Unstage From Commit" msgstr "Aus der Bereitstellung herausnehmen" -#: git-gui.sh:1990 lib/index.tcl:352 +#: git-gui.sh:2005 lib/index.tcl:393 msgid "Revert Changes" msgstr "Änderungen revidieren" -#: git-gui.sh:1997 git-gui.sh:2314 git-gui.sh:2412 +#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427 msgid "Sign Off" msgstr "Abzeichnen" -#: git-gui.sh:2001 git-gui.sh:2318 +#: git-gui.sh:2016 git-gui.sh:2333 msgid "Commit@@verb" msgstr "Eintragen" -#: git-gui.sh:2012 +#: git-gui.sh:2027 msgid "Local Merge..." msgstr "Lokales Zusammenführen..." -#: git-gui.sh:2017 +#: git-gui.sh:2032 msgid "Abort Merge..." msgstr "Zusammenführen abbrechen..." -#: git-gui.sh:2029 +#: git-gui.sh:2044 msgid "Push..." msgstr "Versenden..." -#: git-gui.sh:2040 lib/choose_repository.tcl:40 +#: git-gui.sh:2055 lib/choose_repository.tcl:40 msgid "Apple" msgstr "Apple" -#: git-gui.sh:2043 git-gui.sh:2065 lib/about.tcl:13 +#: git-gui.sh:2058 git-gui.sh:2080 lib/about.tcl:13 #: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49 #, tcl-format msgid "About %s" msgstr "Über %s" -#: git-gui.sh:2047 +#: git-gui.sh:2062 msgid "Preferences..." msgstr "Einstellungen..." -#: git-gui.sh:2055 git-gui.sh:2580 +#: git-gui.sh:2070 git-gui.sh:2595 msgid "Options..." msgstr "Optionen..." -#: git-gui.sh:2061 lib/choose_repository.tcl:46 +#: git-gui.sh:2076 lib/choose_repository.tcl:46 msgid "Help" msgstr "Hilfe" -#: git-gui.sh:2102 +#: git-gui.sh:2117 msgid "Online Documentation" msgstr "Online-Dokumentation" -#: git-gui.sh:2186 +#: git-gui.sh:2201 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" -msgstr "" +msgstr "Fehler: Verzeichnis »%s« kann nicht gelesen werden: Datei oder Verzeichnis nicht gefunden" -#: git-gui.sh:2219 +#: git-gui.sh:2234 msgid "Current Branch:" msgstr "Aktueller Zweig:" -#: git-gui.sh:2240 +#: git-gui.sh:2255 msgid "Staged Changes (Will Commit)" msgstr "Bereitgestellte Änderungen (zum Eintragen)" -#: git-gui.sh:2259 +#: git-gui.sh:2274 msgid "Unstaged Changes" msgstr "Nicht bereitgestellte Änderungen" -#: git-gui.sh:2308 +#: git-gui.sh:2323 msgid "Stage Changed" msgstr "Alles bereitstellen" -#: git-gui.sh:2324 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2339 lib/transport.tcl:93 lib/transport.tcl:182 msgid "Push" msgstr "Versenden" -#: git-gui.sh:2354 +#: git-gui.sh:2369 msgid "Initial Commit Message:" msgstr "Erste Versionsbeschreibung:" -#: git-gui.sh:2355 +#: git-gui.sh:2370 msgid "Amended Commit Message:" msgstr "Nachgebesserte Versionsbeschreibung:" -#: git-gui.sh:2356 +#: git-gui.sh:2371 msgid "Amended Initial Commit Message:" msgstr "Nachgebesserte erste Versionsbeschreibung:" -#: git-gui.sh:2357 +#: git-gui.sh:2372 msgid "Amended Merge Commit Message:" msgstr "Nachgebesserte Zusammenführungs-Versionsbeschreibung:" -#: git-gui.sh:2358 +#: git-gui.sh:2373 msgid "Merge Commit Message:" msgstr "Zusammenführungs-Versionsbeschreibung:" -#: git-gui.sh:2359 +#: git-gui.sh:2374 msgid "Commit Message:" msgstr "Versionsbeschreibung:" -#: git-gui.sh:2404 git-gui.sh:2542 lib/console.tcl:71 +#: git-gui.sh:2419 git-gui.sh:2557 lib/console.tcl:71 msgid "Copy All" msgstr "Alle kopieren" -#: git-gui.sh:2428 lib/blame.tcl:104 +#: git-gui.sh:2443 lib/blame.tcl:104 msgid "File:" msgstr "Datei:" -#: git-gui.sh:2530 +#: git-gui.sh:2545 msgid "Refresh" msgstr "Aktualisieren" -#: git-gui.sh:2551 +#: git-gui.sh:2566 msgid "Apply/Reverse Hunk" msgstr "Änderung anwenden/umkehren" -#: git-gui.sh:2557 +#: git-gui.sh:2572 msgid "Decrease Font Size" msgstr "Schriftgröße verkleinern" -#: git-gui.sh:2561 +#: git-gui.sh:2576 msgid "Increase Font Size" msgstr "Schriftgröße vergrößern" -#: git-gui.sh:2566 +#: git-gui.sh:2581 msgid "Show Less Context" msgstr "Weniger Kontext anzeigen" -#: git-gui.sh:2573 +#: git-gui.sh:2588 msgid "Show More Context" msgstr "Mehr Kontext anzeigen" -#: git-gui.sh:2587 +#: git-gui.sh:2602 msgid "Unstage Hunk From Commit" msgstr "Aus der Bereitstellung herausnehmen" -#: git-gui.sh:2589 +#: git-gui.sh:2604 msgid "Stage Hunk For Commit" msgstr "In die Bereitstellung hinzufügen" -#: git-gui.sh:2608 +#: git-gui.sh:2623 msgid "Initializing..." msgstr "Initialisieren..." -#: git-gui.sh:2699 +#: git-gui.sh:2718 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -443,15 +443,23 @@ msgid "" "by %s:\n" "\n" msgstr "" +"Möglicherweise gibt es Probleme mit manchen Umgebungsvariablen.\n" +"\n" +"Die folgenden Umgebungsvariablen können vermutlich nicht \n" +"von %s an Git weitergegeben werden:\n" +"\n" -#: git-gui.sh:2729 +#: git-gui.sh:2748 msgid "" "\n" "This is due to a known issue with the\n" "Tcl binary distributed by Cygwin." msgstr "" +"\n" +"Dies ist ein bekanntes Problem der Tcl-Version, die\n" +"in Cygwin mitgeliefert wird." -#: git-gui.sh:2734 +#: git-gui.sh:2753 #, tcl-format msgid "" "\n" @@ -461,6 +469,11 @@ msgid "" "user.email settings into your personal\n" "~/.gitconfig file.\n" msgstr "" +"\n" +"\n" +"Um den Namen »%s« zu ändern, sollten Sie die \n" +"gewünschten Werte für die Einstellung user.name und \n" +"user.email in Ihre Datei ~/.gitconfig einfügen.\n" #: lib/about.tcl:25 msgid "git-gui - a graphical user interface for Git." @@ -485,19 +498,19 @@ msgstr "%s lesen..." #: lib/blame.tcl:473 msgid "Loading copy/move tracking annotations..." -msgstr "" +msgstr "Annotierungen für Kopieren/Verschieben werden geladen..." #: lib/blame.tcl:493 msgid "lines annotated" -msgstr "" +msgstr "Zeilen annotiert" #: lib/blame.tcl:674 msgid "Loading original location annotations..." -msgstr "" +msgstr "Annotierungen für ursprünglichen Ort werden geladen..." #: lib/blame.tcl:677 msgid "Annotation complete." -msgstr "" +msgstr "Annotierung vollständig." #: lib/blame.tcl:731 msgid "Loading annotation..." @@ -733,7 +746,7 @@ msgstr "Änderungen »%s« von »%s« anfordern" #: lib/checkout_op.tcl:127 #, tcl-format msgid "fatal: Cannot resolve %s" -msgstr "" +msgstr "Fehler: »%s« kann nicht als Zweig oder Version erkannt werden" #: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31 msgid "Close" @@ -994,20 +1007,20 @@ msgstr "Verknüpft ist nur für lokale Projektarchive verfügbar." #: lib/choose_repository.tcl:617 msgid "Failed to configure origin" -msgstr "" +msgstr "Der Ursprungsort konnte nicht eingerichtet werden" #: lib/choose_repository.tcl:629 msgid "Counting objects" -msgstr "" +msgstr "Objekte werden gezählt" #: lib/choose_repository.tcl:630 msgid "buckets" -msgstr "" +msgstr "Buckets" #: lib/choose_repository.tcl:654 #, tcl-format msgid "Unable to copy objects/info/alternates: %s" -msgstr "" +msgstr "Kopien von Objekten/Info/Alternates konnten nicht erstellt werden: %s" #: lib/choose_repository.tcl:690 #, tcl-format @@ -1017,11 +1030,11 @@ msgstr "Von »%s« konnte nichts kopiert werden." #: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906 #: lib/choose_repository.tcl:918 msgid "The 'master' branch has not been initialized." -msgstr "" +msgstr "Der »master«-Zweig wurde noch nicht initialisiert." #: lib/choose_repository.tcl:705 msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "" +msgstr "Hardlinks nicht verfügbar. Stattdessen wird kopiert." #: lib/choose_repository.tcl:717 #, tcl-format @@ -1052,24 +1065,24 @@ msgstr "Objekte" #: lib/choose_repository.tcl:792 #, tcl-format msgid "Unable to hardlink object: %s" -msgstr "Objekt kann nicht hartverlinkt werden: %s" +msgstr "Für Objekt konnte kein Hardlink erstellt werden: %s" #: lib/choose_repository.tcl:847 msgid "Cannot fetch branches and objects. See console output for details." -msgstr "" +msgstr "Zweige und Objekte konnten nicht angefordert werden. Kontrollieren Sie die Ausgaben auf der Konsole für weitere Angaben." #: lib/choose_repository.tcl:858 msgid "Cannot fetch tags. See console output for details." -msgstr "" +msgstr "Markierungen konnten nicht angefordert werden. Kontrollieren Sie die Ausgaben auf der Konsole für weitere Angaben." #: lib/choose_repository.tcl:882 msgid "Cannot determine HEAD. See console output for details." -msgstr "" +msgstr "Die Zweigspitze (HEAD) konnte nicht gefunden werden. Kontrollieren Sie die Ausgaben auf der Konsole für weitere Angaben." #: lib/choose_repository.tcl:891 #, tcl-format msgid "Unable to cleanup %s" -msgstr "" +msgstr "Verzeichnis »%s« kann nicht aufgeräumt werden." #: lib/choose_repository.tcl:897 msgid "Clone failed." @@ -1077,25 +1090,25 @@ msgstr "Kopieren fehlgeschlagen." #: lib/choose_repository.tcl:904 msgid "No default branch obtained." -msgstr "" +msgstr "Kein voreingestellter Zweig gefunden." #: lib/choose_repository.tcl:915 #, tcl-format msgid "Cannot resolve %s as a commit." -msgstr "" +msgstr "»%s« wurde nicht als Version gefunden." #: lib/choose_repository.tcl:927 msgid "Creating working directory" msgstr "Arbeitskopie erstellen" -#: lib/choose_repository.tcl:928 lib/index.tcl:15 lib/index.tcl:80 -#: lib/index.tcl:149 +#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127 +#: lib/index.tcl:193 msgid "files" msgstr "Dateien" #: lib/choose_repository.tcl:957 msgid "Initial file checkout failed." -msgstr "" +msgstr "Erstellen der Arbeitskopie fehlgeschlagen." #: lib/choose_repository.tcl:973 msgid "Open" @@ -1246,7 +1259,7 @@ msgid "" "\n" "A good commit message has the following format:\n" "\n" -"- First line: Describe in one sentance what you did.\n" +"- First line: Describe in one sentence what you did.\n" "- Second line: Blank\n" "- Remaining lines: Describe why this change is good.\n" msgstr "" @@ -1291,7 +1304,7 @@ msgstr "Keine Änderungen, die eingetragen werden können." #: lib/commit.tcl:303 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." -msgstr "" +msgstr "Warning: Tcl/Tk unterstützt die Zeichencodierung »%s« nicht." #: lib/commit.tcl:317 msgid "commit-tree failed:" @@ -1446,32 +1459,54 @@ msgid "You must correct the above errors before committing." msgstr "" "Sie müssen die obigen Fehler zuerst beheben, bevor Sie eintragen können." -#: lib/index.tcl:241 +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "Bereitstellung kann nicht wieder freigegeben werden." + +#: lib/index.tcl:15 +msgid "Index Error" +msgstr "Fehler in Bereitstellung" + +#: lib/index.tcl:21 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "Das Aktualisieren der Git-Bereitstellung ist fehlgeschlagen. Eine allgemeine Git-Aktualisierung wird jetzt gestartet, um git-gui wieder mit git zu synchronisieren." + +#: lib/index.tcl:27 +msgid "Continue" +msgstr "Fortsetzen" + +#: lib/index.tcl:31 +msgid "Unlock Index" +msgstr "Bereitstellung freigeben" + +#: lib/index.tcl:282 #, tcl-format msgid "Unstaging %s from commit" msgstr "Datei »%s« aus der Bereitstellung herausnehmen" -#: lib/index.tcl:285 +#: lib/index.tcl:326 #, tcl-format msgid "Adding %s" msgstr "»%s« hinzufügen..." -#: lib/index.tcl:340 +#: lib/index.tcl:381 #, tcl-format msgid "Revert changes in file %s?" msgstr "Änderungen in Datei »%s« revidieren?" -#: lib/index.tcl:342 +#: lib/index.tcl:383 #, tcl-format msgid "Revert changes in these %i files?" msgstr "Änderungen in den gewählten %i Dateien revidieren?" -#: lib/index.tcl:348 +#: lib/index.tcl:389 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" "Alle nicht bereitgestellten Änderungen werden beim Revidieren verloren gehen." -#: lib/index.tcl:351 +#: lib/index.tcl:392 msgid "Do Nothing" msgstr "Nichts tun" @@ -1867,12 +1902,3 @@ msgstr "Kompaktes Datenformat benutzen (für langsame Netzverbindungen)" #: lib/transport.tcl:168 msgid "Include tags" msgstr "Mit Markierungen übertragen" - -#~ msgid "Next >" -#~ msgstr "Weiter >" - -#~ msgid "Fetch" -#~ msgstr "Anfordern" - -#~ msgid "Unstaged Changes (Will Not Be Committed)" -#~ msgstr "Nicht bereitgestellte Änderungen (werden nicht eingetragen)" diff --git a/git-gui/po/git-gui.pot b/git-gui/po/git-gui.pot index 00f0f5922a..dfa48ae263 100644 --- a/git-gui/po/git-gui.pot +++ b/git-gui/po/git-gui.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-10 04:04-0400\n" +"POT-Creation-Date: 2007-11-24 10:36+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -16,33 +16,33 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744 -#: git-gui.sh:763 +#: git-gui.sh:41 git-gui.sh:604 git-gui.sh:618 git-gui.sh:631 git-gui.sh:714 +#: git-gui.sh:733 msgid "git-gui: fatal error" msgstr "" -#: git-gui.sh:595 +#: git-gui.sh:565 #, tcl-format msgid "Invalid font specified in %s:" msgstr "" -#: git-gui.sh:620 +#: git-gui.sh:590 msgid "Main Font" msgstr "" -#: git-gui.sh:621 +#: git-gui.sh:591 msgid "Diff/Console Font" msgstr "" -#: git-gui.sh:635 +#: git-gui.sh:605 msgid "Cannot find git in PATH." msgstr "" -#: git-gui.sh:662 +#: git-gui.sh:632 msgid "Cannot parse Git version string:" msgstr "" -#: git-gui.sh:680 +#: git-gui.sh:650 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -54,79 +54,79 @@ msgid "" "Assume '%s' is version 1.5.0?\n" msgstr "" -#: git-gui.sh:853 +#: git-gui.sh:888 msgid "Git directory not found:" msgstr "" -#: git-gui.sh:860 +#: git-gui.sh:895 msgid "Cannot move to top of working directory:" msgstr "" -#: git-gui.sh:867 +#: git-gui.sh:902 msgid "Cannot use funny .git directory:" msgstr "" -#: git-gui.sh:872 +#: git-gui.sh:907 msgid "No working directory" msgstr "" -#: git-gui.sh:1019 +#: git-gui.sh:1054 msgid "Refreshing file status..." msgstr "" -#: git-gui.sh:1084 +#: git-gui.sh:1119 msgid "Scanning for modified files ..." msgstr "" -#: git-gui.sh:1259 lib/browser.tcl:245 +#: git-gui.sh:1294 lib/browser.tcl:245 msgid "Ready." msgstr "" -#: git-gui.sh:1525 +#: git-gui.sh:1560 msgid "Unmodified" msgstr "" -#: git-gui.sh:1527 +#: git-gui.sh:1562 msgid "Modified, not staged" msgstr "" -#: git-gui.sh:1528 git-gui.sh:1533 +#: git-gui.sh:1563 git-gui.sh:1568 msgid "Staged for commit" msgstr "" -#: git-gui.sh:1529 git-gui.sh:1534 +#: git-gui.sh:1564 git-gui.sh:1569 msgid "Portions staged for commit" msgstr "" -#: git-gui.sh:1530 git-gui.sh:1535 +#: git-gui.sh:1565 git-gui.sh:1570 msgid "Staged for commit, missing" msgstr "" -#: git-gui.sh:1532 +#: git-gui.sh:1567 msgid "Untracked, not staged" msgstr "" -#: git-gui.sh:1537 +#: git-gui.sh:1572 msgid "Missing" msgstr "" -#: git-gui.sh:1538 +#: git-gui.sh:1573 msgid "Staged for removal" msgstr "" -#: git-gui.sh:1539 +#: git-gui.sh:1574 msgid "Staged for removal, still present" msgstr "" -#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544 +#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579 msgid "Requires merge resolution" msgstr "" -#: git-gui.sh:1579 +#: git-gui.sh:1614 msgid "Starting gitk... please wait..." msgstr "" -#: git-gui.sh:1588 +#: git-gui.sh:1623 #, tcl-format msgid "" "Unable to start gitk:\n" @@ -134,295 +134,295 @@ msgid "" "%s does not exist" msgstr "" -#: git-gui.sh:1788 lib/choose_repository.tcl:32 +#: git-gui.sh:1823 lib/choose_repository.tcl:35 msgid "Repository" msgstr "" -#: git-gui.sh:1789 +#: git-gui.sh:1824 msgid "Edit" msgstr "" -#: git-gui.sh:1791 lib/choose_rev.tcl:560 +#: git-gui.sh:1826 lib/choose_rev.tcl:560 msgid "Branch" msgstr "" -#: git-gui.sh:1794 lib/choose_rev.tcl:547 +#: git-gui.sh:1829 lib/choose_rev.tcl:547 msgid "Commit@@noun" msgstr "" -#: git-gui.sh:1797 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +#: git-gui.sh:1832 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 msgid "Merge" msgstr "" -#: git-gui.sh:1798 lib/choose_rev.tcl:556 +#: git-gui.sh:1833 lib/choose_rev.tcl:556 msgid "Remote" msgstr "" -#: git-gui.sh:1807 +#: git-gui.sh:1842 msgid "Browse Current Branch's Files" msgstr "" -#: git-gui.sh:1811 +#: git-gui.sh:1846 msgid "Browse Branch Files..." msgstr "" -#: git-gui.sh:1816 +#: git-gui.sh:1851 msgid "Visualize Current Branch's History" msgstr "" -#: git-gui.sh:1820 +#: git-gui.sh:1855 msgid "Visualize All Branch History" msgstr "" -#: git-gui.sh:1827 +#: git-gui.sh:1862 #, tcl-format msgid "Browse %s's Files" msgstr "" -#: git-gui.sh:1829 +#: git-gui.sh:1864 #, tcl-format msgid "Visualize %s's History" msgstr "" -#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:1869 lib/database.tcl:27 lib/database.tcl:67 msgid "Database Statistics" msgstr "" -#: git-gui.sh:1837 lib/database.tcl:34 +#: git-gui.sh:1872 lib/database.tcl:34 msgid "Compress Database" msgstr "" -#: git-gui.sh:1840 +#: git-gui.sh:1875 msgid "Verify Database" msgstr "" -#: git-gui.sh:1847 git-gui.sh:1851 git-gui.sh:1855 lib/shortcut.tcl:9 -#: lib/shortcut.tcl:45 lib/shortcut.tcl:84 +#: git-gui.sh:1882 git-gui.sh:1886 git-gui.sh:1890 lib/shortcut.tcl:7 +#: lib/shortcut.tcl:39 lib/shortcut.tcl:71 msgid "Create Desktop Icon" msgstr "" -#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95 +#: git-gui.sh:1895 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184 msgid "Quit" msgstr "" -#: git-gui.sh:1867 +#: git-gui.sh:1902 msgid "Undo" msgstr "" -#: git-gui.sh:1870 +#: git-gui.sh:1905 msgid "Redo" msgstr "" -#: git-gui.sh:1874 git-gui.sh:2366 +#: git-gui.sh:1909 git-gui.sh:2403 msgid "Cut" msgstr "" -#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512 +#: git-gui.sh:1912 git-gui.sh:2406 git-gui.sh:2477 git-gui.sh:2549 #: lib/console.tcl:67 msgid "Copy" msgstr "" -#: git-gui.sh:1880 git-gui.sh:2372 +#: git-gui.sh:1915 git-gui.sh:2409 msgid "Paste" msgstr "" -#: git-gui.sh:1883 git-gui.sh:2375 lib/branch_delete.tcl:26 +#: git-gui.sh:1918 git-gui.sh:2412 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "" -#: git-gui.sh:1887 git-gui.sh:2379 git-gui.sh:2516 lib/console.tcl:69 +#: git-gui.sh:1922 git-gui.sh:2416 git-gui.sh:2553 lib/console.tcl:69 msgid "Select All" msgstr "" -#: git-gui.sh:1896 +#: git-gui.sh:1931 msgid "Create..." msgstr "" -#: git-gui.sh:1902 +#: git-gui.sh:1937 msgid "Checkout..." msgstr "" -#: git-gui.sh:1908 +#: git-gui.sh:1943 msgid "Rename..." msgstr "" -#: git-gui.sh:1913 git-gui.sh:2012 +#: git-gui.sh:1948 git-gui.sh:2048 msgid "Delete..." msgstr "" -#: git-gui.sh:1918 +#: git-gui.sh:1953 msgid "Reset..." msgstr "" -#: git-gui.sh:1930 git-gui.sh:2313 +#: git-gui.sh:1965 git-gui.sh:2350 msgid "New Commit" msgstr "" -#: git-gui.sh:1938 git-gui.sh:2320 +#: git-gui.sh:1973 git-gui.sh:2357 msgid "Amend Last Commit" msgstr "" -#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "" -#: git-gui.sh:1953 +#: git-gui.sh:1988 msgid "Stage To Commit" msgstr "" -#: git-gui.sh:1958 +#: git-gui.sh:1994 msgid "Stage Changed Files To Commit" msgstr "" -#: git-gui.sh:1964 +#: git-gui.sh:2000 msgid "Unstage From Commit" msgstr "" -#: git-gui.sh:1969 lib/index.tcl:352 +#: git-gui.sh:2005 lib/index.tcl:393 msgid "Revert Changes" msgstr "" -#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390 +#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427 msgid "Sign Off" msgstr "" -#: git-gui.sh:1980 git-gui.sh:2296 +#: git-gui.sh:2016 git-gui.sh:2333 msgid "Commit@@verb" msgstr "" -#: git-gui.sh:1991 +#: git-gui.sh:2027 msgid "Local Merge..." msgstr "" -#: git-gui.sh:1996 +#: git-gui.sh:2032 msgid "Abort Merge..." msgstr "" -#: git-gui.sh:2008 +#: git-gui.sh:2044 msgid "Push..." msgstr "" -#: git-gui.sh:2019 lib/choose_repository.tcl:41 +#: git-gui.sh:2055 lib/choose_repository.tcl:40 msgid "Apple" msgstr "" -#: git-gui.sh:2022 git-gui.sh:2044 lib/about.tcl:13 -#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50 +#: git-gui.sh:2058 git-gui.sh:2080 lib/about.tcl:13 +#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49 #, tcl-format msgid "About %s" msgstr "" -#: git-gui.sh:2026 +#: git-gui.sh:2062 msgid "Preferences..." msgstr "" -#: git-gui.sh:2034 git-gui.sh:2558 +#: git-gui.sh:2070 git-gui.sh:2595 msgid "Options..." msgstr "" -#: git-gui.sh:2040 lib/choose_repository.tcl:47 +#: git-gui.sh:2076 lib/choose_repository.tcl:46 msgid "Help" msgstr "" -#: git-gui.sh:2081 +#: git-gui.sh:2117 msgid "Online Documentation" msgstr "" -#: git-gui.sh:2165 +#: git-gui.sh:2201 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" -#: git-gui.sh:2198 +#: git-gui.sh:2234 msgid "Current Branch:" msgstr "" -#: git-gui.sh:2219 +#: git-gui.sh:2255 msgid "Staged Changes (Will Commit)" msgstr "" -#: git-gui.sh:2239 +#: git-gui.sh:2274 msgid "Unstaged Changes" msgstr "" -#: git-gui.sh:2286 +#: git-gui.sh:2323 msgid "Stage Changed" msgstr "" -#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2339 lib/transport.tcl:93 lib/transport.tcl:182 msgid "Push" msgstr "" -#: git-gui.sh:2332 +#: git-gui.sh:2369 msgid "Initial Commit Message:" msgstr "" -#: git-gui.sh:2333 +#: git-gui.sh:2370 msgid "Amended Commit Message:" msgstr "" -#: git-gui.sh:2334 +#: git-gui.sh:2371 msgid "Amended Initial Commit Message:" msgstr "" -#: git-gui.sh:2335 +#: git-gui.sh:2372 msgid "Amended Merge Commit Message:" msgstr "" -#: git-gui.sh:2336 +#: git-gui.sh:2373 msgid "Merge Commit Message:" msgstr "" -#: git-gui.sh:2337 +#: git-gui.sh:2374 msgid "Commit Message:" msgstr "" -#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71 +#: git-gui.sh:2419 git-gui.sh:2557 lib/console.tcl:71 msgid "Copy All" msgstr "" -#: git-gui.sh:2406 lib/blame.tcl:104 +#: git-gui.sh:2443 lib/blame.tcl:104 msgid "File:" msgstr "" -#: git-gui.sh:2508 +#: git-gui.sh:2545 msgid "Refresh" msgstr "" -#: git-gui.sh:2529 +#: git-gui.sh:2566 msgid "Apply/Reverse Hunk" msgstr "" -#: git-gui.sh:2535 +#: git-gui.sh:2572 msgid "Decrease Font Size" msgstr "" -#: git-gui.sh:2539 +#: git-gui.sh:2576 msgid "Increase Font Size" msgstr "" -#: git-gui.sh:2544 +#: git-gui.sh:2581 msgid "Show Less Context" msgstr "" -#: git-gui.sh:2551 +#: git-gui.sh:2588 msgid "Show More Context" msgstr "" -#: git-gui.sh:2565 +#: git-gui.sh:2602 msgid "Unstage Hunk From Commit" msgstr "" -#: git-gui.sh:2567 +#: git-gui.sh:2604 msgid "Stage Hunk For Commit" msgstr "" -#: git-gui.sh:2586 +#: git-gui.sh:2623 msgid "Initializing..." msgstr "" -#: git-gui.sh:2677 +#: git-gui.sh:2718 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -433,14 +433,14 @@ msgid "" "\n" msgstr "" -#: git-gui.sh:2707 +#: git-gui.sh:2748 msgid "" "\n" "This is due to a known issue with the\n" "Tcl binary distributed by Cygwin." msgstr "" -#: git-gui.sh:2712 +#: git-gui.sh:2753 #, tcl-format msgid "" "\n" @@ -555,7 +555,7 @@ msgstr "" msgid "Create New Branch" msgstr "" -#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199 +#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375 msgid "Create" msgstr "" @@ -703,9 +703,9 @@ msgstr "" msgid "Browse Branch Files" msgstr "" -#: lib/browser.tcl:277 lib/choose_repository.tcl:215 -#: lib/choose_repository.tcl:305 lib/choose_repository.tcl:315 -#: lib/choose_repository.tcl:811 +#: lib/browser.tcl:277 lib/choose_repository.tcl:391 +#: lib/choose_repository.tcl:482 lib/choose_repository.tcl:492 +#: lib/choose_repository.tcl:989 msgid "Browse" msgstr "" @@ -844,209 +844,225 @@ msgid "" "If you like this text, it can be your font." msgstr "" -#: lib/choose_repository.tcl:25 +#: lib/choose_repository.tcl:27 msgid "Git Gui" msgstr "" -#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204 +#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380 msgid "Create New Repository" msgstr "" -#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291 +#: lib/choose_repository.tcl:86 +msgid "New..." +msgstr "" + +#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468 msgid "Clone Existing Repository" msgstr "" -#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800 +#: lib/choose_repository.tcl:99 +msgid "Clone..." +msgstr "" + +#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978 msgid "Open Existing Repository" msgstr "" -#: lib/choose_repository.tcl:91 -msgid "Next >" +#: lib/choose_repository.tcl:112 +msgid "Open..." +msgstr "" + +#: lib/choose_repository.tcl:125 +msgid "Recent Repositories" msgstr "" -#: lib/choose_repository.tcl:152 +#: lib/choose_repository.tcl:131 +msgid "Open Recent Repository:" +msgstr "" + +#: lib/choose_repository.tcl:294 #, tcl-format msgid "Location %s already exists." msgstr "" -#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165 -#: lib/choose_repository.tcl:172 +#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307 +#: lib/choose_repository.tcl:314 #, tcl-format msgid "Failed to create repository %s:" msgstr "" -#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309 +#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486 msgid "Directory:" msgstr "" -#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363 -#: lib/choose_repository.tcl:834 +#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544 +#: lib/choose_repository.tcl:1013 msgid "Git Repository" msgstr "" -#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260 +#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437 #, tcl-format msgid "Directory %s already exists." msgstr "" -#: lib/choose_repository.tcl:265 +#: lib/choose_repository.tcl:442 #, tcl-format msgid "File %s already exists." msgstr "" -#: lib/choose_repository.tcl:286 +#: lib/choose_repository.tcl:463 msgid "Clone" msgstr "" -#: lib/choose_repository.tcl:299 +#: lib/choose_repository.tcl:476 msgid "URL:" msgstr "" -#: lib/choose_repository.tcl:319 +#: lib/choose_repository.tcl:496 msgid "Clone Type:" msgstr "" -#: lib/choose_repository.tcl:325 +#: lib/choose_repository.tcl:502 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" msgstr "" -#: lib/choose_repository.tcl:331 +#: lib/choose_repository.tcl:508 msgid "Full Copy (Slower, Redundant Backup)" msgstr "" -#: lib/choose_repository.tcl:337 +#: lib/choose_repository.tcl:514 msgid "Shared (Fastest, Not Recommended, No Backup)" msgstr "" -#: lib/choose_repository.tcl:369 lib/choose_repository.tcl:418 -#: lib/choose_repository.tcl:560 lib/choose_repository.tcl:630 -#: lib/choose_repository.tcl:840 lib/choose_repository.tcl:848 +#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597 +#: lib/choose_repository.tcl:738 lib/choose_repository.tcl:808 +#: lib/choose_repository.tcl:1019 lib/choose_repository.tcl:1027 #, tcl-format msgid "Not a Git repository: %s" msgstr "" -#: lib/choose_repository.tcl:405 +#: lib/choose_repository.tcl:586 msgid "Standard only available for local repository." msgstr "" -#: lib/choose_repository.tcl:409 +#: lib/choose_repository.tcl:590 msgid "Shared only available for local repository." msgstr "" -#: lib/choose_repository.tcl:439 +#: lib/choose_repository.tcl:617 msgid "Failed to configure origin" msgstr "" -#: lib/choose_repository.tcl:451 +#: lib/choose_repository.tcl:629 msgid "Counting objects" msgstr "" -#: lib/choose_repository.tcl:452 +#: lib/choose_repository.tcl:630 msgid "buckets" msgstr "" -#: lib/choose_repository.tcl:476 +#: lib/choose_repository.tcl:654 #, tcl-format msgid "Unable to copy objects/info/alternates: %s" msgstr "" -#: lib/choose_repository.tcl:512 +#: lib/choose_repository.tcl:690 #, tcl-format msgid "Nothing to clone from %s." msgstr "" -#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728 -#: lib/choose_repository.tcl:740 +#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906 +#: lib/choose_repository.tcl:918 msgid "The 'master' branch has not been initialized." msgstr "" -#: lib/choose_repository.tcl:527 +#: lib/choose_repository.tcl:705 msgid "Hardlinks are unavailable. Falling back to copying." msgstr "" -#: lib/choose_repository.tcl:539 +#: lib/choose_repository.tcl:717 #, tcl-format msgid "Cloning from %s" msgstr "" -#: lib/choose_repository.tcl:570 +#: lib/choose_repository.tcl:748 msgid "Copying objects" msgstr "" -#: lib/choose_repository.tcl:571 +#: lib/choose_repository.tcl:749 msgid "KiB" msgstr "" -#: lib/choose_repository.tcl:595 +#: lib/choose_repository.tcl:773 #, tcl-format msgid "Unable to copy object: %s" msgstr "" -#: lib/choose_repository.tcl:605 +#: lib/choose_repository.tcl:783 msgid "Linking objects" msgstr "" -#: lib/choose_repository.tcl:606 +#: lib/choose_repository.tcl:784 msgid "objects" msgstr "" -#: lib/choose_repository.tcl:614 +#: lib/choose_repository.tcl:792 #, tcl-format msgid "Unable to hardlink object: %s" msgstr "" -#: lib/choose_repository.tcl:669 +#: lib/choose_repository.tcl:847 msgid "Cannot fetch branches and objects. See console output for details." msgstr "" -#: lib/choose_repository.tcl:680 +#: lib/choose_repository.tcl:858 msgid "Cannot fetch tags. See console output for details." msgstr "" -#: lib/choose_repository.tcl:704 +#: lib/choose_repository.tcl:882 msgid "Cannot determine HEAD. See console output for details." msgstr "" -#: lib/choose_repository.tcl:713 +#: lib/choose_repository.tcl:891 #, tcl-format msgid "Unable to cleanup %s" msgstr "" -#: lib/choose_repository.tcl:719 +#: lib/choose_repository.tcl:897 msgid "Clone failed." msgstr "" -#: lib/choose_repository.tcl:726 +#: lib/choose_repository.tcl:904 msgid "No default branch obtained." msgstr "" -#: lib/choose_repository.tcl:737 +#: lib/choose_repository.tcl:915 #, tcl-format msgid "Cannot resolve %s as a commit." msgstr "" -#: lib/choose_repository.tcl:749 +#: lib/choose_repository.tcl:927 msgid "Creating working directory" msgstr "" -#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80 -#: lib/index.tcl:149 +#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127 +#: lib/index.tcl:193 msgid "files" msgstr "" -#: lib/choose_repository.tcl:779 +#: lib/choose_repository.tcl:957 msgid "Initial file checkout failed." msgstr "" -#: lib/choose_repository.tcl:795 +#: lib/choose_repository.tcl:973 msgid "Open" msgstr "" -#: lib/choose_repository.tcl:805 +#: lib/choose_repository.tcl:983 msgid "Repository:" msgstr "" -#: lib/choose_repository.tcl:854 +#: lib/choose_repository.tcl:1033 #, tcl-format msgid "Failed to open repository %s:" msgstr "" @@ -1161,7 +1177,7 @@ msgid "" "\n" "A good commit message has the following format:\n" "\n" -"- First line: Describe in one sentance what you did.\n" +"- First line: Describe in one sentence what you did.\n" "- Second line: Blank\n" "- Remaining lines: Describe why this change is good.\n" msgstr "" @@ -1330,31 +1346,53 @@ msgstr "" msgid "You must correct the above errors before committing." msgstr "" -#: lib/index.tcl:241 +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "" + +#: lib/index.tcl:15 +msgid "Index Error" +msgstr "" + +#: lib/index.tcl:21 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "" + +#: lib/index.tcl:27 +msgid "Continue" +msgstr "" + +#: lib/index.tcl:31 +msgid "Unlock Index" +msgstr "" + +#: lib/index.tcl:282 #, tcl-format msgid "Unstaging %s from commit" msgstr "" -#: lib/index.tcl:285 +#: lib/index.tcl:326 #, tcl-format msgid "Adding %s" msgstr "" -#: lib/index.tcl:340 +#: lib/index.tcl:381 #, tcl-format msgid "Revert changes in file %s?" msgstr "" -#: lib/index.tcl:342 +#: lib/index.tcl:383 #, tcl-format msgid "Revert changes in these %i files?" msgstr "" -#: lib/index.tcl:348 +#: lib/index.tcl:389 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" -#: lib/index.tcl:351 +#: lib/index.tcl:392 msgid "Do Nothing" msgstr "" @@ -1539,18 +1577,6 @@ msgstr "" msgid "Failed to completely save options:" msgstr "" -#: lib/remote.tcl:165 -msgid "Prune from" -msgstr "" - -#: lib/remote.tcl:170 -msgid "Fetch from" -msgstr "" - -#: lib/remote.tcl:213 -msgid "Push to" -msgstr "" - #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 msgid "Delete Remote Branch" msgstr "" @@ -1627,11 +1653,23 @@ msgstr "" msgid "Scanning %s..." msgstr "" -#: lib/shortcut.tcl:26 lib/shortcut.tcl:74 -msgid "Cannot write script:" +#: lib/remote.tcl:165 +msgid "Prune from" +msgstr "" + +#: lib/remote.tcl:170 +msgid "Fetch from" +msgstr "" + +#: lib/remote.tcl:213 +msgid "Push to" +msgstr "" + +#: lib/shortcut.tcl:20 lib/shortcut.tcl:61 +msgid "Cannot write shortcut:" msgstr "" -#: lib/shortcut.tcl:149 +#: lib/shortcut.tcl:136 msgid "Cannot write icon:" msgstr "" diff --git a/git-gui/po/glossary/it.po b/git-gui/po/glossary/it.po index 8e3d9a2f07..bb46b48d6b 100644 --- a/git-gui/po/glossary/it.po +++ b/git-gui/po/glossary/it.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: git-gui glossary\n" -"POT-Creation-Date: 2007-10-05 22:30+0200\n" +"POT-Creation-Date: 2007-10-19 21:43+0200\n" "PO-Revision-Date: 2007-10-10 15:24+0200\n" "Last-Translator: Michele Ballabio <barra_cuda@katamail.com>\n" "Language-Team: Italian \n" @@ -50,8 +50,8 @@ msgstr "attivazione, checkout, revisione attiva, prelievo (TortoiseCVS)?" #. "The action of updating the working tree to a revision which was stored in the object database." msgid "checkout [verb]" msgstr "" -"attivare, effettuare un checkout, attivare revisione, prelevare (TortoiseCVS), " -"ritirare (TSVN)?" +"attivare, effettuare un checkout, attivare revisione, prelevare " +"(TortoiseCVS), ritirare (TSVN)?" #. "" msgid "clone [verb]" @@ -99,7 +99,7 @@ msgstr "effettuare la fusione, unire, fondere, eseguire la fusione" msgid "message" msgstr "messaggio, commento" -#. "" +#. "Deletes all stale tracking branches under <name>. These stale branches have already been removed from the remote repository referenced by <name>, but are still locally available in 'remotes/<name>'." msgid "prune" msgstr "potatura" @@ -117,6 +117,10 @@ msgstr "propaga" msgid "redo" msgstr "ripeti, rifai" +#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks." +msgid "remote" +msgstr "remoto" + #. "A collection of refs (?) together with an object database containing all objects which are reachable from the refs... (oops, you've lost me here. Again, please an explanation for mere mortals?)" msgid "repository" msgstr "archivio, repository, database? deposito (rapidsvn)?" @@ -160,8 +164,8 @@ msgstr "etichettare" #. "A regular git branch that is used to follow changes from another repository." msgid "tracking branch" msgstr "" -"duplicato locale di ramo remoto, ramo in 'tracking', ramo inseguitore? ramo di {inseguimento,allineamento," -"rilevamento,puntamento}?" +"duplicato locale di ramo remoto, ramo in 'tracking', ramo inseguitore? ramo " +"di {inseguimento,allineamento,rilevamento,puntamento}?" #. "" msgid "undo" diff --git a/git-gui/po/hu.po b/git-gui/po/hu.po index e8c04f7aea..627c05eb99 100644 --- a/git-gui/po/hu.po +++ b/git-gui/po/hu.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui-i 18n\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-10 04:04-0400\n" -"PO-Revision-Date: 2007-07-27 13:15+0200\n" +"POT-Creation-Date: 2007-11-24 10:36+0100\n" +"PO-Revision-Date: 2007-12-04 01:15+0100\n" "Last-Translator: Miklos Vajna <vmiklos@frugalware.org>\n" "Language-Team: Hungarian\n" "MIME-Version: 1.0\n" @@ -16,33 +16,33 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744 -#: git-gui.sh:763 +#: git-gui.sh:41 git-gui.sh:604 git-gui.sh:618 git-gui.sh:631 git-gui.sh:714 +#: git-gui.sh:733 msgid "git-gui: fatal error" -msgstr "" +msgstr "git-gui: végzetes hiba" -#: git-gui.sh:595 -#, fuzzy, tcl-format +#: git-gui.sh:565 +#, tcl-format msgid "Invalid font specified in %s:" -msgstr "Érvénytelen font lett megadva a grafikus felületben.%s:" +msgstr "Érvénytelen font lett megadva itt: %s:" -#: git-gui.sh:620 +#: git-gui.sh:590 msgid "Main Font" msgstr "Fő betűtípus" -#: git-gui.sh:621 +#: git-gui.sh:591 msgid "Diff/Console Font" msgstr "Diff/konzol betűtípus" -#: git-gui.sh:635 +#: git-gui.sh:605 msgid "Cannot find git in PATH." msgstr "A git nem található a PATH-ban." -#: git-gui.sh:662 +#: git-gui.sh:632 msgid "Cannot parse Git version string:" msgstr "Nem értelmezhető a Git verzió sztring:" -#: git-gui.sh:680 +#: git-gui.sh:650 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -61,80 +61,79 @@ msgstr "" "\n" "Feltételezhetjük, hogy a(z) '%s' verziója legalább 1.5.0?\n" -#: git-gui.sh:853 +#: git-gui.sh:888 msgid "Git directory not found:" msgstr "A Git könyvtár nem található:" -#: git-gui.sh:860 -#, fuzzy +#: git-gui.sh:895 msgid "Cannot move to top of working directory:" -msgstr "Nem használható vicces .git könyvtár:" +msgstr "Nem lehet a munkakönyvtár tetejére lépni:" -#: git-gui.sh:867 +#: git-gui.sh:902 msgid "Cannot use funny .git directory:" msgstr "Nem használható vicces .git könyvtár:" -#: git-gui.sh:872 +#: git-gui.sh:907 msgid "No working directory" msgstr "Nincs munkakönyvtár" -#: git-gui.sh:1019 +#: git-gui.sh:1054 msgid "Refreshing file status..." msgstr "A fájlok státuszának frissítése..." -#: git-gui.sh:1084 +#: git-gui.sh:1119 msgid "Scanning for modified files ..." msgstr "Módosított fájlok keresése ..." -#: git-gui.sh:1259 lib/browser.tcl:245 +#: git-gui.sh:1294 lib/browser.tcl:245 msgid "Ready." msgstr "Kész." -#: git-gui.sh:1525 +#: git-gui.sh:1560 msgid "Unmodified" msgstr "Nem módosított" -#: git-gui.sh:1527 +#: git-gui.sh:1562 msgid "Modified, not staged" msgstr "Módosított, de nem kiválasztott" -#: git-gui.sh:1528 git-gui.sh:1533 +#: git-gui.sh:1563 git-gui.sh:1568 msgid "Staged for commit" msgstr "Kiválasztva commitolásra" -#: git-gui.sh:1529 git-gui.sh:1534 +#: git-gui.sh:1564 git-gui.sh:1569 msgid "Portions staged for commit" msgstr "Részek kiválasztva commitolásra" -#: git-gui.sh:1530 git-gui.sh:1535 +#: git-gui.sh:1565 git-gui.sh:1570 msgid "Staged for commit, missing" msgstr "Kiválasztva commitolásra, hiányzó" -#: git-gui.sh:1532 +#: git-gui.sh:1567 msgid "Untracked, not staged" msgstr "Nem követett, nem kiválasztott" -#: git-gui.sh:1537 +#: git-gui.sh:1572 msgid "Missing" msgstr "Hiányzó" -#: git-gui.sh:1538 +#: git-gui.sh:1573 msgid "Staged for removal" msgstr "Kiválasztva eltávolításra" -#: git-gui.sh:1539 +#: git-gui.sh:1574 msgid "Staged for removal, still present" msgstr "Kiválasztva eltávolításra, jelenleg is elérhető" -#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544 +#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579 msgid "Requires merge resolution" msgstr "Merge feloldás szükséges" -#: git-gui.sh:1579 +#: git-gui.sh:1614 msgid "Starting gitk... please wait..." msgstr "A gitk indítása... várjunk..." -#: git-gui.sh:1588 +#: git-gui.sh:1623 #, tcl-format msgid "" "Unable to start gitk:\n" @@ -145,300 +144,295 @@ msgstr "" "\n" "A(z) %s nem létezik" -#: git-gui.sh:1788 lib/choose_repository.tcl:32 +#: git-gui.sh:1823 lib/choose_repository.tcl:35 msgid "Repository" msgstr "Repó" -#: git-gui.sh:1789 +#: git-gui.sh:1824 msgid "Edit" msgstr "Szerkesztés" -#: git-gui.sh:1791 lib/choose_rev.tcl:560 +#: git-gui.sh:1826 lib/choose_rev.tcl:560 msgid "Branch" msgstr "Branch" -#: git-gui.sh:1794 lib/choose_rev.tcl:547 -#, fuzzy +#: git-gui.sh:1829 lib/choose_rev.tcl:547 msgid "Commit@@noun" -msgstr "Commit" +msgstr "Commit@@főnév" -#: git-gui.sh:1797 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +#: git-gui.sh:1832 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 msgid "Merge" msgstr "Merge" -#: git-gui.sh:1798 lib/choose_rev.tcl:556 -#, fuzzy +#: git-gui.sh:1833 lib/choose_rev.tcl:556 msgid "Remote" -msgstr "Távoli:" +msgstr "Távoli" -#: git-gui.sh:1807 +#: git-gui.sh:1842 msgid "Browse Current Branch's Files" msgstr "A jelenlegi branch fájljainak böngészése" -#: git-gui.sh:1811 +#: git-gui.sh:1846 msgid "Browse Branch Files..." msgstr "A branch fájljainak böngészése..." -#: git-gui.sh:1816 +#: git-gui.sh:1851 msgid "Visualize Current Branch's History" msgstr "A jelenlegi branch történetének vizualizálása" -#: git-gui.sh:1820 +#: git-gui.sh:1855 msgid "Visualize All Branch History" msgstr "Az összes branch történetének vizualizálása" -#: git-gui.sh:1827 +#: git-gui.sh:1862 #, tcl-format msgid "Browse %s's Files" msgstr "A(z) %s branch fájljainak böngészése" -#: git-gui.sh:1829 +#: git-gui.sh:1864 #, tcl-format msgid "Visualize %s's History" msgstr "A(z) %s branch történetének vizualizálása" -#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:1869 lib/database.tcl:27 lib/database.tcl:67 msgid "Database Statistics" msgstr "Adatbázis statisztikák" -#: git-gui.sh:1837 lib/database.tcl:34 +#: git-gui.sh:1872 lib/database.tcl:34 msgid "Compress Database" msgstr "Adatbázis tömörítése" -#: git-gui.sh:1840 +#: git-gui.sh:1875 msgid "Verify Database" msgstr "Adatbázis ellenőrzése" -#: git-gui.sh:1847 git-gui.sh:1851 git-gui.sh:1855 lib/shortcut.tcl:9 -#: lib/shortcut.tcl:45 lib/shortcut.tcl:84 +#: git-gui.sh:1882 git-gui.sh:1886 git-gui.sh:1890 lib/shortcut.tcl:7 +#: lib/shortcut.tcl:39 lib/shortcut.tcl:71 msgid "Create Desktop Icon" msgstr "Asztal ikon létrehozása" -#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95 +#: git-gui.sh:1895 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184 msgid "Quit" msgstr "Kilépés" -#: git-gui.sh:1867 +#: git-gui.sh:1902 msgid "Undo" msgstr "Visszavonás" -#: git-gui.sh:1870 +#: git-gui.sh:1905 msgid "Redo" msgstr "Mégis" -#: git-gui.sh:1874 git-gui.sh:2366 +#: git-gui.sh:1909 git-gui.sh:2403 msgid "Cut" msgstr "Kivágás" -#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512 +#: git-gui.sh:1912 git-gui.sh:2406 git-gui.sh:2477 git-gui.sh:2549 #: lib/console.tcl:67 msgid "Copy" msgstr "Másolás" -#: git-gui.sh:1880 git-gui.sh:2372 +#: git-gui.sh:1915 git-gui.sh:2409 msgid "Paste" msgstr "Beillesztés" -#: git-gui.sh:1883 git-gui.sh:2375 lib/branch_delete.tcl:26 +#: git-gui.sh:1918 git-gui.sh:2412 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Törlés" -#: git-gui.sh:1887 git-gui.sh:2379 git-gui.sh:2516 lib/console.tcl:69 +#: git-gui.sh:1922 git-gui.sh:2416 git-gui.sh:2553 lib/console.tcl:69 msgid "Select All" msgstr "Mindent kiválaszt" -#: git-gui.sh:1896 +#: git-gui.sh:1931 msgid "Create..." msgstr "Létrehozás..." -#: git-gui.sh:1902 +#: git-gui.sh:1937 msgid "Checkout..." msgstr "Checkout..." -#: git-gui.sh:1908 +#: git-gui.sh:1943 msgid "Rename..." msgstr "Átnevezés..." -#: git-gui.sh:1913 git-gui.sh:2012 +#: git-gui.sh:1948 git-gui.sh:2048 msgid "Delete..." msgstr "Törlés..." -#: git-gui.sh:1918 +#: git-gui.sh:1953 msgid "Reset..." msgstr "Visszaállítás..." -#: git-gui.sh:1930 git-gui.sh:2313 +#: git-gui.sh:1965 git-gui.sh:2350 msgid "New Commit" msgstr "Új commit" -#: git-gui.sh:1938 git-gui.sh:2320 +#: git-gui.sh:1973 git-gui.sh:2357 msgid "Amend Last Commit" msgstr "Utolsó commit javítása" -#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "Keresés újra" -#: git-gui.sh:1953 +#: git-gui.sh:1988 msgid "Stage To Commit" msgstr "Kiválasztás commitolásra" -#: git-gui.sh:1958 +#: git-gui.sh:1994 msgid "Stage Changed Files To Commit" msgstr "Módosított fájlok kiválasztása commitolásra" -#: git-gui.sh:1964 +#: git-gui.sh:2000 msgid "Unstage From Commit" msgstr "Commitba való kiválasztás visszavonása" -#: git-gui.sh:1969 lib/index.tcl:352 +#: git-gui.sh:2005 lib/index.tcl:393 msgid "Revert Changes" msgstr "Változtatások visszaállítása" -#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390 +#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427 msgid "Sign Off" msgstr "Aláír" -#: git-gui.sh:1980 git-gui.sh:2296 -#, fuzzy +#: git-gui.sh:2016 git-gui.sh:2333 msgid "Commit@@verb" -msgstr "Commit" +msgstr "Commit@@ige" -#: git-gui.sh:1991 +#: git-gui.sh:2027 msgid "Local Merge..." msgstr "Helyi merge..." -#: git-gui.sh:1996 +#: git-gui.sh:2032 msgid "Abort Merge..." msgstr "Merge megszakítása..." -#: git-gui.sh:2008 +#: git-gui.sh:2044 msgid "Push..." msgstr "Push..." -#: git-gui.sh:2019 lib/choose_repository.tcl:41 +#: git-gui.sh:2055 lib/choose_repository.tcl:40 msgid "Apple" msgstr "Apple" -#: git-gui.sh:2022 git-gui.sh:2044 lib/about.tcl:13 -#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50 +#: git-gui.sh:2058 git-gui.sh:2080 lib/about.tcl:13 +#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49 #, tcl-format msgid "About %s" msgstr "Névjegy: %s" -#: git-gui.sh:2026 +#: git-gui.sh:2062 msgid "Preferences..." -msgstr "" +msgstr "Beállítások..." -#: git-gui.sh:2034 git-gui.sh:2558 +#: git-gui.sh:2070 git-gui.sh:2595 msgid "Options..." msgstr "Opciók..." -#: git-gui.sh:2040 lib/choose_repository.tcl:47 +#: git-gui.sh:2076 lib/choose_repository.tcl:46 msgid "Help" msgstr "Segítség" -#: git-gui.sh:2081 +#: git-gui.sh:2117 msgid "Online Documentation" msgstr "Online dokumentáció" -#: git-gui.sh:2165 +#: git-gui.sh:2201 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" -msgstr "" +msgstr "végzetes hiba: nem érhető el a(z) %s útvonal: Nincs ilyen fájl vagy könyvtár" -#: git-gui.sh:2198 +#: git-gui.sh:2234 msgid "Current Branch:" msgstr "Jelenlegi branch:" -#: git-gui.sh:2219 -#, fuzzy +#: git-gui.sh:2255 msgid "Staged Changes (Will Commit)" msgstr "Kiválasztott változtatások (commitolva lesz)" -#: git-gui.sh:2239 -#, fuzzy +#: git-gui.sh:2274 msgid "Unstaged Changes" -msgstr "Változtatások kiválasztása" +msgstr "Kiválasztatlan változtatások" -#: git-gui.sh:2286 +#: git-gui.sh:2323 msgid "Stage Changed" msgstr "Változtatások kiválasztása" -#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2339 lib/transport.tcl:93 lib/transport.tcl:182 msgid "Push" msgstr "Push" -#: git-gui.sh:2332 +#: git-gui.sh:2369 msgid "Initial Commit Message:" msgstr "Kezdeti commit üzenet:" -#: git-gui.sh:2333 +#: git-gui.sh:2370 msgid "Amended Commit Message:" msgstr "Javító commit üzenet:" -#: git-gui.sh:2334 +#: git-gui.sh:2371 msgid "Amended Initial Commit Message:" msgstr "Kezdeti javító commit üzenet:" -#: git-gui.sh:2335 +#: git-gui.sh:2372 msgid "Amended Merge Commit Message:" msgstr "Javító merge commit üzenet:" -#: git-gui.sh:2336 +#: git-gui.sh:2373 msgid "Merge Commit Message:" msgstr "Merge commit üzenet:" -#: git-gui.sh:2337 +#: git-gui.sh:2374 msgid "Commit Message:" msgstr "Commit üzenet:" -#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71 +#: git-gui.sh:2419 git-gui.sh:2557 lib/console.tcl:71 msgid "Copy All" msgstr "Összes másolása" -#: git-gui.sh:2406 lib/blame.tcl:104 +#: git-gui.sh:2443 lib/blame.tcl:104 msgid "File:" msgstr "Fájl:" -#: git-gui.sh:2508 +#: git-gui.sh:2545 msgid "Refresh" msgstr "Frissítés" -#: git-gui.sh:2529 +#: git-gui.sh:2566 msgid "Apply/Reverse Hunk" msgstr "Hunk alkalmazása/visszaállítása" -#: git-gui.sh:2535 +#: git-gui.sh:2572 msgid "Decrease Font Size" msgstr "Font méret csökkentése" -#: git-gui.sh:2539 +#: git-gui.sh:2576 msgid "Increase Font Size" msgstr "Fönt méret növelése" -#: git-gui.sh:2544 +#: git-gui.sh:2581 msgid "Show Less Context" msgstr "Kevesebb környezet mutatása" -#: git-gui.sh:2551 +#: git-gui.sh:2588 msgid "Show More Context" msgstr "Több környezet mutatása" -#: git-gui.sh:2565 +#: git-gui.sh:2602 msgid "Unstage Hunk From Commit" msgstr "Hunk törlése commitból" -#: git-gui.sh:2567 +#: git-gui.sh:2604 msgid "Stage Hunk For Commit" msgstr "Hunk kiválasztása commitba" -#: git-gui.sh:2586 +#: git-gui.sh:2623 msgid "Initializing..." msgstr "Inicializálás..." -#: git-gui.sh:2677 +#: git-gui.sh:2718 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -448,15 +442,24 @@ msgid "" "by %s:\n" "\n" msgstr "" +"Lehetséges, hogy környezeti problémák vannak.\n" +"\n" +"A következő környezeti változók valószínűleg\n" +"figyelmen kívül lesznek hagyva a(z) %s által\n" +"indított folyamatok által:\n" +"\n" -#: git-gui.sh:2707 +#: git-gui.sh:2748 msgid "" "\n" "This is due to a known issue with the\n" "Tcl binary distributed by Cygwin." msgstr "" +"\n" +"Ez a Cygwin által terjesztett Tcl binárisban\n" +"lévő ismert hiba miatt van." -#: git-gui.sh:2712 +#: git-gui.sh:2753 #, tcl-format msgid "" "\n" @@ -466,6 +469,12 @@ msgid "" "user.email settings into your personal\n" "~/.gitconfig file.\n" msgstr "" +"\n" +"\n" +"Egy jó helyettesítés a(z) %s számára\n" +"a user.name és user.email beállítások\n" +"elhelyezése a személyes\n" +"~/.gitconfig fájlba.\n" #: lib/about.tcl:25 msgid "git-gui - a graphical user interface for Git." @@ -490,50 +499,47 @@ msgstr "A(z) %s olvasása..." #: lib/blame.tcl:473 msgid "Loading copy/move tracking annotations..." -msgstr "" +msgstr "A másolást/átnevezést követő annotációk betöltése..." #: lib/blame.tcl:493 msgid "lines annotated" -msgstr "" +msgstr "sor annotálva" #: lib/blame.tcl:674 msgid "Loading original location annotations..." -msgstr "" +msgstr "Az eredeti hely annotációk betöltése..." #: lib/blame.tcl:677 msgid "Annotation complete." -msgstr "" +msgstr "Az annotáció kész." #: lib/blame.tcl:731 -#, fuzzy msgid "Loading annotation..." -msgstr "A(z) %s betöltése..." +msgstr "Az annotáció betöltése..." #: lib/blame.tcl:787 msgid "Author:" -msgstr "" +msgstr "Szerző:" #: lib/blame.tcl:791 -#, fuzzy msgid "Committer:" -msgstr "Commit:" +msgstr "Commiter:" #: lib/blame.tcl:796 msgid "Original File:" -msgstr "" +msgstr "Eredeti fájl:" #: lib/blame.tcl:910 msgid "Originally By:" -msgstr "" +msgstr "Eredeti szerző:" #: lib/blame.tcl:916 -#, fuzzy msgid "In File:" -msgstr "Fájl:" +msgstr "Ebben a fájlban:" #: lib/blame.tcl:921 msgid "Copied Or Moved Here By:" -msgstr "" +msgstr "Ide másolta vagy helyezte:" #: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19 msgid "Checkout Branch" @@ -574,7 +580,7 @@ msgstr "Branch létrehozása" msgid "Create New Branch" msgstr "Új branch létrehozása" -#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199 +#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375 msgid "Create" msgstr "Létrehozás" @@ -727,9 +733,9 @@ msgstr "[Fel a szülőhöz]" msgid "Browse Branch Files" msgstr "A branch fájljainak böngészése" -#: lib/browser.tcl:277 lib/choose_repository.tcl:215 -#: lib/choose_repository.tcl:305 lib/choose_repository.tcl:315 -#: lib/choose_repository.tcl:811 +#: lib/browser.tcl:277 lib/choose_repository.tcl:391 +#: lib/choose_repository.tcl:482 lib/choose_repository.tcl:492 +#: lib/choose_repository.tcl:989 msgid "Browse" msgstr "Böngészés" @@ -741,7 +747,7 @@ msgstr "A(z) %s letöltése innen: %s" #: lib/checkout_op.tcl:127 #, tcl-format msgid "fatal: Cannot resolve %s" -msgstr "" +msgstr "végzetes: Nem lehet feloldani a következőt: %s" #: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31 msgid "Close" @@ -797,9 +803,9 @@ msgstr "" "Az újrakeresés most automatikusan el fog indulni.\n" #: lib/checkout_op.tcl:322 -#, fuzzy, tcl-format +#, tcl-format msgid "Updating working directory to '%s'..." -msgstr "Nincs munkakönyvtár" +msgstr "A munkkönyvtár frissiítése a következőre: '%s'..." #: lib/checkout_op.tcl:353 #, tcl-format @@ -828,9 +834,9 @@ msgstr "" "checkout'-ból." #: lib/checkout_op.tcl:446 -#, fuzzy, tcl-format +#, tcl-format msgid "Checked out '%s'." -msgstr "Checkout..." +msgstr "'%s' kifejtve." #: lib/checkout_op.tcl:478 #, tcl-format @@ -869,244 +875,251 @@ msgstr "" "Ennek nem szabad megtörténnie. A(z) %s most kilép és feladja." #: lib/choose_font.tcl:39 -#, fuzzy msgid "Select" -msgstr "Mindent kiválaszt" +msgstr "Kiválaszt" #: lib/choose_font.tcl:53 msgid "Font Family" -msgstr "" +msgstr "Font család" #: lib/choose_font.tcl:73 -#, fuzzy msgid "Font Size" -msgstr "Font méret csökkentése" +msgstr "Font méret" #: lib/choose_font.tcl:90 msgid "Font Example" -msgstr "" +msgstr "Font példa" #: lib/choose_font.tcl:101 msgid "" "This is example text.\n" "If you like this text, it can be your font." msgstr "" +"Ez egy példa szöveg.\n" +"Ha ez megfelel, ez lehet a betűtípus." -#: lib/choose_repository.tcl:25 +#: lib/choose_repository.tcl:27 msgid "Git Gui" -msgstr "" +msgstr "Git Gui" -#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204 -#, fuzzy +#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380 msgid "Create New Repository" -msgstr "Forrás repó" +msgstr "Új repó létrehozása" + +#: lib/choose_repository.tcl:86 +msgid "New..." +msgstr "Új..." -#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291 -#, fuzzy +#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468 msgid "Clone Existing Repository" -msgstr "Cél repó" +msgstr "Létező repó másolása" + +#: lib/choose_repository.tcl:99 +msgid "Clone..." +msgstr "Másolás..." -#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800 -#, fuzzy +#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978 msgid "Open Existing Repository" -msgstr "Cél repó" +msgstr "Létező könyvtár megnyitása" -#: lib/choose_repository.tcl:91 -msgid "Next >" -msgstr "" +#: lib/choose_repository.tcl:112 +msgid "Open..." +msgstr "Meggyitás..." + +#: lib/choose_repository.tcl:125 +msgid "Recent Repositories" +msgstr "Legutóbbi repók" -#: lib/choose_repository.tcl:152 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:131 +msgid "Open Recent Repository:" +msgstr "Legutóbbi repók megnyitása:" + +#: lib/choose_repository.tcl:294 +#, tcl-format msgid "Location %s already exists." -msgstr "A(z) '%s' branch már létezik." +msgstr "A(z) '%s' hely már létezik." -#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165 -#: lib/choose_repository.tcl:172 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307 +#: lib/choose_repository.tcl:314 +#, tcl-format msgid "Failed to create repository %s:" -msgstr "Nem sikerült teljesen elmenteni a beállításokat:" +msgstr "Nem sikerült letrehozni a(z) %s repót:" -#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309 +#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486 msgid "Directory:" -msgstr "" +msgstr "Könyvtár:" -#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363 -#: lib/choose_repository.tcl:834 -#, fuzzy +#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544 +#: lib/choose_repository.tcl:1013 msgid "Git Repository" -msgstr "Repó" +msgstr "Git repó" -#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437 +#, tcl-format msgid "Directory %s already exists." -msgstr "A(z) '%s' branch már létezik." +msgstr "A(z) '%s' könyvtár már létezik." -#: lib/choose_repository.tcl:265 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:442 +#, tcl-format msgid "File %s already exists." -msgstr "A(z) '%s' branch már létezik." +msgstr "A(z) '%s' fájl már létezik." -#: lib/choose_repository.tcl:286 -#, fuzzy +#: lib/choose_repository.tcl:463 msgid "Clone" msgstr "Bezárás" -#: lib/choose_repository.tcl:299 +#: lib/choose_repository.tcl:476 msgid "URL:" -msgstr "" +msgstr "URL:" -#: lib/choose_repository.tcl:319 +#: lib/choose_repository.tcl:496 msgid "Clone Type:" -msgstr "" +msgstr "Másolás típusa:" -#: lib/choose_repository.tcl:325 +#: lib/choose_repository.tcl:502 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" -msgstr "" +msgstr "Általános (Gyors, félig-redundáns, hardlinkek)" -#: lib/choose_repository.tcl:331 +#: lib/choose_repository.tcl:508 msgid "Full Copy (Slower, Redundant Backup)" -msgstr "" +msgstr "Teljes másolás (Lassabb, redundáns biztonsági mentés)" -#: lib/choose_repository.tcl:337 +#: lib/choose_repository.tcl:514 msgid "Shared (Fastest, Not Recommended, No Backup)" -msgstr "" +msgstr "Megosztott (Leggyorsabb, nem ajánlott, nincs mentés)" -#: lib/choose_repository.tcl:369 lib/choose_repository.tcl:418 -#: lib/choose_repository.tcl:560 lib/choose_repository.tcl:630 -#: lib/choose_repository.tcl:840 lib/choose_repository.tcl:848 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597 +#: lib/choose_repository.tcl:738 lib/choose_repository.tcl:808 +#: lib/choose_repository.tcl:1019 lib/choose_repository.tcl:1027 +#, tcl-format msgid "Not a Git repository: %s" -msgstr "Nincs kiválasztott repó." +msgstr "Nem Git repó: %s" -#: lib/choose_repository.tcl:405 +#: lib/choose_repository.tcl:586 msgid "Standard only available for local repository." -msgstr "" +msgstr "A standard csak helyi repókra érhető el." -#: lib/choose_repository.tcl:409 +#: lib/choose_repository.tcl:590 msgid "Shared only available for local repository." -msgstr "" +msgstr "A megosztott csak helyi repókra érhető el." -#: lib/choose_repository.tcl:439 +#: lib/choose_repository.tcl:617 msgid "Failed to configure origin" -msgstr "" +msgstr "Nem sikerült beállítani az origint" -#: lib/choose_repository.tcl:451 +#: lib/choose_repository.tcl:629 msgid "Counting objects" -msgstr "" +msgstr "Objektumok számolása" -#: lib/choose_repository.tcl:452 +#: lib/choose_repository.tcl:630 msgid "buckets" -msgstr "" +msgstr "vödrök" -#: lib/choose_repository.tcl:476 +#: lib/choose_repository.tcl:654 #, tcl-format msgid "Unable to copy objects/info/alternates: %s" -msgstr "" +msgstr "Nem sikerült másolni az objects/info/alternates-t: %s" -#: lib/choose_repository.tcl:512 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:690 +#, tcl-format msgid "Nothing to clone from %s." -msgstr "Új változások letöltése innen: %s" +msgstr "Semmi másolni való nincs innen: %s" -#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728 -#: lib/choose_repository.tcl:740 +#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906 +#: lib/choose_repository.tcl:918 msgid "The 'master' branch has not been initialized." -msgstr "" +msgstr "A 'master' branch nincs inicializálva." -#: lib/choose_repository.tcl:527 +#: lib/choose_repository.tcl:705 msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "" +msgstr "Nem érhetőek el hardlinkek. Másolás használata." -#: lib/choose_repository.tcl:539 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:717 +#, tcl-format msgid "Cloning from %s" -msgstr "A(z) %s letöltése innen: %s" +msgstr "Másolás innen: %s" -#: lib/choose_repository.tcl:570 -#, fuzzy +#: lib/choose_repository.tcl:748 msgid "Copying objects" -msgstr "Az objektum adatbázis tömörítése" +msgstr "Objektumok másolása" -#: lib/choose_repository.tcl:571 +#: lib/choose_repository.tcl:749 msgid "KiB" -msgstr "" +msgstr "KiB" -#: lib/choose_repository.tcl:595 +#: lib/choose_repository.tcl:773 #, tcl-format msgid "Unable to copy object: %s" -msgstr "" +msgstr "Nem sikerült másolni az objektumot: %s" -#: lib/choose_repository.tcl:605 +#: lib/choose_repository.tcl:783 msgid "Linking objects" -msgstr "" +msgstr "Objektumok összefűzése" -#: lib/choose_repository.tcl:606 +#: lib/choose_repository.tcl:784 msgid "objects" -msgstr "" +msgstr "objektum" -#: lib/choose_repository.tcl:614 +#: lib/choose_repository.tcl:792 #, tcl-format msgid "Unable to hardlink object: %s" -msgstr "" +msgstr "Nem sikerült hardlinkelni az objektumot: %s" -#: lib/choose_repository.tcl:669 +#: lib/choose_repository.tcl:847 msgid "Cannot fetch branches and objects. See console output for details." -msgstr "" +msgstr "Nem sikerült letölteni a branch-eket és az objektumokat. Bővebben a konzolos kimenetben." -#: lib/choose_repository.tcl:680 +#: lib/choose_repository.tcl:858 msgid "Cannot fetch tags. See console output for details." -msgstr "" +msgstr "Nem sikerült letölteni a tageket. Bővebben a konzolos kimenetben." -#: lib/choose_repository.tcl:704 +#: lib/choose_repository.tcl:882 msgid "Cannot determine HEAD. See console output for details." -msgstr "" +msgstr "Nem sikerült megállapítani a HEAD-et. Bővebben a konzolos kimenetben." -#: lib/choose_repository.tcl:713 +#: lib/choose_repository.tcl:891 #, tcl-format msgid "Unable to cleanup %s" -msgstr "" +msgstr "Nem sikerült tiszítani: %s." -#: lib/choose_repository.tcl:719 -#, fuzzy +#: lib/choose_repository.tcl:897 msgid "Clone failed." -msgstr "A félbeszakítás nem sikerült." +msgstr "A másolás nem sikerült." -#: lib/choose_repository.tcl:726 +#: lib/choose_repository.tcl:904 msgid "No default branch obtained." -msgstr "" +msgstr "Nincs alapértelmezett branch." -#: lib/choose_repository.tcl:737 +#: lib/choose_repository.tcl:915 #, tcl-format msgid "Cannot resolve %s as a commit." -msgstr "" +msgstr "Nem sikerült felöldani a(z) %s objektumot commitként." -#: lib/choose_repository.tcl:749 -#, fuzzy +#: lib/choose_repository.tcl:927 msgid "Creating working directory" -msgstr "Nincs munkakönyvtár" +msgstr "Munkakönyvtár létrehozása" -#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80 -#: lib/index.tcl:149 +#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127 +#: lib/index.tcl:193 msgid "files" -msgstr "" +msgstr "fájl" -#: lib/choose_repository.tcl:779 +#: lib/choose_repository.tcl:957 msgid "Initial file checkout failed." -msgstr "" +msgstr "A kezdeti fájl-kibontás sikertelen." -#: lib/choose_repository.tcl:795 +#: lib/choose_repository.tcl:973 msgid "Open" -msgstr "" +msgstr "Megnyitás" -#: lib/choose_repository.tcl:805 -#, fuzzy +#: lib/choose_repository.tcl:983 msgid "Repository:" -msgstr "Repó" +msgstr "Repó:" -#: lib/choose_repository.tcl:854 -#, fuzzy, tcl-format +#: lib/choose_repository.tcl:1033 +#, tcl-format msgid "Failed to open repository %s:" -msgstr "Nem sikerült teljesen elmenteni a beállításokat:" +msgstr "Nem sikerült megnyitni a(z) %s repót:" #: lib/choose_rev.tcl:53 msgid "This Detached Checkout" @@ -1143,11 +1156,11 @@ msgstr "A revízió kifejezés üres." #: lib/choose_rev.tcl:530 msgid "Updated" -msgstr "" +msgstr "Frissítve" #: lib/choose_rev.tcl:558 msgid "URL" -msgstr "" +msgstr "URL" #: lib/commit.tcl:9 msgid "" @@ -1243,7 +1256,7 @@ msgid "" "\n" "A good commit message has the following format:\n" "\n" -"- First line: Describe in one sentance what you did.\n" +"- First line: Describe in one sentence what you did.\n" "- Second line: Blank\n" "- Remaining lines: Describe why this change is good.\n" msgstr "" @@ -1262,7 +1275,7 @@ msgstr "a write-tree sikertelen:" #: lib/commit.tcl:275 #, tcl-format msgid "Commit %s appears to be corrupt" -msgstr "" +msgstr "A(z) %s commit sérültnek tűnik" #: lib/commit.tcl:279 msgid "" @@ -1285,7 +1298,7 @@ msgstr "Nincs commitolandó változtatás." #: lib/commit.tcl:303 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." -msgstr "" +msgstr "figyelmeztetés: a Tcl nem támogatja a(z) '%s' kódolást." #: lib/commit.tcl:317 msgid "commit-tree failed:" @@ -1358,11 +1371,17 @@ msgid "" "\n" "Compress the database now?" msgstr "" +"Ennek a repónak jelenleg %i különálló objektuma van.\n" +"\n" +"Az optimális teljesítményhez erősen ajánlott az adatbázis tömörítése, ha " +"több mint %i objektum létezik.\n" +"\n" +"Lehet most tömöríteni az adatbázist?" #: lib/date.tcl:25 -#, fuzzy, tcl-format +#, tcl-format msgid "Invalid date from Git: %s" -msgstr "Érvénytelen revízió: %s" +msgstr "Érvénytelen dátum a Git-től: %s" #: lib/diff.tcl:42 #, tcl-format @@ -1387,14 +1406,14 @@ msgstr "" "Egy újrakeresés fog indulni a hasonló állapotú fájlok megtalálása érdekében." #: lib/diff.tcl:81 -#, fuzzy, tcl-format +#, tcl-format msgid "Loading diff of %s..." -msgstr "A(z) %s betöltése..." +msgstr "A(z) %s diff-jének betöltése..." #: lib/diff.tcl:114 lib/diff.tcl:184 #, tcl-format msgid "Unable to display %s" -msgstr "" +msgstr "Nem lehet megjeleníteni a következőt: %s" #: lib/diff.tcl:115 msgid "Error loading file:" @@ -1402,11 +1421,11 @@ msgstr "Hiba a fájl betöltése közben:" #: lib/diff.tcl:122 msgid "Git Repository (subproject)" -msgstr "" +msgstr "Git repó (alprojekt)" #: lib/diff.tcl:134 msgid "* Binary file (not showing content)." -msgstr "" +msgstr "* Bináris fájl (tartalom elrejtése)." #: lib/diff.tcl:185 msgid "Error loading diff:" @@ -1432,33 +1451,57 @@ msgstr "figyelmeztetés" msgid "You must correct the above errors before committing." msgstr "Ki kell javítanunk a fenti hibákat commit előtt." -#: lib/index.tcl:241 -#, fuzzy, tcl-format +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "Nem sikerült az index zárolásának feloldása." + +#: lib/index.tcl:15 +msgid "Index Error" +msgstr "Index hiba" + +#: lib/index.tcl:21 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "" +"A Git index frissítése sikertelen volt. Egy újraolvasás automatikusan elindult, hogy " +"a git-gui újra szinkonban legyen." + +#: lib/index.tcl:27 +msgid "Continue" +msgstr "Folytatás" + +#: lib/index.tcl:31 +msgid "Unlock Index" +msgstr "Index zárolásának feloldása" + +#: lib/index.tcl:282 +#, tcl-format msgid "Unstaging %s from commit" -msgstr "Commitba való kiválasztás visszavonása" +msgstr "A(z) %s commitba való kiválasztásának visszavonása" -#: lib/index.tcl:285 -#, fuzzy, tcl-format +#: lib/index.tcl:326 +#, tcl-format msgid "Adding %s" -msgstr "A(z) %s olvasása..." +msgstr "A(z) %s hozzáadása..." -#: lib/index.tcl:340 +#: lib/index.tcl:381 #, tcl-format msgid "Revert changes in file %s?" msgstr "Visszaállítja a változtatásokat a(z) %s fájlban?" -#: lib/index.tcl:342 +#: lib/index.tcl:383 #, tcl-format msgid "Revert changes in these %i files?" msgstr "Visszaállítja a változtatásokat ebben e %i fájlban?" -#: lib/index.tcl:348 +#: lib/index.tcl:389 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" "Minden nem kiválasztott változtatás el fog veszni ezáltal a visszaállítás " "által." -#: lib/index.tcl:351 +#: lib/index.tcl:392 msgid "Do Nothing" msgstr "Ne csináljunk semmit" @@ -1661,43 +1704,26 @@ msgid "New Branch Name Template" msgstr "Új branch név sablon" #: lib/option.tcl:176 -#, fuzzy msgid "Change Font" -msgstr "Fő betűtípus" +msgstr "Betűtípus megváltoztatása" #: lib/option.tcl:180 #, tcl-format msgid "Choose %s" -msgstr "" +msgstr "%s választása" #: lib/option.tcl:186 msgid "pt." -msgstr "" +msgstr "pt." #: lib/option.tcl:200 msgid "Preferences" -msgstr "" +msgstr "Beállítások" #: lib/option.tcl:235 msgid "Failed to completely save options:" msgstr "Nem sikerült teljesen elmenteni a beállításokat:" -#: lib/remote.tcl:165 -#, fuzzy -msgid "Prune from" -msgstr "Törlés innen: %s..." - -# tcl-format -#: lib/remote.tcl:170 -#, fuzzy -msgid "Fetch from" -msgstr "Letöltés innen: %s..." - -#: lib/remote.tcl:213 -#, fuzzy -msgid "Push to" -msgstr "Push" - #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 msgid "Delete Remote Branch" msgstr "Távoli branch törlése" @@ -1735,12 +1761,15 @@ msgid "A branch is required for 'Merged Into'." msgstr "Egy branch szükséges a 'Merge-ölt a következőbe'-hez." #: lib/remote_branch_delete.tcl:184 -#, fuzzy, tcl-format +#, tcl-format msgid "" "The following branches are not completely merged into %s:\n" "\n" " - %s" -msgstr "A következő branchek nem teljesen lettek merge-ölve ebbe: %s:" +msgstr "" +"A következő branchek nem teljesen lettek merge-ölve ebbe: %s:" +"\n" +" - %s" #: lib/remote_branch_delete.tcl:189 #, tcl-format @@ -1779,11 +1808,24 @@ msgstr "Nincs kiválasztott repó." msgid "Scanning %s..." msgstr "Keresés itt: %s..." -#: lib/shortcut.tcl:26 lib/shortcut.tcl:74 -msgid "Cannot write script:" -msgstr "Nem sikerült írni a scriptet:" +#: lib/remote.tcl:165 +msgid "Prune from" +msgstr "Törlés innen" -#: lib/shortcut.tcl:149 +# tcl-format +#: lib/remote.tcl:170 +msgid "Fetch from" +msgstr "Letöltés innen" + +#: lib/remote.tcl:213 +msgid "Push to" +msgstr "Push ide" + +#: lib/shortcut.tcl:20 lib/shortcut.tcl:61 +msgid "Cannot write shortcut:" +msgstr "Nem sikerült írni a gyorsbillentyűt:" + +#: lib/shortcut.tcl:136 msgid "Cannot write icon:" msgstr "Nem sikerült írni az ikont:" @@ -1793,9 +1835,9 @@ msgid "%s ... %*i of %*i %s (%3i%%)" msgstr "%s ... %*i / %*i %s (%3i%%)" #: lib/transport.tcl:6 -#, fuzzy, tcl-format +#, tcl-format msgid "fetch %s" -msgstr "Letöltés" +msgstr "a(z) %s letöltése" #: lib/transport.tcl:7 #, tcl-format @@ -1805,7 +1847,7 @@ msgstr "Új változások letöltése innen: %s" #: lib/transport.tcl:18 #, tcl-format msgid "remote prune %s" -msgstr "" +msgstr "a(z) %s távoli törlése" #: lib/transport.tcl:19 #, tcl-format @@ -1815,7 +1857,7 @@ msgstr "A %s repóból törölt követő branchek törlése" #: lib/transport.tcl:25 lib/transport.tcl:71 #, tcl-format msgid "push %s" -msgstr "" +msgstr "%s push-olása" #: lib/transport.tcl:26 #, tcl-format @@ -1845,7 +1887,7 @@ msgstr "Átviteli opciók" #: lib/transport.tcl:160 msgid "Force overwrite existing branch (may discard changes)" -msgstr "" +msgstr "Létező branch felülírásának erőltetése (lehet, hogy el fog dobni változtatásokat)" #: lib/transport.tcl:164 msgid "Use thin pack (for slow network connections)" diff --git a/git-gui/po/it.po b/git-gui/po/it.po index 7668414104..33a8399175 100644 --- a/git-gui/po/it.po +++ b/git-gui/po/it.po @@ -9,41 +9,41 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-10 14:42+0200\n" -"PO-Revision-Date: 2007-10-10 15:27+0200\n" -"Last-Translator: Paolo Ciarrocchi <paolo.ciarrocchi@gmail.com>\n" +"POT-Creation-Date: 2007-11-09 11:18+0100\n" +"PO-Revision-Date: 2007-11-01 21:05+0100\n" +"Last-Translator: Michele Ballabio <barra_cuda@katamail.com>\n" "Language-Team: Italian <tp@lists.linux.it>\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744 -#: git-gui.sh:763 +#: git-gui.sh:41 git-gui.sh:604 git-gui.sh:618 git-gui.sh:631 git-gui.sh:714 +#: git-gui.sh:733 msgid "git-gui: fatal error" msgstr "git-gui: errore grave" -#: git-gui.sh:595 +#: git-gui.sh:565 #, tcl-format msgid "Invalid font specified in %s:" msgstr "Caratteri non validi specificati in %s:" -#: git-gui.sh:620 +#: git-gui.sh:590 msgid "Main Font" msgstr "Caratteri principali" -#: git-gui.sh:621 +#: git-gui.sh:591 msgid "Diff/Console Font" msgstr "Caratteri per confronti e terminale" -#: git-gui.sh:635 +#: git-gui.sh:605 msgid "Cannot find git in PATH." msgstr "Impossibile trovare git nel PATH" -#: git-gui.sh:662 +#: git-gui.sh:632 msgid "Cannot parse Git version string:" msgstr "Impossibile determinare la versione di Git:" -#: git-gui.sh:680 +#: git-gui.sh:650 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -54,7 +54,7 @@ msgid "" "\n" "Assume '%s' is version 1.5.0?\n" msgstr "" -"La versione di GIT non può essere determinata.\n" +"La versione di Git non può essere determinata.\n" "\n" "%s riporta che la versione è '%s'.\n" "\n" @@ -62,79 +62,79 @@ msgstr "" "\n" "Assumere che '%s' sia alla versione 1.5.0?\n" -#: git-gui.sh:853 +#: git-gui.sh:888 msgid "Git directory not found:" msgstr "Non trovo la directory di git: " -#: git-gui.sh:860 +#: git-gui.sh:895 msgid "Cannot move to top of working directory:" msgstr "Impossibile spostarsi sulla directory principale del progetto:" -#: git-gui.sh:867 +#: git-gui.sh:902 msgid "Cannot use funny .git directory:" msgstr "Impossibile usare una .git directory strana:" -#: git-gui.sh:872 +#: git-gui.sh:907 msgid "No working directory" msgstr "Nessuna directory di lavoro" -#: git-gui.sh:1019 +#: git-gui.sh:1054 msgid "Refreshing file status..." msgstr "Controllo dello stato dei file in corso..." -#: git-gui.sh:1084 +#: git-gui.sh:1119 msgid "Scanning for modified files ..." msgstr "Ricerca di file modificati in corso..." -#: git-gui.sh:1259 lib/browser.tcl:245 +#: git-gui.sh:1294 lib/browser.tcl:245 msgid "Ready." msgstr "Pronto." -#: git-gui.sh:1525 +#: git-gui.sh:1560 msgid "Unmodified" msgstr "Non modificato" -#: git-gui.sh:1527 +#: git-gui.sh:1562 msgid "Modified, not staged" msgstr "Modificato, non preparato per una nuova revisione" -#: git-gui.sh:1528 git-gui.sh:1533 +#: git-gui.sh:1563 git-gui.sh:1568 msgid "Staged for commit" msgstr "Preparato per una nuova revisione" -#: git-gui.sh:1529 git-gui.sh:1534 +#: git-gui.sh:1564 git-gui.sh:1569 msgid "Portions staged for commit" msgstr "Parti preparate per una nuova revisione" -#: git-gui.sh:1530 git-gui.sh:1535 +#: git-gui.sh:1565 git-gui.sh:1570 msgid "Staged for commit, missing" msgstr "Preparato per una nuova revisione, mancante" -#: git-gui.sh:1532 +#: git-gui.sh:1567 msgid "Untracked, not staged" msgstr "Non tracciato, non preparato per una nuova revisione" -#: git-gui.sh:1537 +#: git-gui.sh:1572 msgid "Missing" msgstr "Mancante" -#: git-gui.sh:1538 +#: git-gui.sh:1573 msgid "Staged for removal" msgstr "Preparato per la rimozione" -#: git-gui.sh:1539 +#: git-gui.sh:1574 msgid "Staged for removal, still present" msgstr "Preparato alla rimozione, ancora presente" -#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544 +#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579 msgid "Requires merge resolution" msgstr "Richiede risoluzione dei conflitti" -#: git-gui.sh:1579 +#: git-gui.sh:1614 msgid "Starting gitk... please wait..." msgstr "Avvio di gitk... attendere..." -#: git-gui.sh:1588 +#: git-gui.sh:1623 #, tcl-format msgid "" "Unable to start gitk:\n" @@ -145,297 +145,297 @@ msgstr "" "\n" "%s non esiste" -#: git-gui.sh:1788 lib/choose_repository.tcl:32 +#: git-gui.sh:1823 lib/choose_repository.tcl:35 msgid "Repository" msgstr "Archivio" -#: git-gui.sh:1789 +#: git-gui.sh:1824 msgid "Edit" msgstr "Modifica" -#: git-gui.sh:1791 lib/choose_rev.tcl:560 +#: git-gui.sh:1826 lib/choose_rev.tcl:560 msgid "Branch" msgstr "Ramo" -#: git-gui.sh:1794 lib/choose_rev.tcl:547 +#: git-gui.sh:1829 lib/choose_rev.tcl:547 msgid "Commit@@noun" msgstr "Revisione" -#: git-gui.sh:1797 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +#: git-gui.sh:1832 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 msgid "Merge" msgstr "Fusione (Merge)" -#: git-gui.sh:1798 lib/choose_rev.tcl:556 +#: git-gui.sh:1833 lib/choose_rev.tcl:556 msgid "Remote" msgstr "Remoto" -#: git-gui.sh:1807 +#: git-gui.sh:1842 msgid "Browse Current Branch's Files" -msgstr "Esplora i file del ramo corrente" +msgstr "Esplora i file del ramo attuale" -#: git-gui.sh:1811 +#: git-gui.sh:1846 msgid "Browse Branch Files..." msgstr "Esplora i file del ramo..." -#: git-gui.sh:1816 +#: git-gui.sh:1851 msgid "Visualize Current Branch's History" -msgstr "Visualizza la cronologia del ramo corrente" +msgstr "Visualizza la cronologia del ramo attuale" -#: git-gui.sh:1820 +#: git-gui.sh:1855 msgid "Visualize All Branch History" msgstr "Visualizza la cronologia di tutti i rami" -#: git-gui.sh:1827 +#: git-gui.sh:1862 #, tcl-format msgid "Browse %s's Files" msgstr "Esplora i file di %s" -#: git-gui.sh:1829 +#: git-gui.sh:1864 #, tcl-format msgid "Visualize %s's History" msgstr "Visualizza la cronologia di %s" -#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:1869 lib/database.tcl:27 lib/database.tcl:67 msgid "Database Statistics" msgstr "Statistiche dell'archivio" -#: git-gui.sh:1837 lib/database.tcl:34 +#: git-gui.sh:1872 lib/database.tcl:34 msgid "Compress Database" msgstr "Comprimi l'archivio" -#: git-gui.sh:1840 +#: git-gui.sh:1875 msgid "Verify Database" msgstr "Verifica l'archivio" -#: git-gui.sh:1847 git-gui.sh:1851 git-gui.sh:1855 lib/shortcut.tcl:9 -#: lib/shortcut.tcl:45 lib/shortcut.tcl:84 +#: git-gui.sh:1882 git-gui.sh:1886 git-gui.sh:1890 lib/shortcut.tcl:7 +#: lib/shortcut.tcl:39 lib/shortcut.tcl:71 msgid "Create Desktop Icon" msgstr "Crea icona desktop" -#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95 +#: git-gui.sh:1895 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184 msgid "Quit" msgstr "Esci" -#: git-gui.sh:1867 +#: git-gui.sh:1902 msgid "Undo" msgstr "Annulla" -#: git-gui.sh:1870 +#: git-gui.sh:1905 msgid "Redo" msgstr "Ripeti" -#: git-gui.sh:1874 git-gui.sh:2366 +#: git-gui.sh:1909 git-gui.sh:2403 msgid "Cut" msgstr "Taglia" -#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512 +#: git-gui.sh:1912 git-gui.sh:2406 git-gui.sh:2477 git-gui.sh:2549 #: lib/console.tcl:67 msgid "Copy" msgstr "Copia" -#: git-gui.sh:1880 git-gui.sh:2372 +#: git-gui.sh:1915 git-gui.sh:2409 msgid "Paste" msgstr "Incolla" -#: git-gui.sh:1883 git-gui.sh:2375 lib/branch_delete.tcl:26 +#: git-gui.sh:1918 git-gui.sh:2412 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "Elimina" -#: git-gui.sh:1887 git-gui.sh:2379 git-gui.sh:2516 lib/console.tcl:69 +#: git-gui.sh:1922 git-gui.sh:2416 git-gui.sh:2553 lib/console.tcl:69 msgid "Select All" msgstr "Seleziona tutto" -#: git-gui.sh:1896 +#: git-gui.sh:1931 msgid "Create..." msgstr "Crea..." -#: git-gui.sh:1902 +#: git-gui.sh:1937 msgid "Checkout..." msgstr "Attiva..." -#: git-gui.sh:1908 +#: git-gui.sh:1943 msgid "Rename..." msgstr "Rinomina" -#: git-gui.sh:1913 git-gui.sh:2012 +#: git-gui.sh:1948 git-gui.sh:2048 msgid "Delete..." msgstr "Elimina..." -#: git-gui.sh:1918 +#: git-gui.sh:1953 msgid "Reset..." msgstr "Ripristina..." -#: git-gui.sh:1930 git-gui.sh:2313 +#: git-gui.sh:1965 git-gui.sh:2350 msgid "New Commit" msgstr "Nuova revisione" -#: git-gui.sh:1938 git-gui.sh:2320 +#: git-gui.sh:1973 git-gui.sh:2357 msgid "Amend Last Commit" msgstr "Correggi l'ultima revisione" -#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "Analizza nuovamente" -#: git-gui.sh:1953 +#: git-gui.sh:1988 msgid "Stage To Commit" msgstr "Prepara per una nuova revisione" -#: git-gui.sh:1958 +#: git-gui.sh:1994 msgid "Stage Changed Files To Commit" msgstr "Prepara i file modificati per una nuova revisione" -#: git-gui.sh:1964 +#: git-gui.sh:2000 msgid "Unstage From Commit" msgstr "Annulla preparazione" -#: git-gui.sh:1969 lib/index.tcl:352 +#: git-gui.sh:2005 lib/index.tcl:393 msgid "Revert Changes" msgstr "Annulla modifiche" -#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390 +#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427 msgid "Sign Off" msgstr "Sign Off" -#: git-gui.sh:1980 git-gui.sh:2296 +#: git-gui.sh:2016 git-gui.sh:2333 msgid "Commit@@verb" msgstr "Nuova revisione" -#: git-gui.sh:1991 +#: git-gui.sh:2027 msgid "Local Merge..." msgstr "Fusione locale..." -#: git-gui.sh:1996 +#: git-gui.sh:2032 msgid "Abort Merge..." msgstr "Interrompi fusione..." -#: git-gui.sh:2008 +#: git-gui.sh:2044 msgid "Push..." msgstr "Propaga..." -#: git-gui.sh:2019 lib/choose_repository.tcl:41 +#: git-gui.sh:2055 lib/choose_repository.tcl:40 msgid "Apple" msgstr "Apple" -#: git-gui.sh:2022 git-gui.sh:2044 lib/about.tcl:13 -#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50 +#: git-gui.sh:2058 git-gui.sh:2080 lib/about.tcl:13 +#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49 #, tcl-format msgid "About %s" msgstr "Informazioni su %s" -#: git-gui.sh:2026 +#: git-gui.sh:2062 msgid "Preferences..." msgstr "Preferenze..." -#: git-gui.sh:2034 git-gui.sh:2558 +#: git-gui.sh:2070 git-gui.sh:2595 msgid "Options..." msgstr "Opzioni..." -#: git-gui.sh:2040 lib/choose_repository.tcl:47 +#: git-gui.sh:2076 lib/choose_repository.tcl:46 msgid "Help" msgstr "Aiuto" -#: git-gui.sh:2081 +#: git-gui.sh:2117 msgid "Online Documentation" msgstr "Documentazione sul web" -#: git-gui.sh:2165 +#: git-gui.sh:2201 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "" "errore grave: impossibile effettuare lo stat del path %s: file o directory " "non trovata" -#: git-gui.sh:2198 +#: git-gui.sh:2234 msgid "Current Branch:" msgstr "Ramo attuale:" -#: git-gui.sh:2219 +#: git-gui.sh:2255 msgid "Staged Changes (Will Commit)" msgstr "Modifiche preparate (saranno nella nuova revisione)" -#: git-gui.sh:2239 +#: git-gui.sh:2274 msgid "Unstaged Changes" msgstr "Modifiche non preparate" -#: git-gui.sh:2286 +#: git-gui.sh:2323 msgid "Stage Changed" msgstr "Prepara modificati" -#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2339 lib/transport.tcl:93 lib/transport.tcl:182 msgid "Push" msgstr "Propaga (Push)" -#: git-gui.sh:2332 +#: git-gui.sh:2369 msgid "Initial Commit Message:" msgstr "Messaggio di revisione iniziale:" -#: git-gui.sh:2333 +#: git-gui.sh:2370 msgid "Amended Commit Message:" msgstr "Messaggio di revisione corretto:" -#: git-gui.sh:2334 +#: git-gui.sh:2371 msgid "Amended Initial Commit Message:" msgstr "Messaggio iniziale di revisione corretto:" -#: git-gui.sh:2335 +#: git-gui.sh:2372 msgid "Amended Merge Commit Message:" msgstr "Messaggio di fusione corretto:" -#: git-gui.sh:2336 +#: git-gui.sh:2373 msgid "Merge Commit Message:" msgstr "Messaggio di fusione:" -#: git-gui.sh:2337 +#: git-gui.sh:2374 msgid "Commit Message:" msgstr "Messaggio di revisione:" -#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71 +#: git-gui.sh:2419 git-gui.sh:2557 lib/console.tcl:71 msgid "Copy All" msgstr "Copia tutto" -#: git-gui.sh:2406 lib/blame.tcl:104 +#: git-gui.sh:2443 lib/blame.tcl:104 msgid "File:" msgstr "File:" -#: git-gui.sh:2508 +#: git-gui.sh:2545 msgid "Refresh" msgstr "Rinfresca" -#: git-gui.sh:2529 +#: git-gui.sh:2566 msgid "Apply/Reverse Hunk" msgstr "Applica/Inverti sezione" -#: git-gui.sh:2535 +#: git-gui.sh:2572 msgid "Decrease Font Size" msgstr "Diminuisci dimensione caratteri" -#: git-gui.sh:2539 +#: git-gui.sh:2576 msgid "Increase Font Size" msgstr "Aumenta dimensione caratteri" -#: git-gui.sh:2544 +#: git-gui.sh:2581 msgid "Show Less Context" msgstr "Mostra meno contesto" -#: git-gui.sh:2551 +#: git-gui.sh:2588 msgid "Show More Context" msgstr "Mostra più contesto" -#: git-gui.sh:2565 +#: git-gui.sh:2602 msgid "Unstage Hunk From Commit" msgstr "Sezione non preparata per una nuova revisione" -#: git-gui.sh:2567 +#: git-gui.sh:2604 msgid "Stage Hunk For Commit" msgstr "Prepara sezione per una nuova revisione" -#: git-gui.sh:2586 +#: git-gui.sh:2623 msgid "Initializing..." msgstr "Inizializzazione..." -#: git-gui.sh:2677 +#: git-gui.sh:2718 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -452,7 +452,7 @@ msgstr "" "da %s:\n" "\n" -#: git-gui.sh:2707 +#: git-gui.sh:2748 msgid "" "\n" "This is due to a known issue with the\n" @@ -462,7 +462,7 @@ msgstr "" "Ciò è dovuto a un problema conosciuto\n" "causato dall'eseguibile Tcl distribuito da Cygwin." -#: git-gui.sh:2712 +#: git-gui.sh:2753 #, tcl-format msgid "" "\n" @@ -582,7 +582,7 @@ msgstr "Crea ramo" msgid "Create New Branch" msgstr "Crea nuovo ramo" -#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199 +#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375 msgid "Create" msgstr "Crea" @@ -682,7 +682,7 @@ msgid "" "Failed to delete branches:\n" "%s" msgstr "" -"Cancellazione rami fallita:\n" +"Impossibile cancellare i rami:\n" "%s" #: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22 @@ -736,9 +736,9 @@ msgstr "[Directory superiore]" msgid "Browse Branch Files" msgstr "Esplora i file del ramo" -#: lib/browser.tcl:277 lib/choose_repository.tcl:215 -#: lib/choose_repository.tcl:305 lib/choose_repository.tcl:315 -#: lib/choose_repository.tcl:811 +#: lib/browser.tcl:277 lib/choose_repository.tcl:391 +#: lib/choose_repository.tcl:482 lib/choose_repository.tcl:492 +#: lib/choose_repository.tcl:989 msgid "Browse" msgstr "Sfoglia" @@ -782,11 +782,12 @@ msgstr "La strategia di fusione '%s' non è supportata." #: lib/checkout_op.tcl:239 #, tcl-format msgid "Failed to update '%s'." -msgstr "Aggiornamento di '%s' fallito." +msgstr "Impossibile aggiornare '%s'." #: lib/checkout_op.tcl:251 msgid "Staging area (index) is already locked." -msgstr "L'area di preparazione per una nuova revisione (indice) è già bloccata." +msgstr "" +"L'area di preparazione per una nuova revisione (indice) è già bloccata." #: lib/checkout_op.tcl:266 msgid "" @@ -801,7 +802,7 @@ msgstr "" "\n" "Un altro programma Git ha modificato questo archivio dall'ultima analisi. " "Bisogna effettuare una nuova analisi prima di poter cambiare il ramo " -"corrente.\n" +"attuale.\n" "\n" "La nuova analisi comincerà ora.\n" @@ -870,7 +871,7 @@ msgid "" "\n" "This should not have occurred. %s will now close and give up." msgstr "" -"Preparazione ramo corrente fallita.\n" +"Impossibile preparare il ramo attuale.\n" "\n" "Questa directory di lavoro è stata convertita solo parzialmente. I file sono " "stati aggiornati correttamente, ma l'aggiornamento di un file di Git ha " @@ -902,214 +903,230 @@ msgstr "" "Questo è un testo d'esempio.\n" "Se ti piace questo testo, può essere il carattere giusto." -#: lib/choose_repository.tcl:25 +#: lib/choose_repository.tcl:27 msgid "Git Gui" msgstr "Git Gui" -#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204 +#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380 msgid "Create New Repository" msgstr "Crea nuovo archivio" -#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291 +#: lib/choose_repository.tcl:86 +msgid "New..." +msgstr "Nuovo..." + +#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468 msgid "Clone Existing Repository" msgstr "Clona archivio esistente" -#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800 +#: lib/choose_repository.tcl:99 +msgid "Clone..." +msgstr "Clona..." + +#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978 msgid "Open Existing Repository" msgstr "Apri archivio esistente" -#: lib/choose_repository.tcl:91 -msgid "Next >" -msgstr "Successivo >" +#: lib/choose_repository.tcl:112 +msgid "Open..." +msgstr "Apri..." + +#: lib/choose_repository.tcl:125 +msgid "Recent Repositories" +msgstr "Archivi recenti" + +#: lib/choose_repository.tcl:131 +msgid "Open Recent Repository:" +msgstr "Apri archivio recente:" -#: lib/choose_repository.tcl:152 +#: lib/choose_repository.tcl:294 #, tcl-format msgid "Location %s already exists." msgstr "La posizione %s esiste già." -#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165 -#: lib/choose_repository.tcl:172 +#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307 +#: lib/choose_repository.tcl:314 #, tcl-format msgid "Failed to create repository %s:" msgstr "Impossibile creare l'archivio %s:" -#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309 +#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486 msgid "Directory:" msgstr "Directory:" -#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363 -#: lib/choose_repository.tcl:834 +#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544 +#: lib/choose_repository.tcl:1013 msgid "Git Repository" msgstr "Archivio Git" -#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260 +#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437 #, tcl-format msgid "Directory %s already exists." msgstr "La directory %s esiste già." -#: lib/choose_repository.tcl:265 +#: lib/choose_repository.tcl:442 #, tcl-format msgid "File %s already exists." msgstr "Il file %s esiste già." -#: lib/choose_repository.tcl:286 +#: lib/choose_repository.tcl:463 msgid "Clone" msgstr "Clona" -#: lib/choose_repository.tcl:299 +#: lib/choose_repository.tcl:476 msgid "URL:" msgstr "URL:" -#: lib/choose_repository.tcl:319 +#: lib/choose_repository.tcl:496 msgid "Clone Type:" msgstr "Tipo di clone:" -#: lib/choose_repository.tcl:325 +#: lib/choose_repository.tcl:502 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" msgstr "Standard (veloce, semi-ridondante, con hardlink)" -#: lib/choose_repository.tcl:331 +#: lib/choose_repository.tcl:508 msgid "Full Copy (Slower, Redundant Backup)" msgstr "Copia completa (più lento, backup ridondante)" -#: lib/choose_repository.tcl:337 +#: lib/choose_repository.tcl:514 msgid "Shared (Fastest, Not Recommended, No Backup)" msgstr "Shared (il più veloce, non raccomandato, nessun backup)" -#: lib/choose_repository.tcl:369 lib/choose_repository.tcl:418 -#: lib/choose_repository.tcl:560 lib/choose_repository.tcl:630 -#: lib/choose_repository.tcl:840 lib/choose_repository.tcl:848 +#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597 +#: lib/choose_repository.tcl:738 lib/choose_repository.tcl:808 +#: lib/choose_repository.tcl:1019 lib/choose_repository.tcl:1027 #, tcl-format msgid "Not a Git repository: %s" msgstr "%s non è un archivio Git." -#: lib/choose_repository.tcl:405 +#: lib/choose_repository.tcl:586 msgid "Standard only available for local repository." msgstr "Standard è disponibile solo per archivi locali." -#: lib/choose_repository.tcl:409 +#: lib/choose_repository.tcl:590 msgid "Shared only available for local repository." msgstr "Shared è disponibile solo per archivi locali." -#: lib/choose_repository.tcl:439 +#: lib/choose_repository.tcl:617 msgid "Failed to configure origin" msgstr "Impossibile configurare origin" -#: lib/choose_repository.tcl:451 +#: lib/choose_repository.tcl:629 msgid "Counting objects" msgstr "Calcolo oggetti" -#: lib/choose_repository.tcl:452 +#: lib/choose_repository.tcl:630 msgid "buckets" msgstr "" -#: lib/choose_repository.tcl:476 +#: lib/choose_repository.tcl:654 #, tcl-format msgid "Unable to copy objects/info/alternates: %s" msgstr "Impossibile copiare oggetti/info/alternate: %s" -#: lib/choose_repository.tcl:512 +#: lib/choose_repository.tcl:690 #, tcl-format msgid "Nothing to clone from %s." msgstr "Niente da clonare da %s." -#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728 -#: lib/choose_repository.tcl:740 +#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906 +#: lib/choose_repository.tcl:918 msgid "The 'master' branch has not been initialized." msgstr "Il ramo 'master' non è stato inizializzato." -#: lib/choose_repository.tcl:527 +#: lib/choose_repository.tcl:705 msgid "Hardlinks are unavailable. Falling back to copying." msgstr "Impossibile utilizzare gli hardlink. Si ricorrerà alla copia." -#: lib/choose_repository.tcl:539 +#: lib/choose_repository.tcl:717 #, tcl-format msgid "Cloning from %s" msgstr "Clonazione da %s" -#: lib/choose_repository.tcl:570 +#: lib/choose_repository.tcl:748 msgid "Copying objects" msgstr "Copia degli oggetti" -#: lib/choose_repository.tcl:571 +#: lib/choose_repository.tcl:749 msgid "KiB" msgstr "KiB" -#: lib/choose_repository.tcl:595 +#: lib/choose_repository.tcl:773 #, tcl-format msgid "Unable to copy object: %s" msgstr "Impossibile copiare oggetto: %s" -#: lib/choose_repository.tcl:605 +#: lib/choose_repository.tcl:783 msgid "Linking objects" msgstr "Collegamento oggetti" -#: lib/choose_repository.tcl:606 +#: lib/choose_repository.tcl:784 msgid "objects" msgstr "oggetti" -#: lib/choose_repository.tcl:614 +#: lib/choose_repository.tcl:792 #, tcl-format msgid "Unable to hardlink object: %s" msgstr "Hardlink impossibile sull'oggetto: %s" -#: lib/choose_repository.tcl:669 +#: lib/choose_repository.tcl:847 msgid "Cannot fetch branches and objects. See console output for details." msgstr "" "Impossibile recuperare rami e oggetti. Controllare i dettagli forniti dalla " "console." -#: lib/choose_repository.tcl:680 +#: lib/choose_repository.tcl:858 msgid "Cannot fetch tags. See console output for details." msgstr "" "Impossibile recuperare le etichette. Controllare i dettagli forniti dalla " "console." -#: lib/choose_repository.tcl:704 +#: lib/choose_repository.tcl:882 msgid "Cannot determine HEAD. See console output for details." msgstr "" "Impossibile determinare HEAD. Controllare i dettagli forniti dalla console." -#: lib/choose_repository.tcl:713 +#: lib/choose_repository.tcl:891 #, tcl-format msgid "Unable to cleanup %s" msgstr "Impossibile ripulire %s" -#: lib/choose_repository.tcl:719 +#: lib/choose_repository.tcl:897 msgid "Clone failed." -msgstr "Clonazione fallita." +msgstr "Clonazione non riuscita." -#: lib/choose_repository.tcl:726 +#: lib/choose_repository.tcl:904 msgid "No default branch obtained." msgstr "Non è stato trovato un ramo predefinito." -#: lib/choose_repository.tcl:737 +#: lib/choose_repository.tcl:915 #, tcl-format msgid "Cannot resolve %s as a commit." msgstr "Impossibile risolvere %s come una revisione." -#: lib/choose_repository.tcl:749 +#: lib/choose_repository.tcl:927 msgid "Creating working directory" msgstr "Creazione directory di lavoro" -#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80 -#: lib/index.tcl:149 +#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127 +#: lib/index.tcl:193 msgid "files" msgstr "file" -#: lib/choose_repository.tcl:779 +#: lib/choose_repository.tcl:957 msgid "Initial file checkout failed." -msgstr "Attivazione iniziale impossibile." +msgstr "Attivazione iniziale non riuscita." -#: lib/choose_repository.tcl:795 +#: lib/choose_repository.tcl:973 msgid "Open" msgstr "Apri" -#: lib/choose_repository.tcl:805 +#: lib/choose_repository.tcl:983 msgid "Repository:" msgstr "Archivio:" -#: lib/choose_repository.tcl:854 +#: lib/choose_repository.tcl:1033 #, tcl-format msgid "Failed to open repository %s:" msgstr "Impossibile accedere all'archivio %s:" @@ -1164,8 +1181,8 @@ msgid "" msgstr "" "Non c'è niente da correggere.\n" "\n" -"Stai per creare la revisione iniziale. Non esiste una revisione " -"precedente da correggere.\n" +"Stai per creare la revisione iniziale. Non esiste una revisione precedente " +"da correggere.\n" #: lib/commit.tcl:18 msgid "" @@ -1242,8 +1259,8 @@ msgid "" msgstr "" "Nessuna modifica per la nuova revisione.\n" "\n" -"Devi preparare per una nuova revisione almeno 1 file prima di effettuare questa " -"operazione.\n" +"Devi preparare per una nuova revisione almeno 1 file prima di effettuare " +"questa operazione.\n" #: lib/commit.tcl:183 msgid "" @@ -1265,12 +1282,12 @@ msgstr "" #: lib/commit.tcl:257 msgid "write-tree failed:" -msgstr "write-tree fallito:" +msgstr "write-tree non riuscito:" #: lib/commit.tcl:275 #, tcl-format msgid "Commit %s appears to be corrupt" -msgstr "La revisione %s sembra essere corrotta" +msgstr "La revisione %s sembra essere danneggiata" #: lib/commit.tcl:279 msgid "" @@ -1297,11 +1314,11 @@ msgstr "attenzione: Tcl non supporta la codifica '%s'." #: lib/commit.tcl:317 msgid "commit-tree failed:" -msgstr "commit-tree fallito:" +msgstr "commit-tree non riuscito:" #: lib/commit.tcl:339 msgid "update-ref failed:" -msgstr "update-ref fallito:" +msgstr "update-ref non riuscito:" #: lib/commit.tcl:430 #, tcl-format @@ -1318,7 +1335,7 @@ msgstr "Successo" #: lib/console.tcl:196 msgid "Error: Command Failed" -msgstr "Errore: comando fallito" +msgstr "Errore: comando non riuscito" #: lib/database.tcl:43 msgid "Number of loose objects" @@ -1429,7 +1446,7 @@ msgstr "Errore nel caricamento delle differenze:" #: lib/diff.tcl:302 msgid "Failed to unstage selected hunk." -msgstr "La sezione scelta è ancora pronta per una nuova revisione." +msgstr "Impossibile rimuovere la sezione scelta dalla nuova revisione." #: lib/diff.tcl:309 msgid "Failed to stage selected hunk." @@ -1445,35 +1462,60 @@ msgstr "attenzione" #: lib/error.tcl:81 msgid "You must correct the above errors before committing." -msgstr "Bisogna correggere gli errori suddetti prima di creare una nuova revisione." +msgstr "" +"Bisogna correggere gli errori suddetti prima di creare una nuova revisione." -#: lib/index.tcl:241 +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "Impossibile sbloccare l'accesso all'indice" + +#: lib/index.tcl:15 +msgid "Index Error" +msgstr "Errore nell'indice" + +#: lib/index.tcl:21 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "" +"Impossibile aggiornare l'indice. Ora sarà avviata una nuova analisi che " +"aggiornerà git-gui." + +#: lib/index.tcl:27 +msgid "Continue" +msgstr "Continua" + +#: lib/index.tcl:31 +msgid "Unlock Index" +msgstr "Sblocca l'accesso all'indice" + +#: lib/index.tcl:282 #, tcl-format msgid "Unstaging %s from commit" msgstr "%s non farà parte della prossima revisione" -#: lib/index.tcl:285 +#: lib/index.tcl:326 #, tcl-format msgid "Adding %s" msgstr "Aggiunta di %s in corso" -#: lib/index.tcl:340 +#: lib/index.tcl:381 #, tcl-format msgid "Revert changes in file %s?" msgstr "Annullare le modifiche nel file %s?" -#: lib/index.tcl:342 +#: lib/index.tcl:383 #, tcl-format msgid "Revert changes in these %i files?" msgstr "Annullare le modifiche in questi %i file?" -#: lib/index.tcl:348 +#: lib/index.tcl:389 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" "Tutte le modifiche non preparate per una nuova revisione saranno perse per " "sempre." -#: lib/index.tcl:351 +#: lib/index.tcl:392 msgid "Do Nothing" msgstr "Non fare niente" @@ -1519,8 +1561,8 @@ msgstr "" "Il file %s ha dei conflitti.\n" "\n" "Bisogna risolvere i conflitti, preparare il file per una nuova revisione ed " -"infine crearla per completare la fusione corrente. Solo a questo punto " -"potrai iniziare un'altra fusione.\n" +"infine crearla per completare la fusione attuale. Solo a questo punto potrai " +"iniziare un'altra fusione.\n" #: lib/merge.tcl:54 #, tcl-format @@ -1536,9 +1578,9 @@ msgstr "" "\n" "Il file %s è stato modificato.\n" "\n" -"Bisogna completare la creazione della revisione corrente prima di iniziare una fusione. " -"In questo modo sarà più facile interrompere una fusione non riuscita, nel " -"caso ce ne fosse bisogno.\n" +"Bisogna completare la creazione della revisione attuale prima di iniziare " +"una fusione. In questo modo sarà più facile interrompere una fusione non " +"riuscita, nel caso ce ne fosse bisogno.\n" #: lib/merge.tcl:106 #, tcl-format @@ -1556,7 +1598,7 @@ msgstr "Fusione completata con successo." #: lib/merge.tcl:133 msgid "Merge failed. Conflict resolution is required." -msgstr "Fusione fallita. Bisogna risolvere i conflitti." +msgstr "Fusione non riuscita. Bisogna risolvere i conflitti." #: lib/merge.tcl:158 #, tcl-format @@ -1587,10 +1629,10 @@ msgid "" msgstr "" "Interrompere fusione?\n" "\n" -"L'interruzione della fusione corrente causerà la perdita di *TUTTE* le " +"L'interruzione della fusione attuale causerà la perdita di *TUTTE* le " "modifiche non ancora presenti nell'archivio.\n" "\n" -"Continuare con l'interruzione della fusione corrente?" +"Continuare con l'interruzione della fusione attuale?" #: lib/merge.tcl:228 msgid "" @@ -1605,7 +1647,7 @@ msgstr "" "L'annullamento delle modifiche causerà la perdita di *TUTTE* le modifiche " "non ancora presenti nell'archivio.\n" "\n" -"Continuare con l'annullamento delle modifiche correnti?" +"Continuare con l'annullamento delle modifiche attuali?" #: lib/merge.tcl:239 msgid "Aborting" @@ -1613,7 +1655,7 @@ msgstr "Interruzione in corso" #: lib/merge.tcl:266 msgid "Abort failed." -msgstr "Interruzione fallita." +msgstr "Interruzione non riuscita." #: lib/merge.tcl:268 msgid "Abort completed. Ready." @@ -1621,7 +1663,7 @@ msgstr "Interruzione completata. Pronto." #: lib/option.tcl:82 msgid "Restore Defaults" -msgstr "Ripristina predefiniti" +msgstr "Ripristina valori predefiniti" #: lib/option.tcl:86 msgid "Save" @@ -1763,8 +1805,8 @@ msgid "" "One or more of the merge tests failed because you have not fetched the " "necessary commits. Try fetching from %s first." msgstr "" -"Una o più verifiche di fusione sono fallite perché mancano le revisioni " -"necessarie. Prova prima a recuperarle da %s." +"Impossibile verificare una o più fusioni: mancano le revisioni necessarie. " +"Prova prima a recuperarle da %s." #: lib/remote_branch_delete.tcl:207 msgid "Please select one or more branches to delete." @@ -1794,18 +1836,18 @@ msgstr "Nessun archivio selezionato." msgid "Scanning %s..." msgstr "Analisi in corso %s..." -#: lib/shortcut.tcl:26 lib/shortcut.tcl:74 -msgid "Cannot write script:" -msgstr "Impossibile scrivere script:" +#: lib/shortcut.tcl:20 lib/shortcut.tcl:61 +msgid "Cannot write shortcut:" +msgstr "Impossibile scrivere shortcut:" -#: lib/shortcut.tcl:149 +#: lib/shortcut.tcl:136 msgid "Cannot write icon:" msgstr "Impossibile scrivere icona:" #: lib/status_bar.tcl:83 #, tcl-format msgid "%s ... %*i of %*i %s (%3i%%)" -msgstr "%s ... %*i di %*i %s (%3i%%)" +msgstr "%1$s ... %6$s: %2$*i di %4$*i (%7$3i%%)" #: lib/transport.tcl:6 #, tcl-format @@ -1869,4 +1911,3 @@ msgstr "Utilizza 'thin pack' (per connessioni lente)" #: lib/transport.tcl:168 msgid "Include tags" msgstr "Includi etichette" - diff --git a/git-gui/po/ja.po b/git-gui/po/ja.po index f3a547b1b9..e2cf5bdc06 100644 --- a/git-gui/po/ja.po +++ b/git-gui/po/ja.po @@ -8,41 +8,41 @@ msgid "" msgstr "" "Project-Id-Version: git-gui\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2007-10-10 04:04-0400\n" -"PO-Revision-Date: 2007-10-31 16:23+0900\n" +"POT-Creation-Date: 2007-11-24 10:36+0100\n" +"PO-Revision-Date: 2007-12-05 06:12+0900\n" "Last-Translator: しらいし ななこ <nanako3@bluebottle.com>\n" "Language-Team: Japanese\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: git-gui.sh:41 git-gui.sh:634 git-gui.sh:648 git-gui.sh:661 git-gui.sh:744 -#: git-gui.sh:763 +#: git-gui.sh:41 git-gui.sh:604 git-gui.sh:618 git-gui.sh:631 git-gui.sh:714 +#: git-gui.sh:733 msgid "git-gui: fatal error" msgstr "git-gui: 致命的なエラー" -#: git-gui.sh:595 +#: git-gui.sh:565 #, tcl-format msgid "Invalid font specified in %s:" msgstr "%s に無効なフォントが指定されています:" -#: git-gui.sh:620 +#: git-gui.sh:590 msgid "Main Font" msgstr "主フォント" -#: git-gui.sh:621 +#: git-gui.sh:591 msgid "Diff/Console Font" msgstr "diff/コンソール・フォント" -#: git-gui.sh:635 +#: git-gui.sh:605 msgid "Cannot find git in PATH." msgstr "PATH 中に git が見つかりません" -#: git-gui.sh:662 +#: git-gui.sh:632 msgid "Cannot parse Git version string:" msgstr "Git バージョン名が理解できません:" -#: git-gui.sh:680 +#: git-gui.sh:650 #, tcl-format msgid "" "Git version cannot be determined.\n" @@ -61,79 +61,79 @@ msgstr "" "\n" "'%s' はバージョン 1.5.0 と思って良いですか?\n" -#: git-gui.sh:853 +#: git-gui.sh:888 msgid "Git directory not found:" msgstr "Git ディレクトリが見つかりません:" -#: git-gui.sh:860 +#: git-gui.sh:895 msgid "Cannot move to top of working directory:" msgstr "作業ディレクトリの最上位に移動できません" -#: git-gui.sh:867 +#: git-gui.sh:902 msgid "Cannot use funny .git directory:" msgstr "変な .git ディレクトリは使えません" -#: git-gui.sh:872 +#: git-gui.sh:907 msgid "No working directory" msgstr "作業ディレクトリがありません" -#: git-gui.sh:1019 +#: git-gui.sh:1054 msgid "Refreshing file status..." msgstr "ファイル状態を更新しています…" -#: git-gui.sh:1084 +#: git-gui.sh:1119 msgid "Scanning for modified files ..." msgstr "変更されたファイルをスキャンしています…" -#: git-gui.sh:1259 lib/browser.tcl:245 +#: git-gui.sh:1294 lib/browser.tcl:245 msgid "Ready." msgstr "準備完了" -#: git-gui.sh:1525 +#: git-gui.sh:1560 msgid "Unmodified" msgstr "変更無し" -#: git-gui.sh:1527 +#: git-gui.sh:1562 msgid "Modified, not staged" msgstr "変更あり、コミット未予定" -#: git-gui.sh:1528 git-gui.sh:1533 +#: git-gui.sh:1563 git-gui.sh:1568 msgid "Staged for commit" msgstr "コミット予定済" -#: git-gui.sh:1529 git-gui.sh:1534 +#: git-gui.sh:1564 git-gui.sh:1569 msgid "Portions staged for commit" msgstr "部分的にコミット予定済" -#: git-gui.sh:1530 git-gui.sh:1535 +#: git-gui.sh:1565 git-gui.sh:1570 msgid "Staged for commit, missing" msgstr "コミット予定済、ファイル無し" -#: git-gui.sh:1532 +#: git-gui.sh:1567 msgid "Untracked, not staged" msgstr "管理外、コミット未予定" -#: git-gui.sh:1537 +#: git-gui.sh:1572 msgid "Missing" msgstr "ファイル無し" -#: git-gui.sh:1538 +#: git-gui.sh:1573 msgid "Staged for removal" msgstr "削除予定済" -#: git-gui.sh:1539 +#: git-gui.sh:1574 msgid "Staged for removal, still present" msgstr "削除予定済、ファイル未削除" -#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544 +#: git-gui.sh:1576 git-gui.sh:1577 git-gui.sh:1578 git-gui.sh:1579 msgid "Requires merge resolution" msgstr "要マージ解決" -#: git-gui.sh:1579 +#: git-gui.sh:1614 msgid "Starting gitk... please wait..." msgstr "gitk を起動中…お待ち下さい…" -#: git-gui.sh:1588 +#: git-gui.sh:1623 #, tcl-format msgid "" "Unable to start gitk:\n" @@ -144,295 +144,297 @@ msgstr "" "\n" "%s がありません" -#: git-gui.sh:1788 lib/choose_repository.tcl:32 +#: git-gui.sh:1823 lib/choose_repository.tcl:35 msgid "Repository" msgstr "リポジトリ" -#: git-gui.sh:1789 +#: git-gui.sh:1824 msgid "Edit" msgstr "編集" -#: git-gui.sh:1791 lib/choose_rev.tcl:560 +#: git-gui.sh:1826 lib/choose_rev.tcl:560 msgid "Branch" msgstr "ブランチ" -#: git-gui.sh:1794 lib/choose_rev.tcl:547 +#: git-gui.sh:1829 lib/choose_rev.tcl:547 msgid "Commit@@noun" msgstr "コミット" -#: git-gui.sh:1797 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 +#: git-gui.sh:1832 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168 msgid "Merge" msgstr "マージ" -#: git-gui.sh:1798 lib/choose_rev.tcl:556 +#: git-gui.sh:1833 lib/choose_rev.tcl:556 msgid "Remote" msgstr "リモート" -#: git-gui.sh:1807 +#: git-gui.sh:1842 msgid "Browse Current Branch's Files" msgstr "現在のブランチのファイルを見る" -#: git-gui.sh:1811 +#: git-gui.sh:1846 msgid "Browse Branch Files..." msgstr "ブランチのファイルを見る…" -#: git-gui.sh:1816 +#: git-gui.sh:1851 msgid "Visualize Current Branch's History" msgstr "現在のブランチの履歴を見る" -#: git-gui.sh:1820 +#: git-gui.sh:1855 msgid "Visualize All Branch History" msgstr "全てのブランチの履歴を見る" -#: git-gui.sh:1827 +#: git-gui.sh:1862 #, tcl-format msgid "Browse %s's Files" msgstr "ブランチ %s のファイルを見る" -#: git-gui.sh:1829 +#: git-gui.sh:1864 #, tcl-format msgid "Visualize %s's History" msgstr "ブランチ %s の履歴を見る" -#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67 +#: git-gui.sh:1869 lib/database.tcl:27 lib/database.tcl:67 msgid "Database Statistics" msgstr "データベース統計" -#: git-gui.sh:1837 lib/database.tcl:34 +#: git-gui.sh:1872 lib/database.tcl:34 msgid "Compress Database" msgstr "データベース圧縮" -#: git-gui.sh:1840 +#: git-gui.sh:1875 msgid "Verify Database" msgstr "データベース検証" -#: git-gui.sh:1847 git-gui.sh:1851 git-gui.sh:1855 lib/shortcut.tcl:9 -#: lib/shortcut.tcl:45 lib/shortcut.tcl:84 +#: git-gui.sh:1882 git-gui.sh:1886 git-gui.sh:1890 lib/shortcut.tcl:7 +#: lib/shortcut.tcl:39 lib/shortcut.tcl:71 msgid "Create Desktop Icon" msgstr "デスクトップ・アイコンを作る" -#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95 +#: git-gui.sh:1895 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184 msgid "Quit" msgstr "終了" -#: git-gui.sh:1867 +#: git-gui.sh:1902 msgid "Undo" msgstr "元に戻す" -#: git-gui.sh:1870 +#: git-gui.sh:1905 msgid "Redo" msgstr "やり直し" -#: git-gui.sh:1874 git-gui.sh:2366 +#: git-gui.sh:1909 git-gui.sh:2403 msgid "Cut" msgstr "切り取り" -#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512 +#: git-gui.sh:1912 git-gui.sh:2406 git-gui.sh:2477 git-gui.sh:2549 #: lib/console.tcl:67 msgid "Copy" msgstr "コピー" -#: git-gui.sh:1880 git-gui.sh:2372 +#: git-gui.sh:1915 git-gui.sh:2409 msgid "Paste" msgstr "貼り付け" -#: git-gui.sh:1883 git-gui.sh:2375 lib/branch_delete.tcl:26 +#: git-gui.sh:1918 git-gui.sh:2412 lib/branch_delete.tcl:26 #: lib/remote_branch_delete.tcl:38 msgid "Delete" msgstr "削除" -#: git-gui.sh:1887 git-gui.sh:2379 git-gui.sh:2516 lib/console.tcl:69 +#: git-gui.sh:1922 git-gui.sh:2416 git-gui.sh:2553 lib/console.tcl:69 msgid "Select All" msgstr "全て選択" -#: git-gui.sh:1896 +#: git-gui.sh:1931 msgid "Create..." msgstr "作成…" -#: git-gui.sh:1902 +#: git-gui.sh:1937 msgid "Checkout..." msgstr "チェックアウト" -#: git-gui.sh:1908 +#: git-gui.sh:1943 msgid "Rename..." msgstr "名前変更…" -#: git-gui.sh:1913 git-gui.sh:2012 +#: git-gui.sh:1948 git-gui.sh:2048 msgid "Delete..." msgstr "削除…" -#: git-gui.sh:1918 +#: git-gui.sh:1953 msgid "Reset..." msgstr "リセット…" -#: git-gui.sh:1930 git-gui.sh:2313 +#: git-gui.sh:1965 git-gui.sh:2350 msgid "New Commit" msgstr "新規コミット" -#: git-gui.sh:1938 git-gui.sh:2320 +#: git-gui.sh:1973 git-gui.sh:2357 msgid "Amend Last Commit" msgstr "最新コミットを訂正" -#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99 +#: git-gui.sh:1982 git-gui.sh:2317 lib/remote_branch_delete.tcl:99 msgid "Rescan" msgstr "再スキャン" -#: git-gui.sh:1953 +#: git-gui.sh:1988 msgid "Stage To Commit" msgstr "コミット予定する" -#: git-gui.sh:1958 +#: git-gui.sh:1994 msgid "Stage Changed Files To Commit" msgstr "変更されたファイルをコミット予定" -#: git-gui.sh:1964 +#: git-gui.sh:2000 msgid "Unstage From Commit" msgstr "コミットから降ろす" -#: git-gui.sh:1969 lib/index.tcl:352 +#: git-gui.sh:2005 lib/index.tcl:393 msgid "Revert Changes" msgstr "変更を元に戻す" -#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390 +#: git-gui.sh:2012 git-gui.sh:2329 git-gui.sh:2427 msgid "Sign Off" msgstr "署名" -#: git-gui.sh:1980 git-gui.sh:2296 +#: git-gui.sh:2016 git-gui.sh:2333 msgid "Commit@@verb" msgstr "コミット" -#: git-gui.sh:1991 +#: git-gui.sh:2027 msgid "Local Merge..." msgstr "ローカル・マージ…" -#: git-gui.sh:1996 +#: git-gui.sh:2032 msgid "Abort Merge..." msgstr "マージ中止…" -#: git-gui.sh:2008 +#: git-gui.sh:2044 msgid "Push..." msgstr "プッシュ…" -#: git-gui.sh:2019 lib/choose_repository.tcl:41 +#: git-gui.sh:2055 lib/choose_repository.tcl:40 msgid "Apple" msgstr "りんご" -#: git-gui.sh:2022 git-gui.sh:2044 lib/about.tcl:13 -#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:50 +#: git-gui.sh:2058 git-gui.sh:2080 lib/about.tcl:13 +#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49 #, tcl-format msgid "About %s" msgstr "%s について" -#: git-gui.sh:2026 +#: git-gui.sh:2062 msgid "Preferences..." msgstr "設定…" -#: git-gui.sh:2034 git-gui.sh:2558 +#: git-gui.sh:2070 git-gui.sh:2595 msgid "Options..." msgstr "オプション…" -#: git-gui.sh:2040 lib/choose_repository.tcl:47 +#: git-gui.sh:2076 lib/choose_repository.tcl:46 msgid "Help" msgstr "ヘルプ" -#: git-gui.sh:2081 +#: git-gui.sh:2117 msgid "Online Documentation" msgstr "オンライン・ドキュメント" -#: git-gui.sh:2165 +#: git-gui.sh:2201 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" -msgstr "致命的: パス %s が stat できません。そのようなファイルやディレクトリはありません" +msgstr "" +"致命的: パス %s が stat できません。そのようなファイルやディレクトリはありま" +"せん" -#: git-gui.sh:2198 +#: git-gui.sh:2234 msgid "Current Branch:" msgstr "現在のブランチ" -#: git-gui.sh:2219 +#: git-gui.sh:2255 msgid "Staged Changes (Will Commit)" msgstr "ステージングされた(コミット予定済の)変更" -#: git-gui.sh:2239 +#: git-gui.sh:2274 msgid "Unstaged Changes" msgstr "コミット予定に入っていない変更" -#: git-gui.sh:2286 +#: git-gui.sh:2323 msgid "Stage Changed" msgstr "変更をコミット予定に入れる" -#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182 +#: git-gui.sh:2339 lib/transport.tcl:93 lib/transport.tcl:182 msgid "Push" msgstr "プッシュ" -#: git-gui.sh:2332 +#: git-gui.sh:2369 msgid "Initial Commit Message:" msgstr "最初のコミットメッセージ:" -#: git-gui.sh:2333 +#: git-gui.sh:2370 msgid "Amended Commit Message:" msgstr "訂正したコミットメッセージ:" -#: git-gui.sh:2334 +#: git-gui.sh:2371 msgid "Amended Initial Commit Message:" msgstr "訂正した最初のコミットメッセージ:" -#: git-gui.sh:2335 +#: git-gui.sh:2372 msgid "Amended Merge Commit Message:" msgstr "訂正したマージコミットメッセージ:" -#: git-gui.sh:2336 +#: git-gui.sh:2373 msgid "Merge Commit Message:" msgstr "マージコミットメッセージ:" -#: git-gui.sh:2337 +#: git-gui.sh:2374 msgid "Commit Message:" msgstr "コミットメッセージ:" -#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71 +#: git-gui.sh:2419 git-gui.sh:2557 lib/console.tcl:71 msgid "Copy All" msgstr "全てコピー" -#: git-gui.sh:2406 lib/blame.tcl:104 +#: git-gui.sh:2443 lib/blame.tcl:104 msgid "File:" msgstr "ファイル:" -#: git-gui.sh:2508 +#: git-gui.sh:2545 msgid "Refresh" msgstr "再読み込み" -#: git-gui.sh:2529 +#: git-gui.sh:2566 msgid "Apply/Reverse Hunk" msgstr "パッチを適用/取り消す" -#: git-gui.sh:2535 +#: git-gui.sh:2572 msgid "Decrease Font Size" msgstr "フォントを小さく" -#: git-gui.sh:2539 +#: git-gui.sh:2576 msgid "Increase Font Size" msgstr "フォントを大きく" -#: git-gui.sh:2544 +#: git-gui.sh:2581 msgid "Show Less Context" msgstr "文脈を少なく" -#: git-gui.sh:2551 +#: git-gui.sh:2588 msgid "Show More Context" msgstr "文脈を多く" -#: git-gui.sh:2565 +#: git-gui.sh:2602 msgid "Unstage Hunk From Commit" msgstr "パッチをコミット予定から外す" -#: git-gui.sh:2567 +#: git-gui.sh:2604 msgid "Stage Hunk For Commit" msgstr "パッチをコミット予定に加える" -#: git-gui.sh:2586 +#: git-gui.sh:2623 msgid "Initializing..." msgstr "初期化しています…" -#: git-gui.sh:2677 +#: git-gui.sh:2718 #, tcl-format msgid "" "Possible environment issues exist.\n" @@ -447,7 +449,7 @@ msgstr "" "以下の環境変数は %s が起動する Git サブプロセスによって無視されるでしょう:\n" "\n" -#: git-gui.sh:2707 +#: git-gui.sh:2748 msgid "" "\n" "This is due to a known issue with the\n" @@ -457,7 +459,7 @@ msgstr "" "これは Cygwin で配布されている Tcl バイナリに\n" "関しての既知の問題によります" -#: git-gui.sh:2712 +#: git-gui.sh:2753 #, tcl-format msgid "" "\n" @@ -576,7 +578,7 @@ msgstr "ブランチを作成" msgid "Create New Branch" msgstr "ブランチを新規作成" -#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199 +#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375 msgid "Create" msgstr "作成" @@ -729,9 +731,9 @@ msgstr "[上位フォルダへ]" msgid "Browse Branch Files" msgstr "現在のブランチのファイルを見る" -#: lib/browser.tcl:277 lib/choose_repository.tcl:215 -#: lib/choose_repository.tcl:305 lib/choose_repository.tcl:315 -#: lib/choose_repository.tcl:811 +#: lib/browser.tcl:277 lib/choose_repository.tcl:391 +#: lib/choose_repository.tcl:482 lib/choose_repository.tcl:492 +#: lib/choose_repository.tcl:989 msgid "Browse" msgstr "ブラウズ" @@ -891,209 +893,225 @@ msgstr "" "これはサンプル文です。\n" "このフォントが気に入ればお使いになれます。" -#: lib/choose_repository.tcl:25 +#: lib/choose_repository.tcl:27 msgid "Git Gui" msgstr "Git GUI" -#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204 +#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380 msgid "Create New Repository" msgstr "新しいリポジトリを作る" -#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291 +#: lib/choose_repository.tcl:86 +msgid "New..." +msgstr "新規…" + +#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468 msgid "Clone Existing Repository" msgstr "既存リポジトリを複製する" -#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800 +#: lib/choose_repository.tcl:99 +msgid "Clone..." +msgstr "複製…" + +#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978 msgid "Open Existing Repository" msgstr "既存リポジトリを開く" -#: lib/choose_repository.tcl:91 -msgid "Next >" -msgstr "次 >" +#: lib/choose_repository.tcl:112 +msgid "Open..." +msgstr "開く…" + +#: lib/choose_repository.tcl:125 +msgid "Recent Repositories" +msgstr "最近使ったリポジトリ" + +#: lib/choose_repository.tcl:131 +msgid "Open Recent Repository:" +msgstr "最近使ったリポジトリを開く" -#: lib/choose_repository.tcl:152 +#: lib/choose_repository.tcl:294 #, tcl-format msgid "Location %s already exists." msgstr "'%s' は既に存在します。" -#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165 -#: lib/choose_repository.tcl:172 +#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307 +#: lib/choose_repository.tcl:314 #, tcl-format msgid "Failed to create repository %s:" msgstr "リポジトリ %s を作製できません:" -#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309 +#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486 msgid "Directory:" msgstr "ディレクトリ:" -#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363 -#: lib/choose_repository.tcl:834 +#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544 +#: lib/choose_repository.tcl:1013 msgid "Git Repository" msgstr "GIT リポジトリ" -#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260 +#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437 #, tcl-format msgid "Directory %s already exists." msgstr "ディレクトリ '%s' は既に存在します。" -#: lib/choose_repository.tcl:265 +#: lib/choose_repository.tcl:442 #, tcl-format msgid "File %s already exists." msgstr "ファイル '%s' は既に存在します。" -#: lib/choose_repository.tcl:286 +#: lib/choose_repository.tcl:463 msgid "Clone" msgstr "複製" -#: lib/choose_repository.tcl:299 +#: lib/choose_repository.tcl:476 msgid "URL:" msgstr "URL:" -#: lib/choose_repository.tcl:319 +#: lib/choose_repository.tcl:496 msgid "Clone Type:" msgstr "複製方式:" -#: lib/choose_repository.tcl:325 +#: lib/choose_repository.tcl:502 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" msgstr "標準(高速・中冗長度・ハードリンク)" -#: lib/choose_repository.tcl:331 +#: lib/choose_repository.tcl:508 msgid "Full Copy (Slower, Redundant Backup)" msgstr "全複写(低速・冗長バックアップ)" -#: lib/choose_repository.tcl:337 +#: lib/choose_repository.tcl:514 msgid "Shared (Fastest, Not Recommended, No Backup)" msgstr "共有(最高速・非推奨・バックアップ無し)" -#: lib/choose_repository.tcl:369 lib/choose_repository.tcl:418 -#: lib/choose_repository.tcl:560 lib/choose_repository.tcl:630 -#: lib/choose_repository.tcl:840 lib/choose_repository.tcl:848 +#: lib/choose_repository.tcl:550 lib/choose_repository.tcl:597 +#: lib/choose_repository.tcl:738 lib/choose_repository.tcl:808 +#: lib/choose_repository.tcl:1019 lib/choose_repository.tcl:1027 #, tcl-format msgid "Not a Git repository: %s" msgstr "Git リポジトリではありません: %s" -#: lib/choose_repository.tcl:405 +#: lib/choose_repository.tcl:586 msgid "Standard only available for local repository." msgstr "標準方式は同一計算機上のリポジトリにのみ使えます。" -#: lib/choose_repository.tcl:409 +#: lib/choose_repository.tcl:590 msgid "Shared only available for local repository." msgstr "共有方式は同一計算機上のリポジトリにのみ使えます。" -#: lib/choose_repository.tcl:439 +#: lib/choose_repository.tcl:617 msgid "Failed to configure origin" msgstr "origin を設定できませんでした" -#: lib/choose_repository.tcl:451 +#: lib/choose_repository.tcl:629 msgid "Counting objects" msgstr "オブジェクトを数えています" -#: lib/choose_repository.tcl:452 +#: lib/choose_repository.tcl:630 msgid "buckets" msgstr "バケツ" -#: lib/choose_repository.tcl:476 +#: lib/choose_repository.tcl:654 #, tcl-format msgid "Unable to copy objects/info/alternates: %s" msgstr "objects/info/alternates を複写できません: %s" -#: lib/choose_repository.tcl:512 +#: lib/choose_repository.tcl:690 #, tcl-format msgid "Nothing to clone from %s." msgstr "%s から複製する内容はありません" -#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728 -#: lib/choose_repository.tcl:740 +#: lib/choose_repository.tcl:692 lib/choose_repository.tcl:906 +#: lib/choose_repository.tcl:918 msgid "The 'master' branch has not been initialized." msgstr "'master' ブランチが初期化されていません" -#: lib/choose_repository.tcl:527 +#: lib/choose_repository.tcl:705 msgid "Hardlinks are unavailable. Falling back to copying." msgstr "ハードリンクが作れないので、コピーします" -#: lib/choose_repository.tcl:539 +#: lib/choose_repository.tcl:717 #, tcl-format msgid "Cloning from %s" msgstr "%s から複製しています" -#: lib/choose_repository.tcl:570 +#: lib/choose_repository.tcl:748 msgid "Copying objects" msgstr "オブジェクトを複写しています" -#: lib/choose_repository.tcl:571 +#: lib/choose_repository.tcl:749 msgid "KiB" msgstr "KiB" -#: lib/choose_repository.tcl:595 +#: lib/choose_repository.tcl:773 #, tcl-format msgid "Unable to copy object: %s" msgstr "オブジェクトを複写できません: %s" -#: lib/choose_repository.tcl:605 +#: lib/choose_repository.tcl:783 msgid "Linking objects" msgstr "オブジェクトを連結しています" -#: lib/choose_repository.tcl:606 +#: lib/choose_repository.tcl:784 msgid "objects" msgstr "オブジェクト" -#: lib/choose_repository.tcl:614 +#: lib/choose_repository.tcl:792 #, tcl-format msgid "Unable to hardlink object: %s" msgstr "オブジェクトをハードリンクできません: %s" -#: lib/choose_repository.tcl:669 +#: lib/choose_repository.tcl:847 msgid "Cannot fetch branches and objects. See console output for details." msgstr "ブランチやオブジェクトを取得できません。コンソール出力を見て下さい" -#: lib/choose_repository.tcl:680 +#: lib/choose_repository.tcl:858 msgid "Cannot fetch tags. See console output for details." msgstr "タグを取得できません。コンソール出力を見て下さい" -#: lib/choose_repository.tcl:704 +#: lib/choose_repository.tcl:882 msgid "Cannot determine HEAD. See console output for details." msgstr "HEAD を確定できません。コンソール出力を見て下さい" -#: lib/choose_repository.tcl:713 +#: lib/choose_repository.tcl:891 #, tcl-format msgid "Unable to cleanup %s" msgstr "%s を掃除できません" -#: lib/choose_repository.tcl:719 +#: lib/choose_repository.tcl:897 msgid "Clone failed." msgstr "複写に失敗しました。" -#: lib/choose_repository.tcl:726 +#: lib/choose_repository.tcl:904 msgid "No default branch obtained." msgstr "デフォールト・ブランチが取得されませんでした" -#: lib/choose_repository.tcl:737 +#: lib/choose_repository.tcl:915 #, tcl-format msgid "Cannot resolve %s as a commit." msgstr "%s をコミットとして解釈できません" -#: lib/choose_repository.tcl:749 +#: lib/choose_repository.tcl:927 msgid "Creating working directory" msgstr "作業ディレクトリを作成しています" -#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80 -#: lib/index.tcl:149 +#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127 +#: lib/index.tcl:193 msgid "files" msgstr "ファイル" -#: lib/choose_repository.tcl:779 +#: lib/choose_repository.tcl:957 msgid "Initial file checkout failed." msgstr "初期チェックアウトに失敗しました" -#: lib/choose_repository.tcl:795 +#: lib/choose_repository.tcl:973 msgid "Open" msgstr "開く" -#: lib/choose_repository.tcl:805 +#: lib/choose_repository.tcl:983 msgid "Repository:" msgstr "リポジトリ:" -#: lib/choose_repository.tcl:854 +#: lib/choose_repository.tcl:1033 #, tcl-format msgid "Failed to open repository %s:" msgstr "リポジトリ %s を開けません:" @@ -1232,7 +1250,7 @@ msgid "" "\n" "A good commit message has the following format:\n" "\n" -"- First line: Describe in one sentance what you did.\n" +"- First line: Describe in one sentence what you did.\n" "- Second line: Blank\n" "- Remaining lines: Describe why this change is good.\n" msgstr "" @@ -1349,7 +1367,8 @@ msgid "" msgstr "" "このリポジトリにはおおよそ %i 個の個別オブジェクトがあります\n" "\n" -"最適な性能を保つために、%i 個以上の個別オブジェクトを作る毎にデータベースを圧縮することを推奨します\n" +"最適な性能を保つために、%i 個以上の個別オブジェクトを作る毎にデータベースを圧" +"縮することを推奨します\n" "\n" "データベースを圧縮しますか?" @@ -1426,31 +1445,53 @@ msgstr "警告" msgid "You must correct the above errors before committing." msgstr "コミットする前に、以上のエラーを修正して下さい" -#: lib/index.tcl:241 +#: lib/index.tcl:6 +msgid "Unable to unlock the index." +msgstr "インデックスをロックできません" + +#: lib/index.tcl:15 +msgid "Index Error" +msgstr "索引エラー" + +#: lib/index.tcl:21 +msgid "" +"Updating the Git index failed. A rescan will be automatically started to " +"resynchronize git-gui." +msgstr "GIT インデックスの更新が失敗しました。git-gui と同期をとるために再スキャンします。" + +#: lib/index.tcl:27 +msgid "Continue" +msgstr "続行" + +#: lib/index.tcl:31 +msgid "Unlock Index" +msgstr "インデックスのロック解除" + +#: lib/index.tcl:282 #, tcl-format msgid "Unstaging %s from commit" msgstr "コミットから '%s' を降ろす" -#: lib/index.tcl:285 +#: lib/index.tcl:326 #, tcl-format msgid "Adding %s" msgstr "コミットに %s を加えています" -#: lib/index.tcl:340 +#: lib/index.tcl:381 #, tcl-format msgid "Revert changes in file %s?" msgstr "ファイル %s にした変更を元に戻しますか?" -#: lib/index.tcl:342 +#: lib/index.tcl:383 #, tcl-format msgid "Revert changes in these %i files?" msgstr "これら %i 個のファイルにした変更を元に戻しますか?" -#: lib/index.tcl:348 +#: lib/index.tcl:389 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "変更を元に戻すとコミット予定していない変更は全て失われます。" -#: lib/index.tcl:351 +#: lib/index.tcl:392 msgid "Do Nothing" msgstr "何もしない" @@ -1669,18 +1710,6 @@ msgstr "設定" msgid "Failed to completely save options:" msgstr "完全にオプションを保存できません:" -#: lib/remote.tcl:165 -msgid "Prune from" -msgstr "から刈込む…" - -#: lib/remote.tcl:170 -msgid "Fetch from" -msgstr "取得元" - -#: lib/remote.tcl:213 -msgid "Push to" -msgstr "プッシュ先" - #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34 msgid "Delete Remote Branch" msgstr "リモート・ブランチを削除" @@ -1765,11 +1794,23 @@ msgstr "リポジトリが選択されていません。" msgid "Scanning %s..." msgstr "%s をスキャンしています…" -#: lib/shortcut.tcl:26 lib/shortcut.tcl:74 -msgid "Cannot write script:" -msgstr "スクリプトが書けません:" +#: lib/remote.tcl:165 +msgid "Prune from" +msgstr "から刈込む…" + +#: lib/remote.tcl:170 +msgid "Fetch from" +msgstr "取得元" -#: lib/shortcut.tcl:149 +#: lib/remote.tcl:213 +msgid "Push to" +msgstr "プッシュ先" + +#: lib/shortcut.tcl:20 lib/shortcut.tcl:61 +msgid "Cannot write shortcut:" +msgstr "ショートカットが書けません:" + +#: lib/shortcut.tcl:136 msgid "Cannot write icon:" msgstr "アイコンが書けません:" @@ -1840,4 +1881,3 @@ msgstr "Thin Pack を使う(遅いネットワーク接続)" #: lib/transport.tcl:168 msgid "Include tags" msgstr "タグを含める" - diff --git a/git-mergetool.sh b/git-mergetool.sh index 5587c5ecea..2f31fa2417 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -152,10 +152,11 @@ merge_file () { exit 1 fi - BACKUP="$path.BACKUP.$$" - LOCAL="$path.LOCAL.$$" - REMOTE="$path.REMOTE.$$" - BASE="$path.BASE.$$" + ext="$$$(expr "$path" : '.*\(\.[^/]*\)$')" + BACKUP="$path.BACKUP.$ext" + LOCAL="$path.LOCAL.$ext" + REMOTE="$path.REMOTE.$ext" + BASE="$path.BASE.$ext" mv -- "$path" "$BACKUP" cp -- "$BACKUP" "$path" diff --git a/git-send-email.perl b/git-send-email.perl index 76baa8e431..c0e1dd348c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -367,10 +367,11 @@ if ($thread && !defined $initial_reply_to && $prompting) { } while (!defined $_); $initial_reply_to = $_; - $initial_reply_to =~ s/^\s+<?/</; - $initial_reply_to =~ s/>?\s+$/>/; } +$initial_reply_to =~ s/^\s*<?/</; +$initial_reply_to =~ s/>?\s*$/>/; + if (!defined $smtp_server) { foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) { if (-x $_) { diff --git a/git-submodule.sh b/git-submodule.sh index 82ac28fa27..ad9fe628fd 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -158,7 +158,7 @@ module_add() die "'$path' already exists in the index" module_clone "$path" "$realrepo" || exit - (unset GIT_DIR && cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || + (unset GIT_DIR; cd "$path" && git checkout -q ${branch:+-b "$branch" "origin/$branch"}) || die "Unable to checkout submodule '$path'" git add "$path" || die "Failed to add submodule '$path'" @@ -228,14 +228,14 @@ modules_update() module_clone "$path" "$url" || exit subsha1= else - subsha1=$(unset GIT_DIR && cd "$path" && + subsha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD) || die "Unable to find current revision in submodule path '$path'" fi if test "$subsha1" != "$sha1" then - (unset GIT_DIR && cd "$path" && git-fetch && + (unset GIT_DIR; cd "$path" && git-fetch && git-checkout -q "$sha1") || die "Unable to checkout '$sha1' in submodule path '$path'" @@ -246,7 +246,7 @@ modules_update() set_name_rev () { revname=$( ( - unset GIT_DIR && + unset GIT_DIR cd "$1" && { git describe "$2" 2>/dev/null || git describe --tags "$2" 2>/dev/null || @@ -285,7 +285,7 @@ modules_list() else if test -z "$cached" then - sha1=$(unset GIT_DIR && cd "$path" && git rev-parse --verify HEAD) + sha1=$(unset GIT_DIR; cd "$path" && git rev-parse --verify HEAD) set_name_rev "$path" "$sha1" fi say "+$sha1 $path$revname" @@ -169,7 +169,7 @@ static int handle_alias(int *argcp, const char ***argv) strbuf_init(&buf, PATH_MAX); strbuf_addstr(&buf, alias_string); - sq_quote_argv(&buf, (*argv) + 1, *argcp - 1, PATH_MAX); + sq_quote_argv(&buf, (*argv) + 1, PATH_MAX); free(alias_string); alias_string = buf.buf; } @@ -198,7 +198,7 @@ static int handle_alias(int *argcp, const char ***argv) if (!strcmp(alias_command, new_argv[0])) die("recursive alias: %s", alias_command); - trace_argv_printf(new_argv, count, + trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); @@ -252,7 +252,7 @@ static int run_command(struct cmd_struct *p, int argc, const char **argv) if (p->option & NEED_WORK_TREE) setup_work_tree(); - trace_argv_printf(argv, argc, "trace: built-in: git"); + trace_argv_printf(argv, "trace: built-in: git"); status = p->fn(argc, argv, prefix); if (status) @@ -294,6 +294,7 @@ static void handle_internal_command(int argc, const char **argv) { "cherry", cmd_cherry, RUN_SETUP }, { "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE }, { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE }, + { "commit", cmd_commit, RUN_SETUP | NEED_WORK_TREE }, { "commit-tree", cmd_commit_tree, RUN_SETUP }, { "config", cmd_config }, { "count-objects", cmd_count_objects, RUN_SETUP }, @@ -346,11 +347,11 @@ static void handle_internal_command(int argc, const char **argv) { "rev-parse", cmd_rev_parse }, { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE }, { "rm", cmd_rm, RUN_SETUP }, - { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE }, { "send-pack", cmd_send_pack, RUN_SETUP }, { "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER }, { "show-branch", cmd_show_branch, RUN_SETUP }, { "show", cmd_show, RUN_SETUP | USE_PAGER }, + { "status", cmd_status, RUN_SETUP | NEED_WORK_TREE }, { "stripspace", cmd_stripspace }, { "symbolic-ref", cmd_symbolic_ref, RUN_SETUP }, { "tag", cmd_tag, RUN_SETUP }, diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index ff5daa7901..24b31582af 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -695,10 +695,9 @@ sub validate_refname { # in utf-8 thanks to "binmode STDOUT, ':utf8'" at beginning sub to_utf8 { my $str = shift; - my $res; - eval { $res = decode_utf8($str, Encode::FB_CROAK); }; - if (defined $res) { - return $res; + if (utf8::valid($str)) { + utf8::decode($str); + return $str; } else { return decode($fallback_encoding, $str, Encode::FB_DEFAULT); } @@ -255,9 +255,31 @@ static const char *cmd_to_page(const char *git_cmd) } } +static void setup_man_path(void) +{ + struct strbuf new_path; + const char *old_path = getenv("MANPATH"); + + strbuf_init(&new_path, 0); + + /* We should always put ':' after our path. If there is no + * old_path, the ':' at the end will let 'man' to try + * system-wide paths after ours to find the manual page. If + * there is old_path, we need ':' as delimiter. */ + strbuf_addstr(&new_path, GIT_MAN_PATH); + strbuf_addch(&new_path, ':'); + if (old_path) + strbuf_addstr(&new_path, old_path); + + setenv("MANPATH", new_path.buf, 1); + + strbuf_release(&new_path); +} + static void show_man_page(const char *git_cmd) { const char *page = cmd_to_page(git_cmd); + setup_man_path(); execlp("man", "man", page, NULL); } @@ -4,30 +4,31 @@ int data_received; int active_requests = 0; #ifdef USE_CURL_MULTI -int max_requests = -1; -CURLM *curlm; +static int max_requests = -1; +static CURLM *curlm; #endif #ifndef NO_CURL_EASY_DUPHANDLE -CURL *curl_default; +static CURL *curl_default; #endif char curl_errorstr[CURL_ERROR_SIZE]; -int curl_ssl_verify = -1; -char *ssl_cert = NULL; +static int curl_ssl_verify = -1; +static char *ssl_cert = NULL; #if LIBCURL_VERSION_NUM >= 0x070902 -char *ssl_key = NULL; +static char *ssl_key = NULL; #endif #if LIBCURL_VERSION_NUM >= 0x070908 -char *ssl_capath = NULL; +static char *ssl_capath = NULL; #endif -char *ssl_cainfo = NULL; -long curl_low_speed_limit = -1; -long curl_low_speed_time = -1; -int curl_ftp_no_epsv = 0; +static char *ssl_cainfo = NULL; +static long curl_low_speed_limit = -1; +static long curl_low_speed_time = -1; +static int curl_ftp_no_epsv = 0; +static char *curl_http_proxy = NULL; -struct curl_slist *pragma_header; +static struct curl_slist *pragma_header; -struct active_request_slot *active_queue_head = NULL; +static struct active_request_slot *active_queue_head = NULL; size_t fread_buffer(void *ptr, size_t eltsize, size_t nmemb, struct buffer *buffer) @@ -160,6 +161,13 @@ static int http_options(const char *var, const char *value) curl_ftp_no_epsv = git_config_bool(var, value); return 0; } + if (!strcmp("http.proxy", var)) { + if (curl_http_proxy == NULL) { + curl_http_proxy = xmalloc(strlen(value)+1); + strcpy(curl_http_proxy, value); + } + return 0; + } /* Fall back on the default ones */ return git_default_config(var, value); @@ -205,6 +213,9 @@ static CURL* get_curl_handle(void) if (curl_ftp_no_epsv) curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0); + if (curl_http_proxy) + curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy); + return result; } @@ -80,24 +80,6 @@ extern void http_cleanup(void); extern int data_received; extern int active_requests; -#ifndef NO_CURL_EASY_DUPHANDLE -extern CURL *curl_default; -#endif extern char curl_errorstr[CURL_ERROR_SIZE]; -extern int curl_ssl_verify; -extern char *ssl_cert; -#if LIBCURL_VERSION_NUM >= 0x070902 -extern char *ssl_key; -#endif -#if LIBCURL_VERSION_NUM >= 0x070908 -extern char *ssl_capath; -#endif -extern char *ssl_cainfo; -extern long curl_low_speed_limit; -extern long curl_low_speed_time; - -extern struct curl_slist *pragma_header; -extern struct curl_slist *no_range_header; - #endif /* HTTP_H */ @@ -113,25 +113,15 @@ static int add_raw(char *buf, size_t size, int offset, const char *str) static int crud(unsigned char c) { - static char crud_array[256]; - static int crud_array_initialized = 0; - - if (!crud_array_initialized) { - int k; - - for (k = 0; k <= 31; ++k) crud_array[k] = 1; - crud_array[' '] = 1; - crud_array['.'] = 1; - crud_array[','] = 1; - crud_array[':'] = 1; - crud_array[';'] = 1; - crud_array['<'] = 1; - crud_array['>'] = 1; - crud_array['"'] = 1; - crud_array['\''] = 1; - crud_array_initialized = 1; - } - return crud_array[c]; + return c <= 32 || + c == '.' || + c == ',' || + c == ':' || + c == ';' || + c == '<' || + c == '>' || + c == '"' || + c == '\''; } /* @@ -185,7 +175,7 @@ static const char *env_hint = "\n" "Run\n" "\n" -" git config --global user.email \"you@email.com\"\n" +" git config --global user.email \"you@example.com\"\n" " git config --global user.name \"Your Name\"\n" "\n" "to set your account\'s default identity.\n" @@ -193,11 +183,14 @@ static const char *env_hint = "\n"; const char *fmt_ident(const char *name, const char *email, - const char *date_str, int error_on_no_name) + const char *date_str, int flag) { static char buffer[1000]; char date[50]; int i; + int error_on_no_name = (flag & IDENT_ERROR_ON_NO_NAME); + int warn_on_no_name = (flag & IDENT_WARN_ON_NO_NAME); + int name_addr_only = (flag & IDENT_NO_DATE); setup_ident(); if (!name) @@ -208,12 +201,12 @@ const char *fmt_ident(const char *name, const char *email, if (!*name) { struct passwd *pw; - if (0 <= error_on_no_name && + if ((warn_on_no_name || error_on_no_name) && name == git_default_name && env_hint) { fprintf(stderr, env_hint, au_env, co_env); env_hint = NULL; /* warn only once, for "git-var -l" */ } - if (0 < error_on_no_name) + if (error_on_no_name) die("empty ident %s <%s> not allowed", name, email); pw = getpwuid(getuid()); if (!pw) @@ -224,32 +217,41 @@ const char *fmt_ident(const char *name, const char *email, } strcpy(date, git_default_date); - if (date_str) + if (!name_addr_only && date_str) parse_date(date_str, date, sizeof(date)); i = copy(buffer, sizeof(buffer), 0, name); i = add_raw(buffer, sizeof(buffer), i, " <"); i = copy(buffer, sizeof(buffer), i, email); - i = add_raw(buffer, sizeof(buffer), i, "> "); - i = copy(buffer, sizeof(buffer), i, date); + if (!name_addr_only) { + i = add_raw(buffer, sizeof(buffer), i, "> "); + i = copy(buffer, sizeof(buffer), i, date); + } else { + i = add_raw(buffer, sizeof(buffer), i, ">"); + } if (i >= sizeof(buffer)) die("Impossibly long personal identifier"); buffer[i] = 0; return buffer; } -const char *git_author_info(int error_on_no_name) +const char *fmt_name(const char *name, const char *email) +{ + return fmt_ident(name, email, NULL, IDENT_ERROR_ON_NO_NAME | IDENT_NO_DATE); +} + +const char *git_author_info(int flag) { return fmt_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), getenv("GIT_AUTHOR_DATE"), - error_on_no_name); + flag); } -const char *git_committer_info(int error_on_no_name) +const char *git_committer_info(int flag) { return fmt_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), getenv("GIT_COMMITTER_DATE"), - error_on_no_name); + flag); } @@ -42,9 +42,10 @@ int read_mailmap(struct path_list *map, const char *filename, char **repo_abbrev continue; if (right_bracket == left_bracket + 1) continue; - for (end_of_name = left_bracket; end_of_name != buffer - && isspace(end_of_name[-1]); end_of_name--) - /* keep on looking */ + for (end_of_name = left_bracket; + end_of_name != buffer && isspace(end_of_name[-1]); + end_of_name--) + ; /* keep on looking */ if (end_of_name == buffer) continue; name = xmalloc(end_of_name - buffer + 1); diff --git a/perl/Git.pm b/perl/Git.pm index 7468460f9a..a2812ea612 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -581,6 +581,41 @@ sub config_int { }; } +=item get_colorbool ( NAME ) + +Finds if color should be used for NAMEd operation from the configuration, +and returns boolean (true for "use color", false for "do not use color"). + +=cut + +sub get_colorbool { + my ($self, $var) = @_; + my $stdout_to_tty = (-t STDOUT) ? "true" : "false"; + my $use_color = $self->command_oneline('config', '--get-colorbool', + $var, $stdout_to_tty); + return ($use_color eq 'true'); +} + +=item get_color ( SLOT, COLOR ) + +Finds color for SLOT from the configuration, while defaulting to COLOR, +and returns the ANSI color escape sequence: + + print $repo->get_color("color.interactive.prompt", "underline blue white"); + print "some text"; + print $repo->get_color("", "normal"); + +=cut + +sub get_color { + my ($self, $slot, $default) = @_; + my $color = $self->command_oneline('config', '--get-color', $slot, $default); + if (!defined $color) { + $color = ""; + } + return $color; +} + =item ident ( TYPE | IDENTSTR ) =item ident_person ( TYPE | IDENTSTR | IDENTARRAY ) @@ -56,20 +56,13 @@ void sq_quote_print(FILE *stream, const char *src) fputc('\'', stream); } -void sq_quote_argv(struct strbuf *dst, const char** argv, int count, - size_t maxlen) +void sq_quote_argv(struct strbuf *dst, const char** argv, size_t maxlen) { int i; - /* Count argv if needed. */ - if (count < 0) { - for (count = 0; argv[count]; count++) - ; /* just counting */ - } - /* Copy into destination buffer. */ - strbuf_grow(dst, 32 * count); - for (i = 0; i < count; ++i) { + strbuf_grow(dst, 255); + for (i = 0; argv[i]; ++i) { strbuf_addch(dst, ' '); sq_quote_buf(dst, argv[i]); if (maxlen && dst->len > maxlen) @@ -31,8 +31,7 @@ extern void sq_quote_print(FILE *stream, const char *src); extern void sq_quote_buf(struct strbuf *, const char *src); -extern void sq_quote_argv(struct strbuf *, const char **argv, int count, - size_t maxlen); +extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); /* This unwraps what sq_quote() produces in place, but returns * NULL if the input does not look like what sq_quote would have @@ -643,6 +643,37 @@ int check_ref_format(const char *ref) } } +const char *ref_rev_parse_rules[] = { + "%.*s", + "refs/%.*s", + "refs/tags/%.*s", + "refs/heads/%.*s", + "refs/remotes/%.*s", + "refs/remotes/%.*s/HEAD", + NULL +}; + +const char *ref_fetch_rules[] = { + "%.*s", + "refs/%.*s", + "refs/heads/%.*s", + NULL +}; + +int refname_match(const char *abbrev_name, const char *full_name, const char **rules) +{ + const char **p; + const int abbrev_name_len = strlen(abbrev_name); + + for (p = rules; *p; p++) { + if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) { + return 1; + } + } + + return 0; +} + static struct ref_lock *verify_lock(struct ref_lock *lock, const unsigned char *old_sha1, int mustexist) { @@ -1063,7 +1094,7 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1, adjust_shared_perm(log_file); msglen = msg ? strlen(msg) : 0; - committer = git_committer_info(-1); + committer = git_committer_info(0); maxlen = strlen(committer) + msglen + 100; logrec = xmalloc(maxlen); len = sprintf(logrec, "%s %s %s\n", @@ -278,6 +278,8 @@ static int handle_config(const char *key, const char *value) } else if (!strcmp(subkey, ".tagopt")) { if (!strcmp(value, "--no-tags")) remote->fetch_tags = -1; + } else if (!strcmp(subkey, ".proxy")) { + remote->http_proxy = xstrdup(value); } return 0; } @@ -417,25 +419,6 @@ int remote_has_url(struct remote *remote, const char *url) return 0; } -/* - * Returns true if, under the matching rules for fetching, name is the - * same as the given full name. - */ -static int ref_matches_abbrev(const char *name, const char *full) -{ - if (!prefixcmp(name, "refs/") || !strcmp(name, "HEAD")) - return !strcmp(name, full); - if (prefixcmp(full, "refs/")) - return 0; - if (!prefixcmp(name, "heads/") || - !prefixcmp(name, "tags/") || - !prefixcmp(name, "remotes/")) - return !strcmp(name, full + 5); - if (prefixcmp(full + 5, "heads/")) - return 0; - return !strcmp(full + 11, name); -} - int remote_find_tracking(struct remote *remote, struct refspec *refspec) { int find_src = refspec->src == NULL; @@ -531,10 +514,7 @@ static int count_refspec_match(const char *pattern, char *name = refs->name; int namelen = strlen(name); - if (namelen < patlen || - memcmp(name + namelen - patlen, pattern, patlen)) - continue; - if (namelen != patlen && name[namelen - patlen - 1] != '/') + if (!refname_match(pattern, name, ref_rev_parse_rules)) continue; /* A match is "weak" if it is with refs outside @@ -816,7 +796,7 @@ int branch_merge_matches(struct branch *branch, { if (!branch || i < 0 || i >= branch->merge_nr) return 0; - return ref_matches_abbrev(branch->merge[i]->src, refname); + return refname_match(branch->merge[i]->src, refname, ref_fetch_rules); } static struct ref *get_expanded_map(const struct ref *remote_refs, @@ -855,7 +835,7 @@ static const struct ref *find_ref_by_name_abbrev(const struct ref *refs, const c { const struct ref *ref; for (ref = refs; ref; ref = ref->next) { - if (ref_matches_abbrev(name, ref->name)) + if (refname_match(name, ref->name, ref_fetch_rules)) return ref; } return NULL; @@ -25,6 +25,11 @@ struct remote { const char *receivepack; const char *uploadpack; + + /* + * for curl remotes only + */ + char *http_proxy; }; struct remote *remote_get(const char *name); @@ -222,6 +222,22 @@ void setup_work_tree(void) initialized = 1; } +static int check_repository_format_gently(int *nongit_ok) +{ + git_config(check_repository_format_version); + if (GIT_REPO_VERSION < repository_format_version) { + if (!nongit_ok) + die ("Expected git repo version <= %d, found %d", + GIT_REPO_VERSION, repository_format_version); + warning("Expected git repo version <= %d, found %d", + GIT_REPO_VERSION, repository_format_version); + warning("Please upgrade Git"); + *nongit_ok = -1; + return -1; + } + return 0; +} + /* * We cannot decide in this function whether we are in the work tree or * not, since the config can only be read _after_ this function was called. @@ -246,8 +262,15 @@ const char *setup_git_directory_gently(int *nongit_ok) static char buffer[1024 + 1]; const char *retval; - if (!work_tree_env) - return set_work_tree(gitdirenv); + if (!work_tree_env) { + retval = set_work_tree(gitdirenv); + /* config may override worktree */ + if (check_repository_format_gently(nongit_ok)) + return NULL; + return retval; + } + if (check_repository_format_gently(nongit_ok)) + return NULL; retval = get_relative_cwd(buffer, sizeof(buffer) - 1, get_git_work_tree()); if (!retval || !*retval) @@ -286,6 +309,7 @@ const char *setup_git_directory_gently(int *nongit_ok) if (!work_tree_env) inside_work_tree = 0; setenv(GIT_DIR_ENVIRONMENT, ".", 1); + check_repository_format_gently(nongit_ok); return NULL; } chdir(".."); @@ -306,6 +330,8 @@ const char *setup_git_directory_gently(int *nongit_ok) if (!work_tree_env) inside_work_tree = 1; git_work_tree_cfg = xstrndup(cwd, offset); + if (check_repository_format_gently(nongit_ok)) + return NULL; if (offset == len) return NULL; @@ -356,17 +382,12 @@ int check_repository_format_version(const char *var, const char *value) int check_repository_format(void) { - git_config(check_repository_format_version); - if (GIT_REPO_VERSION < repository_format_version) - die ("Expected git repo version <= %d, found %d", - GIT_REPO_VERSION, repository_format_version); - return 0; + return check_repository_format_gently(NULL); } const char *setup_git_directory(void) { const char *retval = setup_git_directory_gently(NULL); - check_repository_format(); /* If the work tree is not the default one, recompute prefix */ if (inside_work_tree < 0) { diff --git a/sha1_name.c b/sha1_name.c index 2d727d54dc..13e11645e1 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -239,23 +239,13 @@ static int ambiguous_path(const char *path, int len) return slash; } -static const char *ref_fmt[] = { - "%.*s", - "refs/%.*s", - "refs/tags/%.*s", - "refs/heads/%.*s", - "refs/remotes/%.*s", - "refs/remotes/%.*s/HEAD", - NULL -}; - int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) { const char **p, *r; int refs_found = 0; *ref = NULL; - for (p = ref_fmt; *p; p++) { + for (p = ref_rev_parse_rules; *p; p++) { unsigned char sha1_from_ref[20]; unsigned char *this_result; @@ -277,7 +267,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log) int logs_found = 0; *log = NULL; - for (p = ref_fmt; *p; p++) { + for (p = ref_rev_parse_rules; *p; p++) { struct stat st; unsigned char hash[20]; char path[PATH_MAX]; @@ -610,24 +600,35 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) { struct commit_list *list = NULL, *backup = NULL, *l; int retval = -1; + char *temp_commit_buffer = NULL; if (prefix[0] == '!') { if (prefix[1] != '!') die ("Invalid search pattern: %s", prefix); prefix++; } - if (!save_commit_buffer) - return error("Could not expand oneline-name."); for_each_ref(handle_one_ref, &list); for (l = list; l; l = l->next) commit_list_insert(l->item, &backup); while (list) { char *p; struct commit *commit; + enum object_type type; + unsigned long size; commit = pop_most_recent_commit(&list, ONELINE_SEEN); parse_object(commit->object.sha1); - if (!commit->buffer || !(p = strstr(commit->buffer, "\n\n"))) + if (temp_commit_buffer) + free(temp_commit_buffer); + if (commit->buffer) + p = commit->buffer; + else { + p = read_sha1_file(commit->object.sha1, &type, &size); + if (!p) + continue; + temp_commit_buffer = p; + } + if (!(p = strstr(p, "\n\n"))) continue; if (!prefixcmp(p + 2, prefix)) { hashcpy(sha1, commit->object.sha1); @@ -635,6 +636,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1) break; } } + if (temp_commit_buffer) + free(temp_commit_buffer); free_commit_list(list); for (l = backup; l; l = l->next) clear_commit_marks(l->item, ONELINE_SEEN); @@ -117,5 +117,6 @@ extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); extern int strbuf_getline(struct strbuf *, FILE *, int); extern void stripspace(struct strbuf *buf, int skip_comments); +extern void launch_editor(const char *path, struct strbuf *buffer, const char *const *env); #endif /* STRBUF_H */ diff --git a/t/t0001-init.sh b/t/t0001-init.sh index b14b3ec394..c015405f12 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -25,7 +25,7 @@ check_config () { test_expect_success 'plain' ' ( - unset GIT_DIR GIT_WORK_TREE && + unset GIT_DIR GIT_WORK_TREE mkdir plain && cd plain && git init @@ -35,7 +35,7 @@ test_expect_success 'plain' ' test_expect_success 'plain with GIT_WORK_TREE' ' if ( - unset GIT_DIR && + unset GIT_DIR mkdir plain-wt && cd plain-wt && GIT_WORK_TREE=$(pwd) git init @@ -48,7 +48,7 @@ test_expect_success 'plain with GIT_WORK_TREE' ' test_expect_success 'plain bare' ' ( - unset GIT_DIR GIT_WORK_TREE GIT_CONFIG && + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG mkdir plain-bare-1 && cd plain-bare-1 && git --bare init @@ -58,7 +58,7 @@ test_expect_success 'plain bare' ' test_expect_success 'plain bare with GIT_WORK_TREE' ' if ( - unset GIT_DIR GIT_CONFIG && + unset GIT_DIR GIT_CONFIG mkdir plain-bare-2 && cd plain-bare-2 && GIT_WORK_TREE=$(pwd) git --bare init @@ -72,7 +72,7 @@ test_expect_success 'plain bare with GIT_WORK_TREE' ' test_expect_success 'GIT_DIR bare' ' ( - unset GIT_CONFIG && + unset GIT_CONFIG mkdir git-dir-bare.git && GIT_DIR=git-dir-bare.git git init ) && @@ -82,7 +82,7 @@ test_expect_success 'GIT_DIR bare' ' test_expect_success 'GIT_DIR non-bare' ' ( - unset GIT_CONFIG && + unset GIT_CONFIG mkdir non-bare && cd non-bare && GIT_DIR=.git git init @@ -93,7 +93,7 @@ test_expect_success 'GIT_DIR non-bare' ' test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' ( - unset GIT_CONFIG && + unset GIT_CONFIG mkdir git-dir-wt-1.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-1.git git init ) && @@ -103,7 +103,7 @@ test_expect_success 'GIT_DIR & GIT_WORK_TREE (1)' ' test_expect_success 'GIT_DIR & GIT_WORK_TREE (2)' ' if ( - unset GIT_CONFIG && + unset GIT_CONFIG mkdir git-dir-wt-2.git && GIT_WORK_TREE=$(pwd) GIT_DIR=git-dir-wt-2.git git --bare init ) diff --git a/t/t1302-repo-version.sh b/t/t1302-repo-version.sh new file mode 100755 index 0000000000..37fc1c8d36 --- /dev/null +++ b/t/t1302-repo-version.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# +# Copyright (c) 2007 Nguyễn Thái Ngọc Duy +# + +test_description='Test repository version check' + +. ./test-lib.sh + +cat >test.patch <<EOF +diff --git a/test.txt b/test.txt +new file mode 100644 +--- /dev/null ++++ b/test.txt +@@ -0,0 +1 @@ ++123 +EOF + +test_create_repo "test" +test_create_repo "test2" + +GIT_CONFIG=test2/.git/config git config core.repositoryformatversion 99 || exit 1 + +test_expect_success 'gitdir selection on normal repos' ' + (test "$(git config core.repositoryformatversion)" = 0 && + cd test && + test "$(git config core.repositoryformatversion)" = 0)' + +# Make sure it would stop at test2, not trash +test_expect_success 'gitdir selection on unsupported repo' ' + (cd test2 && + test "$(git config core.repositoryformatversion)" = 99)' + +test_expect_success 'gitdir not required mode' ' + (git apply --stat test.patch && + cd test && git apply --stat ../test.patch && + cd ../test2 && git apply --stat ../test.patch)' + +test_expect_success 'gitdir required mode on normal repos' ' + (git apply --check --index test.patch && + cd test && git apply --check --index ../test.patch)' + +test_expect_failure 'gitdir required mode on unsupported repo' ' + (cd test2 && git apply --check --index ../test.patch)' + +test_done diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index ae0639d8f3..e25b255683 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -86,7 +86,7 @@ EOF git config core.excludesFile excludes-file -git runstatus | grep "^# " > output +git status | grep "^# " > output cat > expect << EOF # .gitignore diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 2fe50bc7ce..a32692417d 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -71,10 +71,10 @@ test_expect_success 'favour same basenames over different ones' ' git rm path1 && mkdir subdir && git mv another-path subdir/path1 && - git runstatus | grep "renamed: .*path1 -> subdir/path1"' + git status | grep "renamed: .*path1 -> subdir/path1"' test_expect_success 'favour same basenames even with minor differences' ' git show HEAD:path1 | sed "s/15/16/" > subdir/path1 && - git runstatus | grep "renamed: .*path1 -> subdir/path1"' + git status | grep "renamed: .*path1 -> subdir/path1"' test_done diff --git a/t/t4019-diff-wserror.sh b/t/t4019-diff-wserror.sh new file mode 100755 index 0000000000..67e080bdbe --- /dev/null +++ b/t/t4019-diff-wserror.sh @@ -0,0 +1,123 @@ +#!/bin/sh + +test_description='diff whitespace error detection' + +. ./test-lib.sh + +test_expect_success setup ' + + git config diff.color.whitespace "blue reverse" && + >F && + git add F && + echo " Eight SP indent" >>F && + echo " HT and SP indent" >>F && + echo "With trailing SP " >>F && + echo "No problem" >>F + +' + +blue_grep='7;34m' ;# ESC [ 7 ; 3 4 m + +test_expect_success default ' + + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With error >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -trail' ' + + git config core.whitespace -trail + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -trail (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=-trail" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT error >/dev/null && + grep With normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -space' ' + + rm -f .gitattributes + git config core.whitespace -space + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT normal >/dev/null && + grep With error >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'without -space (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=-space" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight normal >/dev/null && + grep HT normal >/dev/null && + grep With error >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'with indent-non-tab only' ' + + rm -f .gitattributes + git config core.whitespace indent,-trailing,-space + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight error >/dev/null && + grep HT normal >/dev/null && + grep With normal >/dev/null && + grep No normal >/dev/null + +' + +test_expect_success 'with indent-non-tab only (attribute)' ' + + git config --unset core.whitespace + echo "F whitespace=indent,-trailing,-space" >.gitattributes + git diff --color >output + grep "$blue_grep" output >error + grep -v "$blue_grep" output >normal + + grep Eight error >/dev/null && + grep HT normal >/dev/null && + grep With normal >/dev/null && + grep No normal >/dev/null + +' + +test_done diff --git a/t/t4124-apply-ws-rule.sh b/t/t4124-apply-ws-rule.sh new file mode 100755 index 0000000000..85f3da2b98 --- /dev/null +++ b/t/t4124-apply-ws-rule.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +test_description='core.whitespace rules and git-apply' + +. ./test-lib.sh + +prepare_test_file () { + + # A line that has character X is touched iff RULE is in effect: + # X RULE + # ! trailing-space + # @ space-before-tab + # # indent-with-non-tab + sed -e "s/_/ /g" -e "s/>/ /" <<-\EOF + An_SP in an ordinary line>and a HT. + >A HT. + _>A SP and a HT (@). + _>_A SP, a HT and a SP (@). + _______Seven SP. + ________Eight SP (#). + _______>Seven SP and a HT (@). + ________>Eight SP and a HT (@#). + _______>_Seven SP, a HT and a SP (@). + ________>_Eight SP, a HT and a SP (@#). + _______________Fifteen SP (#). + _______________>Fifteen SP and a HT (@#). + ________________Sixteen SP (#). + ________________>Sixteen SP and a HT (@#). + _____a__Five SP, a non WS, two SP. + A line with a (!) trailing SP_ + A line with a (!) trailing HT> + EOF +} + +apply_patch () { + >target && + sed -e "s|\([ab]\)/file|\1/target|" <patch | + git apply "$@" +} + +test_fix () { + + # fix should not barf + apply_patch --whitespace=fix || return 1 + + # find touched lines + diff file target | sed -n -e "s/^> //p" >fixed + + # the changed lines are all expeced to change + fixed_cnt=$(wc -l <fixed) + case "$1" in + '') expect_cnt=$fixed_cnt ;; + ?*) expect_cnt=$(grep "[$1]" <fixed | wc -l) ;; + esac + test $fixed_cnt -eq $expect_cnt || return 1 + + # and we are not missing anything + case "$1" in + '') expect_cnt=0 ;; + ?*) expect_cnt=$(grep "[$1]" <file | wc -l) ;; + esac + test $fixed_cnt -eq $expect_cnt || return 1 + + # Get the patch actually applied + git diff-files -p target >fixed-patch + test -s fixed-patch && return 0 + + # Make sure it is complaint-free + >target + git apply --whitespace=error-all <fixed-patch + +} + +test_expect_success setup ' + + >file && + git add file && + prepare_test_file >file && + git diff-files -p >patch && + >target && + git add target + +' + +test_expect_success 'whitespace=nowarn, default rule' ' + + apply_patch --whitespace=nowarn && + diff file target + +' + +test_expect_success 'whitespace=warn, default rule' ' + + apply_patch --whitespace=warn && + diff file target + +' + +test_expect_success 'whitespace=error-all, default rule' ' + + apply_patch --whitespace=error-all && return 1 + test -s target && return 1 + : happy + +' + +test_expect_success 'whitespace=error-all, no rule' ' + + git config core.whitespace -trailing,-space-before,-indent && + apply_patch --whitespace=error-all && + diff file target + +' + +test_expect_success 'whitespace=error-all, no rule (attribute)' ' + + git config --unset core.whitespace && + echo "target -whitespace" >.gitattributes && + apply_patch --whitespace=error-all && + diff file target + +' + +for t in - '' +do + case "$t" in '') tt='!' ;; *) tt= ;; esac + for s in - '' + do + case "$s" in '') ts='@' ;; *) ts= ;; esac + for i in - '' + do + case "$i" in '') ti='#' ;; *) ti= ;; esac + rule=${t}trailing,${s}space,${i}indent + + rm -f .gitattributes + test_expect_success "rule=$rule" ' + git config core.whitespace "$rule" && + test_fix "$tt$ts$ti" + ' + + test_expect_success "rule=$rule (attributes)" ' + git config --unset core.whitespace && + echo "target whitespace=$rule" >.gitattributes && + test_fix "$tt$ts$ti" + ' + + done + done +done + +test_done diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 35889c0a12..02882c1e4b 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -95,6 +95,31 @@ test_expect_success 'fetch following tags' ' ' +test_expect_failure 'fetch must not resolve short tag name' ' + + cd "$D" && + + mkdir five && + cd five && + git init && + + git fetch .. anno:five + +' + +test_expect_failure 'fetch must not resolve short remote name' ' + + cd "$D" && + git-update-ref refs/remotes/six/HEAD HEAD + + mkdir six && + cd six && + git init && + + git fetch .. six:six + +' + test_expect_success 'create bundle 1' ' cd "$D" && echo >file updated again by origin && @@ -228,4 +253,46 @@ test_expect_success 'bundle should record HEAD correctly' ' ' +test_expect_success 'explicit fetch should not update tracking' ' + + cd "$D" && + git branch -f side && + ( + cd three && + o=$(git rev-parse --verify refs/remotes/origin/master) && + git fetch origin master && + n=$(git rev-parse --verify refs/remotes/origin/master) && + test "$o" = "$n" && + ! git rev-parse --verify refs/remotes/origin/side + ) +' + +test_expect_success 'explicit pull should not update tracking' ' + + cd "$D" && + git branch -f side && + ( + cd three && + o=$(git rev-parse --verify refs/remotes/origin/master) && + git pull origin master && + n=$(git rev-parse --verify refs/remotes/origin/master) && + test "$o" = "$n" && + ! git rev-parse --verify refs/remotes/origin/side + ) +' + +test_expect_success 'configured fetch updates tracking' ' + + cd "$D" && + git branch -f side && + ( + cd three && + o=$(git rev-parse --verify refs/remotes/origin/master) && + git fetch origin && + n=$(git rev-parse --verify refs/remotes/origin/master) && + test "$o" != "$n" && + git rev-parse --verify refs/remotes/origin/side + ) +' + test_done diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 987c9d21ca..9d2dc33cbd 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -145,11 +145,21 @@ test_expect_success 'push with no ambiguity (1)' ' test_expect_success 'push with no ambiguity (2)' ' mk_test remotes/origin/master && - git push testrepo master:master && + git push testrepo master:origin/master && check_push_result $the_commit remotes/origin/master ' +test_expect_success 'push with colon-less refspec, no ambiguity' ' + + mk_test heads/master heads/t/master && + git branch -f t/master master && + git push testrepo master && + check_push_result $the_commit heads/master && + check_push_result $the_first_commit heads/t/master + +' + test_expect_success 'push with weak ambiguity (1)' ' mk_test heads/master remotes/origin/master && @@ -244,6 +254,23 @@ test_expect_success 'push with colon-less refspec (4)' ' ' +test_expect_success 'push with HEAD' ' + + mk_test heads/master && + git checkout master && + git push testrepo HEAD && + check_push_result $the_commit heads/master + +' + +test_expect_success 'push with HEAD nonexisting at remote' ' + + mk_test heads/master && + git checkout -b local master && + git push testrepo HEAD && + check_push_result $the_commit heads/local +' + test_expect_success 'push with dry-run' ' mk_test heads/master && diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index c722635050..8a23aaf21b 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -169,5 +169,44 @@ test_expect_success 'Verify descending sort' ' git diff expected actual ' +cat >expected <<\EOF +'refs/heads/master' +'refs/tags/testtag' +EOF + +test_expect_success 'Quoting style: shell' ' + git for-each-ref --shell --format="%(refname)" >actual && + git diff expected actual +' + +test_expect_success 'Quoting style: perl' ' + git for-each-ref --perl --format="%(refname)" >actual && + git diff expected actual +' + +test_expect_success 'Quoting style: python' ' + git for-each-ref --python --format="%(refname)" >actual && + git diff expected actual +' + +cat >expected <<\EOF +"refs/heads/master" +"refs/tags/testtag" +EOF + +test_expect_success 'Quoting style: tcl' ' + git for-each-ref --tcl --format="%(refname)" >actual && + git diff expected actual +' + +for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do + test_expect_success "more than one quoting style: $i" " + git for-each-ref $i 2>&1 | (read line && + case \$line in + \"error: more than one quoting style\"*) : happy;; + *) false + esac) + " +done test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index f013c176ed..dfd118878f 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -126,6 +126,20 @@ test_expect_success 'git-clean symbolic link' ' ' +test_expect_success 'git-clean with wildcard' ' + + touch a.clean b.clean other.c && + git-clean "*.clean" && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.clean && + test ! -f b.clean && + test -f other.c + +' + test_expect_success 'git-clean -n' ' mkdir -p build docs && diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index cf389b81da..baed6ce96b 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -122,7 +122,20 @@ test_expect_success 'using alternate GIT_INDEX_FILE (2)' ' ) && cmp .git/index saved-index >/dev/null +' + +cat > expect << EOF +zort + +Signed-off-by: C O Mitter <committer@example.com> +EOF +test_expect_success '--signoff' ' + echo "yet another content *narf*" >> foo && + echo "zort" | + GIT_EDITOR=../t7500/add-content git commit -s -F - foo && + git cat-file commit HEAD | sed "1,/^$/d" > output && + diff expect output ' test_done diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 0316ecf5a1..05aa97d6f3 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -4,7 +4,7 @@ # # FIXME: Test the various index usages, -i and -o, test reflog, -# signoff, hooks +# signoff test_description='git-commit' . ./test-lib.sh @@ -244,8 +244,35 @@ test_expect_success 'multiple -m' ' ' +author="The Real Author <someguy@his.email.org>" +test_expect_success 'amend commit to fix author' ' + + oldtick=$GIT_AUTHOR_DATE && + test_tick && + git reset --hard && + git cat-file -p HEAD | + sed -e "s/author.*/author $author $oldtick/" \ + -e "s/^\(committer.*> \).*$/\1$GIT_COMMITTER_DATE/" > \ + expected && + git commit --amend --author="$author" && + git cat-file -p HEAD > current && + diff expected current + +' + +test_expect_success 'git commit <file> with dirty index' ' + echo tacocat > elif && + echo tehlulz > chz && + git add chz && + git commit elif -m "tacocat is a palindrome" && + git show --stat | grep elif && + git diff --cached | grep chz +' + test_expect_success 'same tree (single parent)' ' + git reset --hard + if git commit -m empty then echo oops -- should have complained diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh new file mode 100755 index 0000000000..21ac785e3d --- /dev/null +++ b/t/t7502-commit.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +test_description='git commit porcelain-ish' + +. ./test-lib.sh + +test_expect_success 'the basics' ' + + echo doing partial >"commit is" && + mkdir not && + echo very much encouraged but we should >not/forbid && + git add "commit is" not && + echo update added "commit is" file >"commit is" && + echo also update another >not/forbid && + test_tick && + git commit -a -m "initial with -a" && + + git cat-file blob HEAD:"commit is" >current.1 && + git cat-file blob HEAD:not/forbid >current.2 && + + cmp current.1 "commit is" && + cmp current.2 not/forbid + +' + +test_expect_success 'partial' ' + + echo another >"commit is" && + echo another >not/forbid && + test_tick && + git commit -m "partial commit to handle a file" "commit is" && + + changed=$(git diff-tree --name-only HEAD^ HEAD) && + test "$changed" = "commit is" + +' + +test_expect_success 'partial modification in a subdirecotry' ' + + test_tick && + git commit -m "partial commit to subdirectory" not && + + changed=$(git diff-tree -r --name-only HEAD^ HEAD) && + test "$changed" = "not/forbid" + +' + +test_expect_success 'partial removal' ' + + git rm not/forbid && + git commit -m "partial commit to remove not/forbid" not && + + changed=$(git diff-tree -r --name-only HEAD^ HEAD) && + test "$changed" = "not/forbid" && + remain=$(git ls-tree -r --name-only HEAD) && + test "$remain" = "commit is" + +' + +test_expect_success 'sign off' ' + + >positive && + git add positive && + git commit -s -m "thank you" && + actual=$(git cat-file commit HEAD | sed -ne "s/Signed-off-by: //p") && + expected=$(git var GIT_COMMITTER_IDENT | sed -e "s/>.*/>/") && + test "z$actual" = "z$expected" + +' + +test_expect_success 'multiple -m' ' + + >negative && + git add negative && + git commit -m "one" -m "two" -m "three" && + actual=$(git cat-file commit HEAD | sed -e "1,/^\$/d") && + expected=$(echo one; echo; echo two; echo; echo three) && + test "z$actual" = "z$expected" + +' + +test_expect_success 'verbose' ' + + echo minus >negative && + git add negative && + git status -v | sed -ne "/^diff --git /p" >actual && + echo "diff --git a/negative b/negative" >expect && + diff -u expect actual + +' + +test_done diff --git a/t/t7502-status.sh b/t/t7502-status.sh new file mode 100755 index 0000000000..9ce50cade8 --- /dev/null +++ b/t/t7502-status.sh @@ -0,0 +1,122 @@ +#!/bin/sh +# +# Copyright (c) 2007 Johannes E. Schindelin +# + +test_description='git-status' + +. ./test-lib.sh + +test_expect_success 'setup' ' + : > tracked && + : > modified && + mkdir dir1 && + : > dir1/tracked && + : > dir1/modified && + mkdir dir2 && + : > dir1/tracked && + : > dir1/modified && + git add . && + test_tick && + git commit -m initial && + : > untracked && + : > dir1/untracked && + : > dir2/untracked && + echo 1 > dir1/modified && + echo 2 > dir2/modified && + echo 3 > dir2/added && + git add dir2/added +' + +cat > expect << \EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success 'status' ' + + git status > output && + git diff expect output + +' + +cat > expect << \EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: ../dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# untracked +# ../dir2/modified +# ../dir2/untracked +# ../expect +# ../output +# ../untracked +EOF + +test_expect_success 'status with relative paths' ' + + (cd dir1 && git status) > output && + git diff expect output + +' + +cat > expect << \EOF +# On branch master +# Changes to be committed: +# (use "git reset HEAD <file>..." to unstage) +# +# new file: dir2/added +# +# Changed but not updated: +# (use "git add <file>..." to update what will be committed) +# +# modified: dir1/modified +# +# Untracked files: +# (use "git add <file>..." to include in what will be committed) +# +# dir1/untracked +# dir2/modified +# dir2/untracked +# expect +# output +# untracked +EOF + +test_expect_success 'status without relative paths' ' + + git config status.relativePaths false + (cd dir1 && git status) > output && + git diff expect output + +' + +test_done diff --git a/t/t7503-pre-commit-hook.sh b/t/t7503-pre-commit-hook.sh new file mode 100755 index 0000000000..d787cac2f7 --- /dev/null +++ b/t/t7503-pre-commit-hook.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +test_description='pre-commit hook' + +. ./test-lib.sh + +test_expect_success 'with no hook' ' + + echo "foo" > file && + git add file && + git commit -m "first" + +' + +test_expect_success '--no-verify with no hook' ' + + echo "bar" > file && + git add file && + git commit --no-verify -m "bar" + +' + +# now install hook that always succeeds +HOOKDIR="$(git rev-parse --git-dir)/hooks" +HOOK="$HOOKDIR/pre-commit" +mkdir -p "$HOOKDIR" +cat > "$HOOK" <<EOF +#!/bin/sh +exit 0 +EOF +chmod +x "$HOOK" + +test_expect_success 'with succeeding hook' ' + + echo "more" >> file && + git add file && + git commit -m "more" + +' + +test_expect_success '--no-verify with succeeding hook' ' + + echo "even more" >> file && + git add file && + git commit --no-verify -m "even more" + +' + +# now a hook that fails +cat > "$HOOK" <<EOF +#!/bin/sh +exit 1 +EOF + +test_expect_failure 'with failing hook' ' + + echo "another" >> file && + git add file && + git commit -m "another" + +' + +test_expect_success '--no-verify with failing hook' ' + + echo "stuff" >> file && + git add file && + git commit --no-verify -m "stuff" + +' + +chmod -x "$HOOK" +test_expect_success 'with non-executable hook' ' + + echo "content" >> file && + git add file && + git commit -m "content" + +' + +test_expect_success '--no-verify with non-executable hook' ' + + echo "more content" >> file && + git add file && + git commit --no-verify -m "more content" + +' + +test_done diff --git a/t/t7504-commit-msg-hook.sh b/t/t7504-commit-msg-hook.sh new file mode 100755 index 0000000000..751b11300b --- /dev/null +++ b/t/t7504-commit-msg-hook.sh @@ -0,0 +1,220 @@ +#!/bin/sh + +test_description='commit-msg hook' + +. ./test-lib.sh + +test_expect_success 'with no hook' ' + + echo "foo" > file && + git add file && + git commit -m "first" + +' + +# set up fake editor for interactive editing +cat > fake-editor <<'EOF' +#!/bin/sh +cp FAKE_MSG "$1" +exit 0 +EOF +chmod +x fake-editor +FAKE_EDITOR="$(pwd)/fake-editor" +export FAKE_EDITOR + +test_expect_success 'with no hook (editor)' ' + + echo "more foo" >> file && + git add file && + echo "more foo" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit + +' + +test_expect_success '--no-verify with no hook' ' + + echo "bar" > file && + git add file && + git commit --no-verify -m "bar" + +' + +test_expect_success '--no-verify with no hook (editor)' ' + + echo "more bar" > file && + git add file && + echo "more bar" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify + +' + +# now install hook that always succeeds +HOOKDIR="$(git rev-parse --git-dir)/hooks" +HOOK="$HOOKDIR/commit-msg" +mkdir -p "$HOOKDIR" +cat > "$HOOK" <<EOF +#!/bin/sh +exit 0 +EOF +chmod +x "$HOOK" + +test_expect_success 'with succeeding hook' ' + + echo "more" >> file && + git add file && + git commit -m "more" + +' + +test_expect_success 'with succeeding hook (editor)' ' + + echo "more more" >> file && + git add file && + echo "more more" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit + +' + +test_expect_success '--no-verify with succeeding hook' ' + + echo "even more" >> file && + git add file && + git commit --no-verify -m "even more" + +' + +test_expect_success '--no-verify with succeeding hook (editor)' ' + + echo "even more more" >> file && + git add file && + echo "even more more" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify + +' + +# now a hook that fails +cat > "$HOOK" <<EOF +#!/bin/sh +exit 1 +EOF + +test_expect_failure 'with failing hook' ' + + echo "another" >> file && + git add file && + git commit -m "another" + +' + +test_expect_failure 'with failing hook (editor)' ' + + echo "more another" >> file && + git add file && + echo "more another" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit + +' + +test_expect_success '--no-verify with failing hook' ' + + echo "stuff" >> file && + git add file && + git commit --no-verify -m "stuff" + +' + +test_expect_success '--no-verify with failing hook (editor)' ' + + echo "more stuff" >> file && + git add file && + echo "more stuff" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify + +' + +chmod -x "$HOOK" +test_expect_success 'with non-executable hook' ' + + echo "content" >> file && + git add file && + git commit -m "content" + +' + +test_expect_success 'with non-executable hook (editor)' ' + + echo "content again" >> file && + git add file && + echo "content again" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit -m "content again" + +' + +test_expect_success '--no-verify with non-executable hook' ' + + echo "more content" >> file && + git add file && + git commit --no-verify -m "more content" + +' + +test_expect_success '--no-verify with non-executable hook (editor)' ' + + echo "even more content" >> file && + git add file && + echo "even more content" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify + +' + +# now a hook that edits the commit message +cat > "$HOOK" <<'EOF' +#!/bin/sh +echo "new message" > "$1" +exit 0 +EOF +chmod +x "$HOOK" + +commit_msg_is () { + test "`git log --pretty=format:%s%b -1`" = "$1" +} + +test_expect_success 'hook edits commit message' ' + + echo "additional" >> file && + git add file && + git commit -m "additional" && + commit_msg_is "new message" + +' + +test_expect_success 'hook edits commit message (editor)' ' + + echo "additional content" >> file && + git add file && + echo "additional content" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit && + commit_msg_is "new message" + +' + +test_expect_success "hook doesn't edit commit message" ' + + echo "plus" >> file && + git add file && + git commit --no-verify -m "plus" && + commit_msg_is "plus" + +' + +test_expect_success "hook doesn't edit commit message (editor)" ' + + echo "more plus" >> file && + git add file && + echo "more plus" > FAKE_MSG && + GIT_EDITOR="$FAKE_EDITOR" git commit --no-verify && + commit_msg_is "more plus" + +' + +test_done diff --git a/t/t9301-fast-export.sh b/t/t9301-fast-export.sh index e9c9fe65d0..f09bfb1117 100755 --- a/t/t9301-fast-export.sh +++ b/t/t9301-fast-export.sh @@ -106,9 +106,9 @@ test_expect_success 'signed-tags=abort' ' ' -test_expect_success 'signed-tags=ignore' ' +test_expect_success 'signed-tags=verbatim' ' - git fast-export --signed-tags=ignore sign-your-name > output && + git fast-export --signed-tags=verbatim sign-your-name > output && grep PGP output ' diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh index 08f0f2a3a3..7706430d81 100755 --- a/t/t9600-cvsimport.sh +++ b/t/t9600-cvsimport.sh @@ -3,13 +3,29 @@ test_description='git-cvsimport basic tests' . ./test-lib.sh -if ! ( type cvs && type cvsps ) >/dev/null 2>&1 +if ! type cvs >/dev/null 2>&1 then - test_expect_success 'skipping cvsimport tests, cvs/cvsps not found' '' + say 'skipping cvsimport tests, cvs not found' test_done exit fi +cvsps_version=`cvsps -h 2>&1 | sed -ne 's/cvsps version //p'` +case "$cvsps_version" in +2.1) + ;; +'') + say 'skipping cvsimport tests, cvsps not found' + test_done + exit + ;; +*) + say 'skipping cvsimport tests, cvsps too old' + test_done + exit + ;; +esac + CVSROOT=$(pwd)/cvsroot export CVSROOT # for clean cvsps cache diff --git a/templates/Makefile b/templates/Makefile index 6f4dbd362f..ebd3a62fd8 100644 --- a/templates/Makefile +++ b/templates/Makefile @@ -46,6 +46,6 @@ clean: $(RM) -r blt boilerplates.made install: all - $(INSTALL) -d -m755 '$(DESTDIR_SQ)$(template_dir_SQ)' + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(template_dir_SQ)' (cd blt && $(TAR) cf - .) | \ (cd '$(DESTDIR_SQ)$(template_dir_SQ)' && $(TAR) xf -) @@ -93,7 +93,7 @@ void trace_printf(const char *fmt, ...) close(fd); } -void trace_argv_printf(const char **argv, int count, const char *fmt, ...) +void trace_argv_printf(const char **argv, const char *fmt, ...) { struct strbuf buf; va_list ap; @@ -117,7 +117,7 @@ void trace_argv_printf(const char **argv, int count, const char *fmt, ...) } strbuf_setlen(&buf, len); - sq_quote_argv(&buf, argv, count, 0); + sq_quote_argv(&buf, argv, 0); strbuf_addch(&buf, '\n'); write_or_whine_pipe(fd, buf.buf, buf.len, err_msg); strbuf_release(&buf); diff --git a/transport.c b/transport.c index 50db9807d0..58e66f6c11 100644 --- a/transport.c +++ b/transport.c @@ -470,6 +470,10 @@ static struct ref *get_refs_via_curl(struct transport *transport) curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, fwrite_buffer); curl_easy_setopt(slot->curl, CURLOPT_URL, refs_url); curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, NULL); + if (transport->remote->http_proxy) + curl_easy_setopt(slot->curl, CURLOPT_PROXY, + transport->remote->http_proxy); + if (start_active_slot(slot)) { run_active_slot(slot); if (results.curl_result != CURLE_OK) { @@ -655,7 +659,7 @@ static int fetch_refs_via_pack(struct transport *transport, free(heads); free_refs(refs); free(dest); - return 0; + return (refs ? 0 : -1); } static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags) @@ -21,7 +21,7 @@ static void list_vars(void) { struct git_var *ptr; for(ptr = git_vars; ptr->read; ptr++) { - printf("%s=%s\n", ptr->name, ptr->read(0)); + printf("%s=%s\n", ptr->name, ptr->read(IDENT_WARN_ON_NO_NAME)); } } @@ -32,7 +32,7 @@ static const char *read_var(const char *var) val = NULL; for(ptr = git_vars; ptr->read; ptr++) { if (strcmp(var, ptr->name) == 0) { - val = ptr->read(1); + val = ptr->read(IDENT_ERROR_ON_NO_NAME); break; } } @@ -0,0 +1,96 @@ +/* + * Whitespace rules + * + * Copyright (c) 2007 Junio C Hamano + */ + +#include "cache.h" +#include "attr.h" + +static struct whitespace_rule { + const char *rule_name; + unsigned rule_bits; +} whitespace_rule_names[] = { + { "trailing-space", WS_TRAILING_SPACE }, + { "space-before-tab", WS_SPACE_BEFORE_TAB }, + { "indent-with-non-tab", WS_INDENT_WITH_NON_TAB }, +}; + +unsigned parse_whitespace_rule(const char *string) +{ + unsigned rule = WS_DEFAULT_RULE; + + while (string) { + int i; + size_t len; + const char *ep; + int negated = 0; + + string = string + strspn(string, ", \t\n\r"); + ep = strchr(string, ','); + if (!ep) + len = strlen(string); + else + len = ep - string; + + if (*string == '-') { + negated = 1; + string++; + len--; + } + if (!len) + break; + for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) { + if (strncmp(whitespace_rule_names[i].rule_name, + string, len)) + continue; + if (negated) + rule &= ~whitespace_rule_names[i].rule_bits; + else + rule |= whitespace_rule_names[i].rule_bits; + break; + } + string = ep; + } + return rule; +} + +static void setup_whitespace_attr_check(struct git_attr_check *check) +{ + static struct git_attr *attr_whitespace; + + if (!attr_whitespace) + attr_whitespace = git_attr("whitespace", 10); + check[0].attr = attr_whitespace; +} + +unsigned whitespace_rule(const char *pathname) +{ + struct git_attr_check attr_whitespace_rule; + + setup_whitespace_attr_check(&attr_whitespace_rule); + if (!git_checkattr(pathname, 1, &attr_whitespace_rule)) { + const char *value; + + value = attr_whitespace_rule.value; + if (ATTR_TRUE(value)) { + /* true (whitespace) */ + unsigned all_rule = 0; + int i; + for (i = 0; i < ARRAY_SIZE(whitespace_rule_names); i++) + all_rule |= whitespace_rule_names[i].rule_bits; + return all_rule; + } else if (ATTR_FALSE(value)) { + /* false (-whitespace) */ + return 0; + } else if (ATTR_UNSET(value)) { + /* reset to default (!whitespace) */ + return whitespace_rule_cfg; + } else { + /* string */ + return parse_whitespace_rule(value); + } + } else { + return whitespace_rule_cfg; + } +} diff --git a/wt-status.c b/wt-status.c index bf2fe8d237..51c1879691 100644 --- a/wt-status.c +++ b/wt-status.c @@ -8,6 +8,7 @@ #include "revision.h" #include "diffcore.h" +int wt_status_relative_paths = 1; int wt_status_use_color = 0; static char wt_status_colors[][COLOR_MAXLEN] = { "", /* WT_STATUS_HEADER: normal */ @@ -81,33 +82,50 @@ static void wt_status_print_trailer(struct wt_status *s) color_fprintf_ln(s->fp, color(WT_STATUS_HEADER), "#"); } -static const char *quote_crlf(const char *in, char *buf, size_t sz) +static char *quote_path(const char *in, int len, + struct strbuf *out, const char *prefix) { - const char *scan; - char *out; - const char *ret = in; + if (len < 0) + len = strlen(in); + + strbuf_grow(out, len); + strbuf_setlen(out, 0); + if (prefix) { + int off = 0; + while (prefix[off] && off < len && prefix[off] == in[off]) + if (prefix[off] == '/') { + prefix += off + 1; + in += off + 1; + len -= off + 1; + off = 0; + } else + off++; + + for (; *prefix; prefix++) + if (*prefix == '/') + strbuf_addstr(out, "../"); + } - for (scan = in, out = buf; *scan; scan++) { - int ch = *scan; - int quoted; + for ( ; len > 0; in++, len--) { + int ch = *in; switch (ch) { case '\n': - quoted = 'n'; + strbuf_addstr(out, "\\n"); break; case '\r': - quoted = 'r'; + strbuf_addstr(out, "\\r"); break; default: - *out++ = ch; + strbuf_addch(out, ch); continue; } - *out++ = '\\'; - *out++ = quoted; - ret = buf; } - *out = '\0'; - return ret; + + if (!out->len) + strbuf_addstr(out, "./"); + + return out->buf; } static void wt_status_print_filepair(struct wt_status *s, @@ -115,10 +133,12 @@ static void wt_status_print_filepair(struct wt_status *s, { const char *c = color(t); const char *one, *two; - char onebuf[PATH_MAX], twobuf[PATH_MAX]; + struct strbuf onebuf, twobuf; - one = quote_crlf(p->one->path, onebuf, sizeof(onebuf)); - two = quote_crlf(p->two->path, twobuf, sizeof(twobuf)); + strbuf_init(&onebuf, 0); + strbuf_init(&twobuf, 0); + one = quote_path(p->one->path, -1, &onebuf, s->prefix); + two = quote_path(p->two->path, -1, &twobuf, s->prefix); color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t"); switch (p->status) { @@ -150,6 +170,8 @@ static void wt_status_print_filepair(struct wt_status *s, die("bug: unhandled diff status %c", p->status); } fprintf(s->fp, "\n"); + strbuf_release(&onebuf); + strbuf_release(&twobuf); } static void wt_status_print_updated_cb(struct diff_queue_struct *q, @@ -204,8 +226,9 @@ static void wt_read_cache(struct wt_status *s) static void wt_status_print_initial(struct wt_status *s) { int i; - char buf[PATH_MAX]; + struct strbuf buf; + strbuf_init(&buf, 0); wt_read_cache(s); if (active_nr) { s->commitable = 1; @@ -214,11 +237,12 @@ static void wt_status_print_initial(struct wt_status *s) for (i = 0; i < active_nr; i++) { color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t"); color_fprintf_ln(s->fp, color(WT_STATUS_UPDATED), "new file: %s", - quote_crlf(active_cache[i]->name, - buf, sizeof(buf))); + quote_path(active_cache[i]->name, -1, + &buf, s->prefix)); } if (active_nr) wt_status_print_trailer(s); + strbuf_release(&buf); } static void wt_status_print_updated(struct wt_status *s) @@ -253,7 +277,9 @@ static void wt_status_print_untracked(struct wt_status *s) struct dir_struct dir; int i; int shown_header = 0; + struct strbuf buf; + strbuf_init(&buf, 0); memset(&dir, 0, sizeof(dir)); if (!s->untracked) { @@ -285,20 +311,38 @@ static void wt_status_print_untracked(struct wt_status *s) shown_header = 1; } color_fprintf(s->fp, color(WT_STATUS_HEADER), "#\t"); - color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%.*s", - ent->len, ent->name); + color_fprintf_ln(s->fp, color(WT_STATUS_UNTRACKED), "%s", + quote_path(ent->name, ent->len, + &buf, s->prefix)); } + strbuf_release(&buf); } static void wt_status_print_verbose(struct wt_status *s) { struct rev_info rev; + int saved_stdout; + + fflush(s->fp); + + /* Sigh, the entire diff machinery is hardcoded to output to + * stdout. Do the dup-dance...*/ + saved_stdout = dup(STDOUT_FILENO); + if (saved_stdout < 0 ||dup2(fileno(s->fp), STDOUT_FILENO) < 0) + die("couldn't redirect stdout\n"); + init_revisions(&rev, NULL); setup_revisions(0, NULL, &rev, s->reference); rev.diffopt.output_format |= DIFF_FORMAT_PATCH; rev.diffopt.detect_rename = 1; wt_read_cache(s); run_diff_index(&rev, 1); + + fflush(stdout); + + if (dup2(saved_stdout, STDOUT_FILENO) < 0) + die("couldn't restore stdout\n"); + close(saved_stdout); } void wt_status_print(struct wt_status *s) @@ -351,12 +395,17 @@ void wt_status_print(struct wt_status *s) int git_status_config(const char *k, const char *v) { if (!strcmp(k, "status.color") || !strcmp(k, "color.status")) { - wt_status_use_color = git_config_colorbool(k, v); + wt_status_use_color = git_config_colorbool(k, v, -1); return 0; } if (!prefixcmp(k, "status.color.") || !prefixcmp(k, "color.status.")) { int slot = parse_status_slot(k, 13); color_parse(v, k, wt_status_colors[slot]); + return 0; + } + if (!strcmp(k, "status.relativepaths")) { + wt_status_relative_paths = git_config_bool(k, v); + return 0; } return git_default_config(k, v); } diff --git a/wt-status.h b/wt-status.h index 77449326db..63d50f2871 100644 --- a/wt-status.h +++ b/wt-status.h @@ -23,9 +23,12 @@ struct wt_status { int workdir_untracked; const char *index_file; FILE *fp; + const char *prefix; }; int git_status_config(const char *var, const char *value); +int wt_status_use_color; +int wt_status_relative_paths; void wt_status_prepare(struct wt_status *s); void wt_status_print(struct wt_status *s); |