Merge branch 'master' into cc/help
authorJunio C Hamano <gitster@pobox.com>
Mon, 10 Dec 2007 09:22:42 +0000 (01:22 -0800)
committerJunio C Hamano <gitster@pobox.com>
Mon, 10 Dec 2007 09:22:42 +0000 (01:22 -0800)
This is to primarily pull in MANPATH tweak and help.txt formatting fix
from the master branch.

117 files changed:
.gitignore
.mailmap
Documentation/Makefile
Documentation/RelNotes-1.5.4.txt
Documentation/SubmittingPatches
Documentation/config.txt
Documentation/diff-format.txt
Documentation/diff-generate-patch.txt [new file with mode: 0644]
Documentation/diff-options.txt
Documentation/git-add.txt
Documentation/git-apply.txt
Documentation/git-bisect.txt
Documentation/git-commit.txt
Documentation/git-config.txt
Documentation/git-fast-export.txt
Documentation/git-help.txt
Documentation/git-log.txt
Documentation/git-rerere.txt
Documentation/git-send-pack.txt
Documentation/git-status.txt
Documentation/git.txt
Documentation/gitattributes.txt
Makefile
builtin-add.c
builtin-apply.c
builtin-branch.c
builtin-clean.c
builtin-commit-tree.c
builtin-commit.c [new file with mode: 0644]
builtin-config.c
builtin-fast-export.c
builtin-fetch.c
builtin-for-each-ref.c
builtin-grep.c
builtin-log.c
builtin-ls-files.c
builtin-ls-remote.c
builtin-pack-objects.c
builtin-push.c
builtin-rev-parse.c
builtin-runstatus.c
builtin-shortlog.c
builtin-tag.c
builtin.h
cache.h
color.c
color.h
command-list.txt
commit.h
config.c
config.mak.in
configure.ac
contrib/examples/git-commit.sh [new file with mode: 0755]
contrib/hg-to-git/hg-to-git.py
contrib/remotes2config.sh [changed mode: 0644->0755]
diff.c
dir.c
environment.c
exec_cmd.c
git-add--interactive.perl
git-am.sh
git-bisect.sh
git-commit.sh [deleted file]
git-cvsserver.perl
git-gui/Makefile
git-gui/lib/commit.tcl
git-gui/lib/git-gui.ico
git-gui/po/de.po
git-gui/po/git-gui.pot
git-gui/po/glossary/it.po
git-gui/po/hu.po
git-gui/po/it.po
git-gui/po/ja.po
git-mergetool.sh
git-send-email.perl
git-submodule.sh
git.c
gitweb/gitweb.perl
help.c
http.c
http.h
ident.c
mailmap.c
perl/Git.pm
quote.c
quote.h
refs.c
remote.c
remote.h
setup.c
sha1_name.c
strbuf.h
t/t0001-init.sh
t/t1302-repo-version.sh [new file with mode: 0755]
t/t3001-ls-files-others-exclude.sh
t/t4001-diff-rename.sh
t/t4019-diff-wserror.sh [new file with mode: 0755]
t/t4124-apply-ws-rule.sh [new file with mode: 0755]
t/t5510-fetch.sh
t/t5516-fetch-push.sh
t/t6300-for-each-ref.sh
t/t7300-clean.sh
t/t7500-commit.sh
t/t7501-commit.sh
t/t7502-commit.sh [new file with mode: 0755]
t/t7502-status.sh [new file with mode: 0755]
t/t7503-pre-commit-hook.sh [new file with mode: 0755]
t/t7504-commit-msg-hook.sh [new file with mode: 0755]
t/t9301-fast-export.sh
t/t9600-cvsimport.sh
templates/Makefile
trace.c
transport.c
var.c
ws.c [new file with mode: 0644]
wt-status.c
wt-status.h
index 916fabc6c5485525df37832db38b007e3c7203ef..bac60ce31ae3b8d74619df7dd93356c49f21d081 100644 (file)
@@ -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
index 3b2ce578a1a02a86d7a1f0b66b5ea5e51472033b..1f729c223ce8ec6f913a36497f0c32b7bba67819 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -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>
index f0df0b0d28e70ac6b7981f883bf6bc547f3fdf96..9f0f9d70f6decd721141b48f9be2f0a8da429bcb 100644 (file)
@@ -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+
 
index 44f5043ce7843e96349ad2cb4f19d0246424ff87..7386e66dc9f80eb7a9cafba3f637f04eaef21e14 100644 (file)
@@ -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
index 83bf54c7ac153b7010dcecc34d28c05dc68c10b6..de08d094e3e3683913bac49f643bb6b49fbec04d 100644 (file)
@@ -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
index 4124ad2970cfd76eb6592658c02007188c48003a..fabe7f859f32aa53ae86244f014e58bd3aa5ee3d 100644 (file)
@@ -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
index 9709c35c98bc678d1f2e339c8e2d4bbcd7e6231f..2c3a4c433b2a6d2b0846243a4f1dbebeed45236e 100644 (file)
@@ -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 (file)
index 0000000..029c5f2
--- /dev/null
@@ -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").
index e4af393515c346528bccb7a4f2d3823aebddddfc..d0154bbc0a2f868b3f5f1c63dcffd1fc9355ebc3 100644 (file)
@@ -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[]
 
index 63829d93cc827255355aa07a7db061b1a3a9e4d9..bf94cd43bdd8a9e113af37bec5acd568dd1b3930 100644 (file)
@@ -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.
index c1c54bfe0b7d2c1b133e245a3a963caa0b7afb8c..bae3e7b909736b0827b9fda783d068ade997c466 100644 (file)
@@ -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
index 4795349c10fd91c330ddde2d8397401be09cc86b..8b9d61a8a4cdfcf9c993ed02a60297eb9d978b9a 100644 (file)
@@ -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
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 4bb279155053c5ec8f31b01a04803a992ada24f0..4261384158f53ebe85dc32148b5652dc697e5b3b 100644 (file)
@@ -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::
index 7640450787064aac7211b5a3d5504275b62119ff..98509b4f441abc7671645ece78c9ba83a8dac4c0 100644 (file)
@@ -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
index 073ff7f123d633358f57d9995d23da14da81df77..fd3d571464ba3ae60ee0ae331cf6c7bef0a74b38 100644 (file)
@@ -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.
 
 
index 0e873fde280f0df9b807440290831797b01331fa..ac9e15d7748a17bdd552acfb0c690ffea459a87c 100644 (file)
@@ -1,5 +1,5 @@
 git-help(1)
-======
+===========
 
 NAME
 ----
index 5ec547cc0c10fb940b1bd2481940997cd375e830..5920d1799acd2fe84e302b005695e2c795ecad36 100644 (file)
@@ -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
 --------
index c4d4263238e5b7c6dff705de5d8552a577fc35d6..8ce492c8f2738275aa951f2fd98f1bcca16baee6 100644 (file)
@@ -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
 --------
index 2fa01d4a3ca92ed3a3896e4df416cf8f3933c885..a2d9cb61be1598eb4568c7d03aafbd733e1acd9c 100644 (file)
@@ -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.
index 8fd0fc62368611bee25b4bbc3becef853937ff2c..5c5a480ec45d181a548a39c8a88dba3e3692eaa8 100644 (file)
@@ -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]
index c4e4d24ea40a82f20cd72dfa3f66a284bc206eb3..a29b634e7a8d86a3e03f7d90ca81a9e86b068730 100644 (file)
@@ -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
index 19bd25f29900c99d78592fe290772856092e2dc5..71c7ad76d57f5ce89206ccbc8f4c66cadd8f7743 100644 (file)
@@ -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
 -------
 
index 932b0d4346dc7480e1ce56ed33614cf9bb50a546..429bc1ddb55f502b5c7ed51515aa7600599b2f15 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -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
index cf815a0b8ef0e588cfaf25f71747ba7248d19d70..5c29cc2f3f680e4dee19b040e647dd8b014cf10d 100644 (file)
@@ -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;
        }
 
index 91f8752ff7fdb588e64f594519a2e9503c516630..f2e9a332ca0e148366f49b2825ed8826576f1bad 100644 (file)
@@ -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",
index c64768beb2c112fc32a65fb4070f01331ebf1540..089cae59299659b20359b7249e57ddc3a43ded06 100644 (file)
@@ -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.")) {
index 56ae4eb9bb4efad179f7d664880457535bd6048f..ae30d4e76c3e758689464f41a63dda0605d60e9f 100644 (file)
@@ -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;
index 88b0ab36eba6ded8f1a39e0d4c83122b7e026874..6610d18358bae81ac1f162ca0c71062d36664c2a 100644 (file)
@@ -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 (file)
index 0000000..b6b81d5
--- /dev/null
@@ -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;
+}
index 4c9ded3b1a146c20d24559bbbee267e9be743fd2..e4a12e316648e6b0ab1ee0b424773f3c672c751e 100644 (file)
@@ -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--;
index 72be45db46faef46695b333a298f2857706dff9f..2136aadfd7831828ee29fbfa9ae7974c65271dee 100755 (executable)
@@ -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;
index de9947e7ac2cc1236909fab813198b3df93bd39e..320e235682340f07cb28b0a4de0c39b6bd9da383 100644 (file)
@@ -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;
index daf3a081650b6b39fe18f0fab61fa8b3f6c8be0f..f36a43c26459bd386618e551e2e93743cd8030aa 100644 (file)
@@ -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))
index bbf747fc7b66f6b4f19d9dc62a9ba10965199917..f1ff8dc556ce6caa1cafe77be41396dd9b7c9ee6 100644 (file)
@@ -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++;
index e1f1cf67143721933010065130adaba8723b272b..b6a11220e258468bddd92181bf18ce55343abf2e 100644 (file)
@@ -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);
index 7f607098305fcf14c3e2a7634b6a5dc118445306..0f0ab2da167c57402efad9dc09e58964759c23cd 100644 (file)
@@ -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;
index 56f3f880238e79a92ac35b4112e425a05c3fe916..c2caeeabe2f9d2bce190656a58094b5ebeee4e30 100644 (file)
@@ -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;
 }
index 4f446588ac9ce9d8aa50d0c288817a16855422e6..250dc56ab5121d3ffda916228ed3dbf71d0def88 100644 (file)
@@ -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)
index 41df717f847ecc41bf0a695fa09fbb926b42f720..c8cb63e23840915ecd7445d1fe4a18f9c6cb694d 100644 (file)
@@ -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);
        }
 }
index d1038a0e66edf728fbba9476b3b9f443647c612c..20d1789e0161ed3d2d18cec94b1915f518a5d662 100644 (file)
@@ -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;
 }
index 2db25c88bf648e4d5f2f41502fd29c5f7324e56b..8d167a9674e70a36662528c98165bd3be8a9f431 100644 (file)
@@ -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"))
index 3fe754677d3f7ab11419a04dd828c70b5958ed87..b9cc134443feb4f9573166faf0745074384e0c21 100644 (file)
@@ -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)
index 114c684d246e975852bb5446ea2e7ab682ea036c..517419fd3d885d677e8c2eeb533fc14f3df501f5 100644 (file)
@@ -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);
index 3c1bf38d83c9a1ebf4a1036114a158b58a6c1b75..cb675c4d7a80b99a06d6d04156e767ea025eb512 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -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);
diff --git a/cache.h b/cache.h
index d0e7a71c6e61e56c841f9670266a2e5d61211158..1bcb3df7a20b7eb90c15807b92ae0e016266d5fd 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -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 */
diff --git a/color.c b/color.c
index 97cfbda31ac02b7e4fe747052c28821a34ee0165..7bd424a8f6012859f40f2aa6210e7d4ce7686dc0 100644 (file)
--- a/color.c
+++ b/color.c
@@ -116,7 +116,7 @@ void color_parse(const char *value, const char *var, char *dst)
        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;
diff --git a/color.h b/color.h
index 68098006ed057552370ec27359eb776e139bec5e..ff63513d39b1553e65230ef98583549506670950 100644 (file)
--- a/color.h
+++ b/color.h
@@ -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, ...);
index 49506a411ee3a0e88ba44a1dfc65c5dd1a801e8a..28342da959faebe5fde82fc4ac6df962fec35a2d 100644 (file)
@@ -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
index aa679867a9376496febd5105121b1f49f3ff96a4..10e2b5d4cfdc7ac129ead711421ccc51d2667f02 100644 (file)
--- a/commit.h
+++ b/commit.h
@@ -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)
index ed96213c44265289c26d46edaaf740cebd0b4c86..49d2b427e52008e612b534f0c567e9fadaeab6e3 100644 (file)
--- a/config.c
+++ b/config.c
@@ -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 ||
index 11d256e9cf5b51154a3bf0084f9e3bcea5702352..7d5df9bf3c5dc898a68b538bae55f3d44dbc01ff 100644 (file)
@@ -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@
index 5f8a15b9f9580bea6f350e8af468f81cf2535c9e..dd4b4eb9822f131f0efc746013a803c4adba02d2 100644 (file)
@@ -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/contrib/examples/git-commit.sh b/contrib/examples/git-commit.sh
new file mode 100755 (executable)
index 0000000..2c4a406
--- /dev/null
@@ -0,0 +1,639 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Linus Torvalds
+# Copyright (c) 2006 Junio C Hamano
+
+USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
+SUBDIRECTORY_OK=Yes
+OPTIONS_SPEC=
+. git-sh-setup
+require_work_tree
+
+git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
+
+case "$0" in
+*status)
+       status_only=t
+       ;;
+*commit)
+       status_only=
+       ;;
+esac
+
+refuse_partial () {
+       echo >&2 "$1"
+       echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
+       exit 1
+}
+
+TMP_INDEX=
+THIS_INDEX="${GIT_INDEX_FILE:-$GIT_DIR/index}"
+NEXT_INDEX="$GIT_DIR/next-index$$"
+rm -f "$NEXT_INDEX"
+save_index () {
+       cp -p "$THIS_INDEX" "$NEXT_INDEX"
+}
+
+run_status () {
+       # If TMP_INDEX is defined, that means we are doing
+       # "--only" partial commit, and that index file is used
+       # to build the tree for the commit.  Otherwise, if
+       # NEXT_INDEX exists, that is the index file used to
+       # make the commit.  Otherwise we are using as-is commit
+       # so the regular index file is what we use to compare.
+       if test '' != "$TMP_INDEX"
+       then
+               GIT_INDEX_FILE="$TMP_INDEX"
+               export GIT_INDEX_FILE
+       elif test -f "$NEXT_INDEX"
+       then
+               GIT_INDEX_FILE="$NEXT_INDEX"
+               export GIT_INDEX_FILE
+       fi
+
+       if test "$status_only" = "t" -o "$use_status_color" = "t"; then
+               color=
+       else
+               color=--nocolor
+       fi
+       git runstatus ${color} \
+               ${verbose:+--verbose} \
+               ${amend:+--amend} \
+               ${untracked_files:+--untracked}
+}
+
+trap '
+       test -z "$TMP_INDEX" || {
+               test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
+       }
+       rm -f "$NEXT_INDEX"
+' 0
+
+################################################################
+# Command line argument parsing and sanity checking
+
+all=
+also=
+allow_empty=f
+interactive=
+only=
+logfile=
+use_commit=
+amend=
+edit_flag=
+no_edit=
+log_given=
+log_message=
+verify=t
+quiet=
+verbose=
+signoff=
+force_author=
+only_include_assumed=
+untracked_files=
+templatefile="`git config commit.template`"
+while test $# != 0
+do
+       case "$1" in
+       -F|--F|-f|--f|--fi|--fil|--file)
+               case "$#" in 1) usage ;; esac
+               shift
+               no_edit=t
+               log_given=t$log_given
+               logfile="$1"
+               ;;
+       -F*|-f*)
+               no_edit=t
+               log_given=t$log_given
+               logfile="${1#-[Ff]}"
+               ;;
+       --F=*|--f=*|--fi=*|--fil=*|--file=*)
+               no_edit=t
+               log_given=t$log_given
+               logfile="${1#*=}"
+               ;;
+       -a|--a|--al|--all)
+               all=t
+               ;;
+       --allo|--allow|--allow-|--allow-e|--allow-em|--allow-emp|\
+       --allow-empt|--allow-empty)
+               allow_empty=t
+               ;;
+       --au=*|--aut=*|--auth=*|--autho=*|--author=*)
+               force_author="${1#*=}"
+               ;;
+       --au|--aut|--auth|--autho|--author)
+               case "$#" in 1) usage ;; esac
+               shift
+               force_author="$1"
+               ;;
+       -e|--e|--ed|--edi|--edit)
+               edit_flag=t
+               ;;
+       -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
+               also=t
+               ;;
+       --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
+       --interactiv|--interactive)
+               interactive=t
+               ;;
+       -o|--o|--on|--onl|--only)
+               only=t
+               ;;
+       -m|--m|--me|--mes|--mess|--messa|--messag|--message)
+               case "$#" in 1) usage ;; esac
+               shift
+               log_given=m$log_given
+               log_message="${log_message:+${log_message}
+
+}$1"
+               no_edit=t
+               ;;
+       -m*)
+               log_given=m$log_given
+               log_message="${log_message:+${log_message}
+
+}${1#-m}"
+               no_edit=t
+               ;;
+       --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
+               log_given=m$log_given
+               log_message="${log_message:+${log_message}
+
+}${1#*=}"
+               no_edit=t
+               ;;
+       -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
+       --no-verify)
+               verify=
+               ;;
+       --a|--am|--ame|--amen|--amend)
+               amend=t
+               use_commit=HEAD
+               ;;
+       -c)
+               case "$#" in 1) usage ;; esac
+               shift
+               log_given=t$log_given
+               use_commit="$1"
+               no_edit=
+               ;;
+       --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
+       --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
+       --reedit-messag=*|--reedit-message=*)
+               log_given=t$log_given
+               use_commit="${1#*=}"
+               no_edit=
+               ;;
+       --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
+       --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
+       --reedit-message)
+               case "$#" in 1) usage ;; esac
+               shift
+               log_given=t$log_given
+               use_commit="$1"
+               no_edit=
+               ;;
+       -C)
+               case "$#" in 1) usage ;; esac
+               shift
+               log_given=t$log_given
+               use_commit="$1"
+               no_edit=t
+               ;;
+       --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
+       --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
+       --reuse-message=*)
+               log_given=t$log_given
+               use_commit="${1#*=}"
+               no_edit=t
+               ;;
+       --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
+       --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
+               case "$#" in 1) usage ;; esac
+               shift
+               log_given=t$log_given
+               use_commit="$1"
+               no_edit=t
+               ;;
+       -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
+               signoff=t
+               ;;
+       -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
+               case "$#" in 1) usage ;; esac
+               shift
+               templatefile="$1"
+               no_edit=
+               ;;
+       -q|--q|--qu|--qui|--quie|--quiet)
+               quiet=t
+               ;;
+       -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
+               verbose=t
+               ;;
+       -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
+       --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
+       --untracked-file|--untracked-files)
+               untracked_files=t
+               ;;
+       --)
+               shift
+               break
+               ;;
+       -*)
+               usage
+               ;;
+       *)
+               break
+               ;;
+       esac
+       shift
+done
+case "$edit_flag" in t) no_edit= ;; esac
+
+################################################################
+# Sanity check options
+
+case "$amend,$initial_commit" in
+t,t)
+       die "You do not have anything to amend." ;;
+t,)
+       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+               die "You are in the middle of a merge -- cannot amend."
+       fi ;;
+esac
+
+case "$log_given" in
+tt*)
+       die "Only one of -c/-C/-F can be used." ;;
+*tm*|*mt*)
+       die "Option -m cannot be combined with -c/-C/-F." ;;
+esac
+
+case "$#,$also,$only,$amend" in
+*,t,t,*)
+       die "Only one of --include/--only can be used." ;;
+0,t,,* | 0,,t,)
+       die "No paths with --include/--only does not make sense." ;;
+0,,t,t)
+       only_include_assumed="# Clever... amending the last one with dirty index." ;;
+0,,,*)
+       ;;
+*,,,*)
+       only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
+       also=
+       ;;
+esac
+unset only
+case "$all,$interactive,$also,$#" in
+*t,*t,*)
+       die "Cannot use -a, --interactive or -i at the same time." ;;
+t,,,[1-9]*)
+       die "Paths with -a does not make sense." ;;
+,t,,[1-9]*)
+       die "Paths with --interactive does not make sense." ;;
+,,t,0)
+       die "No paths with -i does not make sense." ;;
+esac
+
+if test ! -z "$templatefile" -a -z "$log_given"
+then
+       if test ! -f "$templatefile"
+       then
+               die "Commit template file does not exist."
+       fi
+fi
+
+################################################################
+# Prepare index to have a tree to be committed
+
+case "$all,$also" in
+t,)
+       if test ! -f "$THIS_INDEX"
+       then
+               die 'nothing to commit (use "git add file1 file2" to include for commit)'
+       fi
+       save_index &&
+       (
+               cd_to_toplevel &&
+               GIT_INDEX_FILE="$NEXT_INDEX" &&
+               export GIT_INDEX_FILE &&
+               git diff-files --name-only -z |
+               git update-index --remove -z --stdin
+       ) || exit
+       ;;
+,t)
+       save_index &&
+       git ls-files --error-unmatch -- "$@" >/dev/null || exit
+
+       git diff-files --name-only -z -- "$@"  |
+       (
+               cd_to_toplevel &&
+               GIT_INDEX_FILE="$NEXT_INDEX" &&
+               export GIT_INDEX_FILE &&
+               git update-index --remove -z --stdin
+       ) || exit
+       ;;
+,)
+       if test "$interactive" = t; then
+               git add --interactive || exit
+       fi
+       case "$#" in
+       0)
+               ;; # commit as-is
+       *)
+               if test -f "$GIT_DIR/MERGE_HEAD"
+               then
+                       refuse_partial "Cannot do a partial commit during a merge."
+               fi
+
+               TMP_INDEX="$GIT_DIR/tmp-index$$"
+               W=
+               test -z "$initial_commit" && W=--with-tree=HEAD
+               commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
+
+               # Build a temporary index and update the real index
+               # the same way.
+               if test -z "$initial_commit"
+               then
+                       GIT_INDEX_FILE="$THIS_INDEX" \
+                       git read-tree --index-output="$TMP_INDEX" -i -m HEAD
+               else
+                       rm -f "$TMP_INDEX"
+               fi || exit
+
+               printf '%s\n' "$commit_only" |
+               GIT_INDEX_FILE="$TMP_INDEX" \
+               git update-index --add --remove --stdin &&
+
+               save_index &&
+               printf '%s\n' "$commit_only" |
+               (
+                       GIT_INDEX_FILE="$NEXT_INDEX"
+                       export GIT_INDEX_FILE
+                       git update-index --add --remove --stdin
+               ) || exit
+               ;;
+       esac
+       ;;
+esac
+
+################################################################
+# If we do as-is commit, the index file will be THIS_INDEX,
+# otherwise NEXT_INDEX after we make this commit.  We leave
+# the index as is if we abort.
+
+if test -f "$NEXT_INDEX"
+then
+       USE_INDEX="$NEXT_INDEX"
+else
+       USE_INDEX="$THIS_INDEX"
+fi
+
+case "$status_only" in
+t)
+       # This will silently fail in a read-only repository, which is
+       # what we want.
+       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
+       run_status
+       exit $?
+       ;;
+'')
+       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
+       ;;
+esac
+
+################################################################
+# Grab commit message, write out tree and make commit.
+
+if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
+then
+    GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
+    || exit
+fi
+
+if test "$log_message" != ''
+then
+       printf '%s\n' "$log_message"
+elif test "$logfile" != ""
+then
+       if test "$logfile" = -
+       then
+               test -t 0 &&
+               echo >&2 "(reading log message from standard input)"
+               cat
+       else
+               cat <"$logfile"
+       fi
+elif test "$use_commit" != ""
+then
+       encoding=$(git config i18n.commitencoding || echo UTF-8)
+       git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
+       sed -e '1,/^$/d' -e 's/^    //'
+elif test -f "$GIT_DIR/MERGE_MSG"
+then
+       cat "$GIT_DIR/MERGE_MSG"
+elif test -f "$GIT_DIR/SQUASH_MSG"
+then
+       cat "$GIT_DIR/SQUASH_MSG"
+elif test "$templatefile" != ""
+then
+       cat "$templatefile"
+fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
+
+case "$signoff" in
+t)
+       sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
+               s/>.*/>/
+               s/^/Signed-off-by: /
+               ')
+       blank_before_signoff=
+       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+       grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
+'
+       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
+       grep "$sign"$ >/dev/null ||
+       printf '%s%s\n' "$blank_before_signoff" "$sign" \
+               >>"$GIT_DIR"/COMMIT_EDITMSG
+       ;;
+esac
+
+if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
+       echo "#"
+       echo "# It looks like you may be committing a MERGE."
+       echo "# If this is not correct, please remove the file"
+       printf '%s\n' "#        $GIT_DIR/MERGE_HEAD"
+       echo "# and try again"
+       echo "#"
+fi >>"$GIT_DIR"/COMMIT_EDITMSG
+
+# Author
+if test '' != "$use_commit"
+then
+       eval "$(get_author_ident_from_commit "$use_commit")"
+       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
+fi
+if test '' != "$force_author"
+then
+       GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
+       GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
+       test '' != "$GIT_AUTHOR_NAME" &&
+       test '' != "$GIT_AUTHOR_EMAIL" ||
+       die "malformed --author parameter"
+       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
+fi
+
+PARENTS="-p HEAD"
+if test -z "$initial_commit"
+then
+       rloga='commit'
+       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
+               rloga='commit (merge)'
+               PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
+       elif test -n "$amend"; then
+               rloga='commit (amend)'
+               PARENTS=$(git cat-file commit HEAD |
+                       sed -n -e '/^$/q' -e 's/^parent /-p /p')
+       fi
+       current="$(git rev-parse --verify HEAD)"
+else
+       if [ -z "$(git ls-files)" ]; then
+               echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
+               exit 1
+       fi
+       PARENTS=""
+       rloga='commit (initial)'
+       current=''
+fi
+set_reflog_action "$rloga"
+
+if test -z "$no_edit"
+then
+       {
+               echo ""
+               echo "# Please enter the commit message for your changes."
+               echo "# (Comment lines starting with '#' will not be included)"
+               test -z "$only_include_assumed" || echo "$only_include_assumed"
+               run_status
+       } >>"$GIT_DIR"/COMMIT_EDITMSG
+else
+       # we need to check if there is anything to commit
+       run_status >/dev/null
+fi
+case "$allow_empty,$?,$PARENTS" in
+t,* | ?,0,* | ?,*,-p' '?*-p' '?*)
+       # an explicit --allow-empty, or a merge commit can record the
+       # same tree as its parent.  Otherwise having commitable paths
+       # is required.
+       ;;
+*)
+       rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+       use_status_color=t
+       run_status
+       exit 1
+esac
+
+case "$no_edit" in
+'')
+       git-var GIT_AUTHOR_IDENT > /dev/null  || die
+       git-var GIT_COMMITTER_IDENT > /dev/null  || die
+       git_editor "$GIT_DIR/COMMIT_EDITMSG"
+       ;;
+esac
+
+case "$verify" in
+t)
+       if test -x "$GIT_DIR"/hooks/commit-msg
+       then
+               "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
+       fi
+esac
+
+if test -z "$no_edit"
+then
+    sed -e '
+        /^diff --git a\/.*/{
+           s///
+           q
+       }
+       /^#/d
+    ' "$GIT_DIR"/COMMIT_EDITMSG
+else
+    cat "$GIT_DIR"/COMMIT_EDITMSG
+fi |
+git stripspace >"$GIT_DIR"/COMMIT_MSG
+
+# Test whether the commit message has any content we didn't supply.
+have_commitmsg=
+grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
+       git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
+
+# Is the commit message totally empty?
+if test -s "$GIT_DIR"/COMMIT_BAREMSG
+then
+       if test "$templatefile" != ""
+       then
+               # Test whether this is just the unaltered template.
+               if cnt=`sed -e '/^#/d' < "$templatefile" |
+                       git stripspace |
+                       diff "$GIT_DIR"/COMMIT_BAREMSG - |
+                       wc -l` &&
+                  test 0 -lt $cnt
+               then
+                       have_commitmsg=t
+               fi
+       else
+               # No template, so the content in the commit message must
+               # have come from the user.
+               have_commitmsg=t
+       fi
+fi
+
+rm -f "$GIT_DIR"/COMMIT_BAREMSG
+
+if test "$have_commitmsg" = "t"
+then
+       if test -z "$TMP_INDEX"
+       then
+               tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
+       else
+               tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
+               rm -f "$TMP_INDEX"
+       fi &&
+       commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
+       rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
+       git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
+       rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
+       if test -f "$NEXT_INDEX"
+       then
+               mv "$NEXT_INDEX" "$THIS_INDEX"
+       else
+               : ;# happy
+       fi
+else
+       echo >&2 "* no commit message?  aborting commit."
+       false
+fi
+ret="$?"
+rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
+
+cd_to_toplevel
+
+git rerere
+
+if test "$ret" = 0
+then
+       git gc --auto
+       if test -x "$GIT_DIR"/hooks/post-commit
+       then
+               "$GIT_DIR"/hooks/post-commit
+       fi
+       if test -z "$quiet"
+       then
+               commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
+                      --summary --root HEAD --`
+               echo "Created${initial_commit:+ initial} commit $commit"
+       fi
+fi
+
+exit "$ret"
index 7a1c3e497f00fd886a0602551bfa933931a995be..9befb92c410794a3e81cc571b82f9f35e0def091 100755 (executable)
@@ -211,7 +211,7 @@ def getgitenv(user, date):
     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
old mode 100644 (file)
new mode 100755 (executable)
index 5838b3a..1cda19f
@@ -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
diff --git a/diff.c b/diff.c
index 6b54959610db604bfabc15e6edd2b212f16d0c62..f780e3e8e67f4b1e07ef1d70ab3b9f101ff6b868 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -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");
diff --git a/dir.c b/dir.c
index d448902909a7da216fbd49cecc505e68c0ba5e5f..6b3273d1d18298dc6cb8c08b42948af05c775221 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -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;
 }
 
 /*
index 1dab72ec1525ca6dd15ca20666cd91506b85890c..f3e3d4138d463520dbe6d709dfbe0803b619456d 100644 (file)
@@ -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;
index 2d0a75851284392aa8ae44bc486df6a034d0af13..e189caca629262334541ea8313d2931b06e67adf 100644 (file)
@@ -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);
index fb1e92a7664f77aa5ca4ca30b4711bafaf155466..0cdd80073bcbe0d9ffea30de85f9dda57f552e7f 100755 (executable)
@@ -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 @@ sub help_cmd {
 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();
+}
index 2e407084260350e7fa56987a7603afdcd00acfb5..65c634f77af98b3598bfb50583de05f0cf5d6eb4 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -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" ;;
index 7a6521ec3c62b04fe6d4c3e80c418ccc02b4ec65..5385249890698632dedcaf8dda03d865f66abca9 100755 (executable)
@@ -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-commit.sh b/git-commit.sh
deleted file mode 100755 (executable)
index 2c4a406..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Linus Torvalds
-# Copyright (c) 2006 Junio C Hamano
-
-USAGE='[-a | --interactive] [-s] [-v] [--no-verify] [-m <message> | -F <logfile> | (-C|-c) <commit> | --amend] [-u] [-e] [--author <author>] [--template <file>] [[-i | -o] <path>...]'
-SUBDIRECTORY_OK=Yes
-OPTIONS_SPEC=
-. git-sh-setup
-require_work_tree
-
-git rev-parse --verify HEAD >/dev/null 2>&1 || initial_commit=t
-
-case "$0" in
-*status)
-       status_only=t
-       ;;
-*commit)
-       status_only=
-       ;;
-esac
-
-refuse_partial () {
-       echo >&2 "$1"
-       echo >&2 "You might have meant to say 'git commit -i paths...', perhaps?"
-       exit 1
-}
-
-TMP_INDEX=
-THIS_INDEX="${GIT_INDEX_FILE:-$GIT_DIR/index}"
-NEXT_INDEX="$GIT_DIR/next-index$$"
-rm -f "$NEXT_INDEX"
-save_index () {
-       cp -p "$THIS_INDEX" "$NEXT_INDEX"
-}
-
-run_status () {
-       # If TMP_INDEX is defined, that means we are doing
-       # "--only" partial commit, and that index file is used
-       # to build the tree for the commit.  Otherwise, if
-       # NEXT_INDEX exists, that is the index file used to
-       # make the commit.  Otherwise we are using as-is commit
-       # so the regular index file is what we use to compare.
-       if test '' != "$TMP_INDEX"
-       then
-               GIT_INDEX_FILE="$TMP_INDEX"
-               export GIT_INDEX_FILE
-       elif test -f "$NEXT_INDEX"
-       then
-               GIT_INDEX_FILE="$NEXT_INDEX"
-               export GIT_INDEX_FILE
-       fi
-
-       if test "$status_only" = "t" -o "$use_status_color" = "t"; then
-               color=
-       else
-               color=--nocolor
-       fi
-       git runstatus ${color} \
-               ${verbose:+--verbose} \
-               ${amend:+--amend} \
-               ${untracked_files:+--untracked}
-}
-
-trap '
-       test -z "$TMP_INDEX" || {
-               test -f "$TMP_INDEX" && rm -f "$TMP_INDEX"
-       }
-       rm -f "$NEXT_INDEX"
-' 0
-
-################################################################
-# Command line argument parsing and sanity checking
-
-all=
-also=
-allow_empty=f
-interactive=
-only=
-logfile=
-use_commit=
-amend=
-edit_flag=
-no_edit=
-log_given=
-log_message=
-verify=t
-quiet=
-verbose=
-signoff=
-force_author=
-only_include_assumed=
-untracked_files=
-templatefile="`git config commit.template`"
-while test $# != 0
-do
-       case "$1" in
-       -F|--F|-f|--f|--fi|--fil|--file)
-               case "$#" in 1) usage ;; esac
-               shift
-               no_edit=t
-               log_given=t$log_given
-               logfile="$1"
-               ;;
-       -F*|-f*)
-               no_edit=t
-               log_given=t$log_given
-               logfile="${1#-[Ff]}"
-               ;;
-       --F=*|--f=*|--fi=*|--fil=*|--file=*)
-               no_edit=t
-               log_given=t$log_given
-               logfile="${1#*=}"
-               ;;
-       -a|--a|--al|--all)
-               all=t
-               ;;
-       --allo|--allow|--allow-|--allow-e|--allow-em|--allow-emp|\
-       --allow-empt|--allow-empty)
-               allow_empty=t
-               ;;
-       --au=*|--aut=*|--auth=*|--autho=*|--author=*)
-               force_author="${1#*=}"
-               ;;
-       --au|--aut|--auth|--autho|--author)
-               case "$#" in 1) usage ;; esac
-               shift
-               force_author="$1"
-               ;;
-       -e|--e|--ed|--edi|--edit)
-               edit_flag=t
-               ;;
-       -i|--i|--in|--inc|--incl|--inclu|--includ|--include)
-               also=t
-               ;;
-       --int|--inte|--inter|--intera|--interac|--interact|--interacti|\
-       --interactiv|--interactive)
-               interactive=t
-               ;;
-       -o|--o|--on|--onl|--only)
-               only=t
-               ;;
-       -m|--m|--me|--mes|--mess|--messa|--messag|--message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}$1"
-               no_edit=t
-               ;;
-       -m*)
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}${1#-m}"
-               no_edit=t
-               ;;
-       --m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
-               log_given=m$log_given
-               log_message="${log_message:+${log_message}
-
-}${1#*=}"
-               no_edit=t
-               ;;
-       -n|--n|--no|--no-|--no-v|--no-ve|--no-ver|--no-veri|--no-verif|\
-       --no-verify)
-               verify=
-               ;;
-       --a|--am|--ame|--amen|--amend)
-               amend=t
-               use_commit=HEAD
-               ;;
-       -c)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=
-               ;;
-       --ree=*|--reed=*|--reedi=*|--reedit=*|--reedit-=*|--reedit-m=*|\
-       --reedit-me=*|--reedit-mes=*|--reedit-mess=*|--reedit-messa=*|\
-       --reedit-messag=*|--reedit-message=*)
-               log_given=t$log_given
-               use_commit="${1#*=}"
-               no_edit=
-               ;;
-       --ree|--reed|--reedi|--reedit|--reedit-|--reedit-m|--reedit-me|\
-       --reedit-mes|--reedit-mess|--reedit-messa|--reedit-messag|\
-       --reedit-message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=
-               ;;
-       -C)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=t
-               ;;
-       --reu=*|--reus=*|--reuse=*|--reuse-=*|--reuse-m=*|--reuse-me=*|\
-       --reuse-mes=*|--reuse-mess=*|--reuse-messa=*|--reuse-messag=*|\
-       --reuse-message=*)
-               log_given=t$log_given
-               use_commit="${1#*=}"
-               no_edit=t
-               ;;
-       --reu|--reus|--reuse|--reuse-|--reuse-m|--reuse-me|--reuse-mes|\
-       --reuse-mess|--reuse-messa|--reuse-messag|--reuse-message)
-               case "$#" in 1) usage ;; esac
-               shift
-               log_given=t$log_given
-               use_commit="$1"
-               no_edit=t
-               ;;
-       -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
-               signoff=t
-               ;;
-       -t|--t|--te|--tem|--temp|--templ|--templa|--templat|--template)
-               case "$#" in 1) usage ;; esac
-               shift
-               templatefile="$1"
-               no_edit=
-               ;;
-       -q|--q|--qu|--qui|--quie|--quiet)
-               quiet=t
-               ;;
-       -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
-               verbose=t
-               ;;
-       -u|--u|--un|--unt|--untr|--untra|--untrac|--untrack|--untracke|\
-       --untracked|--untracked-|--untracked-f|--untracked-fi|--untracked-fil|\
-       --untracked-file|--untracked-files)
-               untracked_files=t
-               ;;
-       --)
-               shift
-               break
-               ;;
-       -*)
-               usage
-               ;;
-       *)
-               break
-               ;;
-       esac
-       shift
-done
-case "$edit_flag" in t) no_edit= ;; esac
-
-################################################################
-# Sanity check options
-
-case "$amend,$initial_commit" in
-t,t)
-       die "You do not have anything to amend." ;;
-t,)
-       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-               die "You are in the middle of a merge -- cannot amend."
-       fi ;;
-esac
-
-case "$log_given" in
-tt*)
-       die "Only one of -c/-C/-F can be used." ;;
-*tm*|*mt*)
-       die "Option -m cannot be combined with -c/-C/-F." ;;
-esac
-
-case "$#,$also,$only,$amend" in
-*,t,t,*)
-       die "Only one of --include/--only can be used." ;;
-0,t,,* | 0,,t,)
-       die "No paths with --include/--only does not make sense." ;;
-0,,t,t)
-       only_include_assumed="# Clever... amending the last one with dirty index." ;;
-0,,,*)
-       ;;
-*,,,*)
-       only_include_assumed="# Explicit paths specified without -i nor -o; assuming --only paths..."
-       also=
-       ;;
-esac
-unset only
-case "$all,$interactive,$also,$#" in
-*t,*t,*)
-       die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,,[1-9]*)
-       die "Paths with -a does not make sense." ;;
-,t,,[1-9]*)
-       die "Paths with --interactive does not make sense." ;;
-,,t,0)
-       die "No paths with -i does not make sense." ;;
-esac
-
-if test ! -z "$templatefile" -a -z "$log_given"
-then
-       if test ! -f "$templatefile"
-       then
-               die "Commit template file does not exist."
-       fi
-fi
-
-################################################################
-# Prepare index to have a tree to be committed
-
-case "$all,$also" in
-t,)
-       if test ! -f "$THIS_INDEX"
-       then
-               die 'nothing to commit (use "git add file1 file2" to include for commit)'
-       fi
-       save_index &&
-       (
-               cd_to_toplevel &&
-               GIT_INDEX_FILE="$NEXT_INDEX" &&
-               export GIT_INDEX_FILE &&
-               git diff-files --name-only -z |
-               git update-index --remove -z --stdin
-       ) || exit
-       ;;
-,t)
-       save_index &&
-       git ls-files --error-unmatch -- "$@" >/dev/null || exit
-
-       git diff-files --name-only -z -- "$@"  |
-       (
-               cd_to_toplevel &&
-               GIT_INDEX_FILE="$NEXT_INDEX" &&
-               export GIT_INDEX_FILE &&
-               git update-index --remove -z --stdin
-       ) || exit
-       ;;
-,)
-       if test "$interactive" = t; then
-               git add --interactive || exit
-       fi
-       case "$#" in
-       0)
-               ;; # commit as-is
-       *)
-               if test -f "$GIT_DIR/MERGE_HEAD"
-               then
-                       refuse_partial "Cannot do a partial commit during a merge."
-               fi
-
-               TMP_INDEX="$GIT_DIR/tmp-index$$"
-               W=
-               test -z "$initial_commit" && W=--with-tree=HEAD
-               commit_only=`git ls-files --error-unmatch $W -- "$@"` || exit
-
-               # Build a temporary index and update the real index
-               # the same way.
-               if test -z "$initial_commit"
-               then
-                       GIT_INDEX_FILE="$THIS_INDEX" \
-                       git read-tree --index-output="$TMP_INDEX" -i -m HEAD
-               else
-                       rm -f "$TMP_INDEX"
-               fi || exit
-
-               printf '%s\n' "$commit_only" |
-               GIT_INDEX_FILE="$TMP_INDEX" \
-               git update-index --add --remove --stdin &&
-
-               save_index &&
-               printf '%s\n' "$commit_only" |
-               (
-                       GIT_INDEX_FILE="$NEXT_INDEX"
-                       export GIT_INDEX_FILE
-                       git update-index --add --remove --stdin
-               ) || exit
-               ;;
-       esac
-       ;;
-esac
-
-################################################################
-# If we do as-is commit, the index file will be THIS_INDEX,
-# otherwise NEXT_INDEX after we make this commit.  We leave
-# the index as is if we abort.
-
-if test -f "$NEXT_INDEX"
-then
-       USE_INDEX="$NEXT_INDEX"
-else
-       USE_INDEX="$THIS_INDEX"
-fi
-
-case "$status_only" in
-t)
-       # This will silently fail in a read-only repository, which is
-       # what we want.
-       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --unmerged --refresh
-       run_status
-       exit $?
-       ;;
-'')
-       GIT_INDEX_FILE="$USE_INDEX" git update-index -q --refresh || exit
-       ;;
-esac
-
-################################################################
-# Grab commit message, write out tree and make commit.
-
-if test t = "$verify" && test -x "$GIT_DIR"/hooks/pre-commit
-then
-    GIT_INDEX_FILE="${TMP_INDEX:-${USE_INDEX}}" "$GIT_DIR"/hooks/pre-commit \
-    || exit
-fi
-
-if test "$log_message" != ''
-then
-       printf '%s\n' "$log_message"
-elif test "$logfile" != ""
-then
-       if test "$logfile" = -
-       then
-               test -t 0 &&
-               echo >&2 "(reading log message from standard input)"
-               cat
-       else
-               cat <"$logfile"
-       fi
-elif test "$use_commit" != ""
-then
-       encoding=$(git config i18n.commitencoding || echo UTF-8)
-       git show -s --pretty=raw --encoding="$encoding" "$use_commit" |
-       sed -e '1,/^$/d' -e 's/^    //'
-elif test -f "$GIT_DIR/MERGE_MSG"
-then
-       cat "$GIT_DIR/MERGE_MSG"
-elif test -f "$GIT_DIR/SQUASH_MSG"
-then
-       cat "$GIT_DIR/SQUASH_MSG"
-elif test "$templatefile" != ""
-then
-       cat "$templatefile"
-fi | git stripspace >"$GIT_DIR"/COMMIT_EDITMSG
-
-case "$signoff" in
-t)
-       sign=$(git-var GIT_COMMITTER_IDENT | sed -e '
-               s/>.*/>/
-               s/^/Signed-off-by: /
-               ')
-       blank_before_signoff=
-       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
-       grep 'Signed-off-by:' >/dev/null || blank_before_signoff='
-'
-       tail -n 1 "$GIT_DIR"/COMMIT_EDITMSG |
-       grep "$sign"$ >/dev/null ||
-       printf '%s%s\n' "$blank_before_signoff" "$sign" \
-               >>"$GIT_DIR"/COMMIT_EDITMSG
-       ;;
-esac
-
-if test -f "$GIT_DIR/MERGE_HEAD" && test -z "$no_edit"; then
-       echo "#"
-       echo "# It looks like you may be committing a MERGE."
-       echo "# If this is not correct, please remove the file"
-       printf '%s\n' "#        $GIT_DIR/MERGE_HEAD"
-       echo "# and try again"
-       echo "#"
-fi >>"$GIT_DIR"/COMMIT_EDITMSG
-
-# Author
-if test '' != "$use_commit"
-then
-       eval "$(get_author_ident_from_commit "$use_commit")"
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
-fi
-if test '' != "$force_author"
-then
-       GIT_AUTHOR_NAME=`expr "z$force_author" : 'z\(.*[^ ]\) *<.*'` &&
-       GIT_AUTHOR_EMAIL=`expr "z$force_author" : '.*\(<.*\)'` &&
-       test '' != "$GIT_AUTHOR_NAME" &&
-       test '' != "$GIT_AUTHOR_EMAIL" ||
-       die "malformed --author parameter"
-       export GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL
-fi
-
-PARENTS="-p HEAD"
-if test -z "$initial_commit"
-then
-       rloga='commit'
-       if [ -f "$GIT_DIR/MERGE_HEAD" ]; then
-               rloga='commit (merge)'
-               PARENTS="-p HEAD "`sed -e 's/^/-p /' "$GIT_DIR/MERGE_HEAD"`
-       elif test -n "$amend"; then
-               rloga='commit (amend)'
-               PARENTS=$(git cat-file commit HEAD |
-                       sed -n -e '/^$/q' -e 's/^parent /-p /p')
-       fi
-       current="$(git rev-parse --verify HEAD)"
-else
-       if [ -z "$(git ls-files)" ]; then
-               echo >&2 'nothing to commit (use "git add file1 file2" to include for commit)'
-               exit 1
-       fi
-       PARENTS=""
-       rloga='commit (initial)'
-       current=''
-fi
-set_reflog_action "$rloga"
-
-if test -z "$no_edit"
-then
-       {
-               echo ""
-               echo "# Please enter the commit message for your changes."
-               echo "# (Comment lines starting with '#' will not be included)"
-               test -z "$only_include_assumed" || echo "$only_include_assumed"
-               run_status
-       } >>"$GIT_DIR"/COMMIT_EDITMSG
-else
-       # we need to check if there is anything to commit
-       run_status >/dev/null
-fi
-case "$allow_empty,$?,$PARENTS" in
-t,* | ?,0,* | ?,*,-p' '?*-p' '?*)
-       # an explicit --allow-empty, or a merge commit can record the
-       # same tree as its parent.  Otherwise having commitable paths
-       # is required.
-       ;;
-*)
-       rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-       use_status_color=t
-       run_status
-       exit 1
-esac
-
-case "$no_edit" in
-'')
-       git-var GIT_AUTHOR_IDENT > /dev/null  || die
-       git-var GIT_COMMITTER_IDENT > /dev/null  || die
-       git_editor "$GIT_DIR/COMMIT_EDITMSG"
-       ;;
-esac
-
-case "$verify" in
-t)
-       if test -x "$GIT_DIR"/hooks/commit-msg
-       then
-               "$GIT_DIR"/hooks/commit-msg "$GIT_DIR"/COMMIT_EDITMSG || exit
-       fi
-esac
-
-if test -z "$no_edit"
-then
-    sed -e '
-        /^diff --git a\/.*/{
-           s///
-           q
-       }
-       /^#/d
-    ' "$GIT_DIR"/COMMIT_EDITMSG
-else
-    cat "$GIT_DIR"/COMMIT_EDITMSG
-fi |
-git stripspace >"$GIT_DIR"/COMMIT_MSG
-
-# Test whether the commit message has any content we didn't supply.
-have_commitmsg=
-grep -v -i '^Signed-off-by' "$GIT_DIR"/COMMIT_MSG |
-       git stripspace > "$GIT_DIR"/COMMIT_BAREMSG
-
-# Is the commit message totally empty?
-if test -s "$GIT_DIR"/COMMIT_BAREMSG
-then
-       if test "$templatefile" != ""
-       then
-               # Test whether this is just the unaltered template.
-               if cnt=`sed -e '/^#/d' < "$templatefile" |
-                       git stripspace |
-                       diff "$GIT_DIR"/COMMIT_BAREMSG - |
-                       wc -l` &&
-                  test 0 -lt $cnt
-               then
-                       have_commitmsg=t
-               fi
-       else
-               # No template, so the content in the commit message must
-               # have come from the user.
-               have_commitmsg=t
-       fi
-fi
-
-rm -f "$GIT_DIR"/COMMIT_BAREMSG
-
-if test "$have_commitmsg" = "t"
-then
-       if test -z "$TMP_INDEX"
-       then
-               tree=$(GIT_INDEX_FILE="$USE_INDEX" git write-tree)
-       else
-               tree=$(GIT_INDEX_FILE="$TMP_INDEX" git write-tree) &&
-               rm -f "$TMP_INDEX"
-       fi &&
-       commit=$(git commit-tree $tree $PARENTS <"$GIT_DIR/COMMIT_MSG") &&
-       rlogm=$(sed -e 1q "$GIT_DIR"/COMMIT_MSG) &&
-       git update-ref -m "$GIT_REFLOG_ACTION: $rlogm" HEAD $commit "$current" &&
-       rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" &&
-       if test -f "$NEXT_INDEX"
-       then
-               mv "$NEXT_INDEX" "$THIS_INDEX"
-       else
-               : ;# happy
-       fi
-else
-       echo >&2 "* no commit message?  aborting commit."
-       false
-fi
-ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
-
-cd_to_toplevel
-
-git rerere
-
-if test "$ret" = 0
-then
-       git gc --auto
-       if test -x "$GIT_DIR"/hooks/post-commit
-       then
-               "$GIT_DIR"/hooks/post-commit
-       fi
-       if test -z "$quiet"
-       then
-               commit=`git diff-tree --always --shortstat --pretty="format:%h: %s"\
-                      --summary --root HEAD --`
-               echo "Created${initial_commit:+ initial} commit $commit"
-       fi
-fi
-
-exit "$ret"
index 0d55fec04fa7e3e2a02987543a857a26ae1f96cb..ecded3b9cba9e18117f7372af37e9b56203a6fcf 100755 (executable)
@@ -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 ...
index e8603192788fb0d8c83ff5ad33eb947cd77252b4..26ac4b6bb0e974130ae84f4e35e1464f8b08e202 100644 (file)
@@ -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 \
index 10b0430f54863111268a4b67364cbc678b0eb50d..b2d2d5308609fc26d10bf5a300fbf372fb3c52af 100644 (file)
@@ -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.
 "]
index 563dd66238c1a5c169438fdb87ab797f6d19d1bc..334cfa5a1a59c320e86789ccf4ed3320584a0215 100644 (file)
Binary files a/git-gui/lib/git-gui.ico and b/git-gui/lib/git-gui.ico differ
index 3df30edb871164e2374ee004f511642ae7aaec43..ac8ae0a205b3adbd2558e6cd61a0d9168c1e79c8 100644 (file)
@@ -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)"
index 00f0f5922a9f6b01730158a33213220557a48f0c..dfa48ae26364b5d30a810bfa9b55984bba582692 100644 (file)
@@ -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 ""
 
index 8e3d9a2f07b10f41d0b534158c91621310fc7b0f..bb46b48d6b84446a23c14af88c339fda7e417718 100644 (file)
@@ -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"
index e8c04f7aeae959bfd103cded105202883065d9ca..627c05eb99431183cdea5bf6cd87e650f6d9ff8c 100644 (file)
@@ -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)"
index 766841410404d03b80678a9133a79d1bf8d8d97d..33a8399175984cd01531cc2fedc066a4daaa1e5a 100644 (file)
@@ -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"
-
index f3a547b1b95ca054a0319e05ab2a7af0d94a4da2..e2cf5bdc06de45d634b6cac583cbc0e4cafb94d6 100644 (file)
@@ -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 "タグを含める"
-
index 5587c5ecea0f6a97f2715636890c9e2f89845d52..2f31fa2417300180662b66afdde11bdf1d6febb2 100755 (executable)
@@ -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"
index 76baa8e431e082c1e36eb9c78125094de0b8a85e..c0e1dd348c1f62029bb99b16cae290d2e4a77217 100755 (executable)
@@ -367,10 +367,11 @@ sub expand_aliases {
        } 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 $_) {
index 82ac28fa27dc41b821905f1a83155994d56c4f3b..ad9fe628fdf0f7d5a9a968abeb03d6213e3772d7 100755 (executable)
@@ -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"
diff --git a/git.c b/git.c
index f510fe37069a5b11dfef445f862da9f52337d172..15fec8974ad5361a2308b3c46424e896bc8e3246 100644 (file)
--- a/git.c
+++ b/git.c
@@ -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 },
index ff5daa7901d9976dc35e1b4a05e1cf0140297d6a..24b31582afbc78415a5ce34acf06e0d589be0f91 100755 (executable)
@@ -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);
        }
diff --git a/help.c b/help.c
index ec0d0155ac79051c3fcfbbbc72db1ea32404e069..56477f4506a94905c58dad09543bfbb68db61d91 100644 (file)
--- a/help.c
+++ b/help.c
@@ -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);
 }
 
diff --git a/http.c b/http.c
index 87ebf7b86548d229afbfd9263d2470296a7b2ac7..146f62609dbf75cf8b6d873f040e1386d73b57d1 100644 (file)
--- a/http.c
+++ b/http.c
@@ -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;
 }
 
diff --git a/http.h b/http.h
index 72abac20f856b45c873cc370f23c7df08b650370..fe1b0d153bcd80d12a405c26e0f073cbf14dde34 100644 (file)
--- a/http.h
+++ b/http.h
@@ -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 */
diff --git a/ident.c b/ident.c
index 9b2a852cb00327a607946caa864fcf31184da28e..892d77ac9366978fcb172e0d258410f271631012 100644 (file)
--- a/ident.c
+++ b/ident.c
@@ -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);
 }
index 87141670595c50a4fa7b87a12b85ff0e2b7da8af..f0172552e4c42c1526e2395802a41070d43cadae 100644 (file)
--- a/mailmap.c
+++ b/mailmap.c
@@ -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);
index 7468460f9a6d29d5c4bf14db4921bf28e23b6814..a2812ea612b997c1a76d89075dd1263a3af4fd37 100644 (file)
@@ -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 )
diff --git a/quote.c b/quote.c
index 04557833a561b4613a511af8fb9f0fb18b36b2fa..6986b4420f66e1f01cd4517d35ce9adc300eaa8b 100644 (file)
--- a/quote.c
+++ b/quote.c
@@ -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)
diff --git a/quote.h b/quote.h
index 42879909983679f31b9ac6d7e5bfc330d8167a91..ab7596f57b7f23899ef1bbb8d0c7ba6ec5baf12f 100644 (file)
--- a/quote.h
+++ b/quote.h
@@ -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
diff --git a/refs.c b/refs.c
index 54ec98d153889f40313dba9a5ee8f07ddd0e160a..759924d0c93621d72918f29145ae0377f34e8e0c 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -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",
index bb010590837fd6ea188e64c5263bb1fe12ab93f4..3fb0f99b29e7ffd927abf166cfa004c1937aaf60 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -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;
index b10036cae6f89e087da56979e2248e1e5c5d42d3..86e036d61006a577ad091bdc30e58987871415b0 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -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);
diff --git a/setup.c b/setup.c
index 2c7b5cb200414a0fa3f2727c68ea60e51b39c261..b59dbe7f51e8ffcbf2721d2ec7201400830e6830 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -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) {
index 2d727d54dc43c23cb2fe19369d58e57e2a020ca9..13e11645e1fd6b61812cc3e88d2ad6cd42cad9ce 100644 (file)
@@ -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);
index 13919123dc5261e7b8e4a4fdfc696f2355482b6c..36d61db65728f61188ef3bedbdbe88d0f2d9a0b9 100644 (file)
--- a/strbuf.h
+++ b/strbuf.h
@@ -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 */
index b14b3ec39418b37a2a7e4b3745032360c146dff7..c015405f124f738e66213987c3ba88c7d310caab 100755 (executable)
@@ -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 (executable)
index 0000000..37fc1c8
--- /dev/null
@@ -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
index ae0639d8f3a3fa428dca31df55193487a74b5b57..e25b25568337ae36a5ef1377a14df031d5dfaeb1 100755 (executable)
@@ -86,7 +86,7 @@ EOF
 
 git config core.excludesFile excludes-file
 
-git runstatus | grep "^#       " > output
+git status | grep "^#  " > output
 
 cat > expect << EOF
 #      .gitignore
index 2fe50bc7ce050f32affa287c5c6e3ab7b1a66f45..a32692417db73444dbdc143e6908b7371be79d42 100755 (executable)
@@ -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 (executable)
index 0000000..67e080b
--- /dev/null
@@ -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 (executable)
index 0000000..85f3da2
--- /dev/null
@@ -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
index 35889c0a125fffdfb556ec521d61c18ac4e96c17..02882c1e4bdcef725b3575ccee6fb298f01c21b4 100755 (executable)
@@ -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
index 987c9d21caf2a3d7653157f5e6d74f0841863c8b..9d2dc33cbd0d1df19b0a9003e545104a982da694 100755 (executable)
@@ -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 &&
index c722635050fed8011c04177dc5a8220cae12a843..8a23aaf21b1977fab66aa2989cac56635251ecb6 100755 (executable)
@@ -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
index f013c176ed910d278cbb886004429869f288ebc7..dfd118878fd37c096ccd426aa01fa2ac36581367 100755 (executable)
@@ -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 &&
index cf389b81da041e6bcbc7d20cd367b4274001353f..baed6ce96beb260a32e027dd573313c82202ea7b 100755 (executable)
@@ -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
index 0316ecf5a16792f226725eb9626ad77c369877bb..05aa97d6f3d3a87d94004b9f9f4394d8e35175f6 100755 (executable)
@@ -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 (executable)
index 0000000..21ac785
--- /dev/null
@@ -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 (executable)
index 0000000..9ce50ca
--- /dev/null
@@ -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 (executable)
index 0000000..d787cac
--- /dev/null
@@ -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 (executable)
index 0000000..751b113
--- /dev/null
@@ -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
index e9c9fe65d0a7cc01323480facdcaba233b57f564..f09bfb1117caa05981d65e45fe2a9cc4c7ca19f3 100755 (executable)
@@ -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
 
 '
index 08f0f2a3a34d4d5e3bf45216f5d824854894f2f1..7706430d81e62e70d7124234e89b54fc65caa7d5 100755 (executable)
@@ -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
index 6f4dbd362fffdd85570c2223ad7d98015e7970ae..ebd3a62fd866453ad77406ec063b923e99ee0990 100644 (file)
@@ -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 -)
diff --git a/trace.c b/trace.c
index d3d1b6d55e86aab94ddb9712f5eee743b3bfa9a8..4713f9165c54405d51e81c3e90847120ee907e5d 100644 (file)
--- a/trace.c
+++ b/trace.c
@@ -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);
index 50db9807d003162c81f391e08f247bac7ce410c9..58e66f6c11798dac416941ce5ad3dbae91c31a06 100644 (file)
@@ -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)
diff --git a/var.c b/var.c
index 4127031910c83987c8ef394e3711942e2db8a8f9..0de0efa2aa3b216a0bc846135a54ed0dd0549f8b 100644 (file)
--- a/var.c
+++ b/var.c
@@ -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;
                }
        }
diff --git a/ws.c b/ws.c
new file mode 100644 (file)
index 0000000..52c10ca
--- /dev/null
+++ b/ws.c
@@ -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;
+       }
+}
index bf2fe8d237b51e87d40dbe60eb70f485273083ff..51c18796915c0a9e052806eadd460b0f9afa7fee 100644 (file)
@@ -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);
 }
index 77449326dbec5c3f83559c300aec2922445829ef..63d50f2871f51d4363afa2f7bbb21c81186b9f44 100644 (file)
@@ -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);