aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/Makefile10
-rw-r--r--Documentation/RelNotes-1.5.3.6.txt45
-rw-r--r--Documentation/RelNotes-1.5.4.txt44
-rw-r--r--Documentation/asciidoc.conf3
-rw-r--r--Documentation/config.txt14
-rw-r--r--Documentation/core-tutorial.txt4
-rw-r--r--Documentation/diff-options.txt24
-rw-r--r--Documentation/git-add.txt1
-rw-r--r--Documentation/git-clone.txt1
-rw-r--r--Documentation/git-commit.txt11
-rw-r--r--Documentation/git-cvsexportcommit.txt22
-rw-r--r--Documentation/git-diff.txt1
-rw-r--r--Documentation/git-format-patch.txt14
-rw-r--r--Documentation/git-get-tar-commit-id.txt4
-rw-r--r--Documentation/git-ls-files.txt5
-rw-r--r--Documentation/git-reflog.txt15
-rw-r--r--Documentation/git-remote.txt4
-rw-r--r--Documentation/git-rev-list.txt9
-rw-r--r--Documentation/git-rev-parse.txt76
-rw-r--r--Documentation/git-svn.txt6
-rw-r--r--Documentation/git.txt1
-rw-r--r--Documentation/gitattributes.txt17
-rw-r--r--Documentation/howto/maintain-git.txt277
-rw-r--r--Documentation/urls.txt6
-rw-r--r--Documentation/user-manual.txt89
-rw-r--r--Makefile16
-rw-r--r--builtin-add.c24
-rw-r--r--builtin-apply.c3
-rw-r--r--builtin-blame.c10
-rw-r--r--builtin-branch.c44
-rw-r--r--builtin-clean.c153
-rw-r--r--builtin-config.c4
-rw-r--r--builtin-diff-files.c4
-rw-r--r--builtin-diff-index.c4
-rw-r--r--builtin-diff-tree.c7
-rw-r--r--builtin-diff.c12
-rw-r--r--builtin-fetch--tool.c8
-rw-r--r--builtin-fetch-pack.c42
-rw-r--r--builtin-fetch.c104
-rw-r--r--builtin-fmt-merge-msg.c2
-rw-r--r--builtin-for-each-ref.c19
-rw-r--r--builtin-grep.c6
-rw-r--r--builtin-init-db.c16
-rw-r--r--builtin-log.c166
-rw-r--r--builtin-ls-files.c9
-rw-r--r--builtin-merge-ours.c28
-rw-r--r--builtin-pack-objects.c2
-rw-r--r--builtin-pack-refs.c12
-rw-r--r--builtin-rev-list.c42
-rw-r--r--builtin-rev-parse.c128
-rw-r--r--builtin-revert.c2
-rw-r--r--builtin-tag.c38
-rw-r--r--builtin.h2
-rw-r--r--bundle.c9
-rw-r--r--cache.h17
-rw-r--r--check-racy.c2
-rw-r--r--combine-diff.c10
-rw-r--r--commit.c150
-rw-r--r--commit.h25
-rw-r--r--config.c27
-rw-r--r--config.mak.in3
-rw-r--r--configure.ac18
-rwxr-xr-xcontrib/examples/git-clean.sh (renamed from git-clean.sh)45
-rwxr-xr-xcontrib/examples/git-merge-ours.sh (renamed from git-merge-ours.sh)0
-rwxr-xr-xcontrib/fast-import/git-p417
-rwxr-xr-xcontrib/gitview/gitview17
-rw-r--r--csum-file.c18
-rw-r--r--csum-file.h7
-rw-r--r--diff-lib.c44
-rw-r--r--diff.c223
-rw-r--r--diff.h46
-rw-r--r--dir.c18
-rw-r--r--dir.h1
-rw-r--r--entry.c2
-rw-r--r--environment.c1
-rw-r--r--fast-import.c20
-rwxr-xr-xgit-add--interactive.perl11
-rwxr-xr-xgit-am.sh94
-rwxr-xr-xgit-bisect.sh34
-rwxr-xr-xgit-checkout.sh105
-rwxr-xr-xgit-clone.sh101
-rwxr-xr-xgit-commit.sh7
-rw-r--r--git-compat-util.h41
-rwxr-xr-xgit-cvsexportcommit.perl39
-rwxr-xr-xgit-cvsimport.perl3
-rwxr-xr-xgit-filter-branch.sh1
-rw-r--r--git-gui/.gitignore5
-rwxr-xr-xgit-gui/GIT-VERSION-GEN2
-rw-r--r--git-gui/Makefile190
-rwxr-xr-xgit-gui/git-gui.sh723
-rw-r--r--git-gui/lib/about.tcl81
-rw-r--r--git-gui/lib/blame.tcl54
-rw-r--r--git-gui/lib/branch_checkout.tcl16
-rw-r--r--git-gui/lib/branch_create.tcl38
-rw-r--r--git-gui/lib/branch_delete.tcl22
-rw-r--r--git-gui/lib/branch_rename.tcl22
-rw-r--r--git-gui/lib/browser.tcl22
-rw-r--r--git-gui/lib/checkout_op.tcl54
-rw-r--r--git-gui/lib/choose_repository.tcl1044
-rw-r--r--git-gui/lib/choose_rev.tcl34
-rw-r--r--git-gui/lib/commit.tcl56
-rw-r--r--git-gui/lib/console.tcl91
-rw-r--r--git-gui/lib/database.tcl34
-rw-r--r--git-gui/lib/date.tcl53
-rw-r--r--git-gui/lib/diff.tcl29
-rw-r--r--git-gui/lib/error.tcl8
-rw-r--r--git-gui/lib/git-gui.icobin0 -> 318 bytes
-rw-r--r--git-gui/lib/index.tcl140
-rw-r--r--git-gui/lib/logo.tcl43
-rw-r--r--git-gui/lib/merge.tcl60
-rw-r--r--git-gui/lib/option.tcl131
-rw-r--r--git-gui/lib/remote.tcl53
-rw-r--r--git-gui/lib/remote_branch_delete.tcl46
-rw-r--r--git-gui/lib/shortcut.tcl57
-rw-r--r--git-gui/lib/status_bar.tcl38
-rw-r--r--git-gui/lib/transport.tcl48
-rw-r--r--git-gui/lib/win32.tcl26
-rw-r--r--git-gui/lib/win32_shortcut.js34
-rw-r--r--git-gui/macosx/AppMain.tcl22
-rw-r--r--git-gui/macosx/Info.plist28
-rw-r--r--git-gui/macosx/git-gui.icnsbin0 -> 28866 bytes
-rw-r--r--git-gui/po/.gitignore2
-rw-r--r--git-gui/po/README209
-rw-r--r--git-gui/po/de.po1878
-rw-r--r--git-gui/po/git-gui.pot1704
-rw-r--r--git-gui/po/glossary/Makefile9
-rw-r--r--git-gui/po/glossary/de.po185
-rw-r--r--git-gui/po/glossary/git-gui-glossary.pot164
-rw-r--r--git-gui/po/glossary/git-gui-glossary.txt37
-rw-r--r--git-gui/po/glossary/it.po180
-rwxr-xr-xgit-gui/po/glossary/txt-to-pot.sh48
-rw-r--r--git-gui/po/glossary/zh_cn.po170
-rw-r--r--git-gui/po/hu.po1895
-rw-r--r--git-gui/po/it.po1872
-rw-r--r--git-gui/po/ja.po1843
-rw-r--r--git-gui/po/po2msg.sh133
-rw-r--r--git-gui/po/ru.po1893
-rw-r--r--git-gui/po/zh_cn.po1769
-rw-r--r--git-gui/windows/git-gui.sh16
-rwxr-xr-xgit-instaweb.sh74
-rwxr-xr-xgit-lost-found.sh1
-rwxr-xr-xgit-merge.sh137
-rwxr-xr-xgit-mergetool.sh1
-rwxr-xr-xgit-pull.sh1
-rwxr-xr-xgit-quiltimport.sh39
-rwxr-xr-xgit-rebase--interactive.sh15
-rwxr-xr-xgit-rebase.sh64
-rwxr-xr-xgit-repack.sh24
-rwxr-xr-xgit-request-pull.sh1
-rwxr-xr-xgit-send-email.perl48
-rwxr-xr-xgit-sh-setup.sh52
-rwxr-xr-xgit-stash.sh35
-rwxr-xr-xgit-submodule.sh1
-rwxr-xr-xgit-svn.perl326
-rw-r--r--git.c6
-rw-r--r--gitweb/gitweb.css8
-rwxr-xr-xgitweb/gitweb.perl26
-rw-r--r--help.c1
-rw-r--r--index-pack.c14
-rw-r--r--lockfile.c17
-rw-r--r--log-tree.c6
-rw-r--r--merge-recursive.c2
-rw-r--r--pager.c2
-rw-r--r--parse-options.c61
-rw-r--r--parse-options.h15
-rw-r--r--patch-ids.c2
-rw-r--r--pretty.c360
-rw-r--r--progress.c104
-rw-r--r--progress.h3
-rw-r--r--read-cache.c48
-rw-r--r--refs.c12
-rw-r--r--refs.h3
-rw-r--r--revision.c158
-rw-r--r--revision.h21
-rw-r--r--run-command.c6
-rw-r--r--run-command.h1
-rw-r--r--sha1_file.c8
-rw-r--r--sideband.c51
-rw-r--r--strbuf.c31
-rw-r--r--strbuf.h4
-rwxr-xr-xt/t2008-checkout-subdir.sh82
-rwxr-xr-xt/t2200-add-update.sh30
-rwxr-xr-xt/t3402-rebase-merge.sh7
-rwxr-xr-xt/t3403-rebase-skip.sh19
-rwxr-xr-xt/t3404-rebase-interactive.sh3
-rwxr-xr-xt/t3700-add.sh24
-rwxr-xr-xt/t3902-quoted.sh7
-rwxr-xr-x[-rw-r--r--]t/t4018-diff-funcname.sh0
-rwxr-xr-xt/t4021-format-patch-numbered.sh106
-rwxr-xr-xt/t4022-diff-rewrite.sh26
-rwxr-xr-xt/t5300-pack-object.sh34
-rwxr-xr-xt/t5302-pack-index.sh24
-rwxr-xr-xt/t5502-quickfetch.sh33
-rwxr-xr-xt/t5510-fetch.sh13
-rwxr-xr-xt/t6008-rev-list-submodule.sh42
-rwxr-xr-xt/t6030-bisect-porcelain.sh39
-rwxr-xr-xt/t7004-tag.sh26
-rwxr-xr-xt/t7005-editor.sh5
-rwxr-xr-xt/t7300-clean.sh11
-rwxr-xr-xt/t7500-commit.sh32
-rwxr-xr-x[-rw-r--r--]t/t7501-commit.sh16
-rwxr-xr-xt/t9001-send-email.sh37
-rwxr-xr-xt/t9101-git-svn-props.sh2
-rwxr-xr-xt/t9106-git-svn-dcommit-clobber-series.sh1
-rwxr-xr-xt/t9116-git-svn-log.sh80
-rwxr-xr-xt/t9117-git-svn-init-clone.sh55
-rwxr-xr-xt/t9119-git-svn-info.sh368
-rw-r--r--templates/hooks--pre-commit2
-rw-r--r--transport.c2
-rw-r--r--tree-diff.c14
-rw-r--r--tree-walk.h7
-rw-r--r--unpack-trees.c4
-rw-r--r--utf8.c1
-rw-r--r--wt-status.c15
-rw-r--r--xdiff/xdiffi.c2
-rw-r--r--xdiff/xutils.c2
216 files changed, 20735 insertions, 2302 deletions
diff --git a/Documentation/Makefile b/Documentation/Makefile
index 39ec0ede0..d88664177 100644
--- a/Documentation/Makefile
+++ b/Documentation/Makefile
@@ -37,9 +37,6 @@ man7dir=$(mandir)/man7
ASCIIDOC=asciidoc
ASCIIDOC_EXTRA =
-ifdef ASCIIDOC8
-ASCIIDOC_EXTRA += -a asciidoc7compatible
-endif
INSTALL?=install
RM ?= rm -f
DOC_REF = origin/man
@@ -52,6 +49,13 @@ DOCBOOK2X_TEXI=docbook2x-texi
-include ../config.mak.autogen
-include ../config.mak
+ifdef ASCIIDOC8
+ASCIIDOC_EXTRA += -a asciidoc7compatible
+endif
+ifdef DOCBOOK_XSL_172
+ASCIIDOC_EXTRA += -a docbook-xsl-172
+endif
+
#
# Please note that there is a minor bug in asciidoc.
# The version after 6.0.3 _will_ include the patch found here:
diff --git a/Documentation/RelNotes-1.5.3.6.txt b/Documentation/RelNotes-1.5.3.6.txt
index 06e44f773..069a2b2cf 100644
--- a/Documentation/RelNotes-1.5.3.6.txt
+++ b/Documentation/RelNotes-1.5.3.6.txt
@@ -4,18 +4,45 @@ GIT v1.5.3.6 Release Notes
Fixes since v1.5.3.5
--------------------
- * git-cvsexportcommit handles root commits better;
+ * git-cvsexportcommit handles root commits better.
* git-svn dcommit used to clobber when sending a series of
- patches;
+ patches.
+
+ * git-svn dcommit failed after attempting to rebase when
+ started with a dirty index; now it stops upfront.
* git-grep sometimes refused to work when your index was
- unmerged;
+ unmerged.
- * Quite a lot of documentation clarifications.
+ * "git-grep -A1 -B2" acted as if it was told to run "git -A1 -B21".
+
+ * git-hash-object did not honor configuration variables, such as
+ core.compression.
+
+ * git-index-pack choked on a huge pack on 32-bit machines, even when
+ large file offsets are supported.
+
+ * atom feeds from git-web said "10" for the month of November.
+
+ * a memory leak in commit walker was plugged.
+
+ * When git-send-email inserted the original author's From:
+ address in body, it did not mark the message with
+ Content-type: as needed.
---
-exec >/var/tmp/1
-O=v1.5.3.5-32-gcb6c162
-echo O=`git describe refs/heads/maint`
-git shortlog --no-merges $O..refs/heads/maint
+ * git-revert and git-cherry-pick incorrectly refused to start
+ when the work tree was dirty.
+
+ * git-clean did not honor core.excludesfile configuration.
+
+ * git-add mishandled ".gitignore" files when applying them to
+ subdirectories.
+
+ * While importing a too branchy history, git-fastimport did not
+ honor delta depth limit properly.
+
+ * Support for zlib implementations that lack ZLIB_VERNUM and definition
+ of deflateBound() has been added.
+
+ * Quite a lot of documentation clarifications.
diff --git a/Documentation/RelNotes-1.5.4.txt b/Documentation/RelNotes-1.5.4.txt
index 93fb9c914..a4a2a7f42 100644
--- a/Documentation/RelNotes-1.5.4.txt
+++ b/Documentation/RelNotes-1.5.4.txt
@@ -32,6 +32,11 @@ Updates since v1.5.3
(read: safer than the usual one) after the user accumulates
too many loose objects.
+ * 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", but we now use the safer
+ default).
+
* git-push has been rewritten in C.
* git-push learned --dry-run option to show what would happen
@@ -52,11 +57,39 @@ Updates since v1.5.3
* git-lost-found was deprecated in favor of git-fsck's --lost-found
option.
+ * "git log" learned --early-output option to help interactive
+ GUI implementations.
+
* git-svnimport was removed in favor of git-svn.
* git-bisect learned "skip" action to mark untestable commits.
- * rename detection diff family, while detecting exact matches,
+ * git-format-patch learned "format.numbered" configuration variable
+ to automatically turn --numbered option on when more than one
+ commits are formatted.
+
+ * 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.
+
+ * "git cvsexportcommit" learned -w option to specify and switch
+ to the CVS working directory.
+
+ * "git checkout" from a subdirectory learned to use "../path"
+ to allow checking out a path outside the current directory
+ without cd'ing up.
+
+ * Output processing for '--pretty=format:<user format>' has
+ been optimized.
+
+ * Rename detection diff family, while detecting exact matches,
has been greatly optimized.
* Example update and post-receive hooks have been improved.
@@ -77,8 +110,15 @@ Fixes since v1.5.3
All of the fixes in v1.5.3 maintenance series are included in
this release, unless otherwise noted.
+ * git-svn talking with the SVN over http will correctly quote branch
+ and project names.
+
+ * "git rev-list --objects A..B" choked when the lower boundary
+ of the range involved a subproject. This fix is also queued
+ for 'maint' (but not in there yet).
+
--
exec >/var/tmp/1
-O=v1.5.3.5-618-g5d4138a
+O=v1.5.3.6-727-g5d3d1ca
echo O=`git describe refs/heads/master`
git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint
diff --git a/Documentation/asciidoc.conf b/Documentation/asciidoc.conf
index af5b1558a..99d8874aa 100644
--- a/Documentation/asciidoc.conf
+++ b/Documentation/asciidoc.conf
@@ -23,7 +23,9 @@ ifdef::backend-docbook[]
endif::backend-docbook[]
ifdef::backend-docbook[]
+ifndef::docbook-xsl-172[]
# "unbreak" docbook-xsl v1.68 for manpages. v1.69 works with or without this.
+# v1.72 breaks with this because it replaces dots not in roff requests.
[listingblock]
<example><title>{title}</title>
<literallayout>
@@ -36,6 +38,7 @@ ifdef::doctype-manpage[]
endif::doctype-manpage[]
</literallayout>
{title#}</example>
+endif::docbook-xsl-172[]
endif::backend-docbook[]
ifdef::doctype-manpage[]
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 8d5d20058..39d1ef529 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -226,13 +226,15 @@ core.compression::
An integer -1..9, indicating a default compression level.
-1 is the zlib default. 0 means no compression,
and 1..9 are various speed/size tradeoffs, 9 being slowest.
+ If set, this provides a default to other compression variables,
+ such as 'core.loosecompression' and 'pack.compression'.
core.loosecompression::
An integer -1..9, indicating the compression level for objects that
are not in a pack file. -1 is the zlib default. 0 means no
compression, and 1..9 are various speed/size tradeoffs, 9 being
slowest. If not set, defaults to core.compression. If that is
- not set, defaults to 0 (best speed).
+ not set, defaults to 1 (best speed).
core.packedGitWindowSize::
Number of bytes of a pack file to map into memory in a
@@ -432,6 +434,12 @@ fetch.unpackLimit::
pack from a push can make the push operation complete faster,
especially on slow filesystems.
+format.numbered::
+ A boolean which can enable sequence numbers in patch subjects.
+ Seting this option to "auto" will enable it only if there is
+ more than one patch. See --numbered option in
+ gitlink:git-format-patch[1].
+
format.headers::
Additional email headers to include in a patch to be submitted
by mail. See gitlink:git-format-patch[1].
@@ -642,7 +650,9 @@ pack.compression::
in a pack file. -1 is the zlib default. 0 means no
compression, and 1..9 are various speed/size tradeoffs, 9 being
slowest. If not set, defaults to core.compression. If that is
- not set, defaults to -1.
+ not set, defaults to -1, the zlib default, which is "a default
+ compromise between speed and compression (currently equivalent
+ to level 6)."
pack.deltaCacheSize::
The maximum memory in bytes used for caching deltas in
diff --git a/Documentation/core-tutorial.txt b/Documentation/core-tutorial.txt
index 401d1deca..bd6cd4124 100644
--- a/Documentation/core-tutorial.txt
+++ b/Documentation/core-tutorial.txt
@@ -1152,7 +1152,7 @@ back to the earlier repository with "hello" and "example" file,
and bring ourselves back to the pre-merge state:
------------
-$ git show-branch --more=3 master mybranch
+$ git show-branch --more=2 master mybranch
! [master] Merge work in mybranch
* [mybranch] Merge work in mybranch
--
@@ -1215,7 +1215,7 @@ $ git-read-tree -m -u $mb HEAD mybranch
This is the same `git-read-tree` command we have already seen,
but it takes three trees, unlike previous examples. This reads
the contents of each tree into different 'stage' in the index
-file (the first tree goes to stage 1, the second stage 2,
+file (the first tree goes to stage 1, the second to stage 2,
etc.). After reading three trees into three stages, the paths
that are the same in all three stages are 'collapsed' into stage
0. Also paths that are the same in two of three stages are
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index b1f528ae8..e4af39351 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -1,5 +1,25 @@
+// Please don't remove this comment as asciidoc behaves badly when
+// the first non-empty line is ifdef/ifndef. The symptom is that
+// without this comment the <git-diff-core> attribute conditionally
+// defined below ends up being defined unconditionally.
+// Last checked with asciidoc 7.0.2.
+
+ifndef::git-format-patch[]
+ifndef::git-diff[]
+:git-diff-core: 1
+endif::git-diff[]
+endif::git-format-patch[]
+
+ifdef::git-format-patch[]
-p::
- Generate patch (see section on generating patches)
+ Generate patches without diffstat.
+endif::git-format-patch[]
+
+ifndef::git-format-patch[]
+-p::
+ Generate patch (see section on generating patches).
+ {git-diff? This is the default.}
+endif::git-format-patch[]
-u::
Synonym for "-p".
@@ -13,6 +33,7 @@
--raw::
Generate the raw format.
+ {git-diff-core? This is the default.}
--patch-with-raw::
Synonym for "-p --raw".
@@ -41,6 +62,7 @@
--patch-with-stat::
Synonym for "-p --stat".
+ {git-format-patch? This is the default.}
-z::
NUL-line termination on output. This affects the --raw
diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt
index 963e1ab1e..63829d93c 100644
--- a/Documentation/git-add.txt
+++ b/Documentation/git-add.txt
@@ -224,6 +224,7 @@ See Also
--------
gitlink:git-status[1]
gitlink:git-rm[1]
+gitlink:git-reset[1]
gitlink:git-mv[1]
gitlink:git-commit[1]
gitlink:git-update-index[1]
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 14e58f386..c90bcece2 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -130,6 +130,7 @@ OPTIONS
for "host.xz:foo/.git"). Cloning into an existing directory
is not allowed.
+:git-clone: 1
include::urls.txt[]
Examples
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index e54fb1210..d4bfd49ce 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -154,10 +154,13 @@ EXAMPLES
--------
When recording your own work, the contents of modified files in
your working tree are temporarily stored to a staging area
-called the "index" with gitlink:git-add[1]. Removal
-of a file is staged with gitlink:git-rm[1]. After building the
-state to be committed incrementally with these commands, `git
-commit` (without any pathname parameter) is used to record what
+called the "index" with gitlink:git-add[1]. A file can be
+reverted back, only in the index but not in the working tree,
+to that of the last commit with `git-reset HEAD -- <file>`,
+which effectively reverts `git-add` and prevents the changes to
+this file from participating in the next commit. After building
+the state to be committed incrementally with these commands,
+`git commit` (without any pathname parameter) is used to record what
has been staged so far. This is the most basic form of the
command. An example:
diff --git a/Documentation/git-cvsexportcommit.txt b/Documentation/git-cvsexportcommit.txt
index c3922f923..3f9d2295d 100644
--- a/Documentation/git-cvsexportcommit.txt
+++ b/Documentation/git-cvsexportcommit.txt
@@ -8,7 +8,7 @@ git-cvsexportcommit - Export a single commit to a CVS checkout
SYNOPSIS
--------
-'git-cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
+'git-cvsexportcommit' [-h] [-u] [-v] [-c] [-P] [-p] [-a] [-d cvsroot] [-w cvsworkdir] [-f] [-m msgprefix] [PARENTCOMMIT] COMMITID
DESCRIPTION
@@ -16,8 +16,9 @@ DESCRIPTION
Exports a commit from GIT to a CVS checkout, making it easier
to merge patches from a git repository into a CVS repository.
-Execute it from the root of the CVS working copy. GIT_DIR must be defined.
-See examples below.
+Specify the name of a CVS checkout using the -w switch or execute it
+from the root of the CVS working copy. In the latter case GIT_DIR must
+be defined. See examples below.
It does its best to do the safe thing, it will check that the files are
unchanged and up to date in the CVS checkout, and it will not autocommit
@@ -61,6 +62,11 @@ OPTIONS
-u::
Update affected files from CVS repository before attempting export.
+-w::
+ Specify the location of the CVS checkout to use for the export. This
+ option does not require GIT_DIR to be set before execution if the
+ current directory is within a git repository.
+
-v::
Verbose.
@@ -76,6 +82,12 @@ $ git-cvsexportcommit -v <commit-sha1>
$ cvs commit -F .msg <files>
------------
+Merge one patch into CVS (-c and -w options). The working directory is within the Git Repo::
++
+------------
+ $ git-cvsexportcommit -v -c -w ~/project_cvs_checkout <commit-sha1>
+------------
+
Merge pending patches into CVS automatically -- only if you really know what you are doing::
+
------------
@@ -86,11 +98,11 @@ $ git-cherry cvshead myhead | sed -n 's/^+ //p' | xargs -l1 git-cvsexportcommit
Author
------
-Written by Martin Langhoff <martin@catalyst.net.nz>
+Written by Martin Langhoff <martin@catalyst.net.nz> and others.
Documentation
--------------
-Documentation by Martin Langhoff <martin@catalyst.net.nz>
+Documentation by Martin Langhoff <martin@catalyst.net.nz> and others.
GIT
---
diff --git a/Documentation/git-diff.txt b/Documentation/git-diff.txt
index 11c4216c4..2808a5ec4 100644
--- a/Documentation/git-diff.txt
+++ b/Documentation/git-diff.txt
@@ -75,6 +75,7 @@ and the range notations ("<commit>..<commit>" and
OPTIONS
-------
+:git-diff: 1
include::diff-options.txt[]
<path>...::
diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt
index f0617efa0..6fb942985 100644
--- a/Documentation/git-format-patch.txt
+++ b/Documentation/git-format-patch.txt
@@ -9,9 +9,10 @@ git-format-patch - Prepare patches for e-mail submission
SYNOPSIS
--------
[verse]
-'git-format-patch' [-n | -k] [-o <dir> | --stdout] [--thread]
+'git-format-patch' [-k] [-o <dir> | --stdout] [--thread]
[--attach[=<boundary>] | --inline[=<boundary>]]
[-s | --signoff] [<common diff options>]
+ [-n | --numbered | -N | --no-numbered]
[--start-number <n>] [--numbered-files]
[--in-reply-to=Message-Id] [--suffix=.<sfx>]
[--ignore-if-in-upstream]
@@ -65,6 +66,7 @@ reference.
OPTIONS
-------
+:git-format-patch: 1
include::diff-options.txt[]
-<n>::
@@ -77,6 +79,9 @@ include::diff-options.txt[]
-n|--numbered::
Name output in '[PATCH n/m]' format.
+-N|--no-numbered::
+ Name output in '[PATCH]' format.
+
--start-number <n>::
Start numbering the patches at <n> instead of 1.
@@ -142,15 +147,16 @@ not add any suffix.
CONFIGURATION
-------------
-You can specify extra mail header lines to be added to each
-message in the repository configuration. You can also specify
-new defaults for the subject prefix and file suffix.
+You can specify extra mail header lines to be added to each message
+in the repository configuration, new defaults for the subject prefix
+and file suffix, and number patches when outputting more than one.
------------
[format]
headers = "Organization: git-foo\n"
subjectprefix = CHANGE
suffix = .txt
+ numbered = auto
------------
diff --git a/Documentation/git-get-tar-commit-id.txt b/Documentation/git-get-tar-commit-id.txt
index 76316bbc9..60d1c52f4 100644
--- a/Documentation/git-get-tar-commit-id.txt
+++ b/Documentation/git-get-tar-commit-id.txt
@@ -3,7 +3,7 @@ git-get-tar-commit-id(1)
NAME
----
-git-get-tar-commit-id - Extract commit ID from an archive created using git-tar-tree
+git-get-tar-commit-id - Extract commit ID from an archive created using git-archive
SYNOPSIS
@@ -19,7 +19,7 @@ runtime is not influenced by the size of <tarfile> very much.
If no commit ID is found, git-get-tar-commit-id quietly exists with a
return code of 1. This can happen if <tarfile> had not been created
-using git-archive or if the <treeish> parameter of git-archive had been
+using git-archive or if the first parameter of git-archive had been
a tree ID instead of a commit ID or tag.
diff --git a/Documentation/git-ls-files.txt b/Documentation/git-ls-files.txt
index 9e454f0a4..2ec0c0d27 100644
--- a/Documentation/git-ls-files.txt
+++ b/Documentation/git-ls-files.txt
@@ -15,6 +15,7 @@ SYNOPSIS
[-x <pattern>|--exclude=<pattern>]
[-X <file>|--exclude-from=<file>]
[--exclude-per-directory=<file>]
+ [--exclude-standard]
[--error-unmatch] [--with-tree=<tree-ish>]
[--full-name] [--abbrev] [--] [<file>]\*
@@ -77,6 +78,10 @@ OPTIONS
read additional exclude patterns that apply only to the
directory and its subdirectories in <file>.
+--exclude-standard::
+ Add the standard git exclusions: .git/info/exclude, .gitignore
+ in each directory, and the user's global exclusion file.
+
--error-unmatch::
If any <file> does not appear in the index, treat this as an
error (return 1).
diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt
index 5c7316ceb..25003c386 100644
--- a/Documentation/git-reflog.txt
+++ b/Documentation/git-reflog.txt
@@ -19,7 +19,7 @@ depending on the subcommand:
git reflog expire [--dry-run] [--stale-fix] [--verbose]
[--expire=<time>] [--expire-unreachable=<time>] [--all] <refs>...
-git reflog [show] [log-options]
+git reflog [show] [log-options] [<ref>]
Reflog is a mechanism to record when the tip of branches are
updated. This command is to manage the information recorded in it.
@@ -32,9 +32,16 @@ directly by the end users -- instead, see gitlink:git-gc[1].
The subcommand "show" (which is also the default, in the absence of any
subcommands) will take all the normal log options, and show the log of
-`HEAD`, which will cover all recent actions, including branch switches.
-It is basically an alias for 'git log -g --abbrev-commit
---pretty=oneline', see gitlink:git-log[1].
+the reference provided in the command-line (or `HEAD`, by default).
+The reflog will cover all recent actions (HEAD reflog records branch switching
+as well). It is an alias for 'git log -g --abbrev-commit --pretty=oneline';
+see gitlink:git-log[1].
+
+The reflog is useful in various git commands, to specify the old value
+of a reference. For example, `HEAD@\{2\}` means "where HEAD used to be
+two moves ago", `master@\{one.week.ago\}` means "where master used to
+point to one week ago", and so on. See gitlink:git-rev-parse[1] for
+more details.
OPTIONS
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 027ba11bd..4b263c249 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -79,7 +79,7 @@ caution.
Fetch updates for a named set of remotes in the repository as defined by
remotes.<group>. If a named group is not specified on the command line,
the configuration parameter remotes.default will get used; if
-remotes.default is not defined, all remotes which do not the
+remotes.default is not defined, all remotes which do not have the
configuration parameter remote.<name>.skipDefaultUpdate set to true will
be updated. (See gitlink:git-config[1]).
@@ -101,7 +101,7 @@ $ git remote
origin
$ git branch -r
origin/master
-$ git remote add linux-nfs git://linux-nfs.org/pub/nfs-2.6.git
+$ git remote add linux-nfs git://linux-nfs.org/pub/linux/nfs-2.6.git
$ git remote
linux-nfs
origin
diff --git a/Documentation/git-rev-list.txt b/Documentation/git-rev-list.txt
index 485280423..989fbf356 100644
--- a/Documentation/git-rev-list.txt
+++ b/Documentation/git-rev-list.txt
@@ -20,6 +20,7 @@ SYNOPSIS
[ \--not ]
[ \--all ]
[ \--stdin ]
+ [ \--quiet ]
[ \--topo-order ]
[ \--parents ]
[ \--timestamp ]
@@ -270,6 +271,14 @@ limiting may be applied.
In addition to the '<commit>' listed on the command
line, read them from the standard input.
+--quiet::
+
+ Don't print anything to standard output. This form of
+ git-rev-list is primarly meant to allow the caller to
+ test the exit status to see if a range of objects is fully
+ connected (or not). It is faster than redirecting stdout
+ to /dev/null as the output does not have to be formatted.
+
--cherry-pick::
Omit any commit that introduces the same change as
diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt
index 4758c33de..329fce0aa 100644
--- a/Documentation/git-rev-parse.txt
+++ b/Documentation/git-rev-parse.txt
@@ -23,6 +23,13 @@ distinguish between them.
OPTIONS
-------
+--parseopt::
+ Use `git-rev-parse` in option parsing mode (see PARSEOPT section below).
+
+--keep-dash-dash::
+ Only meaningful in `--parseopt` mode. Tells the option parser to echo
+ out the first `--` met instead of skipping it.
+
--revs-only::
Do not output flags and parameters not meant for
`git-rev-list` command.
@@ -288,10 +295,75 @@ Here are a handful examples:
C^@ I J F
F^! D G H D F
+PARSEOPT
+--------
+
+In `--parseopt` mode, `git-rev-parse` helps massaging options to bring to shell
+scripts the same facilities C builtins have. It works as an option normalizer
+(e.g. splits single switches aggregate values), a bit like `getopt(1)` does.
+
+It takes on the standard input the specification of the options to parse and
+understand, and echoes on the standard output a line suitable for `sh(1)` `eval`
+to replace the arguments with normalized ones. In case of error, it outputs
+usage on the standard error stream, and exits with code 129.
+
+Input Format
+~~~~~~~~~~~~
+
+`git-rev-parse --parseopt` input format is fully text based. It has two parts,
+separated by a line that contains only `--`. The lines before the separator
+(should be more than one) are used for the usage.
+The lines after the separator describe the options.
+
+Each line of options has this format:
+
+------------
+<opt_spec><arg_spec>? SP+ help LF
+------------
+
+`<opt_spec>`::
+ its format is the short option character, then the long option name
+ separated by a comma. Both parts are not required, though at least one
+ is necessary. `h,help`, `dry-run` and `f` are all three correct
+ `<opt_spec>`.
+
+`<arg_spec>`::
+ an `<arg_spec>` tells the option parser if the option has an argument
+ (`=`), an optional one (`?` though its use is discouraged) or none
+ (no `<arg_spec>` in that case).
+
+The remainder of the line, after stripping the spaces, is used
+as the help associated to the option.
+
+Blank lines are ignored, and lines that don't match this specification are used
+as option group headers (start the line with a space to create such
+lines on purpose).
+
+Example
+~~~~~~~
+
+------------
+OPTS_SPEC="\
+some-command [options] <args>...
+
+some-command does foo and bar!
+--
+h,help show the help
+
+foo some nifty option --foo
+bar= some cool option --bar with an argument
+
+ An option group Header
+C? option C with an optional argument"
+
+eval `echo "$OPTS_SPEC" | git-rev-parse --parseopt -- "$@" || echo exit $?`
+------------
+
+
Author
------
-Written by Linus Torvalds <torvalds@osdl.org> and
-Junio C Hamano <junkio@cox.net>
+Written by Linus Torvalds <torvalds@osdl.org> .
+Junio C Hamano <junkio@cox.net> and Pierre Habouzit <madcoder@debian.org>
Documentation
--------------
diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt
index 488e4b1ca..918a9928b 100644
--- a/Documentation/git-svn.txt
+++ b/Documentation/git-svn.txt
@@ -193,6 +193,12 @@ Any other arguments are passed directly to `git log'
repository (that has been init-ed with git-svn).
The -r<revision> option is required for this.
+'info'::
+ Shows information about a file or directory similar to what
+ `svn info' provides. Does not currently support a -r/--revision
+ argument. Use the --url option to output only the value of the
+ 'URL:' field.
+
--
OPTIONS
diff --git a/Documentation/git.txt b/Documentation/git.txt
index 6db7ae1ea..546020100 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -46,6 +46,7 @@ Documentation for older releases are available here:
* link:v1.5.3/git.html[documentation for release 1.5.3]
* release notes for
+ link:RelNotes-1.5.3.6.txt[1.5.3.6],
link:RelNotes-1.5.3.5.txt[1.5.3.5],
link:RelNotes-1.5.3.4.txt[1.5.3.4],
link:RelNotes-1.5.3.3.txt[1.5.3.3],
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 20cf8ff81..19bd25f29 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -148,22 +148,23 @@ with `$Id$` upon check-in.
`filter`
^^^^^^^^
-A `filter` attribute can be set to a string value. This names
+A `filter` attribute can be set to a string value that names a
filter driver specified in the configuration.
-A filter driver consists of `clean` command and `smudge`
+A filter driver consists of a `clean` command and a `smudge`
command, either of which can be left unspecified. Upon
-checkout, when `smudge` command is specified, the command is fed
-the blob object from its standard input, and its standard output
-is used to update the worktree file. Similarly, `clean` command
-is used to convert the contents of worktree file upon checkin.
+checkout, when the `smudge` command is specified, the command is
+fed the blob object from its standard input, and its standard
+output is used to update the worktree file. Similarly, the
+`clean` command is used to convert the contents of worktree file
+upon checkin.
-Missing filter driver definition in the config is not an error
+A missing filter driver definition in the config is not an error
but makes the filter a no-op passthru.
The content filtering is done to massage the content into a
shape that is more convenient for the platform, filesystem, and
-the user to use. The keyword here is "more convenient" and not
+the user to use. The key phrase here is "more convenient" and not
"turning something unusable into usable". In other words, the
intent is that if someone unsets the filter driver definition,
or does not have the appropriate filter program, the project
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
new file mode 100644
index 000000000..4357e2691
--- /dev/null
+++ b/Documentation/howto/maintain-git.txt
@@ -0,0 +1,277 @@
+From: Junio C Hamano <gitster@pobox.com>
+Date: Wed, 21 Nov 2007 16:32:55 -0800
+Subject: Addendum to "MaintNotes"
+Abstract: Imagine that git development is racing along as usual, when our friendly
+ neighborhood maintainer is struck down by a wayward bus. Out of the
+ hordes of suckers (loyal developers), you have been tricked (chosen) to
+ step up as the new maintainer. This howto will show you "how to" do it.
+
+The maintainer's git time is spent on three activities.
+
+ - Communication (60%)
+
+ Mailing list discussions on general design, fielding user
+ questions, diagnosing bug reports; reviewing, commenting on,
+ suggesting alternatives to, and rejecting patches.
+
+ - Integration (30%)
+
+ Applying new patches from the contributors while spotting and
+ correcting minor mistakes, shuffling the integration and
+ testing branches, pushing the results out, cutting the
+ releases, and making announcements.
+
+ - Own development (10%)
+
+ Scratching my own itch and sending proposed patch series out.
+
+The policy on Integration is informally mentioned in "A Note
+from the maintainer" message, which is periodically posted to
+this mailing list after each feature release is made.
+
+The policy.
+
+ - Feature releases are numbered as vX.Y.Z and are meant to
+ contain bugfixes and enhancements in any area, including
+ functionality, performance and usability, without regression.
+
+ - Maintenance releases are numbered as vX.Y.Z.W and are meant
+ to contain only bugfixes for the corresponding vX.Y.Z feature
+ release and earlier maintenance releases vX.Y.Z.V (V < W).
+
+ - 'master' branch is used to prepare for the next feature
+ release. In other words, at some point, the tip of 'master'
+ branch is tagged with vX.Y.Z.
+
+ - 'maint' branch is used to prepare for the next maintenance
+ release. After the feature release vX.Y.Z is made, the tip
+ of 'maint' branch is set to that release, and bugfixes will
+ accumulate on the branch, and at some point, the tip of the
+ branch is tagged with vX.Y.Z.1, vX.Y.Z.2, and so on.
+
+ - 'next' branch is used to publish changes (both enhancements
+ and fixes) that (1) have worthwhile goal, (2) are in a fairly
+ good shape suitable for everyday use, (3) but have not yet
+ demonstrated to be regression free. New changes are tested
+ in 'next' before merged to 'master'.
+
+ - 'pu' branch is used to publish other proposed changes that do
+ not yet pass the criteria set for 'next'.
+
+ - The tips of 'master', 'maint' and 'next' branches will always
+ fast forward, to allow people to build their own
+ customization on top of them.
+
+ - Usually 'master' contains all of 'maint', 'next' contains all
+ of 'master' and 'pu' contains all of 'next'.
+
+ - The tip of 'master' is meant to be more stable than any
+ tagged releases, and the users are encouraged to follow it.
+
+ - The 'next' branch is where new action takes place, and the
+ users are encouraged to test it so that regressions and bugs
+ are found before new topics are merged to 'master'.
+
+
+A typical git day for the maintainer implements the above policy
+by doing the following:
+
+ - Scan mailing list and #git channel log. Respond with review
+ comments, suggestions etc. Kibitz. Collect potentially
+ usable patches from the mailing list. Patches about a single
+ topic go to one mailbox (I read my mail in Gnus, and type
+ \C-o to save/append messages in files in mbox format).
+
+ - Review the patches in the saved mailboxes. Edit proposed log
+ message for typofixes and clarifications, and add Acks
+ collected from the list. Edit patch to incorporate "Oops,
+ that should have been like this" fixes from the discussion.
+
+ - Classify the collected patches and handle 'master' and
+ 'maint' updates:
+
+ - Obviously correct fixes that pertain to the tip of 'maint'
+ are directly applied to 'maint'.
+
+ - Obviously correct fixes that pertain to the tip of 'master'
+ are directly applied to 'master'.
+
+ This step is done with "git am".
+
+ $ git checkout master ;# or "git checkout maint"
+ $ git am -3 -s mailbox
+ $ make test
+
+ - Merge downwards (maint->master):
+
+ $ git checkout master
+ $ git merge maint
+ $ make test
+
+ - Review the last issue of "What's cooking" message, review the
+ topics scheduled for merging upwards (topic->master and
+ topic->maint), and merge.
+
+ $ git checkout master ;# or "git checkout maint"
+ $ git merge ai/topic ;# or "git merge ai/maint-topic"
+ $ git log -p ORIG_HEAD.. ;# final review
+ $ git diff ORIG_HEAD.. ;# final review
+ $ make test ;# final review
+ $ git branch -d ai/topic ;# or "git branch -d ai/maint-topic"
+
+ - Merge downwards (maint->master) if needed:
+
+ $ git checkout master
+ $ git merge maint
+ $ make test
+
+ - Merge downwards (master->next) if needed:
+
+ $ git checkout next
+ $ git merge master
+ $ make test
+
+ - Handle the remaining patches:
+
+ - Anything unobvious that is applicable to 'master' (in other
+ words, does not depend on anything that is still in 'next'
+ and not in 'master') is applied to a new topic branch that
+ is forked from the tip of 'master'. This includes both
+ enhancements and unobvious fixes to 'master'. A topic
+ branch is named as ai/topic where "ai" is typically
+ author's initial and "topic" is a descriptive name of the
+ topic (in other words, "what's the series is about").
+
+ - An unobvious fix meant for 'maint' is applied to a new
+ topic branch that is forked from the tip of 'maint'. The
+ topic is named as ai/maint-topic.
+
+ - Changes that pertain to an existing topic are applied to
+ the branch, but:
+
+ - obviously correct ones are applied first;
+
+ - questionable ones are discarded or applied to near the tip;
+
+ - Replacement patches to an existing topic are accepted only
+ for commits not in 'next'.
+
+ The above except the "replacement" are all done with:
+
+ $ git am -3 -s mailbox
+
+ while patch replacement is often done by:
+
+ $ git format-patch ai/topic~$n..ai/topic ;# export existing
+
+ then replace some parts with the new patch, and reapplying:
+
+ $ git reset --hard ai/topic~$n
+ $ git am -3 -s 000*.txt
+
+ The full test suite is always run for 'maint' and 'master'
+ after patch application; for topic branches the tests are run
+ as time permits.
+
+ - Update "What's cooking" message to review the updates to
+ existing topics, newly added topics and graduated topics.
+
+ This step is helped with Meta/UWC script (where Meta/ contains
+ a checkout of the 'todo' branch).
+
+ - Merge topics to 'next'. For each branch whose tip is not
+ merged to 'next', one of three things can happen:
+
+ - The commits are all next-worthy; merge the topic to next:
+
+ $ git checkout next
+ $ git merge ai/topic ;# or "git merge ai/maint-topic"
+ $ make test
+
+ - The new parts are of mixed quality, but earlier ones are
+ next-worthy; merge the early parts to next:
+
+ $ git checkout next
+ $ git merge ai/topic~2 ;# the tip two are dubious
+ $ make test
+
+ - Nothing is next-worthy; do not do anything.
+
+ - Rebase topics that do not have any commit in next yet. This
+ step is optional but sometimes is worth doing when an old
+ series that is not in next can take advantage of low-level
+ framework change that is merged to 'master' already.
+
+ $ git rebase master ai/topic
+
+ This step is helped with Meta/git-topic.perl script to
+ identify which topic is rebaseable. There also is a
+ pre-rebase hook to make sure that topics that are already in
+ 'next' are not rebased beyond the merged commit.
+
+ - Rebuild "pu" to merge the tips of topics not in 'next'.
+
+ $ git checkout pu
+ $ git reset --hard next
+ $ git merge ai/topic ;# repeat for all remaining topics
+ $ make test
+
+ This step is helped with Meta/PU script
+
+ - Push four integration branches to a private repository at
+ k.org and run "make test" on all of them.
+
+ - Push four integration branches to /pub/scm/git/git.git at
+ k.org. This triggers its post-update hook which:
+
+ (1) runs "git pull" in $HOME/git-doc/ repository to pull
+ 'master' just pushed out;
+
+ (2) runs "make doc" in $HOME/git-doc/, install the generated
+ documentation in staging areas, which are separate
+ repositories that have html and man branches checked
+ out.
+
+ (3) runs "git commit" in the staging areas, and run "git
+ push" back to /pub/scm/git/git.git/ to update the html
+ and man branches.
+
+ (4) installs generated documentation to /pub/software/scm/git/docs/
+ to be viewed from http://www.kernel.org/
+
+ - Fetch html and man branches back from k.org, and push four
+ integration branches and the two documentation branches to
+ repo.or.cz
+
+
+Some observations to be made.
+
+ * Each topic is tested individually, and also together with
+ other topics cooking in 'next'. Until it matures, none part
+ of it is merged to 'master'.
+
+ * A topic already in 'next' can get fixes while still in
+ 'next'. Such a topic will have many merges to 'next' (in
+ other words, "git log --first-parent next" will show many
+ "Merge ai/topic to next" for the same topic.
+
+ * An unobvious fix for 'maint' is cooked in 'next' and then
+ merged to 'master' to make extra sure it is Ok and then
+ merged to 'maint'.
+
+ * Even when 'next' becomes empty (in other words, all topics
+ prove stable and are merged to 'master' and "git diff master
+ next" shows empty), it has tons of merge commits that will
+ never be in 'master'.
+
+ * In principle, "git log --first-parent master..next" should
+ show nothing but merges (in practice, there are fixup commits
+ and reverts that are not merges).
+
+ * Commits near the tip of a topic branch that are not in 'next'
+ are fair game to be discarded, replaced or rewritten.
+ Commits already merged to 'next' will not be.
+
+ * Being in the 'next' branch is not a guarantee for a topic to
+ be included in the next feature release. Being in the
+ 'master' branch typically is.
diff --git a/Documentation/urls.txt b/Documentation/urls.txt
index e67f9140a..4f667382e 100644
--- a/Documentation/urls.txt
+++ b/Documentation/urls.txt
@@ -36,5 +36,11 @@ To sync with a local directory, you can use:
- file:///path/to/repo.git/
===============================================================
+ifndef::git-clone[]
They are mostly equivalent, except when cloning. See
gitlink:git-clone[1] for details.
+endif::git-clone[]
+
+ifdef::git-clone[]
+They are equivalent, except the former implies --local option.
+endif::git-clone[]
diff --git a/Documentation/user-manual.txt b/Documentation/user-manual.txt
index 60e13853d..3661879f1 100644
--- a/Documentation/user-manual.txt
+++ b/Documentation/user-manual.txt
@@ -658,16 +658,23 @@ gitlink:git-diff[1]:
$ git diff master..test
-------------------------------------------------
-Sometimes what you want instead is a set of patches:
+That will produce the diff between the tips of the two branches. If
+you'd prefer to find the diff from their common ancestor to test, you
+can use three dots instead of two:
+
+-------------------------------------------------
+$ git diff master...test
+-------------------------------------------------
+
+Sometimes what you want instead is a set of patches; for this you can
+use gitlink:git-format-patch[1]:
-------------------------------------------------
$ git format-patch master..test
-------------------------------------------------
will generate a file with a patch for each commit reachable from test
-but not from master. Note that if master also has commits which are
-not reachable from test, then the combined result of these patches
-will not be the same as the diff produced by the git-diff example.
+but not from master.
[[viewing-old-file-versions]]
Viewing old file versions
@@ -1367,7 +1374,7 @@ If you make a commit that you later wish you hadn't, there are two
fundamentally different ways to fix the problem:
1. You can create a new commit that undoes whatever was done
- by the previous commit. This is the correct thing if your
+ by the old commit. This is the correct thing if your
mistake has already been made public.
2. You can go back and modify the old commit. You should
@@ -1567,9 +1574,9 @@ old history using, for example,
$ git log master@{1}
-------------------------------------------------
-This lists the commits reachable from the previous version of the branch.
-This syntax can be used with any git command that accepts a commit,
-not just with git log. Some other examples:
+This lists the commits reachable from the previous version of the
+"master" branch head. This syntax can be used with any git command
+that accepts a commit, not just with git log. Some other examples:
-------------------------------------------------
$ git show master@{2} # See where the branch pointed 2,
@@ -2554,6 +2561,72 @@ branches into their own work.
For true distributed development that supports proper merging,
published branches should never be rewritten.
+[[bisect-merges]]
+Why bisecting merge commits can be harder than bisecting linear history
+-----------------------------------------------------------------------
+
+The gitlink:git-bisect[1] command correctly handles history that
+includes merge commits. However, when the commit that it finds is a
+merge commit, the user may need to work harder than usual to figure out
+why that commit introduced a problem.
+
+Imagine this history:
+
+................................................
+ ---Z---o---X---...---o---A---C---D
+ \ /
+ o---o---Y---...---o---B
+................................................
+
+Suppose that on the upper line of development, the meaning of one
+of the functions that exists at Z is changed at commit X. The
+commits from Z leading to A change both the function's
+implementation and all calling sites that exist at Z, as well
+as new calling sites they add, to be consistent. There is no
+bug at A.
+
+Suppose that in the meantime on the lower line of development somebody
+adds a new calling site for that function at commit Y. The
+commits from Z leading to B all assume the old semantics of that
+function and the callers and the callee are consistent with each
+other. There is no bug at B, either.
+
+Suppose further that the two development lines merge cleanly at C,
+so no conflict resolution is required.
+
+Nevertheless, the code at C is broken, because the callers added
+on the lower line of development have not been converted to the new
+semantics introduced on the upper line of development. So if all
+you know is that D is bad, that Z is good, and that
+gitlink:git-bisect[1] identifies C as the culprit, how will you
+figure out that the problem is due to this change in semantics?
+
+When the result of a git-bisect is a non-merge commit, you should
+normally be able to discover the problem by examining just that commit.
+Developers can make this easy by breaking their changes into small
+self-contained commits. That won't help in the case above, however,
+because the problem isn't obvious from examination of any single
+commit; instead, a global view of the development is required. To
+make matters worse, the change in semantics in the problematic
+function may be just one small part of the changes in the upper
+line of development.
+
+On the other hand, if instead of merging at C you had rebased the
+history between Z to B on top of A, you would have gotten this
+linear history:
+
+................................................................
+ ---Z---o---X--...---o---A---o---o---Y*--...---o---B*--D*
+................................................................
+
+Bisecting between Z and D* would hit a single culprit commit Y*,
+and understanding why Y* was broken would probably be easier.
+
+Partly for this reason, many experienced git users, even when
+working on an otherwise merge-heavy project, keep the history
+linear by rebasing against the latest upstream version before
+publishing.
+
[[advanced-branch-management]]
Advanced branch management
==========================
diff --git a/Makefile b/Makefile
index af827f6ef..ccf522adc 100644
--- a/Makefile
+++ b/Makefile
@@ -115,6 +115,8 @@ all::
#
# Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
#
+# Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
+#
# Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
# MakeMaker (e.g. using ActiveState under Cygwin).
#
@@ -211,14 +213,14 @@ BASIC_LDFLAGS =
SCRIPT_SH = \
git-bisect.sh git-checkout.sh \
- git-clean.sh git-clone.sh git-commit.sh \
+ git-clone.sh git-commit.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 \
git-sh-setup.sh \
git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
- git-merge-resolve.sh git-merge-ours.sh \
+ git-merge-resolve.sh \
git-lost-found.sh git-quiltimport.sh git-submodule.sh \
git-filter-branch.sh \
git-stash.sh
@@ -327,6 +329,7 @@ BUILTIN_OBJS = \
builtin-check-attr.o \
builtin-checkout-index.o \
builtin-check-ref-format.o \
+ builtin-clean.o \
builtin-commit-tree.o \
builtin-count-objects.o \
builtin-describe.o \
@@ -351,6 +354,7 @@ BUILTIN_OBJS = \
builtin-mailsplit.o \
builtin-merge-base.o \
builtin-merge-file.o \
+ builtin-merge-ours.o \
builtin-mv.o \
builtin-name-rev.o \
builtin-pack-objects.o \
@@ -415,18 +419,17 @@ ifeq ($(uname_S),SunOS)
NO_STRCASESTR = YesPlease
NO_MEMMEM = YesPlease
NO_HSTRERROR = YesPlease
+ NO_MKDTEMP = YesPlease
ifeq ($(uname_R),5.8)
NEEDS_LIBICONV = YesPlease
NO_UNSETENV = YesPlease
NO_SETENV = YesPlease
- NO_MKDTEMP = YesPlease
NO_C99_FORMAT = YesPlease
NO_STRTOUMAX = YesPlease
endif
ifeq ($(uname_R),5.9)
NO_UNSETENV = YesPlease
NO_SETENV = YesPlease
- NO_MKDTEMP = YesPlease
NO_C99_FORMAT = YesPlease
NO_STRTOUMAX = YesPlease
endif
@@ -753,7 +756,7 @@ TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
LIBS = $(GITLIBS) $(EXTLIBS)
BASIC_CFLAGS += -DSHA1_HEADER='$(SHA1_HEADER_SQ)' \
- -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $(COMPAT_CFLAGS)
+ $(COMPAT_CFLAGS)
LIB_OBJS += $(COMPAT_OBJS)
ALL_CFLAGS += $(BASIC_CFLAGS)
@@ -902,6 +905,9 @@ exec_cmd.o: exec_cmd.c GIT-CFLAGS
builtin-init-db.o: builtin-init-db.c GIT-CFLAGS
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DDEFAULT_GIT_TEMPLATE_DIR='"$(template_dir_SQ)"' $<
+config.o: config.c GIT-CFLAGS
+ $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_GITCONFIG='"$(ETC_GITCONFIG_SQ)"' $<
+
http.o: http.c GIT-CFLAGS
$(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DGIT_USER_AGENT='"git/$(GIT_VERSION)"' $<
diff --git a/builtin-add.c b/builtin-add.c
index 45b14e8a6..cf815a0b8 100644
--- a/builtin-add.c
+++ b/builtin-add.c
@@ -21,7 +21,6 @@ static const char * const builtin_add_usage[] = {
};
static int take_worktree_changes;
-static const char *excludes_file;
static void prune_directory(struct dir_struct *dir, const char **pathspec, int prefix)
{
@@ -61,12 +60,7 @@ static void fill_directory(struct dir_struct *dir, const char **pathspec,
memset(dir, 0, sizeof(*dir));
if (!ignored_too) {
dir->collect_ignored = 1;
- dir->exclude_per_dir = ".gitignore";
- path = git_path("info/exclude");
- if (!access(path, R_OK))
- add_excludes_from_file(dir, path);
- if (excludes_file != NULL && !access(excludes_file, R_OK))
- add_excludes_from_file(dir, excludes_file);
+ setup_standard_excludes(dir);
}
/*
@@ -120,7 +114,7 @@ void add_files_to_cache(int verbose, const char *prefix, const char **files)
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
rev.diffopt.format_callback_data = &verbose;
- run_diff_files(&rev, 0);
+ run_diff_files(&rev, DIFF_RACY_IS_MODIFIED);
}
static void refresh(int verbose, const char **pathspec)
@@ -141,18 +135,6 @@ static void refresh(int verbose, const char **pathspec)
free(seen);
}
-static int git_add_config(const char *var, const char *value)
-{
- if (!strcmp(var, "core.excludesfile")) {
- if (!value)
- die("core.excludesfile without value");
- excludes_file = xstrdup(value);
- return 0;
- }
-
- return git_default_config(var, value);
-}
-
int interactive_add(void)
{
const char *argv[2] = { "add--interactive", NULL };
@@ -193,7 +175,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
exit(interactive_add());
}
- git_config(git_add_config);
+ git_config(git_default_config);
newfd = hold_locked_index(&lock_file, 1);
diff --git a/builtin-apply.c b/builtin-apply.c
index 8411b38c7..91f8752ff 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -683,7 +683,6 @@ static char *git_header_name(char *line, int llen)
}
}
}
- return NULL;
}
/* Verify that we recognize the lines following a git header */
@@ -1993,7 +1992,7 @@ static int verify_index_match(struct cache_entry *ce, struct stat *st)
return -1;
return 0;
}
- return ce_match_stat(ce, st, 1);
+ return ce_match_stat(ce, st, CE_MATCH_IGNORE_VALID);
}
static int check_patch(struct patch *patch, struct patch *prev_patch)
diff --git a/builtin-blame.c b/builtin-blame.c
index ba80bf894..c158d319d 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -335,7 +335,7 @@ static struct origin *find_origin(struct scoreboard *sb,
* same and diff-tree is fairly efficient about this.
*/
diff_setup(&diff_opts);
- diff_opts.recursive = 1;
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.detect_rename = 0;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
paths[0] = origin->path;
@@ -409,7 +409,7 @@ static struct origin *find_rename(struct scoreboard *sb,
const char *paths[2];
diff_setup(&diff_opts);
- diff_opts.recursive = 1;
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin->path;
@@ -1075,7 +1075,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
return 1; /* nothing remains for this target */
diff_setup(&diff_opts);
- diff_opts.recursive = 1;
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
paths[0] = NULL;
@@ -1093,7 +1093,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
if ((opt & PICKAXE_BLAME_COPY_HARDEST)
|| ((opt & PICKAXE_BLAME_COPY_HARDER)
&& (!porigin || strcmp(target->path, porigin->path))))
- diff_opts.find_copies_harder = 1;
+ DIFF_OPT_SET(&diff_opts, FIND_COPIES_HARDER);
if (is_null_sha1(target->commit->object.sha1))
do_diff_cache(parent->tree->object.sha1, &diff_opts);
@@ -1102,7 +1102,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
target->commit->tree->object.sha1,
"", &diff_opts);
- if (!diff_opts.find_copies_harder)
+ if (!DIFF_OPT_TST(&diff_opts, FIND_COPIES_HARDER))
diffcore_std(&diff_opts);
retval = 0;
diff --git a/builtin-branch.c b/builtin-branch.c
index 3bf40f145..2694c9cf4 100644
--- a/builtin-branch.c
+++ b/builtin-branch.c
@@ -507,48 +507,36 @@ static void rename_branch(const char *oldname, const char *newname, int force)
int cmd_branch(int argc, const char **argv, const char *prefix)
{
- int delete = 0, force_delete = 0, force_create = 0;
- int rename = 0, force_rename = 0;
+ int delete = 0, rename = 0, force_create = 0;
int verbose = 0, abbrev = DEFAULT_ABBREV, detached = 0;
int reflog = 0, track;
- int kinds = REF_LOCAL_BRANCH, kind_remote = 0, kind_any = 0;
+ int kinds = REF_LOCAL_BRANCH;
struct option options[] = {
OPT_GROUP("Generic options"),
OPT__VERBOSE(&verbose),
OPT_BOOLEAN( 0 , "track", &track, "set up tracking mode (see git-pull(1))"),
OPT_BOOLEAN( 0 , "color", &branch_use_color, "use colored output"),
- OPT_BOOLEAN('r', NULL, &kind_remote, "act on remote-tracking branches"),
+ OPT_SET_INT('r', NULL, &kinds, "act on remote-tracking branches",
+ REF_REMOTE_BRANCH),
OPT__ABBREV(&abbrev),
OPT_GROUP("Specific git-branch actions:"),
- OPT_BOOLEAN('a', NULL, &kind_any, "list both remote-tracking and local branches"),
- OPT_BOOLEAN('d', NULL, &delete, "delete fully merged branch"),
- OPT_BOOLEAN('D', NULL, &force_delete, "delete branch (even if not merged)"),
- OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
- OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
- OPT_BOOLEAN('m', NULL, &rename, "move/rename a branch and its reflog"),
- OPT_BOOLEAN('M', NULL, &force_rename, "move/rename a branch, even if target exists"),
+ OPT_SET_INT('a', NULL, &kinds, "list both remote-tracking and local branches",
+ REF_REMOTE_BRANCH | REF_LOCAL_BRANCH),
+ OPT_BIT('d', NULL, &delete, "delete fully merged branch", 1),
+ OPT_BIT('D', NULL, &delete, "delete branch (even if not merged)", 2),
+ OPT_BIT('m', NULL, &rename, "move/rename a branch and its reflog", 1),
+ OPT_BIT('M', NULL, &rename, "move/rename a branch, even if target exists", 2),
+ OPT_BOOLEAN('l', NULL, &reflog, "create the branch's reflog"),
+ OPT_BOOLEAN('f', NULL, &force_create, "force creation (when already exists)"),
OPT_END(),
};
git_config(git_branch_config);
track = branch_track;
argc = parse_options(argc, argv, options, builtin_branch_usage, 0);
-
- delete |= force_delete;
- rename |= force_rename;
- if (kind_remote)
- kinds = REF_REMOTE_BRANCH;
- if (kind_any)
- kinds = REF_REMOTE_BRANCH | REF_LOCAL_BRANCH;
- if (abbrev && abbrev < MINIMUM_ABBREV)
- abbrev = MINIMUM_ABBREV;
- else if (abbrev > 40)
- abbrev = 40;
-
- if ((delete && rename) || (delete && force_create) ||
- (rename && force_create))
+ if (!!delete + !!rename + !!force_create > 1)
usage_with_options(builtin_branch_usage, options);
head = resolve_ref("HEAD", head_sha1, 0, NULL);
@@ -564,13 +552,13 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
}
if (delete)
- return delete_branches(argc, argv, force_delete, kinds);
+ return delete_branches(argc, argv, delete > 1, kinds);
else if (argc == 0)
print_ref_list(kinds, detached, verbose, abbrev);
else if (rename && (argc == 1))
- rename_branch(head, argv[0], force_rename);
+ rename_branch(head, argv[0], rename > 1);
else if (rename && (argc == 2))
- rename_branch(argv[0], argv[1], force_rename);
+ rename_branch(argv[0], argv[1], rename > 1);
else if (argc <= 2)
create_branch(argv[0], (argc == 2) ? argv[1] : head,
force_create, reflog, track);
diff --git a/builtin-clean.c b/builtin-clean.c
new file mode 100644
index 000000000..56ae4eb9b
--- /dev/null
+++ b/builtin-clean.c
@@ -0,0 +1,153 @@
+/*
+ * "git clean" builtin command
+ *
+ * Copyright (C) 2007 Shawn Bohrer
+ *
+ * Based on git-clean.sh by Pavel Roskin
+ */
+
+#include "builtin.h"
+#include "cache.h"
+#include "dir.h"
+#include "parse-options.h"
+
+static int force = -1; /* unset */
+
+static const char *const builtin_clean_usage[] = {
+ "git-clean [-d] [-f] [-n] [-q] [-x | -X] [--] <paths>...",
+ NULL
+};
+
+static int git_clean_config(const char *var, const char *value)
+{
+ if (!strcmp(var, "clean.requireforce"))
+ force = !git_config_bool(var, value);
+ return git_default_config(var, value);
+}
+
+int cmd_clean(int argc, const char **argv, const char *prefix)
+{
+ int j;
+ 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;
+ struct option options[] = {
+ OPT__QUIET(&quiet),
+ OPT__DRY_RUN(&show_only),
+ OPT_BOOLEAN('f', NULL, &force, "force"),
+ OPT_BOOLEAN('d', NULL, &remove_directories,
+ "remove whole directories"),
+ OPT_BOOLEAN('x', NULL, &ignored, "remove ignored files, too"),
+ OPT_BOOLEAN('X', NULL, &ignored_only,
+ "remove only ignored files"),
+ OPT_END()
+ };
+
+ git_config(git_clean_config);
+ if (force < 0)
+ force = 0;
+ else
+ config_set = 1;
+
+ argc = parse_options(argc, argv, options, builtin_clean_usage, 0);
+
+ memset(&dir, 0, sizeof(dir));
+ if (ignored_only)
+ dir.show_ignored = 1;
+
+ if (ignored && ignored_only)
+ die("-x and -X cannot be used together");
+
+ if (!show_only && !force)
+ die("clean.requireForce%s set and -n or -f not given; "
+ "refusing to clean", config_set ? "" : " not");
+
+ dir.show_other_directories = 1;
+
+ if (!ignored)
+ setup_standard_excludes(&dir);
+
+ pathspec = get_pathspec(prefix, argv);
+ read_cache();
+
+ /*
+ * Calculate common prefix for the pathspec, and
+ * use that to optimize the directory walk
+ */
+ baselen = common_prefix(pathspec);
+ path = ".";
+ base = "";
+ if (baselen)
+ path = base = xmemdupz(*pathspec, baselen);
+ 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;
+ struct cache_entry *ce;
+ struct stat st;
+ char *seen;
+
+ /*
+ * Remove the '/' at the end that directory
+ * walking adds for directory entries.
+ */
+ len = ent->len;
+ if (len && ent->name[len-1] == '/')
+ len--;
+ pos = cache_name_pos(ent->name, len);
+ if (0 <= pos)
+ continue; /* exact match */
+ pos = -pos - 1;
+ if (pos < active_nr) {
+ ce = active_cache[pos];
+ if (ce_namelen(ce) == len &&
+ !memcmp(ce->name, ent->name, len))
+ continue; /* Yup, this one exists unmerged */
+ }
+
+ if (!lstat(ent->name, &st) && (S_ISDIR(st.st_mode))) {
+ int matched_path = 0;
+ 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)) {
+ printf("Would remove %s\n", directory.buf);
+ } else if (quiet && (remove_directories || matched_path)) {
+ remove_dir_recursively(&directory, 0);
+ } else if (remove_directories || matched_path) {
+ printf("Removing %s\n", directory.buf);
+ remove_dir_recursively(&directory, 0);
+ } else if (show_only) {
+ printf("Would not remove %s\n", directory.buf);
+ } else {
+ printf("Not removing %s\n", directory.buf);
+ }
+ strbuf_reset(&directory);
+ } else {
+ if (show_only) {
+ printf("Would remove %s\n", ent->name);
+ continue;
+ } else if (!quiet) {
+ printf("Removing %s\n", ent->name);
+ }
+ unlink(ent->name);
+ }
+ }
+
+ strbuf_release(&directory);
+ return 0;
+}
diff --git a/builtin-config.c b/builtin-config.c
index e5e243f27..f672c9ccc 100644
--- a/builtin-config.c
+++ b/builtin-config.c
@@ -81,7 +81,7 @@ static int get_value(const char* key_, const char* regex_)
local = repo_config = xstrdup(git_path("config"));
if (home)
global = xstrdup(mkpath("%s/.gitconfig", home));
- system_wide = ETC_GITCONFIG;
+ system_wide = git_etc_gitconfig();
}
key = xstrdup(key_);
@@ -191,7 +191,7 @@ int cmd_config(int argc, const char **argv, const char *prefix)
}
}
else if (!strcmp(argv[1], "--system"))
- setenv(CONFIG_ENVIRONMENT, ETC_GITCONFIG, 1);
+ setenv(CONFIG_ENVIRONMENT, git_etc_gitconfig(), 1);
else if (!strcmp(argv[1], "--file") || !strcmp(argv[1], "-f")) {
if (argc < 3)
usage(git_config_set_usage);
diff --git a/builtin-diff-files.c b/builtin-diff-files.c
index 6cb30c8e1..046b7e34b 100644
--- a/builtin-diff-files.c
+++ b/builtin-diff-files.c
@@ -31,5 +31,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix)
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_RAW;
result = run_diff_files_cmd(&rev, argc, argv);
- return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result;
+ if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
+ return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
+ return result;
}
diff --git a/builtin-diff-index.c b/builtin-diff-index.c
index 81e716743..556c506bf 100644
--- a/builtin-diff-index.c
+++ b/builtin-diff-index.c
@@ -44,5 +44,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix)
return -1;
}
result = run_diff_index(&rev, cached);
- return rev.diffopt.exit_with_status ? rev.diffopt.has_changes: result;
+ if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
+ return DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
+ return result;
}
diff --git a/builtin-diff-tree.c b/builtin-diff-tree.c
index 0b591c871..2e13716ee 100644
--- a/builtin-diff-tree.c
+++ b/builtin-diff-tree.c
@@ -118,8 +118,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
}
if (!read_stdin)
- return opt->diffopt.exit_with_status ?
- opt->diffopt.has_changes: 0;
+ return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
+ && DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
if (opt->diffopt.detect_rename)
opt->diffopt.setup |= (DIFF_SETUP_USE_SIZE_CACHE |
@@ -134,5 +134,6 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix)
else
diff_tree_stdin(line);
}
- return opt->diffopt.exit_with_status ? opt->diffopt.has_changes: 0;
+ return DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)
+ && DIFF_OPT_TST(&opt->diffopt, HAS_CHANGES);
}
diff --git a/builtin-diff.c b/builtin-diff.c
index f557d2192..1b615991e 100644
--- a/builtin-diff.c
+++ b/builtin-diff.c
@@ -35,7 +35,7 @@ static void stuff_change(struct diff_options *opt,
!hashcmp(old_sha1, new_sha1) && (old_mode == new_mode))
return;
- if (opt->reverse_diff) {
+ if (DIFF_OPT_TST(opt, REVERSE_DIFF)) {
unsigned tmp;
const unsigned char *tmp_u;
const char *tmp_c;
@@ -253,13 +253,13 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
if (diff_setup_done(&rev.diffopt) < 0)
die("diff_setup_done failed");
}
- rev.diffopt.allow_external = 1;
- rev.diffopt.recursive = 1;
+ DIFF_OPT_SET(&rev.diffopt, ALLOW_EXTERNAL);
+ DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
/* If the user asked for our exit code then don't start a
* pager or we would end up reporting its exit code instead.
*/
- if (!rev.diffopt.exit_with_status)
+ if (!DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
setup_pager();
/* Do we have --cached and not have a pending object, then
@@ -363,8 +363,8 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
else
result = builtin_diff_combined(&rev, argc, argv,
ent, ents);
- if (rev.diffopt.exit_with_status)
- result = rev.diffopt.has_changes;
+ if (DIFF_OPT_TST(&rev.diffopt, EXIT_WITH_STATUS))
+ result = DIFF_OPT_TST(&rev.diffopt, HAS_CHANGES) != 0;
if (1 < rev.diffopt.skip_stat_unmatch)
refresh_index_quietly();
diff --git a/builtin-fetch--tool.c b/builtin-fetch--tool.c
index 6a7851795..ed60847d9 100644
--- a/builtin-fetch--tool.c
+++ b/builtin-fetch--tool.c
@@ -435,9 +435,7 @@ static int pick_rref(int sha1_only, const char *rref, const char *ls_remote_resu
cp++;
if (!*cp)
break;
- np = strchr(cp, '\n');
- if (!np)
- np = cp + strlen(cp);
+ np = strchrnul(cp, '\n');
if (pass) {
lrr_list[i].line = cp;
lrr_list[i].name = cp + 41;
@@ -461,9 +459,7 @@ static int pick_rref(int sha1_only, const char *rref, const char *ls_remote_resu
rref++;
if (!*rref)
break;
- next = strchr(rref, '\n');
- if (!next)
- next = rref + strlen(rref);
+ next = strchrnul(rref, '\n');
rreflen = next - rref;
for (i = 0; i < lrr_count; i++) {
diff --git a/builtin-fetch-pack.c b/builtin-fetch-pack.c
index bb1742f1a..807fa93b5 100644
--- a/builtin-fetch-pack.c
+++ b/builtin-fetch-pack.c
@@ -462,34 +462,12 @@ static int sideband_demux(int fd, void *data)
{
int *xd = data;
- close(xd[1]);
return recv_sideband("fetch-pack", xd[0], fd, 2);
}
-static void setup_sideband(int fd[2], int xd[2], struct async *demux)
-{
- if (!use_sideband) {
- fd[0] = xd[0];
- fd[1] = xd[1];
- return;
- }
- /* xd[] is talking with upload-pack; subprocess reads from
- * xd[0], spits out band#2 to stderr, and feeds us band#1
- * through demux->out.
- */
- demux->proc = sideband_demux;
- demux->data = xd;
- if (start_async(demux))
- die("fetch-pack: unable to fork off sideband demultiplexer");
- close(xd[0]);
- fd[0] = demux->out;
- fd[1] = xd[1];
-}
-
static int get_pack(int xd[2], char **pack_lockfile)
{
struct async demux;
- int fd[2];
const char *argv[20];
char keep_arg[256];
char hdr_arg[256];
@@ -497,7 +475,20 @@ static int get_pack(int xd[2], char **pack_lockfile)
int do_keep = args.keep_pack;
struct child_process cmd;
- setup_sideband(fd, xd, &demux);
+ memset(&demux, 0, sizeof(demux));
+ if (use_sideband) {
+ /* xd[] is talking with upload-pack; subprocess reads from
+ * xd[0], spits out band#2 to stderr, and feeds us band#1
+ * through demux->out.
+ */
+ demux.proc = sideband_demux;
+ demux.data = xd;
+ if (start_async(&demux))
+ die("fetch-pack: unable to fork off sideband"
+ " demultiplexer");
+ }
+ else
+ demux.out = xd[0];
memset(&cmd, 0, sizeof(cmd));
cmd.argv = argv;
@@ -506,7 +497,7 @@ static int get_pack(int xd[2], char **pack_lockfile)
if (!args.keep_pack && unpack_limit) {
struct pack_header header;
- if (read_pack_header(fd[0], &header))
+ if (read_pack_header(demux.out, &header))
die("protocol error: bad pack header");
snprintf(hdr_arg, sizeof(hdr_arg), "--pack_header=%u,%u",
ntohl(header.hdr_version), ntohl(header.hdr_entries));
@@ -542,11 +533,10 @@ static int get_pack(int xd[2], char **pack_lockfile)
*av++ = hdr_arg;
*av++ = NULL;
- cmd.in = fd[0];
+ cmd.in = demux.out;
cmd.git_cmd = 1;
if (start_command(&cmd))
die("fetch-pack: unable to fork off %s", argv[0]);
- close(fd[1]);
if (do_keep && pack_lockfile)
*pack_lockfile = index_pack_lockfile(cmd.out);
diff --git a/builtin-fetch.c b/builtin-fetch.c
index 6b1750d28..31e138eab 100644
--- a/builtin-fetch.c
+++ b/builtin-fetch.c
@@ -8,10 +8,12 @@
#include "path-list.h"
#include "remote.h"
#include "transport.h"
+#include "run-command.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 int append, force, tags, no_tags, update_head_ok, verbose, quiet;
+static const char *depth;
static char *default_rla = NULL;
static struct transport *transport;
@@ -152,6 +154,7 @@ static int s_update_ref(const char *action,
}
#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
+#define REFCOL_WIDTH 10
static int update_local_ref(struct ref *ref,
const char *remote,
@@ -181,8 +184,9 @@ static int update_local_ref(struct ref *ref,
if (!hashcmp(ref->old_sha1, ref->new_sha1)) {
if (verbose)
- sprintf(display, "= %-*s %s -> %s", SUMMARY_WIDTH,
- "[up to date]", remote, pretty_ref);
+ sprintf(display, "= %-*s %-*s -> %s", SUMMARY_WIDTH,
+ "[up to date]", REFCOL_WIDTH, remote,
+ pretty_ref);
return 0;
}
@@ -194,15 +198,17 @@ static int update_local_ref(struct ref *ref,
* If this is the head, and it's not okay to update
* the head, and the old value of the head isn't empty...
*/
- sprintf(display, "! %-*s %s -> %s (can't fetch in current branch)",
- SUMMARY_WIDTH, "[rejected]", remote, pretty_ref);
+ sprintf(display, "! %-*s %-*s -> %s (can't fetch in current branch)",
+ SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
+ pretty_ref);
return 1;
}
if (!is_null_sha1(ref->old_sha1) &&
!prefixcmp(ref->name, "refs/tags/")) {
- sprintf(display, "- %-*s %s -> %s",
- SUMMARY_WIDTH, "[tag update]", remote, pretty_ref);
+ sprintf(display, "- %-*s %-*s -> %s",
+ SUMMARY_WIDTH, "[tag update]", REFCOL_WIDTH, remote,
+ pretty_ref);
return s_update_ref("updating tag", ref, 0);
}
@@ -220,8 +226,8 @@ static int update_local_ref(struct ref *ref,
what = "[new branch]";
}
- sprintf(display, "* %-*s %s -> %s",
- SUMMARY_WIDTH, what, remote, pretty_ref);
+ sprintf(display, "* %-*s %-*s -> %s", SUMMARY_WIDTH, what,
+ REFCOL_WIDTH, remote, pretty_ref);
return s_update_ref(msg, ref, 0);
}
@@ -230,20 +236,21 @@ static int update_local_ref(struct ref *ref,
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
strcat(quickref, "..");
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
- sprintf(display, " %-*s %s -> %s (fast forward)",
- SUMMARY_WIDTH, quickref, remote, pretty_ref);
+ sprintf(display, " %-*s %-*s -> %s", SUMMARY_WIDTH, quickref,
+ REFCOL_WIDTH, remote, pretty_ref);
return s_update_ref("fast forward", ref, 1);
} else if (force || ref->force) {
char quickref[84];
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
strcat(quickref, "...");
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
- sprintf(display, "+ %-*s %s -> %s (forced update)",
- SUMMARY_WIDTH, quickref, remote, pretty_ref);
+ sprintf(display, "+ %-*s %-*s -> %s (forced update)",
+ SUMMARY_WIDTH, quickref, REFCOL_WIDTH, remote, pretty_ref);
return s_update_ref("forced-update", ref, 1);
} else {
- sprintf(display, "! %-*s %s -> %s (non fast forward)",
- SUMMARY_WIDTH, "[rejected]", remote, pretty_ref);
+ sprintf(display, "! %-*s %-*s -> %s (non fast forward)",
+ SUMMARY_WIDTH, "[rejected]", REFCOL_WIDTH, remote,
+ pretty_ref);
return 1;
}
}
@@ -330,9 +337,72 @@ static void store_updated_refs(const char *url, struct ref *ref_map)
fclose(fp);
}
+/*
+ * We would want to bypass the object transfer altogether if
+ * everything we are going to fetch already exists and connected
+ * locally.
+ *
+ * The refs we are going to fetch are in to_fetch (nr_heads in
+ * total). If running
+ *
+ * $ git-rev-list --objects to_fetch[0] to_fetch[1] ... --not --all
+ *
+ * does not error out, that means everything reachable from the
+ * refs we are going to fetch exists and is connected to some of
+ * our existing refs.
+ */
+static int quickfetch(struct ref *ref_map)
+{
+ struct child_process revlist;
+ struct ref *ref;
+ char **argv;
+ int i, err;
+
+ /*
+ * If we are deepening a shallow clone we already have these
+ * objects reachable. Running rev-list here will return with
+ * a good (0) exit status and we'll bypass the fetch that we
+ * really need to perform. Claiming failure now will ensure
+ * we perform the network exchange to deepen our history.
+ */
+ if (depth)
+ return -1;
+
+ for (i = 0, ref = ref_map; ref; ref = ref->next)
+ i++;
+ if (!i)
+ return 0;
+
+ argv = xmalloc(sizeof(*argv) * (i + 6));
+ i = 0;
+ argv[i++] = xstrdup("rev-list");
+ argv[i++] = xstrdup("--quiet");
+ argv[i++] = xstrdup("--objects");
+ for (ref = ref_map; ref; ref = ref->next)
+ argv[i++] = xstrdup(sha1_to_hex(ref->old_sha1));
+ argv[i++] = xstrdup("--not");
+ argv[i++] = xstrdup("--all");
+ argv[i++] = NULL;
+
+ memset(&revlist, 0, sizeof(revlist));
+ revlist.argv = (const char**)argv;
+ revlist.git_cmd = 1;
+ revlist.no_stdin = 1;
+ revlist.no_stdout = 1;
+ revlist.no_stderr = 1;
+ err = run_command(&revlist);
+
+ for (i = 0; argv[i]; i++)
+ free(argv[i]);
+ free(argv);
+ return err;
+}
+
static int fetch_refs(struct transport *transport, struct ref *ref_map)
{
- int ret = transport_fetch_refs(transport, ref_map);
+ int ret = quickfetch(ref_map);
+ if (ret)
+ ret = transport_fetch_refs(transport, ref_map);
if (!ret)
store_updated_refs(transport->url, ref_map);
transport_unlock_pack(transport);
@@ -384,7 +454,7 @@ static struct ref *find_non_local_tags(struct transport *transport,
if (!path_list_has_path(&existing_refs, ref_name) &&
!path_list_has_path(&new_refs, ref_name) &&
- lookup_object(ref->old_sha1)) {
+ has_sha1_file(ref->old_sha1)) {
path_list_insert(ref_name, &new_refs);
rm = alloc_ref(strlen(ref_name) + 1);
@@ -468,7 +538,7 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
static const char **refs = NULL;
int ref_nr = 0;
int cmd_len = 0;
- const char *depth = NULL, *upload_pack = NULL;
+ const char *upload_pack = NULL;
int keep = 0;
for (i = 1; i < argc; i++) {
diff --git a/builtin-fmt-merge-msg.c b/builtin-fmt-merge-msg.c
index 8a3c962f8..6163bd497 100644
--- a/builtin-fmt-merge-msg.c
+++ b/builtin-fmt-merge-msg.c
@@ -176,7 +176,7 @@ static void shortlog(const char *name, unsigned char *sha1,
struct commit *commit;
struct object *branch;
struct list subjects = { NULL, NULL, 0, 0 };
- int flags = UNINTERESTING | TREECHANGE | SEEN | SHOWN | ADDED;
+ int flags = UNINTERESTING | TREESAME | SEEN | SHOWN | ADDED;
branch = deref_tag(parse_object(sha1), sha1_to_hex(sha1), 40);
if (!branch || branch->type != OBJ_COMMIT)
diff --git a/builtin-for-each-ref.c b/builtin-for-each-ref.c
index bfde2e2bb..daf3a0816 100644
--- a/builtin-for-each-ref.c
+++ b/builtin-for-each-ref.c
@@ -833,16 +833,19 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
int i, num_refs;
const char *format = "%(objectname) %(objecttype)\t%(refname)";
struct ref_sort *sort = NULL, **sort_tail = &sort;
- int maxcount = 0, quote_style;
- int quote_shell = 0, quote_perl = 0, quote_python = 0, quote_tcl = 0;
+ int maxcount = 0, quote_style = 0;
struct refinfo **refs;
struct grab_ref_cbdata cbdata;
struct option opts[] = {
- OPT_BOOLEAN('s', "shell", &quote_shell, "quote placeholders suitably for shells"),
- OPT_BOOLEAN('p', "perl", &quote_perl, "quote placeholders suitably for perl"),
- OPT_BOOLEAN( 0 , "python", &quote_python, "quote placeholders suitably for python"),
- OPT_BOOLEAN( 0 , "tcl", &quote_tcl, "quote placeholders suitably for tcl"),
+ OPT_BIT('s', "shell", &quote_style,
+ "quote placeholders suitably for shells", QUOTE_SHELL),
+ OPT_BIT('p', "perl", &quote_style,
+ "quote placeholders suitably for perl", QUOTE_PERL),
+ OPT_BIT(0 , "python", &quote_style,
+ "quote placeholders suitably for python", QUOTE_PYTHON),
+ OPT_BIT(0 , "tcl", &quote_style,
+ "quote placeholders suitably for tcl", QUOTE_TCL),
OPT_GROUP(""),
OPT_INTEGER( 0 , "count", &maxcount, "show only <n> matched refs"),
@@ -857,15 +860,13 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
error("invalid --count argument: `%d'", maxcount);
usage_with_options(for_each_ref_usage, opts);
}
- if (quote_shell + quote_perl + quote_python + quote_tcl > 1) {
+ if (HAS_MULTI_BITS(quote_style)) {
error("more than one quoting style ?");
usage_with_options(for_each_ref_usage, opts);
}
if (verify_format(format))
usage_with_options(for_each_ref_usage, opts);
- quote_style = QUOTE_SHELL * quote_shell + QUOTE_PERL * quote_perl +
- QUOTE_PYTHON * quote_python + QUOTE_TCL * quote_tcl;
if (!sort)
sort = default_sort();
sort_atom_limit = used_atom_cnt;
diff --git a/builtin-grep.c b/builtin-grep.c
index 185876b0a..bbf747fc7 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -294,7 +294,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
if (opt->pre_context) {
push_arg("-B");
len += snprintf(argptr, sizeof(randarg)-len,
- "%u", opt->pre_context);
+ "%u", opt->pre_context) + 1;
if (sizeof(randarg) <= len)
die("maximum length of args exceeded");
push_arg(argptr);
@@ -303,7 +303,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
if (opt->post_context) {
push_arg("-A");
len += snprintf(argptr, sizeof(randarg)-len,
- "%u", opt->post_context);
+ "%u", opt->post_context) + 1;
if (sizeof(randarg) <= len)
die("maximum length of args exceeded");
push_arg(argptr);
@@ -313,7 +313,7 @@ static int external_grep(struct grep_opt *opt, const char **paths, int cached)
else {
push_arg("-C");
len += snprintf(argptr, sizeof(randarg)-len,
- "%u", opt->post_context);
+ "%u", opt->post_context) + 1;
if (sizeof(randarg) <= len)
die("maximum length of args exceeded");
push_arg(argptr);
diff --git a/builtin-init-db.c b/builtin-init-db.c
index 763fa55e7..e1393b8d1 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -5,6 +5,7 @@
*/
#include "cache.h"
#include "builtin.h"
+#include "exec_cmd.h"
#ifndef DEFAULT_GIT_TEMPLATE_DIR
#define DEFAULT_GIT_TEMPLATE_DIR "/usr/share/git-core/templates"
@@ -131,10 +132,19 @@ static void copy_templates(const char *git_dir, int len, const char *template_di
int template_len;
DIR *dir;
- if (!template_dir) {
+ if (!template_dir)
template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
- if (!template_dir)
- template_dir = DEFAULT_GIT_TEMPLATE_DIR;
+ if (!template_dir) {
+ /*
+ * if the hard-coded template is relative, it is
+ * interpreted relative to the exec_dir
+ */
+ template_dir = DEFAULT_GIT_TEMPLATE_DIR;
+ if (!is_absolute_path(template_dir)) {
+ const char *exec_path = git_exec_path();
+ template_dir = prefix_path(exec_path, strlen(exec_path),
+ template_dir);
+ }
}
strcpy(template_path, template_dir);
template_len = strlen(template_path);
diff --git a/builtin-log.c b/builtin-log.c
index 8b2bf632c..e1f1cf671 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -55,13 +55,13 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
rev->abbrev = DEFAULT_ABBREV;
rev->commit_format = CMIT_FMT_DEFAULT;
rev->verbose_header = 1;
- rev->diffopt.recursive = 1;
+ DIFF_OPT_SET(&rev->diffopt, RECURSIVE);
rev->show_root_diff = default_show_root;
rev->subject_prefix = fmt_patch_subject_prefix;
argc = setup_revisions(argc, argv, rev, "HEAD");
if (rev->diffopt.pickaxe || rev->diffopt.filter)
rev->always_show_header = 0;
- if (rev->diffopt.follow_renames) {
+ if (DIFF_OPT_TST(&rev->diffopt, FOLLOW_RENAMES)) {
rev->always_show_header = 0;
if (rev->diffopt.nr_paths != 1)
usage("git logs can only follow renames on one pathname at a time");
@@ -77,11 +77,134 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix,
}
}
+/*
+ * This gives a rough estimate for how many commits we
+ * will print out in the list.
+ */
+static int estimate_commit_count(struct rev_info *rev, struct commit_list *list)
+{
+ int n = 0;
+
+ while (list) {
+ struct commit *commit = list->item;
+ unsigned int flags = commit->object.flags;
+ list = list->next;
+ if (!(flags & (TREESAME | UNINTERESTING)))
+ n++;
+ }
+ return n;
+}
+
+static void show_early_header(struct rev_info *rev, const char *stage, int nr)
+{
+ if (rev->shown_one) {
+ rev->shown_one = 0;
+ if (rev->commit_format != CMIT_FMT_ONELINE)
+ putchar(rev->diffopt.line_termination);
+ }
+ printf("Final output: %d %s\n", nr, stage);
+}
+
+struct itimerval early_output_timer;
+
+static void log_show_early(struct rev_info *revs, struct commit_list *list)
+{
+ int i = revs->early_output;
+ int show_header = 1;
+
+ sort_in_topological_order(&list, revs->lifo);
+ while (list && i) {
+ struct commit *commit = list->item;
+ switch (simplify_commit(revs, commit)) {
+ case commit_show:
+ if (show_header) {
+ int n = estimate_commit_count(revs, list);
+ show_early_header(revs, "incomplete", n);
+ show_header = 0;
+ }
+ log_tree_commit(revs, commit);
+ i--;
+ break;
+ case commit_ignore:
+ break;
+ case commit_error:
+ return;
+ }
+ list = list->next;
+ }
+
+ /* Did we already get enough commits for the early output? */
+ if (!i)
+ return;
+
+ /*
+ * ..if no, then repeat it twice a second until we
+ * do.
+ *
+ * NOTE! We don't use "it_interval", because if the
+ * reader isn't listening, we want our output to be
+ * throttled by the writing, and not have the timer
+ * trigger every second even if we're blocked on a
+ * reader!
+ */
+ early_output_timer.it_value.tv_sec = 0;
+ early_output_timer.it_value.tv_usec = 500000;
+ setitimer(ITIMER_REAL, &early_output_timer, NULL);
+}
+
+static void early_output(int signal)
+{
+ show_early_output = log_show_early;
+}
+
+static void setup_early_output(struct rev_info *rev)
+{
+ struct sigaction sa;
+
+ /*
+ * Set up the signal handler, minimally intrusively:
+ * we only set a single volatile integer word (not
+ * using sigatomic_t - trying to avoid unnecessary
+ * system dependencies and headers), and using
+ * SA_RESTART.
+ */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = early_output;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ sigaction(SIGALRM, &sa, NULL);
+
+ /*
+ * If we can get the whole output in less than a
+ * tenth of a second, don't even bother doing the
+ * early-output thing..
+ *
+ * This is a one-time-only trigger.
+ */
+ early_output_timer.it_value.tv_sec = 0;
+ early_output_timer.it_value.tv_usec = 100000;
+ setitimer(ITIMER_REAL, &early_output_timer, NULL);
+}
+
+static void finish_early_output(struct rev_info *rev)
+{
+ int n = estimate_commit_count(rev, rev->commits);
+ signal(SIGALRM, SIG_IGN);
+ show_early_header(rev, "done", n);
+}
+
static int cmd_log_walk(struct rev_info *rev)
{
struct commit *commit;
+ if (rev->early_output)
+ setup_early_output(rev);
+
prepare_revision_walk(rev);
+
+ if (rev->early_output)
+ finish_early_output(rev);
+
while ((commit = get_revision(rev)) != NULL) {
log_tree_commit(rev, commit);
if (!rev->reflog_info) {
@@ -185,11 +308,9 @@ int cmd_show(int argc, const char **argv, const char *prefix)
struct tag *t = (struct tag *)o;
printf("%stag %s%s\n\n",
- diff_get_color(rev.diffopt.color_diff,
- DIFF_COMMIT),
+ diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
t->tag,
- diff_get_color(rev.diffopt.color_diff,
- DIFF_RESET));
+ diff_get_color_opt(&rev.diffopt, DIFF_RESET));
ret = show_object(o->sha1, 1);
objects[i].item = (struct object *)t->tagged;
i--;
@@ -197,11 +318,9 @@ int cmd_show(int argc, const char **argv, const char *prefix)
}
case OBJ_TREE:
printf("%stree %s%s\n\n",
- diff_get_color(rev.diffopt.color_diff,
- DIFF_COMMIT),
+ diff_get_color_opt(&rev.diffopt, DIFF_COMMIT),
name,
- diff_get_color(rev.diffopt.color_diff,
- DIFF_RESET));
+ diff_get_color_opt(&rev.diffopt, DIFF_RESET));
read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
show_tree_object);
break;
@@ -273,6 +392,8 @@ static int istitlechar(char c)
static char *extra_headers = NULL;
static int extra_headers_size = 0;
static const char *fmt_patch_suffix = ".patch";
+static int numbered = 0;
+static int auto_number = 0;
static int git_format_config(const char *var, const char *value)
{
@@ -297,6 +418,15 @@ static int git_format_config(const char *var, const char *value)
if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
return 0;
}
+ if (!strcmp(var, "format.numbered")) {
+ if (!strcasecmp(value, "auto")) {
+ auto_number = 1;
+ return 0;
+ }
+
+ numbered = git_config_bool(var, value);
+ return 0;
+ }
return git_log_config(var, value);
}
@@ -466,7 +596,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
struct rev_info rev;
int nr = 0, total, i, j;
int use_stdout = 0;
- int numbered = 0;
int start_number = -1;
int keep_subject = 0;
int numbered_files = 0; /* _just_ numbers */
@@ -487,7 +616,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
rev.combine_merges = 0;
rev.ignore_merges = 1;
rev.diffopt.msg_sep = "";
- rev.diffopt.recursive = 1;
+ DIFF_OPT_SET(&rev.diffopt, RECURSIVE);
rev.subject_prefix = fmt_patch_subject_prefix;
rev.extra_headers = extra_headers;
@@ -503,6 +632,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
else if (!strcmp(argv[i], "-n") ||
!strcmp(argv[i], "--numbered"))
numbered = 1;
+ else if (!strcmp(argv[i], "-N") ||
+ !strcmp(argv[i], "--no-numbered")) {
+ numbered = 0;
+ auto_number = 0;
+ }
else if (!prefixcmp(argv[i], "--start-number="))
start_number = strtol(argv[i] + 15, NULL, 10);
else if (!strcmp(argv[i], "--numbered-files"))
@@ -590,8 +724,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
if (!rev.diffopt.output_format)
rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH;
- if (!rev.diffopt.text)
- rev.diffopt.binary = 1;
+ if (!DIFF_OPT_TST(&rev.diffopt, TEXT))
+ DIFF_OPT_SET(&rev.diffopt, BINARY);
if (!output_directory && !use_stdout)
output_directory = prefix;
@@ -642,6 +776,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
list[nr - 1] = commit;
}
total = nr;
+ if (!keep_subject && auto_number && total > 1)
+ numbered = 1;
if (numbered)
rev.total = total + start_number - 1;
rev.add_signoff = add_signoff;
@@ -747,7 +883,7 @@ int cmd_cherry(int argc, const char **argv, const char *prefix)
revs.diff = 1;
revs.combine_merges = 0;
revs.ignore_merges = 1;
- revs.diffopt.recursive = 1;
+ DIFF_OPT_SET(&revs.diffopt, RECURSIVE);
if (add_pending_commit(head, &revs, 0))
die("Unknown commit %s", head);
diff --git a/builtin-ls-files.c b/builtin-ls-files.c
index e0b856f43..7f6070983 100644
--- a/builtin-ls-files.c
+++ b/builtin-ls-files.c
@@ -387,8 +387,8 @@ static void overlay_tree(const char *tree_name, const char *prefix)
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>] "
- "[ --exclude-per-directory=<filename> ] [--full-name] [--abbrev] "
- "[--] [<file>]*";
+ "[ --exclude-per-directory=<filename> ] [--exclude-standard] "
+ "[--full-name] [--abbrev] [--] [<file>]*";
int cmd_ls_files(int argc, const char **argv, const char *prefix)
{
@@ -496,6 +496,11 @@ int cmd_ls_files(int argc, const char **argv, const char *prefix)
dir.exclude_per_dir = arg + 24;
continue;
}
+ if (!strcmp(arg, "--exclude-standard")) {
+ exc_given = 1;
+ setup_standard_excludes(&dir);
+ continue;
+ }
if (!strcmp(arg, "--full-name")) {
prefix_offset = 0;
continue;
diff --git a/builtin-merge-ours.c b/builtin-merge-ours.c
new file mode 100644
index 000000000..8f5bbaf40
--- /dev/null
+++ b/builtin-merge-ours.c
@@ -0,0 +1,28 @@
+/*
+ * Implementation of git-merge-ours.sh as builtin
+ *
+ * Copyright (c) 2007 Thomas Harning Jr
+ * Original:
+ * Original Copyright (c) 2005 Junio C Hamano
+ *
+ * Pretend we resolved the heads, but declare our tree trumps everybody else.
+ */
+#include "git-compat-util.h"
+#include "builtin.h"
+
+static const char *diff_index_args[] = {
+ "diff-index", "--quiet", "--cached", "HEAD", "--", NULL
+};
+#define NARGS (ARRAY_SIZE(diff_index_args) - 1)
+
+int cmd_merge_ours(int argc, const char **argv, const char *prefix)
+{
+ /*
+ * We need to exit with 2 if the index does not match our HEAD tree,
+ * because the current index is what we will be committing as the
+ * merge result.
+ */
+ if (cmd_diff_index(NARGS, diff_index_args, prefix))
+ exit(2);
+ exit(0);
+}
diff --git a/builtin-pack-objects.c b/builtin-pack-objects.c
index 545ece5da..4f446588a 100644
--- a/builtin-pack-objects.c
+++ b/builtin-pack-objects.c
@@ -990,7 +990,7 @@ static void add_pbase_object(struct tree_desc *tree,
return;
if (name[cmplen] != '/') {
add_object_entry(entry.sha1,
- S_ISDIR(entry.mode) ? OBJ_TREE : OBJ_BLOB,
+ object_type(entry.mode),
fullname, 1);
return;
}
diff --git a/builtin-pack-refs.c b/builtin-pack-refs.c
index a62f06bb8..1923fb191 100644
--- a/builtin-pack-refs.c
+++ b/builtin-pack-refs.c
@@ -122,19 +122,13 @@ static char const * const pack_refs_usage[] = {
int cmd_pack_refs(int argc, const char **argv, const char *prefix)
{
- int all = 0, prune = 1;
- unsigned int flags = 0;
+ unsigned int flags = PACK_REFS_PRUNE;
struct option opts[] = {
- OPT_BOOLEAN(0, "all", &all, "pack everything"),
- OPT_BOOLEAN(0, "prune", &prune, "prune loose refs (default)"),
+ OPT_BIT(0, "all", &flags, "pack everything", PACK_REFS_ALL),
+ OPT_BIT(0, "prune", &flags, "prune loose refs (default)", PACK_REFS_PRUNE),
OPT_END(),
};
-
if (parse_options(argc, argv, opts, pack_refs_usage, 0))
usage_with_options(pack_refs_usage, opts);
- if (prune)
- flags |= PACK_REFS_PRUNE;
- if (all)
- flags |= PACK_REFS_ALL;
return pack_refs(flags);
}
diff --git a/builtin-rev-list.c b/builtin-rev-list.c
index 697046723..1cb5f6711 100644
--- a/builtin-rev-list.c
+++ b/builtin-rev-list.c
@@ -26,6 +26,7 @@ static const char rev_list_usage[] =
" --remove-empty\n"
" --all\n"
" --stdin\n"
+" --quiet\n"
" ordering output:\n"
" --topo-order\n"
" --date-order\n"
@@ -50,6 +51,7 @@ static int show_timestamp;
static int hdr_termination;
static const char *header_prefix;
+static void finish_commit(struct commit *commit);
static void show_commit(struct commit *commit)
{
if (show_timestamp)
@@ -93,6 +95,11 @@ static void show_commit(struct commit *commit)
strbuf_release(&buf);
}
maybe_flush_or_die(stdout, "stdout");
+ finish_commit(commit);
+}
+
+static void finish_commit(struct commit *commit)
+{
if (commit->parents) {
free_commit_list(commit->parents);
commit->parents = NULL;
@@ -101,6 +108,12 @@ static void show_commit(struct commit *commit)
commit->buffer = NULL;
}
+static void finish_object(struct object_array_entry *p)
+{
+ if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
+ die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
+}
+
static void show_object(struct object_array_entry *p)
{
/* An object with name "foo\n0000000..." can be used to
@@ -108,9 +121,7 @@ static void show_object(struct object_array_entry *p)
*/
const char *ep = strchr(p->name, '\n');
- if (p->item->type == OBJ_BLOB && !has_sha1_file(p->item->sha1))
- die("missing blob object '%s'", sha1_to_hex(p->item->sha1));
-
+ finish_object(p);
if (ep) {
printf("%s %.*s\n", sha1_to_hex(p->item->sha1),
(int) (ep - p->name),
@@ -142,7 +153,7 @@ static int count_distance(struct commit_list *entry)
if (commit->object.flags & (UNINTERESTING | COUNTED))
break;
- if (!revs.prune_fn || (commit->object.flags & TREECHANGE))
+ if (!(commit->object.flags & TREESAME))
nr++;
commit->object.flags |= COUNTED;
p = commit->parents;
@@ -198,7 +209,7 @@ static inline int halfway(struct commit_list *p, int nr)
/*
* Don't short-cut something we are not going to return!
*/
- if (revs.prune_fn && !(p->item->object.flags & TREECHANGE))
+ if (p->item->object.flags & TREESAME)
return 0;
if (DEBUG_BISECT)
return 0;
@@ -234,7 +245,7 @@ static void show_list(const char *debug, int counted, int nr,
char *ep, *sp;
fprintf(stderr, "%c%c%c ",
- (flags & TREECHANGE) ? 'T' : ' ',
+ (flags & TREESAME) ? ' ' : 'T',
(flags & UNINTERESTING) ? 'U' : ' ',
(flags & COUNTED) ? 'C' : ' ');
if (commit->util)
@@ -268,7 +279,7 @@ static struct commit_list *best_bisection(struct commit_list *list, int nr)
int distance;
unsigned flags = p->item->object.flags;
- if (revs.prune_fn && !(flags & TREECHANGE))
+ if (flags & TREESAME)
continue;
distance = weight(p);
if (nr - distance < distance)
@@ -308,7 +319,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
int distance;
unsigned flags = p->item->object.flags;
- if (revs.prune_fn && !(flags & TREECHANGE))
+ if (flags & TREESAME)
continue;
distance = weight(p);
if (nr - distance < distance)
@@ -362,7 +373,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
p->item->util = &weights[n++];
switch (count_interesting_parents(commit)) {
case 0:
- if (!revs.prune_fn || (flags & TREECHANGE)) {
+ if (!(flags & TREESAME)) {
weight_set(p, 1);
counted++;
show_list("bisection 2 count one",
@@ -435,7 +446,7 @@ static struct commit_list *do_find_bisection(struct commit_list *list,
* add one for p itself if p is to be counted,
* otherwise inherit it from q directly.
*/
- if (!revs.prune_fn || (flags & TREECHANGE)) {
+ if (!(flags & TREESAME)) {
weight_set(p, weight(q)+1);
counted++;
show_list("bisection 2 count one",
@@ -482,7 +493,7 @@ static struct commit_list *find_bisection(struct commit_list *list,
continue;
p->next = last;
last = p;
- if (!revs.prune_fn || (flags & TREECHANGE))
+ if (!(flags & TREESAME))
nr++;
on_list++;
}
@@ -527,6 +538,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
int read_from_stdin = 0;
int bisect_show_vars = 0;
int bisect_find_all = 0;
+ int quiet = 0;
git_config(git_default_config);
init_revisions(&revs, prefix);
@@ -565,6 +577,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
read_revisions_from_stdin(&revs);
continue;
}
+ if (!strcmp(arg, "--quiet")) {
+ quiet = 1;
+ continue;
+ }
usage(rev_list_usage);
}
@@ -640,7 +656,9 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix)
}
}
- traverse_commit_list(&revs, show_commit, show_object);
+ traverse_commit_list(&revs,
+ quiet ? finish_commit : show_commit,
+ quiet ? finish_object : show_object);
return 0;
}
diff --git a/builtin-rev-parse.c b/builtin-rev-parse.c
index 8d78b69c9..d1038a0e6 100644
--- a/builtin-rev-parse.c
+++ b/builtin-rev-parse.c
@@ -8,6 +8,7 @@
#include "refs.h"
#include "quote.h"
#include "builtin.h"
+#include "parse-options.h"
#define DO_REVS 1
#define DO_NOREV 2
@@ -209,13 +210,138 @@ static int try_difference(const char *arg)
return 0;
}
+static int parseopt_dump(const struct option *o, const char *arg, int unset)
+{
+ struct strbuf *parsed = o->value;
+ if (unset)
+ strbuf_addf(parsed, " --no-%s", o->long_name);
+ else if (o->short_name)
+ strbuf_addf(parsed, " -%c", o->short_name);
+ else
+ strbuf_addf(parsed, " --%s", o->long_name);
+ if (arg) {
+ strbuf_addch(parsed, ' ');
+ sq_quote_buf(parsed, arg);
+ }
+ return 0;
+}
+
+static const char *skipspaces(const char *s)
+{
+ while (isspace(*s))
+ s++;
+ return s;
+}
+
+static int cmd_parseopt(int argc, const char **argv, const char *prefix)
+{
+ static int keep_dashdash = 0;
+ static char const * const parseopt_usage[] = {
+ "git-rev-parse --parseopt [options] -- [<args>...]",
+ NULL
+ };
+ static struct option parseopt_opts[] = {
+ OPT_BOOLEAN(0, "keep-dashdash", &keep_dashdash,
+ "keep the `--` passed as an arg"),
+ OPT_END(),
+ };
+
+ struct strbuf sb, parsed;
+ const char **usage = NULL;
+ struct option *opts = NULL;
+ int onb = 0, osz = 0, unb = 0, usz = 0;
+
+ strbuf_init(&parsed, 0);
+ strbuf_addstr(&parsed, "set --");
+ argc = parse_options(argc, argv, parseopt_opts, parseopt_usage,
+ PARSE_OPT_KEEP_DASHDASH);
+ if (argc < 1 || strcmp(argv[0], "--"))
+ usage_with_options(parseopt_usage, parseopt_opts);
+
+ strbuf_init(&sb, 0);
+ /* get the usage up to the first line with a -- on it */
+ for (;;) {
+ if (strbuf_getline(&sb, stdin, '\n') == EOF)
+ die("premature end of input");
+ ALLOC_GROW(usage, unb + 1, usz);
+ if (!strcmp("--", sb.buf)) {
+ if (unb < 1)
+ die("no usage string given before the `--' separator");
+ usage[unb] = NULL;
+ break;
+ }
+ usage[unb++] = strbuf_detach(&sb, NULL);
+ }
+
+ /* parse: (<short>|<short>,<long>|<long>)[=?]? SP+ <help> */
+ while (strbuf_getline(&sb, stdin, '\n') != EOF) {
+ const char *s;
+ struct option *o;
+
+ if (!sb.len)
+ continue;
+
+ ALLOC_GROW(opts, onb + 1, osz);
+ memset(opts + onb, 0, sizeof(opts[onb]));
+
+ o = &opts[onb++];
+ s = strchr(sb.buf, ' ');
+ if (!s || *sb.buf == ' ') {
+ o->type = OPTION_GROUP;
+ o->help = xstrdup(skipspaces(s));
+ continue;
+ }
+
+ o->type = OPTION_CALLBACK;
+ o->help = xstrdup(skipspaces(s));
+ o->value = &parsed;
+ o->callback = &parseopt_dump;
+ switch (s[-1]) {
+ case '=':
+ s--;
+ break;
+ case '?':
+ o->flags = PARSE_OPT_OPTARG;
+ s--;
+ break;
+ default:
+ o->flags = PARSE_OPT_NOARG;
+ break;
+ }
+
+ if (s - sb.buf == 1) /* short option only */
+ o->short_name = *sb.buf;
+ else if (sb.buf[1] != ',') /* long option only */
+ o->long_name = xmemdupz(sb.buf, s - sb.buf);
+ else {
+ o->short_name = *sb.buf;
+ o->long_name = xmemdupz(sb.buf + 2, s - sb.buf - 2);
+ }
+ }
+ strbuf_release(&sb);
+
+ /* put an OPT_END() */
+ ALLOC_GROW(opts, onb + 1, osz);
+ memset(opts + onb, 0, sizeof(opts[onb]));
+ argc = parse_options(argc, argv, opts, usage,
+ keep_dashdash ? PARSE_OPT_KEEP_DASHDASH : 0);
+
+ strbuf_addf(&parsed, " --");
+ sq_quote_argv(&parsed, argv, argc, 0);
+ puts(parsed.buf);
+ return 0;
+}
+
int cmd_rev_parse(int argc, const char **argv, const char *prefix)
{
int i, as_is = 0, verify = 0;
unsigned char sha1[20];
- git_config(git_default_config);
+ if (argc > 1 && !strcmp("--parseopt", argv[1]))
+ return cmd_parseopt(argc - 1, argv + 1, prefix);
+ prefix = setup_git_directory();
+ git_config(git_default_config);
for (i = 1; i < argc; i++) {
const char *arg = argv[i];
diff --git a/builtin-revert.c b/builtin-revert.c
index afc28845f..365b330f9 100644
--- a/builtin-revert.c
+++ b/builtin-revert.c
@@ -258,7 +258,7 @@ static int revert_or_cherry_pick(int argc, const char **argv)
if (get_sha1("HEAD", head))
die ("You do not have a valid HEAD");
wt_status_prepare(&s);
- if (s.commitable || s.workdir_dirty)
+ if (s.commitable)
die ("Dirty index: cannot %s", me);
discard_cache();
}
diff --git a/builtin-tag.c b/builtin-tag.c
index 4aca3dc79..cbb0f04e8 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -246,9 +246,37 @@ static int git_tag_config(const char *var, const char *value)
return git_default_config(var, value);
}
+static void write_tag_body(int fd, const unsigned char *sha1)
+{
+ unsigned long size;
+ enum object_type type;
+ char *buf, *sp, *eob;
+ size_t len;
+
+ buf = read_sha1_file(sha1, &type, &size);
+ if (!buf)
+ return;
+ /* skip header */
+ sp = strstr(buf, "\n\n");
+
+ if (!sp || !size || type != OBJ_TAG) {
+ free(buf);
+ return;
+ }
+ sp += 2; /* skip the 2 LFs */
+ eob = strstr(sp, "\n" PGP_SIGNATURE "\n");
+ if (eob)
+ len = eob - sp;
+ else
+ len = buf + size - sp;
+ write_or_die(fd, sp, len);
+
+ free(buf);
+}
+
static void create_tag(const unsigned char *object, const char *tag,
struct strbuf *buf, int message, int sign,
- unsigned char *result)
+ unsigned char *prev, unsigned char *result)
{
enum object_type type;
char header_buf[1024];
@@ -281,7 +309,11 @@ static void create_tag(const unsigned char *object, const char *tag,
if (fd < 0)
die("could not create file '%s': %s",
path, strerror(errno));
- write_or_die(fd, tag_template, strlen(tag_template));
+
+ if (!is_null_sha1(prev))
+ write_tag_body(fd, prev);
+ else
+ write_or_die(fd, tag_template, strlen(tag_template));
close(fd);
launch_editor(path, buf);
@@ -418,7 +450,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
die("tag '%s' already exists", tag);
if (annotate)
- create_tag(object, tag, &buf, message, sign, object);
+ create_tag(object, tag, &buf, message, sign, prev, object);
lock = lock_any_ref_for_update(ref, prev, 0);
if (!lock)
diff --git a/builtin.h b/builtin.h
index 525107f38..98ada7b7f 100644
--- a/builtin.h
+++ b/builtin.h
@@ -24,6 +24,7 @@ extern int cmd_check_attr(int argc, const char **argv, const char *prefix);
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_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);
@@ -52,6 +53,7 @@ extern int cmd_ls_remote(int argc, const char **argv, const char *prefix);
extern int cmd_mailinfo(int argc, const char **argv, const char *prefix);
extern int cmd_mailsplit(int argc, const char **argv, const char *prefix);
extern int cmd_merge_base(int argc, const char **argv, const char *prefix);
+extern int cmd_merge_ours(int argc, const char **argv, const char *prefix);
extern int cmd_merge_file(int argc, const char **argv, const char *prefix);
extern int cmd_mv(int argc, const char **argv, const char *prefix);
extern int cmd_name_rev(int argc, const char **argv, const char *prefix);
diff --git a/bundle.c b/bundle.c
index e4d60cde6..9b9b9166d 100644
--- a/bundle.c
+++ b/bundle.c
@@ -6,6 +6,7 @@
#include "revision.h"
#include "list-objects.h"
#include "run-command.h"
+#include "refs.h"
static const char bundle_signature[] = "# v2 git bundle\n";
@@ -232,11 +233,17 @@ int create_bundle(struct bundle_header *header, const char *path,
struct object_array_entry *e = revs.pending.objects + i;
unsigned char sha1[20];
char *ref;
+ const char *display_ref;
+ int flag;
if (e->item->flags & UNINTERESTING)
continue;
if (dwim_ref(e->name, strlen(e->name), sha1, &ref) != 1)
continue;
+ if (!resolve_ref(e->name, sha1, 1, &flag))
+ flag = 0;
+ display_ref = (flag & REF_ISSYMREF) ? e->name : ref;
+
/*
* Make sure the refs we wrote out is correct; --max-count and
* other limiting options could have prevented all the tips
@@ -287,7 +294,7 @@ int create_bundle(struct bundle_header *header, const char *path,
ref_count++;
write_or_die(bundle_fd, sha1_to_hex(e->item->sha1), 40);
write_or_die(bundle_fd, " ", 1);
- write_or_die(bundle_fd, ref, strlen(ref));
+ write_or_die(bundle_fd, display_ref, strlen(display_ref));
write_or_die(bundle_fd, "\n", 1);
free(ref);
}
diff --git a/cache.h b/cache.h
index e0c1cc3fe..aaa135bfd 100644
--- a/cache.h
+++ b/cache.h
@@ -175,8 +175,8 @@ extern struct index_state the_index;
#define remove_file_from_cache(path) remove_file_from_index(&the_index, (path))
#define add_file_to_cache(path, verbose) add_file_to_index(&the_index, (path), (verbose))
#define refresh_cache(flags) refresh_index(&the_index, (flags), NULL, NULL)
-#define ce_match_stat(ce, st, really) ie_match_stat(&the_index, (ce), (st), (really))
-#define ce_modified(ce, st, really) ie_modified(&the_index, (ce), (st), (really))
+#define ce_match_stat(ce, st, options) ie_match_stat(&the_index, (ce), (st), (options))
+#define ce_modified(ce, st, options) ie_modified(&the_index, (ce), (st), (options))
#endif
enum object_type {
@@ -268,8 +268,14 @@ extern int remove_file_from_index(struct index_state *, const char *path);
extern int add_file_to_index(struct index_state *, const char *path, int verbose);
extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh);
extern int ce_same_name(struct cache_entry *a, struct cache_entry *b);
-extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, int);
-extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, int);
+
+/* do stat comparison even if CE_VALID is true */
+#define CE_MATCH_IGNORE_VALID 01
+/* do not check the contents but report dirty on racily-clean entries */
+#define CE_MATCH_RACY_IS_DIRTY 02
+extern int ie_match_stat(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+extern int ie_modified(struct index_state *, struct cache_entry *, struct stat *, unsigned int);
+
extern int ce_path_match(const struct cache_entry *ce, const char **pathspec);
extern int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path);
extern int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object);
@@ -284,6 +290,7 @@ extern int refresh_index(struct index_state *, unsigned int flags, const char **
struct lock_file {
struct lock_file *next;
+ int fd;
pid_t owner;
char on_list;
char filename[PATH_MAX];
@@ -564,6 +571,7 @@ extern int git_config_bool(const char *, const char *);
extern int git_config_set(const char *, const char *);
extern int git_config_set_multivar(const char *, const char *, const char *, int);
extern int git_config_rename_section(const char *, const char *);
+extern const char *git_etc_gitconfig(void);
extern int check_repository_format_version(const char *var, const char *value);
#define MAX_GITNAME (1000)
@@ -589,6 +597,7 @@ extern int pager_in_use;
extern int pager_use_color;
extern char *editor_program;
+extern char *excludes_file;
/* base85 */
int decode_85(char *dst, const char *line, int linelen);
diff --git a/check-racy.c b/check-racy.c
index d6a08b4a5..00d92a166 100644
--- a/check-racy.c
+++ b/check-racy.c
@@ -18,7 +18,7 @@ int main(int ac, char **av)
if (ce_match_stat(ce, &st, 0))
dirty++;
- else if (ce_match_stat(ce, &st, 2))
+ else if (ce_match_stat(ce, &st, CE_MATCH_RACY_IS_DIRTY))
racy++;
else
clean++;
diff --git a/combine-diff.c b/combine-diff.c
index fe5a2a195..5a658dc0d 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -664,7 +664,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int mode_differs = 0;
int i, show_hunks;
int working_tree_file = is_null_sha1(elem->sha1);
- int abbrev = opt->full_index ? 40 : DEFAULT_ABBREV;
+ int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
mmfile_t result_file;
context = opt->context;
@@ -784,7 +784,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (show_hunks || mode_differs || working_tree_file) {
const char *abb;
- int use_color = opt->color_diff;
+ int use_color = DIFF_OPT_TST(opt, COLOR_DIFF);
const char *c_meta = diff_get_color(use_color, DIFF_METAINFO);
const char *c_reset = diff_get_color(use_color, DIFF_RESET);
int added = 0;
@@ -836,7 +836,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
dump_quoted_path("+++ /dev/", "null", c_meta, c_reset);
else
dump_quoted_path("+++ b/", elem->path, c_meta, c_reset);
- dump_sline(sline, cnt, num_parent, opt->color_diff);
+ dump_sline(sline, cnt, num_parent, DIFF_OPT_TST(opt, COLOR_DIFF));
}
free(result);
@@ -929,8 +929,8 @@ void diff_tree_combined(const unsigned char *sha1,
diffopts = *opt;
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
- diffopts.recursive = 1;
- diffopts.allow_external = 0;
+ DIFF_OPT_SET(&diffopts, RECURSIVE);
+ DIFF_OPT_CLR(&diffopts, ALLOW_EXTERNAL);
show_log_first = !!rev->loginfo && !rev->no_commit_id;
needsep = 0;
diff --git a/commit.c b/commit.c
index b50926587..f074811ed 100644
--- a/commit.c
+++ b/commit.c
@@ -8,22 +8,6 @@
int save_commit_buffer = 1;
-struct sort_node
-{
- /*
- * the number of children of the associated commit
- * that also occur in the list being sorted.
- */
- unsigned int indegree;
-
- /*
- * reference to original list item that we will re-use
- * on output.
- */
- struct commit_list * list_item;
-
-};
-
const char *commit_type = "commit";
static struct commit *check_commit(struct object *obj,
@@ -431,69 +415,38 @@ struct commit *pop_commit(struct commit_list **stack)
return item;
}
-void topo_sort_default_setter(struct commit *c, void *data)
-{
- c->util = data;
-}
-
-void *topo_sort_default_getter(struct commit *c)
-{
- return c->util;
-}
-
/*
* Performs an in-place topological sort on the list supplied.
*/
void sort_in_topological_order(struct commit_list ** list, int lifo)
{
- sort_in_topological_order_fn(list, lifo, topo_sort_default_setter,
- topo_sort_default_getter);
-}
-
-void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
- topo_sort_set_fn_t setter,
- topo_sort_get_fn_t getter)
-{
- struct commit_list * next = *list;
- struct commit_list * work = NULL, **insert;
- struct commit_list ** pptr = list;
- struct sort_node * nodes;
- struct sort_node * next_nodes;
- int count = 0;
-
- /* determine the size of the list */
- while (next) {
- next = next->next;
- count++;
- }
+ struct commit_list *next, *orig = *list;
+ struct commit_list *work, **insert;
+ struct commit_list **pptr;
- if (!count)
+ if (!orig)
return;
- /* allocate an array to help sort the list */
- nodes = xcalloc(count, sizeof(*nodes));
- /* link the list to the array */
- next_nodes = nodes;
- next=*list;
- while (next) {
- next_nodes->list_item = next;
- setter(next->item, next_nodes);
- next_nodes++;
- next = next->next;
+ *list = NULL;
+
+ /* Mark them and clear the indegree */
+ for (next = orig; next; next = next->next) {
+ struct commit *commit = next->item;
+ commit->object.flags |= TOPOSORT;
+ commit->indegree = 0;
}
+
/* update the indegree */
- next=*list;
- while (next) {
+ for (next = orig; next; next = next->next) {
struct commit_list * parents = next->item->parents;
while (parents) {
- struct commit * parent=parents->item;
- struct sort_node * pn = (struct sort_node *) getter(parent);
+ struct commit *parent = parents->item;
- if (pn)
- pn->indegree++;
- parents=parents->next;
+ if (parent->object.flags & TOPOSORT)
+ parent->indegree++;
+ parents = parents->next;
}
- next=next->next;
}
+
/*
* find the tips
*
@@ -501,55 +454,56 @@ void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
*
* the tips serve as a starting set for the work queue.
*/
- next=*list;
+ work = NULL;
insert = &work;
- while (next) {
- struct sort_node * node = (struct sort_node *) getter(next->item);
+ for (next = orig; next; next = next->next) {
+ struct commit *commit = next->item;
- if (node->indegree == 0) {
- insert = &commit_list_insert(next->item, insert)->next;
- }
- next=next->next;
+ if (!commit->indegree)
+ insert = &commit_list_insert(commit, insert)->next;
}
/* process the list in topological order */
if (!lifo)
sort_by_date(&work);
+
+ pptr = list;
+ *list = NULL;
while (work) {
- struct commit * work_item = pop_commit(&work);
- struct sort_node * work_node = (struct sort_node *) getter(work_item);
- struct commit_list * parents = work_item->parents;
+ struct commit *commit;
+ struct commit_list *parents, *work_item;
- while (parents) {
- struct commit * parent=parents->item;
- struct sort_node * pn = (struct sort_node *) getter(parent);
-
- if (pn) {
- /*
- * parents are only enqueued for emission
- * when all their children have been emitted thereby
- * guaranteeing topological order.
- */
- pn->indegree--;
- if (!pn->indegree) {
- if (!lifo)
- insert_by_date(parent, &work);
- else
- commit_list_insert(parent, &work);
- }
+ work_item = work;
+ work = work_item->next;
+ work_item->next = NULL;
+
+ commit = work_item->item;
+ for (parents = commit->parents; parents ; parents = parents->next) {
+ struct commit *parent=parents->item;
+
+ if (!(parent->object.flags & TOPOSORT))
+ continue;
+
+ /*
+ * parents are only enqueued for emission
+ * when all their children have been emitted thereby
+ * guaranteeing topological order.
+ */
+ if (!--parent->indegree) {
+ if (!lifo)
+ insert_by_date(parent, &work);
+ else
+ commit_list_insert(parent, &work);
}
- parents=parents->next;
}
/*
* work_item is a commit all of whose children
* have already been emitted. we can emit it now.
*/
- *pptr = work_node->list_item;
- pptr = &(*pptr)->next;
- *pptr = NULL;
- setter(work_item, NULL);
+ commit->object.flags &= ~TOPOSORT;
+ *pptr = work_item;
+ pptr = &work_item->next;
}
- free(nodes);
}
/* merge-base stuff */
diff --git a/commit.h b/commit.h
index 13b537293..aa679867a 100644
--- a/commit.h
+++ b/commit.h
@@ -14,6 +14,7 @@ struct commit_list {
struct commit {
struct object object;
void *util;
+ unsigned int indegree;
unsigned long date;
struct commit_list *parents;
struct tree *tree;
@@ -84,31 +85,12 @@ void clear_commit_marks(struct commit *commit, unsigned int mark);
/*
* Performs an in-place topological sort of list supplied.
*
- * Pre-conditions for sort_in_topological_order:
- * all commits in input list and all parents of those
- * commits must have object.util == NULL
- *
- * Pre-conditions for sort_in_topological_order_fn:
- * all commits in input list and all parents of those
- * commits must have getter(commit) == NULL
- *
- * Post-conditions:
* invariant of resulting list is:
* a reachable from b => ord(b) < ord(a)
* in addition, when lifo == 0, commits on parallel tracks are
* sorted in the dates order.
*/
-
-typedef void (*topo_sort_set_fn_t)(struct commit*, void *data);
-typedef void* (*topo_sort_get_fn_t)(struct commit*);
-
-void topo_sort_default_setter(struct commit *c, void *data);
-void *topo_sort_default_getter(struct commit *c);
-
void sort_in_topological_order(struct commit_list ** list, int lifo);
-void sort_in_topological_order_fn(struct commit_list ** list, int lifo,
- topo_sort_set_fn_t setter,
- topo_sort_get_fn_t getter);
struct commit_graft {
unsigned char sha1[20];
@@ -135,4 +117,9 @@ extern int interactive_add(void);
extern void add_files_to_cache(int verbose, const char *prefix, const char **files);
extern int rerere(void);
+static inline int single_parent(struct commit *commit)
+{
+ return commit->parents && !commit->parents->next;
+}
+
#endif /* COMMIT_H */
diff --git a/config.c b/config.c
index dc3148d45..ed96213c4 100644
--- a/config.c
+++ b/config.c
@@ -6,6 +6,7 @@
*
*/
#include "cache.h"
+#include "exec_cmd.h"
#define MAXNAME (256)
@@ -431,6 +432,13 @@ int git_default_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.excludesfile")) {
+ if (!value)
+ die("core.excludesfile without value");
+ excludes_file = xstrdup(value);
+ return 0;
+ }
+
/* Add other config variables here and to Documentation/config.txt. */
return 0;
}
@@ -452,6 +460,21 @@ int git_config_from_file(config_fn_t fn, const char *filename)
return ret;
}
+const char *git_etc_gitconfig(void)
+{
+ static const char *system_wide;
+ if (!system_wide) {
+ system_wide = ETC_GITCONFIG;
+ if (!is_absolute_path(system_wide)) {
+ /* interpret path relative to exec-dir */
+ const char *exec_path = git_exec_path();
+ system_wide = prefix_path(exec_path, strlen(exec_path),
+ system_wide);
+ }
+ }
+ return system_wide;
+}
+
int git_config(config_fn_t fn)
{
int ret = 0;
@@ -464,8 +487,8 @@ int git_config(config_fn_t fn)
* config file otherwise. */
filename = getenv(CONFIG_ENVIRONMENT);
if (!filename) {
- if (!access(ETC_GITCONFIG, R_OK))
- ret += git_config_from_file(fn, ETC_GITCONFIG);
+ if (!access(git_etc_gitconfig(), R_OK))
+ ret += git_config_from_file(fn, git_etc_gitconfig());
home = getenv("HOME");
filename = getenv(CONFIG_LOCAL_ENVIRONMENT);
if (!filename)
diff --git a/config.mak.in b/config.mak.in
index 776b80565..11d256e9c 100644
--- a/config.mak.in
+++ b/config.mak.in
@@ -35,7 +35,10 @@ NO_SOCKADDR_STORAGE=@NO_SOCKADDR_STORAGE@
NO_IPV6=@NO_IPV6@
NO_C99_FORMAT=@NO_C99_FORMAT@
NO_STRCASESTR=@NO_STRCASESTR@
+NO_MEMMEM=@NO_MEMMEM@
NO_STRLCPY=@NO_STRLCPY@
+NO_STRTOUMAX=@NO_STRTOUMAX@
NO_SETENV=@NO_SETENV@
+NO_MKDTEMP=@NO_MKDTEMP@
NO_ICONV=@NO_ICONV@
NO_DEFLATE_BOUND=@NO_DEFLATE_BOUND@
diff --git a/configure.ac b/configure.ac
index 53e9a17c7..7bcf1a488 100644
--- a/configure.ac
+++ b/configure.ac
@@ -289,18 +289,36 @@ AC_CHECK_FUNC(strcasestr,
[NO_STRCASESTR=YesPlease])
AC_SUBST(NO_STRCASESTR)
#
+# Define NO_MEMMEM if you don't have memmem.
+AC_CHECK_FUNC(memmem,
+[NO_MEMMEM=],
+[NO_MEMMEM=YesPlease])
+AC_SUBST(NO_MEMMEM)
+#
# Define NO_STRLCPY if you don't have strlcpy.
AC_CHECK_FUNC(strlcpy,
[NO_STRLCPY=],
[NO_STRLCPY=YesPlease])
AC_SUBST(NO_STRLCPY)
#
+# Define NO_STRTOUMAX if you don't have strtoumax in the C library.
+AC_CHECK_FUNC(strtoumax,
+[NO_STRTOUMAX=],
+[NO_STRTOUMAX=YesPlease])
+AC_SUBST(NO_STRTOUMAX)
+#
# Define NO_SETENV if you don't have setenv in the C library.
AC_CHECK_FUNC(setenv,
[NO_SETENV=],
[NO_SETENV=YesPlease])
AC_SUBST(NO_SETENV)
#
+# Define NO_MKDTEMP if you don't have mkdtemp in the C library.
+AC_CHECK_FUNC(mkdtemp,
+[NO_MKDTEMP=],
+[NO_MKDTEMP=YesPlease])
+AC_SUBST(NO_MKDTEMP)
+#
# Define NO_MMAP if you want to avoid mmap.
#
# Define NO_ICONV if your libc does not properly support iconv.
diff --git a/git-clean.sh b/contrib/examples/git-clean.sh
index 521fabc20..01c95e9fe 100755
--- a/git-clean.sh
+++ b/contrib/examples/git-clean.sh
@@ -3,16 +3,22 @@
# Copyright (c) 2005-2006 Pavel Roskin
#
-USAGE="[-d] [-f] [-n] [-q] [-x | -X] [--] <paths>..."
-LONG_USAGE='Clean untracked files from the working directory
- -d remove directories as well
- -f override clean.requireForce and clean anyway
- -n don'\''t remove anything, just show what would be done
- -q be quiet, only report errors
- -x remove ignored files as well
- -X remove only ignored files
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-clean [options] <paths>...
+
+Clean untracked files from the working directory
+
When optional <paths>... arguments are given, the paths
-affected are further limited to those that match them.'
+affected are further limited to those that match them.
+--
+d remove directories as well
+f override clean.requireForce and clean anyway
+n don't remove anything, just show what would be done
+q be quiet, only report errors
+x remove ignored files as well
+X remove only ignored files"
+
SUBDIRECTORY_OK=Yes
. git-sh-setup
require_work_tree
@@ -56,11 +62,9 @@ do
shift
break
;;
- -*)
- usage
- ;;
*)
- break
+ usage # should not happen
+ ;;
esac
shift
done
@@ -77,21 +81,28 @@ case "$disabled" in
;;
esac
-case "$ignored,$ignoredonly" in
- 1,1) usage;;
-esac
+if [ "$ignored,$ignoredonly" = "1,1" ]; then
+ die "-x and -X cannot be set together"
+fi
if [ -z "$ignored" ]; then
excl="--exclude-per-directory=.gitignore"
+ excl_info= excludes_file=
if [ -f "$GIT_DIR/info/exclude" ]; then
excl_info="--exclude-from=$GIT_DIR/info/exclude"
fi
+ if cfg_excl=$(git config core.excludesfile) && test -f "$cfg_excl"
+ then
+ excludes_file="--exclude-from=$cfg_excl"
+ fi
if [ "$ignoredonly" ]; then
excl="$excl --ignored"
fi
fi
-git ls-files --others --directory $excl ${excl_info:+"$excl_info"} -- "$@" |
+git ls-files --others --directory \
+ $excl ${excl_info:+"$excl_info"} ${excludes_file:+"$excludes_file"} \
+ -- "$@" |
while read -r file; do
if [ -d "$file" -a ! -L "$file" ]; then
if [ -z "$cleandir" ]; then
diff --git a/git-merge-ours.sh b/contrib/examples/git-merge-ours.sh
index c81a790aa..c81a790aa 100755
--- a/git-merge-ours.sh
+++ b/contrib/examples/git-merge-ours.sh
diff --git a/contrib/fast-import/git-p4 b/contrib/fast-import/git-p4
index c148b5ab7..c80a6da25 100755
--- a/contrib/fast-import/git-p4
+++ b/contrib/fast-import/git-p4
@@ -1141,7 +1141,7 @@ class P4Sync(Command):
l = p4CmdList("labels %s..." % ' '.join (self.depotPaths))
if len(l) > 0 and not self.silent:
- print "Finding files belonging to labels in %s" % `self.depotPath`
+ print "Finding files belonging to labels in %s" % `self.depotPaths`
for output in l:
label = output["label"]
@@ -1207,6 +1207,15 @@ class P4Sync(Command):
for branch in lostAndFoundBranches:
self.knownBranches[branch] = branch
+ def getBranchMappingFromGitBranches(self):
+ branches = p4BranchesInGit(self.importIntoRemotes)
+ for branch in branches.keys():
+ if branch == "master":
+ branch = "main"
+ else:
+ branch = branch[len(self.projectName):]
+ self.knownBranches[branch] = branch
+
def listExistingP4GitBranches(self):
# branches holds mapping from name to commit
branches = p4BranchesInGit(self.importIntoRemotes)
@@ -1541,8 +1550,10 @@ class P4Sync(Command):
## FIXME - what's a P4 projectName ?
self.projectName = self.guessProjectName()
- if not self.hasOrigin:
- self.getBranchMapping();
+ if self.hasOrigin:
+ self.getBranchMappingFromGitBranches()
+ else:
+ self.getBranchMapping()
if self.verbose:
print "p4-git branches: %s" % self.p4BranchesInGit
print "initial parents: %s" % self.initialParents
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index 449ee69bf..4c99dfb90 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -27,20 +27,17 @@ import math
import string
import fcntl
+have_gtksourceview2 = False
+have_gtksourceview = False
try:
import gtksourceview2
have_gtksourceview2 = True
except ImportError:
- have_gtksourceview2 = False
-
-try:
- import gtksourceview
- have_gtksourceview = True
-except ImportError:
- have_gtksourceview = False
-
-if not have_gtksourceview2 and not have_gtksourceview:
- print "Running without gtksourceview2 or gtksourceview module"
+ try:
+ import gtksourceview
+ have_gtksourceview = True
+ except ImportError:
+ print "Running without gtksourceview2 or gtksourceview module"
re_ident = re.compile('(author|committer) (?P<ident>.*) (?P<epoch>\d+) (?P<tz>[+-]\d{4})')
diff --git a/csum-file.c b/csum-file.c
index 3729e73e1..9728a9954 100644
--- a/csum-file.c
+++ b/csum-file.c
@@ -18,7 +18,8 @@ static void sha1flush(struct sha1file *f, unsigned int count)
for (;;) {
int ret = xwrite(f->fd, buf, count);
if (ret > 0) {
- display_throughput(f->tp, ret);
+ f->total += ret;
+ display_throughput(f->tp, f->total);
buf = (char *) buf + ret;
count -= ret;
if (count)
@@ -87,21 +88,12 @@ struct sha1file *sha1fd(int fd, const char *name)
struct sha1file *sha1fd_throughput(int fd, const char *name, struct progress *tp)
{
- struct sha1file *f;
- unsigned len;
-
- f = xmalloc(sizeof(*f));
-
- len = strlen(name);
- if (len >= PATH_MAX)
- die("you wascally wabbit, you");
- f->namelen = len;
- memcpy(f->name, name, len+1);
-
+ struct sha1file *f = xmalloc(sizeof(*f));
f->fd = fd;
- f->error = 0;
f->offset = 0;
+ f->total = 0;
f->tp = tp;
+ f->name = name;
f->do_crc = 0;
SHA1_Init(&f->ctx);
return f;
diff --git a/csum-file.h b/csum-file.h
index 4d1b23129..1af76562f 100644
--- a/csum-file.h
+++ b/csum-file.h
@@ -5,11 +5,12 @@ struct progress;
/* A SHA1-protected file */
struct sha1file {
- int fd, error;
- unsigned int offset, namelen;
+ int fd;
+ unsigned int offset;
SHA_CTX ctx;
+ off_t total;
struct progress *tp;
- char name[PATH_MAX];
+ const char *name;
int do_crc;
uint32_t crc32;
unsigned char buffer[8192];
diff --git a/diff-lib.c b/diff-lib.c
index da5571302..f8e936ae1 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -121,7 +121,7 @@ static int queue_diff(struct diff_options *o,
} else {
struct diff_filespec *d1, *d2;
- if (o->reverse_diff) {
+ if (DIFF_OPT_TST(o, REVERSE_DIFF)) {
unsigned tmp;
const char *tmp_c;
tmp = mode1; mode1 = mode2; mode2 = tmp;
@@ -173,9 +173,10 @@ static int is_in_index(const char *path)
}
static int handle_diff_files_args(struct rev_info *revs,
- int argc, const char **argv, int *silent)
+ int argc, const char **argv,
+ unsigned int *options)
{
- *silent = 0;
+ *options = 0;
/* revs->max_count == -2 means --no-index */
while (1 < argc && argv[1][0] == '-') {
@@ -188,11 +189,11 @@ static int handle_diff_files_args(struct rev_info *revs,
else if (!strcmp(argv[1], "-n") ||
!strcmp(argv[1], "--no-index")) {
revs->max_count = -2;
- revs->diffopt.exit_with_status = 1;
- revs->diffopt.no_index = 1;
+ DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
+ DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
}
else if (!strcmp(argv[1], "-q"))
- *silent = 1;
+ *options |= DIFF_SILENT_ON_REMOVED;
else
return error("invalid option: %s", argv[1]);
argv++; argc--;
@@ -207,7 +208,7 @@ static int handle_diff_files_args(struct rev_info *revs,
if (!is_in_index(revs->diffopt.paths[0]) ||
!is_in_index(revs->diffopt.paths[1])) {
revs->max_count = -2;
- revs->diffopt.no_index = 1;
+ DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
}
}
@@ -258,7 +259,7 @@ int setup_diff_no_index(struct rev_info *revs,
break;
} else if (i < argc - 3 && !strcmp(argv[i], "--no-index")) {
i = argc - 3;
- revs->diffopt.exit_with_status = 1;
+ DIFF_OPT_SET(&revs->diffopt, EXIT_WITH_STATUS);
break;
}
if (argc != i + 2 || (!is_outside_repo(argv[i + 1], nongit, prefix) &&
@@ -296,7 +297,7 @@ int setup_diff_no_index(struct rev_info *revs,
else
revs->diffopt.paths = argv + argc - 2;
revs->diffopt.nr_paths = 2;
- revs->diffopt.no_index = 1;
+ DIFF_OPT_SET(&revs->diffopt, NO_INDEX);
revs->max_count = -2;
if (diff_setup_done(&revs->diffopt) < 0)
die("diff_setup_done failed");
@@ -305,12 +306,12 @@ int setup_diff_no_index(struct rev_info *revs,
int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
{
- int silent_on_removed;
+ unsigned int options;
- if (handle_diff_files_args(revs, argc, argv, &silent_on_removed))
+ if (handle_diff_files_args(revs, argc, argv, &options))
return -1;
- if (revs->diffopt.no_index) {
+ if (DIFF_OPT_TST(&revs->diffopt, NO_INDEX)) {
if (revs->diffopt.nr_paths != 2)
return error("need two files/directories with --no-index");
if (queue_diff(&revs->diffopt, revs->diffopt.paths[0],
@@ -329,13 +330,16 @@ int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv)
perror("read_cache");
return -1;
}
- return run_diff_files(revs, silent_on_removed);
+ return run_diff_files(revs, options);
}
-int run_diff_files(struct rev_info *revs, int silent_on_removed)
+int run_diff_files(struct rev_info *revs, unsigned int option)
{
int entries, i;
int diff_unmerged_stage = revs->max_count;
+ int silent_on_removed = option & DIFF_SILENT_ON_REMOVED;
+ unsigned ce_option = ((option & DIFF_RACY_IS_MODIFIED)
+ ? CE_MATCH_RACY_IS_DIRTY : 0);
if (diff_unmerged_stage < 0)
diff_unmerged_stage = 2;
@@ -346,7 +350,8 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
struct cache_entry *ce = active_cache[i];
int changed;
- if (revs->diffopt.quiet && revs->diffopt.has_changes)
+ if (DIFF_OPT_TST(&revs->diffopt, QUIET) &&
+ DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
if (!ce_path_match(ce, revs->prune_data))
@@ -441,8 +446,8 @@ int run_diff_files(struct rev_info *revs, int silent_on_removed)
ce->sha1, ce->name, NULL);
continue;
}
- changed = ce_match_stat(ce, &st, 0);
- if (!changed && !revs->diffopt.find_copies_harder)
+ changed = ce_match_stat(ce, &st, ce_option);
+ if (!changed && !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
continue;
oldmode = ntohl(ce->ce_mode);
newmode = ntohl(ce_mode_from_stat(ce, st.st_mode));
@@ -561,7 +566,7 @@ static int show_modified(struct rev_info *revs,
oldmode = old->ce_mode;
if (mode == oldmode && !hashcmp(sha1, old->sha1) &&
- !revs->diffopt.find_copies_harder)
+ !DIFF_OPT_TST(&revs->diffopt, FIND_COPIES_HARDER))
return 0;
mode = ntohl(mode);
@@ -581,7 +586,8 @@ static int diff_cache(struct rev_info *revs,
struct cache_entry *ce = *ac;
int same = (entries > 1) && ce_same_name(ce, ac[1]);
- if (revs->diffopt.quiet && revs->diffopt.has_changes)
+ if (DIFF_OPT_TST(&revs->diffopt, QUIET) &&
+ DIFF_OPT_TST(&revs->diffopt, HAS_CHANGES))
break;
if (!ce_path_match(ce, pathspec))
diff --git a/diff.c b/diff.c
index a6aaaf7e5..6b5495961 100644
--- a/diff.c
+++ b/diff.c
@@ -814,10 +814,10 @@ static void show_stats(struct diffstat_t* data, struct diff_options *options)
}
/* Find the longest filename and max number of changes */
- reset = diff_get_color(options->color_diff, DIFF_RESET);
- set = diff_get_color(options->color_diff, DIFF_PLAIN);
- add_c = diff_get_color(options->color_diff, DIFF_FILE_NEW);
- del_c = diff_get_color(options->color_diff, DIFF_FILE_OLD);
+ reset = diff_get_color_opt(options, DIFF_RESET);
+ set = diff_get_color_opt(options, DIFF_PLAIN);
+ add_c = diff_get_color_opt(options, DIFF_FILE_NEW);
+ del_c = diff_get_color_opt(options, DIFF_FILE_OLD);
for (i = 0; i < data->nr; i++) {
struct diffstat_file *file = data->files[i];
@@ -1243,8 +1243,8 @@ static void builtin_diff(const char *name_a,
mmfile_t mf1, mf2;
const char *lbl[2];
char *a_one, *b_two;
- const char *set = diff_get_color(o->color_diff, DIFF_METAINFO);
- const char *reset = diff_get_color(o->color_diff, DIFF_RESET);
+ const char *set = diff_get_color_opt(o, DIFF_METAINFO);
+ const char *reset = diff_get_color_opt(o, DIFF_RESET);
a_one = quote_two("a/", name_a + (*name_a == '/'));
b_two = quote_two("b/", name_b + (*name_b == '/'));
@@ -1277,7 +1277,7 @@ static void builtin_diff(const char *name_a,
goto free_ab_and_return;
if (complete_rewrite) {
emit_rewrite_diff(name_a, name_b, one, two,
- o->color_diff);
+ DIFF_OPT_TST(o, COLOR_DIFF));
o->found_changes = 1;
goto free_ab_and_return;
}
@@ -1286,13 +1286,13 @@ static void builtin_diff(const char *name_a,
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
- if (!o->text &&
+ if (!DIFF_OPT_TST(o, TEXT) &&
(diff_filespec_is_binary(one) || diff_filespec_is_binary(two))) {
/* Quite common confusing case */
if (mf1.size == mf2.size &&
!memcmp(mf1.ptr, mf2.ptr, mf1.size))
goto free_ab_and_return;
- if (o->binary)
+ if (DIFF_OPT_TST(o, BINARY))
emit_binary_diff(&mf1, &mf2);
else
printf("Binary files %s and %s differ\n",
@@ -1315,7 +1315,7 @@ static void builtin_diff(const char *name_a,
memset(&xecfg, 0, sizeof(xecfg));
memset(&ecbdata, 0, sizeof(ecbdata));
ecbdata.label_path = lbl;
- ecbdata.color_diff = o->color_diff;
+ ecbdata.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
ecbdata.found_changesp = &o->found_changes;
xpp.flags = XDF_NEED_MINIMAL | o->xdl_opts;
xecfg.ctxlen = o->context;
@@ -1331,11 +1331,11 @@ static void builtin_diff(const char *name_a,
ecb.outf = xdiff_outf;
ecb.priv = &ecbdata;
ecbdata.xm.consume = fn_out_consume;
- if (o->color_diff_words)
+ if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
ecbdata.diff_words =
xcalloc(1, sizeof(struct diff_words_data));
xdl_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
- if (o->color_diff_words)
+ if (DIFF_OPT_TST(o, COLOR_DIFF_WORDS))
free_diff_words_data(&ecbdata);
}
@@ -1409,7 +1409,7 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
data.xm.consume = checkdiff_consume;
data.filename = name_b ? name_b : name_a;
data.lineno = 0;
- data.color_diff = o->color_diff;
+ data.color_diff = DIFF_OPT_TST(o, COLOR_DIFF);
if (fill_mmfile(&mf1, one) < 0 || fill_mmfile(&mf2, two) < 0)
die("unable to read files to diff");
@@ -1853,7 +1853,7 @@ static void run_diff_cmd(const char *pgm,
struct diff_options *o,
int complete_rewrite)
{
- if (!o->allow_external)
+ if (!DIFF_OPT_TST(o, ALLOW_EXTERNAL))
pgm = NULL;
else {
const char *cmd = external_diff_attr(name);
@@ -1951,9 +1951,9 @@ static void run_diff(struct diff_filepair *p, struct diff_options *o)
}
if (hashcmp(one->sha1, two->sha1)) {
- int abbrev = o->full_index ? 40 : DEFAULT_ABBREV;
+ int abbrev = DIFF_OPT_TST(o, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
- if (o->binary) {
+ if (DIFF_OPT_TST(o, BINARY)) {
mmfile_t mf;
if ((!fill_mmfile(&mf, one) && diff_filespec_is_binary(one)) ||
(!fill_mmfile(&mf, two) && diff_filespec_is_binary(two)))
@@ -2045,7 +2045,10 @@ void diff_setup(struct diff_options *options)
options->change = diff_change;
options->add_remove = diff_addremove;
- options->color_diff = diff_use_color_default;
+ if (diff_use_color_default)
+ DIFF_OPT_SET(options, COLOR_DIFF);
+ else
+ DIFF_OPT_CLR(options, COLOR_DIFF);
options->detect_rename = diff_detect_rename_default;
}
@@ -2064,7 +2067,7 @@ int diff_setup_done(struct diff_options *options)
if (count > 1)
die("--name-only, --name-status, --check and -s are mutually exclusive");
- if (options->find_copies_harder)
+ if (DIFF_OPT_TST(options, FIND_COPIES_HARDER))
options->detect_rename = DIFF_DETECT_COPY;
if (options->output_format & (DIFF_FORMAT_NAME |
@@ -2088,12 +2091,12 @@ int diff_setup_done(struct diff_options *options)
DIFF_FORMAT_SHORTSTAT |
DIFF_FORMAT_SUMMARY |
DIFF_FORMAT_CHECKDIFF))
- options->recursive = 1;
+ DIFF_OPT_SET(options, RECURSIVE);
/*
* Also pickaxe would not work very well if you do not say recursive
*/
if (options->pickaxe)
- options->recursive = 1;
+ DIFF_OPT_SET(options, RECURSIVE);
if (options->detect_rename && options->rename_limit < 0)
options->rename_limit = diff_rename_limit_default;
@@ -2115,9 +2118,9 @@ int diff_setup_done(struct diff_options *options)
* to have found. It does not make sense not to return with
* exit code in such a case either.
*/
- if (options->quiet) {
+ if (DIFF_OPT_TST(options, QUIET)) {
options->output_format = DIFF_FORMAT_NO_OUTPUT;
- options->exit_with_status = 1;
+ DIFF_OPT_SET(options, EXIT_WITH_STATUS);
}
/*
@@ -2125,7 +2128,7 @@ int diff_setup_done(struct diff_options *options)
* upon the first hit. We need to run diff as usual.
*/
if (options->pickaxe || options->filter)
- options->quiet = 0;
+ DIFF_OPT_CLR(options, QUIET);
return 0;
}
@@ -2182,21 +2185,32 @@ static int diff_scoreopt_parse(const char *opt);
int diff_opt_parse(struct diff_options *options, const char **av, int ac)
{
const char *arg = av[0];
+
+ /* Output format options */
if (!strcmp(arg, "-p") || !strcmp(arg, "-u"))
options->output_format |= DIFF_FORMAT_PATCH;
else if (opt_arg(arg, 'U', "unified", &options->context))
options->output_format |= DIFF_FORMAT_PATCH;
else if (!strcmp(arg, "--raw"))
options->output_format |= DIFF_FORMAT_RAW;
- else if (!strcmp(arg, "--patch-with-raw")) {
+ else if (!strcmp(arg, "--patch-with-raw"))
options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW;
- }
- else if (!strcmp(arg, "--numstat")) {
+ else if (!strcmp(arg, "--numstat"))
options->output_format |= DIFF_FORMAT_NUMSTAT;
- }
- else if (!strcmp(arg, "--shortstat")) {
+ else if (!strcmp(arg, "--shortstat"))
options->output_format |= DIFF_FORMAT_SHORTSTAT;
- }
+ else if (!strcmp(arg, "--check"))
+ options->output_format |= DIFF_FORMAT_CHECKDIFF;
+ else if (!strcmp(arg, "--summary"))
+ options->output_format |= DIFF_FORMAT_SUMMARY;
+ else if (!strcmp(arg, "--patch-with-stat"))
+ options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT;
+ else if (!strcmp(arg, "--name-only"))
+ options->output_format |= DIFF_FORMAT_NAME;
+ else if (!strcmp(arg, "--name-status"))
+ options->output_format |= DIFF_FORMAT_NAME_STATUS;
+ else if (!strcmp(arg, "-s"))
+ options->output_format |= DIFF_FORMAT_NO_OUTPUT;
else if (!prefixcmp(arg, "--stat")) {
char *end;
int width = options->stat_width;
@@ -2224,99 +2238,89 @@ int diff_opt_parse(struct diff_options *options, const char **av, int ac)
options->stat_name_width = name_width;
options->stat_width = width;
}
- else if (!strcmp(arg, "--check"))
- options->output_format |= DIFF_FORMAT_CHECKDIFF;
- else if (!strcmp(arg, "--summary"))
- options->output_format |= DIFF_FORMAT_SUMMARY;
- else if (!strcmp(arg, "--patch-with-stat")) {
- options->output_format |= DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT;
- }
- else if (!strcmp(arg, "-z"))
- options->line_termination = 0;
- else if (!prefixcmp(arg, "-l"))
- options->rename_limit = strtoul(arg+2, NULL, 10);
- else if (!strcmp(arg, "--full-index"))
- options->full_index = 1;
- else if (!strcmp(arg, "--binary")) {
- options->output_format |= DIFF_FORMAT_PATCH;
- options->binary = 1;
- }
- else if (!strcmp(arg, "-a") || !strcmp(arg, "--text")) {
- options->text = 1;
- }
- else if (!strcmp(arg, "--name-only"))
- options->output_format |= DIFF_FORMAT_NAME;
- else if (!strcmp(arg, "--name-status"))
- options->output_format |= DIFF_FORMAT_NAME_STATUS;
- else if (!strcmp(arg, "-R"))
- options->reverse_diff = 1;
- else if (!prefixcmp(arg, "-S"))
- options->pickaxe = arg + 2;
- else if (!strcmp(arg, "-s")) {
- options->output_format |= DIFF_FORMAT_NO_OUTPUT;
- }
- else if (!prefixcmp(arg, "-O"))
- options->orderfile = arg + 2;
- else if (!prefixcmp(arg, "--diff-filter="))
- options->filter = arg + 14;
- else if (!strcmp(arg, "--pickaxe-all"))
- options->pickaxe_opts = DIFF_PICKAXE_ALL;
- else if (!strcmp(arg, "--pickaxe-regex"))
- options->pickaxe_opts = DIFF_PICKAXE_REGEX;
+
+ /* renames options */
else if (!prefixcmp(arg, "-B")) {
- if ((options->break_opt =
- diff_scoreopt_parse(arg)) == -1)
+ if ((options->break_opt = diff_scoreopt_parse(arg)) == -1)
return -1;
}
else if (!prefixcmp(arg, "-M")) {
- if ((options->rename_score =
- diff_scoreopt_parse(arg)) == -1)
+ if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
return -1;
options->detect_rename = DIFF_DETECT_RENAME;
}
else if (!prefixcmp(arg, "-C")) {
if (options->detect_rename == DIFF_DETECT_COPY)
- options->find_copies_harder = 1;
- if ((options->rename_score =
- diff_scoreopt_parse(arg)) == -1)
+ DIFF_OPT_SET(options, FIND_COPIES_HARDER);
+ if ((options->rename_score = diff_scoreopt_parse(arg)) == -1)
return -1;
options->detect_rename = DIFF_DETECT_COPY;
}
- else if (!strcmp(arg, "--find-copies-harder"))
- options->find_copies_harder = 1;
- else if (!strcmp(arg, "--follow"))
- options->follow_renames = 1;
- else if (!strcmp(arg, "--abbrev"))
- options->abbrev = DEFAULT_ABBREV;
- else if (!prefixcmp(arg, "--abbrev=")) {
- options->abbrev = strtoul(arg + 9, NULL, 10);
- if (options->abbrev < MINIMUM_ABBREV)
- options->abbrev = MINIMUM_ABBREV;
- else if (40 < options->abbrev)
- options->abbrev = 40;
- }
- else if (!strcmp(arg, "--color"))
- options->color_diff = 1;
- else if (!strcmp(arg, "--no-color"))
- options->color_diff = 0;
+ else if (!strcmp(arg, "--no-renames"))
+ options->detect_rename = 0;
+
+ /* xdiff options */
else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE;
else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_CHANGE;
else if (!strcmp(arg, "--ignore-space-at-eol"))
options->xdl_opts |= XDF_IGNORE_WHITESPACE_AT_EOL;
+
+ /* flags options */
+ else if (!strcmp(arg, "--binary")) {
+ options->output_format |= DIFF_FORMAT_PATCH;
+ DIFF_OPT_SET(options, BINARY);
+ }
+ else if (!strcmp(arg, "--full-index"))
+ DIFF_OPT_SET(options, FULL_INDEX);
+ else if (!strcmp(arg, "-a") || !strcmp(arg, "--text"))
+ DIFF_OPT_SET(options, TEXT);
+ else if (!strcmp(arg, "-R"))
+ DIFF_OPT_SET(options, REVERSE_DIFF);
+ else if (!strcmp(arg, "--find-copies-harder"))
+ DIFF_OPT_SET(options, FIND_COPIES_HARDER);
+ else if (!strcmp(arg, "--follow"))
+ DIFF_OPT_SET(options, FOLLOW_RENAMES);
+ else if (!strcmp(arg, "--color"))
+ DIFF_OPT_SET(options, COLOR_DIFF);
+ else if (!strcmp(arg, "--no-color"))
+ DIFF_OPT_CLR(options, COLOR_DIFF);
else if (!strcmp(arg, "--color-words"))
- options->color_diff = options->color_diff_words = 1;
- else if (!strcmp(arg, "--no-renames"))
- options->detect_rename = 0;
+ options->flags |= DIFF_OPT_COLOR_DIFF | DIFF_OPT_COLOR_DIFF_WORDS;
else if (!strcmp(arg, "--exit-code"))
- options->exit_with_status = 1;
+ DIFF_OPT_SET(options, EXIT_WITH_STATUS);
else if (!strcmp(arg, "--quiet"))
- options->quiet = 1;
+ DIFF_OPT_SET(options, QUIET);
else if (!strcmp(arg, "--ext-diff"))
- options->allow_external = 1;
+ DIFF_OPT_SET(options, ALLOW_EXTERNAL);
else if (!strcmp(arg, "--no-ext-diff"))
- options->allow_external = 0;
+ DIFF_OPT_CLR(options, ALLOW_EXTERNAL);
+
+ /* misc options */
+ else if (!strcmp(arg, "-z"))
+ options->line_termination = 0;
+ else if (!prefixcmp(arg, "-l"))
+ options->rename_limit = strtoul(arg+2, NULL, 10);
+ else if (!prefixcmp(arg, "-S"))
+ options->pickaxe = arg + 2;
+ else if (!strcmp(arg, "--pickaxe-all"))
+ options->pickaxe_opts = DIFF_PICKAXE_ALL;
+ else if (!strcmp(arg, "--pickaxe-regex"))
+ options->pickaxe_opts = DIFF_PICKAXE_REGEX;
+ else if (!prefixcmp(arg, "-O"))
+ options->orderfile = arg + 2;
+ else if (!prefixcmp(arg, "--diff-filter="))
+ options->filter = arg + 14;
+ else if (!strcmp(arg, "--abbrev"))
+ options->abbrev = DEFAULT_ABBREV;
+ else if (!prefixcmp(arg, "--abbrev=")) {
+ options->abbrev = strtoul(arg + 9, NULL, 10);
+ if (options->abbrev < MINIMUM_ABBREV)
+ options->abbrev = MINIMUM_ABBREV;
+ else if (40 < options->abbrev)
+ options->abbrev = 40;
+ }
else
return 0;
return 1;
@@ -2712,7 +2716,7 @@ static void diff_summary(struct diff_filepair *p)
break;
default:
if (p->score) {
- puts(" rewrite ");
+ fputs(" rewrite ", stdout);
write_name_quoted(p->two->path, stdout, ' ');
printf("(%d%%)\n", similarity_index(p));
}
@@ -3071,7 +3075,7 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
* to determine how many paths were dirty only
* due to stat info mismatch.
*/
- if (!diffopt->no_index)
+ if (!DIFF_OPT_TST(diffopt, NO_INDEX))
diffopt->skip_stat_unmatch++;
diff_free_filepair(p);
}
@@ -3082,10 +3086,10 @@ static void diffcore_skip_stat_unmatch(struct diff_options *diffopt)
void diffcore_std(struct diff_options *options)
{
- if (options->quiet)
+ if (DIFF_OPT_TST(options, QUIET))
return;
- if (options->skip_stat_unmatch && !options->find_copies_harder)
+ if (options->skip_stat_unmatch && !DIFF_OPT_TST(options, FIND_COPIES_HARDER))
diffcore_skip_stat_unmatch(options);
if (options->break_opt != -1)
diffcore_break(options->break_opt);
@@ -3100,7 +3104,10 @@ void diffcore_std(struct diff_options *options)
diff_resolve_rename_copy();
diffcore_apply_filter(options->filter);
- options->has_changes = !!diff_queued_diff.nr;
+ if (diff_queued_diff.nr)
+ DIFF_OPT_SET(options, HAS_CHANGES);
+ else
+ DIFF_OPT_CLR(options, HAS_CHANGES);
}
@@ -3124,7 +3131,7 @@ void diff_addremove(struct diff_options *options,
* Before the final output happens, they are pruned after
* merged into rename/copy pairs as appropriate.
*/
- if (options->reverse_diff)
+ if (DIFF_OPT_TST(options, REVERSE_DIFF))
addremove = (addremove == '+' ? '-' :
addremove == '-' ? '+' : addremove);
@@ -3139,7 +3146,7 @@ void diff_addremove(struct diff_options *options,
fill_filespec(two, sha1, mode);
diff_queue(&diff_queued_diff, one, two);
- options->has_changes = 1;
+ DIFF_OPT_SET(options, HAS_CHANGES);
}
void diff_change(struct diff_options *options,
@@ -3151,7 +3158,7 @@ void diff_change(struct diff_options *options,
char concatpath[PATH_MAX];
struct diff_filespec *one, *two;
- if (options->reverse_diff) {
+ if (DIFF_OPT_TST(options, REVERSE_DIFF)) {
unsigned tmp;
const unsigned char *tmp_c;
tmp = old_mode; old_mode = new_mode; new_mode = tmp;
@@ -3165,7 +3172,7 @@ void diff_change(struct diff_options *options,
fill_filespec(two, new_sha1, new_mode);
diff_queue(&diff_queued_diff, one, two);
- options->has_changes = 1;
+ DIFF_OPT_SET(options, HAS_CHANGES);
}
void diff_unmerge(struct diff_options *options,
diff --git a/diff.h b/diff.h
index 4546aad21..a52496a10 100644
--- a/diff.h
+++ b/diff.h
@@ -43,26 +43,32 @@ typedef void (*diff_format_fn_t)(struct diff_queue_struct *q,
#define DIFF_FORMAT_CALLBACK 0x1000
+#define DIFF_OPT_RECURSIVE (1 << 0)
+#define DIFF_OPT_TREE_IN_RECURSIVE (1 << 1)
+#define DIFF_OPT_BINARY (1 << 2)
+#define DIFF_OPT_TEXT (1 << 3)
+#define DIFF_OPT_FULL_INDEX (1 << 4)
+#define DIFF_OPT_SILENT_ON_REMOVE (1 << 5)
+#define DIFF_OPT_FIND_COPIES_HARDER (1 << 6)
+#define DIFF_OPT_FOLLOW_RENAMES (1 << 7)
+#define DIFF_OPT_COLOR_DIFF (1 << 8)
+#define DIFF_OPT_COLOR_DIFF_WORDS (1 << 9)
+#define DIFF_OPT_HAS_CHANGES (1 << 10)
+#define DIFF_OPT_QUIET (1 << 11)
+#define DIFF_OPT_NO_INDEX (1 << 12)
+#define DIFF_OPT_ALLOW_EXTERNAL (1 << 13)
+#define DIFF_OPT_EXIT_WITH_STATUS (1 << 14)
+#define DIFF_OPT_REVERSE_DIFF (1 << 15)
+#define DIFF_OPT_TST(opts, flag) ((opts)->flags & DIFF_OPT_##flag)
+#define DIFF_OPT_SET(opts, flag) ((opts)->flags |= DIFF_OPT_##flag)
+#define DIFF_OPT_CLR(opts, flag) ((opts)->flags &= ~DIFF_OPT_##flag)
+
struct diff_options {
const char *filter;
const char *orderfile;
const char *pickaxe;
const char *single_follow;
- unsigned recursive:1,
- tree_in_recursive:1,
- binary:1,
- text:1,
- full_index:1,
- silent_on_remove:1,
- find_copies_harder:1,
- follow_renames:1,
- color_diff:1,
- color_diff_words:1,
- has_changes:1,
- quiet:1,
- no_index:1,
- allow_external:1,
- exit_with_status:1;
+ unsigned flags;
int context;
int break_opt;
int detect_rename;
@@ -71,7 +77,6 @@ struct diff_options {
int output_format;
int pickaxe_opts;
int rename_score;
- int reverse_diff;
int rename_limit;
int setup;
int abbrev;
@@ -105,6 +110,9 @@ enum color_diff {
DIFF_WHITESPACE = 7,
};
const char *diff_get_color(int diff_use_color, enum color_diff ix);
+#define diff_get_color_opt(o, ix) \
+ diff_get_color(DIFF_OPT_TST((o), COLOR_DIFF), ix)
+
extern const char mime_boundary_leader[];
@@ -224,7 +232,11 @@ extern void diff_flush(struct diff_options*);
extern const char *diff_unique_abbrev(const unsigned char *, int);
-extern int run_diff_files(struct rev_info *revs, int silent_on_removed);
+/* do not report anything on removed paths */
+#define DIFF_SILENT_ON_REMOVED 01
+/* report racily-clean paths as modified */
+#define DIFF_RACY_IS_MODIFIED 02
+extern int run_diff_files(struct rev_info *revs, unsigned int option);
extern int setup_diff_no_index(struct rev_info *revs,
int argc, const char ** argv, int nongit, const char *prefix);
extern int run_diff_files_cmd(struct rev_info *revs, int argc, const char **argv);
diff --git a/dir.c b/dir.c
index 01790ab27..225fdfb52 100644
--- a/dir.c
+++ b/dir.c
@@ -654,6 +654,7 @@ static void free_simplify(struct path_simplify *simplify)
int read_directory(struct dir_struct *dir, const char *path, const char *base, int baselen, const char **pathspec)
{
struct path_simplify *simplify = create_simplify(pathspec);
+ char *pp = NULL;
/*
* Make sure to do the per-directory exclude for all the
@@ -661,7 +662,8 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
*/
if (baselen) {
if (dir->exclude_per_dir) {
- char *p, *pp = xmalloc(baselen+1);
+ char *p;
+ pp = xmalloc(baselen+1);
memcpy(pp, base, baselen+1);
p = pp;
while (1) {
@@ -677,12 +679,12 @@ int read_directory(struct dir_struct *dir, const char *path, const char *base, i
else
p = pp + baselen;
}
- free(pp);
}
}
read_directory_recursive(dir, path, base, baselen, 0, simplify);
free_simplify(simplify);
+ free(pp);
qsort(dir->entries, dir->nr, sizeof(struct dir_entry *), cmp_name);
qsort(dir->ignored, dir->ignored_nr, sizeof(struct dir_entry *), cmp_name);
return dir->nr;
@@ -778,3 +780,15 @@ int remove_dir_recursively(struct strbuf *path, int only_empty)
ret = rmdir(path->buf);
return ret;
}
+
+void setup_standard_excludes(struct dir_struct *dir)
+{
+ const char *path;
+
+ dir->exclude_per_dir = ".gitignore";
+ path = git_path("info/exclude");
+ if (!access(path, R_OK))
+ add_excludes_from_file(dir, path);
+ if (excludes_file && !access(excludes_file, R_OK))
+ add_excludes_from_file(dir, excludes_file);
+}
diff --git a/dir.h b/dir.h
index aaa247b25..82009dc13 100644
--- a/dir.h
+++ b/dir.h
@@ -71,6 +71,7 @@ extern struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathna
extern char *get_relative_cwd(char *buffer, int size, const char *dir);
extern int is_inside_dir(const char *dir);
+extern void setup_standard_excludes(struct dir_struct *dir);
extern int remove_dir_recursively(struct strbuf *path, int only_empty);
#endif
diff --git a/entry.c b/entry.c
index cfadc6a29..257ab46e9 100644
--- a/entry.c
+++ b/entry.c
@@ -203,7 +203,7 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *t
strcpy(path + len, ce->name);
if (!lstat(path, &st)) {
- unsigned changed = ce_match_stat(ce, &st, 1);
+ unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
if (!changed)
return 0;
if (!state->force) {
diff --git a/environment.c b/environment.c
index b5a6c69f7..1dab72ec1 100644
--- a/environment.c
+++ b/environment.c
@@ -34,6 +34,7 @@ char *pager_program;
int pager_in_use;
int pager_use_color = 1;
char *editor_program;
+char *excludes_file;
int auto_crlf = 0; /* 1: both ways, -1: only when adding git objects */
/* This is set by setup_git_dir_gently() and/or git_default_config() */
diff --git a/fast-import.c b/fast-import.c
index f93d7d6c9..98c2bd535 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -153,13 +153,16 @@ Format of STDIN stream:
#define PACK_ID_BITS 16
#define MAX_PACK_ID ((1<<PACK_ID_BITS)-1)
+#define DEPTH_BITS 13
+#define MAX_DEPTH ((1<<DEPTH_BITS)-1)
struct object_entry
{
struct object_entry *next;
uint32_t offset;
- unsigned type : TYPE_BITS;
- unsigned pack_id : PACK_ID_BITS;
+ uint32_t type : TYPE_BITS,
+ pack_id : PACK_ID_BITS,
+ depth : DEPTH_BITS;
unsigned char sha1[20];
};
@@ -1083,7 +1086,7 @@ static int store_object(
unsigned pos = sizeof(hdr) - 1;
delta_count_by_type[type]++;
- last->depth++;
+ e->depth = last->depth + 1;
hdrlen = encode_header(OBJ_OFS_DELTA, deltalen, hdr);
write_or_die(pack_data->pack_fd, hdr, hdrlen);
@@ -1095,8 +1098,7 @@ static int store_object(
write_or_die(pack_data->pack_fd, hdr + pos, sizeof(hdr) - pos);
pack_size += sizeof(hdr) - pos;
} else {
- if (last)
- last->depth = 0;
+ e->depth = 0;
hdrlen = encode_header(type, dat->len, hdr);
write_or_die(pack_data->pack_fd, hdr, hdrlen);
pack_size += hdrlen;
@@ -1114,6 +1116,7 @@ static int store_object(
strbuf_swap(&last->data, dat);
}
last->offset = e->offset;
+ last->depth = e->depth;
}
return 0;
}
@@ -1160,7 +1163,7 @@ static void load_tree(struct tree_entry *root)
if (myoe && myoe->pack_id != MAX_PACK_ID) {
if (myoe->type != OBJ_TREE)
die("Not a tree: %s", sha1_to_hex(sha1));
- t->delta_depth = 0;
+ t->delta_depth = myoe->depth;
buf = gfi_unpack_entry(myoe, &size);
} else {
enum object_type type;
@@ -2289,8 +2292,11 @@ int main(int argc, const char **argv)
}
else if (!prefixcmp(a, "--max-pack-size="))
max_packsize = strtoumax(a + 16, NULL, 0) * 1024 * 1024;
- else if (!prefixcmp(a, "--depth="))
+ else if (!prefixcmp(a, "--depth=")) {
max_depth = strtoul(a + 8, NULL, 0);
+ if (max_depth > MAX_DEPTH)
+ die("--depth cannot exceed %u", MAX_DEPTH);
+ }
else if (!prefixcmp(a, "--active-branches="))
max_active_branches = strtoul(a + 18, NULL, 0);
else if (!prefixcmp(a, "--import-marks="))
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index ac598f88e..fb1e92a76 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -37,10 +37,7 @@ sub list_untracked {
chomp $_;
$_;
}
- run_cmd_pipe(qw(git ls-files --others
- --exclude-per-directory=.gitignore),
- "--exclude-from=$GIT_DIR/info/exclude",
- '--', @_);
+ run_cmd_pipe(qw(git ls-files --others --exclude-standard --), @_);
}
my $status_fmt = '%12s %12s %s';
@@ -567,10 +564,12 @@ sub patch_update_cmd {
IMMEDIATE => 1,
HEADER => $status_head, },
@mods);
- return if (!$it);
+ patch_update_file($it->{VALUE}) if ($it);
+}
+sub patch_update_file {
my ($ix, $num);
- my $path = $it->{VALUE};
+ my $path = shift;
my ($head, @hunk) = parse_diff($path);
for (@{$head->{TEXT}}) {
print;
diff --git a/git-am.sh b/git-am.sh
index 2514d07de..4126f0e85 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -2,11 +2,26 @@
#
# Copyright (c) 2005, 2006 Junio C Hamano
-USAGE='[--signoff] [--dotest=<dir>] [--keep] [--utf8 | --no-utf8]
- [--3way] [--interactive] [--binary]
- [--whitespace=<option>] [-C<n>] [-p<n>]
- <mbox>|<Maildir>...
- or, when resuming [--skip | --resolved]'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-am [options] <mbox>|<Maildir>...
+git-am [options] --resolved
+git-am [options] --skip
+--
+d,dotest= use <dir> and not .dotest
+i,interactive run interactively
+b,binary pass --allo-binary-replacement to git-apply
+3,3way allow fall back on 3way merging if needed
+s,signoff add a Signed-off-by line to the commit message
+u,utf8 recode into utf8 (default)
+k,keep pass -k flagg to git-mailinfo
+whitespace= pass it through git-apply
+C= pass it through git-apply
+p= pass it through git-apply
+resolvemsg= override error message when patch failure occurs
+r,resolved to be used after a patch failure
+skip skip the current patch"
+
. git-sh-setup
set_reflog_action am
require_work_tree
@@ -110,49 +125,38 @@ git_apply_opt=
while test $# != 0
do
case "$1" in
- -d=*|--d=*|--do=*|--dot=*|--dote=*|--dotes=*|--dotest=*)
- dotest=`expr "z$1" : 'z-[^=]*=\(.*\)'`; shift ;;
- -d|--d|--do|--dot|--dote|--dotes|--dotest)
- case "$#" in 1) usage ;; esac; shift
- dotest="$1"; shift;;
-
- -i|--i|--in|--int|--inte|--inter|--intera|--interac|--interact|\
- --interacti|--interactiv|--interactive)
- interactive=t; shift ;;
-
- -b|--b|--bi|--bin|--bina|--binar|--binary)
- binary=t; shift ;;
-
- -3|--3|--3w|--3wa|--3way)
- threeway=t; shift ;;
- -s|--s|--si|--sig|--sign|--signo|--signof|--signoff)
- sign=t; shift ;;
- -u|--u|--ut|--utf|--utf8)
- utf8=t; shift ;; # this is now default
- --no-u|--no-ut|--no-utf|--no-utf8)
- utf8=; shift ;;
- -k|--k|--ke|--kee|--keep)
- keep=t; shift ;;
-
- -r|--r|--re|--res|--reso|--resol|--resolv|--resolve|--resolved)
- resolved=t; shift ;;
-
- --sk|--ski|--skip)
- skip=t; shift ;;
-
- --whitespace=*|-C*|-p*)
- git_apply_opt="$git_apply_opt $1"; shift ;;
-
- --resolvemsg=*)
- resolvemsg=${1#--resolvemsg=}; shift ;;
-
+ -i|--interactive)
+ interactive=t ;;
+ -b|--binary)
+ binary=t ;;
+ -3|--3way)
+ threeway=t ;;
+ -s|--signoff)
+ sign=t ;;
+ -u|--utf8)
+ utf8=t ;; # this is now default
+ --no-utf8)
+ utf8= ;;
+ -k|--keep)
+ keep=t ;;
+ -r|--resolved)
+ resolved=t ;;
+ --skip)
+ skip=t ;;
+ -d|--dotest)
+ shift; dotest=$1;;
+ --resolvemsg)
+ shift; resolvemsg=$1 ;;
+ --whitespace)
+ git_apply_opt="$git_apply_opt $1=$2"; shift ;;
+ -C|-p)
+ git_apply_opt="$git_apply_opt $1$2"; shift ;;
--)
- shift; break ;;
- -*)
- usage ;;
+ shift; break ;;
*)
- break ;;
+ usage ;;
esac
+ shift
done
# If the dotest directory exists, but we have finished applying all the
diff --git a/git-bisect.sh b/git-bisect.sh
index 1ed44e56a..7a6521ec3 100755
--- a/git-bisect.sh
+++ b/git-bisect.sh
@@ -22,6 +22,7 @@ git bisect log
git bisect run <cmd>...
use <cmd>... to automatically bisect.'
+OPTIONS_SPEC=
. git-sh-setup
require_work_tree
@@ -36,7 +37,7 @@ sq() {
}
bisect_autostart() {
- test -d "$GIT_DIR/refs/bisect" || {
+ test -f "$GIT_DIR/BISECT_NAMES" || {
echo >&2 'You need to start by "git bisect start"'
if test -t 0
then
@@ -71,7 +72,7 @@ bisect_start() {
;;
refs/heads/*)
[ -s "$GIT_DIR/head-name" ] && die "won't bisect on seeked tree"
- echo "$head" | sed 's#^refs/heads/##' >"$GIT_DIR/head-name"
+ echo "${head#refs/heads/}" >"$GIT_DIR/head-name"
;;
*)
die "Bad HEAD - strange symbolic ref"
@@ -82,7 +83,6 @@ bisect_start() {
# Get rid of any old bisect state
#
bisect_clean_state
- mkdir "$GIT_DIR/refs/bisect"
#
# Check for one bad and then some good revisions.
@@ -130,7 +130,7 @@ bisect_write() {
good|skip) tag="$state"-"$rev" ;;
*) die "Bad bisect_write argument: $state" ;;
esac
- echo "$rev" >"$GIT_DIR/refs/bisect/$tag"
+ git update-ref "refs/bisect/$tag" "$rev"
echo "# $state: "$(git show-branch $rev) >>"$GIT_DIR/BISECT_LOG"
test -z "$nolog" && echo "git-bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
}
@@ -191,7 +191,7 @@ bisect_next_check() {
;;
*)
THEN=''
- test -d "$GIT_DIR/refs/bisect" || {
+ test -f "$GIT_DIR/BISECT_NAMES" || {
echo >&2 'You need to start by "git bisect start".'
THEN='then '
}
@@ -275,8 +275,7 @@ exit_if_skipped_commits () {
if expr "$_tried" : ".*[|].*" > /dev/null ; then
echo "There are only 'skip'ped commit left to test."
echo "The first bad commit could be any of:"
- echo "$_tried" | sed -e 's/[|]/\
-/g'
+ echo "$_tried" | tr '[|]' '[\012]'
echo "We cannot bisect more!"
exit 2
fi
@@ -317,20 +316,23 @@ bisect_next() {
exit_if_skipped_commits "$bisect_rev"
echo "Bisecting: $bisect_nr revisions left to test after this"
- echo "$bisect_rev" >"$GIT_DIR/refs/heads/new-bisect"
+ git branch -f new-bisect "$bisect_rev"
git checkout -q new-bisect || exit
- mv "$GIT_DIR/refs/heads/new-bisect" "$GIT_DIR/refs/heads/bisect" &&
- GIT_DIR="$GIT_DIR" git symbolic-ref HEAD refs/heads/bisect
+ git branch -M new-bisect bisect
git show-branch "$bisect_rev"
}
bisect_visualize() {
bisect_next_check fail
- not=`cd "$GIT_DIR/refs" && echo bisect/good-*`
- eval gitk bisect/bad --not $not -- $(cat "$GIT_DIR/BISECT_NAMES")
+ not=$(git for-each-ref --format='%(refname)' "refs/bisect/good-*")
+ eval gitk refs/bisect/bad --not $not -- $(cat "$GIT_DIR/BISECT_NAMES")
}
bisect_reset() {
+ test -f "$GIT_DIR/BISECT_NAMES" || {
+ echo "We are not bisecting."
+ return
+ }
case "$#" in
0) if [ -s "$GIT_DIR/head-name" ]; then
branch=`cat "$GIT_DIR/head-name"`
@@ -350,8 +352,12 @@ bisect_reset() {
}
bisect_clean_state() {
- rm -fr "$GIT_DIR/refs/bisect"
- rm -f "$GIT_DIR/refs/heads/bisect"
+ # There may be some refs packed during bisection.
+ git for-each-ref --format='%(refname) %(objectname)' refs/bisect/\* refs/heads/bisect |
+ while read ref hash
+ do
+ git update-ref -d $ref $hash
+ done
rm -f "$GIT_DIR/BISECT_LOG"
rm -f "$GIT_DIR/BISECT_NAMES"
rm -f "$GIT_DIR/BISECT_RUN"
diff --git a/git-checkout.sh b/git-checkout.sh
index 899392067..aa724ac1a 100755
--- a/git-checkout.sh
+++ b/git-checkout.sh
@@ -1,6 +1,16 @@
#!/bin/sh
-USAGE='[-q] [-f] [-b <new_branch>] [-m] [<branch>] [<paths>...]'
+OPTIONS_KEEPDASHDASH=t
+OPTIONS_SPEC="\
+git-branch [options] [<branch>] [<paths>...]
+--
+b= create a new branch started at <branch>
+l create the new branchs reflog
+track tells if the new branch should track the remote branch
+f proceed even if the index or working tree is not HEAD
+m performa three-way merge on local modifications if needed
+q,quiet be quiet
+"
SUBDIRECTORY_OK=Sometimes
. git-sh-setup
require_work_tree
@@ -20,13 +30,12 @@ quiet=
v=-v
LF='
'
-while [ "$#" != "0" ]; do
- arg="$1"
- shift
- case "$arg" in
- "-b")
- newbranch="$1"
+
+while test $# != 0; do
+ case "$1" in
+ -b)
shift
+ newbranch="$1"
[ -z "$newbranch" ] &&
die "git checkout: -b needs a branch name"
git show-ref --verify --quiet -- "refs/heads/$newbranch" &&
@@ -34,64 +43,54 @@ while [ "$#" != "0" ]; do
git check-ref-format "heads/$newbranch" ||
die "git checkout: we do not like '$newbranch' as a branch name."
;;
- "-l")
+ -l)
newbranch_log=-l
;;
- "--track"|"--no-track")
- track="$arg"
+ --track|--no-track)
+ track="$1"
;;
- "-f")
+ -f)
force=1
;;
-m)
merge=1
;;
- "-q")
+ -q|--quiet)
quiet=1
v=
;;
--)
+ shift
break
;;
- -*)
- usage
- ;;
*)
- if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null)
- then
- if [ -z "$rev" ]; then
- echo "unknown flag $arg"
- exit 1
- fi
- new_name="$arg"
- if git show-ref --verify --quiet -- "refs/heads/$arg"
- then
- rev=$(git rev-parse --verify "refs/heads/$arg^0")
- branch="$arg"
- fi
- new="$rev"
- elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null)
- then
- # checking out selected paths from a tree-ish.
- new="$rev"
- new_name="$arg^{tree}"
- branch=
- else
- new=
- new_name=
- branch=
- set x "$arg" "$@"
- shift
- fi
- case "$1" in
- --)
- shift ;;
- esac
- break
+ usage
;;
- esac
+ esac
+ shift
done
+arg="$1"
+if rev=$(git rev-parse --verify "$arg^0" 2>/dev/null)
+then
+ [ -z "$rev" ] && die "unknown flag $arg"
+ new_name="$arg"
+ if git show-ref --verify --quiet -- "refs/heads/$arg"
+ then
+ rev=$(git rev-parse --verify "refs/heads/$arg^0")
+ branch="$arg"
+ fi
+ new="$rev"
+ shift
+elif rev=$(git rev-parse --verify "$arg^{tree}" 2>/dev/null)
+then
+ # checking out selected paths from a tree-ish.
+ new="$rev"
+ new_name="$arg^{tree}"
+ shift
+fi
+[ "$1" = "--" ] && shift
+
case "$newbranch,$track" in
,--*)
die "git checkout: --track and --no-track require -b"
@@ -134,12 +133,12 @@ Did you intend to checkout '$@' which can not be resolved as commit?"
fi
# Make sure the request is about existing paths.
- git ls-files --error-unmatch -- "$@" >/dev/null || exit
- git ls-files -- "$@" |
- git checkout-index -f -u --stdin
+ git ls-files --full-name --error-unmatch -- "$@" >/dev/null || exit
+ git ls-files --full-name -- "$@" |
+ (cd_to_toplevel && git checkout-index -f -u --stdin)
- # Run a post-checkout hook -- the HEAD does not change so the
- # current HEAD is passed in for both args
+ # Run a post-checkout hook -- the HEAD does not change so the
+ # current HEAD is passed in for both args
if test -x "$GIT_DIR"/hooks/post-checkout; then
"$GIT_DIR"/hooks/post-checkout $old $old 0
fi
@@ -294,5 +293,5 @@ fi
# Run a post-checkout hook
if test -x "$GIT_DIR"/hooks/post-checkout; then
- "$GIT_DIR"/hooks/post-checkout $old $new 1
+ "$GIT_DIR"/hooks/post-checkout $old $new 1
fi
diff --git a/git-clone.sh b/git-clone.sh
index 3f0069360..24ad179bb 100755
--- a/git-clone.sh
+++ b/git-clone.sh
@@ -8,15 +8,36 @@
# See git-sh-setup why.
unset CDPATH
+OPTIONS_SPEC="\
+git-clone [options] [--] <repo> [<dir>]
+--
+n,no-checkout don't create a checkout
+bare create a bare repository
+naked create a bare repository
+l,local to clone from a local repository
+no-hardlinks don't use local hardlinks, always copy
+s,shared setup as a shared repository
+template= path to the template directory
+q,quiet be quiet
+reference= reference repository
+o,origin= use <name> instead of 'origin' to track upstream
+u,upload-pack= path to git-upload-pack on the remote
+depth= create a shallow clone of that depth
+
+use-separate-remote compatibility, do not use
+no-separate-remote compatibility, do not use"
+
die() {
echo >&2 "$@"
exit 1
}
usage() {
- die "Usage: $0 [--template=<template_directory>] [--reference <reference-repo>] [--bare] [-l [-s]] [-q] [-u <upload-pack>] [--origin <name>] [--depth <n>] [-n] [--] <repo> [<dir>]"
+ exec "$0" -h
}
+eval "$(echo "$OPTIONS_SPEC" | git rev-parse --parseopt -- "$@" || echo exit $?)"
+
get_repo_base() {
(
cd "`/bin/pwd`" &&
@@ -106,67 +127,57 @@ depth=
no_progress=
local_explicitly_asked_for=
test -t 1 || no_progress=--no-progress
-while
- case "$#,$1" in
- 0,*) break ;;
- *,-n|*,--no|*,--no-|*,--no-c|*,--no-ch|*,--no-che|*,--no-chec|\
- *,--no-check|*,--no-checko|*,--no-checkou|*,--no-checkout)
- no_checkout=yes ;;
- *,--na|*,--nak|*,--nake|*,--naked|\
- *,-b|*,--b|*,--ba|*,--bar|*,--bare) bare=yes ;;
- *,-l|*,--l|*,--lo|*,--loc|*,--loca|*,--local)
- local_explicitly_asked_for=yes
- use_local_hardlink=yes ;;
- *,--no-h|*,--no-ha|*,--no-har|*,--no-hard|*,--no-hardl|\
- *,--no-hardli|*,--no-hardlin|*,--no-hardlink|*,--no-hardlinks)
- use_local_hardlink=no ;;
- *,-s|*,--s|*,--sh|*,--sha|*,--shar|*,--share|*,--shared)
- local_shared=yes; ;;
- 1,--template) usage ;;
- *,--template)
+
+while test $# != 0
+do
+ case "$1" in
+ -n|--no-checkout)
+ no_checkout=yes ;;
+ --naked|--bare)
+ bare=yes ;;
+ -l|--local)
+ local_explicitly_asked_for=yes
+ use_local_hardlink=yes
+ ;;
+ --no-hardlinks)
+ use_local_hardlink=no ;;
+ -s|--shared)
+ local_shared=yes ;;
+ --template)
shift; template="--template=$1" ;;
- *,--template=*)
- template="$1" ;;
- *,-q|*,--quiet) quiet=-q ;;
- *,--use-separate-remote) ;;
- *,--no-separate-remote)
+ -q|--quiet)
+ quiet=-q ;;
+ --use-separate-remote|--no-separate-remote)
die "clones are always made with separate-remote layout" ;;
- 1,--reference) usage ;;
- *,--reference)
+ --reference)
shift; reference="$1" ;;
- *,--reference=*)
- reference=`expr "z$1" : 'z--reference=\(.*\)'` ;;
- *,-o|*,--or|*,--ori|*,--orig|*,--origi|*,--origin)
- case "$2" in
+ -o,--origin)
+ shift;
+ case "$1" in
'')
usage ;;
*/*)
- die "'$2' is not suitable for an origin name"
+ die "'$1' is not suitable for an origin name"
esac
- git check-ref-format "heads/$2" ||
- die "'$2' is not suitable for a branch name"
+ git check-ref-format "heads/$1" ||
+ die "'$1' is not suitable for a branch name"
test -z "$origin_override" ||
die "Do not give more than one --origin options."
origin_override=yes
- origin="$2"; shift
+ origin="$1"
;;
- 1,-u|1,--upload-pack) usage ;;
- *,-u|*,--upload-pack)
+ -u|--upload-pack)
shift
upload_pack="--upload-pack=$1" ;;
- *,--upload-pack=*)
- upload_pack=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)') ;;
- 1,--depth) usage;;
- *,--depth)
+ --depth)
shift
- depth="--depth=$1";;
- *,--)
+ depth="--depth=$1" ;;
+ --)
shift
break ;;
- *,-*) usage ;;
- *) break ;;
+ *)
+ usage ;;
esac
-do
shift
done
diff --git a/git-commit.sh b/git-commit.sh
index fcb8443bd..485339754 100755
--- a/git-commit.sh
+++ b/git-commit.sh
@@ -5,6 +5,7 @@
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
@@ -26,7 +27,7 @@ refuse_partial () {
}
TMP_INDEX=
-THIS_INDEX="$GIT_DIR/index"
+THIS_INDEX="${GIT_INDEX_FILE:-$GIT_DIR/index}"
NEXT_INDEX="$GIT_DIR/next-index$$"
rm -f "$NEXT_INDEX"
save_index () {
@@ -282,9 +283,9 @@ unset only
case "$all,$interactive,$also,$#" in
*t,*t,*)
die "Cannot use -a, --interactive or -i at the same time." ;;
-t,,[1-9]*)
+t,,,[1-9]*)
die "Paths with -a does not make sense." ;;
-,t,[1-9]*)
+,t,,[1-9]*)
die "Paths with --interactive does not make sense." ;;
,,t,0)
die "No paths with -i does not make sense." ;;
diff --git a/git-compat-util.h b/git-compat-util.h
index 7b29d1b90..79eb10eac 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -4,10 +4,24 @@
#define _FILE_OFFSET_BITS 64
#ifndef FLEX_ARRAY
-#if defined(__GNUC__) && (__GNUC__ < 3)
-#define FLEX_ARRAY 0
-#else
-#define FLEX_ARRAY /* empty */
+/*
+ * See if our compiler is known to support flexible array members.
+ */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
+# define FLEX_ARRAY /* empty */
+#elif defined(__GNUC__)
+# if (__GNUC__ >= 3)
+# define FLEX_ARRAY /* empty */
+# else
+# define FLEX_ARRAY 0 /* older GNU extension */
+# endif
+#endif
+
+/*
+ * Otherwise, default to safer but a bit wasteful traditional style
+ */
+#ifndef FLEX_ARRAY
+# define FLEX_ARRAY 1
#endif
#endif
@@ -20,6 +34,7 @@
#endif
#define MSB(x, bits) ((x) & TYPEOF(x)(~0ULL << (sizeof(x) * 8 - (bits))))
+#define HAS_MULTI_BITS(i) ((i) & ((i) - 1)) /* checks if an integer has more than 1 bit set */
/* Approximation of the length of the decimal representation of this type. */
#define decimal_length(x) ((int)(sizeof(x) * 2.56 + 0.5) + 1)
@@ -52,6 +67,8 @@
#include <fnmatch.h>
#include <sys/poll.h>
#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <sys/select.h>
#include <assert.h>
#include <regex.h>
#include <netinet/in.h>
@@ -183,6 +200,22 @@ void *gitmemmem(const void *haystack, size_t haystacklen,
const void *needle, size_t needlelen);
#endif
+#ifdef __GLIBC_PREREQ
+#if __GLIBC_PREREQ(2, 1)
+#define HAVE_STRCHRNUL
+#endif
+#endif
+
+#ifndef HAVE_STRCHRNUL
+#define strchrnul gitstrchrnul
+static inline char *gitstrchrnul(const char *s, int c)
+{
+ while (*s && *s != c)
+ s++;
+ return (char *)s;
+}
+#endif
+
extern void release_pack_memory(size_t, int);
static inline char* xstrdup(const char *str)
diff --git a/git-cvsexportcommit.perl b/git-cvsexportcommit.perl
index 26844af43..92e41620f 100755
--- a/git-cvsexportcommit.perl
+++ b/git-cvsexportcommit.perl
@@ -1,28 +1,42 @@
#!/usr/bin/perl -w
-# Known limitations:
-# - does not propagate permissions
-# - error handling has not been extensively tested
-#
-
use strict;
use Getopt::Std;
use File::Temp qw(tempdir);
use Data::Dumper;
use File::Basename qw(basename dirname);
-unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
- die "GIT_DIR is not defined or is unreadable";
-}
-
-our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u);
+our ($opt_h, $opt_P, $opt_p, $opt_v, $opt_c, $opt_f, $opt_a, $opt_m, $opt_d, $opt_u, $opt_w);
-getopts('uhPpvcfam:d:');
+getopts('uhPpvcfam:d:w:');
$opt_h && usage();
die "Need at least one commit identifier!" unless @ARGV;
+if ($opt_w) {
+ unless ($ENV{GIT_DIR}) {
+ # Remember where our GIT_DIR is before changing to CVS checkout
+ my $gd =`git-rev-parse --git-dir`;
+ chomp($gd);
+ if ($gd eq '.git') {
+ my $wd = `pwd`;
+ chomp($wd);
+ $gd = $wd."/.git" ;
+ }
+ $ENV{GIT_DIR} = $gd;
+ }
+
+ if (! -d $opt_w."/CVS" ) {
+ die "$opt_w is not a CVS checkout";
+ }
+ chdir $opt_w or die "Cannot change to CVS checkout at $opt_w";
+}
+unless ($ENV{GIT_DIR} && -r $ENV{GIT_DIR}){
+ die "GIT_DIR is not defined or is unreadable";
+}
+
+
my @cvs;
if ($opt_d) {
@cvs = ('cvs', '-d', $opt_d);
@@ -274,6 +288,7 @@ if ($dirtypatch) {
print "You'll need to apply the patch in .cvsexportcommit.diff manually\n";
print "using a patch program. After applying the patch and resolving the\n";
print "problems you may commit using:";
+ print "\n cd \"$opt_w\"" if $opt_w;
print "\n $cmd\n\n";
exit(1);
}
@@ -301,7 +316,7 @@ sleep(1);
sub usage {
print STDERR <<END;
-Usage: GIT_DIR=/path/to/.git ${\basename $0} [-h] [-p] [-v] [-c] [-f] [-m msgprefix] [ parent ] commit
+Usage: GIT_DIR=/path/to/.git ${\basename $0} [-h] [-p] [-v] [-c] [-f] [-u] [-w cvsworkdir] [-m msgprefix] [ parent ] commit
END
exit(1);
}
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index e4bc2b54f..efa6a0c41 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -223,7 +223,8 @@ sub conn {
}
}
- $user="anonymous" unless defined $user;
+ # if username is not explicit in CVSROOT, then use current user, as cvs would
+ $user=(getlogin() || $ENV{'LOGNAME'} || $ENV{'USER'} || "anonymous") unless $user;
my $rr2 = "-";
unless ($port) {
$rr2 = ":pserver:$user\@$serv:$repo";
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index ffcc408ee..c9f515d0e 100755
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -92,6 +92,7 @@ USAGE="[--env-filter <command>] [--tree-filter <command>] \
[--original <namespace>] [-d <directory>] [-f | --force] \
[<rev-list options>...]"
+OPTIONS_SPEC=
. git-sh-setup
git diff-files --quiet &&
diff --git a/git-gui/.gitignore b/git-gui/.gitignore
index 020b86dea..6483b21cb 100644
--- a/git-gui/.gitignore
+++ b/git-gui/.gitignore
@@ -1,5 +1,8 @@
+.DS_Store
+config.mak
+Git Gui.app*
+git-gui.tcl
GIT-VERSION-FILE
GIT-GUI-VARS
-git-citool
git-gui
lib/tclIndex
diff --git a/git-gui/GIT-VERSION-GEN b/git-gui/GIT-VERSION-GEN
index 9770b0bc2..cfe46a857 100755
--- a/git-gui/GIT-VERSION-GEN
+++ b/git-gui/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=0.8.GITGUI
+DEF_VER=0.9.GITGUI
LF='
'
diff --git a/git-gui/Makefile b/git-gui/Makefile
index 18e675013..e86031927 100644
--- a/git-gui/Makefile
+++ b/git-gui/Makefile
@@ -2,18 +2,27 @@ all::
# Define V=1 to have a more verbose compile.
#
+# Define NO_MSGFMT if you do not have msgfmt from the GNU gettext
+# package and want to use our rough pure Tcl po->msg translator.
+# TCL_PATH must be vaild for this to work.
+#
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN
-include GIT-VERSION-FILE
+uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not')
uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not')
SCRIPT_SH = git-gui.sh
+GITGUI_MAIN := git-gui
GITGUI_BUILT_INS = git-citool
-ALL_PROGRAMS = $(GITGUI_BUILT_INS) $(patsubst %.sh,%,$(SCRIPT_SH))
ALL_LIBFILES = $(wildcard lib/*.tcl)
PRELOAD_FILES = lib/class.tcl
+NONTCL_LIBFILES = \
+ lib/git-gui.ico \
+ $(wildcard lib/win32_*.js) \
+#end NONTCL_LIBFILES
ifndef SHELL_PATH
SHELL_PATH = /bin/sh
@@ -31,7 +40,7 @@ ifndef INSTALL
INSTALL = install
endif
-RM_F ?= rm -f
+RM_RF ?= rm -rf
RMDIR ?= rmdir
INSTALL_D0 = $(INSTALL) -d -m755 # space is required here
@@ -40,6 +49,8 @@ INSTALL_R0 = $(INSTALL) -m644 # space is required here
INSTALL_R1 =
INSTALL_X0 = $(INSTALL) -m755 # space is required here
INSTALL_X1 =
+INSTALL_A0 = find # space is required here
+INSTALL_A1 = | cpio -pud
INSTALL_L0 = rm -f # space is required here
INSTALL_L1 = && ln # space is required here
INSTALL_L2 =
@@ -47,15 +58,16 @@ INSTALL_L3 =
REMOVE_D0 = $(RMDIR) # space is required here
REMOVE_D1 = || true
-REMOVE_F0 = $(RM_F) # space is required here
+REMOVE_F0 = $(RM_RF) # space is required here
REMOVE_F1 =
CLEAN_DST = true
ifndef V
QUIET = @
- QUIET_GEN = $(QUIET)echo ' ' GEN $@ &&
- QUIET_BUILT_IN = $(QUIET)echo ' ' BUILTIN $@ &&
+ QUIET_GEN = $(QUIET)echo ' ' GEN '$@' &&
QUIET_INDEX = $(QUIET)echo ' ' INDEX $(dir $@) &&
+ QUIET_MSGFMT0 = $(QUIET)printf ' MSGFMT %12s ' $@ && v=`
+ QUIET_MSGFMT1 = 2>&1` && echo "$$v" | sed -e 's/fuzzy translations/fuzzy/' | sed -e 's/ messages//g'
QUIET_2DEVNULL = 2>/dev/null
INSTALL_D0 = dir=
@@ -64,6 +76,8 @@ ifndef V
INSTALL_R1 = && echo ' ' INSTALL 644 `basename $$src` && $(INSTALL) -m644 $$src
INSTALL_X0 = src=
INSTALL_X1 = && echo ' ' INSTALL 755 `basename $$src` && $(INSTALL) -m755 $$src
+ INSTALL_A0 = src=
+ INSTALL_A1 = && echo ' ' INSTALL ' ' `basename "$$src"` && find "$$src" | cpio -pud
INSTALL_L0 = dst=
INSTALL_L1 = && src=
@@ -74,51 +88,133 @@ ifndef V
REMOVE_D0 = dir=
REMOVE_D1 = && echo ' ' REMOVE $$dir && test -d "$$dir" && $(RMDIR) "$$dir" || true
REMOVE_F0 = dst=
- REMOVE_F1 = && echo ' ' REMOVE `basename "$$dst"` && $(RM_F) "$$dst"
+ REMOVE_F1 = && echo ' ' REMOVE `basename "$$dst"` && $(RM_RF) "$$dst"
endif
TCL_PATH ?= tclsh
TCLTK_PATH ?= wish
+TKFRAMEWORK = /Library/Frameworks/Tk.framework/Resources/Wish.app
ifeq ($(findstring $(MAKEFLAGS),s),s)
QUIET_GEN =
-QUIET_BUILT_IN =
endif
+-include config.mak
+
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
TCL_PATH_SQ = $(subst ','\'',$(TCL_PATH))
TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
+TCLTK_PATH_SED = $(subst ','\'',$(subst \,\\,$(TCLTK_PATH)))
gg_libdir ?= $(sharedir)/git-gui/lib
libdir_SQ = $(subst ','\'',$(gg_libdir))
+libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir)))
+exedir = $(dir $(gitexecdir))share/git-gui/lib
+
+GITGUI_SCRIPT := $$0
+GITGUI_RELATIVE :=
+GITGUI_MACOSXAPP :=
+
+ifeq ($(exedir),$(gg_libdir))
+ GITGUI_RELATIVE := 1
+endif
+
+ifeq ($(uname_O),Cygwin)
+ GITGUI_SCRIPT := `cygpath --windows --absolute "$(GITGUI_SCRIPT)"`
+ ifeq ($(GITGUI_RELATIVE),)
+ gg_libdir := $(shell cygpath --windows --absolute "$(gg_libdir)")
+ endif
+endif
+ifeq ($(uname_S),Darwin)
+ ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y)
+ GITGUI_MACOSXAPP := YesPlease
+ endif
+endif
+ifneq (,$(findstring MINGW,$(uname_S)))
+ NO_MSGFMT=1
+ GITGUI_WINDOWS_WRAPPER := YesPlease
+endif
+
+ifdef GITGUI_MACOSXAPP
+GITGUI_MAIN := git-gui.tcl
+
+git-gui: GIT-VERSION-FILE GIT-GUI-VARS
+ $(QUIET_GEN)rm -f $@ $@+ && \
+ echo '#!$(SHELL_PATH_SQ)' >$@+ && \
+ echo 'if test "z$$*" = zversion ||' >>$@+ && \
+ echo ' test "z$$*" = z--version' >>$@+ && \
+ echo then >>$@+ && \
+ echo ' 'echo \'git-gui version '$(GITGUI_VERSION)'\' >>$@+ && \
+ echo else >>$@+ && \
+ echo ' 'exec \''$(libdir_SQ)/Git Gui.app/Contents/MacOS/Wish'\' \
+ '"$$0" "$$@"' >>$@+ && \
+ echo fi >>$@+ && \
+ chmod +x $@+ && \
+ mv $@+ $@
+
+Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-VARS \
+ macosx/Info.plist \
+ macosx/git-gui.icns \
+ macosx/AppMain.tcl \
+ $(TKFRAMEWORK)/Contents/MacOS/Wish
+ $(QUIET_GEN)rm -rf '$@' '$@'+ && \
+ mkdir -p '$@'+/Contents/MacOS && \
+ mkdir -p '$@'+/Contents/Resources/Scripts && \
+ cp '$(subst ','\'',$(TKFRAMEWORK))/Contents/MacOS/Wish' \
+ '$@'+/Contents/MacOS && \
+ cp macosx/git-gui.icns '$@'+/Contents/Resources && \
+ sed -e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
+ macosx/Info.plist \
+ >'$@'+/Contents/Info.plist && \
+ sed -e 's|@@gitexecdir@@|$(gitexecdir_SQ)|' \
+ -e 's|@@GITGUI_LIBDIR@@|$(libdir_SED)|' \
+ macosx/AppMain.tcl \
+ >'$@'+/Contents/Resources/Scripts/AppMain.tcl && \
+ mv '$@'+ '$@'
+endif
+
+ifdef GITGUI_WINDOWS_WRAPPER
+GITGUI_MAIN := git-gui.tcl
-exedir = $(dir $(gitexecdir))share/git-gui/lib
-exedir_SQ = $(subst ','\'',$(exedir))
+git-gui: windows/git-gui.sh
+ cp $< $@
+endif
-$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
+$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-VARS
$(QUIET_GEN)rm -f $@ $@+ && \
- GITGUI_RELATIVE= && \
- if test '$(exedir_SQ)' = '$(libdir_SQ)'; then \
- if test "$(uname_O)" = Cygwin; \
- then GITGUI_RELATIVE= ; \
- else GITGUI_RELATIVE=1; \
- fi; \
- fi && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
- -e 's|^ exec wish "$$0"| exec $(subst |,'\|',$(TCLTK_PATH_SQ)) "$$0"|' \
+ -e '1,30s|^ argv0=$$0| argv0=$(GITGUI_SCRIPT)|' \
+ -e '1,30s|^ exec wish | exec '\''$(TCLTK_PATH_SED)'\'' |' \
-e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
- -e 's|@@GITGUI_RELATIVE@@|'$$GITGUI_RELATIVE'|' \
- -e $$GITGUI_RELATIVE's|@@GITGUI_LIBDIR@@|$(libdir_SQ)|' \
- $@.sh >$@+ && \
+ -e 's|@@GITGUI_RELATIVE@@|$(GITGUI_RELATIVE)|' \
+ -e '$(GITGUI_RELATIVE)s|@@GITGUI_LIBDIR@@|$(libdir_SED)|' \
+ git-gui.sh >$@+ && \
chmod +x $@+ && \
mv $@+ $@
-$(GITGUI_BUILT_INS): git-gui
- $(QUIET_BUILT_IN)rm -f $@ && ln git-gui $@
+XGETTEXT ?= xgettext
+ifdef NO_MSGFMT
+ MSGFMT ?= $(TCL_PATH) po/po2msg.sh
+else
+ MSGFMT ?= msgfmt
+endif
+
+msgsdir = $(gg_libdir)/msgs
+msgsdir_SQ = $(subst ','\'',$(msgsdir))
+PO_TEMPLATE = po/git-gui.pot
+ALL_POFILES = $(wildcard po/*.po)
+ALL_MSGFILES = $(subst .po,.msg,$(ALL_POFILES))
+
+$(PO_TEMPLATE): $(SCRIPT_SH) $(ALL_LIBFILES)
+ $(XGETTEXT) -kmc -LTcl -o $@ $(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)
-lib/tclIndex: $(ALL_LIBFILES)
+lib/tclIndex: $(ALL_LIBFILES) GIT-GUI-VARS
$(QUIET_INDEX)if echo \
$(foreach p,$(PRELOAD_FILES),source $p\;) \
auto_mkindex lib '*.tcl' \
@@ -132,16 +228,13 @@ lib/tclIndex: $(ALL_LIBFILES)
echo >>$@ ; \
fi
-# These can record GITGUI_VERSION
-$(patsubst %.sh,%,$(SCRIPT_SH)): GIT-VERSION-FILE GIT-GUI-VARS
-lib/tclIndex: GIT-GUI-VARS
-
TRACK_VARS = \
$(subst ','\'',SHELL_PATH='$(SHELL_PATH_SQ)') \
$(subst ','\'',TCL_PATH='$(TCL_PATH_SQ)') \
$(subst ','\'',TCLTK_PATH='$(TCLTK_PATH_SQ)') \
$(subst ','\'',gitexecdir='$(gitexecdir_SQ)') \
$(subst ','\'',gg_libdir='$(libdir_SQ)') \
+ GITGUI_MACOSXAPP=$(GITGUI_MACOSXAPP) \
#end TRACK_VARS
GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
@@ -151,24 +244,49 @@ GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
echo 1>$@ "$$VARS"; \
fi
-all:: $(ALL_PROGRAMS) lib/tclIndex
+ifdef GITGUI_MACOSXAPP
+all:: git-gui Git\ Gui.app
+endif
+ifdef GITGUI_WINDOWS_WRAPPER
+all:: git-gui
+endif
+all:: $(GITGUI_MAIN) lib/tclIndex $(ALL_MSGFILES)
install: all
$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1)
$(QUIET)$(INSTALL_X0)git-gui $(INSTALL_X1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(INSTALL_L0)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L1)'$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' $(INSTALL_L2)'$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' $(INSTALL_L3) &&) true
+ifdef GITGUI_WINDOWS_WRAPPER
+ $(QUIET)$(INSTALL_R0)git-gui.tcl $(INSTALL_R1) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
+endif
$(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(INSTALL_D1)
$(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)'
- $(QUIET)$(foreach p,$(ALL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
+ifdef GITGUI_MACOSXAPP
+ $(QUIET)$(INSTALL_A0)'Git Gui.app' $(INSTALL_A1) '$(DESTDIR_SQ)$(libdir_SQ)'
+ $(QUIET)$(INSTALL_X0)git-gui.tcl $(INSTALL_X1) '$(DESTDIR_SQ)$(libdir_SQ)'
+endif
+ $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
+ $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(INSTALL_D1)
+ $(QUIET)$(foreach p,$(ALL_MSGFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true
uninstall:
$(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui $(REMOVE_F1)
$(QUIET)$(foreach p,$(GITGUI_BUILT_INS), $(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/$p $(REMOVE_F1) &&) true
+ifdef GITGUI_WINDOWS_WRAPPER
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui.tcl $(REMOVE_F1)
+endif
$(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(libdir_SQ)'
$(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/tclIndex $(REMOVE_F1)
- $(QUIET)$(foreach p,$(ALL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
+ifdef GITGUI_MACOSXAPP
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)/Git Gui.app' $(REMOVE_F1)
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.tcl $(REMOVE_F1)
+endif
+ $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
+ $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(msgsdir_SQ)'
+ $(QUIET)$(foreach p,$(ALL_MSGFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(msgsdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
$(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(REMOVE_D1)
+ $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(REMOVE_D1)
$(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(REMOVE_D1)
$(QUIET)$(REMOVE_D0)`dirname '$(DESTDIR_SQ)$(libdir_SQ)'` $(REMOVE_D1)
@@ -177,8 +295,14 @@ dist-version:
@echo $(GITGUI_VERSION) > $(TARDIR)/version
clean::
- rm -f $(ALL_PROGRAMS) lib/tclIndex
- rm -f GIT-VERSION-FILE GIT-GUI-VARS
+ $(RM_RF) $(GITGUI_MAIN) lib/tclIndex po/*.msg
+ $(RM_RF) GIT-VERSION-FILE GIT-GUI-VARS
+ifdef GITGUI_MACOSXAPP
+ $(RM_RF) 'Git Gui.app'* git-gui
+endif
+ifdef GITGUI_WINDOWS_WRAPPER
+ $(RM_RF) git-gui
+endif
.PHONY: all install uninstall dist-version clean
.PHONY: .FORCE-GIT-VERSION-FILE
diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh
index 9335a9761..1fca11f27 100755
--- a/git-gui/git-gui.sh
+++ b/git-gui/git-gui.sh
@@ -6,11 +6,12 @@
echo 'git-gui version @@GITGUI_VERSION@@'; \
exit; \
fi; \
- exec wish "$0" -- "$@"
+ argv0=$0; \
+ exec wish "$argv0" -- "$@"
set appvers {@@GITGUI_VERSION@@}
-set copyright {
-Copyright © 2006, 2007 Shawn Pearce, et. al.
+set copyright [encoding convertfrom utf-8 {
+Copyright © 2006, 2007 Shawn Pearce, et. al.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,7 +25,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}]
######################################################################
##
@@ -37,7 +38,7 @@ if {[catch {package require Tcl 8.4} err]
tk_messageBox \
-icon error \
-type ok \
- -title "git-gui: fatal error" \
+ -title [mc "git-gui: fatal error"] \
-message $err
exit 1
}
@@ -46,6 +47,24 @@ catch {rename send {}} ; # What an evil concept...
######################################################################
##
+## locate our library
+
+set oguilib {@@GITGUI_LIBDIR@@}
+set oguirel {@@GITGUI_RELATIVE@@}
+if {$oguirel eq {1}} {
+ set oguilib [file dirname [file dirname [file normalize $argv0]]]
+ set oguilib [file join $oguilib share git-gui lib]
+ set oguimsg [file join $oguilib msgs]
+} elseif {[string match @@* $oguirel]} {
+ set oguilib [file join [file dirname [file normalize $argv0]] lib]
+ set oguimsg [file join [file dirname [file normalize $argv0]] po]
+} else {
+ set oguimsg [file join $oguilib msgs]
+}
+unset oguirel
+
+######################################################################
+##
## enable verbose loading?
if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
@@ -64,21 +83,39 @@ if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
######################################################################
##
-## Fake internationalization to ease backporting of changes.
+## Internationalization (i18n) through msgcat and gettext. See
+## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html
+
+package require msgcat
-proc mc {fmt args} {
+proc _mc_trim {fmt} {
set cmk [string first @@ $fmt]
if {$cmk > 0} {
- set fmt [string range $fmt 0 [expr {$cmk - 1}]]
+ return [string range $fmt 0 [expr {$cmk - 1}]]
}
- return [eval [list format $fmt] $args]
+ return $fmt
+}
+
+proc mc {en_fmt args} {
+ set fmt [_mc_trim [::msgcat::mc $en_fmt]]
+ if {[catch {set msg [eval [list format $fmt] $args]} err]} {
+ set msg [eval [list format [_mc_trim $en_fmt]] $args]
+ }
+ return $msg
+}
+
+proc strcat {args} {
+ return [join $args {}]
}
+::msgcat::mcload $oguimsg
+unset oguimsg
+
######################################################################
##
## read only globals
-set _appname [lindex [file split $argv0] end]
+set _appname {Git Gui}
set _gitdir {}
set _gitexec {}
set _reponame {}
@@ -175,6 +212,7 @@ proc disable_option {option} {
proc is_many_config {name} {
switch -glob -- $name {
+ gui.recentrepo -
remote.*.fetch -
remote.*.push
{return 1}
@@ -203,51 +241,6 @@ proc get_config {name} {
}
}
-proc load_config {include_global} {
- global repo_config global_config default_config
-
- array unset global_config
- if {$include_global} {
- catch {
- set fd_rc [git_read config --global --list]
- while {[gets $fd_rc line] >= 0} {
- if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
- if {[is_many_config $name]} {
- lappend global_config($name) $value
- } else {
- set global_config($name) $value
- }
- }
- }
- close $fd_rc
- }
- }
-
- array unset repo_config
- catch {
- set fd_rc [git_read config --list]
- while {[gets $fd_rc line] >= 0} {
- if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
- if {[is_many_config $name]} {
- lappend repo_config($name) $value
- } else {
- set repo_config($name) $value
- }
- }
- }
- close $fd_rc
- }
-
- foreach name [array names default_config] {
- if {[catch {set v $global_config($name)}]} {
- set global_config($name) $default_config($name)
- }
- if {[catch {set v $repo_config($name)}]} {
- set repo_config($name) $default_config($name)
- }
- }
-}
-
######################################################################
##
## handy utils
@@ -313,6 +306,9 @@ proc _which {what} {
$env(PATH)] {;}]
set _search_exe .exe
} elseif {[is_Windows]} {
+ set gitguidir [file dirname [info script]]
+ regsub -all ";" $gitguidir "\\;" gitguidir
+ set env(PATH) "$gitguidir;$env(PATH)"
set _search_path [split $env(PATH) {;}]
set _search_exe .exe
} else {
@@ -491,6 +487,110 @@ proc rmsel_tag {text} {
return $text
}
+set root_exists 0
+bind . <Visibility> {
+ bind . <Visibility> {}
+ set root_exists 1
+}
+
+if {[is_Windows]} {
+ wm iconbitmap . -default $oguilib/git-gui.ico
+}
+
+######################################################################
+##
+## config defaults
+
+set cursor_ptr arrow
+font create font_diff -family Courier -size 10
+font create font_ui
+catch {
+ label .dummy
+ eval font configure font_ui [font actual [.dummy cget -font]]
+ destroy .dummy
+}
+
+font create font_uiitalic
+font create font_uibold
+font create font_diffbold
+font create font_diffitalic
+
+foreach class {Button Checkbutton Entry Label
+ Labelframe Listbox Menu Message
+ Radiobutton Spinbox Text} {
+ option add *$class.font font_ui
+}
+unset class
+
+if {[is_Windows] || [is_MacOSX]} {
+ option add *Menu.tearOff 0
+}
+
+if {[is_MacOSX]} {
+ set M1B M1
+ set M1T Cmd
+} else {
+ set M1B Control
+ set M1T Ctrl
+}
+
+proc bind_button3 {w cmd} {
+ bind $w <Any-Button-3> $cmd
+ if {[is_MacOSX]} {
+ # Mac OS X sends Button-2 on right click through three-button mouse,
+ # or through trackpad right-clicking (two-finger touch + click).
+ bind $w <Any-Button-2> $cmd
+ bind $w <Control-Button-1> $cmd
+ }
+}
+
+proc apply_config {} {
+ global repo_config font_descs
+
+ foreach option $font_descs {
+ set name [lindex $option 0]
+ set font [lindex $option 1]
+ if {[catch {
+ set need_weight 1
+ foreach {cn cv} $repo_config(gui.$name) {
+ if {$cn eq {-weight}} {
+ set need_weight 0
+ }
+ font configure $font $cn $cv
+ }
+ if {$need_weight} {
+ font configure $font -weight normal
+ }
+ } err]} {
+ error_popup [strcat [mc "Invalid font specified in %s:" "gui.$name"] "\n\n$err"]
+ }
+ foreach {cn cv} [font configure $font] {
+ font configure ${font}bold $cn $cv
+ font configure ${font}italic $cn $cv
+ }
+ font configure ${font}bold -weight bold
+ font configure ${font}italic -slant italic
+ }
+}
+
+set default_config(merge.diffstat) true
+set default_config(merge.summary) false
+set default_config(merge.verbosity) 2
+set default_config(user.name) {}
+set default_config(user.email) {}
+
+set default_config(gui.matchtrackingbranch) false
+set default_config(gui.pruneduringfetch) false
+set default_config(gui.trustmtime) false
+set default_config(gui.diffcontext) 5
+set default_config(gui.newbranchtemplate) {}
+set default_config(gui.fontui) [font configure font_ui]
+set default_config(gui.fontdiff) [font configure font_diff]
+set font_descs {
+ {fontui font_ui {mc "Main Font"}}
+ {fontdiff font_diff {mc "Diff/Console Font"}}
+}
+
######################################################################
##
## find git
@@ -515,7 +615,7 @@ if {[catch {set _git_version [git --version]} err]} {
tk_messageBox \
-icon error \
-type ok \
- -title "git-gui: fatal error" \
+ -title [mc "git-gui: fatal error"] \
-message "Cannot determine Git version:
$err
@@ -528,8 +628,8 @@ if {![regsub {^git version } $_git_version {} _git_version]} {
tk_messageBox \
-icon error \
-type ok \
- -title "git-gui: fatal error" \
- -message "Cannot parse Git version string:\n\n$_git_version"
+ -title [mc "git-gui: fatal error"] \
+ -message [strcat [mc "Cannot parse Git version string:"] "\n\n$_git_version"]
exit 1
}
@@ -547,14 +647,14 @@ if {![regexp {^[1-9]+(\.[0-9]+)+$} $_git_version]} {
-type yesno \
-default no \
-title "[appname]: warning" \
- -message "Git version cannot be determined.
+ -message [mc "Git version cannot be determined.
-$_git claims it is version '$_real_git_version'.
+%s claims it is version '%s'.
-[appname] requires at least Git 1.5.0 or later.
+%s requires at least Git 1.5.0 or later.
-Assume '$_real_git_version' is version 1.5.0?
-"] eq {yes}} {
+Assume '%s' is version 1.5.0?
+" $_git $_real_git_version [appname] $_real_git_version]] eq {yes}} {
set _git_version 1.5.0
} else {
exit 1
@@ -611,7 +711,7 @@ if {[git-version < 1.5]} {
tk_messageBox \
-icon error \
-type ok \
- -title "git-gui: fatal error" \
+ -title [mc "git-gui: fatal error"] \
-message "[appname] requires Git 1.5.0 or later.
You are using [git-version]:
@@ -624,22 +724,13 @@ You are using [git-version]:
##
## configure our library
-set oguilib {@@GITGUI_LIBDIR@@}
-set oguirel {@@GITGUI_RELATIVE@@}
-if {$oguirel eq {1}} {
- set oguilib [file dirname [file dirname [file normalize $argv0]]]
- set oguilib [file join $oguilib share git-gui lib]
-} elseif {[string match @@* $oguirel]} {
- set oguilib [file join [file dirname [file normalize $argv0]] lib]
-}
-
set idx [file join $oguilib tclIndex]
if {[catch {set fd [open $idx r]} err]} {
catch {wm withdraw .}
tk_messageBox \
-icon error \
-type ok \
- -title "git-gui: fatal error" \
+ -title [mc "git-gui: fatal error"] \
-message $err
exit 1
}
@@ -666,13 +757,78 @@ if {$idx ne {}} {
} else {
set auto_path [concat [list $oguilib] $auto_path]
}
-unset -nocomplain oguirel idx fd
+unset -nocomplain idx fd
+
+######################################################################
+##
+## config file parsing
+
+git-version proc _parse_config {arr_name args} {
+ >= 1.5.3 {
+ upvar $arr_name arr
+ array unset arr
+ set buf {}
+ catch {
+ set fd_rc [eval \
+ [list git_read config] \
+ $args \
+ [list --null --list]]
+ fconfigure $fd_rc -translation binary
+ set buf [read $fd_rc]
+ close $fd_rc
+ }
+ foreach line [split $buf "\0"] {
+ if {[regexp {^([^\n]+)\n(.*)$} $line line name value]} {
+ if {[is_many_config $name]} {
+ lappend arr($name) $value
+ } else {
+ set arr($name) $value
+ }
+ }
+ }
+ }
+ default {
+ upvar $arr_name arr
+ array unset arr
+ catch {
+ set fd_rc [eval [list git_read config --list] $args]
+ while {[gets $fd_rc line] >= 0} {
+ if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
+ if {[is_many_config $name]} {
+ lappend arr($name) $value
+ } else {
+ set arr($name) $value
+ }
+ }
+ }
+ close $fd_rc
+ }
+ }
+}
+
+proc load_config {include_global} {
+ global repo_config global_config default_config
+
+ if {$include_global} {
+ _parse_config global_config --global
+ }
+ _parse_config repo_config
+
+ foreach name [array names default_config] {
+ if {[catch {set v $global_config($name)}]} {
+ set global_config($name) $default_config($name)
+ }
+ if {[catch {set v $repo_config($name)}]} {
+ set repo_config($name) $default_config($name)
+ }
+ }
+}
######################################################################
##
## feature option selection
-if {[regexp {^git-(.+)$} [appname] _junk subcommand]} {
+if {[regexp {^git-(.+)$} [file tail $argv0] _junk subcommand]} {
unset _junk
} else {
set subcommand gui
@@ -720,35 +876,35 @@ if {[catch {
set _gitdir [git rev-parse --git-dir]
set _prefix [git rev-parse --show-prefix]
} err]} {
- catch {wm withdraw .}
- error_popup "Cannot find the git directory:\n\n$err"
- exit 1
+ load_config 1
+ apply_config
+ choose_repository::pick
}
if {![file isdirectory $_gitdir] && [is_Cygwin]} {
- catch {set _gitdir [exec cygpath --unix $_gitdir]}
+ catch {set _gitdir [exec cygpath --windows $_gitdir]}
}
if {![file isdirectory $_gitdir]} {
catch {wm withdraw .}
- error_popup "Git directory not found:\n\n$_gitdir"
+ error_popup [strcat [mc "Git directory not found:"] "\n\n$_gitdir"]
exit 1
}
if {$_prefix ne {}} {
regsub -all {[^/]+/} $_prefix ../ cdup
if {[catch {cd $cdup} err]} {
catch {wm withdraw .}
- error_popup "Cannot move to top of working directory:\n\n$err"
+ error_popup [strcat [mc "Cannot move to top of working directory:"] "\n\n$err"]
exit 1
}
unset cdup
} elseif {![is_enabled bare]} {
if {[lindex [file split $_gitdir] end] ne {.git}} {
catch {wm withdraw .}
- error_popup "Cannot use funny .git directory:\n\n$_gitdir"
+ error_popup [strcat [mc "Cannot use funny .git directory:"] "\n\n$_gitdir"]
exit 1
}
if {[catch {cd [file dirname $_gitdir]} err]} {
catch {wm withdraw .}
- error_popup "No working directory [file dirname $_gitdir]:\n\n$err"
+ error_popup [strcat [mc "No working directory"] " [file dirname $_gitdir]:\n\n$err"]
exit 1
}
}
@@ -895,7 +1051,7 @@ proc rescan {after {honor_trustmtime 1}} {
rescan_stage2 {} $after
} else {
set rescan_active 1
- ui_status {Refreshing file status...}
+ ui_status [mc "Refreshing file status..."]
set fd_rf [git_read update-index \
-q \
--unmerged \
@@ -960,7 +1116,7 @@ proc rescan_stage2 {fd after} {
set buf_rlo {}
set rescan_active 3
- ui_status {Scanning for modified files ...}
+ ui_status [mc "Scanning for modified files ..."]
set fd_di [git_read diff-index --cached -z [PARENT]]
set fd_df [git_read diff-files -z]
set fd_lo [eval git_read ls-files --others -z $ls_others]
@@ -1401,31 +1557,32 @@ set all_icons(O$ui_workdir) file_plain
set max_status_desc 0
foreach i {
- {__ "Unmodified"}
-
- {_M "Modified, not staged"}
- {M_ "Staged for commit"}
- {MM "Portions staged for commit"}
- {MD "Staged for commit, missing"}
-
- {_O "Untracked, not staged"}
- {A_ "Staged for commit"}
- {AM "Portions staged for commit"}
- {AD "Staged for commit, missing"}
-
- {_D "Missing"}
- {D_ "Staged for removal"}
- {DO "Staged for removal, still present"}
-
- {U_ "Requires merge resolution"}
- {UU "Requires merge resolution"}
- {UM "Requires merge resolution"}
- {UD "Requires merge resolution"}
+ {__ {mc "Unmodified"}}
+
+ {_M {mc "Modified, not staged"}}
+ {M_ {mc "Staged for commit"}}
+ {MM {mc "Portions staged for commit"}}
+ {MD {mc "Staged for commit, missing"}}
+
+ {_O {mc "Untracked, not staged"}}
+ {A_ {mc "Staged for commit"}}
+ {AM {mc "Portions staged for commit"}}
+ {AD {mc "Staged for commit, missing"}}
+
+ {_D {mc "Missing"}}
+ {D_ {mc "Staged for removal"}}
+ {DO {mc "Staged for removal, still present"}}
+
+ {U_ {mc "Requires merge resolution"}}
+ {UU {mc "Requires merge resolution"}}
+ {UM {mc "Requires merge resolution"}}
+ {UD {mc "Requires merge resolution"}}
} {
- if {$max_status_desc < [string length [lindex $i 1]]} {
- set max_status_desc [string length [lindex $i 1]]
+ set text [eval [lindex $i 1]]
+ if {$max_status_desc < [string length $text]} {
+ set max_status_desc [string length $text]
}
- set all_descs([lindex $i 0]) [lindex $i 1]
+ set all_descs([lindex $i 0]) $text
}
unset i
@@ -1433,16 +1590,6 @@ unset i
##
## util
-proc bind_button3 {w cmd} {
- bind $w <Any-Button-3> $cmd
- if {[is_MacOSX]} {
- # Mac OS X sends Button-2 on right click through three-button mouse,
- # or through trackpad right-clicking (two-finger touch + click).
- bind $w <Any-Button-2> $cmd
- bind $w <Control-Button-1> $cmd
- }
-}
-
proc scrollbar2many {list mode args} {
foreach w $list {eval $w $mode $args}
}
@@ -1464,7 +1611,7 @@ proc incr_font_size {font {amt 1}} {
##
## ui commands
-set starting_gitk_msg {Starting gitk... please wait...}
+set starting_gitk_msg [mc "Starting gitk... please wait..."]
proc do_gitk {revs} {
# -- Always start gitk through whatever we were loaded with. This
@@ -1473,7 +1620,7 @@ proc do_gitk {revs} {
set exe [file join [file dirname $::_git] gitk]
set cmd [list [info nameofexecutable] $exe]
if {! [file exists $exe]} {
- error_popup "Unable to start gitk:\n\n$exe does not exist"
+ error_popup [mc "Unable to start gitk:\n\n%s does not exist" $exe]
} else {
global env
@@ -1546,8 +1693,8 @@ proc do_quit {} {
#
set cfg_geometry [list]
lappend cfg_geometry [wm geometry .]
- lappend cfg_geometry [lindex [.vpane sash coord 0] 1]
- lappend cfg_geometry [lindex [.vpane.files sash coord 0] 0]
+ lappend cfg_geometry [lindex [.vpane sash coord 0] 0]
+ lappend cfg_geometry [lindex [.vpane.files sash coord 0] 1]
if {[catch {set rc_geometry $repo_config(gui.geometry)}]} {
set rc_geometry {}
}
@@ -1664,104 +1811,26 @@ proc add_range_to_selection {w x y} {
######################################################################
##
-## config defaults
-
-set cursor_ptr arrow
-font create font_diff -family Courier -size 10
-font create font_ui
-catch {
- label .dummy
- eval font configure font_ui [font actual [.dummy cget -font]]
- destroy .dummy
-}
-
-font create font_uiitalic
-font create font_uibold
-font create font_diffbold
-font create font_diffitalic
-
-foreach class {Button Checkbutton Entry Label
- Labelframe Listbox Menu Message
- Radiobutton Spinbox Text} {
- option add *$class.font font_ui
-}
-unset class
-
-if {[is_Windows] || [is_MacOSX]} {
- option add *Menu.tearOff 0
-}
-
-if {[is_MacOSX]} {
- set M1B M1
- set M1T Cmd
-} else {
- set M1B Control
- set M1T Ctrl
-}
-
-proc apply_config {} {
- global repo_config font_descs
-
- foreach option $font_descs {
- set name [lindex $option 0]
- set font [lindex $option 1]
- if {[catch {
- foreach {cn cv} $repo_config(gui.$name) {
- font configure $font $cn $cv -weight normal
- }
- } err]} {
- error_popup "Invalid font specified in gui.$name:\n\n$err"
- }
- foreach {cn cv} [font configure $font] {
- font configure ${font}bold $cn $cv
- font configure ${font}italic $cn $cv
- }
- font configure ${font}bold -weight bold
- font configure ${font}italic -slant italic
- }
-}
-
-set default_config(merge.diffstat) true
-set default_config(merge.summary) false
-set default_config(merge.verbosity) 2
-set default_config(user.name) {}
-set default_config(user.email) {}
+## ui construction
-set default_config(gui.matchtrackingbranch) false
-set default_config(gui.pruneduringfetch) false
-set default_config(gui.trustmtime) false
-set default_config(gui.diffcontext) 5
-set default_config(gui.newbranchtemplate) {}
-set default_config(gui.fontui) [font configure font_ui]
-set default_config(gui.fontdiff) [font configure font_diff]
-set font_descs {
- {fontui font_ui {Main Font}}
- {fontdiff font_diff {Diff/Console Font}}
-}
load_config 0
apply_config
-
-######################################################################
-##
-## ui construction
-
set ui_comm {}
# -- Menu Bar
#
menu .mbar -tearoff 0
-.mbar add cascade -label Repository -menu .mbar.repository
-.mbar add cascade -label Edit -menu .mbar.edit
+.mbar add cascade -label [mc Repository] -menu .mbar.repository
+.mbar add cascade -label [mc Edit] -menu .mbar.edit
if {[is_enabled branch]} {
- .mbar add cascade -label Branch -menu .mbar.branch
+ .mbar add cascade -label [mc Branch] -menu .mbar.branch
}
if {[is_enabled multicommit] || [is_enabled singlecommit]} {
- .mbar add cascade -label Commit -menu .mbar.commit
+ .mbar add cascade -label [mc Commit@@noun] -menu .mbar.commit
}
if {[is_enabled transport]} {
- .mbar add cascade -label Merge -menu .mbar.merge
- .mbar add cascade -label Fetch -menu .mbar.fetch
- .mbar add cascade -label Push -menu .mbar.push
+ .mbar add cascade -label [mc Merge] -menu .mbar.merge
+ .mbar add cascade -label [mc Remote] -menu .mbar.remote
}
. configure -menu .mbar
@@ -1770,87 +1839,87 @@ if {[is_enabled transport]} {
menu .mbar.repository
.mbar.repository add command \
- -label {Browse Current Branch's Files} \
+ -label [mc "Browse Current Branch's Files"] \
-command {browser::new $current_branch}
set ui_browse_current [.mbar.repository index last]
.mbar.repository add command \
- -label {Browse Branch Files...} \
+ -label [mc "Browse Branch Files..."] \
-command browser_open::dialog
.mbar.repository add separator
.mbar.repository add command \
- -label {Visualize Current Branch's History} \
+ -label [mc "Visualize Current Branch's History"] \
-command {do_gitk $current_branch}
set ui_visualize_current [.mbar.repository index last]
.mbar.repository add command \
- -label {Visualize All Branch History} \
+ -label [mc "Visualize All Branch History"] \
-command {do_gitk --all}
.mbar.repository add separator
proc current_branch_write {args} {
global current_branch
.mbar.repository entryconf $::ui_browse_current \
- -label "Browse $current_branch's Files"
+ -label [mc "Browse %s's Files" $current_branch]
.mbar.repository entryconf $::ui_visualize_current \
- -label "Visualize $current_branch's History"
+ -label [mc "Visualize %s's History" $current_branch]
}
trace add variable current_branch write current_branch_write
if {[is_enabled multicommit]} {
- .mbar.repository add command -label {Database Statistics} \
+ .mbar.repository add command -label [mc "Database Statistics"] \
-command do_stats
- .mbar.repository add command -label {Compress Database} \
+ .mbar.repository add command -label [mc "Compress Database"] \
-command do_gc
- .mbar.repository add command -label {Verify Database} \
+ .mbar.repository add command -label [mc "Verify Database"] \
-command do_fsck_objects
.mbar.repository add separator
if {[is_Cygwin]} {
.mbar.repository add command \
- -label {Create Desktop Icon} \
+ -label [mc "Create Desktop Icon"] \
-command do_cygwin_shortcut
} elseif {[is_Windows]} {
.mbar.repository add command \
- -label {Create Desktop Icon} \
+ -label [mc "Create Desktop Icon"] \
-command do_windows_shortcut
} elseif {[is_MacOSX]} {
.mbar.repository add command \
- -label {Create Desktop Icon} \
+ -label [mc "Create Desktop Icon"] \
-command do_macosx_app
}
}
-.mbar.repository add command -label Quit \
+.mbar.repository add command -label [mc Quit] \
-command do_quit \
-accelerator $M1T-Q
# -- Edit Menu
#
menu .mbar.edit
-.mbar.edit add command -label Undo \
+.mbar.edit add command -label [mc Undo] \
-command {catch {[focus] edit undo}} \
-accelerator $M1T-Z
-.mbar.edit add command -label Redo \
+.mbar.edit add command -label [mc Redo] \
-command {catch {[focus] edit redo}} \
-accelerator $M1T-Y
.mbar.edit add separator
-.mbar.edit add command -label Cut \
+.mbar.edit add command -label [mc Cut] \
-command {catch {tk_textCut [focus]}} \
-accelerator $M1T-X
-.mbar.edit add command -label Copy \
+.mbar.edit add command -label [mc Copy] \
-command {catch {tk_textCopy [focus]}} \
-accelerator $M1T-C
-.mbar.edit add command -label Paste \
+.mbar.edit add command -label [mc Paste] \
-command {catch {tk_textPaste [focus]; [focus] see insert}} \
-accelerator $M1T-V
-.mbar.edit add command -label Delete \
+.mbar.edit add command -label [mc Delete] \
-command {catch {[focus] delete sel.first sel.last}} \
-accelerator Del
.mbar.edit add separator
-.mbar.edit add command -label {Select All} \
+.mbar.edit add command -label [mc "Select All"] \
-command {catch {[focus] tag add sel 0.0 end}} \
-accelerator $M1T-A
@@ -1859,29 +1928,29 @@ menu .mbar.edit
if {[is_enabled branch]} {
menu .mbar.branch
- .mbar.branch add command -label {Create...} \
+ .mbar.branch add command -label [mc "Create..."] \
-command branch_create::dialog \
-accelerator $M1T-N
lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state]
- .mbar.branch add command -label {Checkout...} \
+ .mbar.branch add command -label [mc "Checkout..."] \
-command branch_checkout::dialog \
-accelerator $M1T-O
lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state]
- .mbar.branch add command -label {Rename...} \
+ .mbar.branch add command -label [mc "Rename..."] \
-command branch_rename::dialog
lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state]
- .mbar.branch add command -label {Delete...} \
+ .mbar.branch add command -label [mc "Delete..."] \
-command branch_delete::dialog
lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state]
- .mbar.branch add command -label {Reset...} \
+ .mbar.branch add command -label [mc "Reset..."] \
-command merge::reset_hard
lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state]
@@ -1893,7 +1962,7 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
menu .mbar.commit
.mbar.commit add radiobutton \
- -label {New Commit} \
+ -label [mc "New Commit"] \
-command do_select_commit_type \
-variable selected_commit_type \
-value new
@@ -1901,7 +1970,7 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
[list .mbar.commit entryconf [.mbar.commit index last] -state]
.mbar.commit add radiobutton \
- -label {Amend Last Commit} \
+ -label [mc "Amend Last Commit"] \
-command do_select_commit_type \
-variable selected_commit_type \
-value amend
@@ -1910,40 +1979,41 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
.mbar.commit add separator
- .mbar.commit add command -label Rescan \
+ .mbar.commit add command -label [mc Rescan] \
-command do_rescan \
-accelerator F5
lappend disable_on_lock \
[list .mbar.commit entryconf [.mbar.commit index last] -state]
- .mbar.commit add command -label {Stage To Commit} \
- -command do_add_selection
+ .mbar.commit add command -label [mc "Stage To Commit"] \
+ -command do_add_selection \
+ -accelerator $M1T-T
lappend disable_on_lock \
[list .mbar.commit entryconf [.mbar.commit index last] -state]
- .mbar.commit add command -label {Stage Changed Files To Commit} \
+ .mbar.commit add command -label [mc "Stage Changed Files To Commit"] \
-command do_add_all \
-accelerator $M1T-I
lappend disable_on_lock \
[list .mbar.commit entryconf [.mbar.commit index last] -state]
- .mbar.commit add command -label {Unstage From Commit} \
+ .mbar.commit add command -label [mc "Unstage From Commit"] \
-command do_unstage_selection
lappend disable_on_lock \
[list .mbar.commit entryconf [.mbar.commit index last] -state]
- .mbar.commit add command -label {Revert Changes} \
+ .mbar.commit add command -label [mc "Revert Changes"] \
-command do_revert_selection
lappend disable_on_lock \
[list .mbar.commit entryconf [.mbar.commit index last] -state]
.mbar.commit add separator
- .mbar.commit add command -label {Sign Off} \
+ .mbar.commit add command -label [mc "Sign Off"] \
-command do_signoff \
-accelerator $M1T-S
- .mbar.commit add command -label Commit \
+ .mbar.commit add command -label [mc Commit@@verb] \
-command do_commit \
-accelerator $M1T-Return
lappend disable_on_lock \
@@ -1954,12 +2024,12 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
#
if {[is_enabled branch]} {
menu .mbar.merge
- .mbar.merge add command -label {Local Merge...} \
+ .mbar.merge add command -label [mc "Local Merge..."] \
-command merge::dialog \
-accelerator $M1T-M
lappend disable_on_lock \
[list .mbar.merge entryconf [.mbar.merge index last] -state]
- .mbar.merge add command -label {Abort Merge...} \
+ .mbar.merge add command -label [mc "Abort Merge..."] \
-command merge::reset_hard
lappend disable_on_lock \
[list .mbar.merge entryconf [.mbar.merge index last] -state]
@@ -1968,41 +2038,46 @@ if {[is_enabled branch]} {
# -- Transport Menu
#
if {[is_enabled transport]} {
- menu .mbar.fetch
+ menu .mbar.remote
- menu .mbar.push
- .mbar.push add command -label {Push...} \
+ .mbar.remote add command \
+ -label [mc "Push..."] \
-command do_push_anywhere \
-accelerator $M1T-P
- .mbar.push add command -label {Delete...} \
+ .mbar.remote add command \
+ -label [mc "Delete..."] \
-command remote_branch_delete::dialog
}
if {[is_MacOSX]} {
# -- Apple Menu (Mac OS X only)
#
- .mbar add cascade -label Apple -menu .mbar.apple
+ .mbar add cascade -label [mc Apple] -menu .mbar.apple
menu .mbar.apple
- .mbar.apple add command -label "About [appname]" \
+ .mbar.apple add command -label [mc "About %s" [appname]] \
-command do_about
- .mbar.apple add command -label "Options..." \
- -command do_options
+ .mbar.apple add separator
+ .mbar.apple add command \
+ -label [mc "Preferences..."] \
+ -command do_options \
+ -accelerator $M1T-,
+ bind . <$M1B-,> do_options
} else {
# -- Edit Menu
#
.mbar.edit add separator
- .mbar.edit add command -label {Options...} \
+ .mbar.edit add command -label [mc "Options..."] \
-command do_options
}
# -- Help Menu
#
-.mbar add cascade -label Help -menu .mbar.help
+.mbar add cascade -label [mc Help] -menu .mbar.help
menu .mbar.help
if {![is_MacOSX]} {
- .mbar.help add command -label "About [appname]" \
+ .mbar.help add command -label [mc "About %s" [appname]] \
-command do_about
}
@@ -2039,17 +2114,11 @@ if {[file isfile $doc_path]} {
}
if {$browser ne {}} {
- .mbar.help add command -label {Online Documentation} \
+ .mbar.help add command -label [mc "Online Documentation"] \
-command [list exec $browser $doc_url &]
}
unset browser doc_path doc_url
-set root_exists 0
-bind . <Visibility> {
- bind . <Visibility> {}
- set root_exists 1
-}
-
# -- Standard bindings
#
wm protocol . WM_DELETE_WINDOW do_quit
@@ -2129,7 +2198,7 @@ blame {
}
blame {
if {$head eq {} && ![file exists $path]} {
- puts stderr "fatal: cannot stat path $path: No such file or directory"
+ puts stderr [mc "fatal: cannot stat path %s: No such file or directory" $path]
exit 1
}
blame::new $head $path
@@ -2141,7 +2210,8 @@ citool -
gui {
if {[llength $argv] != 0} {
puts -nonewline stderr "usage: $argv0"
- if {$subcommand ne {gui} && [appname] ne "git-$subcommand"} {
+ if {$subcommand ne {gui}
+ && [file tail $argv0] ne "git-$subcommand"} {
puts -nonewline stderr " $subcommand"
}
puts stderr {}
@@ -2161,7 +2231,7 @@ frame .branch \
-borderwidth 1 \
-relief sunken
label .branch.l1 \
- -text {Current Branch:} \
+ -text [mc "Current Branch:"] \
-anchor w \
-justify left
label .branch.cb \
@@ -2174,15 +2244,15 @@ pack .branch -side top -fill x
# -- Main Window Layout
#
-panedwindow .vpane -orient vertical
-panedwindow .vpane.files -orient horizontal
+panedwindow .vpane -orient horizontal
+panedwindow .vpane.files -orient vertical
.vpane add .vpane.files -sticky nsew -height 100 -width 200
pack .vpane -anchor n -side top -fill both -expand 1
# -- Index File List
#
frame .vpane.files.index -height 100 -width 200
-label .vpane.files.index.title -text {Staged Changes (Will Be Committed)} \
+label .vpane.files.index.title -text [mc "Staged Changes (Will Commit)"] \
-background lightgreen
text $ui_index -background white -borderwidth 0 \
-width 20 -height 10 \
@@ -2197,12 +2267,11 @@ pack .vpane.files.index.title -side top -fill x
pack .vpane.files.index.sx -side bottom -fill x
pack .vpane.files.index.sy -side right -fill y
pack $ui_index -side left -fill both -expand 1
-.vpane.files add .vpane.files.index -sticky nsew
# -- Working Directory File List
#
frame .vpane.files.workdir -height 100 -width 200
-label .vpane.files.workdir.title -text {Unstaged Changes (Will Not Be Committed)} \
+label .vpane.files.workdir.title -text [mc "Unstaged Changes"] \
-background lightsalmon
text $ui_workdir -background white -borderwidth 0 \
-width 20 -height 10 \
@@ -2217,7 +2286,9 @@ pack .vpane.files.workdir.title -side top -fill x
pack .vpane.files.workdir.sx -side bottom -fill x
pack .vpane.files.workdir.sy -side right -fill y
pack $ui_workdir -side left -fill both -expand 1
+
.vpane.files add .vpane.files.workdir -sticky nsew
+.vpane.files add .vpane.files.index -sticky nsew
foreach i [list $ui_index $ui_workdir] {
rmsel_tag $i
@@ -2230,8 +2301,8 @@ unset i
frame .vpane.lower -height 300 -width 400
frame .vpane.lower.commarea
frame .vpane.lower.diff -relief sunken -borderwidth 1
-pack .vpane.lower.commarea -side top -fill x
-pack .vpane.lower.diff -side bottom -fill both -expand 1
+pack .vpane.lower.diff -fill both -expand 1
+pack .vpane.lower.commarea -side bottom -fill x
.vpane add .vpane.lower -sticky nsew
# -- Commit Area Buttons
@@ -2243,29 +2314,29 @@ label .vpane.lower.commarea.buttons.l -text {} \
pack .vpane.lower.commarea.buttons.l -side top -fill x
pack .vpane.lower.commarea.buttons -side left -fill y
-button .vpane.lower.commarea.buttons.rescan -text {Rescan} \
+button .vpane.lower.commarea.buttons.rescan -text [mc Rescan] \
-command do_rescan
pack .vpane.lower.commarea.buttons.rescan -side top -fill x
lappend disable_on_lock \
{.vpane.lower.commarea.buttons.rescan conf -state}
-button .vpane.lower.commarea.buttons.incall -text {Stage Changed} \
+button .vpane.lower.commarea.buttons.incall -text [mc "Stage Changed"] \
-command do_add_all
pack .vpane.lower.commarea.buttons.incall -side top -fill x
lappend disable_on_lock \
{.vpane.lower.commarea.buttons.incall conf -state}
-button .vpane.lower.commarea.buttons.signoff -text {Sign Off} \
+button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
-command do_signoff
pack .vpane.lower.commarea.buttons.signoff -side top -fill x
-button .vpane.lower.commarea.buttons.commit -text {Commit} \
+button .vpane.lower.commarea.buttons.commit -text [mc Commit@@verb] \
-command do_commit
pack .vpane.lower.commarea.buttons.commit -side top -fill x
lappend disable_on_lock \
{.vpane.lower.commarea.buttons.commit conf -state}
-button .vpane.lower.commarea.buttons.push -text {Push} \
+button .vpane.lower.commarea.buttons.push -text [mc Push] \
-command do_push_anywhere
pack .vpane.lower.commarea.buttons.push -side top -fill x
@@ -2276,14 +2347,14 @@ frame .vpane.lower.commarea.buffer.header
set ui_comm .vpane.lower.commarea.buffer.t
set ui_coml .vpane.lower.commarea.buffer.header.l
radiobutton .vpane.lower.commarea.buffer.header.new \
- -text {New Commit} \
+ -text [mc "New Commit"] \
-command do_select_commit_type \
-variable selected_commit_type \
-value new
lappend disable_on_lock \
[list .vpane.lower.commarea.buffer.header.new conf -state]
radiobutton .vpane.lower.commarea.buffer.header.amend \
- -text {Amend Last Commit} \
+ -text [mc "Amend Last Commit"] \
-command do_select_commit_type \
-variable selected_commit_type \
-value amend
@@ -2295,12 +2366,12 @@ label $ui_coml \
proc trace_commit_type {varname args} {
global ui_coml commit_type
switch -glob -- $commit_type {
- initial {set txt {Initial Commit Message:}}
- amend {set txt {Amended Commit Message:}}
- amend-initial {set txt {Amended Initial Commit Message:}}
- amend-merge {set txt {Amended Merge Commit Message:}}
- merge {set txt {Merge Commit Message:}}
- * {set txt {Commit Message:}}
+ initial {set txt [mc "Initial Commit Message:"]}
+ amend {set txt [mc "Amended Commit Message:"]}
+ amend-initial {set txt [mc "Amended Initial Commit Message:"]}
+ amend-merge {set txt [mc "Amended Merge Commit Message:"]}
+ merge {set txt [mc "Merge Commit Message:"]}
+ * {set txt [mc "Commit Message:"]}
}
$ui_coml conf -text $txt
}
@@ -2329,23 +2400,23 @@ pack .vpane.lower.commarea.buffer -side left -fill y
set ctxm .vpane.lower.commarea.buffer.ctxm
menu $ctxm -tearoff 0
$ctxm add command \
- -label {Cut} \
+ -label [mc Cut] \
-command {tk_textCut $ui_comm}
$ctxm add command \
- -label {Copy} \
+ -label [mc Copy] \
-command {tk_textCopy $ui_comm}
$ctxm add command \
- -label {Paste} \
+ -label [mc Paste] \
-command {tk_textPaste $ui_comm}
$ctxm add command \
- -label {Delete} \
+ -label [mc Delete] \
-command {$ui_comm delete sel.first sel.last}
$ctxm add separator
$ctxm add command \
- -label {Select All} \
+ -label [mc "Select All"] \
-command {focus $ui_comm;$ui_comm tag add sel 0.0 end}
$ctxm add command \
- -label {Copy All} \
+ -label [mc "Copy All"] \
-command {
$ui_comm tag add sel 0.0 end
tk_textCopy $ui_comm
@@ -2353,7 +2424,7 @@ $ctxm add command \
}
$ctxm add separator
$ctxm add command \
- -label {Sign Off} \
+ -label [mc "Sign Off"] \
-command do_signoff
bind_button3 $ui_comm "tk_popup $ctxm %X %Y"
@@ -2369,7 +2440,7 @@ proc trace_current_diff_path {varname args} {
} else {
set p $current_diff_path
set s [mapdesc [lindex $file_states($p) 0] $p]
- set f {File:}
+ set f [mc "File:"]
set p [escape_path $p]
set o normal
}
@@ -2403,7 +2474,7 @@ pack .vpane.lower.diff.header.path -fill x
set ctxm .vpane.lower.diff.header.ctxm
menu $ctxm -tearoff 0
$ctxm add command \
- -label {Copy} \
+ -label [mc Copy] \
-command {
clipboard clear
clipboard append \
@@ -2471,19 +2542,19 @@ $ui_diff tag raise sel
set ctxm .vpane.lower.diff.body.ctxm
menu $ctxm -tearoff 0
$ctxm add command \
- -label {Refresh} \
+ -label [mc Refresh] \
-command reshow_diff
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add command \
- -label {Copy} \
+ -label [mc Copy] \
-command {tk_textCopy $ui_diff}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add command \
- -label {Select All} \
+ -label [mc "Select All"] \
-command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add command \
- -label {Copy All} \
+ -label [mc "Copy All"] \
-command {
$ui_diff tag add sel 0.0 end
tk_textCopy $ui_diff
@@ -2492,45 +2563,45 @@ $ctxm add command \
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add separator
$ctxm add command \
- -label {Apply/Reverse Hunk} \
+ -label [mc "Apply/Reverse Hunk"] \
-command {apply_hunk $cursorX $cursorY}
set ui_diff_applyhunk [$ctxm index last]
lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
$ctxm add separator
$ctxm add command \
- -label {Decrease Font Size} \
+ -label [mc "Decrease Font Size"] \
-command {incr_font_size font_diff -1}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add command \
- -label {Increase Font Size} \
+ -label [mc "Increase Font Size"] \
-command {incr_font_size font_diff 1}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add separator
$ctxm add command \
- -label {Show Less Context} \
+ -label [mc "Show Less Context"] \
-command {if {$repo_config(gui.diffcontext) >= 1} {
incr repo_config(gui.diffcontext) -1
reshow_diff
}}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add command \
- -label {Show More Context} \
+ -label [mc "Show More Context"] \
-command {if {$repo_config(gui.diffcontext) < 99} {
incr repo_config(gui.diffcontext)
reshow_diff
}}
lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
$ctxm add separator
-$ctxm add command -label {Options...} \
+$ctxm add command -label [mc "Options..."] \
-command do_options
proc popup_diff_menu {ctxm x y X Y} {
global current_diff_path file_states
set ::cursorX $x
set ::cursorY $y
if {$::ui_index eq $::current_diff_side} {
- set l "Unstage Hunk From Commit"
+ set l [mc "Unstage Hunk From Commit"]
} else {
- set l "Stage Hunk For Commit"
+ set l [mc "Stage Hunk For Commit"]
}
if {$::is_3way_diff
|| $current_diff_path eq {}
@@ -2549,7 +2620,7 @@ bind_button3 $ui_diff [list popup_diff_menu $ctxm %x %y %X %Y]
#
set main_status [::status_bar::new .status]
pack .status -anchor w -side bottom -fill x
-$main_status show {Initializing...}
+$main_status show [mc "Initializing..."]
# -- Load geometry
#
@@ -2557,17 +2628,19 @@ catch {
set gm $repo_config(gui.geometry)
wm geometry . [lindex $gm 0]
.vpane sash place 0 \
- [lindex [.vpane sash coord 0] 0] \
- [lindex $gm 1]
+ [lindex $gm 1] \
+ [lindex [.vpane sash coord 0] 1]
.vpane.files sash place 0 \
- [lindex $gm 2] \
- [lindex [.vpane.files sash coord 0] 1]
+ [lindex [.vpane.files sash coord 0] 0] \
+ [lindex $gm 2]
unset gm
}
# -- Key Bindings
#
bind $ui_comm <$M1B-Key-Return> {do_commit;break}
+bind $ui_comm <$M1B-Key-t> {do_add_selection;break}
+bind $ui_comm <$M1B-Key-T> {do_add_selection;break}
bind $ui_comm <$M1B-Key-i> {do_add_all;break}
bind $ui_comm <$M1B-Key-I> {do_add_all;break}
bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break}
@@ -2617,6 +2690,8 @@ bind . <$M1B-Key-r> do_rescan
bind . <$M1B-Key-R> do_rescan
bind . <$M1B-Key-s> do_signoff
bind . <$M1B-Key-S> do_signoff
+bind . <$M1B-Key-t> do_add_selection
+bind . <$M1B-Key-T> do_add_selection
bind . <$M1B-Key-i> do_add_all
bind . <$M1B-Key-I> do_add_all
bind . <$M1B-Key-Return> do_commit
@@ -2640,13 +2715,13 @@ focus -force $ui_comm
if {[is_Cygwin]} {
set ignored_env 0
set suggest_user {}
- set msg "Possible environment issues exist.
+ set msg [mc "Possible environment issues exist.
The following environment variables are probably
going to be ignored by any Git subprocess run
-by [appname]:
+by %s:
-"
+" [appname]]
foreach name [array names env] {
switch -regexp -- $name {
{^GIT_INDEX_FILE$} -
@@ -2670,18 +2745,18 @@ by [appname]:
}
}
if {$ignored_env > 0} {
- append msg "
+ append msg [mc "
This is due to a known issue with the
-Tcl binary distributed by Cygwin."
+Tcl binary distributed by Cygwin."]
if {$suggest_user ne {}} {
- append msg "
+ append msg [mc "
-A good replacement for $suggest_user
+A good replacement for %s
is placing values for the user.name and
user.email settings into your personal
~/.gitconfig file.
-"
+" $suggest_user]
}
warn_popup $msg
}
@@ -2693,8 +2768,14 @@ user.email settings into your personal
if {[is_enabled transport]} {
load_all_remotes
- populate_fetch_menu
+ set n [.mbar.remote index end]
populate_push_menu
+ populate_fetch_menu
+ set n [expr {[.mbar.remote index end] - $n}]
+ if {$n > 0} {
+ .mbar.remote insert $n separator
+ }
+ unset n
}
if {[winfo exists $ui_comm]} {
diff --git a/git-gui/lib/about.tcl b/git-gui/lib/about.tcl
new file mode 100644
index 000000000..719fc547b
--- /dev/null
+++ b/git-gui/lib/about.tcl
@@ -0,0 +1,81 @@
+# git-gui about git-gui dialog
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc do_about {} {
+ global appvers copyright oguilib
+ global tcl_patchLevel tk_patchLevel
+
+ set w .about_dialog
+ toplevel $w
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+
+ pack [git_logo $w.git_logo] -side left -fill y -padx 10 -pady 10
+ label $w.header -text [mc "About %s" [appname]] \
+ -font font_uibold
+ pack $w.header -side top -fill x
+
+ frame $w.buttons
+ button $w.buttons.close -text {Close} \
+ -default active \
+ -command [list destroy $w]
+ pack $w.buttons.close -side right
+ pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+ label $w.desc \
+ -text "[mc "git-gui - a graphical user interface for Git."]\n$copyright" \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid
+ pack $w.desc -side top -fill x -padx 5 -pady 5
+
+ set v {}
+ append v "git-gui version $appvers\n"
+ append v "[git version]\n"
+ append v "\n"
+ if {$tcl_patchLevel eq $tk_patchLevel} {
+ append v "Tcl/Tk version $tcl_patchLevel"
+ } else {
+ append v "Tcl version $tcl_patchLevel"
+ append v ", Tk version $tk_patchLevel"
+ }
+
+ set d {}
+ append d "git wrapper: $::_git\n"
+ append d "git exec dir: [gitexec]\n"
+ append d "git-gui lib: $oguilib"
+
+ label $w.vers \
+ -text $v \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid
+ pack $w.vers -side top -fill x -padx 5 -pady 5
+
+ label $w.dirs \
+ -text $d \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid
+ pack $w.dirs -side top -fill x -padx 5 -pady 5
+
+ menu $w.ctxm -tearoff 0
+ $w.ctxm add command \
+ -label {Copy} \
+ -command "
+ clipboard clear
+ clipboard append -format STRING -type STRING -- \[$w.vers cget -text\]
+ "
+
+ bind $w <Visibility> "grab $w; focus $w.buttons.close"
+ bind $w <Key-Escape> "destroy $w"
+ bind $w <Key-Return> "destroy $w"
+ bind_button3 $w.vers "tk_popup $w.ctxm %X %Y; grab $w; focus $w"
+ wm title $w "About [appname]"
+ tkwait window $w
+}
diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl
index 96072847a..00ecf2133 100644
--- a/git-gui/lib/blame.tcl
+++ b/git-gui/lib/blame.tcl
@@ -74,11 +74,11 @@ constructor new {i_commit i_path} {
set path $i_path
make_toplevel top w
- wm title $top "[appname] ([reponame]): File Viewer"
+ wm title $top [append "[appname] ([reponame]): " [mc "File Viewer"]]
frame $w.header -background gold
label $w.header.commit_l \
- -text {Commit:} \
+ -text [mc "Commit:"] \
-background gold \
-anchor w \
-justify left
@@ -101,7 +101,7 @@ constructor new {i_commit i_path} {
-anchor w \
-justify left
label $w.header.path_l \
- -text {File:} \
+ -text [mc "File:"] \
-background gold \
-anchor w \
-justify left
@@ -246,7 +246,7 @@ constructor new {i_commit i_path} {
menu $w.ctxm -tearoff 0
$w.ctxm add command \
- -label "Copy Commit" \
+ -label [mc "Copy Commit"] \
-command [cb _copycommit]
foreach i $w_columns {
@@ -366,7 +366,7 @@ method _load {jump} {
set amov_data [list [list]]
set asim_data [list [list]]
- $status show "Reading $commit:[escape_path $path]..."
+ $status show [mc "Reading %s..." "$commit:[escape_path $path]"]
$w_path conf -text [escape_path $path]
if {$commit eq {}} {
set fd [open $path r]
@@ -470,7 +470,7 @@ method _read_file {fd jump} {
_exec_blame $this $w_asim @asim_data \
[list] \
- { copy/move tracking}
+ [mc "Loading copy/move tracking annotations..."]
}
} ifdeleted { catch {close $fd} }
@@ -489,8 +489,8 @@ method _exec_blame {cur_w cur_d options cur_s} {
set blame_lines 0
$status start \
- "Loading$cur_s annotations..." \
- {lines annotated}
+ $cur_s \
+ [mc "lines annotated"]
}
method _read_blame {fd cur_w cur_d} {
@@ -671,10 +671,10 @@ method _read_blame {fd cur_w cur_d} {
if {$cur_w eq $w_asim} {
_exec_blame $this $w_amov @amov_data \
$original_options \
- { original location}
+ [mc "Loading original location annotations..."]
} else {
set current_fd {}
- $status stop {Annotation complete.}
+ $status stop [mc "Annotation complete."]
}
} else {
$status update $blame_lines $total_lines
@@ -728,7 +728,7 @@ method _showcommit {cur_w lno} {
if {$dat eq {}} {
set cmit {}
- $w_cviewer insert end "Loading annotation..." still_loading
+ $w_cviewer insert end [mc "Loading annotation..."] still_loading
} else {
set cmit [lindex $dat 0]
set file [lindex $dat 1]
@@ -743,20 +743,14 @@ method _showcommit {cur_w lno} {
set author_time {}
catch {set author_name $header($cmit,author)}
catch {set author_email $header($cmit,author-mail)}
- catch {set author_time [clock format \
- $header($cmit,author-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set author_time [format_date $header($cmit,author-time)]}
set committer_name {}
set committer_email {}
set committer_time {}
catch {set committer_name $header($cmit,committer)}
catch {set committer_email $header($cmit,committer-mail)}
- catch {set committer_time [clock format \
- $header($cmit,committer-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set committer_time [format_date $header($cmit,committer-time)]}
if {[catch {set msg $header($cmit,message)}]} {
set msg {}
@@ -790,16 +784,16 @@ method _showcommit {cur_w lno} {
}
$w_cviewer insert end "commit $cmit\n" header_key
- $w_cviewer insert end "Author:\t" header_key
+ $w_cviewer insert end [strcat [mc "Author:"] "\t"] header_key
$w_cviewer insert end "$author_name $author_email" header_val
$w_cviewer insert end " $author_time\n" header_val
- $w_cviewer insert end "Committer:\t" header_key
+ $w_cviewer insert end [strcat [mc "Committer:"] "\t"] header_key
$w_cviewer insert end "$committer_name $committer_email" header_val
$w_cviewer insert end " $committer_time\n" header_val
if {$file ne $path} {
- $w_cviewer insert end "Original File:\t" header_key
+ $w_cviewer insert end [strcat [mc "Original File:"] "\t"] header_key
$w_cviewer insert end "[escape_path $file]\n" header_val
}
@@ -892,10 +886,7 @@ method _open_tooltip {cur_w} {
set author_time {}
catch {set author_name $header($cmit,author)}
catch {set summary $header($cmit,summary)}
- catch {set author_time [clock format \
- $header($cmit,author-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set author_time [format_date $header($cmit,author-time)]}
$tooltip_t insert end "commit $cmit\n"
$tooltip_t insert end "$author_name $author_time\n"
@@ -914,23 +905,20 @@ method _open_tooltip {cur_w} {
set author_time {}
catch {set author_name $header($cmit,author)}
catch {set summary $header($cmit,summary)}
- catch {set author_time [clock format \
- $header($cmit,author-time) \
- -format {%Y-%m-%d %H:%M:%S}
- ]}
+ catch {set author_time [format_date $header($cmit,author-time)]}
- $tooltip_t insert end "Originally By:\n" section_header
+ $tooltip_t insert end [strcat [mc "Originally By:"] "\n"] section_header
$tooltip_t insert end "commit $cmit\n"
$tooltip_t insert end "$author_name $author_time\n"
$tooltip_t insert end "$summary\n"
if {$file ne $path} {
- $tooltip_t insert end "In File: " section_header
+ $tooltip_t insert end [strcat [mc "In File:"] " "] section_header
$tooltip_t insert end "$file\n"
}
$tooltip_t insert end "\n"
- $tooltip_t insert end "Copied Or Moved Here By:\n" section_header
+ $tooltip_t insert end [strcat [mc "Copied Or Moved Here By:"] "\n"] section_header
$tooltip_t insert end $save
}
diff --git a/git-gui/lib/branch_checkout.tcl b/git-gui/lib/branch_checkout.tcl
index 72c45b455..6603703ea 100644
--- a/git-gui/lib/branch_checkout.tcl
+++ b/git-gui/lib/branch_checkout.tcl
@@ -11,37 +11,37 @@ field opt_detach 0; # force a detached head case?
constructor dialog {} {
make_toplevel top w
- wm title $top "[appname] ([reponame]): Checkout Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Checkout Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Checkout Branch} -font font_uibold
+ label $w.header -text [mc "Checkout Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.create -text Checkout \
+ button $w.buttons.create -text [mc Checkout] \
-default active \
-command [cb _checkout]
pack $w.buttons.create -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- set w_rev [::choose_rev::new $w.rev {Revision}]
+ set w_rev [::choose_rev::new $w.rev [mc Revision]]
$w_rev bind_listbox <Double-Button-1> [cb _checkout]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.options -text {Options}
+ labelframe $w.options -text [mc Options]
checkbutton $w.options.fetch \
- -text {Fetch Tracking Branch} \
+ -text [mc "Fetch Tracking Branch"] \
-variable @opt_fetch
pack $w.options.fetch -anchor nw
checkbutton $w.options.detach \
- -text {Detach From Local Branch} \
+ -text [mc "Detach From Local Branch"] \
-variable @opt_detach
pack $w.options.detach -anchor nw
diff --git a/git-gui/lib/branch_create.tcl b/git-gui/lib/branch_create.tcl
index def615d19..53dfb4ce6 100644
--- a/git-gui/lib/branch_create.tcl
+++ b/git-gui/lib/branch_create.tcl
@@ -19,28 +19,28 @@ constructor dialog {} {
global repo_config
make_toplevel top w
- wm title $top "[appname] ([reponame]): Create Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Create Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Create New Branch} -font font_uibold
+ label $w.header -text [mc "Create New Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.create -text Create \
+ button $w.buttons.create -text [mc Create] \
-default active \
-command [cb _create]
pack $w.buttons.create -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.desc -text {Branch Name}
+ labelframe $w.desc -text [mc "Branch Name"]
radiobutton $w.desc.name_r \
-anchor w \
- -text {Name:} \
+ -text [mc "Name:"] \
-value user \
-variable @name_type
set w_name $w.desc.name_t
@@ -55,7 +55,7 @@ constructor dialog {} {
radiobutton $w.desc.match_r \
-anchor w \
- -text {Match Tracking Branch Name} \
+ -text [mc "Match Tracking Branch Name"] \
-value match \
-variable @name_type
grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2
@@ -63,38 +63,38 @@ constructor dialog {} {
grid columnconfigure $w.desc 1 -weight 1
pack $w.desc -anchor nw -fill x -pady 5 -padx 5
- set w_rev [::choose_rev::new $w.rev {Starting Revision}]
+ set w_rev [::choose_rev::new $w.rev [mc "Starting Revision"]]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.options -text {Options}
+ labelframe $w.options -text [mc Options]
frame $w.options.merge
- label $w.options.merge.l -text {Update Existing Branch:}
+ label $w.options.merge.l -text [mc "Update Existing Branch:"]
pack $w.options.merge.l -side left
radiobutton $w.options.merge.no \
- -text No \
+ -text [mc No] \
-value none \
-variable @opt_merge
pack $w.options.merge.no -side left
radiobutton $w.options.merge.ff \
- -text {Fast Forward Only} \
+ -text [mc "Fast Forward Only"] \
-value ff \
-variable @opt_merge
pack $w.options.merge.ff -side left
radiobutton $w.options.merge.reset \
- -text {Reset} \
+ -text [mc Reset] \
-value reset \
-variable @opt_merge
pack $w.options.merge.reset -side left
pack $w.options.merge -anchor nw
checkbutton $w.options.fetch \
- -text {Fetch Tracking Branch} \
+ -text [mc "Fetch Tracking Branch"] \
-variable @opt_fetch
pack $w.options.fetch -anchor nw
checkbutton $w.options.checkout \
- -text {Checkout After Creation} \
+ -text [mc "Checkout After Creation"] \
-variable @opt_checkout
pack $w.options.checkout -anchor nw
pack $w.options -anchor nw -fill x -pady 5 -padx 5
@@ -128,7 +128,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please select a tracking branch."
+ -message [mc "Please select a tracking branch."]
return
}
if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
@@ -137,7 +137,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Tracking branch [$w get] is not a branch in the remote repository."
+ -message [mc "Tracking branch %s is not a branch in the remote repository." [$w get]]
return
}
}
@@ -150,7 +150,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please supply a branch name."
+ -message [mc "Please supply a branch name."]
focus $w_name
return
}
@@ -161,7 +161,7 @@ method _create {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "'$newbranch' is not an acceptable branch name."
+ -message [mc "'%s' is not an acceptable branch name." $newbranch]
focus $w_name
return
}
diff --git a/git-gui/lib/branch_delete.tcl b/git-gui/lib/branch_delete.tcl
index c7573c6c7..86c4f7337 100644
--- a/git-gui/lib/branch_delete.tcl
+++ b/git-gui/lib/branch_delete.tcl
@@ -12,29 +12,29 @@ constructor dialog {} {
global current_branch
make_toplevel top w
- wm title $top "[appname] ([reponame]): Delete Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Delete Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Delete Local Branch} -font font_uibold
+ label $w.header -text [mc "Delete Local Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
set w_delete $w.buttons.delete
button $w_delete \
- -text Delete \
+ -text [mc Delete] \
-default active \
-state disabled \
-command [cb _delete]
pack $w_delete -side right
button $w.buttons.cancel \
- -text {Cancel} \
+ -text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.list -text {Local Branches}
+ labelframe $w.list -text [mc "Local Branches"]
set w_heads $w.list.l
listbox $w_heads \
-height 10 \
@@ -49,9 +49,9 @@ constructor dialog {} {
set w_check [choose_rev::new \
$w.check \
- {Delete Only If Merged Into} \
+ [mc "Delete Only If Merged Into"] \
]
- $w_check none {Always (Do not perform merge test.)}
+ $w_check none [mc "Always (Do not perform merge test.)"]
pack $w.check -anchor nw -fill x -pady 5 -padx 5
foreach h [load_all_heads] {
@@ -100,7 +100,7 @@ method _delete {} {
lappend to_delete [list $b $o]
}
if {$not_merged ne {}} {
- set msg "The following branches are not completely merged into [$w_check get]:
+ set msg "[mc "The following branches are not completely merged into %s:" [$w_check get]]
- [join $not_merged "\n - "]"
tk_messageBox \
@@ -112,9 +112,7 @@ method _delete {} {
}
if {$to_delete eq {}} return
if {$check_cmt eq {}} {
- set msg {Recovering deleted branches is difficult.
-
-Delete the selected branches?}
+ set msg [mc "Recovering deleted branches is difficult. \n\n Delete the selected branches?"]
if {[tk_messageBox \
-icon warning \
-type yesno \
@@ -140,7 +138,7 @@ Delete the selected branches?}
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Failed to delete branches:\n$failed"
+ -message [mc "Failed to delete branches:\n%s" $failed]
}
destroy $w
diff --git a/git-gui/lib/branch_rename.tcl b/git-gui/lib/branch_rename.tcl
index 1cadc31d2..166538808 100644
--- a/git-gui/lib/branch_rename.tcl
+++ b/git-gui/lib/branch_rename.tcl
@@ -11,7 +11,7 @@ constructor dialog {} {
global current_branch
make_toplevel top w
- wm title $top "[appname] ([reponame]): Rename Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Rename Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
@@ -19,24 +19,24 @@ constructor dialog {} {
set oldname $current_branch
set newname [get_config gui.newbranchtemplate]
- label $w.header -text {Rename Branch} -font font_uibold
+ label $w.header -text [mc "Rename Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.rename -text Rename \
+ button $w.buttons.rename -text [mc Rename] \
-default active \
-command [cb _rename]
pack $w.buttons.rename -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
frame $w.rename
- label $w.rename.oldname_l -text {Branch:}
+ label $w.rename.oldname_l -text [mc "Branch:"]
eval tk_optionMenu $w.rename.oldname_m @oldname [load_all_heads]
- label $w.rename.newname_l -text {New Name:}
+ label $w.rename.newname_l -text [mc "New Name:"]
entry $w.rename.newname_t \
-borderwidth 1 \
-relief sunken \
@@ -72,7 +72,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please select a branch to rename."
+ -message [mc "Please select a branch to rename."]
focus $w.rename.oldname_m
return
}
@@ -83,7 +83,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please supply a branch name."
+ -message [mc "Please supply a branch name."]
focus $w.rename.newname_t
return
}
@@ -93,7 +93,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Branch '$newname' already exists."
+ -message [mc "Branch '%s' already exists." $newname]
focus $w.rename.newname_t
return
}
@@ -103,7 +103,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "We do not like '$newname' as a branch name."
+ -message [mc "'%s' is not an acceptable branch name." $newname]
focus $w.rename.newname_t
return
}
@@ -114,7 +114,7 @@ method _rename {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Failed to rename '$oldname'.\n\n$err"
+ -message [strcat [mc "Failed to rename '%s'." $oldname] "\n\n$err"]
return
}
diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl
index 31349009a..53d5a6281 100644
--- a/git-gui/lib/browser.tcl
+++ b/git-gui/lib/browser.tcl
@@ -14,7 +14,7 @@ field w
field browser_commit
field browser_path
field browser_files {}
-field browser_status {Starting...}
+field browser_status [mc "Starting..."]
field browser_stack {}
field browser_busy 1
@@ -23,7 +23,7 @@ field ls_buf {}; # Buffered record output from ls-tree
constructor new {commit {path {}}} {
global cursor_ptr M1B
make_toplevel top w
- wm title $top "[appname] ([reponame]): File Browser"
+ wm title $top [append "[appname] ([reponame]): " [mc "File Browser"]]
set browser_commit $commit
set browser_path $browser_commit:$path
@@ -122,7 +122,7 @@ method _parent {} {
} else {
regsub {/[^/]+$} $browser_path {} browser_path
}
- set browser_status "Loading $browser_path..."
+ set browser_status [mc "Loading %s..." $browser_path]
_ls $this [lindex $parent 0] [lindex $parent 1]
}
}
@@ -139,7 +139,7 @@ method _enter {} {
tree {
set name [lindex $info 2]
set escn [escape_path $name]
- set browser_status "Loading $escn..."
+ set browser_status [mc "Loading %s..." $escn]
append browser_path $escn
_ls $this [lindex $info 1] $name
}
@@ -183,7 +183,7 @@ method _ls {tree_id {name {}}} {
-align center -padx 5 -pady 1 \
-name icon0 \
-image ::browser::img_parent
- $w insert end {[Up To Parent]}
+ $w insert end [mc "\[Up To Parent\]"]
lappend browser_files parent
}
lappend browser_stack [list $tree_id $name]
@@ -242,7 +242,7 @@ method _read {fd} {
if {[eof $fd]} {
close $fd
- set browser_status Ready.
+ set browser_status [mc "Ready."]
set browser_busy 0
set ls_buf {}
if {$n > 0} {
@@ -263,27 +263,27 @@ field w_rev ; # mega-widget to pick the initial revision
constructor dialog {} {
make_toplevel top w
- wm title $top "[appname] ([reponame]): Browse Branch Files"
+ wm title $top [append "[appname] ([reponame]): " [mc "Browse Branch Files"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
label $w.header \
- -text {Browse Branch Files} \
+ -text [mc "Browse Branch Files"] \
-font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.browse -text Browse \
+ button $w.buttons.browse -text [mc Browse] \
-default active \
-command [cb _open]
pack $w.buttons.browse -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- set w_rev [::choose_rev::new $w.rev {Revision}]
+ set w_rev [::choose_rev::new $w.rev [mc Revision]]
$w_rev bind_listbox <Double-Button-1> [cb _open]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
diff --git a/git-gui/lib/checkout_op.tcl b/git-gui/lib/checkout_op.tcl
index 76f04f285..f24396692 100644
--- a/git-gui/lib/checkout_op.tcl
+++ b/git-gui/lib/checkout_op.tcl
@@ -76,7 +76,7 @@ method run {} {
_toplevel $this {Refreshing Tracking Branch}
set w_cons [::console::embed \
$w.console \
- "Fetching $r_name from $remote"]
+ [mc "Fetching %s from %s" $r_name $remote]]
pack $w.console -fill both -expand 1
$w_cons exec $cmd [cb _finish_fetch]
@@ -124,7 +124,7 @@ method _finish_fetch {ok} {
}
if {[catch {set new_hash [git rev-parse --verify "$l_trck^0"]} err]} {
set ok 0
- $w_cons insert "fatal: Cannot resolve $l_trck"
+ $w_cons insert [mc "fatal: Cannot resolve %s" $l_trck]
$w_cons insert $err
}
}
@@ -137,7 +137,7 @@ method _finish_fetch {ok} {
destroy $w
set w {}
} else {
- button $w.close -text Close -command [list destroy $w]
+ button $w.close -text [mc Close] -command [list destroy $w]
pack $w.close -side bottom -anchor e -padx 10 -pady 10
}
@@ -166,7 +166,7 @@ method _update_ref {} {
# Assume it does not exist, and that is what the error was.
#
if {!$create} {
- _error $this "Branch '$newbranch' does not exist."
+ _error $this [mc "Branch '%s' does not exist." $newbranch]
return 0
}
@@ -176,7 +176,7 @@ method _update_ref {} {
# We were told to create it, but not do a merge.
# Bad. Name shouldn't have existed.
#
- _error $this "Branch '$newbranch' already exists."
+ _error $this [mc "Branch '%s' already exists." $newbranch]
return 0
} elseif {!$create && $merge_type eq {none}} {
# We aren't creating, it exists and we don't merge.
@@ -203,7 +203,7 @@ method _update_ref {} {
set new $cur
set new_hash $cur
} else {
- _error $this "Branch '$newbranch' already exists.\n\nIt cannot fast-forward to $new_expr.\nA merge is required."
+ _error $this [mc "Branch '%s' already exists.\n\nIt cannot fast-forward to %s.\nA merge is required." $newbranch $new_expr]
return 0
}
}
@@ -217,7 +217,7 @@ method _update_ref {} {
}
}
default {
- _error $this "Merge strategy '$merge_type' not supported."
+ _error $this [mc "Merge strategy '%s' not supported." $merge_type]
return 0
}
}
@@ -236,7 +236,7 @@ method _update_ref {} {
if {[catch {
git update-ref -m $reflog_msg $ref $new $cur
} err]} {
- _error $this "Failed to update '$newbranch'.\n\n$err"
+ _error $this [strcat [mc "Failed to update '%s'." $newbranch] "\n\n$err"]
return 0
}
}
@@ -248,7 +248,7 @@ method _checkout {} {
if {[lock_index checkout_op]} {
after idle [cb _start_checkout]
} else {
- _error $this "Staging area (index) is already locked."
+ _error $this [mc "Staging area (index) is already locked."]
delete_this
}
}
@@ -263,12 +263,12 @@ method _start_checkout {} {
&& $curType eq {normal}
&& $curHEAD eq $HEAD} {
} elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
- info_popup {Last scanned state does not match repository state.
+ info_popup [mc "Last scanned state does not match repository state.
Another Git program has modified this repository since the last scan. A rescan must be performed before the current branch can be changed.
The rescan will be automatically started now.
-}
+"]
unlock_index
rescan ui_ready
delete_this
@@ -319,7 +319,7 @@ method _readtree {} {
set readtree_d {}
$::main_status start \
- "Updating working directory to '[_name $this]'..." \
+ [mc "Updating working directory to '%s'..." [_name $this]] \
{files checked out}
set fd [git_read --stderr read-tree \
@@ -350,12 +350,12 @@ method _readtree_wait {fd} {
if {[catch {close $fd}]} {
set err $readtree_d
regsub {^fatal: } $err {} err
- $::main_status stop "Aborted checkout of '[_name $this]' (file level merging is required)."
- warn_popup "File level merge required.
+ $::main_status stop [mc "Aborted checkout of '%s' (file level merging is required)." [_name $this]]
+ warn_popup [strcat [mc "File level merge required."] "
$err
-Staying on branch '$current_branch'."
+" [mc "Staying on branch '%s'." $current_branch]]
unlock_index
delete_this
return
@@ -426,9 +426,9 @@ method _after_readtree {} {
}
if {$is_detached} {
- info_popup "You are no longer on a local branch.
+ info_popup [mc "You are no longer on a local branch.
-If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."
+If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."]
}
# -- Update our repository state. If we were previously in
@@ -443,7 +443,7 @@ If you wanted to be on a branch, create one now starting from 'This Detached Che
$ui_comm delete 0.0 end
$ui_comm edit reset
$ui_comm edit modified false
- rescan [list ui_status "Checked out '$name'."]
+ rescan [list ui_status [mc "Checked out '%s'." $name]]
} else {
repository_state commit_type HEAD MERGE_HEAD
set PARENT $HEAD
@@ -475,7 +475,7 @@ method _confirm_reset {cur} {
pack [label $w.msg1 \
-anchor w \
-justify left \
- -text "Resetting '$name' to $new_expr will lose the following commits:" \
+ -text [mc "Resetting '%s' to '%s' will lose the following commits:" $name $new_expr]\
] -anchor w
set list $w.list.l
@@ -497,21 +497,21 @@ method _confirm_reset {cur} {
pack [label $w.msg2 \
-anchor w \
-justify left \
- -text {Recovering lost commits may not be easy.} \
+ -text [mc "Recovering lost commits may not be easy."] \
]
pack [label $w.msg3 \
-anchor w \
-justify left \
- -text "Reset '$name'?" \
+ -text [mc "Reset '%s'?" $name] \
]
frame $w.buttons
button $w.buttons.visualize \
- -text Visualize \
+ -text [mc Visualize] \
-command $gitk
pack $w.buttons.visualize -side left
button $w.buttons.reset \
- -text Reset \
+ -text [mc Reset] \
-command "
set @reset_ok 1
destroy $w
@@ -519,7 +519,7 @@ method _confirm_reset {cur} {
pack $w.buttons.reset -side right
button $w.buttons.cancel \
-default active \
- -text Cancel \
+ -text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
@@ -575,13 +575,13 @@ method _toplevel {title} {
}
method _fatal {err} {
- error_popup "Failed to set current branch.
+ error_popup [strcat [mc "Failed to set current branch.
This working directory is only partially switched. We successfully updated your files, but failed to update an internal Git file.
-This should not have occurred. [appname] will now close and give up.
+This should not have occurred. %s will now close and give up." [appname]] "
-$err"
+$err"]
exit 1
}
diff --git a/git-gui/lib/choose_repository.tcl b/git-gui/lib/choose_repository.tcl
new file mode 100644
index 000000000..2bac50e14
--- /dev/null
+++ b/git-gui/lib/choose_repository.tcl
@@ -0,0 +1,1044 @@
+# git-gui Git repository chooser
+# Copyright (C) 2007 Shawn Pearce
+
+class choose_repository {
+
+field top
+field w
+field w_body ; # Widget holding the center content
+field w_next ; # Next button
+field w_quit ; # Quit button
+field o_cons ; # Console object (if active)
+field w_types ; # List of type buttons in clone
+field w_recentlist ; # Listbox containing recent repositories
+
+field done 0 ; # Finished picking the repository?
+field local_path {} ; # Where this repository is locally
+field origin_url {} ; # Where we are cloning from
+field origin_name origin ; # What we shall call 'origin'
+field clone_type hardlink ; # Type of clone to construct
+field readtree_err ; # Error output from read-tree (if any)
+field sorted_recent ; # recent repositories (sorted)
+
+constructor pick {} {
+ global M1T M1B
+
+ make_toplevel top w
+ wm title $top [mc "Git Gui"]
+
+ if {$top eq {.}} {
+ menu $w.mbar -tearoff 0
+ $top configure -menu $w.mbar
+
+ set m_repo $w.mbar.repository
+ $w.mbar add cascade \
+ -label [mc Repository] \
+ -menu $m_repo
+ menu $m_repo
+
+ if {[is_MacOSX]} {
+ $w.mbar add cascade -label [mc Apple] -menu .mbar.apple
+ menu $w.mbar.apple
+ $w.mbar.apple add command \
+ -label [mc "About %s" [appname]] \
+ -command do_about
+ } else {
+ $w.mbar add cascade -label [mc Help] -menu $w.mbar.help
+ menu $w.mbar.help
+ $w.mbar.help add command \
+ -label [mc "About %s" [appname]] \
+ -command do_about
+ }
+
+ wm protocol $top WM_DELETE_WINDOW exit
+ bind $top <$M1B-q> exit
+ bind $top <$M1B-Q> exit
+ bind $top <Key-Escape> exit
+ } else {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ bind $top <Key-Escape> [list destroy $top]
+ set m_repo {}
+ }
+
+ pack [git_logo $w.git_logo] -side left -fill y -padx 10 -pady 10
+
+ set w_body $w.body
+ set opts $w_body.options
+ frame $w_body
+ text $opts \
+ -cursor $::cursor_ptr \
+ -relief flat \
+ -background [$w_body cget -background] \
+ -wrap none \
+ -spacing1 5 \
+ -width 50 \
+ -height 3
+ pack $opts -anchor w -fill x
+
+ $opts tag conf link_new -foreground blue -underline 1
+ $opts tag bind link_new <1> [cb _next new]
+ $opts insert end [mc "Create New Repository"] link_new
+ $opts insert end "\n"
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _next new] \
+ -accelerator $M1T-N \
+ -label [mc "New..."]
+ bind $top <$M1B-n> [cb _next new]
+ bind $top <$M1B-N> [cb _next new]
+ }
+
+ $opts tag conf link_clone -foreground blue -underline 1
+ $opts tag bind link_clone <1> [cb _next clone]
+ $opts insert end [mc "Clone Existing Repository"] link_clone
+ $opts insert end "\n"
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _next clone] \
+ -accelerator $M1T-C \
+ -label [mc "Clone..."]
+ bind $top <$M1B-c> [cb _next clone]
+ bind $top <$M1B-C> [cb _next clone]
+ }
+
+ $opts tag conf link_open -foreground blue -underline 1
+ $opts tag bind link_open <1> [cb _next open]
+ $opts insert end [mc "Open Existing Repository"] link_open
+ $opts insert end "\n"
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _next open] \
+ -accelerator $M1T-O \
+ -label [mc "Open..."]
+ bind $top <$M1B-o> [cb _next open]
+ bind $top <$M1B-O> [cb _next open]
+ }
+
+ $opts conf -state disabled
+
+ set sorted_recent [_get_recentrepos]
+ if {[llength $sorted_recent] > 0} {
+ if {$m_repo ne {}} {
+ $m_repo add separator
+ $m_repo add command \
+ -state disabled \
+ -label [mc "Recent Repositories"]
+ }
+
+ label $w_body.space
+ label $w_body.recentlabel \
+ -anchor w \
+ -text [mc "Open Recent Repository:"]
+ set w_recentlist $w_body.recentlist
+ text $w_recentlist \
+ -cursor $::cursor_ptr \
+ -relief flat \
+ -background [$w_body.recentlabel cget -background] \
+ -wrap none \
+ -width 50 \
+ -height 10
+ $w_recentlist tag conf link \
+ -foreground blue \
+ -underline 1
+ set home $::env(HOME)
+ if {[is_Cygwin]} {
+ set home [exec cygpath --windows --absolute $home]
+ }
+ set home "[file normalize $home]/"
+ set hlen [string length $home]
+ foreach p $sorted_recent {
+ set path $p
+ if {[string equal -length $hlen $home $p]} {
+ set p "~/[string range $p $hlen end]"
+ }
+ regsub -all "\n" $p "\\n" p
+ $w_recentlist insert end $p link
+ $w_recentlist insert end "\n"
+
+ if {$m_repo ne {}} {
+ $m_repo add command \
+ -command [cb _open_recent_path $path] \
+ -label " $p"
+ }
+ }
+ $w_recentlist conf -state disabled
+ $w_recentlist tag bind link <1> [cb _open_recent %x,%y]
+ pack $w_body.space -anchor w -fill x
+ pack $w_body.recentlabel -anchor w -fill x
+ pack $w_recentlist -anchor w -fill x
+ }
+ pack $w_body -fill x -padx 10 -pady 10
+
+ frame $w.buttons
+ set w_next $w.buttons.next
+ set w_quit $w.buttons.quit
+ button $w_quit \
+ -text [mc "Quit"] \
+ -command exit
+ pack $w_quit -side right -padx 5
+ pack $w.buttons -side bottom -fill x -padx 10 -pady 10
+
+ if {$m_repo ne {}} {
+ $m_repo add separator
+ $m_repo add command \
+ -label [mc Quit] \
+ -command exit \
+ -accelerator $M1T-Q
+ }
+
+ bind $top <Return> [cb _invoke_next]
+ bind $top <Visibility> "
+ [cb _center]
+ grab $top
+ focus $top
+ bind $top <Visibility> {}
+ "
+ wm deiconify $top
+ tkwait variable @done
+
+ if {$top eq {.}} {
+ eval destroy [winfo children $top]
+ }
+}
+
+proc _home {} {
+ if {[catch {set h $::env(HOME)}]
+ || ![file isdirectory $h]} {
+ set h .
+ }
+ return $h
+}
+
+method _center {} {
+ set nx [winfo reqwidth $top]
+ set ny [winfo reqheight $top]
+ set rx [expr {([winfo screenwidth $top] - $nx) / 3}]
+ set ry [expr {([winfo screenheight $top] - $ny) / 3}]
+ wm geometry $top [format {+%d+%d} $rx $ry]
+}
+
+method _invoke_next {} {
+ if {[winfo exists $w_next]} {
+ uplevel #0 [$w_next cget -command]
+ }
+}
+
+proc _get_recentrepos {} {
+ set recent [list]
+ foreach p [get_config gui.recentrepo] {
+ if {[_is_git [file join $p .git]]} {
+ lappend recent $p
+ }
+ }
+ return [lsort $recent]
+}
+
+proc _unset_recentrepo {p} {
+ regsub -all -- {([()\[\]{}\.^$+*?\\])} $p {\\\1} p
+ git config --global --unset gui.recentrepo "^$p\$"
+}
+
+proc _append_recentrepos {path} {
+ set path [file normalize $path]
+ set recent [get_config gui.recentrepo]
+
+ if {[lindex $recent end] eq $path} {
+ return
+ }
+
+ set i [lsearch $recent $path]
+ if {$i >= 0} {
+ _unset_recentrepo $path
+ set recent [lreplace $recent $i $i]
+ }
+
+ lappend recent $path
+ git config --global --add gui.recentrepo $path
+
+ while {[llength $recent] > 10} {
+ _unset_recentrepo [lindex $recent 0]
+ set recent [lrange $recent 1 end]
+ }
+}
+
+method _open_recent {xy} {
+ set id [lindex [split [$w_recentlist index @$xy] .] 0]
+ set local_path [lindex $sorted_recent [expr {$id - 1}]]
+ _do_open2 $this
+}
+
+method _open_recent_path {p} {
+ set local_path $p
+ _do_open2 $this
+}
+
+method _next {action} {
+ destroy $w_body
+ if {![winfo exists $w_next]} {
+ button $w_next -default active
+ pack $w_next -side right -padx 5 -before $w_quit
+ }
+ _do_$action $this
+}
+
+method _write_local_path {args} {
+ if {$local_path eq {}} {
+ $w_next conf -state disabled
+ } else {
+ $w_next conf -state normal
+ }
+}
+
+method _git_init {} {
+ if {[file exists $local_path]} {
+ error_popup [mc "Location %s already exists." $local_path]
+ return 0
+ }
+
+ if {[catch {file mkdir $local_path} err]} {
+ error_popup [strcat \
+ [mc "Failed to create repository %s:" $local_path] \
+ "\n\n$err"]
+ return 0
+ }
+
+ if {[catch {cd $local_path} err]} {
+ error_popup [strcat \
+ [mc "Failed to create repository %s:" $local_path] \
+ "\n\n$err"]
+ return 0
+ }
+
+ if {[catch {git init} err]} {
+ error_popup [strcat \
+ [mc "Failed to create repository %s:" $local_path] \
+ "\n\n$err"]
+ return 0
+ }
+
+ _append_recentrepos [pwd]
+ set ::_gitdir .git
+ set ::_prefix {}
+ return 1
+}
+
+proc _is_git {path} {
+ if {[file exists [file join $path HEAD]]
+ && [file exists [file join $path objects]]
+ && [file exists [file join $path config]]} {
+ return 1
+ }
+ if {[is_Cygwin]} {
+ if {[file exists [file join $path HEAD]]
+ && [file exists [file join $path objects.lnk]]
+ && [file exists [file join $path config.lnk]]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc _objdir {path} {
+ set objdir [file join $path .git objects]
+ if {[file isdirectory $objdir]} {
+ return $objdir
+ }
+
+ set objdir [file join $path objects]
+ if {[file isdirectory $objdir]} {
+ return $objdir
+ }
+
+ if {[is_Cygwin]} {
+ set objdir [file join $path .git objects.lnk]
+ if {[file isfile $objdir]} {
+ return [win32_read_lnk $objdir]
+ }
+
+ set objdir [file join $path objects.lnk]
+ if {[file isfile $objdir]} {
+ return [win32_read_lnk $objdir]
+ }
+ }
+
+ return {}
+}
+
+######################################################################
+##
+## Create New Repository
+
+method _do_new {} {
+ $w_next conf \
+ -state disabled \
+ -command [cb _do_new2] \
+ -text [mc "Create"]
+
+ frame $w_body
+ label $w_body.h \
+ -font font_uibold \
+ -text [mc "Create New Repository"]
+ pack $w_body.h -side top -fill x -pady 10
+ pack $w_body -fill x -padx 10
+
+ frame $w_body.where
+ label $w_body.where.l -text [mc "Directory:"]
+ entry $w_body.where.t \
+ -textvariable @local_path \
+ -font font_diff \
+ -width 50
+ button $w_body.where.b \
+ -text [mc "Browse"] \
+ -command [cb _new_local_path]
+
+ pack $w_body.where.b -side right
+ pack $w_body.where.l -side left
+ pack $w_body.where.t -fill x
+ pack $w_body.where -fill x
+
+ trace add variable @local_path write [cb _write_local_path]
+ bind $w_body.h <Destroy> [list trace remove variable @local_path write [cb _write_local_path]]
+ update
+ focus $w_body.where.t
+}
+
+method _new_local_path {} {
+ if {$local_path ne {}} {
+ set p [file dirname $local_path]
+ } else {
+ set p [_home]
+ }
+
+ set p [tk_chooseDirectory \
+ -initialdir $p \
+ -parent $top \
+ -title [mc "Git Repository"] \
+ -mustexist false]
+ if {$p eq {}} return
+
+ set p [file normalize $p]
+ if {[file isdirectory $p]} {
+ foreach i [glob \
+ -directory $p \
+ -tails \
+ -nocomplain \
+ * .*] {
+ switch -- $i {
+ . continue
+ .. continue
+ default {
+ error_popup [mc "Directory %s already exists." $p]
+ return
+ }
+ }
+ }
+ if {[catch {file delete $p} err]} {
+ error_popup [strcat \
+ [mc "Directory %s already exists." $p] \
+ "\n\n$err"]
+ return
+ }
+ } elseif {[file exists $p]} {
+ error_popup [mc "File %s already exists." $p]
+ return
+ }
+ set local_path $p
+}
+
+method _do_new2 {} {
+ if {![_git_init $this]} {
+ return
+ }
+ set done 1
+}
+
+######################################################################
+##
+## Clone Existing Repository
+
+method _do_clone {} {
+ $w_next conf \
+ -state disabled \
+ -command [cb _do_clone2] \
+ -text [mc "Clone"]
+
+ frame $w_body
+ label $w_body.h \
+ -font font_uibold \
+ -text [mc "Clone Existing Repository"]
+ pack $w_body.h -side top -fill x -pady 10
+ pack $w_body -fill x -padx 10
+
+ set args $w_body.args
+ frame $w_body.args
+ pack $args -fill both
+
+ label $args.origin_l -text [mc "URL:"]
+ entry $args.origin_t \
+ -textvariable @origin_url \
+ -font font_diff \
+ -width 50
+ button $args.origin_b \
+ -text [mc "Browse"] \
+ -command [cb _open_origin]
+ grid $args.origin_l $args.origin_t $args.origin_b -sticky ew
+
+ label $args.where_l -text [mc "Directory:"]
+ entry $args.where_t \
+ -textvariable @local_path \
+ -font font_diff \
+ -width 50
+ button $args.where_b \
+ -text [mc "Browse"] \
+ -command [cb _new_local_path]
+ grid $args.where_l $args.where_t $args.where_b -sticky ew
+
+ label $args.type_l -text [mc "Clone Type:"]
+ frame $args.type_f
+ set w_types [list]
+ lappend w_types [radiobutton $args.type_f.hardlink \
+ -state disabled \
+ -anchor w \
+ -text [mc "Standard (Fast, Semi-Redundant, Hardlinks)"] \
+ -variable @clone_type \
+ -value hardlink]
+ lappend w_types [radiobutton $args.type_f.full \
+ -state disabled \
+ -anchor w \
+ -text [mc "Full Copy (Slower, Redundant Backup)"] \
+ -variable @clone_type \
+ -value full]
+ lappend w_types [radiobutton $args.type_f.shared \
+ -state disabled \
+ -anchor w \
+ -text [mc "Shared (Fastest, Not Recommended, No Backup)"] \
+ -variable @clone_type \
+ -value shared]
+ foreach r $w_types {
+ pack $r -anchor w
+ }
+ grid $args.type_l $args.type_f -sticky new
+
+ grid columnconfigure $args 1 -weight 1
+
+ trace add variable @local_path write [cb _update_clone]
+ trace add variable @origin_url write [cb _update_clone]
+ bind $w_body.h <Destroy> "
+ [list trace remove variable @local_path write [cb _update_clone]]
+ [list trace remove variable @origin_url write [cb _update_clone]]
+ "
+ update
+ focus $args.origin_t
+}
+
+method _open_origin {} {
+ if {$origin_url ne {} && [file isdirectory $origin_url]} {
+ set p $origin_url
+ } else {
+ set p [_home]
+ }
+
+ set p [tk_chooseDirectory \
+ -initialdir $p \
+ -parent $top \
+ -title [mc "Git Repository"] \
+ -mustexist true]
+ if {$p eq {}} return
+
+ set p [file normalize $p]
+ if {![_is_git [file join $p .git]] && ![_is_git $p]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $p]]
+ return
+ }
+ set origin_url $p
+}
+
+method _update_clone {args} {
+ if {$local_path ne {} && $origin_url ne {}} {
+ $w_next conf -state normal
+ } else {
+ $w_next conf -state disabled
+ }
+
+ if {$origin_url ne {} &&
+ ( [_is_git [file join $origin_url .git]]
+ || [_is_git $origin_url])} {
+ set e normal
+ if {[[lindex $w_types 0] cget -state] eq {disabled}} {
+ set clone_type hardlink
+ }
+ } else {
+ set e disabled
+ set clone_type full
+ }
+
+ foreach r $w_types {
+ $r conf -state $e
+ }
+}
+
+method _do_clone2 {} {
+ if {[file isdirectory $origin_url]} {
+ set origin_url [file normalize $origin_url]
+ }
+
+ if {$clone_type eq {hardlink} && ![file isdirectory $origin_url]} {
+ error_popup [mc "Standard only available for local repository."]
+ return
+ }
+ if {$clone_type eq {shared} && ![file isdirectory $origin_url]} {
+ error_popup [mc "Shared only available for local repository."]
+ return
+ }
+
+ if {$clone_type eq {hardlink} || $clone_type eq {shared}} {
+ set objdir [_objdir $origin_url]
+ if {$objdir eq {}} {
+ error_popup [mc "Not a Git repository: %s" [file tail $origin_url]]
+ return
+ }
+ }
+
+ set giturl $origin_url
+ if {[is_Cygwin] && [file isdirectory $giturl]} {
+ set giturl [exec cygpath --unix --absolute $giturl]
+ if {$clone_type eq {shared}} {
+ set objdir [exec cygpath --unix --absolute $objdir]
+ }
+ }
+
+ if {![_git_init $this]} return
+ set local_path [pwd]
+
+ if {[catch {
+ git config remote.$origin_name.url $giturl
+ git config remote.$origin_name.fetch +refs/heads/*:refs/remotes/$origin_name/*
+ } err]} {
+ error_popup [strcat [mc "Failed to configure origin"] "\n\n$err"]
+ return
+ }
+
+ destroy $w_body $w_next
+
+ switch -exact -- $clone_type {
+ hardlink {
+ set o_cons [status_bar::two_line $w_body]
+ pack $w_body -fill x -padx 10 -pady 10
+
+ $o_cons start \
+ [mc "Counting objects"] \
+ [mc "buckets"]
+ update
+
+ if {[file exists [file join $objdir info alternates]]} {
+ set pwd [pwd]
+ if {[catch {
+ file mkdir [gitdir objects info]
+ set f_in [open [file join $objdir info alternates] r]
+ set f_cp [open [gitdir objects info alternates] w]
+ fconfigure $f_in -translation binary -encoding binary
+ fconfigure $f_cp -translation binary -encoding binary
+ cd $objdir
+ while {[gets $f_in line] >= 0} {
+ if {[is_Cygwin]} {
+ puts $f_cp [exec cygpath --unix --absolute $line]
+ } else {
+ puts $f_cp [file normalize $line]
+ }
+ }
+ close $f_in
+ close $f_cp
+ cd $pwd
+ } err]} {
+ catch {cd $pwd}
+ _clone_failed $this [mc "Unable to copy objects/info/alternates: %s" $err]
+ return
+ }
+ }
+
+ set tolink [list]
+ set buckets [glob \
+ -tails \
+ -nocomplain \
+ -directory [file join $objdir] ??]
+ set bcnt [expr {[llength $buckets] + 2}]
+ set bcur 1
+ $o_cons update $bcur $bcnt
+ update
+
+ file mkdir [file join .git objects pack]
+ foreach i [glob -tails -nocomplain \
+ -directory [file join $objdir pack] *] {
+ lappend tolink [file join pack $i]
+ }
+ $o_cons update [incr bcur] $bcnt
+ update
+
+ foreach i $buckets {
+ file mkdir [file join .git objects $i]
+ foreach j [glob -tails -nocomplain \
+ -directory [file join $objdir $i] *] {
+ lappend tolink [file join $i $j]
+ }
+ $o_cons update [incr bcur] $bcnt
+ update
+ }
+ $o_cons stop
+
+ if {$tolink eq {}} {
+ info_popup [strcat \
+ [mc "Nothing to clone from %s." $origin_url] \
+ "\n" \
+ [mc "The 'master' branch has not been initialized."] \
+ ]
+ destroy $w_body
+ set done 1
+ return
+ }
+
+ set i [lindex $tolink 0]
+ if {[catch {
+ file link -hard \
+ [file join .git objects $i] \
+ [file join $objdir $i]
+ } err]} {
+ info_popup [mc "Hardlinks are unavailable. Falling back to copying."]
+ set i [_copy_files $this $objdir $tolink]
+ } else {
+ set i [_link_files $this $objdir [lrange $tolink 1 end]]
+ }
+ if {!$i} return
+
+ destroy $w_body
+ }
+ full {
+ set o_cons [console::embed \
+ $w_body \
+ [mc "Cloning from %s" $origin_url]]
+ pack $w_body -fill both -expand 1 -padx 10
+ $o_cons exec \
+ [list git fetch --no-tags -k $origin_name] \
+ [cb _do_clone_tags]
+ }
+ shared {
+ set fd [open [gitdir objects info alternates] w]
+ fconfigure $fd -translation binary
+ puts $fd $objdir
+ close $fd
+ }
+ }
+
+ if {$clone_type eq {hardlink} || $clone_type eq {shared}} {
+ if {![_clone_refs $this]} return
+ set pwd [pwd]
+ if {[catch {
+ cd $origin_url
+ set HEAD [git rev-parse --verify HEAD^0]
+ } err]} {
+ _clone_failed $this [mc "Not a Git repository: %s" [file tail $origin_url]]
+ return 0
+ }
+ cd $pwd
+ _do_clone_checkout $this $HEAD
+ }
+}
+
+method _copy_files {objdir tocopy} {
+ $o_cons start \
+ [mc "Copying objects"] \
+ [mc "KiB"]
+ set tot 0
+ set cmp 0
+ foreach p $tocopy {
+ incr tot [file size [file join $objdir $p]]
+ }
+ foreach p $tocopy {
+ if {[catch {
+ set f_in [open [file join $objdir $p] r]
+ set f_cp [open [file join .git objects $p] w]
+ fconfigure $f_in -translation binary -encoding binary
+ fconfigure $f_cp -translation binary -encoding binary
+
+ while {![eof $f_in]} {
+ incr cmp [fcopy $f_in $f_cp -size 16384]
+ $o_cons update \
+ [expr {$cmp / 1024}] \
+ [expr {$tot / 1024}]
+ update
+ }
+
+ close $f_in
+ close $f_cp
+ } err]} {
+ _clone_failed $this [mc "Unable to copy object: %s" $err]
+ return 0
+ }
+ }
+ return 1
+}
+
+method _link_files {objdir tolink} {
+ set total [llength $tolink]
+ $o_cons start \
+ [mc "Linking objects"] \
+ [mc "objects"]
+ for {set i 0} {$i < $total} {} {
+ set p [lindex $tolink $i]
+ if {[catch {
+ file link -hard \
+ [file join .git objects $p] \
+ [file join $objdir $p]
+ } err]} {
+ _clone_failed $this [mc "Unable to hardlink object: %s" $err]
+ return 0
+ }
+
+ incr i
+ if {$i % 5 == 0} {
+ $o_cons update $i $total
+ update
+ }
+ }
+ return 1
+}
+
+method _clone_refs {} {
+ set pwd [pwd]
+ if {[catch {cd $origin_url} err]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $origin_url]]
+ return 0
+ }
+ set fd_in [git_read for-each-ref \
+ --tcl \
+ {--format=list %(refname) %(objectname) %(*objectname)}]
+ cd $pwd
+
+ set fd [open [gitdir packed-refs] w]
+ fconfigure $fd -translation binary
+ puts $fd "# pack-refs with: peeled"
+ while {[gets $fd_in line] >= 0} {
+ set line [eval $line]
+ set refn [lindex $line 0]
+ set robj [lindex $line 1]
+ set tobj [lindex $line 2]
+
+ if {[regsub ^refs/heads/ $refn \
+ "refs/remotes/$origin_name/" refn]} {
+ puts $fd "$robj $refn"
+ } elseif {[string match refs/tags/* $refn]} {
+ puts $fd "$robj $refn"
+ if {$tobj ne {}} {
+ puts $fd "^$tobj"
+ }
+ }
+ }
+ close $fd_in
+ close $fd
+ return 1
+}
+
+method _do_clone_tags {ok} {
+ if {$ok} {
+ $o_cons exec \
+ [list git fetch --tags -k $origin_name] \
+ [cb _do_clone_HEAD]
+ } else {
+ $o_cons done $ok
+ _clone_failed $this [mc "Cannot fetch branches and objects. See console output for details."]
+ }
+}
+
+method _do_clone_HEAD {ok} {
+ if {$ok} {
+ $o_cons exec \
+ [list git fetch $origin_name HEAD] \
+ [cb _do_clone_full_end]
+ } else {
+ $o_cons done $ok
+ _clone_failed $this [mc "Cannot fetch tags. See console output for details."]
+ }
+}
+
+method _do_clone_full_end {ok} {
+ $o_cons done $ok
+
+ if {$ok} {
+ destroy $w_body
+
+ set HEAD {}
+ if {[file exists [gitdir FETCH_HEAD]]} {
+ set fd [open [gitdir FETCH_HEAD] r]
+ while {[gets $fd line] >= 0} {
+ if {[regexp "^(.{40})\t\t" $line line HEAD]} {
+ break
+ }
+ }
+ close $fd
+ }
+
+ catch {git pack-refs}
+ _do_clone_checkout $this $HEAD
+ } else {
+ _clone_failed $this [mc "Cannot determine HEAD. See console output for details."]
+ }
+}
+
+method _clone_failed {{why {}}} {
+ if {[catch {file delete -force $local_path} err]} {
+ set why [strcat \
+ $why \
+ "\n\n" \
+ [mc "Unable to cleanup %s" $local_path] \
+ "\n\n" \
+ $err]
+ }
+ if {$why ne {}} {
+ update
+ error_popup [strcat [mc "Clone failed."] "\n" $why]
+ }
+}
+
+method _do_clone_checkout {HEAD} {
+ if {$HEAD eq {}} {
+ info_popup [strcat \
+ [mc "No default branch obtained."] \
+ "\n" \
+ [mc "The 'master' branch has not been initialized."] \
+ ]
+ set done 1
+ return
+ }
+ if {[catch {
+ git update-ref HEAD $HEAD^0
+ } err]} {
+ info_popup [strcat \
+ [mc "Cannot resolve %s as a commit." $HEAD^0] \
+ "\n $err" \
+ "\n" \
+ [mc "The 'master' branch has not been initialized."] \
+ ]
+ set done 1
+ return
+ }
+
+ set o_cons [status_bar::two_line $w_body]
+ pack $w_body -fill x -padx 10 -pady 10
+ $o_cons start \
+ [mc "Creating working directory"] \
+ [mc "files"]
+
+ set readtree_err {}
+ set fd [git_read --stderr read-tree \
+ -m \
+ -u \
+ -v \
+ HEAD \
+ HEAD \
+ ]
+ fconfigure $fd -blocking 0 -translation binary
+ fileevent $fd readable [cb _readtree_wait $fd]
+}
+
+method _readtree_wait {fd} {
+ set buf [read $fd]
+ $o_cons update_meter $buf
+ append readtree_err $buf
+
+ fconfigure $fd -blocking 1
+ if {![eof $fd]} {
+ fconfigure $fd -blocking 0
+ return
+ }
+
+ if {[catch {close $fd}]} {
+ set err $readtree_err
+ regsub {^fatal: } $err {} err
+ error_popup [strcat \
+ [mc "Initial file checkout failed."] \
+ "\n\n$err"]
+ return
+ }
+
+ set done 1
+}
+
+######################################################################
+##
+## Open Existing Repository
+
+method _do_open {} {
+ $w_next conf \
+ -state disabled \
+ -command [cb _do_open2] \
+ -text [mc "Open"]
+
+ frame $w_body
+ label $w_body.h \
+ -font font_uibold \
+ -text [mc "Open Existing Repository"]
+ pack $w_body.h -side top -fill x -pady 10
+ pack $w_body -fill x -padx 10
+
+ frame $w_body.where
+ label $w_body.where.l -text [mc "Repository:"]
+ entry $w_body.where.t \
+ -textvariable @local_path \
+ -font font_diff \
+ -width 50
+ button $w_body.where.b \
+ -text [mc "Browse"] \
+ -command [cb _open_local_path]
+
+ pack $w_body.where.b -side right
+ pack $w_body.where.l -side left
+ pack $w_body.where.t -fill x
+ pack $w_body.where -fill x
+
+ trace add variable @local_path write [cb _write_local_path]
+ bind $w_body.h <Destroy> [list trace remove variable @local_path write [cb _write_local_path]]
+ update
+ focus $w_body.where.t
+}
+
+method _open_local_path {} {
+ if {$local_path ne {}} {
+ set p $local_path
+ } else {
+ set p [_home]
+ }
+
+ set p [tk_chooseDirectory \
+ -initialdir $p \
+ -parent $top \
+ -title [mc "Git Repository"] \
+ -mustexist true]
+ if {$p eq {}} return
+
+ set p [file normalize $p]
+ if {![_is_git [file join $p .git]]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $p]]
+ return
+ }
+ set local_path $p
+}
+
+method _do_open2 {} {
+ if {![_is_git [file join $local_path .git]]} {
+ error_popup [mc "Not a Git repository: %s" [file tail $local_path]]
+ return
+ }
+
+ if {[catch {cd $local_path} err]} {
+ error_popup [strcat \
+ [mc "Failed to open repository %s:" $local_path] \
+ "\n\n$err"]
+ return
+ }
+
+ _append_recentrepos [pwd]
+ set ::_gitdir .git
+ set ::_prefix {}
+ set done 1
+}
+
+}
diff --git a/git-gui/lib/choose_rev.tcl b/git-gui/lib/choose_rev.tcl
index ec064b3e1..a063c5bc4 100644
--- a/git-gui/lib/choose_rev.tcl
+++ b/git-gui/lib/choose_rev.tcl
@@ -50,14 +50,14 @@ constructor _new {path unmerged_only title} {
if {$is_detached} {
radiobutton $w.detachedhead_r \
-anchor w \
- -text {This Detached Checkout} \
+ -text [mc "This Detached Checkout"] \
-value HEAD \
-variable @revtype
grid $w.detachedhead_r -sticky we -padx {0 5} -columnspan 2
}
radiobutton $w.expr_r \
- -text {Revision Expression:} \
+ -text [mc "Revision Expression:"] \
-value expr \
-variable @revtype
entry $w.expr_t \
@@ -71,17 +71,17 @@ constructor _new {path unmerged_only title} {
frame $w.types
radiobutton $w.types.head_r \
- -text {Local Branch} \
+ -text [mc "Local Branch"] \
-value head \
-variable @revtype
pack $w.types.head_r -side left
radiobutton $w.types.trck_r \
- -text {Tracking Branch} \
+ -text [mc "Tracking Branch"] \
-value trck \
-variable @revtype
pack $w.types.trck_r -side left
radiobutton $w.types.tag_r \
- -text {Tag} \
+ -text [mc "Tag"] \
-value tag \
-variable @revtype
pack $w.types.tag_r -side left
@@ -133,13 +133,13 @@ constructor _new {path unmerged_only title} {
append fmt { %(objecttype)}
append fmt { %(objectname)}
append fmt { [concat %(taggername) %(authorname)]}
- append fmt { [concat %(taggerdate) %(authordate)]}
+ append fmt { [reformat_date [concat %(taggerdate) %(authordate)]]}
append fmt { %(subject)}
append fmt {] [list}
append fmt { %(*objecttype)}
append fmt { %(*objectname)}
append fmt { %(*authorname)}
- append fmt { %(*authordate)}
+ append fmt { [reformat_date %(*authordate)]}
append fmt { %(*subject)}
append fmt {]}
set all_refn [list]
@@ -314,7 +314,7 @@ method commit_or_die {} {
}
set top [winfo toplevel $w]
- set msg "Invalid revision: [get $this]\n\n$err"
+ set msg [strcat [mc "Invalid revision: %s" [get $this]] "\n\n$err"]
tk_messageBox \
-icon error \
-type ok \
@@ -335,7 +335,7 @@ method _expr {} {
if {$i ne {}} {
return [lindex $cur_specs $i 1]
} else {
- error "No revision selected."
+ error [mc "No revision selected."]
}
}
@@ -343,7 +343,7 @@ method _expr {} {
if {$c_expr ne {}} {
return $c_expr
} else {
- error "Revision expression is empty."
+ error [mc "Revision expression is empty."]
}
}
HEAD { return HEAD }
@@ -527,14 +527,14 @@ method _open_tooltip {} {
set last [_reflog_last $this [lindex $spec 1]]
if {$last ne {}} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "updated"
+ $tooltip_t insert end [mc "Updated"]
$tooltip_t insert end " $last"
}
$tooltip_t insert end "\n"
if {$tag ne {}} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "tag" section_header
+ $tooltip_t insert end [mc "Tag"] section_header
$tooltip_t insert end " [lindex $tag 1]\n"
$tooltip_t insert end [lindex $tag 2]
$tooltip_t insert end " ([lindex $tag 3])\n"
@@ -544,7 +544,7 @@ method _open_tooltip {} {
if {$cmit ne {}} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "commit" section_header
+ $tooltip_t insert end [mc "Commit@@noun"] section_header
$tooltip_t insert end " [lindex $cmit 1]\n"
$tooltip_t insert end [lindex $cmit 2]
$tooltip_t insert end " ([lindex $cmit 3])\n"
@@ -553,11 +553,11 @@ method _open_tooltip {} {
if {[llength $spec] > 2} {
$tooltip_t insert end "\n"
- $tooltip_t insert end "remote" section_header
+ $tooltip_t insert end [mc "Remote"] section_header
$tooltip_t insert end " [lindex $spec 2]\n"
- $tooltip_t insert end "url"
+ $tooltip_t insert end [mc "URL"]
$tooltip_t insert end " $remote_url([lindex $spec 2])\n"
- $tooltip_t insert end "branch"
+ $tooltip_t insert end [mc "Branch"]
$tooltip_t insert end " [lindex $spec 3]"
}
@@ -583,7 +583,7 @@ method _reflog_last {name} {
}
if {$last ne {}} {
- set last [clock format $last -format {%a %b %e %H:%M:%S %Y}]
+ set last [format_date $last]
}
set reflog_last($name) $last
return $last
diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl
index 57238129e..10b0430f5 100644
--- a/git-gui/lib/commit.tcl
+++ b/git-gui/lib/commit.tcl
@@ -6,19 +6,19 @@ proc load_last_commit {} {
global repo_config
if {[llength $PARENT] == 0} {
- error_popup {There is nothing to amend.
+ error_popup [mc "There is nothing to amend.
You are about to create the initial commit. There is no commit before this to amend.
-}
+"]
return
}
repository_state curType curHEAD curMERGE_HEAD
if {$curType eq {merge}} {
- error_popup {Cannot amend while merging.
+ error_popup [mc "Cannot amend while merging.
You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity.
-}
+"]
return
}
@@ -46,7 +46,7 @@ You are currently in the middle of a merge that has not been fully completed. Y
}
set msg [string trim $msg]
} err]} {
- error_popup "Error loading commit data for amend:\n\n$err"
+ error_popup [strcat [mc "Error loading commit data for amend:"] "\n\n$err"]
return
}
@@ -73,12 +73,12 @@ proc committer_ident {} {
if {$GIT_COMMITTER_IDENT eq {}} {
if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} {
- error_popup "Unable to obtain your identity:\n\n$err"
+ error_popup [strcat [mc "Unable to obtain your identity:"] "\n\n$err"]
return {}
}
if {![regexp {^(.*) [0-9]+ [-+0-9]+$} \
$me me GIT_COMMITTER_IDENT]} {
- error_popup "Invalid GIT_COMMITTER_IDENT:\n\n$me"
+ error_popup [strcat [mc "Invalid GIT_COMMITTER_IDENT:"] "\n\n$me"]
return {}
}
}
@@ -130,12 +130,12 @@ proc commit_tree {} {
&& $curType eq {normal}
&& $curHEAD eq $HEAD} {
} elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
- info_popup {Last scanned state does not match repository state.
+ info_popup [mc "Last scanned state does not match repository state.
Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created.
The rescan will be automatically started now.
-}
+"]
unlock_index
rescan ui_ready
return
@@ -151,26 +151,26 @@ The rescan will be automatically started now.
D? -
M? {set files_ready 1}
U? {
- error_popup "Unmerged files cannot be committed.
+ error_popup [mc "Unmerged files cannot be committed.
-File [short_path $path] has merge conflicts. You must resolve them and stage the file before committing.
-"
+File %s has merge conflicts. You must resolve them and stage the file before committing.
+" [short_path $path]]
unlock_index
return
}
default {
- error_popup "Unknown file state [lindex $s 0] detected.
+ error_popup [mc "Unknown file state %s detected.
-File [short_path $path] cannot be committed by this program.
-"
+File %s cannot be committed by this program.
+" [lindex $s 0] [short_path $path]]
}
}
}
if {!$files_ready && ![string match *merge $curType]} {
- info_popup {No changes to commit.
+ info_popup [mc "No changes to commit.
You must stage at least 1 file before you can commit.
-}
+"]
unlock_index
return
}
@@ -180,14 +180,14 @@ You must stage at least 1 file before you can commit.
set msg [string trim [$ui_comm get 1.0 end]]
regsub -all -line {[ \t\r]+$} $msg {} msg
if {$msg eq {}} {
- error_popup {Please supply a commit message.
+ error_popup [mc "Please supply a commit message.
A good commit message has the following format:
- First line: Describe in one sentance what you did.
- Second line: Blank
- Remaining lines: Describe why this change is good.
-}
+"]
unlock_index
return
}
@@ -254,7 +254,7 @@ proc commit_committree {fd_wt curHEAD msg} {
gets $fd_wt tree_id
if {[catch {close $fd_wt} err]} {
- error_popup "write-tree failed:\n\n$err"
+ error_popup [strcat [mc "write-tree failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index
return
@@ -272,18 +272,18 @@ proc commit_committree {fd_wt curHEAD msg} {
&& [string length $old_tree] == 45} {
set old_tree [string range $old_tree 5 end]
} else {
- error "Commit $PARENT appears to be corrupt"
+ error [mc "Commit %s appears to be corrupt" $PARENT]
}
if {$tree_id eq $old_tree} {
- info_popup {No changes to commit.
+ info_popup [mc "No changes to commit.
No files were modified by this commit and it was not a merge commit.
A rescan will be automatically started now.
-}
+"]
unlock_index
- rescan {ui_status {No changes to commit.}}
+ rescan {ui_status [mc "No changes to commit."]}
return
}
}
@@ -300,7 +300,7 @@ A rescan will be automatically started now.
if {$use_enc ne {}} {
fconfigure $msg_wt -encoding $use_enc
} else {
- puts stderr "warning: Tcl does not support encoding '$enc'."
+ puts stderr [mc "warning: Tcl does not support encoding '%s'." $enc]
fconfigure $msg_wt -encoding utf-8
}
puts -nonewline $msg_wt $msg
@@ -314,7 +314,7 @@ A rescan will be automatically started now.
}
lappend cmd <$msg_p
if {[catch {set cmt_id [eval git $cmd]} err]} {
- error_popup "commit-tree failed:\n\n$err"
+ error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index
return
@@ -336,7 +336,7 @@ A rescan will be automatically started now.
if {[catch {
git update-ref -m $reflogm HEAD $cmt_id $curHEAD
} err]} {
- error_popup "update-ref failed:\n\n$err"
+ error_popup [strcat [mc "update-ref failed:"] "\n\n$err"]
ui_status {Commit failed.}
unlock_index
return
@@ -427,5 +427,5 @@ A rescan will be automatically started now.
display_all_files
unlock_index
reshow_diff
- ui_status "Created commit [string range $cmt_id 0 7]: $subject"
+ ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject]
}
diff --git a/git-gui/lib/console.tcl b/git-gui/lib/console.tcl
index b038a7835..5597188d8 100644
--- a/git-gui/lib/console.tcl
+++ b/git-gui/lib/console.tcl
@@ -6,6 +6,7 @@ class console {
field t_short
field t_long
field w
+field w_t
field console_cr
field is_toplevel 1; # are we our own window?
@@ -36,6 +37,7 @@ method _init {} {
}
set console_cr 1.0
+ set w_t $w.m.t
frame $w.m
label $w.m.l1 \
@@ -43,51 +45,47 @@ method _init {} {
-anchor w \
-justify left \
-font font_uibold
- text $w.m.t \
+ text $w_t \
-background white -borderwidth 1 \
-relief sunken \
-width 80 -height 10 \
-wrap none \
-font font_diff \
-state disabled \
- -xscrollcommand [list $w.m.sbx set] \
- -yscrollcommand [list $w.m.sby set]
- label $w.m.s -text {Working... please wait...} \
+ -xscrollcommand [cb _sb_set $w.m.sbx h] \
+ -yscrollcommand [cb _sb_set $w.m.sby v]
+ label $w.m.s -text [mc "Working... please wait..."] \
-anchor w \
-justify left \
-font font_uibold
- scrollbar $w.m.sbx -command [list $w.m.t xview] -orient h
- scrollbar $w.m.sby -command [list $w.m.t yview]
pack $w.m.l1 -side top -fill x
pack $w.m.s -side bottom -fill x
- pack $w.m.sbx -side bottom -fill x
- pack $w.m.sby -side right -fill y
- pack $w.m.t -side left -fill both -expand 1
+ pack $w_t -side left -fill both -expand 1
pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
menu $w.ctxm -tearoff 0
- $w.ctxm add command -label "Copy" \
- -command "tk_textCopy $w.m.t"
- $w.ctxm add command -label "Select All" \
- -command "focus $w.m.t;$w.m.t tag add sel 0.0 end"
- $w.ctxm add command -label "Copy All" \
+ $w.ctxm add command -label [mc "Copy"] \
+ -command "tk_textCopy $w_t"
+ $w.ctxm add command -label [mc "Select All"] \
+ -command "focus $w_t;$w_t tag add sel 0.0 end"
+ $w.ctxm add command -label [mc "Copy All"] \
-command "
- $w.m.t tag add sel 0.0 end
- tk_textCopy $w.m.t
- $w.m.t tag remove sel 0.0 end
+ $w_t tag add sel 0.0 end
+ tk_textCopy $w_t
+ $w_t tag remove sel 0.0 end
"
if {$is_toplevel} {
- button $w.ok -text {Close} \
+ button $w.ok -text [mc "Close"] \
-state disabled \
-command [list destroy $w]
pack $w.ok -side bottom -anchor e -pady 10 -padx 10
bind $w <Visibility> [list focus $w]
}
- bind_button3 $w.m.t "tk_popup $w.ctxm %X %Y"
- bind $w.m.t <$M1B-Key-a> "$w.m.t tag add sel 0.0 end;break"
- bind $w.m.t <$M1B-Key-A> "$w.m.t tag add sel 0.0 end;break"
+ bind_button3 $w_t "tk_popup $w.ctxm %X %Y"
+ bind $w_t <$M1B-Key-a> "$w_t tag add sel 0.0 end;break"
+ bind $w_t <$M1B-Key-A> "$w_t tag add sel 0.0 end;break"
}
method exec {cmd {after {}}} {
@@ -104,8 +102,8 @@ method exec {cmd {after {}}} {
method _read {fd after} {
set buf [read $fd]
if {$buf ne {}} {
- if {![winfo exists $w.m.t]} {_init $this}
- $w.m.t conf -state normal
+ if {![winfo exists $w_t]} {_init $this}
+ $w_t conf -state normal
set c 0
set n [string length $buf]
while {$c < $n} {
@@ -115,20 +113,20 @@ method _read {fd after} {
if {$lf < 0} {set lf [expr {$n + 1}]}
if {$lf < $cr} {
- $w.m.t insert end [string range $buf $c $lf]
- set console_cr [$w.m.t index {end -1c}]
+ $w_t insert end [string range $buf $c $lf]
+ set console_cr [$w_t index {end -1c}]
set c $lf
incr c
} else {
- $w.m.t delete $console_cr end
- $w.m.t insert end "\n"
- $w.m.t insert end [string range $buf $c [expr {$cr - 1}]]
+ $w_t delete $console_cr end
+ $w_t insert end "\n"
+ $w_t insert end [string range $buf $c [expr {$cr - 1}]]
set c $cr
incr c
}
}
- $w.m.t conf -state disabled
- $w.m.t see end
+ $w_t conf -state disabled
+ $w_t see end
}
fconfigure $fd -blocking 1
@@ -171,33 +169,50 @@ method chain {cmdlist {ok 1}} {
}
method insert {txt} {
- if {![winfo exists $w.m.t]} {_init $this}
- $w.m.t conf -state normal
- $w.m.t insert end "$txt\n"
- set console_cr [$w.m.t index {end -1c}]
- $w.m.t conf -state disabled
+ if {![winfo exists $w_t]} {_init $this}
+ $w_t conf -state normal
+ $w_t insert end "$txt\n"
+ set console_cr [$w_t index {end -1c}]
+ $w_t conf -state disabled
}
method done {ok} {
if {$ok} {
if {[winfo exists $w.m.s]} {
- $w.m.s conf -background green -text {Success}
+ bind $w.m.s <Destroy> [list delete_this $this]
+ $w.m.s conf -background green -text [mc "Success"]
if {$is_toplevel} {
$w.ok conf -state normal
focus $w.ok
}
+ } else {
+ delete_this
}
} else {
if {![winfo exists $w.m.s]} {
_init $this
}
- $w.m.s conf -background red -text {Error: Command Failed}
+ bind $w.m.s <Destroy> [list delete_this $this]
+ $w.m.s conf -background red -text [mc "Error: Command Failed"]
if {$is_toplevel} {
$w.ok conf -state normal
focus $w.ok
}
}
- delete_this
+}
+
+method _sb_set {sb orient first last} {
+ if {![winfo exists $sb]} {
+ if {$first == $last || ($first == 0 && $last == 1)} return
+ if {$orient eq {h}} {
+ scrollbar $sb -orient h -command [list $w_t xview]
+ pack $sb -fill x -side bottom -before $w_t
+ } else {
+ scrollbar $sb -orient v -command [list $w_t yview]
+ pack $sb -fill y -side right -before $w_t
+ }
+ }
+ $sb set $first $last
}
}
diff --git a/git-gui/lib/database.tcl b/git-gui/lib/database.tcl
index 0657cc224..d66aa3fe3 100644
--- a/git-gui/lib/database.tcl
+++ b/git-gui/lib/database.tcl
@@ -24,14 +24,14 @@ proc do_stats {} {
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text {Database Statistics}
+ label $w.header -text [mc "Database Statistics"]
pack $w.header -side top -fill x
frame $w.buttons -border 1
- button $w.buttons.close -text Close \
+ button $w.buttons.close -text [mc Close] \
-default active \
-command [list destroy $w]
- button $w.buttons.gc -text {Compress Database} \
+ button $w.buttons.gc -text [mc "Compress Database"] \
-default normal \
-command "destroy $w;do_gc"
pack $w.buttons.close -side right
@@ -40,16 +40,16 @@ proc do_stats {} {
frame $w.stat -borderwidth 1 -relief solid
foreach s {
- {count {Number of loose objects}}
- {size {Disk space used by loose objects} { KiB}}
- {in-pack {Number of packed objects}}
- {packs {Number of packs}}
- {size-pack {Disk space used by packed objects} { KiB}}
- {prune-packable {Packed objects waiting for pruning}}
- {garbage {Garbage files}}
+ {count {mc "Number of loose objects"}}
+ {size {mc "Disk space used by loose objects"} { KiB}}
+ {in-pack {mc "Number of packed objects"}}
+ {packs {mc "Number of packs"}}
+ {size-pack {mc "Disk space used by packed objects"} { KiB}}
+ {prune-packable {mc "Packed objects waiting for pruning"}}
+ {garbage {mc "Garbage files"}}
} {
set name [lindex $s 0]
- set label [lindex $s 1]
+ set label [eval [lindex $s 1]]
if {[catch {set value $stats($name)}]} continue
if {[llength $s] > 2} {
set value "$value[lindex $s 2]"
@@ -64,12 +64,12 @@ proc do_stats {} {
bind $w <Visibility> "grab $w; focus $w.buttons.close"
bind $w <Key-Escape> [list destroy $w]
bind $w <Key-Return> [list destroy $w]
- wm title $w "[appname] ([reponame]): Database Statistics"
+ wm title $w [append "[appname] ([reponame]): " [mc "Database Statistics"]]
tkwait window $w
}
proc do_gc {} {
- set w [console::new {gc} {Compressing the object database}]
+ set w [console::new {gc} [mc "Compressing the object database"]]
console::chain $w {
{exec git pack-refs --prune}
{exec git reflog expire --all}
@@ -80,7 +80,7 @@ proc do_gc {} {
proc do_fsck_objects {} {
set w [console::new {fsck-objects} \
- {Verifying the object database with fsck-objects}]
+ [mc "Verifying the object database with fsck-objects"]]
set cmd [list git fsck-objects]
lappend cmd --full
lappend cmd --cache
@@ -105,11 +105,11 @@ proc hint_gc {} {
set objects_current [expr {$objects_current * 256}]
set object_limit [expr {$object_limit * 256}]
if {[ask_popup \
- "This repository currently has approximately $objects_current loose objects.
+ [mc "This repository currently has approximately %i loose objects.
-To maintain optimal performance it is strongly recommended that you compress the database when more than $object_limit loose objects exist.
+To maintain optimal performance it is strongly recommended that you compress the database when more than %i loose objects exist.
-Compress the database now?"] eq yes} {
+Compress the database now?" $objects_current $object_limit]] eq yes} {
do_gc
}
}
diff --git a/git-gui/lib/date.tcl b/git-gui/lib/date.tcl
new file mode 100644
index 000000000..abe82992b
--- /dev/null
+++ b/git-gui/lib/date.tcl
@@ -0,0 +1,53 @@
+# git-gui date processing support
+# Copyright (C) 2007 Shawn Pearce
+
+set git_month(Jan) 1
+set git_month(Feb) 2
+set git_month(Mar) 3
+set git_month(Apr) 4
+set git_month(May) 5
+set git_month(Jun) 6
+set git_month(Jul) 7
+set git_month(Aug) 8
+set git_month(Sep) 9
+set git_month(Oct) 10
+set git_month(Nov) 11
+set git_month(Dec) 12
+
+proc parse_git_date {s} {
+ if {$s eq {}} {
+ return {}
+ }
+
+ if {![regexp \
+ {^... (...) (\d{1,2}) (\d\d):(\d\d):(\d\d) (\d{4}) ([+-]?)(\d\d)(\d\d)$} $s s \
+ month day hr mm ss yr ew tz_h tz_m]} {
+ error [mc "Invalid date from Git: %s" $s]
+ }
+
+ set s [clock scan [format {%4.4i%2.2i%2.2iT%2s%2s%2s} \
+ $yr $::git_month($month) $day \
+ $hr $mm $ss] \
+ -gmt 1]
+
+ regsub ^0 $tz_h {} tz_h
+ regsub ^0 $tz_m {} tz_m
+ switch -- $ew {
+ - {set ew +}
+ + {set ew -}
+ {} {set ew -}
+ }
+
+ return [expr "$s $ew ($tz_h * 3600 + $tz_m * 60)"]
+}
+
+proc format_date {s} {
+ if {$s eq {}} {
+ return {}
+ }
+ return [clock format $s -format {%a %b %e %H:%M:%S %Y}]
+}
+
+proc reformat_date {s} {
+ return [format_date [parse_git_date $s]]
+}
diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl
index 694834ab7..43565e412 100644
--- a/git-gui/lib/diff.tcl
+++ b/git-gui/lib/diff.tcl
@@ -39,13 +39,13 @@ proc handle_empty_diff {} {
set s $file_states($path)
if {[lindex $s 0] ne {_M}} return
- info_popup "No differences detected.
+ info_popup [mc "No differences detected.
-[short_path $path] has no changes.
+%s has no changes.
The modification date of this file was updated by another application, but the content within the file was not changed.
-A rescan will be automatically started to find other files which may have the same state."
+A rescan will be automatically started to find other files which may have the same state." [short_path $path]]
clear_diff
display_file $path __
@@ -78,7 +78,7 @@ proc show_diff {path w {lno {}}} {
set current_diff_path $path
set current_diff_side $w
set current_diff_header {}
- ui_status "Loading diff of [escape_path $path]..."
+ ui_status [mc "Loading diff of %s..." [escape_path $path]]
# - Git won't give us the diff, there's nothing to compare to!
#
@@ -111,13 +111,16 @@ proc show_diff {path w {lno {}}} {
} err ]} {
set diff_active 0
unlock_index
- ui_status "Unable to display [escape_path $path]"
- error_popup "Error loading file:\n\n$err"
+ ui_status [mc "Unable to display %s" [escape_path $path]]
+ error_popup [strcat [mc "Error loading file:"] "\n\n$err"]
return
}
$ui_diff conf -state normal
if {$type eq {submodule}} {
- $ui_diff insert end "* Git Repository (subproject)\n" d_@
+ $ui_diff insert end [append \
+ "* " \
+ [mc "Git Repository (subproject)"] \
+ "\n"] d_@
} elseif {![catch {set type [exec file $path]}]} {
set n [string length $path]
if {[string equal -length $n $path $type]} {
@@ -128,7 +131,7 @@ proc show_diff {path w {lno {}}} {
}
if {[string first "\0" $content] != -1} {
$ui_diff insert end \
- "* Binary file (not showing content)." \
+ [mc "* Binary file (not showing content)."] \
d_@
} else {
if {$sz > $max_sz} {
@@ -178,8 +181,8 @@ proc show_diff {path w {lno {}}} {
if {[catch {set fd [eval git_read --nice $cmd]} err]} {
set diff_active 0
unlock_index
- ui_status "Unable to display [escape_path $path]"
- error_popup "Error loading diff:\n\n$err"
+ ui_status [mc "Unable to display %s" [escape_path $path]]
+ error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
return
}
@@ -296,14 +299,14 @@ proc apply_hunk {x y} {
set apply_cmd {apply --cached --whitespace=nowarn}
set mi [lindex $file_states($current_diff_path) 0]
if {$current_diff_side eq $ui_index} {
- set mode unstage
+ set failed_msg [mc "Failed to unstage selected hunk."]
lappend apply_cmd --reverse
if {[string index $mi 0] ne {M}} {
unlock_index
return
}
} else {
- set mode stage
+ set failed_msg [mc "Failed to stage selected hunk."]
if {[string index $mi 1] ne {M}} {
unlock_index
return
@@ -328,7 +331,7 @@ proc apply_hunk {x y} {
puts -nonewline $p $current_diff_header
puts -nonewline $p [$ui_diff get $s_lno $e_lno]
close $p} err]} {
- error_popup "Failed to $mode selected hunk.\n\n$err"
+ error_popup [append $failed_msg "\n\n$err"]
unlock_index
return
}
diff --git a/git-gui/lib/error.tcl b/git-gui/lib/error.tcl
index 16a22187b..13565b7ab 100644
--- a/git-gui/lib/error.tcl
+++ b/git-gui/lib/error.tcl
@@ -9,7 +9,7 @@ proc error_popup {msg} {
set cmd [list tk_messageBox \
-icon error \
-type ok \
- -title "$title: error" \
+ -title [append "$title: " [mc "error"]] \
-message $msg]
if {[winfo ismapped .]} {
lappend cmd -parent .
@@ -25,7 +25,7 @@ proc warn_popup {msg} {
set cmd [list tk_messageBox \
-icon warning \
-type ok \
- -title "$title: warning" \
+ -title [append "$title: " [mc "warning"]] \
-message $msg]
if {[winfo ismapped .]} {
lappend cmd -parent .
@@ -78,7 +78,7 @@ proc hook_failed_popup {hook msg} {
-font font_diff \
-yscrollcommand [list $w.m.sby set]
label $w.m.l2 \
- -text {You must correct the above errors before committing.} \
+ -text [mc "You must correct the above errors before committing."] \
-anchor w \
-justify left \
-font font_uibold
@@ -99,6 +99,6 @@ proc hook_failed_popup {hook msg} {
bind $w <Visibility> "grab $w; focus $w"
bind $w <Key-Return> "destroy $w"
- wm title $w "[appname] ([reponame]): error"
+ wm title $w [append "[appname] ([reponame]): " [mc "error"]]
tkwait window $w
}
diff --git a/git-gui/lib/git-gui.ico b/git-gui/lib/git-gui.ico
new file mode 100644
index 000000000..563dd6623
--- /dev/null
+++ b/git-gui/lib/git-gui.ico
Binary files differ
diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl
index 44689ab63..a0b22f294 100644
--- a/git-gui/lib/index.tcl
+++ b/git-gui/lib/index.tcl
@@ -1,6 +1,56 @@
# git-gui index (add/remove) support
# Copyright (C) 2006, 2007 Shawn Pearce
+proc _delete_indexlock {} {
+ if {[catch {file delete -- [gitdir index.lock]} err]} {
+ error_popup [strcat [mc "Unable to unlock the index."] "\n\n$err"]
+ }
+}
+
+proc _close_updateindex {fd after} {
+ fconfigure $fd -blocking 1
+ if {[catch {close $fd} err]} {
+ set w .indexfried
+ toplevel $w
+ wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]]
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+ pack [label $w.msg \
+ -justify left \
+ -anchor w \
+ -text [strcat \
+ [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."] \
+ "\n\n$err"] \
+ ] -anchor w
+
+ frame $w.buttons
+ button $w.buttons.continue \
+ -text [mc "Continue"] \
+ -command [list destroy $w]
+ pack $w.buttons.continue -side right -padx 5
+ button $w.buttons.unlock \
+ -text [mc "Unlock Index"] \
+ -command "destroy $w; _delete_indexlock"
+ pack $w.buttons.unlock -side right
+ pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+ wm protocol $w WM_DELETE_WINDOW update
+ bind $w.buttons.continue <Visibility> "
+ grab $w
+ focus $w.buttons.continue
+ "
+ tkwait window $w
+
+ $::main_status stop
+ unlock_index
+ rescan $after 0
+ return
+ }
+
+ $::main_status stop
+ unlock_index
+ uplevel #0 $after
+}
+
proc update_indexinfo {msg pathList after} {
global update_index_cp
@@ -12,12 +62,7 @@ proc update_indexinfo {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- 0.0]
+ $::main_status start $msg [mc "files"]
set fd [git_write update-index -z --index-info]
fconfigure $fd \
-blocking 0 \
@@ -31,19 +76,16 @@ proc update_indexinfo {msg pathList after} {
$pathList \
$totalCnt \
$batch \
- $msg \
$after \
]
}
-proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
+proc write_update_indexinfo {fd pathList totalCnt batch after} {
global update_index_cp
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
- close $fd
- unlock_index
- uplevel #0 $after
+ _close_updateindex $fd $after
return
}
@@ -68,12 +110,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
display_file $path $new
}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- [expr {100.0 * $update_index_cp / $totalCnt}]]
+ $::main_status update $update_index_cp $totalCnt
}
proc update_index {msg pathList after} {
@@ -87,12 +124,7 @@ proc update_index {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- 0.0]
+ $::main_status start $msg [mc "files"]
set fd [git_write update-index --add --remove -z --stdin]
fconfigure $fd \
-blocking 0 \
@@ -106,19 +138,16 @@ proc update_index {msg pathList after} {
$pathList \
$totalCnt \
$batch \
- $msg \
$after \
]
}
-proc write_update_index {fd pathList totalCnt batch msg after} {
+proc write_update_index {fd pathList totalCnt batch after} {
global update_index_cp
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
- close $fd
- unlock_index
- uplevel #0 $after
+ _close_updateindex $fd $after
return
}
@@ -147,12 +176,7 @@ proc write_update_index {fd pathList totalCnt batch msg after} {
display_file $path $new
}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- [expr {100.0 * $update_index_cp / $totalCnt}]]
+ $::main_status update $update_index_cp $totalCnt
}
proc checkout_index {msg pathList after} {
@@ -166,12 +190,7 @@ proc checkout_index {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- 0.0]
+ $::main_status start $msg [mc "files"]
set fd [git_write checkout-index \
--index \
--quiet \
@@ -191,19 +210,16 @@ proc checkout_index {msg pathList after} {
$pathList \
$totalCnt \
$batch \
- $msg \
$after \
]
}
-proc write_checkout_index {fd pathList totalCnt batch msg after} {
+proc write_checkout_index {fd pathList totalCnt batch after} {
global update_index_cp
global file_states current_diff_path
if {$update_index_cp >= $totalCnt} {
- close $fd
- unlock_index
- uplevel #0 $after
+ _close_updateindex $fd $after
return
}
@@ -222,12 +238,7 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} {
}
}
- ui_status [format \
- "%s... %i/%i files (%.2f%%)" \
- $msg \
- $update_index_cp \
- $totalCnt \
- [expr {100.0 * $update_index_cp / $totalCnt}]]
+ $::main_status update $update_index_cp $totalCnt
}
proc unstage_helper {txt paths} {
@@ -268,7 +279,7 @@ proc do_unstage_selection {} {
[array names selected_paths]
} elseif {$current_diff_path ne {}} {
unstage_helper \
- "Unstaging [short_path $current_diff_path] from commit" \
+ [mc "Unstaging %s from commit" [short_path $current_diff_path]] \
[list $current_diff_path]
}
}
@@ -312,7 +323,7 @@ proc do_add_selection {} {
[array names selected_paths]
} elseif {$current_diff_path ne {}} {
add_helper \
- "Adding [short_path $current_diff_path]" \
+ [mc "Adding %s" [short_path $current_diff_path]] \
[list $current_diff_path]
}
}
@@ -351,26 +362,35 @@ proc revert_helper {txt paths} {
}
}
+
+ # Split question between singular and plural cases, because
+ # such distinction is needed in some languages. Previously, the
+ # code used "Revert changes in" for both, but that can't work
+ # in languages where 'in' must be combined with word from
+ # rest of string (in diffrent way for both cases of course).
+ #
+ # FIXME: Unfortunately, even that isn't enough in some languages
+ # as they have quite complex plural-form rules. Unfortunately,
+ # msgcat doesn't seem to support that kind of string translation.
+ #
set n [llength $pathList]
if {$n == 0} {
unlock_index
return
} elseif {$n == 1} {
- set s "[short_path [lindex $pathList]]"
+ set query [mc "Revert changes in file %s?" [short_path [lindex $pathList]]]
} else {
- set s "these $n files"
+ set query [mc "Revert changes in these %i files?" $n]
}
set reply [tk_dialog \
.confirm_revert \
"[appname] ([reponame])" \
- "Revert changes in $s?
-
-Any unstaged changes will be permanently lost by the revert." \
+ [mc "Any unstaged changes will be permanently lost by the revert."] \
question \
1 \
- {Do Nothing} \
- {Revert Changes} \
+ [mc "Do Nothing"] \
+ [mc "Revert Changes"] \
]
if {$reply == 1} {
checkout_index \
diff --git a/git-gui/lib/logo.tcl b/git-gui/lib/logo.tcl
new file mode 100644
index 000000000..5ff76692f
--- /dev/null
+++ b/git-gui/lib/logo.tcl
@@ -0,0 +1,43 @@
+# git-gui Git Gui logo
+# Copyright (C) 2007 Shawn Pearce
+
+# Henrik Nyh's alternative Git logo, from his blog post
+# http://henrik.nyh.se/2007/06/alternative-git-logo-and-favicon
+#
+image create photo ::git_logo_data -data {
+R0lGODdhYQC8AIQbAGZmZtg4LW9vb3l5eYKCgoyMjEC/TOJpYZWVlZ+fn2/PeKmpqbKysry8vMXF
+xZ/fpc/Pz7fnvPXNytnZ2eLi4s/v0vja1+zs7Of36fX19f3z8v///////////////////ywAAAAA
+YQC8AAAF/uAmjmRpnmiqrmzrvq4hz3RtGw+s7zx5/7dcb0hUAY8zYXHJRCKVzGjPeYRKry8q0Irt
+GrVBr3gFDo/PprKNix6ra+y2902Ly7H05L2dl9n3UX04gGeCf4RFhohiiotdjY5XkJGBfYeUOpOY
+iZablXmXURgPpKWmp6ipqYIKqq6vqREjFYK1trUKs7e7vFq5IrS9wsM0vxvBxMm8xsjKzqy6z9J5
+zNPWatXX2k7Z29433d/iMuHj3+Xm2+jp1+vs0+7vz/HyyvT1xPf4wvr7y9H+pBkbBasgLFYGE8ba
+o8nTlE4OOYGKKJFOKIopGmLMAnHjDo0eWYAM+WUiSRgj/k+eSKmyBMuWI17C3CATZs2WN1XmPLmT
+ZM+QPz0G3VihqNGjSJNWwDCzqdOnUKPu0SChqtWrWLNq3cq1q9evYCVYGCEhgNmzaNOqXcu2rdu3
+cOMGOEBWrt27ePPCpSuirN6/gAO35bvBr+DDiPMSNpy4sWO2ix9Lnmw2MuXLiS1j3gxYM+fPdz2D
+Hv1WNOnTak2jXj23LuvXlV3DZq16Nujatjnjzo15N2/Kvn9LDi7cMfHimaUqX868ufPn0KPPpOCA
+AQMWCQBo3869u/fv4MNrd3DlQoMC3QlkSJFdvPv38LVDWJLBAYHwE1LE38+/+/UhGTAggHv5odDf
+gfv9/seDgPAVeAKCELqnIAwU3BefgyZEqOF3E7rAQH8YlrDhiNt1uEIG6IGoH4kjmpjCBRaqaCCL
+G7p4AgUDIhgiCTTW2AKOEe44Qo8a2khCBgNoKKQIREZopAgZxAjhkhs0CeGTG7Sn5IpW9vekAyRS
+2eWBRl6Q44ZijhlfAQlQmeKIaarpHZsMTHABCxDQGKec3JH3QpIs7snndn6yAKaeXA7aZwuABppo
+fAws0GiEhaKQJ40F3DkjfwVC8CaCAlCgAgIkJjDfCgdiOMGn/Q2w3gkZtPgqC6ma0ECECaBwa4QE
+aOpCrSYAqeMJpEKYqw7ABnsmfwQ8aCwPySqLYKUb/kwAYbPQyoiCtQcOUMKHBwrgK7LaogBuuaxC
+OkS0KEwa37EiLBufALPuwO4Jh/InwAixkknEvSe4C9+p3PY3rr3lpnDufguIcCmzRQAc7IHYLhxf
+w/8mnILA74lg8cARa4xCsZxusMCBomZccgsfv0deuh2HvLKh/sLs3hJSvieuCwUzvIHN4tGXc3ih
+vtDzmj8fSNLR8BWQdH9LH+g00OFF3d/UBx4cUcvuOc21eFRiouV+Xvvr0dDvlX21R/2uzTR89TqU
+L3+5UoBgAxtRHd5/CHpLkd13i4D2e3hHRLKMY+9Hr0Nvx/fq3Pw57cng7/m9wQVObnIyhAiQwHF8
+/tQS8nDgI2wOYeh3CAvhuIBHiDEgqvdtwudkaz3GBPKaTcKuGgqAJRMZmK6h1hnk3ncDcUvhgPFS
+o5B476ZKQcECzCN4qgmYN4lAncmzcAEEkhJp+QlfkyhAAdtbN8H67FvHQAF6b4g6v9UryqfkKkBu
+v/0prxD//kR63YnqB8AeqcdoBRxU/1zAuwRaaX4reJ4DSSRAHUhwgrgqwgUx2B94EWGDHISPBzUY
+QgSNcAn6K6F4fscDCtBOhdoRwPW6kIHDwZA7vWoDBF44Qd/tIUAEBCACbIeG4AXxfmFrQ4B4OCYE
+JBEQELChmgbAACJioj4JOCKCCLCABZ6EAg1IHwDlyLYAB1gRJhSYgHUQAD9WnQ9+CWBAA+wknTpC
+JwQAOw==
+}
+
+proc git_logo {w} {
+ label $w \
+ -borderwidth 1 \
+ -relief sunken \
+ -background white \
+ -image ::git_logo_data
+ return $w
+}
diff --git a/git-gui/lib/merge.tcl b/git-gui/lib/merge.tcl
index 0e50919d4..63e14279c 100644
--- a/git-gui/lib/merge.tcl
+++ b/git-gui/lib/merge.tcl
@@ -10,10 +10,10 @@ method _can_merge {} {
global HEAD commit_type file_states
if {[string match amend* $commit_type]} {
- info_popup {Cannot merge while amending.
+ info_popup [mc "Cannot merge while amending.
You must finish amending this commit before starting any type of merge.
-}
+"]
return 0
}
@@ -24,12 +24,12 @@ You must finish amending this commit before starting any type of merge.
#
repository_state curType curHEAD curMERGE_HEAD
if {$commit_type ne $curType || $HEAD ne $curHEAD} {
- info_popup {Last scanned state does not match repository state.
+ info_popup [mc "Last scanned state does not match repository state.
Another Git program has modified this repository since the last scan. A rescan must be performed before a merge can be performed.
The rescan will be automatically started now.
-}
+"]
unlock_index
rescan ui_ready
return 0
@@ -41,22 +41,22 @@ The rescan will be automatically started now.
continue; # and pray it works!
}
U? {
- error_popup "You are in the middle of a conflicted merge.
+ error_popup [mc "You are in the middle of a conflicted merge.
-File [short_path $path] has merge conflicts.
+File %s has merge conflicts.
You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.
-"
+" [short_path $path]]
unlock_index
return 0
}
?? {
- error_popup "You are in the middle of a change.
+ error_popup [mc "You are in the middle of a change.
-File [short_path $path] is modified.
+File %s is modified.
You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise.
-"
+" [short_path $path]]
unlock_index
return 0
}
@@ -103,7 +103,7 @@ method _start {} {
regsub {^[^:@]*@} $remote {} remote
}
set branch [lindex $spec 2]
- set stitle "$branch of $remote"
+ set stitle [mc "%s of %s" $branch $remote]
}
regsub ^refs/heads/ $branch {} branch
puts $fh "$cmit\t\tbranch '$branch' of $remote"
@@ -116,9 +116,9 @@ method _start {} {
lappend cmd HEAD
lappend cmd $name
- set msg "Merging $current_branch and $stitle"
+ set msg [mc "Merging %s and %s" $current_branch $stitle]
ui_status "$msg..."
- set cons [console::new "Merge" "merge $stitle"]
+ set cons [console::new [mc "Merge"] "merge $stitle"]
console::exec $cons $cmd [cb _finish $cons]
wm protocol $w WM_DELETE_WINDOW {}
@@ -128,9 +128,9 @@ method _start {} {
method _finish {cons ok} {
console::done $cons $ok
if {$ok} {
- set msg {Merge completed successfully.}
+ set msg [mc "Merge completed successfully."]
} else {
- set msg {Merge failed. Conflict resolution is required.}
+ set msg [mc "Merge failed. Conflict resolution is required."]
}
unlock_index
rescan [list ui_status $msg]
@@ -147,7 +147,7 @@ constructor dialog {} {
}
make_toplevel top w
- wm title $top "[appname] ([reponame]): Merge"
+ wm title $top [append "[appname] ([reponame]): " [mc "Merge"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
@@ -155,26 +155,26 @@ constructor dialog {} {
set _start [cb _start]
label $w.header \
- -text "Merge Into $current_branch" \
+ -text [mc "Merge Into %s" $current_branch] \
-font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
button $w.buttons.visualize \
- -text Visualize \
+ -text [mc Visualize] \
-command [cb _visualize]
pack $w.buttons.visualize -side left
button $w.buttons.merge \
- -text Merge \
+ -text [mc Merge] \
-command $_start
pack $w.buttons.merge -side right
button $w.buttons.cancel \
- -text {Cancel} \
+ -text [mc "Cancel"] \
-command [cb _cancel]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- set w_rev [::choose_rev::new_unmerged $w.rev {Revision To Merge}]
+ set w_rev [::choose_rev::new_unmerged $w.rev [mc "Revision To Merge"]]
pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
bind $w <$M1B-Key-Return> $_start
@@ -209,34 +209,34 @@ proc reset_hard {} {
global HEAD commit_type file_states
if {[string match amend* $commit_type]} {
- info_popup {Cannot abort while amending.
+ info_popup [mc "Cannot abort while amending.
You must finish amending this commit.
-}
+"]
return
}
if {![lock_index abort]} return
if {[string match *merge* $commit_type]} {
- set op_question "Abort merge?
+ set op_question [mc "Abort merge?
Aborting the current merge will cause *ALL* uncommitted changes to be lost.
-Continue with aborting the current merge?"
+Continue with aborting the current merge?"]
} else {
- set op_question "Reset changes?
+ set op_question [mc "Reset changes?
Resetting the changes will cause *ALL* uncommitted changes to be lost.
-Continue with resetting the current changes?"
+Continue with resetting the current changes?"]
}
if {[ask_popup $op_question] eq {yes}} {
set fd [git_read --stderr read-tree --reset -u -v HEAD]
fconfigure $fd -blocking 0 -translation binary
fileevent $fd readable [namespace code [list _reset_wait $fd]]
- $::main_status start {Aborting} {files reset}
+ $::main_status start [mc "Aborting"] {files reset}
} else {
unlock_index
}
@@ -263,9 +263,9 @@ proc _reset_wait {fd} {
catch {file delete [gitdir GITGUI_MSG]}
if {$fail} {
- warn_popup "Abort failed.\n\n$err"
+ warn_popup "[mc "Abort failed."]\n\n$err"
}
- rescan {ui_status {Abort completed. Ready.}}
+ rescan {ui_status [mc "Abort completed. Ready."]}
} else {
fconfigure $fd -blocking 0
}
diff --git a/git-gui/lib/option.tcl b/git-gui/lib/option.tcl
index 063f5df6f..f812e5e89 100644
--- a/git-gui/lib/option.tcl
+++ b/git-gui/lib/option.tcl
@@ -54,85 +54,6 @@ proc save_config {} {
}
}
-proc do_about {} {
- global appvers copyright oguilib
- global tcl_patchLevel tk_patchLevel
-
- set w .about_dialog
- toplevel $w
- wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
-
- label $w.header -text "About [appname]" \
- -font font_uibold
- pack $w.header -side top -fill x
-
- frame $w.buttons
- button $w.buttons.close -text {Close} \
- -default active \
- -command [list destroy $w]
- pack $w.buttons.close -side right
- pack $w.buttons -side bottom -fill x -pady 10 -padx 10
-
- label $w.desc \
- -text "git-gui - a graphical user interface for Git.
-$copyright" \
- -padx 5 -pady 5 \
- -justify left \
- -anchor w \
- -borderwidth 1 \
- -relief solid
- pack $w.desc -side top -fill x -padx 5 -pady 5
-
- set v {}
- append v "git-gui version $appvers\n"
- append v "[git version]\n"
- append v "\n"
- if {$tcl_patchLevel eq $tk_patchLevel} {
- append v "Tcl/Tk version $tcl_patchLevel"
- } else {
- append v "Tcl version $tcl_patchLevel"
- append v ", Tk version $tk_patchLevel"
- }
-
- set d {}
- append d "git wrapper: $::_git\n"
- append d "git exec dir: [gitexec]\n"
- append d "git-gui lib: $oguilib"
-
- label $w.vers \
- -text $v \
- -padx 5 -pady 5 \
- -justify left \
- -anchor w \
- -borderwidth 1 \
- -relief solid
- pack $w.vers -side top -fill x -padx 5 -pady 5
-
- label $w.dirs \
- -text $d \
- -padx 5 -pady 5 \
- -justify left \
- -anchor w \
- -borderwidth 1 \
- -relief solid
- pack $w.dirs -side top -fill x -padx 5 -pady 5
-
- menu $w.ctxm -tearoff 0
- $w.ctxm add command \
- -label {Copy} \
- -command "
- clipboard clear
- clipboard append -format STRING -type STRING -- \[$w.vers cget -text\]
- "
-
- bind $w <Visibility> "grab $w; focus $w.buttons.close"
- bind $w <Key-Escape> "destroy $w"
- bind $w <Key-Return> "destroy $w"
- bind_button3 $w.vers "tk_popup $w.ctxm %X %Y; grab $w; focus $w"
- wm title $w "About [appname]"
- tkwait window $w
-}
-
proc do_options {} {
global repo_config global_config font_descs
global repo_config_new global_config_new
@@ -157,48 +78,44 @@ proc do_options {} {
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text "Options" \
- -font font_uibold
- pack $w.header -side top -fill x
-
frame $w.buttons
- button $w.buttons.restore -text {Restore Defaults} \
+ button $w.buttons.restore -text [mc "Restore Defaults"] \
-default normal \
-command do_restore_defaults
pack $w.buttons.restore -side left
- button $w.buttons.save -text Save \
+ button $w.buttons.save -text [mc Save] \
-default active \
-command [list do_save_config $w]
pack $w.buttons.save -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc "Cancel"] \
-default normal \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.repo -text "[reponame] Repository"
- labelframe $w.global -text {Global (All Repositories)}
+ labelframe $w.repo -text [mc "%s Repository" [reponame]]
+ labelframe $w.global -text [mc "Global (All Repositories)"]
pack $w.repo -side left -fill both -expand 1 -pady 5 -padx 5
pack $w.global -side right -fill both -expand 1 -pady 5 -padx 5
set optid 0
foreach option {
- {t user.name {User Name}}
- {t user.email {Email Address}}
-
- {b merge.summary {Summarize Merge Commits}}
- {i-1..5 merge.verbosity {Merge Verbosity}}
- {b merge.diffstat {Show Diffstat After Merge}}
-
- {b gui.trustmtime {Trust File Modification Timestamps}}
- {b gui.pruneduringfetch {Prune Tracking Branches During Fetch}}
- {b gui.matchtrackingbranch {Match Tracking Branches}}
- {i-0..99 gui.diffcontext {Number of Diff Context Lines}}
- {t gui.newbranchtemplate {New Branch Name Template}}
+ {t user.name {mc "User Name"}}
+ {t user.email {mc "Email Address"}}
+
+ {b merge.summary {mc "Summarize Merge Commits"}}
+ {i-1..5 merge.verbosity {mc "Merge Verbosity"}}
+ {b merge.diffstat {mc "Show Diffstat After Merge"}}
+
+ {b gui.trustmtime {mc "Trust File Modification Timestamps"}}
+ {b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}}
+ {b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
+ {i-0..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
+ {t gui.newbranchtemplate {mc "New Branch Name Template"}}
} {
set type [lindex $option 0]
set name [lindex $option 1]
- set text [lindex $option 2]
+ set text [eval [lindex $option 2]]
incr optid
foreach f {repo global} {
switch -glob -- $type {
@@ -246,7 +163,7 @@ proc do_options {} {
foreach option $font_descs {
set name [lindex $option 0]
set font [lindex $option 1]
- set text [lindex $option 2]
+ set text [eval [lindex $option 2]]
set global_config_new(gui.$font^^family) \
[font configure $font -family]
@@ -278,7 +195,13 @@ proc do_options {} {
bind $w <Visibility> "grab $w; focus $w.buttons.save"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> [list do_save_config $w]
- wm title $w "[appname] ([reponame]): Options"
+
+ if {[is_MacOSX]} {
+ set t [mc "Preferences"]
+ } else {
+ set t [mc "Options"]
+ }
+ wm title $w "[appname] ([reponame]): $t"
tkwait window $w
}
@@ -309,7 +232,7 @@ proc do_restore_defaults {} {
proc do_save_config {w} {
if {[catch {save_config} err]} {
- error_popup "Failed to completely save options:\n\n$err"
+ error_popup [strcat [mc "Failed to completely save options:"] "\n\n$err"]
}
reshow_diff
destroy $w
diff --git a/git-gui/lib/remote.tcl b/git-gui/lib/remote.tcl
index cf9b9d582..0e86ddac0 100644
--- a/git-gui/lib/remote.tcl
+++ b/git-gui/lib/remote.tcl
@@ -135,8 +135,10 @@ proc load_all_remotes {} {
proc populate_fetch_menu {} {
global all_remotes repo_config
- set m .mbar.fetch
- set prune_list [list]
+ set remote_m .mbar.remote
+ set fetch_m $remote_m.fetch
+ set prune_m $remote_m.prune
+
foreach r $all_remotes {
set enable 0
if {![catch {set a $repo_config(remote.$r.url)}]} {
@@ -157,28 +159,34 @@ proc populate_fetch_menu {} {
}
if {$enable} {
- lappend prune_list $r
- $m add command \
- -label "Fetch from $r..." \
+ if {![winfo exists $fetch_m]} {
+ menu $prune_m
+ $remote_m insert 0 cascade \
+ -label [mc "Prune from"] \
+ -menu $prune_m
+
+ menu $fetch_m
+ $remote_m insert 0 cascade \
+ -label [mc "Fetch from"] \
+ -menu $fetch_m
+ }
+
+ $fetch_m add command \
+ -label $r \
-command [list fetch_from $r]
+ $prune_m add command \
+ -label $r \
+ -command [list prune_from $r]
}
}
-
- if {$prune_list ne {}} {
- $m add separator
- }
- foreach r $prune_list {
- $m add command \
- -label "Prune from $r..." \
- -command [list prune_from $r]
- }
}
proc populate_push_menu {} {
global all_remotes repo_config
- set m .mbar.push
- set fast_count 0
+ set remote_m .mbar.remote
+ set push_m $remote_m.push
+
foreach r $all_remotes {
set enable 0
if {![catch {set a $repo_config(remote.$r.url)}]} {
@@ -199,13 +207,16 @@ proc populate_push_menu {} {
}
if {$enable} {
- if {!$fast_count} {
- $m add separator
+ if {![winfo exists $push_m]} {
+ menu $push_m
+ $remote_m insert 0 cascade \
+ -label [mc "Push to"] \
+ -menu $push_m
}
- $m add command \
- -label "Push to $r..." \
+
+ $push_m add command \
+ -label $r \
-command [list push_to $r]
- incr fast_count
}
}
}
diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl
index c88a360db..c7b814869 100644
--- a/git-gui/lib/remote_branch_delete.tcl
+++ b/git-gui/lib/remote_branch_delete.tcl
@@ -26,28 +26,28 @@ constructor dialog {} {
global all_remotes M1B
make_toplevel top w
- wm title $top "[appname] ([reponame]): Delete Remote Branch"
+ wm title $top [append "[appname] ([reponame]): " [mc "Delete Remote Branch"]]
if {$top ne {.}} {
wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
}
- label $w.header -text {Delete Remote Branch} -font font_uibold
+ label $w.header -text [mc "Delete Remote Branch"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.delete -text Delete \
+ button $w.buttons.delete -text [mc Delete] \
-default active \
-command [cb _delete]
pack $w.buttons.delete -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc "Cancel"] \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.dest -text {From Repository}
+ labelframe $w.dest -text [mc "From Repository"]
if {$all_remotes ne {}} {
radiobutton $w.dest.remote_r \
- -text {Remote:} \
+ -text [mc "Remote:"] \
-value remote \
-variable @urltype
eval tk_optionMenu $w.dest.remote_m @remote $all_remotes
@@ -63,7 +63,7 @@ constructor dialog {} {
set urltype url
}
radiobutton $w.dest.url_r \
- -text {Arbitrary URL:} \
+ -text [mc "Arbitrary URL:"] \
-value url \
-variable @urltype
entry $w.dest.url_t \
@@ -81,7 +81,7 @@ constructor dialog {} {
grid columnconfigure $w.dest 1 -weight 1
pack $w.dest -anchor nw -fill x -pady 5 -padx 5
- labelframe $w.heads -text {Branches}
+ labelframe $w.heads -text [mc "Branches"]
listbox $w.heads.l \
-height 10 \
-width 70 \
@@ -96,7 +96,7 @@ constructor dialog {} {
-anchor w \
-justify left
button $w.heads.footer.rescan \
- -text {Rescan} \
+ -text [mc "Rescan"] \
-command [cb _rescan]
pack $w.heads.footer.status -side left -fill x
pack $w.heads.footer.rescan -side right
@@ -106,9 +106,9 @@ constructor dialog {} {
pack $w.heads.l -side left -fill both -expand 1
pack $w.heads -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.validate -text {Delete Only If}
+ labelframe $w.validate -text [mc "Delete Only If"]
radiobutton $w.validate.head_r \
- -text {Merged Into:} \
+ -text [mc "Merged Into:"] \
-value head \
-variable @checktype
set head_m [tk_optionMenu $w.validate.head_m @check_head {}]
@@ -116,7 +116,7 @@ constructor dialog {} {
trace add variable @check_head write [cb _write_check_head]
grid $w.validate.head_r $w.validate.head_m -sticky w
radiobutton $w.validate.always_r \
- -text {Always (Do not perform merge checks)} \
+ -text [mc "Always (Do not perform merge checks)"] \
-value always \
-variable @checktype
grid $w.validate.always_r -columnspan 2 -sticky w
@@ -149,7 +149,7 @@ method _delete {} {
-type ok \
-title [wm title $w] \
-parent $w \
- -message "A branch is required for 'Merged Into'."
+ -message [mc "A branch is required for 'Merged Into'."]
return
}
set crev $full_cache("$cache\nrefs/heads/$check_head")
@@ -181,14 +181,12 @@ method _delete {} {
}
if {$not_merged ne {}} {
- set msg "The following branches are not completely merged into $check_head:
+ set msg [mc "The following branches are not completely merged into %s:
- - [join $not_merged "\n - "]"
+ - %s" $check_head [join $not_merged "\n - "]]
if {$need_fetch} {
- append msg "
-
-One or more of the merge tests failed because you have not fetched the necessary commits. Try fetching from $uri first."
+ append msg "\n\n" [mc "One or more of the merge tests failed because you have not fetched the necessary commits. Try fetching from %s first." $uri]
}
tk_messageBox \
@@ -206,7 +204,7 @@ One or more of the merge tests failed because you have not fetched the necessary
-type ok \
-title [wm title $w] \
-parent $w \
- -message "Please select one or more branches to delete."
+ -message [mc "Please select one or more branches to delete."]
return
}
@@ -215,9 +213,9 @@ One or more of the merge tests failed because you have not fetched the necessary
-type yesno \
-title [wm title $w] \
-parent $w \
- -message {Recovering deleted branches is difficult.
+ -message [mc "Recovering deleted branches is difficult.
-Delete the selected branches?}] ne yes} {
+Delete the selected branches?"]] ne yes} {
return
}
@@ -225,7 +223,7 @@ Delete the selected branches?}] ne yes} {
set cons [console::new \
"push $uri" \
- "Deleting branches from $uri"]
+ [mc "Deleting branches from %s" $uri]]
console::exec $cons $push_cmd
}
@@ -285,12 +283,12 @@ method _load {cache uri} {
$w.heads.l conf -state disabled
set head_list [list]
set full_list [list]
- set status {No repository selected.}
+ set status [mc "No repository selected."]
return
}
if {[catch {set x $cached($cache)}]} {
- set status "Scanning $uri..."
+ set status [mc "Scanning %s..." $uri]
$w.heads.l conf -state disabled
set head_list [list]
set full_list [list]
diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl
index c36be2f3c..38c3151b0 100644
--- a/git-gui/lib/shortcut.tcl
+++ b/git-gui/lib/shortcut.tcl
@@ -2,28 +2,22 @@
# Copyright (C) 2006, 2007 Shawn Pearce
proc do_windows_shortcut {} {
- global argv0
-
set fn [tk_getSaveFile \
-parent . \
- -title "[appname] ([reponame]): Create Desktop Icon" \
- -initialfile "Git [reponame].bat"]
+ -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
+ -initialfile "Git [reponame].lnk"]
if {$fn != {}} {
- if {[file extension $fn] ne {.bat}} {
- set fn ${fn}.bat
+ if {[file extension $fn] ne {.lnk}} {
+ set fn ${fn}.lnk
}
if {[catch {
- set ge [file normalize [file dirname $::_git]]
- set fd [open $fn w]
- puts $fd "@ECHO Entering [reponame]"
- puts $fd "@ECHO Starting git-gui... please wait..."
- puts $fd "@SET PATH=$ge;%PATH%"
- puts $fd "@SET GIT_DIR=[file normalize [gitdir]]"
- puts -nonewline $fd "@\"[info nameofexecutable]\""
- puts $fd " \"[file normalize $argv0]\""
- close $fd
+ win32_create_lnk $fn [list \
+ [info nameofexecutable] \
+ [file normalize $::argv0] \
+ ] \
+ [file dirname [file normalize [gitdir]]]
} err]} {
- error_popup "Cannot write script:\n\n$err"
+ error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
}
}
}
@@ -42,15 +36,14 @@ proc do_cygwin_shortcut {} {
}
set fn [tk_getSaveFile \
-parent . \
- -title "[appname] ([reponame]): Create Desktop Icon" \
+ -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialdir $desktop \
- -initialfile "Git [reponame].bat"]
+ -initialfile "Git [reponame].lnk"]
if {$fn != {}} {
- if {[file extension $fn] ne {.bat}} {
- set fn ${fn}.bat
+ if {[file extension $fn] ne {.lnk}} {
+ set fn ${fn}.lnk
}
if {[catch {
- set fd [open $fn w]
set sh [exec cygpath \
--windows \
--absolute \
@@ -59,19 +52,13 @@ proc do_cygwin_shortcut {} {
--unix \
--absolute \
$argv0]
- set gd [exec cygpath \
- --unix \
- --absolute \
- [gitdir]]
- puts $fd "@ECHO Entering [reponame]"
- puts $fd "@ECHO Starting git-gui... please wait..."
- puts -nonewline $fd "@\"$sh\" --login -c \""
- puts -nonewline $fd "GIT_DIR=[sq $gd]"
- puts -nonewline $fd " [sq $me]"
- puts $fd " &\""
- close $fd
+ win32_create_lnk $fn [list \
+ $sh -c \
+ "CHERE_INVOKING=1 source /etc/profile;[sq $me]" \
+ ] \
+ [file dirname [file normalize [gitdir]]]
} err]} {
- error_popup "Cannot write script:\n\n$err"
+ error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
}
}
}
@@ -81,7 +68,7 @@ proc do_macosx_app {} {
set fn [tk_getSaveFile \
-parent . \
- -title "[appname] ([reponame]): Create Desktop Icon" \
+ -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialdir [file join $env(HOME) Desktop] \
-initialfile "Git [reponame].app"]
if {$fn != {}} {
@@ -146,7 +133,7 @@ proc do_macosx_app {} {
file attributes $exe -permissions u+x,g+x,o+x
} err]} {
- error_popup "Cannot write icon:\n\n$err"
+ error_popup [strcat [mc "Cannot write icon:"] "\n\n$err"]
}
}
}
diff --git a/git-gui/lib/status_bar.tcl b/git-gui/lib/status_bar.tcl
index 3bf79eb6e..51d417755 100644
--- a/git-gui/lib/status_bar.tcl
+++ b/git-gui/lib/status_bar.tcl
@@ -6,6 +6,7 @@ class status_bar {
field w ; # our own window path
field w_l ; # text widget we draw messages into
field w_c ; # canvas we draw a progress bar into
+field c_pack ; # script to pack the canvas with
field status {}; # single line of text we show
field prefix {}; # text we format into status
field units {}; # unit of progress
@@ -24,6 +25,29 @@ constructor new {path} {
-anchor w \
-justify left
pack $w_l -side left
+ set c_pack [cb _oneline_pack]
+
+ bind $w <Destroy> [cb _delete %W]
+ return $this
+}
+
+method _oneline_pack {} {
+ $w_c conf -width 100
+ pack $w_c -side right
+}
+
+constructor two_line {path} {
+ set w $path
+ set w_l $w.l
+ set w_c $w.c
+
+ frame $w
+ label $w_l \
+ -textvariable @status \
+ -anchor w \
+ -justify left
+ pack $w_l -anchor w -fill x
+ set c_pack [list pack $w_c -fill x]
bind $w <Destroy> [cb _delete %W]
return $this
@@ -34,13 +58,12 @@ method start {msg uds} {
$w_c coords bar 0 0 0 20
} else {
canvas $w_c \
- -width 100 \
-height [expr {int([winfo reqheight $w_l] * 0.6)}] \
-borderwidth 1 \
-relief groove \
-highlightt 0
$w_c create rectangle 0 0 0 20 -tags bar -fill navy
- pack $w_c -side right
+ eval $c_pack
}
set status $msg
@@ -53,11 +76,16 @@ method update {have total} {
set pdone 0
if {$total > 0} {
set pdone [expr {100 * $have / $total}]
+ set cdone [expr {[winfo width $w_c] * $have / $total}]
}
- set status [format "%s ... %i of %i %s (%2i%%)" \
- $prefix $have $total $units $pdone]
- $w_c coords bar 0 0 $pdone 20
+ set prec [string length [format %i $total]]
+ set status [mc "%s ... %*i of %*i %s (%3i%%)" \
+ $prefix \
+ $prec $have \
+ $prec $total \
+ $units $pdone]
+ $w_c coords bar 0 0 $cdone 20
}
method update_meter {buf} {
diff --git a/git-gui/lib/transport.tcl b/git-gui/lib/transport.tcl
index 3a22bd40d..8e6a9d0a6 100644
--- a/git-gui/lib/transport.tcl
+++ b/git-gui/lib/transport.tcl
@@ -3,8 +3,8 @@
proc fetch_from {remote} {
set w [console::new \
- "fetch $remote" \
- "Fetching new changes from $remote"]
+ [mc "fetch %s" $remote] \
+ [mc "Fetching new changes from %s" $remote]]
set cmds [list]
lappend cmds [list exec git fetch $remote]
if {[is_config_true gui.pruneduringfetch]} {
@@ -15,15 +15,15 @@ proc fetch_from {remote} {
proc prune_from {remote} {
set w [console::new \
- "remote prune $remote" \
- "Pruning tracking branches deleted from $remote"]
+ [mc "remote prune %s" $remote] \
+ [mc "Pruning tracking branches deleted from %s" $remote]]
console::exec $w [list git remote prune $remote]
}
proc push_to {remote} {
set w [console::new \
- "push $remote" \
- "Pushing changes to $remote"]
+ [mc "push %s" $remote] \
+ [mc "Pushing changes to %s" $remote]]
set cmd [list git push]
lappend cmd -v
lappend cmd $remote
@@ -32,6 +32,7 @@ proc push_to {remote} {
proc start_push_anywhere_action {w} {
global push_urltype push_remote push_url push_thin push_tags
+ global push_force
set r_url {}
switch -- $push_urltype {
@@ -45,6 +46,9 @@ proc start_push_anywhere_action {w} {
if {$push_thin} {
lappend cmd --thin
}
+ if {$push_force} {
+ lappend cmd --force
+ }
if {$push_tags} {
lappend cmd --tags
}
@@ -64,8 +68,8 @@ proc start_push_anywhere_action {w} {
}
set cons [console::new \
- "push $r_url" \
- "Pushing $cnt $unit to $r_url"]
+ [mc "push %s" $r_url] \
+ [mc "Pushing %s %s to %s" $cnt $unit $r_url]]
console::exec $cons $cmd
destroy $w
}
@@ -76,26 +80,27 @@ trace add variable push_remote write \
proc do_push_anywhere {} {
global all_remotes current_branch
global push_urltype push_remote push_url push_thin push_tags
+ global push_force
set w .push_setup
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
- label $w.header -text {Push Branches} -font font_uibold
+ label $w.header -text [mc "Push Branches"] -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
- button $w.buttons.create -text Push \
+ button $w.buttons.create -text [mc Push] \
-default active \
-command [list start_push_anywhere_action $w]
pack $w.buttons.create -side right
- button $w.buttons.cancel -text {Cancel} \
+ button $w.buttons.cancel -text [mc "Cancel"] \
-default normal \
-command [list destroy $w]
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
- labelframe $w.source -text {Source Branches}
+ labelframe $w.source -text [mc "Source Branches"]
listbox $w.source.l \
-height 10 \
-width 70 \
@@ -112,10 +117,10 @@ proc do_push_anywhere {} {
pack $w.source.l -side left -fill both -expand 1
pack $w.source -fill both -expand 1 -pady 5 -padx 5
- labelframe $w.dest -text {Destination Repository}
+ labelframe $w.dest -text [mc "Destination Repository"]
if {$all_remotes ne {}} {
radiobutton $w.dest.remote_r \
- -text {Remote:} \
+ -text [mc "Remote:"] \
-value remote \
-variable push_urltype
eval tk_optionMenu $w.dest.remote_m push_remote $all_remotes
@@ -130,7 +135,7 @@ proc do_push_anywhere {} {
set push_urltype url
}
radiobutton $w.dest.url_r \
- -text {Arbitrary URL:} \
+ -text [mc "Arbitrary URL:"] \
-value url \
-variable push_urltype
entry $w.dest.url_t \
@@ -150,25 +155,30 @@ proc do_push_anywhere {} {
grid columnconfigure $w.dest 1 -weight 1
pack $w.dest -anchor nw -fill x -pady 5 -padx 5
- labelframe $w.options -text {Transfer Options}
+ labelframe $w.options -text [mc "Transfer Options"]
+ checkbutton $w.options.force \
+ -text [mc "Force overwrite existing branch (may discard changes)"] \
+ -variable push_force
+ grid $w.options.force -columnspan 2 -sticky w
checkbutton $w.options.thin \
- -text {Use thin pack (for slow network connections)} \
+ -text [mc "Use thin pack (for slow network connections)"] \
-variable push_thin
grid $w.options.thin -columnspan 2 -sticky w
checkbutton $w.options.tags \
- -text {Include tags} \
+ -text [mc "Include tags"] \
-variable push_tags
grid $w.options.tags -columnspan 2 -sticky w
grid columnconfigure $w.options 1 -weight 1
pack $w.options -anchor nw -fill x -pady 5 -padx 5
set push_url {}
+ set push_force 0
set push_thin 0
set push_tags 0
bind $w <Visibility> "grab $w; focus $w.buttons.create"
bind $w <Key-Escape> "destroy $w"
bind $w <Key-Return> [list start_push_anywhere_action $w]
- wm title $w "[appname] ([reponame]): Push"
+ wm title $w [append "[appname] ([reponame]): " [mc "Push"]]
tkwait window $w
}
diff --git a/git-gui/lib/win32.tcl b/git-gui/lib/win32.tcl
new file mode 100644
index 000000000..d7f93d045
--- /dev/null
+++ b/git-gui/lib/win32.tcl
@@ -0,0 +1,26 @@
+# git-gui Misc. native Windows 32 support
+# Copyright (C) 2007 Shawn Pearce
+
+proc win32_read_lnk {lnk_path} {
+ return [exec cscript.exe \
+ /E:jscript \
+ /nologo \
+ [file join $::oguilib win32_shortcut.js] \
+ $lnk_path]
+}
+
+proc win32_create_lnk {lnk_path lnk_exec lnk_dir} {
+ global oguilib
+
+ set lnk_args [lrange $lnk_exec 1 end]
+ set lnk_exec [lindex $lnk_exec 0]
+
+ eval [list exec wscript.exe \
+ /E:jscript \
+ /nologo \
+ [file join $oguilib win32_shortcut.js] \
+ $lnk_path \
+ [file join $oguilib git-gui.ico] \
+ $lnk_dir \
+ $lnk_exec] $lnk_args
+}
diff --git a/git-gui/lib/win32_shortcut.js b/git-gui/lib/win32_shortcut.js
new file mode 100644
index 000000000..117923f88
--- /dev/null
+++ b/git-gui/lib/win32_shortcut.js
@@ -0,0 +1,34 @@
+// git-gui Windows shortcut support
+// Copyright (C) 2007 Shawn Pearce
+
+var WshShell = WScript.CreateObject("WScript.Shell");
+var argv = WScript.Arguments;
+var argi = 0;
+var lnk_path = argv.item(argi++);
+var ico_path = argi < argv.length ? argv.item(argi++) : undefined;
+var dir_path = argi < argv.length ? argv.item(argi++) : undefined;
+var lnk_exec = argi < argv.length ? argv.item(argi++) : undefined;
+var lnk_args = '';
+while (argi < argv.length) {
+ var s = argv.item(argi++);
+ if (lnk_args != '')
+ lnk_args += ' ';
+ if (s.indexOf(' ') >= 0) {
+ lnk_args += '"';
+ lnk_args += s;
+ lnk_args += '"';
+ } else {
+ lnk_args += s;
+ }
+}
+
+var lnk = WshShell.CreateShortcut(lnk_path);
+if (argv.length == 1) {
+ WScript.echo(lnk.TargetPath);
+} else {
+ lnk.TargetPath = lnk_exec;
+ lnk.Arguments = lnk_args;
+ lnk.IconLocation = ico_path + ", 0";
+ lnk.WorkingDirectory = dir_path;
+ lnk.Save();
+}
diff --git a/git-gui/macosx/AppMain.tcl b/git-gui/macosx/AppMain.tcl
new file mode 100644
index 000000000..41ca08e2b
--- /dev/null
+++ b/git-gui/macosx/AppMain.tcl
@@ -0,0 +1,22 @@
+set gitexecdir {@@gitexecdir@@}
+set gitguilib {@@GITGUI_LIBDIR@@}
+set env(PATH) "$gitexecdir:$env(PATH)"
+
+if {[string first -psn [lindex $argv 0]] == 0} {
+ lset argv 0 [file join $gitexecdir git-gui]
+}
+
+if {[file tail [lindex $argv 0]] eq {gitk}} {
+ set argv0 [file join $gitexecdir gitk]
+ set AppMain_source $argv0
+} else {
+ set argv0 [file join $gitexecdir [file tail [lindex $argv 0]]]
+ set AppMain_source [file join $gitguilib git-gui.tcl]
+ if {[pwd] eq {/}} {
+ cd $env(HOME)
+ }
+}
+
+unset gitexecdir gitguilib
+set argv [lrange $argv 1 end]
+source $AppMain_source
diff --git a/git-gui/macosx/Info.plist b/git-gui/macosx/Info.plist
new file mode 100644
index 000000000..99913ec57
--- /dev/null
+++ b/git-gui/macosx/Info.plist
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>Wish</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Git Gui @@GITGUI_VERSION@@ © 2006-2007 Shawn Pearce, et. al.</string>
+ <key>CFBundleIconFile</key>
+ <string>git-gui.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>cz.or.repo.git-gui</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>Git Gui</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>@@GITGUI_VERSION@@</string>
+ <key>CFBundleSignature</key>
+ <string>GITg</string>
+ <key>CFBundleVersion</key>
+ <string>@@GITGUI_VERSION@@</string>
+</dict>
+</plist>
diff --git a/git-gui/macosx/git-gui.icns b/git-gui/macosx/git-gui.icns
new file mode 100644
index 000000000..77d88a77a
--- /dev/null
+++ b/git-gui/macosx/git-gui.icns
Binary files differ
diff --git a/git-gui/po/.gitignore b/git-gui/po/.gitignore
new file mode 100644
index 000000000..a89cf4496
--- /dev/null
+++ b/git-gui/po/.gitignore
@@ -0,0 +1,2 @@
+*.msg
+*~
diff --git a/git-gui/po/README b/git-gui/po/README
new file mode 100644
index 000000000..9d8b7364f
--- /dev/null
+++ b/git-gui/po/README
@@ -0,0 +1,209 @@
+Localizing git-gui for your language
+====================================
+
+This short note is to help you, who reads and writes English and your
+own language, help us getting git-gui localized for more languages. It
+does not try to be a comprehensive manual of GNU gettext, which is the
+i18n framework we use, but tries to help you get started by covering the
+basics and how it is used in this project.
+
+1. Getting started.
+
+You would first need to have a working "git". Your distribution may
+have it as "git-core" package (do not get "GNU Interactive Tools" --
+that is a different "git"). You would also need GNU gettext toolchain
+to test the resulting translation out. Although you can work on message
+translation files with a regular text editor, it is a good idea to have
+specialized so-called "po file editors" (e.g. emacs po-mode, KBabel,
+poedit, GTranslator --- any of them would work well). Please install
+them.
+
+You would then need to clone the git-gui internationalization project
+repository, so that you can work on it:
+
+ $ git clone mob@repo.or.cz:/srv/git/git-gui/git-gui-i18n.git/
+ $ cd git-gui-i18n
+ $ git checkout --track -b mob origin/mob
+ $ git config remote.origin.push mob
+
+The "git checkout" command creates a 'mob' branch from upstream's
+corresponding branch and makes it your current branch. You will be
+working on this branch.
+
+The "git config" command records in your repository configuration file
+that you would push "mob" branch to the upstream when you say "git
+push".
+
+
+2. Starting a new language.
+
+In the git-gui-i18n directory is a po/ subdirectory. It has a
+handful files whose names end with ".po". Is there a file that has
+messages in your language?
+
+If you do not know what your language should be named, you need to find
+it. This currently follows ISO 639-1 two letter codes:
+
+ http://www.loc.gov/standards/iso639-2/php/code_list.php
+
+For example, if you are preparing a translation for Afrikaans, the
+language code is "af". If there already is a translation for your
+language, you do not have to perform any step in this section, but keep
+reading, because we are covering the basics.
+
+If you did not find your language, you would need to start one yourself.
+Copy po/git-gui.pot file to po/af.po (replace "af" with the code for
+your language). Edit the first several lines to match existing *.po
+files to make it clear this is a translation table for git-gui project,
+and you are the primary translator. The result of your editing would
+look something like this:
+
+ # Translation of git-gui to Afrikaans
+ # Copyright (C) 2007 Shawn Pearce
+ # This file is distributed under the same license as the git-gui package.
+ # YOUR NAME <YOUR@E-MAIL.ADDRESS>, 2007.
+ #
+ #, fuzzy
+ msgid ""
+ msgstr ""
+ "Project-Id-Version: git-gui\n"
+ "Report-Msgid-Bugs-To: \n"
+ "POT-Creation-Date: 2007-07-24 22:19+0300\n"
+ "PO-Revision-Date: 2007-07-25 18:00+0900\n"
+ "Last-Translator: YOUR NAME <YOUR@E-MAIL.ADDRESS>\n"
+ "Language-Team: Afrikaans\n"
+ "MIME-Version: 1.0\n"
+ "Content-Type: text/plain; charset=UTF-8\n"
+ "Content-Transfer-Encoding: 8bit\n"
+
+You will find many pairs of a "msgid" line followed by a "msgstr" line.
+These pairs define how messages in git-gui application are translated to
+your language. Your primarily job is to fill in the empty double quote
+pairs on msgstr lines with the translation of the strings on their
+matching msgid lines. A few tips:
+
+ - Control characters, such as newlines, are written in backslash
+ sequence similar to string literals in the C programming language.
+ When the string given on a msgid line has such a backslash sequence,
+ you would typically want to have corresponding ones in the string on
+ your msgstr line.
+
+ - Some messages contain an optional context indicator at the end,
+ for example "@@noun" or "@@verb". This indicator allows the
+ software to select the correct translation depending upon the use.
+ The indicator is not actually part of the message and will not
+ be shown to the end-user.
+
+ If your language does not require a different translation you
+ will still need to translate both messages.
+
+ - Often the messages being translated are format strings given to
+ "printf()"-like functions. Make sure "%s", "%d", and "%%" in your
+ translated messages match the original.
+
+ When you have to change the order of words, you can add "<number>\$"
+ between '%' and the conversion ('s', 'd', etc.) to say "<number>-th
+ parameter to the format string is used at this point". For example,
+ if the original message is like this:
+
+ "Length is %d, Weight is %d"
+
+ and if for whatever reason your translation needs to say weight first
+ and then length, you can say something like:
+
+ "WEIGHT IS %2\$d, LENGTH IS %1\$d"
+
+ The reason you need a backslash before dollar sign is because
+ this is a double quoted string in Tcl language, and without
+ it the letter introduces a variable interpolation, which you
+ do not want here.
+
+ - A long message can be split across multiple lines by ending the
+ string with a double quote, and starting another string on the next
+ line with another double quote. They will be concatenated in the
+ result. For example:
+
+ #: lib/remote_branch_delete.tcl:189
+ #, tcl-format
+ msgid ""
+ "One or more of the merge tests failed because you have not fetched the "
+ "necessary commits. Try fetching from %s first."
+ msgstr ""
+ "HERE YOU WILL WRITE YOUR TRANSLATION OF THE ABOVE LONG "
+ "MESSAGE IN YOUR LANGUAGE."
+
+You can test your translation by running "make install", which would
+create po/af.msg file and installs the result, and then running the
+resulting git-gui under your locale:
+
+ $ make install
+ $ LANG=af git-gui
+
+There is a trick to test your translation without first installing:
+
+ $ make
+ $ LANG=af ./git-gui.sh
+
+When you are satisfied with your translation, commit your changes, and
+push it back to the 'mob' branch:
+
+ $ edit po/af.po
+ ... be sure to update Last-Translator: and
+ ... PO-Revision-Date: lines.
+ $ git add po/af.po
+ $ git commit -m 'Started Afrikaans translation.'
+ $ git push
+
+
+3. Updating your translation.
+
+There may already be a translation for your language, and you may want
+to contribute an update. This may be because you would want to improve
+the translation of existing messages, or because the git-gui software
+itself was updated and there are new messages that need translation.
+
+In any case, make sure you are up-to-date before starting your work:
+
+ $ git pull
+
+In the former case, you will edit po/af.po (again, replace "af" with
+your language code), and after testing and updating the Last-Translator:
+and PO-Revision-Date: lines, "add/commit/push" as in the previous
+section.
+
+By comparing "POT-Creation-Date:" line in po/git-gui.pot file and
+po/af.po file, you can tell if there are new messages that need to be
+translated. You would need the GNU gettext package to perform this
+step.
+
+ $ msgmerge -U po/af.po po/git-gui.pot
+
+[NEEDSWORK: who is responsible for updating po/git-gui.pot file by
+running xgettext? IIRC, Christian recommended against running it
+nilly-willy because it can become a source of unnecessary merge
+conflicts. Perhaps we should mention something like "
+
+The po/git-gui.pot file is updated by the internationalization
+coordinator from time to time. You _could_ update it yourself, but
+translators are discouraged from doing so because we would want all
+language teams to be working off of the same version of git-gui.pot.
+
+" here?]
+
+This updates po/af.po (again, replace "af" with your language
+code) so that it contains msgid lines (i.e. the original) that
+your translation did not have before. There are a few things to
+watch out for:
+
+ - The original text in English of an older message you already
+ translated might have been changed. You will notice a comment line
+ that begins with "#, fuzzy" in front of such a message. msgmerge
+ tool made its best effort to match your old translation with the
+ message from the updated software, but you may find cases that it
+ matched your old translated message to a new msgid and the pairing
+ does not make any sense -- you would need to fix them, and then
+ remove the "#, fuzzy" line from the message (your fixed translation
+ of the message will not be used before you remove the marker).
+
+ - New messages added to the software will have msgstr lines with empty
+ strings. You would need to translate them.
diff --git a/git-gui/po/de.po b/git-gui/po/de.po
new file mode 100644
index 000000000..3df30edb8
--- /dev/null
+++ b/git-gui/po/de.po
@@ -0,0 +1,1878 @@
+# Translation of git-gui to German.
+# Copyright (C) 2007 Shawn Pearce, et al.
+# This file is distributed under the same license as the git package.
+# Christian Stimming <stimming@tuhh.de>, 2007
+#
+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"
+"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
+msgid "git-gui: fatal error"
+msgstr "git-gui: Programmfehler"
+
+#: git-gui.sh:551
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Ungültige Zeichensatz-Angabe in %s:"
+
+#: git-gui.sh:576
+msgid "Main Font"
+msgstr "Programmschriftart"
+
+#: git-gui.sh:577
+msgid "Diff/Console Font"
+msgstr "Vergleich-Schriftart"
+
+#: git-gui.sh:591
+msgid "Cannot find git in PATH."
+msgstr "Git kann im PATH nicht gefunden werden."
+
+#: git-gui.sh:618
+msgid "Cannot parse Git version string:"
+msgstr "Git Versionsangabe kann nicht erkannt werden:"
+
+#: git-gui.sh:636
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Die Version von Git kann nicht bestimmt werden.\n"
+"\n"
+"»%s« behauptet, es sei Version »%s«.\n"
+"\n"
+"%s benötigt mindestens Git 1.5.0 oder höher.\n"
+"\n"
+"Soll angenommen werden, »%s« sei Version 1.5.0?\n"
+
+#: git-gui.sh:874
+msgid "Git directory not found:"
+msgstr "Git-Verzeichnis nicht gefunden:"
+
+#: git-gui.sh:881
+msgid "Cannot move to top of working directory:"
+msgstr ""
+"Es konnte nicht in das oberste Verzeichnis der Arbeitskopie gewechselt "
+"werden:"
+
+#: git-gui.sh:888
+msgid "Cannot use funny .git directory:"
+msgstr "Unerwartete Struktur des .git Verzeichnis:"
+
+#: git-gui.sh:893
+msgid "No working directory"
+msgstr "Kein Arbeitsverzeichnis"
+
+#: git-gui.sh:1040
+msgid "Refreshing file status..."
+msgstr "Dateistatus aktualisieren..."
+
+#: git-gui.sh:1105
+msgid "Scanning for modified files ..."
+msgstr "Nach geänderten Dateien suchen..."
+
+#: git-gui.sh:1280 lib/browser.tcl:245
+msgid "Ready."
+msgstr "Bereit."
+
+#: git-gui.sh:1546
+msgid "Unmodified"
+msgstr "Unverändert"
+
+#: git-gui.sh:1548
+msgid "Modified, not staged"
+msgstr "Verändert, nicht bereitgestellt"
+
+#: git-gui.sh:1549 git-gui.sh:1554
+msgid "Staged for commit"
+msgstr "Bereitgestellt zum Eintragen"
+
+#: git-gui.sh:1550 git-gui.sh:1555
+msgid "Portions staged for commit"
+msgstr "Teilweise bereitgestellt zum Eintragen"
+
+#: git-gui.sh:1551 git-gui.sh:1556
+msgid "Staged for commit, missing"
+msgstr "Bereitgestellt zum Eintragen, fehlend"
+
+#: git-gui.sh:1553
+msgid "Untracked, not staged"
+msgstr "Nicht unter Versionskontrolle, nicht bereitgestellt"
+
+#: git-gui.sh:1558
+msgid "Missing"
+msgstr "Fehlend"
+
+#: git-gui.sh:1559
+msgid "Staged for removal"
+msgstr "Bereitgestellt zum Löschen"
+
+#: git-gui.sh:1560
+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
+msgid "Requires merge resolution"
+msgstr "Konfliktauflösung nötig"
+
+#: git-gui.sh:1600
+msgid "Starting gitk... please wait..."
+msgstr "Gitk wird gestartet... bitte warten."
+
+#: git-gui.sh:1609
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+"Gitk kann nicht gestartet werden:\n"
+"\n"
+"%s existiert nicht"
+
+#: git-gui.sh:1809 lib/choose_repository.tcl:35
+msgid "Repository"
+msgstr "Projektarchiv"
+
+#: git-gui.sh:1810
+msgid "Edit"
+msgstr "Bearbeiten"
+
+#: git-gui.sh:1812 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr "Zweig"
+
+#: git-gui.sh:1815 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
+msgid "Merge"
+msgstr "Zusammenführen"
+
+#: git-gui.sh:1819 lib/choose_rev.tcl:556
+msgid "Remote"
+msgstr "Andere Archive"
+
+#: git-gui.sh:1828
+msgid "Browse Current Branch's Files"
+msgstr "Aktuellen Zweig durchblättern"
+
+#: git-gui.sh:1832
+msgid "Browse Branch Files..."
+msgstr "Einen Zweig durchblättern..."
+
+#: git-gui.sh:1837
+msgid "Visualize Current Branch's History"
+msgstr "Aktuellen Zweig darstellen"
+
+#: git-gui.sh:1841
+msgid "Visualize All Branch History"
+msgstr "Alle Zweige darstellen"
+
+#: git-gui.sh:1848
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "Zweig »%s« durchblättern"
+
+#: git-gui.sh:1850
+#, tcl-format
+msgid "Visualize %s's History"
+msgstr "Historie von »%s« darstellen"
+
+#: git-gui.sh:1855 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr "Datenbankstatistik"
+
+#: git-gui.sh:1858 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "Datenbank komprimieren"
+
+#: git-gui.sh:1861
+msgid "Verify Database"
+msgstr "Datenbank überprüfen"
+
+#: git-gui.sh:1868 git-gui.sh:1872 git-gui.sh:1876 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
+msgid "Quit"
+msgstr "Beenden"
+
+#: git-gui.sh:1888
+msgid "Undo"
+msgstr "Rückgängig"
+
+#: git-gui.sh:1891
+msgid "Redo"
+msgstr "Wiederholen"
+
+#: git-gui.sh:1895 git-gui.sh:2388
+msgid "Cut"
+msgstr "Ausschneiden"
+
+#: git-gui.sh:1898 git-gui.sh:2391 git-gui.sh:2462 git-gui.sh:2534
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr "Kopieren"
+
+#: git-gui.sh:1901 git-gui.sh:2394
+msgid "Paste"
+msgstr "Einfügen"
+
+#: git-gui.sh:1904 git-gui.sh:2397 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
+msgid "Select All"
+msgstr "Alle auswählen"
+
+#: git-gui.sh:1917
+msgid "Create..."
+msgstr "Erstellen..."
+
+#: git-gui.sh:1923
+msgid "Checkout..."
+msgstr "Umstellen..."
+
+#: git-gui.sh:1929
+msgid "Rename..."
+msgstr "Umbenennen..."
+
+#: git-gui.sh:1934 git-gui.sh:2033
+msgid "Delete..."
+msgstr "Löschen..."
+
+#: git-gui.sh:1939
+msgid "Reset..."
+msgstr "Zurücksetzen..."
+
+#: git-gui.sh:1951 git-gui.sh:2335
+msgid "New Commit"
+msgstr "Neue Version"
+
+#: git-gui.sh:1959 git-gui.sh:2342
+msgid "Amend Last Commit"
+msgstr "Letzte Version nachbessern"
+
+#: git-gui.sh:1968 git-gui.sh:2302 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "Neu laden"
+
+#: git-gui.sh:1974
+msgid "Stage To Commit"
+msgstr "Zum Eintragen bereitstellen"
+
+#: git-gui.sh:1979
+msgid "Stage Changed Files To Commit"
+msgstr "Geänderte Dateien zum Eintragen bereitstellen"
+
+#: git-gui.sh:1985
+msgid "Unstage From Commit"
+msgstr "Aus der Bereitstellung herausnehmen"
+
+#: git-gui.sh:1990 lib/index.tcl:352
+msgid "Revert Changes"
+msgstr "Änderungen revidieren"
+
+#: git-gui.sh:1997 git-gui.sh:2314 git-gui.sh:2412
+msgid "Sign Off"
+msgstr "Abzeichnen"
+
+#: git-gui.sh:2001 git-gui.sh:2318
+msgid "Commit@@verb"
+msgstr "Eintragen"
+
+#: git-gui.sh:2012
+msgid "Local Merge..."
+msgstr "Lokales Zusammenführen..."
+
+#: git-gui.sh:2017
+msgid "Abort Merge..."
+msgstr "Zusammenführen abbrechen..."
+
+#: git-gui.sh:2029
+msgid "Push..."
+msgstr "Versenden..."
+
+#: git-gui.sh:2040 lib/choose_repository.tcl:40
+msgid "Apple"
+msgstr "Apple"
+
+#: git-gui.sh:2043 git-gui.sh:2065 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
+msgid "Preferences..."
+msgstr "Einstellungen..."
+
+#: git-gui.sh:2055 git-gui.sh:2580
+msgid "Options..."
+msgstr "Optionen..."
+
+#: git-gui.sh:2061 lib/choose_repository.tcl:46
+msgid "Help"
+msgstr "Hilfe"
+
+#: git-gui.sh:2102
+msgid "Online Documentation"
+msgstr "Online-Dokumentation"
+
+#: git-gui.sh:2186
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr ""
+
+#: git-gui.sh:2219
+msgid "Current Branch:"
+msgstr "Aktueller Zweig:"
+
+#: git-gui.sh:2240
+msgid "Staged Changes (Will Commit)"
+msgstr "Bereitgestellte Änderungen (zum Eintragen)"
+
+#: git-gui.sh:2259
+msgid "Unstaged Changes"
+msgstr "Nicht bereitgestellte Änderungen"
+
+#: git-gui.sh:2308
+msgid "Stage Changed"
+msgstr "Alles bereitstellen"
+
+#: git-gui.sh:2324 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "Versenden"
+
+#: git-gui.sh:2354
+msgid "Initial Commit Message:"
+msgstr "Erste Versionsbeschreibung:"
+
+#: git-gui.sh:2355
+msgid "Amended Commit Message:"
+msgstr "Nachgebesserte Versionsbeschreibung:"
+
+#: git-gui.sh:2356
+msgid "Amended Initial Commit Message:"
+msgstr "Nachgebesserte erste Versionsbeschreibung:"
+
+#: git-gui.sh:2357
+msgid "Amended Merge Commit Message:"
+msgstr "Nachgebesserte Zusammenführungs-Versionsbeschreibung:"
+
+#: git-gui.sh:2358
+msgid "Merge Commit Message:"
+msgstr "Zusammenführungs-Versionsbeschreibung:"
+
+#: git-gui.sh:2359
+msgid "Commit Message:"
+msgstr "Versionsbeschreibung:"
+
+#: git-gui.sh:2404 git-gui.sh:2542 lib/console.tcl:71
+msgid "Copy All"
+msgstr "Alle kopieren"
+
+#: git-gui.sh:2428 lib/blame.tcl:104
+msgid "File:"
+msgstr "Datei:"
+
+#: git-gui.sh:2530
+msgid "Refresh"
+msgstr "Aktualisieren"
+
+#: git-gui.sh:2551
+msgid "Apply/Reverse Hunk"
+msgstr "Änderung anwenden/umkehren"
+
+#: git-gui.sh:2557
+msgid "Decrease Font Size"
+msgstr "Schriftgröße verkleinern"
+
+#: git-gui.sh:2561
+msgid "Increase Font Size"
+msgstr "Schriftgröße vergrößern"
+
+#: git-gui.sh:2566
+msgid "Show Less Context"
+msgstr "Weniger Kontext anzeigen"
+
+#: git-gui.sh:2573
+msgid "Show More Context"
+msgstr "Mehr Kontext anzeigen"
+
+#: git-gui.sh:2587
+msgid "Unstage Hunk From Commit"
+msgstr "Aus der Bereitstellung herausnehmen"
+
+#: git-gui.sh:2589
+msgid "Stage Hunk For Commit"
+msgstr "In die Bereitstellung hinzufügen"
+
+#: git-gui.sh:2608
+msgid "Initializing..."
+msgstr "Initialisieren..."
+
+#: git-gui.sh:2699
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+
+#: git-gui.sh:2729
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+
+#: git-gui.sh:2734
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui - eine grafische Oberfläche für Git."
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr "Datei-Browser"
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr "Version:"
+
+#: lib/blame.tcl:249
+msgid "Copy Commit"
+msgstr "Version kopieren"
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr "%s lesen..."
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr ""
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr ""
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr ""
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr ""
+
+#: lib/blame.tcl:731
+msgid "Loading annotation..."
+msgstr "Annotierung laden..."
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr "Autor:"
+
+#: lib/blame.tcl:791
+msgid "Committer:"
+msgstr "Eintragender:"
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr "Ursprüngliche Datei:"
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr "Ursprünglich von:"
+
+#: lib/blame.tcl:916
+msgid "In File:"
+msgstr "In Datei:"
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr "Kopiert oder verschoben durch:"
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr "Zweig umstellen"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "Umstellen"
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr "Abbrechen"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr "Version"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+msgid "Options"
+msgstr "Optionen"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Ãœbernahmezweig anfordern"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr "Verbindung zu lokalem Zweig lösen"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr "Zweig erstellen"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr "Neuen Zweig erstellen"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375
+msgid "Create"
+msgstr "Erstellen"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr "Zweigname"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr "Name:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr "Passend zu Ãœbernahmezweig-Name"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "Anfangsversion"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "Existierenden Zweig aktualisieren:"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "Nein"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Nur Schnellzusammenführung"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr "Zurücksetzen"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "Arbeitskopie umstellen nach Erstellen"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr "Bitte wählen Sie einen Übernahmezweig."
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr "Übernahmezweig »%s« ist kein Zweig im anderen Projektarchiv."
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr "Bitte geben Sie einen Zweignamen an."
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "»%s« ist kein zulässiger Zweigname."
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr "Zweig löschen"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr "Lokalen Zweig löschen"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr "Lokale Zweige"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "Nur löschen, wenn darin zusammengeführt"
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr "Immer (ohne Zusammenführungstest)"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "Folgende Zweige sind noch nicht mit »%s« zusammengeführt:"
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+"Gelöschte Zweige können nur mit größerem Aufwand wiederhergestellt werden.\n"
+"\n"
+"Gewählte Zweige jetzt löschen?"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"Fehler beim Löschen der Zweige:\n"
+"%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr "Zweig umbenennen"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "Umbenennen"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr "Zweig:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "Neuer Name:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr "Bitte wählen Sie einen Zweig zum umbenennen."
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "Zweig »%s« existiert bereits."
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Fehler beim Umbenennen von »%s«."
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "Starten..."
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "Datei-Browser"
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr "%s laden..."
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr "[Nach oben]"
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+msgid "Browse Branch Files"
+msgstr "Dateien des Zweigs durchblättern"
+
+#: 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 "Blättern"
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "Änderungen »%s« von »%s« anfordern"
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr ""
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr "Schließen"
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "Zweig »%s« existiert nicht."
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"Zweig »%s« existiert bereits.\n"
+"\n"
+"Zweig kann nicht mit »%s« schnellzusammengeführt werden. Reguläres "
+"Zusammenführen ist notwendig."
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr "Zusammenführungsmethode »%s« nicht unterstützt."
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr "Aktualisieren von »%s« fehlgeschlagen."
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr "Bereitstellung (»index«) ist zur Bearbeitung gesperrt (»locked«)."
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Der letzte geladene Status stimmt nicht mehr mit dem Projektarchiv überein.\n"
+"\n"
+"Ein anderes Git-Programm hat das Projektarchiv seit dem letzten Laden "
+"geändert. Vor dem Wechseln des lokalen Zweigs muss neu geladen werden.\n"
+"\n"
+"Es wird gleich neu geladen.\n"
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "Arbeitskopie umstellen auf »%s«..."
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr ""
+"Zweig umstellen von »%s« abgebrochen (Zusammenführen der Dateien ist "
+"notwendig)."
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr "Zusammenführen der Dateien ist notwendig."
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "Es wird auf Zweig »%s« verblieben."
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"Die Arbeitskopie ist nicht auf einem lokalen Zweig.\n"
+"\n"
+"Wenn Sie auf einem Zweig arbeiten möchten, erstellen Sie bitte jetzt einen "
+"Zweig mit der Auswahl »Abgetrennte Arbeitskopie-Version«."
+
+#: lib/checkout_op.tcl:446
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr "Umgestellt auf »%s«."
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr "Zurücksetzen von »%s« nach »%s« wird folgende Versionen verwerfen:"
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr ""
+"Verworfene Versionen können nur mit größerem Aufwand wiederhergestellt "
+"werden."
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "»%s« zurücksetzen?"
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr "Darstellen"
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+"Lokaler Zweig kann nicht gesetzt werden.\n"
+"\n"
+"Diese Arbeitskopie ist nur teilweise umgestellt. Die Dateien sind korrekt "
+"aktualisiert, aber einige interne Git-Dateien konnten nicht geändert "
+"werden.\n"
+"\n"
+"Dies ist ein interner Programmfehler von %s. Programm wird jetzt abgebrochen."
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr "Auswählen"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr "Schriftfamilie"
+
+#: lib/choose_font.tcl:73
+msgid "Font Size"
+msgstr "Schriftgröße"
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr "Schriftbeispiel"
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"Dies ist ein Beispieltext.\n"
+"Wenn Ihnen dieser Text gefällt, sollten Sie diese Schriftart wählen."
+
+#: lib/choose_repository.tcl:27
+msgid "Git Gui"
+msgstr "Git Gui"
+
+#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380
+msgid "Create New Repository"
+msgstr "Neues Projektarchiv"
+
+#: lib/choose_repository.tcl:86
+msgid "New..."
+msgstr "Neu..."
+
+#: lib/choose_repository.tcl:93 lib/choose_repository.tcl:468
+msgid "Clone Existing Repository"
+msgstr "Projektarchiv kopieren"
+
+#: lib/choose_repository.tcl:99
+msgid "Clone..."
+msgstr "Kopieren..."
+
+#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978
+msgid "Open Existing Repository"
+msgstr "Projektarchiv öffnen"
+
+#: lib/choose_repository.tcl:112
+msgid "Open..."
+msgstr "Öffnen..."
+
+#: lib/choose_repository.tcl:125
+msgid "Recent Repositories"
+msgstr "Zuletzt benutzte Projektarchive"
+
+#: lib/choose_repository.tcl:131
+msgid "Open Recent Repository:"
+msgstr "Zuletzt benutztes Projektarchiv öffnen:"
+
+#: lib/choose_repository.tcl:294
+#, tcl-format
+msgid "Location %s already exists."
+msgstr "Projektarchiv »%s« existiert bereits."
+
+#: lib/choose_repository.tcl:300 lib/choose_repository.tcl:307
+#: lib/choose_repository.tcl:314
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "Projektarchiv »%s« konnte nicht erstellt werden:"
+
+#: lib/choose_repository.tcl:385 lib/choose_repository.tcl:486
+msgid "Directory:"
+msgstr "Verzeichnis:"
+
+#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544
+#: lib/choose_repository.tcl:1013
+msgid "Git Repository"
+msgstr "Git Projektarchiv"
+
+#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "Verzeichnis »%s« existiert bereits."
+
+#: lib/choose_repository.tcl:442
+#, tcl-format
+msgid "File %s already exists."
+msgstr "Datei »%s« existiert bereits."
+
+#: lib/choose_repository.tcl:463
+msgid "Clone"
+msgstr "Kopieren"
+
+#: lib/choose_repository.tcl:476
+msgid "URL:"
+msgstr "URL:"
+
+#: lib/choose_repository.tcl:496
+msgid "Clone Type:"
+msgstr "Art der Kopie:"
+
+#: lib/choose_repository.tcl:502
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr "Standard (schnell, teilweise redundant, Hardlinks)"
+
+#: lib/choose_repository.tcl:508
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "Alles kopieren (langsamer, volle Redundanz)"
+
+#: lib/choose_repository.tcl:514
+msgid "Shared (Fastest, Not Recommended, No Backup)"
+msgstr "Verknüpft (schnell, nicht empfohlen, kein Backup)"
+
+#: 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 "Kein Git-Projektarchiv in »%s« gefunden."
+
+#: lib/choose_repository.tcl:586
+msgid "Standard only available for local repository."
+msgstr "Standard ist nur für lokale Projektarchive verfügbar."
+
+#: lib/choose_repository.tcl:590
+msgid "Shared only available for local repository."
+msgstr "Verknüpft ist nur für lokale Projektarchive verfügbar."
+
+#: lib/choose_repository.tcl:617
+msgid "Failed to configure origin"
+msgstr ""
+
+#: lib/choose_repository.tcl:629
+msgid "Counting objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:630
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:654
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:690
+#, tcl-format
+msgid "Nothing to clone from %s."
+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 ""
+
+#: lib/choose_repository.tcl:705
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr ""
+
+#: lib/choose_repository.tcl:717
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "Kopieren von »%s«"
+
+#: lib/choose_repository.tcl:748
+msgid "Copying objects"
+msgstr "Objektdatenbank kopieren"
+
+#: lib/choose_repository.tcl:749
+msgid "KiB"
+msgstr "KB"
+
+#: lib/choose_repository.tcl:773
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "Objekt kann nicht kopiert werden: %s"
+
+#: lib/choose_repository.tcl:783
+msgid "Linking objects"
+msgstr "Objekte verlinken"
+
+#: lib/choose_repository.tcl:784
+msgid "objects"
+msgstr "Objekte"
+
+#: lib/choose_repository.tcl:792
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr "Objekt kann nicht hartverlinkt werden: %s"
+
+#: lib/choose_repository.tcl:847
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:858
+msgid "Cannot fetch tags. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:882
+msgid "Cannot determine HEAD. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:891
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:897
+msgid "Clone failed."
+msgstr "Kopieren fehlgeschlagen."
+
+#: lib/choose_repository.tcl:904
+msgid "No default branch obtained."
+msgstr ""
+
+#: lib/choose_repository.tcl:915
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr ""
+
+#: 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
+msgid "files"
+msgstr "Dateien"
+
+#: lib/choose_repository.tcl:957
+msgid "Initial file checkout failed."
+msgstr ""
+
+#: lib/choose_repository.tcl:973
+msgid "Open"
+msgstr "Öffnen"
+
+#: lib/choose_repository.tcl:983
+msgid "Repository:"
+msgstr "Projektarchiv:"
+
+#: lib/choose_repository.tcl:1033
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Projektarchiv »%s« konnte nicht geöffnet werden."
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr "Abgetrennte Arbeitskopie-Version"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Version Regexp-Ausdruck:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr "Lokaler Zweig"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr "Ãœbernahmezweig"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr "Markierung"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "Ungültige Version: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "Keine Version ausgewählt."
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "Versions-Ausdruck ist leer."
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr "Aktualisiert"
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr "URL"
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"Keine Version zur Nachbesserung vorhanden.\n"
+"\n"
+"Sie sind dabei, die erste Version zu übertragen. Es gibt keine existierende "
+"Version, die Sie nachbessern könnten.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"Nachbesserung währen Zusammenführung nicht möglich.\n"
+"\n"
+"Sie haben das Zusammenführen von Versionen angefangen, aber noch nicht "
+"beendet. Sie können keine vorige Übertragung nachbessern, solange eine "
+"unfertige Zusammenführung existiert. Dazu müssen Sie die Zusammenführung "
+"beenden oder abbrechen.\n"
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr "Fehler beim Laden der Versionsdaten für Nachbessern:"
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr "Benutzername konnte nicht bestimmt werden:"
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "Ungültiger Wert von GIT_COMMITTER_INDENT:"
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Der letzte geladene Status stimmt nicht mehr mit dem Projektarchiv überein.\n"
+"\n"
+"Ein anderes Git-Programm hat das Projektarchiv seit dem letzten Laden "
+"geändert. Vor dem Eintragen einer neuen Version muss neu geladen werden.\n"
+"\n"
+"Es wird gleich neu geladen.\n"
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"Nicht zusammengeführte Dateien können nicht eingetragen werden.\n"
+"\n"
+"Die Datei »%s« hat noch nicht aufgelöste Zusammenführungs-Konflikte. Sie "
+"müssen diese Konflikte auflösen, bevor Sie eintragen können.\n"
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"Unbekannter Dateizustand »%s«.\n"
+"\n"
+"Datei »%s« kann nicht eingetragen werden.\n"
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"Keine Änderungen vorhanden, die eingetragen werden könnten.\n"
+"\n"
+"Sie müssen mindestens eine Datei bereitstellen, bevor Sie eintragen können.\n"
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"Bitte geben Sie eine Versionsbeschreibung ein.\n"
+"\n"
+"Eine gute Versionsbeschreibung enthält folgende Abschnitte:\n"
+"\n"
+"- Erste Zeile: Eine Zusammenfassung, was man gemacht hat.\n"
+"\n"
+"- Zweite Zeile: Leerzeile\n"
+"\n"
+"- Rest: Eine ausführliche Beschreibung, warum diese Änderung hilfreich ist.\n"
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr "write-tree fehlgeschlagen:"
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "Version »%s« scheint beschädigt zu sein"
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"Keine Änderungen einzutragen.\n"
+"\n"
+"Es gibt keine geänderte Datei bei dieser Version und es wurde auch nichts "
+"zusammengeführt.\n"
+"\n"
+"Das Arbeitsverzeichnis wird daher jetzt neu geladen.\n"
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr "Keine Änderungen, die eingetragen werden können."
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr ""
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr "commit-tree fehlgeschlagen:"
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr "update-ref fehlgeschlagen:"
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "Version %s übertragen: %s"
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr "Verarbeitung. Bitte warten..."
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr "Erfolgreich"
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr "Fehler: Kommando fehlgeschlagen"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "Anzahl unverknüpfter Objekte"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "Festplattenplatz von unverknüpften Objekten"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "Anzahl komprimierter Objekte"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "Anzahl Komprimierungseinheiten"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "Festplattenplatz von komprimierten Objekten"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "Komprimierte Objekte, die zum Entfernen vorgesehen sind"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "Dateien im Mülleimer"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Objektdatenbank komprimieren"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "Die Objektdatenbank durch »fsck-objects« überprüfen lassen"
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+"Dieses Projektarchiv enthält ungefähr %i nicht verknüpfte Objekte.\n"
+"\n"
+"Für eine optimale Performance wird empfohlen, die Datenbank des "
+"Projektarchivs zu komprimieren, sobald mehr als %i nicht verknüpfte Objekte "
+"vorliegen.\n"
+"\n"
+"Soll die Datenbank jetzt komprimiert werden?"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Ungültiges Datum von Git: %s"
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Keine Änderungen feststellbar.\n"
+"\n"
+"»%s« enthält keine Änderungen. Zwar wurde das Änderungsdatum dieser Datei "
+"von einem anderen Programm modifiziert, aber der Inhalt der Datei ist "
+"unverändert.\n"
+"\n"
+"Das Arbeitsverzeichnis wird jetzt neu geladen, um diese Änderung bei allen "
+"Dateien zu prüfen."
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "Vergleich von »%s« laden..."
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Datei »%s« kann nicht angezeigt werden"
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr "Fehler beim Laden der Datei:"
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr "Git-Projektarchiv (Unterprojekt)"
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr "* Binärdatei (Inhalt wird nicht angezeigt)"
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr "Fehler beim Laden des Vergleichs:"
+
+#: lib/diff.tcl:302
+msgid "Failed to unstage selected hunk."
+msgstr "Fehler beim Herausnehmen der gewählten Dateien aus der Bereitstellung."
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr "Fehler beim Bereitstellen der gewählten Dateien."
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr "Fehler"
+
+#: lib/error.tcl:28
+msgid "warning"
+msgstr "Warnung"
+
+#: lib/error.tcl:81
+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
+#, tcl-format
+msgid "Unstaging %s from commit"
+msgstr "Datei »%s« aus der Bereitstellung herausnehmen"
+
+#: lib/index.tcl:285
+#, tcl-format
+msgid "Adding %s"
+msgstr "»%s« hinzufügen..."
+
+#: lib/index.tcl:340
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "Änderungen in Datei »%s« revidieren?"
+
+#: lib/index.tcl:342
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr "Änderungen in den gewählten %i Dateien revidieren?"
+
+#: lib/index.tcl:348
+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
+msgid "Do Nothing"
+msgstr "Nichts tun"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"Zusammenführen kann nicht gleichzeitig mit Nachbessern durchgeführt werden.\n"
+"\n"
+"Sie müssen zuerst die Nachbesserungs-Version abschließen, bevor Sie "
+"zusammenführen können.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Der letzte geladene Status stimmt nicht mehr mit dem Projektarchiv überein.\n"
+"\n"
+"Ein anderes Git-Programm hat das Projektarchiv seit dem letzten Laden "
+"geändert. Vor einem Zusammenführen muss neu geladen werden.\n"
+"\n"
+"Es wird gleich neu geladen.\n"
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"Zusammenführung mit Konflikten.\n"
+"\n"
+"Die Datei »%s« enthält Konflikte beim Zusammenführen. Sie müssen diese "
+"Konflikte per Hand auflösen. Anschließend müssen Sie die Datei wieder "
+"bereitstellen und eintragen, um die Zusammenführung abzuschließen. Erst "
+"danach kann eine neue Zusammenführung begonnen werden.\n"
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"Es liegen Änderungen vor.\n"
+"\n"
+"Die Datei »%s« wurde geändert. Sie sollten zuerst die bereitgestellte "
+"Version abschließen, bevor Sie eine Zusammenführung beginnen. Mit dieser "
+"Reihenfolge können Sie mögliche Konflikte beim Zusammenführen wesentlich "
+"einfacher beheben oder abbrechen.\n"
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s von %s"
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr "Zusammenführen von %s und %s"
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr "Zusammenführen erfolgreich abgeschlossen."
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr "Zusammenführen fehlgeschlagen. Konfliktauflösung ist notwendig."
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Zusammenführen in %s"
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr "Zusammenzuführende Version"
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"Abbruch der Nachbesserung ist nicht möglich.\n"
+"\n"
+"Sie müssen die Nachbesserung der Version abschließen.\n"
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"Zusammenführen abbrechen?\n"
+"\n"
+"Wenn Sie abbrechen, gehen alle noch nicht eingetragenen Änderungen "
+"verloren.\n"
+"\n"
+"Zusammenführen jetzt abbrechen?"
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"Änderungen zurücksetzen?\n"
+"\n"
+"Wenn Sie zurücksetzen, gehen alle noch nicht eingetragenen Änderungen "
+"verloren.\n"
+"\n"
+"Änderungen jetzt zurücksetzen?"
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr "Abbruch"
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr "Abbruch fehlgeschlagen."
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr "Abbruch durchgeführt. Bereit."
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr "Voreinstellungen wiederherstellen"
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr "Speichern"
+
+#: lib/option.tcl:96
+#, tcl-format
+msgid "%s Repository"
+msgstr "Projektarchiv %s"
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr "Global (Alle Projektarchive)"
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr "Benutzername"
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr "E-Mail-Adresse"
+
+#: lib/option.tcl:106
+msgid "Summarize Merge Commits"
+msgstr "Zusammenführungs-Versionen zusammenfassen"
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr "Ausführlichkeit der Zusammenführen-Meldungen"
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr "Vergleichsstatistik nach Zusammenführen anzeigen"
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr "Auf Dateiänderungsdatum verlassen"
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr "Übernahmezweige entfernen während Anforderung"
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr "Passend zu Ãœbernahmezweig"
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr "Anzahl der Kontextzeilen beim Vergleich"
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr "Namensvorschlag für neue Zweige"
+
+#: lib/option.tcl:176
+msgid "Change Font"
+msgstr "Schriftart ändern"
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr "%s wählen"
+
+#: lib/option.tcl:186
+msgid "pt."
+msgstr "pt."
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr "Einstellungen"
+
+#: lib/option.tcl:235
+msgid "Failed to completely save options:"
+msgstr "Optionen konnten nicht gespeichert werden:"
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Remote Branch"
+msgstr "Zweig im anderen Projektarchiv löschen"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "Von Projektarchiv"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr "Anderes Archiv:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr "Kommunikation mit URL:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr "Zweige"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "Löschen, falls"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "Zusammenführen mit:"
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "Immer (Keine Zusammenführungsprüfung)"
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr "Für »Zusammenführen mit« muss ein Zweig angegeben werden."
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"Folgende Zweige sind noch nicht mit »%s« zusammengeführt:\n"
+"\n"
+" - %s"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+"Ein oder mehrere Zusammenführungen sind fehlgeschlagen, da Sie nicht die "
+"notwendigen Versionen vorher angefordert haben. Sie sollten versuchen, "
+"zuerst von »%s« anzufordern."
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr "Bitte wählen Sie mindestens einen Zweig, der gelöscht werden soll."
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"Das Wiederherstellen von gelöschten Zweigen ist nur mit größerem Aufwand "
+"möglich.\n"
+"\n"
+"Sollen die ausgewählten Zweige gelöscht werden?"
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "Zweige auf »%s« werden gelöscht"
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr "Kein Projektarchiv ausgewählt."
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+msgid "Scanning %s..."
+msgstr "»%s« laden..."
+
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr "Entfernen von"
+
+#: lib/remote.tcl:170
+msgid "Fetch from"
+msgstr "Anfordern von"
+
+#: lib/remote.tcl:213
+msgid "Push to"
+msgstr "Versenden nach"
+
+#: lib/shortcut.tcl:20 lib/shortcut.tcl:61
+msgid "Cannot write shortcut:"
+msgstr "Fehler beim Schreiben der Verknüpfung:"
+
+#: lib/shortcut.tcl:136
+msgid "Cannot write icon:"
+msgstr "Fehler beim Erstellen des Icons:"
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%s ... %*i von %*i %s (%3i%%)"
+
+#: lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "»%s« anfordern"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "Neue Änderungen von »%s« holen"
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "Entfernen von »%s« im anderen Archiv"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr "Übernahmezweige entfernen, die in »%s« gelöscht wurden"
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr "»%s« versenden..."
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Änderungen nach »%s« versenden"
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "%s %s nach %s versenden"
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr "Zweige versenden"
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr "Herkunftszweige"
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr "Ziel-Projektarchiv"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr "Netzwerk-Einstellungen"
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
+"Überschreiben von existierenden Zweigen erzwingen (könnte Änderungen löschen)"
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr "Kompaktes Datenformat benutzen (für langsame Netzverbindungen)"
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr "Mit Markierungen übertragen"
+
+#~ msgid "Next >"
+#~ msgstr "Weiter >"
+
+#~ msgid "Fetch"
+#~ msgstr "Anfordern"
+
+#~ msgid "Unstaged Changes (Will Not Be Committed)"
+#~ msgstr "Nicht bereitgestellte Änderungen (werden nicht eingetragen)"
diff --git a/git-gui/po/git-gui.pot b/git-gui/po/git-gui.pot
new file mode 100644
index 000000000..00f0f5922
--- /dev/null
+++ b/git-gui/po/git-gui.pot
@@ -0,0 +1,1704 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-10 04:04-0400\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"
+"MIME-Version: 1.0\n"
+"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
+msgid "git-gui: fatal error"
+msgstr ""
+
+#: git-gui.sh:595
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr ""
+
+#: git-gui.sh:620
+msgid "Main Font"
+msgstr ""
+
+#: git-gui.sh:621
+msgid "Diff/Console Font"
+msgstr ""
+
+#: git-gui.sh:635
+msgid "Cannot find git in PATH."
+msgstr ""
+
+#: git-gui.sh:662
+msgid "Cannot parse Git version string:"
+msgstr ""
+
+#: git-gui.sh:680
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+
+#: git-gui.sh:853
+msgid "Git directory not found:"
+msgstr ""
+
+#: git-gui.sh:860
+msgid "Cannot move to top of working directory:"
+msgstr ""
+
+#: git-gui.sh:867
+msgid "Cannot use funny .git directory:"
+msgstr ""
+
+#: git-gui.sh:872
+msgid "No working directory"
+msgstr ""
+
+#: git-gui.sh:1019
+msgid "Refreshing file status..."
+msgstr ""
+
+#: git-gui.sh:1084
+msgid "Scanning for modified files ..."
+msgstr ""
+
+#: git-gui.sh:1259 lib/browser.tcl:245
+msgid "Ready."
+msgstr ""
+
+#: git-gui.sh:1525
+msgid "Unmodified"
+msgstr ""
+
+#: git-gui.sh:1527
+msgid "Modified, not staged"
+msgstr ""
+
+#: git-gui.sh:1528 git-gui.sh:1533
+msgid "Staged for commit"
+msgstr ""
+
+#: git-gui.sh:1529 git-gui.sh:1534
+msgid "Portions staged for commit"
+msgstr ""
+
+#: git-gui.sh:1530 git-gui.sh:1535
+msgid "Staged for commit, missing"
+msgstr ""
+
+#: git-gui.sh:1532
+msgid "Untracked, not staged"
+msgstr ""
+
+#: git-gui.sh:1537
+msgid "Missing"
+msgstr ""
+
+#: git-gui.sh:1538
+msgid "Staged for removal"
+msgstr ""
+
+#: git-gui.sh:1539
+msgid "Staged for removal, still present"
+msgstr ""
+
+#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544
+msgid "Requires merge resolution"
+msgstr ""
+
+#: git-gui.sh:1579
+msgid "Starting gitk... please wait..."
+msgstr ""
+
+#: git-gui.sh:1588
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+
+#: git-gui.sh:1788 lib/choose_repository.tcl:32
+msgid "Repository"
+msgstr ""
+
+#: git-gui.sh:1789
+msgid "Edit"
+msgstr ""
+
+#: git-gui.sh:1791 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr ""
+
+#: git-gui.sh:1794 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
+msgid "Merge"
+msgstr ""
+
+#: git-gui.sh:1798 lib/choose_rev.tcl:556
+msgid "Remote"
+msgstr ""
+
+#: git-gui.sh:1807
+msgid "Browse Current Branch's Files"
+msgstr ""
+
+#: git-gui.sh:1811
+msgid "Browse Branch Files..."
+msgstr ""
+
+#: git-gui.sh:1816
+msgid "Visualize Current Branch's History"
+msgstr ""
+
+#: git-gui.sh:1820
+msgid "Visualize All Branch History"
+msgstr ""
+
+#: git-gui.sh:1827
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr ""
+
+#: git-gui.sh:1829
+#, tcl-format
+msgid "Visualize %s's History"
+msgstr ""
+
+#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr ""
+
+#: git-gui.sh:1837 lib/database.tcl:34
+msgid "Compress Database"
+msgstr ""
+
+#: git-gui.sh:1840
+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
+msgid "Create Desktop Icon"
+msgstr ""
+
+#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95
+msgid "Quit"
+msgstr ""
+
+#: git-gui.sh:1867
+msgid "Undo"
+msgstr ""
+
+#: git-gui.sh:1870
+msgid "Redo"
+msgstr ""
+
+#: git-gui.sh:1874 git-gui.sh:2366
+msgid "Cut"
+msgstr ""
+
+#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr ""
+
+#: git-gui.sh:1880 git-gui.sh:2372
+msgid "Paste"
+msgstr ""
+
+#: git-gui.sh:1883 git-gui.sh:2375 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
+msgid "Select All"
+msgstr ""
+
+#: git-gui.sh:1896
+msgid "Create..."
+msgstr ""
+
+#: git-gui.sh:1902
+msgid "Checkout..."
+msgstr ""
+
+#: git-gui.sh:1908
+msgid "Rename..."
+msgstr ""
+
+#: git-gui.sh:1913 git-gui.sh:2012
+msgid "Delete..."
+msgstr ""
+
+#: git-gui.sh:1918
+msgid "Reset..."
+msgstr ""
+
+#: git-gui.sh:1930 git-gui.sh:2313
+msgid "New Commit"
+msgstr ""
+
+#: git-gui.sh:1938 git-gui.sh:2320
+msgid "Amend Last Commit"
+msgstr ""
+
+#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr ""
+
+#: git-gui.sh:1953
+msgid "Stage To Commit"
+msgstr ""
+
+#: git-gui.sh:1958
+msgid "Stage Changed Files To Commit"
+msgstr ""
+
+#: git-gui.sh:1964
+msgid "Unstage From Commit"
+msgstr ""
+
+#: git-gui.sh:1969 lib/index.tcl:352
+msgid "Revert Changes"
+msgstr ""
+
+#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390
+msgid "Sign Off"
+msgstr ""
+
+#: git-gui.sh:1980 git-gui.sh:2296
+msgid "Commit@@verb"
+msgstr ""
+
+#: git-gui.sh:1991
+msgid "Local Merge..."
+msgstr ""
+
+#: git-gui.sh:1996
+msgid "Abort Merge..."
+msgstr ""
+
+#: git-gui.sh:2008
+msgid "Push..."
+msgstr ""
+
+#: git-gui.sh:2019 lib/choose_repository.tcl:41
+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
+#, tcl-format
+msgid "About %s"
+msgstr ""
+
+#: git-gui.sh:2026
+msgid "Preferences..."
+msgstr ""
+
+#: git-gui.sh:2034 git-gui.sh:2558
+msgid "Options..."
+msgstr ""
+
+#: git-gui.sh:2040 lib/choose_repository.tcl:47
+msgid "Help"
+msgstr ""
+
+#: git-gui.sh:2081
+msgid "Online Documentation"
+msgstr ""
+
+#: git-gui.sh:2165
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr ""
+
+#: git-gui.sh:2198
+msgid "Current Branch:"
+msgstr ""
+
+#: git-gui.sh:2219
+msgid "Staged Changes (Will Commit)"
+msgstr ""
+
+#: git-gui.sh:2239
+msgid "Unstaged Changes"
+msgstr ""
+
+#: git-gui.sh:2286
+msgid "Stage Changed"
+msgstr ""
+
+#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr ""
+
+#: git-gui.sh:2332
+msgid "Initial Commit Message:"
+msgstr ""
+
+#: git-gui.sh:2333
+msgid "Amended Commit Message:"
+msgstr ""
+
+#: git-gui.sh:2334
+msgid "Amended Initial Commit Message:"
+msgstr ""
+
+#: git-gui.sh:2335
+msgid "Amended Merge Commit Message:"
+msgstr ""
+
+#: git-gui.sh:2336
+msgid "Merge Commit Message:"
+msgstr ""
+
+#: git-gui.sh:2337
+msgid "Commit Message:"
+msgstr ""
+
+#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71
+msgid "Copy All"
+msgstr ""
+
+#: git-gui.sh:2406 lib/blame.tcl:104
+msgid "File:"
+msgstr ""
+
+#: git-gui.sh:2508
+msgid "Refresh"
+msgstr ""
+
+#: git-gui.sh:2529
+msgid "Apply/Reverse Hunk"
+msgstr ""
+
+#: git-gui.sh:2535
+msgid "Decrease Font Size"
+msgstr ""
+
+#: git-gui.sh:2539
+msgid "Increase Font Size"
+msgstr ""
+
+#: git-gui.sh:2544
+msgid "Show Less Context"
+msgstr ""
+
+#: git-gui.sh:2551
+msgid "Show More Context"
+msgstr ""
+
+#: git-gui.sh:2565
+msgid "Unstage Hunk From Commit"
+msgstr ""
+
+#: git-gui.sh:2567
+msgid "Stage Hunk For Commit"
+msgstr ""
+
+#: git-gui.sh:2586
+msgid "Initializing..."
+msgstr ""
+
+#: git-gui.sh:2677
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+
+#: git-gui.sh:2707
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+
+#: git-gui.sh:2712
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr ""
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr ""
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr ""
+
+#: lib/blame.tcl:249
+msgid "Copy Commit"
+msgstr ""
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr ""
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr ""
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr ""
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr ""
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr ""
+
+#: lib/blame.tcl:731
+msgid "Loading annotation..."
+msgstr ""
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr ""
+
+#: lib/blame.tcl:791
+msgid "Committer:"
+msgstr ""
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr ""
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr ""
+
+#: lib/blame.tcl:916
+msgid "In File:"
+msgstr ""
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr ""
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr ""
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr ""
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr ""
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr ""
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+msgid "Options"
+msgstr ""
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr ""
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr ""
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr ""
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr ""
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199
+msgid "Create"
+msgstr ""
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr ""
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr ""
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr ""
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr ""
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr ""
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr ""
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr ""
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr ""
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr ""
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr ""
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr ""
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr ""
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr ""
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr ""
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr ""
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr ""
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr ""
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr ""
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr ""
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr ""
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr ""
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr ""
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr ""
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr ""
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr ""
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr ""
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr ""
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr ""
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr ""
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr ""
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+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
+msgid "Browse"
+msgstr ""
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr ""
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr ""
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr ""
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr ""
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr ""
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr ""
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr ""
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr ""
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr ""
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr ""
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr ""
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+
+#: lib/checkout_op.tcl:446
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr ""
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr ""
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr ""
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr ""
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr ""
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr ""
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr ""
+
+#: lib/choose_font.tcl:73
+msgid "Font Size"
+msgstr ""
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr ""
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+
+#: lib/choose_repository.tcl:25
+msgid "Git Gui"
+msgstr ""
+
+#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
+msgid "Create New Repository"
+msgstr ""
+
+#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
+msgid "Clone Existing Repository"
+msgstr ""
+
+#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
+msgid "Open Existing Repository"
+msgstr ""
+
+#: lib/choose_repository.tcl:91
+msgid "Next >"
+msgstr ""
+
+#: lib/choose_repository.tcl:152
+#, tcl-format
+msgid "Location %s already exists."
+msgstr ""
+
+#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165
+#: lib/choose_repository.tcl:172
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr ""
+
+#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
+msgid "Directory:"
+msgstr ""
+
+#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
+#: lib/choose_repository.tcl:834
+msgid "Git Repository"
+msgstr ""
+
+#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr ""
+
+#: lib/choose_repository.tcl:265
+#, tcl-format
+msgid "File %s already exists."
+msgstr ""
+
+#: lib/choose_repository.tcl:286
+msgid "Clone"
+msgstr ""
+
+#: lib/choose_repository.tcl:299
+msgid "URL:"
+msgstr ""
+
+#: lib/choose_repository.tcl:319
+msgid "Clone Type:"
+msgstr ""
+
+#: lib/choose_repository.tcl:325
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr ""
+
+#: lib/choose_repository.tcl:331
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr ""
+
+#: lib/choose_repository.tcl:337
+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
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:405
+msgid "Standard only available for local repository."
+msgstr ""
+
+#: lib/choose_repository.tcl:409
+msgid "Shared only available for local repository."
+msgstr ""
+
+#: lib/choose_repository.tcl:439
+msgid "Failed to configure origin"
+msgstr ""
+
+#: lib/choose_repository.tcl:451
+msgid "Counting objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:452
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:476
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:512
+#, tcl-format
+msgid "Nothing to clone from %s."
+msgstr ""
+
+#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728
+#: lib/choose_repository.tcl:740
+msgid "The 'master' branch has not been initialized."
+msgstr ""
+
+#: lib/choose_repository.tcl:527
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr ""
+
+#: lib/choose_repository.tcl:539
+#, tcl-format
+msgid "Cloning from %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:570
+msgid "Copying objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:571
+msgid "KiB"
+msgstr ""
+
+#: lib/choose_repository.tcl:595
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:605
+msgid "Linking objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:606
+msgid "objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:614
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:669
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:680
+msgid "Cannot fetch tags. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:704
+msgid "Cannot determine HEAD. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:713
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:719
+msgid "Clone failed."
+msgstr ""
+
+#: lib/choose_repository.tcl:726
+msgid "No default branch obtained."
+msgstr ""
+
+#: lib/choose_repository.tcl:737
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr ""
+
+#: lib/choose_repository.tcl:749
+msgid "Creating working directory"
+msgstr ""
+
+#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80
+#: lib/index.tcl:149
+msgid "files"
+msgstr ""
+
+#: lib/choose_repository.tcl:779
+msgid "Initial file checkout failed."
+msgstr ""
+
+#: lib/choose_repository.tcl:795
+msgid "Open"
+msgstr ""
+
+#: lib/choose_repository.tcl:805
+msgid "Repository:"
+msgstr ""
+
+#: lib/choose_repository.tcl:854
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr ""
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr ""
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr ""
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr ""
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr ""
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr ""
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr ""
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr ""
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr ""
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr ""
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr ""
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr ""
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr ""
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr ""
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr ""
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr ""
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr ""
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr ""
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr ""
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr ""
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr ""
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr ""
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr ""
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr ""
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr ""
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr ""
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr ""
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr ""
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr ""
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr ""
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr ""
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr ""
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr ""
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr ""
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr ""
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr ""
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr ""
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr ""
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr ""
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr ""
+
+#: lib/diff.tcl:302
+msgid "Failed to unstage selected hunk."
+msgstr ""
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr ""
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr ""
+
+#: lib/error.tcl:28
+msgid "warning"
+msgstr ""
+
+#: lib/error.tcl:81
+msgid "You must correct the above errors before committing."
+msgstr ""
+
+#: lib/index.tcl:241
+#, tcl-format
+msgid "Unstaging %s from commit"
+msgstr ""
+
+#: lib/index.tcl:285
+#, tcl-format
+msgid "Adding %s"
+msgstr ""
+
+#: lib/index.tcl:340
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr ""
+
+#: lib/index.tcl:342
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr ""
+
+#: lib/index.tcl:348
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr ""
+
+#: lib/index.tcl:351
+msgid "Do Nothing"
+msgstr ""
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr ""
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr ""
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr ""
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr ""
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr ""
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr ""
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr ""
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr ""
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr ""
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr ""
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr ""
+
+#: lib/option.tcl:96
+#, tcl-format
+msgid "%s Repository"
+msgstr ""
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr ""
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr ""
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr ""
+
+#: lib/option.tcl:106
+msgid "Summarize Merge Commits"
+msgstr ""
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr ""
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr ""
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr ""
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr ""
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr ""
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr ""
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr ""
+
+#: lib/option.tcl:176
+msgid "Change Font"
+msgstr ""
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr ""
+
+#: lib/option.tcl:186
+msgid "pt."
+msgstr ""
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr ""
+
+#: lib/option.tcl:235
+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 ""
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+msgid "Scanning %s..."
+msgstr ""
+
+#: lib/shortcut.tcl:26 lib/shortcut.tcl:74
+msgid "Cannot write script:"
+msgstr ""
+
+#: lib/shortcut.tcl:149
+msgid "Cannot write icon:"
+msgstr ""
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr ""
+
+#: lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr ""
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr ""
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr ""
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr ""
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr ""
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr ""
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr ""
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr ""
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr ""
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr ""
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr ""
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr ""
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr ""
diff --git a/git-gui/po/glossary/Makefile b/git-gui/po/glossary/Makefile
new file mode 100644
index 000000000..749aa2e7e
--- /dev/null
+++ b/git-gui/po/glossary/Makefile
@@ -0,0 +1,9 @@
+PO_TEMPLATE = git-gui-glossary.pot
+
+ALL_POFILES = $(wildcard *.po)
+
+$(PO_TEMPLATE): $(subst .pot,.txt,$(PO_TEMPLATE))
+ ./txt-to-pot.sh $< > $@
+
+update-po:: git-gui-glossary.pot
+ $(foreach p, $(ALL_POFILES), echo Updating $p ; msgmerge -U $p $(PO_TEMPLATE) ; )
diff --git a/git-gui/po/glossary/de.po b/git-gui/po/glossary/de.po
new file mode 100644
index 000000000..c94786c6a
--- /dev/null
+++ b/git-gui/po/glossary/de.po
@@ -0,0 +1,185 @@
+# Translation of git-gui glossary to German
+# Copyright (C) 2007 Shawn Pearce, et al.
+# This file is distributed under the same license as the git package.
+# Christian Stimming <stimming@tuhh.de>, 2007
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui glossary\n"
+"POT-Creation-Date: 2007-10-19 21:43+0200\n"
+"PO-Revision-Date: 2007-10-20 15:24+0200\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"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid ""
+"English Term (Dear translator: This file will never be visible to the user!)"
+msgstr ""
+"Deutsche Ãœbersetzung.\n"
+"Andere deutsche SCM:\n"
+" http://tortoisesvn.net/docs/release/TortoiseSVN_de/index.html und http://"
+"tortoisesvn.tigris.org/svn/tortoisesvn/trunk/Languages/Tortoise_de.po "
+"(username=guest, password empty, gut),\n"
+" http://msdn.microsoft.com/de-de/library/ms181038(vs.80).aspx (MS Visual "
+"Source Safe, kommerziell),\n"
+" http://cvsbook.red-bean.com/translations/german/Kap_06.html "
+"(mittelmäßig),\n"
+" http://tortoisecvs.cvs.sourceforge.net/tortoisecvs/po/TortoiseCVS/de_DE.po?"
+"view=markup (mittelmäßig),\n"
+" http://rapidsvn.tigris.org/svn/rapidsvn/trunk/src/locale/de/rapidsvn.po "
+"(username=guest, password empty, schlecht)"
+
+#. ""
+msgid "amend"
+msgstr "nachbessern (ergänzen)"
+
+#. ""
+msgid "annotate"
+msgstr "annotieren"
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr "Zweig"
+
+#. ""
+msgid "branch [verb]"
+msgstr "verzweigen"
+
+#. ""
+msgid "checkout [noun]"
+msgstr ""
+"Arbeitskopie (Erstellung einer Arbeitskopie; Auscheck? Ausspielung? Abruf? "
+"Source Safe: Auscheckvorgang)"
+
+#. "The action of updating the working tree to a revision which was stored in the object database."
+msgid "checkout [verb]"
+msgstr ""
+"Arbeitskopie erstellen; Zweig umstellen [checkout a branch] (auschecken? "
+"ausspielen? abrufen? Source Safe: auschecken)"
+
+#. ""
+msgid "clone [verb]"
+msgstr "kopieren"
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr ""
+"Version; Eintragung; Änderung (Buchung?, Eintragung?, Übertragung?, "
+"Sendung?, Ãœbergabe?, Einspielung?, Ablagevorgang?)"
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr ""
+"eintragen (TortoiseSVN: übertragen; Source Safe: einchecken; senden?, "
+"übergeben?, einspielen?, einpflegen?, ablegen?)"
+
+#. ""
+msgid "diff [noun]"
+msgstr "Vergleich (Source Safe: Unterschiede)"
+
+#. ""
+msgid "diff [verb]"
+msgstr "vergleichen"
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr "Schnellzusammenführung"
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+msgid "fetch"
+msgstr "anfordern (holen?)"
+
+#. "A collection of files. The index is a stored version of your working tree."
+msgid "index (in git-gui: staging area)"
+msgstr "Bereitstellung"
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr "Zusammenführung"
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr "zusammenführen"
+
+#. ""
+msgid "message"
+msgstr "Beschreibung (Meldung?, Nachricht?; Source Safe: Kommentar)"
+
+#. "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 "entfernen"
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr "übernehmen (ziehen?)"
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr "versenden (ausliefern? hochladen? verschicken? schieben?)"
+
+#. ""
+msgid "redo"
+msgstr "wiederholen"
+
+#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
+msgid "remote"
+msgstr "Andere Archive (Gegenseite?, Entfernte?, Server?)"
+
+#. "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 "Projektarchiv"
+
+#. ""
+msgid "reset"
+msgstr "zurücksetzen (zurückkehren?)"
+
+#. ""
+msgid "revert"
+msgstr "revidieren"
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr "Version (TortoiseSVN: Revision; Source Safe: Version)"
+
+#. ""
+msgid "sign off"
+msgstr "abzeichnen (gegenzeichnen?, freizeichnen?, absegnen?)"
+
+#. ""
+msgid "staging area"
+msgstr "Bereitstellung"
+
+#. ""
+msgid "status"
+msgstr "Status"
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr "Markierung"
+
+#. ""
+msgid "tag [verb]"
+msgstr "markieren"
+
+#. "A regular git branch that is used to follow changes from another repository."
+msgid "tracking branch"
+msgstr "Ãœbernahmezweig"
+
+#. ""
+msgid "undo"
+msgstr "rückgängig"
+
+#. ""
+msgid "update"
+msgstr "aktualisieren"
+
+#. ""
+msgid "verify"
+msgstr "überprüfen"
+
+#. "The tree of actual checked out files."
+msgid "working copy, working tree"
+msgstr "Arbeitskopie"
diff --git a/git-gui/po/glossary/git-gui-glossary.pot b/git-gui/po/glossary/git-gui-glossary.pot
new file mode 100644
index 000000000..48af80331
--- /dev/null
+++ b/git-gui/po/glossary/git-gui-glossary.pot
@@ -0,0 +1,164 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: 2007-10-19 21:43+0200\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid "English Term (Dear translator: This file will never be visible to the user!)"
+msgstr ""
+
+#. ""
+msgid "amend"
+msgstr ""
+
+#. ""
+msgid "annotate"
+msgstr ""
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr ""
+
+#. ""
+msgid "branch [verb]"
+msgstr ""
+
+#. ""
+msgid "checkout [noun]"
+msgstr ""
+
+#. "The action of updating the working tree to a revision which was stored in the object database."
+msgid "checkout [verb]"
+msgstr ""
+
+#. ""
+msgid "clone [verb]"
+msgstr ""
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr ""
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr ""
+
+#. ""
+msgid "diff [noun]"
+msgstr ""
+
+#. ""
+msgid "diff [verb]"
+msgstr ""
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr ""
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+msgid "fetch"
+msgstr ""
+
+#. "A collection of files. The index is a stored version of your working tree."
+msgid "index (in git-gui: staging area)"
+msgstr ""
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr ""
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr ""
+
+#. ""
+msgid "message"
+msgstr ""
+
+#. "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 ""
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr ""
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr ""
+
+#. ""
+msgid "redo"
+msgstr ""
+
+#. "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
+msgid "remote"
+msgstr ""
+
+#. "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 ""
+
+#. ""
+msgid "reset"
+msgstr ""
+
+#. ""
+msgid "revert"
+msgstr ""
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr ""
+
+#. ""
+msgid "sign off"
+msgstr ""
+
+#. ""
+msgid "staging area"
+msgstr ""
+
+#. ""
+msgid "status"
+msgstr ""
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr ""
+
+#. ""
+msgid "tag [verb]"
+msgstr ""
+
+#. "A regular git branch that is used to follow changes from another repository."
+msgid "tracking branch"
+msgstr ""
+
+#. ""
+msgid "undo"
+msgstr ""
+
+#. ""
+msgid "update"
+msgstr ""
+
+#. ""
+msgid "verify"
+msgstr ""
+
+#. "The tree of actual checked out files."
+msgid "working copy, working tree"
+msgstr ""
+
diff --git a/git-gui/po/glossary/git-gui-glossary.txt b/git-gui/po/glossary/git-gui-glossary.txt
new file mode 100644
index 000000000..500d0a0ea
--- /dev/null
+++ b/git-gui/po/glossary/git-gui-glossary.txt
@@ -0,0 +1,37 @@
+"English Term (Dear translator: This file will never be visible to the user!)" "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+"amend" ""
+"annotate" ""
+"branch [noun]" "A 'branch' is an active line of development."
+"branch [verb]" ""
+"checkout [noun]" ""
+"checkout [verb]" "The action of updating the working tree to a revision which was stored in the object database."
+"clone [verb]" ""
+"commit [noun]" "A single point in the git history."
+"commit [verb]" "The action of storing a new snapshot of the project's state in the git history."
+"diff [noun]" ""
+"diff [verb]" ""
+"fast forward merge" "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+"fetch" "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+"index (in git-gui: staging area)" "A collection of files. The index is a stored version of your working tree."
+"merge [noun]" "A successful merge results in the creation of a new commit representing the result of the merge."
+"merge [verb]" "To bring the contents of another branch into the current branch."
+"message" ""
+"prune" "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>'."
+"pull" "Pulling a branch means to fetch it and merge it."
+"push" "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+"redo" ""
+"remote" "An other repository ('remote'). One might have a set of remotes whose branches one tracks."
+"repository" "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?)"
+"reset" ""
+"revert" ""
+"revision" "A particular state of files and directories which was stored in the object database."
+"sign off" ""
+"staging area" ""
+"status" ""
+"tag [noun]" "A ref pointing to a tag or commit object"
+"tag [verb]" ""
+"tracking branch" "A regular git branch that is used to follow changes from another repository."
+"undo" ""
+"update" ""
+"verify" ""
+"working copy, working tree" "The tree of actual checked out files."
diff --git a/git-gui/po/glossary/it.po b/git-gui/po/glossary/it.po
new file mode 100644
index 000000000..8e3d9a2f0
--- /dev/null
+++ b/git-gui/po/glossary/it.po
@@ -0,0 +1,180 @@
+# Translation of git-gui glossary to Italian
+# Copyright (C) 2007 Shawn Pearce, et al.
+# This file is distributed under the same license as the git package.
+# Christian Stimming <stimming@tuhh.de>, 2007
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui glossary\n"
+"POT-Creation-Date: 2007-10-05 22:30+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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid ""
+"English Term (Dear translator: This file will never be visible to the user!)"
+msgstr ""
+"Traduzione italiana.\n"
+"Altri SCM in italiano:\n"
+" http://tortoisesvn.tigris.org/svn/tortoisesvn/trunk/Languages/Tortoise_it."
+"po (username=guest, password empty),\n"
+" http://tortoisecvs.cvs.sourceforge.net/tortoisecvs/po/TortoiseCVS/it_IT.po?"
+"view=markup ,\n"
+" http://rapidsvn.tigris.org/svn/rapidsvn/trunk/src/locale/it_IT/rapidsvn.po "
+"(username=guest, password empty)"
+
+#. ""
+msgid "amend"
+msgstr "correggere, correzione"
+
+#. ""
+msgid "annotate"
+msgstr "annotare, annotazione"
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr "ramo, diramazione, ramificazione"
+
+#. ""
+msgid "branch [verb]"
+msgstr "creare ramo, ramificare, diramare"
+
+#. ""
+msgid "checkout [noun]"
+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)?"
+
+#. ""
+msgid "clone [verb]"
+msgstr "clonare"
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr "revisione, commit, deposito (TortoiseCVS), invio (TSVN)?"
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr ""
+"creare una nuova revisione, archiviare, effettuare un commit, depositare "
+"(nel server), fare un deposito (TortoiseCVS), inviare (TSVN)?"
+
+#. ""
+msgid "diff [noun]"
+msgstr "differenza, confronto, comparazione, raffronto"
+
+#. ""
+msgid "diff [verb]"
+msgstr "confronta, mostra le differenze"
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr "fusione in 'fast-forward', fusione in avanti veloce"
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+msgid "fetch"
+msgstr "recuperare, prelevare, prendere da, recuperare (TSVN)"
+
+#. "A collection of files. The index is a stored version of your working tree."
+msgid "index (in git-gui: staging area)"
+msgstr "indice"
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr "fusione, unione"
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr "effettuare la fusione, unire, fondere, eseguire la fusione"
+
+#. ""
+msgid "message"
+msgstr "messaggio, commento"
+
+#. ""
+msgid "prune"
+msgstr "potatura"
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr ""
+"prendi (recupera) e fondi (unisci)? (in pratica una traduzione di fetch + "
+"merge)"
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr "propaga"
+
+#. ""
+msgid "redo"
+msgstr "ripeti, rifai"
+
+#. "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)?"
+
+#. ""
+msgid "reset"
+msgstr "ripristinare, annullare, azzerare, ripristinare"
+
+#. ""
+msgid "revert"
+msgstr ""
+"annullare, inverti (rapidsvn), ritorna allo stato precedente, annulla le "
+"modifiche della revisione"
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr "revisione (TortoiseSVN)"
+
+#. ""
+msgid "sign off"
+msgstr "sign off, firma"
+
+#. ""
+msgid "staging area"
+msgstr ""
+"area di preparazione, zona di preparazione, modifiche in preparazione? "
+"modifiche in allestimento?"
+
+#. ""
+msgid "status"
+msgstr "stato"
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr "etichetta, etichettatura (TortoiseCVS)"
+
+#. ""
+msgid "tag [verb]"
+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}?"
+
+#. ""
+msgid "undo"
+msgstr "annulla"
+
+#. ""
+msgid "update"
+msgstr "aggiornamento, aggiornare"
+
+#. ""
+msgid "verify"
+msgstr "verifica, verificare"
+
+#. "The tree of actual checked out files."
+msgid "working copy, working tree"
+msgstr "directory di lavoro, copia di lavoro"
diff --git a/git-gui/po/glossary/txt-to-pot.sh b/git-gui/po/glossary/txt-to-pot.sh
new file mode 100755
index 000000000..49bf7c536
--- /dev/null
+++ b/git-gui/po/glossary/txt-to-pot.sh
@@ -0,0 +1,48 @@
+#!/bin/sh
+# This is a very, _very_, simple script to convert a tab-separated
+# .txt file into a .pot/.po.
+# Its not clever but it took me 2 minutes to write :)
+# Michael Twomey <michael.twomey@ireland.sun.com>
+# 23 March 2001
+# with slight GnuCash modifications by Christian Stimming <stimming@tuhh.de>
+# 19 Aug 2001, 23 Jul 2007
+
+#check args
+if [ $# -eq 0 ]
+then
+ cat <<!
+Usage: `basename $0` git-gui-glossary.txt > git-gui-glossary.pot
+!
+ exit 1;
+fi
+
+GLOSSARY_CSV="$1";
+
+if [ ! -f "$GLOSSARY_CSV" ]
+then
+ echo "Can't find $GLOSSARY_CSV.";
+ exit 1;
+fi
+
+cat <<!
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR Free Software Foundation, Inc.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"POT-Creation-Date: `date +'%Y-%m-%d %H:%M%z'`\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"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: ENCODING\n"
+
+!
+
+#Yes this is the most simple awk script you've ever seen :)
+awk -F'\t' '{if ($2 != "") print "#. "$2; print "msgid "$1; print "msgstr \"\"\n"}' \
+$GLOSSARY_CSV
diff --git a/git-gui/po/glossary/zh_cn.po b/git-gui/po/glossary/zh_cn.po
new file mode 100644
index 000000000..158835b5c
--- /dev/null
+++ b/git-gui/po/glossary/zh_cn.po
@@ -0,0 +1,170 @@
+# Translation of git-gui glossary to Simplified Chinese
+# Copyright (C) 2007 Shawn Pearce, et al.
+# This file is distributed under the same license as the git package.
+# Xudong Guan <xudong.guan@gmail.com> and the zh-kernel.org mailing list, 2007
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui glossary\n"
+"PO-Revision-Date: 2007-07-23 22:07+0200\n"
+"Last-Translator: Xudong Guan <xudong.guan@gmail.com>\n"
+"Language-Team: Simplified Chinese \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. "English Definition (Dear translator: This file will never be visible to the user! It should only serve as a tool for you, the translator. Nothing more.)"
+msgid ""
+"English Term (Dear translator: This file will never be visible to the user!)"
+msgstr "注:这个文件是为了帮助翻译人员统一åè¯æœ¯è¯­ã€‚最终用户ä¸ä¼šå…³å¿ƒè¿™ä¸ªæ–‡ä»¶ã€‚"
+
+#. ""
+#. amend指用户修改最近一次commitçš„æ“作,修订?修改?修正?
+#. [WANG Cong]: æ ¹æ®æˆ‘的了解,这个è¯ä¼¼ä¹Žç¿»è¯‘æˆâ€œä¿®è®¢â€å¤šä¸€äº›ã€‚“修正â€ä¹Ÿå¯ä»¥ï¼Œâ€œä¿®æ”¹â€å†æ¬¡ä¹‹ã€‚
+#. [ZHANG Le]: 修订,感觉一般指对一些大型出版物的大规模å‡çº§ï¼Œæ¯”如修订新åŽå­—å…¸
+# 修正,其实æ¯æ¬¡amend的结果也ä¸ä¸€å®šå°±æ˜¯æœ€åŽç»“果,说ä¸å®šè¿˜éœ€è¦ä¿®æ”¹ã€‚所以ä¸
+# 如就å«ä¿®æ”¹
+msgid "amend"
+msgstr "修订"
+
+#. ""
+#. git annotate 文件å:用æ¥æ ‡æ³¨æ–‡ä»¶çš„æ¯ä¸€è¡Œåœ¨ä»€ä¹ˆæ—¶å€™è¢«è°æœ€åŽä¿®æ”¹ã€‚
+#. [WANG Cong]: "标记"一般是mark。;)
+#. [ZHANG Le]: 标注,或者干脆用原æ„:注解,或注释
+msgid "annotate"
+msgstr "标注"
+
+#. "A 'branch' is an active line of development."
+msgid "branch [noun]"
+msgstr "分支"
+
+#. ""
+msgid "branch [verb]"
+msgstr "建立分支"
+
+#. ""
+#. [WANG Cong]: 网上有人翻译æˆâ€œæ£€å‡ºâ€ï¼Œæˆ‘感觉更好一些,毕竟把checkçš„æ„æ€ç¿»è¯‘出æ¥äº†ã€‚
+#. [ZHNAG Le]: æå–å§ï¼Œæå–分支ï¼ç‰ˆæœ¬
+#. [rae l]: 签出。subversion软件中的大多è¯æ±‡å·²æœ‰ç¿»è¯‘,既然git与subversionåŒæ˜¯SCM管ç†ï¼Œå¯ä»¥å‚考åŒç±»è½¯ä»¶çš„翻译也ä¸é”™ã€‚
+msgid "checkout [noun]"
+msgstr "签出"
+
+#. "The action of updating the working tree to a revision which was stored in the object database."
+msgid "checkout [verb]"
+msgstr "签出"
+
+#. "A single point in the git history."
+msgid "commit [noun]"
+msgstr "æ交"
+
+#. "The action of storing a new snapshot of the project's state in the git history."
+msgid "commit [verb]"
+msgstr "æ交"
+
+#. ""
+#. 差异?差别?
+#. [ZHANG Le]: 个人感觉差别更加中性一些
+msgid "diff [noun]"
+msgstr "差别"
+
+#. ""
+msgid "diff [verb]"
+msgstr "比较"
+
+#. "A fast-forward is a special type of merge where you have a revision and you are merging another branch's changes that happen to be a descendant of what you have."
+msgid "fast forward merge"
+msgstr "å¿«è¿›å¼åˆå¹¶"
+
+#. "Fetching a branch means to get the branch's head from a remote repository, to find out which objects are missing from the local object database, and to get them, too."
+#. 获å–?å–得?下载?更新?注æ„å’Œupdate的区分
+msgid "fetch"
+msgstr "获å–"
+
+#. "A collection of files. The index is a stored version of your working tree."
+#. index是working tree和repository之间的缓存
+msgid "index (in git-gui: staging area)"
+msgstr "工作缓存?"
+
+#. "A successful merge results in the creation of a new commit representing the result of the merge."
+msgid "merge [noun]"
+msgstr "åˆå¹¶"
+
+#. "To bring the contents of another branch into the current branch."
+msgid "merge [verb]"
+msgstr "åˆå¹¶"
+
+#. ""
+#. message是指commit中的文字信æ¯
+msgid "message"
+msgstr "æè¿°"
+
+#. "Pulling a branch means to fetch it and merge it."
+msgid "pull"
+msgstr "获å–+åˆå¹¶"
+
+#. "Pushing a branch means to get the branch's head ref from a remote repository, and ... (well, can someone please explain it for mere mortals?)"
+msgid "push"
+msgstr "推入"
+
+#. ""
+msgid "redo"
+msgstr "é‡åš"
+
+#. "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 "仓库"
+
+#. ""
+msgid "reset"
+msgstr "é‡ç½®"
+
+#. ""
+msgid "revert"
+msgstr "æ¢å¤"
+
+#. "A particular state of files and directories which was stored in the object database."
+msgid "revision"
+msgstr "版本"
+
+#. ""
+msgid "sign off"
+msgstr "ç­¾å"
+
+#. ""
+#. 似乎是git-gui里é¢æ˜¾ç¤ºçš„本次æ交的文件清å•åŒºåŸŸ
+msgid "staging area"
+msgstr "æ交暂存区"
+
+#. ""
+msgid "status"
+msgstr "状æ€"
+
+#. "A ref pointing to a tag or commit object"
+msgid "tag [noun]"
+msgstr "标签"
+
+#. ""
+msgid "tag [verb]"
+msgstr "添加标签"
+
+#. "A regular git branch that is used to follow changes from another repository."
+msgid "tracking branch"
+msgstr "跟踪分支"
+
+#. ""
+msgid "undo"
+msgstr "撤销"
+
+#. ""
+msgid "update"
+msgstr "更新。注æ„å’Œfetch的区分"
+
+#. ""
+msgid "verify"
+msgstr "验è¯"
+
+#. "The tree of actual checked out files."
+#. "工作副本?工作区域?工作目录"
+#. [LI Yang]: 当å‰å‰¯æœ¬ï¼Œ 当å‰æºç æ ‘?
+msgid "working copy, working tree"
+msgstr "工作副本,工作æºç æ ‘"
diff --git a/git-gui/po/hu.po b/git-gui/po/hu.po
new file mode 100644
index 000000000..e8c04f7ae
--- /dev/null
+++ b/git-gui/po/hu.po
@@ -0,0 +1,1895 @@
+# Hungarian translations for git-gui-i package.
+# Copyright (C) 2007 THE git-gui-i'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the git-gui-i package.
+# Miklos Vajna <vmiklos@frugalware.org>, 2007.
+#
+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"
+"Last-Translator: Miklos Vajna <vmiklos@frugalware.org>\n"
+"Language-Team: Hungarian\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"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
+msgid "git-gui: fatal error"
+msgstr ""
+
+#: git-gui.sh:595
+#, fuzzy, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Érvénytelen font lett megadva a grafikus felületben.%s:"
+
+#: git-gui.sh:620
+msgid "Main Font"
+msgstr "Fő betűtípus"
+
+#: git-gui.sh:621
+msgid "Diff/Console Font"
+msgstr "Diff/konzol betűtípus"
+
+#: git-gui.sh:635
+msgid "Cannot find git in PATH."
+msgstr "A git nem található a PATH-ban."
+
+#: git-gui.sh:662
+msgid "Cannot parse Git version string:"
+msgstr "Nem értelmezhető a Git verzió sztring:"
+
+#: git-gui.sh:680
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Nem állípítható meg a Git verziója.\n"
+"\n"
+"A(z) %s szerint a verzió '%s'.\n"
+"\n"
+"A(z) %s a Git 1.5.0 vagy későbbi verzióját igényli.\n"
+"\n"
+"Feltételezhetjük, hogy a(z) '%s' verziója legalább 1.5.0?\n"
+
+#: git-gui.sh:853
+msgid "Git directory not found:"
+msgstr "A Git könyvtár nem található:"
+
+#: git-gui.sh:860
+#, fuzzy
+msgid "Cannot move to top of working directory:"
+msgstr "Nem használható vicces .git könyvtár:"
+
+#: git-gui.sh:867
+msgid "Cannot use funny .git directory:"
+msgstr "Nem használható vicces .git könyvtár:"
+
+#: git-gui.sh:872
+msgid "No working directory"
+msgstr "Nincs munkakönyvtár"
+
+#: git-gui.sh:1019
+msgid "Refreshing file status..."
+msgstr "A fájlok státuszának frissítése..."
+
+#: git-gui.sh:1084
+msgid "Scanning for modified files ..."
+msgstr "Módosított fájlok keresése ..."
+
+#: git-gui.sh:1259 lib/browser.tcl:245
+msgid "Ready."
+msgstr "Kész."
+
+#: git-gui.sh:1525
+msgid "Unmodified"
+msgstr "Nem módosított"
+
+#: git-gui.sh:1527
+msgid "Modified, not staged"
+msgstr "Módosított, de nem kiválasztott"
+
+#: git-gui.sh:1528 git-gui.sh:1533
+msgid "Staged for commit"
+msgstr "Kiválasztva commitolásra"
+
+#: git-gui.sh:1529 git-gui.sh:1534
+msgid "Portions staged for commit"
+msgstr "Részek kiválasztva commitolásra"
+
+#: git-gui.sh:1530 git-gui.sh:1535
+msgid "Staged for commit, missing"
+msgstr "Kiválasztva commitolásra, hiányzó"
+
+#: git-gui.sh:1532
+msgid "Untracked, not staged"
+msgstr "Nem követett, nem kiválasztott"
+
+#: git-gui.sh:1537
+msgid "Missing"
+msgstr "Hiányzó"
+
+#: git-gui.sh:1538
+msgid "Staged for removal"
+msgstr "Kiválasztva eltávolításra"
+
+#: git-gui.sh:1539
+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
+msgid "Requires merge resolution"
+msgstr "Merge feloldás szükséges"
+
+#: git-gui.sh:1579
+msgid "Starting gitk... please wait..."
+msgstr "A gitk indítása... várjunk..."
+
+#: git-gui.sh:1588
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+"A gitk indítása sikertelen:\n"
+"\n"
+"A(z) %s nem létezik"
+
+#: git-gui.sh:1788 lib/choose_repository.tcl:32
+msgid "Repository"
+msgstr "Repó"
+
+#: git-gui.sh:1789
+msgid "Edit"
+msgstr "Szerkesztés"
+
+#: git-gui.sh:1791 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr "Branch"
+
+#: git-gui.sh:1794 lib/choose_rev.tcl:547
+#, fuzzy
+msgid "Commit@@noun"
+msgstr "Commit"
+
+#: git-gui.sh:1797 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
+msgid "Remote"
+msgstr "Távoli:"
+
+#: git-gui.sh:1807
+msgid "Browse Current Branch's Files"
+msgstr "A jelenlegi branch fájljainak böngészése"
+
+#: git-gui.sh:1811
+msgid "Browse Branch Files..."
+msgstr "A branch fájljainak böngészése..."
+
+#: git-gui.sh:1816
+msgid "Visualize Current Branch's History"
+msgstr "A jelenlegi branch történetének vizualizálása"
+
+#: git-gui.sh:1820
+msgid "Visualize All Branch History"
+msgstr "Az összes branch történetének vizualizálása"
+
+#: git-gui.sh:1827
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "A(z) %s branch fájljainak böngészése"
+
+#: git-gui.sh:1829
+#, 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
+msgid "Database Statistics"
+msgstr "Adatbázis statisztikák"
+
+#: git-gui.sh:1837 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "Adatbázis tömörítése"
+
+#: git-gui.sh:1840
+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
+msgid "Create Desktop Icon"
+msgstr "Asztal ikon létrehozása"
+
+#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95
+msgid "Quit"
+msgstr "Kilépés"
+
+#: git-gui.sh:1867
+msgid "Undo"
+msgstr "Visszavonás"
+
+#: git-gui.sh:1870
+msgid "Redo"
+msgstr "Mégis"
+
+#: git-gui.sh:1874 git-gui.sh:2366
+msgid "Cut"
+msgstr "Kivágás"
+
+#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr "Másolás"
+
+#: git-gui.sh:1880 git-gui.sh:2372
+msgid "Paste"
+msgstr "Beillesztés"
+
+#: git-gui.sh:1883 git-gui.sh:2375 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
+msgid "Select All"
+msgstr "Mindent kiválaszt"
+
+#: git-gui.sh:1896
+msgid "Create..."
+msgstr "Létrehozás..."
+
+#: git-gui.sh:1902
+msgid "Checkout..."
+msgstr "Checkout..."
+
+#: git-gui.sh:1908
+msgid "Rename..."
+msgstr "Ãtnevezés..."
+
+#: git-gui.sh:1913 git-gui.sh:2012
+msgid "Delete..."
+msgstr "Törlés..."
+
+#: git-gui.sh:1918
+msgid "Reset..."
+msgstr "Visszaállítás..."
+
+#: git-gui.sh:1930 git-gui.sh:2313
+msgid "New Commit"
+msgstr "Új commit"
+
+#: git-gui.sh:1938 git-gui.sh:2320
+msgid "Amend Last Commit"
+msgstr "Utolsó commit javítása"
+
+#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "Keresés újra"
+
+#: git-gui.sh:1953
+msgid "Stage To Commit"
+msgstr "Kiválasztás commitolásra"
+
+#: git-gui.sh:1958
+msgid "Stage Changed Files To Commit"
+msgstr "Módosított fájlok kiválasztása commitolásra"
+
+#: git-gui.sh:1964
+msgid "Unstage From Commit"
+msgstr "Commitba való kiválasztás visszavonása"
+
+#: git-gui.sh:1969 lib/index.tcl:352
+msgid "Revert Changes"
+msgstr "Változtatások visszaállítása"
+
+#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390
+msgid "Sign Off"
+msgstr "Aláír"
+
+#: git-gui.sh:1980 git-gui.sh:2296
+#, fuzzy
+msgid "Commit@@verb"
+msgstr "Commit"
+
+#: git-gui.sh:1991
+msgid "Local Merge..."
+msgstr "Helyi merge..."
+
+#: git-gui.sh:1996
+msgid "Abort Merge..."
+msgstr "Merge megszakítása..."
+
+#: git-gui.sh:2008
+msgid "Push..."
+msgstr "Push..."
+
+#: git-gui.sh:2019 lib/choose_repository.tcl:41
+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
+#, tcl-format
+msgid "About %s"
+msgstr "Névjegy: %s"
+
+#: git-gui.sh:2026
+msgid "Preferences..."
+msgstr ""
+
+#: git-gui.sh:2034 git-gui.sh:2558
+msgid "Options..."
+msgstr "Opciók..."
+
+#: git-gui.sh:2040 lib/choose_repository.tcl:47
+msgid "Help"
+msgstr "Segítség"
+
+#: git-gui.sh:2081
+msgid "Online Documentation"
+msgstr "Online dokumentáció"
+
+#: git-gui.sh:2165
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr ""
+
+#: git-gui.sh:2198
+msgid "Current Branch:"
+msgstr "Jelenlegi branch:"
+
+#: git-gui.sh:2219
+#, fuzzy
+msgid "Staged Changes (Will Commit)"
+msgstr "Kiválasztott változtatások (commitolva lesz)"
+
+#: git-gui.sh:2239
+#, fuzzy
+msgid "Unstaged Changes"
+msgstr "Változtatások kiválasztása"
+
+#: git-gui.sh:2286
+msgid "Stage Changed"
+msgstr "Változtatások kiválasztása"
+
+#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "Push"
+
+#: git-gui.sh:2332
+msgid "Initial Commit Message:"
+msgstr "Kezdeti commit üzenet:"
+
+#: git-gui.sh:2333
+msgid "Amended Commit Message:"
+msgstr "Javító commit üzenet:"
+
+#: git-gui.sh:2334
+msgid "Amended Initial Commit Message:"
+msgstr "Kezdeti javító commit üzenet:"
+
+#: git-gui.sh:2335
+msgid "Amended Merge Commit Message:"
+msgstr "Javító merge commit üzenet:"
+
+#: git-gui.sh:2336
+msgid "Merge Commit Message:"
+msgstr "Merge commit üzenet:"
+
+#: git-gui.sh:2337
+msgid "Commit Message:"
+msgstr "Commit üzenet:"
+
+#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71
+msgid "Copy All"
+msgstr "Összes másolása"
+
+#: git-gui.sh:2406 lib/blame.tcl:104
+msgid "File:"
+msgstr "Fájl:"
+
+#: git-gui.sh:2508
+msgid "Refresh"
+msgstr "Frissítés"
+
+#: git-gui.sh:2529
+msgid "Apply/Reverse Hunk"
+msgstr "Hunk alkalmazása/visszaállítása"
+
+#: git-gui.sh:2535
+msgid "Decrease Font Size"
+msgstr "Font méret csökkentése"
+
+#: git-gui.sh:2539
+msgid "Increase Font Size"
+msgstr "Fönt méret növelése"
+
+#: git-gui.sh:2544
+msgid "Show Less Context"
+msgstr "Kevesebb környezet mutatása"
+
+#: git-gui.sh:2551
+msgid "Show More Context"
+msgstr "Több környezet mutatása"
+
+#: git-gui.sh:2565
+msgid "Unstage Hunk From Commit"
+msgstr "Hunk törlése commitból"
+
+#: git-gui.sh:2567
+msgid "Stage Hunk For Commit"
+msgstr "Hunk kiválasztása commitba"
+
+#: git-gui.sh:2586
+msgid "Initializing..."
+msgstr "Inicializálás..."
+
+#: git-gui.sh:2677
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+
+#: git-gui.sh:2707
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+
+#: git-gui.sh:2712
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui - egy grafikus felület a Githez."
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr "Fájl néző"
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr "Commit:"
+
+#: lib/blame.tcl:249
+msgid "Copy Commit"
+msgstr "Commit másolása"
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr "A(z) %s olvasása..."
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr ""
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr ""
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr ""
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr ""
+
+#: lib/blame.tcl:731
+#, fuzzy
+msgid "Loading annotation..."
+msgstr "A(z) %s betöltése..."
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr ""
+
+#: lib/blame.tcl:791
+#, fuzzy
+msgid "Committer:"
+msgstr "Commit:"
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr ""
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr ""
+
+#: lib/blame.tcl:916
+#, fuzzy
+msgid "In File:"
+msgstr "Fájl:"
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr ""
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr "Branch checkoutolása"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "Checkout"
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr "Mégsem"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr "Revízió"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+msgid "Options"
+msgstr "Opciók"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Követő branch letöltése"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr "Helyi branch leválasztása"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr "Branch létrehozása"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr "Új branch létrehozása"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199
+msgid "Create"
+msgstr "Létrehozás"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr "Branch neve"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr "Név:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr "Egyeztetendő követési branch név"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "A következő revíziótól"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "Létező branch frissítése"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "Nem"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Csak fast forward"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr "Visszaállítás"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "Checkout létrehozás után"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr "Válasszunk ki egy követő branchet."
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr "A(z) %s követő branch nem branch a távoli repóban."
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr "Adjunk megy egy branch nevet."
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "A(z) '%s' nem egy elfogadható branch név."
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr "Branch törlése"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr "Helyi branch törlése"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr "Helyi branchek"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "Csak már merge-ölt törlése"
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr "Mindig (Ne legyen merge teszt.)"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "A következő branchek nem teljesen lettek merge-ölve ebbe: %s:"
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+"A törölt branchek visszaállítása bonyolult. \n"
+"\n"
+" Biztosan törli a kiválasztott brancheket?"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"Nem sikerült törölni a következő brancheket:\n"
+"%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr "Branch átnevezése"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "Ãtnevezés"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr "Branch:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "Új név:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr "Válasszunk ki egy átnevezendő branchet."
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "A(z) '%s' branch már létezik."
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Nem sikerült átnevezni: '%s'."
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "Indítás..."
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "Fájl böngésző"
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr "A(z) %s betöltése..."
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr "[Fel a szülőhöz]"
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+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
+msgid "Browse"
+msgstr "Böngészés"
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "A(z) %s letöltése innen: %s"
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr ""
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr "Bezárás"
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "A(z) '%s' branch nem létezik."
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"A(z) '%s' branch már létezik.\n"
+"\n"
+"Nem lehet fast-forwardolni a következőhöz: %s.\n"
+"Egy merge szükséges."
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr "A(z) '%s' merge strategy nem támogatott."
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr "Nem sikerült frissíteni a következőt: '%s'."
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr "A kiválasztási terület (index) már zárolva van."
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Az utolsó keresési állapot nem egyezik meg a repó állpotával.\n"
+"\n"
+"Egy másik Git program módosította ezt a repót az utolsó keresés óta. Egy "
+"újrakeresés mindenképpen szükséges mielőtt a jelenlegi branchet módosítani "
+"lehetne.\n"
+"\n"
+"Az újrakeresés most automatikusan el fog indulni.\n"
+
+#: lib/checkout_op.tcl:322
+#, fuzzy, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "Nincs munkakönyvtár"
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr "A(z) '%s' checkoutja megszakítva (fájlszintű merge-ölés szükséges)."
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr "Fájlszintű merge-ölés szükséges."
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "Jelenleg a(z) '%s' branchen."
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"Már nem egy helyi branchen vagyunk.\n"
+"\n"
+"Ha egy branchen szeretnénk lenni, hozzunk létre egyet az 'Ez a leválasztott "
+"checkout'-ból."
+
+#: lib/checkout_op.tcl:446
+#, fuzzy, tcl-format
+msgid "Checked out '%s'."
+msgstr "Checkout..."
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr ""
+"A(z) '%s' -> '%s' visszaállítás a következő commitok elvesztését jelenti:"
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr "Az elveszett commitok helyreállítása nem biztos, hogy egyszerű."
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "Visszaállítjuk a következőt: '%s'?"
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr "Vizualizálás"
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+"Nem sikerült beállítani a jelenlegi branchet.\n"
+"\n"
+"A munkakönyvtár csak részben váltott át. A fájlok sikeresen frissítve "
+"lettek, de nem sikerült frissíteni egy belső Git fájlt.\n"
+"\n"
+"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"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr ""
+
+#: lib/choose_font.tcl:73
+#, fuzzy
+msgid "Font Size"
+msgstr "Font méret csökkentése"
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr ""
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+
+#: lib/choose_repository.tcl:25
+msgid "Git Gui"
+msgstr ""
+
+#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
+#, fuzzy
+msgid "Create New Repository"
+msgstr "Forrás repó"
+
+#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
+#, fuzzy
+msgid "Clone Existing Repository"
+msgstr "Cél repó"
+
+#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
+#, fuzzy
+msgid "Open Existing Repository"
+msgstr "Cél repó"
+
+#: lib/choose_repository.tcl:91
+msgid "Next >"
+msgstr ""
+
+#: lib/choose_repository.tcl:152
+#, fuzzy, tcl-format
+msgid "Location %s already exists."
+msgstr "A(z) '%s' branch már létezik."
+
+#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165
+#: lib/choose_repository.tcl:172
+#, fuzzy, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "Nem sikerült teljesen elmenteni a beállításokat:"
+
+#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
+msgid "Directory:"
+msgstr ""
+
+#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
+#: lib/choose_repository.tcl:834
+#, fuzzy
+msgid "Git Repository"
+msgstr "Repó"
+
+#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
+#, fuzzy, tcl-format
+msgid "Directory %s already exists."
+msgstr "A(z) '%s' branch már létezik."
+
+#: lib/choose_repository.tcl:265
+#, fuzzy, tcl-format
+msgid "File %s already exists."
+msgstr "A(z) '%s' branch már létezik."
+
+#: lib/choose_repository.tcl:286
+#, fuzzy
+msgid "Clone"
+msgstr "Bezárás"
+
+#: lib/choose_repository.tcl:299
+msgid "URL:"
+msgstr ""
+
+#: lib/choose_repository.tcl:319
+msgid "Clone Type:"
+msgstr ""
+
+#: lib/choose_repository.tcl:325
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr ""
+
+#: lib/choose_repository.tcl:331
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr ""
+
+#: lib/choose_repository.tcl:337
+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
+#, fuzzy, tcl-format
+msgid "Not a Git repository: %s"
+msgstr "Nincs kiválasztott repó."
+
+#: lib/choose_repository.tcl:405
+msgid "Standard only available for local repository."
+msgstr ""
+
+#: lib/choose_repository.tcl:409
+msgid "Shared only available for local repository."
+msgstr ""
+
+#: lib/choose_repository.tcl:439
+msgid "Failed to configure origin"
+msgstr ""
+
+#: lib/choose_repository.tcl:451
+msgid "Counting objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:452
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:476
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:512
+#, fuzzy, tcl-format
+msgid "Nothing to clone from %s."
+msgstr "Új változások letöltése innen: %s"
+
+#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728
+#: lib/choose_repository.tcl:740
+msgid "The 'master' branch has not been initialized."
+msgstr ""
+
+#: lib/choose_repository.tcl:527
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr ""
+
+#: lib/choose_repository.tcl:539
+#, fuzzy, tcl-format
+msgid "Cloning from %s"
+msgstr "A(z) %s letöltése innen: %s"
+
+#: lib/choose_repository.tcl:570
+#, fuzzy
+msgid "Copying objects"
+msgstr "Az objektum adatbázis tömörítése"
+
+#: lib/choose_repository.tcl:571
+msgid "KiB"
+msgstr ""
+
+#: lib/choose_repository.tcl:595
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:605
+msgid "Linking objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:606
+msgid "objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:614
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:669
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:680
+msgid "Cannot fetch tags. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:704
+msgid "Cannot determine HEAD. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:713
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:719
+#, fuzzy
+msgid "Clone failed."
+msgstr "A félbeszakítás nem sikerült."
+
+#: lib/choose_repository.tcl:726
+msgid "No default branch obtained."
+msgstr ""
+
+#: lib/choose_repository.tcl:737
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr ""
+
+#: lib/choose_repository.tcl:749
+#, fuzzy
+msgid "Creating working directory"
+msgstr "Nincs munkakönyvtár"
+
+#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80
+#: lib/index.tcl:149
+msgid "files"
+msgstr ""
+
+#: lib/choose_repository.tcl:779
+msgid "Initial file checkout failed."
+msgstr ""
+
+#: lib/choose_repository.tcl:795
+msgid "Open"
+msgstr ""
+
+#: lib/choose_repository.tcl:805
+#, fuzzy
+msgid "Repository:"
+msgstr "Repó"
+
+#: lib/choose_repository.tcl:854
+#, fuzzy, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Nem sikerült teljesen elmenteni a beállításokat:"
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr "Ez a leválasztott checkout"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Revízió kifejezés:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr "Helyi branch"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr "Követő branch"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr "Tag"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "Érvénytelen revízió: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "Nincs kiválasztva revízió."
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "A revízió kifejezés üres."
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr ""
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr ""
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"Nincs semmi javítanivaló.\n"
+"\n"
+"Az első commit létrehozása előtt nincs semmilyen commit amit javitani "
+"lehetne.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"Nem lehet javítani merge alatt.\n"
+"\n"
+"A jelenlegi merge még nem teljesen fejeződött be. Csak akkor javíthat egy "
+"előbbi commitot, hogyha megszakítja a jelenlegi merge folyamatot.\n"
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr "Hiba a javítandó commit adat betöltése közben:"
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr "Nem sikerült megállapítani az azonosítót:"
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "Érvénytelen GIT_COMMITTER_IDENT:"
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Az utolsó keresési állapot nem egyezik meg a repó állapotával.\n"
+"\n"
+"Egy másik Git program módosította ezt a repót az utolsó keresés óta. Egy "
+"újrakeresés mindenképpen szükséges mielőtt a jelenlegi branchet módosítani "
+"lehetne.\n"
+"\n"
+"Az újrakeresés most automatikusan el fog indulni.\n"
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"Nem commitolhatunk fájlokat merge előtt.\n"
+"\n"
+"A(z) %s fájlban ütközések vannak. Egyszer azokat ki kell javítani, majd "
+"hozzá ki kell választani a fájlt mielőtt commitolni lehetne.\n"
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"Ismeretlen fájl típus %s érzékelve.\n"
+"\n"
+"A(z) %s fájlt nem tudja ez a program commitolni.\n"
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"Nincs commitolandó változtatás.\n"
+"\n"
+"Legalább egy fájl ki kell választani, hogy commitolni lehessen.\n"
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"Adjunk megy egy commit üzenetet.\n"
+"\n"
+"Egy jó commit üzenetnek a következő a formátuma:\n"
+"\n"
+"- Első sor: Egy mondatban leírja, hogy mit csináltunk.\n"
+"- Második sor: Üres\n"
+"- A többi sor: Leírja, hogy miért jó ez a változtatás.\n"
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr "a write-tree sikertelen:"
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr ""
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"Nincs commitolandó változtatás.\n"
+"\n"
+"Egyetlen fájlt se módosított ez a commit és merge commit se volt.\n"
+"\n"
+"Az újrakeresés most automatikusan el fog indulni.\n"
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr "Nincs commitolandó változtatás."
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr ""
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr "a commit-tree sikertelen:"
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr "az update-ref sikertelen:"
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "Létrejött a %s commit: %s"
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr "Munka folyamatban.. Várjunk..."
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr "Siker"
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr "Hiba: a parancs sikertelen"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "Elvesztett objektumok száma"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "Elveszett objektumok által elfoglalt lemezterület"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "Csomagolt objektumok számra"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "Csomagok száma"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "A csomagolt objektumok által használt lemezterület"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "Eltávolításra váró csomagolt objektumok számra"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "Hulladék fájlok"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Az objektum adatbázis tömörítése"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "Az objektum adatbázis ellenőrzése az fsck-objects használatával"
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+
+#: lib/date.tcl:25
+#, fuzzy, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Érvénytelen revízió: %s"
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Nincsenek változások.\n"
+"\n"
+"A(z) %s módosítatlan.\n"
+"\n"
+"A fájl módosítási dátumát frissítette egy másik alkalmazás, de a fájl "
+"tartalma változatlan.\n"
+"\n"
+"Egy újrakeresés fog indulni a hasonló állapotú fájlok megtalálása érdekében."
+
+#: lib/diff.tcl:81
+#, fuzzy, tcl-format
+msgid "Loading diff of %s..."
+msgstr "A(z) %s betöltése..."
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr ""
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr "Hiba a fájl betöltése közben:"
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr ""
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr ""
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr "Hiba a diff betöltése közben:"
+
+#: lib/diff.tcl:302
+msgid "Failed to unstage selected hunk."
+msgstr "Nem visszavonni a hunk kiválasztását."
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr "Nem sikerült kiválasztani a hunkot."
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr "hiba"
+
+#: lib/error.tcl:28
+msgid "warning"
+msgstr "figyelmeztetés"
+
+#: lib/error.tcl:81
+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
+msgid "Unstaging %s from commit"
+msgstr "Commitba való kiválasztás visszavonása"
+
+#: lib/index.tcl:285
+#, fuzzy, tcl-format
+msgid "Adding %s"
+msgstr "A(z) %s olvasása..."
+
+#: lib/index.tcl:340
+#, 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
+#, 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
+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
+msgid "Do Nothing"
+msgstr "Ne csináljunk semmit"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"Javítás közben nem lehetséges a merge.\n"
+"\n"
+"Egyszer be kell fejezni ennek a commitnak a javítását, majd kezdődhet egy "
+"merge.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"Az utolsó keresési állapot nem egyezik meg a repó állapotával.\n"
+"\n"
+"Egy másik Git program módosította ezt a repót az utolsó keresés óta. Egy "
+"újrakeresés mindenképpen szükséges mielőtt a jelenlegi branchet módosítani "
+"lehetne.\n"
+"\n"
+"Az újrakeresés most automatikusan el fog indulni.\n"
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"Jelenleg egy ütközés feloldása közben vagyunk.\n"
+"\n"
+"A(z) %s fájlban ütközések vannak.\n"
+"\n"
+"Fel kell oldanunk őket, kiválasztani a fájlt, és commitolni hogy befejezzük "
+"a jelenlegi merge-t. Csak ezután kezdhetünk el egy újabbat.\n"
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"Jelenleg egy változtatás közben vagyunk.\n"
+"\n"
+"A(z) %s fájl megváltozott.\n"
+"\n"
+"Először be kell fejeznünk a jelenlegi commitot, hogy elkezdhessünk egy merge-"
+"t. Ez segíteni fog, hogy félbeszakíthassunk egy merge-t.\n"
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s / %s"
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr "A(z) %s és a(z) %s merge-ölése"
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr "A merge sikeresen befejeződött."
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr "A merge sikertelen. Fel kell oldanunk az ütközéseket."
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Merge-ölés a következőbe: %s"
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr "Merge-ölni szándékozott revízió"
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"A commit javítás közben megszakítva.\n"
+"\n"
+"Be kell fejeznünk ennek a commitnak a javítását.\n"
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"Megszakítjuk a merge-t?\n"
+"\n"
+"A jelenlegi merge megszakítása *MINDEN* nem commitolt változtatás "
+"elvesztését jelenti.\n"
+"\n"
+"Folytatjuk a jelenlegi merge megszakítását?"
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"Visszavonjuk a módosításokat?\n"
+"\n"
+"A módosítások visszavonása *MINDEN* nem commitolt változtatás elvesztését "
+"jelenti.\n"
+"\n"
+"Folytatjuk a jelenlegi módosítások visszavonását?"
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr "Félbeszakítás"
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr "A félbeszakítás nem sikerült."
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr "A megkeszakítás befejeződött. Kész."
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr "Alapértelmezés visszaállítása"
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr "Mentés"
+
+#: lib/option.tcl:96
+#, tcl-format
+msgid "%s Repository"
+msgstr "%s Repó"
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr "Globális (minden repó)"
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr "Felhasználónév"
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr "Email cím"
+
+#: lib/option.tcl:106
+msgid "Summarize Merge Commits"
+msgstr "A merge commitok összegzése"
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr "Merge beszédesség"
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr "Diffstat mutatása merge után"
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr "A fájl módosítási dátumok megbízhatóak"
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr "A követő branchek eltávolítása letöltés alatt"
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr "A követő branchek egyeztetése"
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr "A diff környezeti sorok száma"
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr "Új branch név sablon"
+
+#: lib/option.tcl:176
+#, fuzzy
+msgid "Change Font"
+msgstr "Fő betűtípus"
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr ""
+
+#: lib/option.tcl:186
+msgid "pt."
+msgstr ""
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr ""
+
+#: 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"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "Forrás repó"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr "Távoli:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr "Tetszőleges URL:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr "Branchek"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "Törlés csak akkor ha"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "Merge-ölt a következőbe:"
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "Mindig (Ne végezzen merge vizsgálatokat)"
+
+#: lib/remote_branch_delete.tcl:152
+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
+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:"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+"Egy vagy több merge teszt hibát jelzett, mivel nem töltöttük le a megfelelő "
+"commitokat. Próbáljunk meg letölteni a következőből: %s először."
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr "Válasszunk ki egy vagy több branchet törlésre."
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"A törölt branchek visszaállítása nehéz.\n"
+"\n"
+"Töröljük a kiválasztott brancheket?"
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "Brancek törlése innen: %s"
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr "Nincs kiválasztott repó."
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+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/shortcut.tcl:149
+msgid "Cannot write icon:"
+msgstr "Nem sikerült írni az ikont:"
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%s ... %*i / %*i %s (%3i%%)"
+
+#: lib/transport.tcl:6
+#, fuzzy, tcl-format
+msgid "fetch %s"
+msgstr "Letöltés"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "Új változások letöltése innen: %s"
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr ""
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+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 ""
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Változások pusholása ide: %s"
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "Pusholás: %s %s, ide: %s"
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr "Branchek pusholása"
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr "Forrás branchek"
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr "Cél repó"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr "Ãtviteli opciók"
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr "Vékony csomagok használata (lassú hálózati kapcsolatok számára)"
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr "Tageket is"
+
+#~ msgid "Cannot find the git directory:"
+#~ msgstr "Nem található a git könyvtár:"
+
+#~ msgid "Unstaged Changes (Will Not Be Committed)"
+#~ msgstr "Nem kiválasztott változtatások (nem lesz commitolva)"
+
+#~ msgid "Push to %s..."
+#~ msgstr "Pusholás ide: %s..."
+
+#~ msgid "Add To Commit"
+#~ msgstr "Hozzáadás a commithoz"
+
+#~ msgid "Add Existing To Commit"
+#~ msgstr "Hozzáadás létező commithoz"
+
+#~ msgid "Running miga..."
+#~ msgstr "A miga futtatása..."
+
+#~ msgid "Add Existing"
+#~ msgstr "Létező hozzáadása"
+
+#~ msgid ""
+#~ "Abort commit?\n"
+#~ "\n"
+#~ "Aborting the current commit will cause *ALL* uncommitted changes to be "
+#~ "lost.\n"
+#~ "\n"
+#~ "Continue with aborting the current commit?"
+#~ msgstr ""
+#~ "Megszakítjuk a commitot?\n"
+#~ "\n"
+#~ "A jelenlegi commit megszakítása *MINDEN* nem commitolt változtatás "
+#~ "elvesztését jelenti.\n"
+#~ "\n"
+#~ "Folytatjuk a jelenlegi commit megszakítását?"
+
+#~ msgid "Aborting... please wait..."
+#~ msgstr "Megszakítás... várjunk..."
diff --git a/git-gui/po/it.po b/git-gui/po/it.po
new file mode 100644
index 000000000..766841410
--- /dev/null
+++ b/git-gui/po/it.po
@@ -0,0 +1,1872 @@
+# Translation of git-gui to Italian
+# Copyright (C) 2007 Shawn Pearce
+# This file is distributed under the same license as the git-gui package.
+# Paolo Ciarrocchi <paolo.ciarrocchi@gmail.com>, 2007
+# Michele Ballabio <barra_cuda@katamail.com>, 2007.
+#
+#
+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"
+"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
+msgid "git-gui: fatal error"
+msgstr "git-gui: errore grave"
+
+#: git-gui.sh:595
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Caratteri non validi specificati in %s:"
+
+#: git-gui.sh:620
+msgid "Main Font"
+msgstr "Caratteri principali"
+
+#: git-gui.sh:621
+msgid "Diff/Console Font"
+msgstr "Caratteri per confronti e terminale"
+
+#: git-gui.sh:635
+msgid "Cannot find git in PATH."
+msgstr "Impossibile trovare git nel PATH"
+
+#: git-gui.sh:662
+msgid "Cannot parse Git version string:"
+msgstr "Impossibile determinare la versione di Git:"
+
+#: git-gui.sh:680
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"La versione di GIT non può essere determinata.\n"
+"\n"
+"%s riporta che la versione è '%s'.\n"
+"\n"
+"%s richiede almeno Git 1.5.0 o superiore.\n"
+"\n"
+"Assumere che '%s' sia alla versione 1.5.0?\n"
+
+#: git-gui.sh:853
+msgid "Git directory not found:"
+msgstr "Non trovo la directory di git: "
+
+#: git-gui.sh:860
+msgid "Cannot move to top of working directory:"
+msgstr "Impossibile spostarsi sulla directory principale del progetto:"
+
+#: git-gui.sh:867
+msgid "Cannot use funny .git directory:"
+msgstr "Impossibile usare una .git directory strana:"
+
+#: git-gui.sh:872
+msgid "No working directory"
+msgstr "Nessuna directory di lavoro"
+
+#: git-gui.sh:1019
+msgid "Refreshing file status..."
+msgstr "Controllo dello stato dei file in corso..."
+
+#: git-gui.sh:1084
+msgid "Scanning for modified files ..."
+msgstr "Ricerca di file modificati in corso..."
+
+#: git-gui.sh:1259 lib/browser.tcl:245
+msgid "Ready."
+msgstr "Pronto."
+
+#: git-gui.sh:1525
+msgid "Unmodified"
+msgstr "Non modificato"
+
+#: git-gui.sh:1527
+msgid "Modified, not staged"
+msgstr "Modificato, non preparato per una nuova revisione"
+
+#: git-gui.sh:1528 git-gui.sh:1533
+msgid "Staged for commit"
+msgstr "Preparato per una nuova revisione"
+
+#: git-gui.sh:1529 git-gui.sh:1534
+msgid "Portions staged for commit"
+msgstr "Parti preparate per una nuova revisione"
+
+#: git-gui.sh:1530 git-gui.sh:1535
+msgid "Staged for commit, missing"
+msgstr "Preparato per una nuova revisione, mancante"
+
+#: git-gui.sh:1532
+msgid "Untracked, not staged"
+msgstr "Non tracciato, non preparato per una nuova revisione"
+
+#: git-gui.sh:1537
+msgid "Missing"
+msgstr "Mancante"
+
+#: git-gui.sh:1538
+msgid "Staged for removal"
+msgstr "Preparato per la rimozione"
+
+#: git-gui.sh:1539
+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
+msgid "Requires merge resolution"
+msgstr "Richiede risoluzione dei conflitti"
+
+#: git-gui.sh:1579
+msgid "Starting gitk... please wait..."
+msgstr "Avvio di gitk... attendere..."
+
+#: git-gui.sh:1588
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+"Impossibile avviare gitk:\n"
+"\n"
+"%s non esiste"
+
+#: git-gui.sh:1788 lib/choose_repository.tcl:32
+msgid "Repository"
+msgstr "Archivio"
+
+#: git-gui.sh:1789
+msgid "Edit"
+msgstr "Modifica"
+
+#: git-gui.sh:1791 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr "Ramo"
+
+#: git-gui.sh:1794 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
+msgid "Merge"
+msgstr "Fusione (Merge)"
+
+#: git-gui.sh:1798 lib/choose_rev.tcl:556
+msgid "Remote"
+msgstr "Remoto"
+
+#: git-gui.sh:1807
+msgid "Browse Current Branch's Files"
+msgstr "Esplora i file del ramo corrente"
+
+#: git-gui.sh:1811
+msgid "Browse Branch Files..."
+msgstr "Esplora i file del ramo..."
+
+#: git-gui.sh:1816
+msgid "Visualize Current Branch's History"
+msgstr "Visualizza la cronologia del ramo corrente"
+
+#: git-gui.sh:1820
+msgid "Visualize All Branch History"
+msgstr "Visualizza la cronologia di tutti i rami"
+
+#: git-gui.sh:1827
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "Esplora i file di %s"
+
+#: git-gui.sh:1829
+#, 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
+msgid "Database Statistics"
+msgstr "Statistiche dell'archivio"
+
+#: git-gui.sh:1837 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "Comprimi l'archivio"
+
+#: git-gui.sh:1840
+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
+msgid "Create Desktop Icon"
+msgstr "Crea icona desktop"
+
+#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95
+msgid "Quit"
+msgstr "Esci"
+
+#: git-gui.sh:1867
+msgid "Undo"
+msgstr "Annulla"
+
+#: git-gui.sh:1870
+msgid "Redo"
+msgstr "Ripeti"
+
+#: git-gui.sh:1874 git-gui.sh:2366
+msgid "Cut"
+msgstr "Taglia"
+
+#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr "Copia"
+
+#: git-gui.sh:1880 git-gui.sh:2372
+msgid "Paste"
+msgstr "Incolla"
+
+#: git-gui.sh:1883 git-gui.sh:2375 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
+msgid "Select All"
+msgstr "Seleziona tutto"
+
+#: git-gui.sh:1896
+msgid "Create..."
+msgstr "Crea..."
+
+#: git-gui.sh:1902
+msgid "Checkout..."
+msgstr "Attiva..."
+
+#: git-gui.sh:1908
+msgid "Rename..."
+msgstr "Rinomina"
+
+#: git-gui.sh:1913 git-gui.sh:2012
+msgid "Delete..."
+msgstr "Elimina..."
+
+#: git-gui.sh:1918
+msgid "Reset..."
+msgstr "Ripristina..."
+
+#: git-gui.sh:1930 git-gui.sh:2313
+msgid "New Commit"
+msgstr "Nuova revisione"
+
+#: git-gui.sh:1938 git-gui.sh:2320
+msgid "Amend Last Commit"
+msgstr "Correggi l'ultima revisione"
+
+#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "Analizza nuovamente"
+
+#: git-gui.sh:1953
+msgid "Stage To Commit"
+msgstr "Prepara per una nuova revisione"
+
+#: git-gui.sh:1958
+msgid "Stage Changed Files To Commit"
+msgstr "Prepara i file modificati per una nuova revisione"
+
+#: git-gui.sh:1964
+msgid "Unstage From Commit"
+msgstr "Annulla preparazione"
+
+#: git-gui.sh:1969 lib/index.tcl:352
+msgid "Revert Changes"
+msgstr "Annulla modifiche"
+
+#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390
+msgid "Sign Off"
+msgstr "Sign Off"
+
+#: git-gui.sh:1980 git-gui.sh:2296
+msgid "Commit@@verb"
+msgstr "Nuova revisione"
+
+#: git-gui.sh:1991
+msgid "Local Merge..."
+msgstr "Fusione locale..."
+
+#: git-gui.sh:1996
+msgid "Abort Merge..."
+msgstr "Interrompi fusione..."
+
+#: git-gui.sh:2008
+msgid "Push..."
+msgstr "Propaga..."
+
+#: git-gui.sh:2019 lib/choose_repository.tcl:41
+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
+#, tcl-format
+msgid "About %s"
+msgstr "Informazioni su %s"
+
+#: git-gui.sh:2026
+msgid "Preferences..."
+msgstr "Preferenze..."
+
+#: git-gui.sh:2034 git-gui.sh:2558
+msgid "Options..."
+msgstr "Opzioni..."
+
+#: git-gui.sh:2040 lib/choose_repository.tcl:47
+msgid "Help"
+msgstr "Aiuto"
+
+#: git-gui.sh:2081
+msgid "Online Documentation"
+msgstr "Documentazione sul web"
+
+#: git-gui.sh:2165
+#, 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
+msgid "Current Branch:"
+msgstr "Ramo attuale:"
+
+#: git-gui.sh:2219
+msgid "Staged Changes (Will Commit)"
+msgstr "Modifiche preparate (saranno nella nuova revisione)"
+
+#: git-gui.sh:2239
+msgid "Unstaged Changes"
+msgstr "Modifiche non preparate"
+
+#: git-gui.sh:2286
+msgid "Stage Changed"
+msgstr "Prepara modificati"
+
+#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "Propaga (Push)"
+
+#: git-gui.sh:2332
+msgid "Initial Commit Message:"
+msgstr "Messaggio di revisione iniziale:"
+
+#: git-gui.sh:2333
+msgid "Amended Commit Message:"
+msgstr "Messaggio di revisione corretto:"
+
+#: git-gui.sh:2334
+msgid "Amended Initial Commit Message:"
+msgstr "Messaggio iniziale di revisione corretto:"
+
+#: git-gui.sh:2335
+msgid "Amended Merge Commit Message:"
+msgstr "Messaggio di fusione corretto:"
+
+#: git-gui.sh:2336
+msgid "Merge Commit Message:"
+msgstr "Messaggio di fusione:"
+
+#: git-gui.sh:2337
+msgid "Commit Message:"
+msgstr "Messaggio di revisione:"
+
+#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71
+msgid "Copy All"
+msgstr "Copia tutto"
+
+#: git-gui.sh:2406 lib/blame.tcl:104
+msgid "File:"
+msgstr "File:"
+
+#: git-gui.sh:2508
+msgid "Refresh"
+msgstr "Rinfresca"
+
+#: git-gui.sh:2529
+msgid "Apply/Reverse Hunk"
+msgstr "Applica/Inverti sezione"
+
+#: git-gui.sh:2535
+msgid "Decrease Font Size"
+msgstr "Diminuisci dimensione caratteri"
+
+#: git-gui.sh:2539
+msgid "Increase Font Size"
+msgstr "Aumenta dimensione caratteri"
+
+#: git-gui.sh:2544
+msgid "Show Less Context"
+msgstr "Mostra meno contesto"
+
+#: git-gui.sh:2551
+msgid "Show More Context"
+msgstr "Mostra più contesto"
+
+#: git-gui.sh:2565
+msgid "Unstage Hunk From Commit"
+msgstr "Sezione non preparata per una nuova revisione"
+
+#: git-gui.sh:2567
+msgid "Stage Hunk For Commit"
+msgstr "Prepara sezione per una nuova revisione"
+
+#: git-gui.sh:2586
+msgid "Initializing..."
+msgstr "Inizializzazione..."
+
+#: git-gui.sh:2677
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+"Possibili problemi con le variabili d'ambiente.\n"
+"\n"
+"Le seguenti variabili d'ambiente saranno probabilmente\n"
+"ignorate da tutti i sottoprocessi di Git avviati\n"
+"da %s:\n"
+"\n"
+
+#: git-gui.sh:2707
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+"\n"
+"Ciò è dovuto a un problema conosciuto\n"
+"causato dall'eseguibile Tcl distribuito da Cygwin."
+
+#: git-gui.sh:2712
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+"\n"
+"\n"
+"Una buona alternativa a %s\n"
+"consiste nell'assegnare valori alle variabili di configurazione\n"
+"user.name e user.email nel tuo file ~/.gitconfig personale.\n"
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui - un'interfaccia grafica per Git."
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr "Mostra file"
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr "Revisione:"
+
+#: lib/blame.tcl:249
+msgid "Copy Commit"
+msgstr "Copia revisione"
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr "Lettura di %s..."
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr "Caricamento annotazioni per copie/spostamenti..."
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr "linee annotate"
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr "Caricamento annotazioni per posizione originaria..."
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr "Annotazione completata."
+
+#: lib/blame.tcl:731
+msgid "Loading annotation..."
+msgstr "Caricamento annotazioni..."
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr "Autore:"
+
+#: lib/blame.tcl:791
+msgid "Committer:"
+msgstr "Revisione creata da:"
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr "File originario:"
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr "In origine da:"
+
+#: lib/blame.tcl:916
+msgid "In File:"
+msgstr "Nel file:"
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr "Copiato o spostato qui da:"
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr "Attiva ramo"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "Attiva"
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr "Annulla"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr "Revisione"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+msgid "Options"
+msgstr "Opzioni"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Recupera duplicato locale di ramo remoto"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr "Stacca da ramo locale"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr "Crea ramo"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr "Crea nuovo ramo"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199
+msgid "Create"
+msgstr "Crea"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr "Nome del ramo"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr "Nome:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr "Appaia nome del duplicato locale di ramo remoto"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "Revisione iniziale"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "Aggiorna ramo esistente:"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "No"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Solo fast forward"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr "Ripristina"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "Attiva dopo la creazione"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr "Scegliere un duplicato locale di ramo remoto"
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr ""
+"Il duplicato locale del ramo remoto %s non è un ramo nell'archivio remoto."
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr "Inserire un nome per il ramo."
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "'%s' non è utilizzabile come nome di ramo."
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr "Elimina ramo"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr "Elimina ramo locale"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr "Rami locali"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "Cancella solo se fuso con un altro ramo"
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr "Sempre (Non effettuare verifiche di fusione)."
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "I rami seguenti non sono stati fusi completamente in %s:"
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+"Ricomporre rami cancellati può essere complicato. \n"
+"\n"
+" Eliminare i rami selezionati?"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"Cancellazione rami fallita:\n"
+"%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr "Rinomina ramo"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "Rinomina"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr "Ramo:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "Nuovo Nome:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr "Scegliere un ramo da rinominare."
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "Il ramo '%s' esiste già."
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Impossibile rinominare '%s'."
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "Avvio in corso..."
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "File browser"
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr "Caricamento %s..."
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr "[Directory superiore]"
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+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
+msgid "Browse"
+msgstr "Sfoglia"
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "Recupero %s da %s"
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr "errore grave: impossibile risolvere %s"
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr "Chiudi"
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "Il ramo '%s' non esiste."
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"Il ramo '%s' esiste già.\n"
+"\n"
+"Non può effettuare un 'fast-forward' a %s.\n"
+"E' necessaria una fusione."
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+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."
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr "L'area di preparazione per una nuova revisione (indice) è già bloccata."
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"L'ultimo stato analizzato non corrisponde allo stato dell'archivio.\n"
+"\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"
+"\n"
+"La nuova analisi comincerà ora.\n"
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "Aggiornamento della directory di lavoro a '%s' in corso..."
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr "Attivazione di '%s' fallita (richiesta una fusione a livello file)."
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr "E' richiesta una fusione a livello file."
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "Si rimarrà sul ramo '%s'."
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"Non si è più su un ramo locale\n"
+"\n"
+"Se si vuole rimanere su un ramo, crearne uno ora a partire da 'Questa "
+"revisione attiva staccata'."
+
+#: lib/checkout_op.tcl:446
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr "Attivazione di '%s' completata."
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr ""
+"Ripristinare '%s' a '%s' comporterà la perdita delle seguenti revisioni:"
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr "Ricomporre le revisioni perdute potrebbe non essere semplice."
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "Ripristinare '%s'?"
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr "Visualizza"
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+"Preparazione ramo corrente fallita.\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 "
+"prodotto degli errori.\n"
+"\n"
+"Questo non sarebbe dovuto succedere. %s ora terminerà senza altre azioni."
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr "Seleziona"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr "Famiglia di caratteri"
+
+#: lib/choose_font.tcl:73
+msgid "Font Size"
+msgstr "Dimensione caratteri"
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr "Esempio caratteri"
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"Questo è un testo d'esempio.\n"
+"Se ti piace questo testo, può essere il carattere giusto."
+
+#: lib/choose_repository.tcl:25
+msgid "Git Gui"
+msgstr "Git Gui"
+
+#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
+msgid "Create New Repository"
+msgstr "Crea nuovo archivio"
+
+#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
+msgid "Clone Existing Repository"
+msgstr "Clona archivio esistente"
+
+#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
+msgid "Open Existing Repository"
+msgstr "Apri archivio esistente"
+
+#: lib/choose_repository.tcl:91
+msgid "Next >"
+msgstr "Successivo >"
+
+#: lib/choose_repository.tcl:152
+#, 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
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "Impossibile creare l'archivio %s:"
+
+#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
+msgid "Directory:"
+msgstr "Directory:"
+
+#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
+#: lib/choose_repository.tcl:834
+msgid "Git Repository"
+msgstr "Archivio Git"
+
+#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "La directory %s esiste già."
+
+#: lib/choose_repository.tcl:265
+#, tcl-format
+msgid "File %s already exists."
+msgstr "Il file %s esiste già."
+
+#: lib/choose_repository.tcl:286
+msgid "Clone"
+msgstr "Clona"
+
+#: lib/choose_repository.tcl:299
+msgid "URL:"
+msgstr "URL:"
+
+#: lib/choose_repository.tcl:319
+msgid "Clone Type:"
+msgstr "Tipo di clone:"
+
+#: lib/choose_repository.tcl:325
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr "Standard (veloce, semi-ridondante, con hardlink)"
+
+#: lib/choose_repository.tcl:331
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "Copia completa (più lento, backup ridondante)"
+
+#: lib/choose_repository.tcl:337
+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
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr "%s non è un archivio Git."
+
+#: lib/choose_repository.tcl:405
+msgid "Standard only available for local repository."
+msgstr "Standard è disponibile solo per archivi locali."
+
+#: lib/choose_repository.tcl:409
+msgid "Shared only available for local repository."
+msgstr "Shared è disponibile solo per archivi locali."
+
+#: lib/choose_repository.tcl:439
+msgid "Failed to configure origin"
+msgstr "Impossibile configurare origin"
+
+#: lib/choose_repository.tcl:451
+msgid "Counting objects"
+msgstr "Calcolo oggetti"
+
+#: lib/choose_repository.tcl:452
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:476
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr "Impossibile copiare oggetti/info/alternate: %s"
+
+#: lib/choose_repository.tcl:512
+#, 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
+msgid "The 'master' branch has not been initialized."
+msgstr "Il ramo 'master' non è stato inizializzato."
+
+#: lib/choose_repository.tcl:527
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr "Impossibile utilizzare gli hardlink. Si ricorrerà alla copia."
+
+#: lib/choose_repository.tcl:539
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "Clonazione da %s"
+
+#: lib/choose_repository.tcl:570
+msgid "Copying objects"
+msgstr "Copia degli oggetti"
+
+#: lib/choose_repository.tcl:571
+msgid "KiB"
+msgstr "KiB"
+
+#: lib/choose_repository.tcl:595
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "Impossibile copiare oggetto: %s"
+
+#: lib/choose_repository.tcl:605
+msgid "Linking objects"
+msgstr "Collegamento oggetti"
+
+#: lib/choose_repository.tcl:606
+msgid "objects"
+msgstr "oggetti"
+
+#: lib/choose_repository.tcl:614
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr "Hardlink impossibile sull'oggetto: %s"
+
+#: lib/choose_repository.tcl:669
+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
+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
+msgid "Cannot determine HEAD. See console output for details."
+msgstr ""
+"Impossibile determinare HEAD. Controllare i dettagli forniti dalla console."
+
+#: lib/choose_repository.tcl:713
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr "Impossibile ripulire %s"
+
+#: lib/choose_repository.tcl:719
+msgid "Clone failed."
+msgstr "Clonazione fallita."
+
+#: lib/choose_repository.tcl:726
+msgid "No default branch obtained."
+msgstr "Non è stato trovato un ramo predefinito."
+
+#: lib/choose_repository.tcl:737
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr "Impossibile risolvere %s come una revisione."
+
+#: lib/choose_repository.tcl:749
+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
+msgid "files"
+msgstr "file"
+
+#: lib/choose_repository.tcl:779
+msgid "Initial file checkout failed."
+msgstr "Attivazione iniziale impossibile."
+
+#: lib/choose_repository.tcl:795
+msgid "Open"
+msgstr "Apri"
+
+#: lib/choose_repository.tcl:805
+msgid "Repository:"
+msgstr "Archivio:"
+
+#: lib/choose_repository.tcl:854
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Impossibile accedere all'archivio %s:"
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr "Questa revisione attiva staccata"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Espressione di revisione:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr "Ramo locale"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr "Duplicato locale di ramo remoto"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr "Etichetta"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "Revisione non valida: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "Nessuna revisione selezionata."
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "L'espressione di revisione è vuota."
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr "Aggiornato"
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr "URL"
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"Non c'è niente da correggere.\n"
+"\n"
+"Stai per creare la revisione iniziale. Non esiste una revisione "
+"precedente da correggere.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"Non è possibile effettuare una correzione durante una fusione.\n"
+"\n"
+"In questo momento si sta effettuando una fusione che non è stata del tutto "
+"completata. Non puoi correggere la revisione precedente a meno che prima tu "
+"non interrompa l'operazione di fusione in corso.\n"
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr "Errore durante il caricamento dei dati della revisione da correggere:"
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr "Impossibile ottenere la tua identità:"
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "GIT_COMMITTER_IDENT non valida:"
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"L'ultimo stato analizzato non corrisponde allo stato dell'archivio.\n"
+"\n"
+"Un altro programma Git ha modificato questo archivio dall'ultima analisi. "
+"Bisogna effettuare una nuova analisi prima di poter creare una nuova "
+"revisione.\n"
+"\n"
+"La nuova analisi comincerà ora.\n"
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"Non è possibile creare una revisione con file non sottoposti a fusione.\n"
+"\n"
+"Il file %s presenta dei conflitti. Devi risolverli e preparare il file per "
+"creare una nuova revisione prima di effettuare questa azione.\n"
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"Stato di file %s sconosciuto.\n"
+"\n"
+"Questo programma non può creare una revisione contenente il file %s.\n"
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"Nessuna modifica per la nuova revisione.\n"
+"\n"
+"Devi preparare per una nuova revisione almeno 1 file prima di effettuare questa "
+"operazione.\n"
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"Bisogna fornire un messaggio di revisione.\n"
+"\n"
+"Un buon messaggio di revisione ha il seguente formato:\n"
+"\n"
+"- Prima linea: descrivi in una frase ciò che hai fatto.\n"
+"- Seconda linea: vuota.\n"
+"- Terza linea: spiega a cosa serve la tua modifica.\n"
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr "write-tree fallito:"
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "La revisione %s sembra essere corrotta"
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"Nessuna modifica per la nuova revisione.\n"
+"\n"
+"Questa revisione non modifica alcun file e non effettua alcuna fusione.\n"
+"\n"
+"Si procederà subito ad una nuova analisi.\n"
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr "Nessuna modifica per la nuova revisione."
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr "attenzione: Tcl non supporta la codifica '%s'."
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr "commit-tree fallito:"
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr "update-ref fallito:"
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "Creata revisione %s: %s"
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr "Elaborazione in corso... attendere..."
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr "Successo"
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr "Errore: comando fallito"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "Numero di oggetti slegati"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "Spazio su disco utilizzato da oggetti slegati"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "Numero di oggetti impacchettati"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "Numero di pacchetti"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "Spazio su disco utilizzato da oggetti impacchettati"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "Oggetti impacchettati che attendono la potatura"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "File inutili"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Compressione dell'archivio in corso"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "Verifica dell'archivio con fsck-objects in corso"
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+"Questo archivio attualmente ha circa %i oggetti slegati.\n"
+"\n"
+"Per mantenere buone prestazioni si raccomanda di comprimere l'archivio "
+"quando sono presenti più di %i oggetti slegati.\n"
+"\n"
+"Comprimere l'archivio ora?"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Git ha restituito una data non valida: %s"
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Non sono state trovate differenze.\n"
+"\n"
+"%s non ha modifiche.\n"
+"\n"
+"La data di modifica di questo file è stata cambiata da un'altra "
+"applicazione, ma il contenuto del file è rimasto invariato.\n"
+"\n"
+"Si procederà automaticamente ad una nuova analisi per trovare altri file che "
+"potrebbero avere lo stesso stato."
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "Caricamento delle differenze di %s..."
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Impossibile visualizzare %s"
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr "Errore nel caricamento del file:"
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr "Archivio Git (sottoprogetto)"
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr "* File binario (il contenuto non sarà mostrato)."
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+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."
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr "Impossibile preparare la sezione scelta per una nuova revisione."
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr "errore"
+
+#: lib/error.tcl:28
+msgid "warning"
+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."
+
+#: lib/index.tcl:241
+#, tcl-format
+msgid "Unstaging %s from commit"
+msgstr "%s non farà parte della prossima revisione"
+
+#: lib/index.tcl:285
+#, tcl-format
+msgid "Adding %s"
+msgstr "Aggiunta di %s in corso"
+
+#: lib/index.tcl:340
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "Annullare le modifiche nel file %s?"
+
+#: lib/index.tcl:342
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr "Annullare le modifiche in questi %i file?"
+
+#: lib/index.tcl:348
+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
+msgid "Do Nothing"
+msgstr "Non fare niente"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"Non posso effettuare fusioni durante una correzione.\n"
+"\n"
+"Bisogna finire di correggere questa revisione prima di iniziare una "
+"qualunque fusione.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"L'ultimo stato analizzato non corrisponde allo stato dell'archivio.\n"
+"\n"
+"Un altro programma Git ha modificato questo archivio dall'ultima analisi."
+"Bisogna effettuare una nuova analisi prima di poter effettuare una fusione.\n"
+"\n"
+"La nuova analisi comincerà ora.\n"
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"Sei nel mezzo di una fusione con conflitti.\n"
+"\n"
+"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"
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"Sei nel mezzo di una modifica.\n"
+"\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"
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s di %s"
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr "Fusione di %s e %s in corso"
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr "Fusione completata con successo."
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr "Fusione fallita. Bisogna risolvere i conflitti."
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Fusione in %s"
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr "Revisione da fondere"
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"Interruzione impossibile durante una correzione.\n"
+"\n"
+"Bisogna finire di correggere questa revisione.\n"
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"Interrompere fusione?\n"
+"\n"
+"L'interruzione della fusione corrente causerà la perdita di *TUTTE* le "
+"modifiche non ancora presenti nell'archivio.\n"
+"\n"
+"Continuare con l'interruzione della fusione corrente?"
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"Ripristinare la revisione corrente e annullare le modifiche?\n"
+"\n"
+"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?"
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr "Interruzione in corso"
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr "Interruzione fallita."
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr "Interruzione completata. Pronto."
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr "Ripristina predefiniti"
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr "Salva"
+
+#: lib/option.tcl:96
+#, tcl-format
+msgid "%s Repository"
+msgstr "Archivio di %s"
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr "Tutti gli archivi"
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr "Nome utente"
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr "Indirizzo Email"
+
+#: lib/option.tcl:106
+msgid "Summarize Merge Commits"
+msgstr "Riepilogo nelle revisioni di fusione"
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr "Prolissità della fusione"
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr "Mostra statistiche delle differenze dopo la fusione"
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr "Fidati delle date di modifica dei file"
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr ""
+"Effettua potatura dei duplicati locali di rami remoti durante il recupero"
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr "Appaia duplicati locali di rami remoti"
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr "Numero di linee di contesto nelle differenze"
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr "Modello per il nome di un nuovo ramo"
+
+#: lib/option.tcl:176
+msgid "Change Font"
+msgstr "Cambia caratteri"
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr "Scegli %s"
+
+#: lib/option.tcl:186
+msgid "pt."
+msgstr "pt."
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr "Preferenze"
+
+#: lib/option.tcl:235
+msgid "Failed to completely save options:"
+msgstr "Impossibile salvare completamente le opzioni:"
+
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr "Effettua potatura da"
+
+#: lib/remote.tcl:170
+msgid "Fetch from"
+msgstr "Recupera da"
+
+#: lib/remote.tcl:213
+msgid "Push to"
+msgstr "Propaga verso"
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Remote Branch"
+msgstr "Cancella ramo remoto"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "Da archivio"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr "Remoto:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr "URL specifico:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr "Rami"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "Elimina solo se"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "Fuso in:"
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "Sempre (non verificare le fusioni)"
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr "Si richiede un ramo per 'Fuso in'."
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"I rami seguenti non sono stati fusi completamente in %s:\n"
+"\n"
+" - %s"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+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."
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr "Scegliere uno o più rami da cancellare."
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"Ricomporre rami cancellati è difficile.\n"
+"\n"
+"Cancellare i rami selezionati?"
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "Cancellazione rami da %s"
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr "Nessun archivio selezionato."
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+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:149
+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%%)"
+
+#: lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "recupera da %s"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "Recupero nuove modifiche da %s"
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "potatura remota di %s"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr "Effettua potatura dei duplicati locali di rami remoti cancellati da %s"
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr "propaga verso %s"
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Propagazione modifiche a %s"
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "Propagazione %s %s a %s"
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr "Propaga rami"
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr "Rami di origine"
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr "Archivio di destinazione"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr "Opzioni di trasferimento"
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr "Sovrascrivi ramo esistente (alcune modifiche potrebbero essere perse)"
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr "Utilizza 'thin pack' (per connessioni lente)"
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr "Includi etichette"
+
diff --git a/git-gui/po/ja.po b/git-gui/po/ja.po
new file mode 100644
index 000000000..f3a547b1b
--- /dev/null
+++ b/git-gui/po/ja.po
@@ -0,0 +1,1843 @@
+# Translation of git-gui to Japanese
+# Copyright (C) 2007 Shawn Pearce
+# This file is distributed under the same license as the git-gui package.
+# ã—らã„ã— ãªãªã“ <nanako3@bluebottle.com>, 2007.
+#
+#, fuzzy
+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"
+"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
+msgid "git-gui: fatal error"
+msgstr "git-gui: 致命的ãªã‚¨ãƒ©ãƒ¼"
+
+#: git-gui.sh:595
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "%s ã«ç„¡åŠ¹ãªãƒ•ã‚©ãƒ³ãƒˆãŒæŒ‡å®šã•ã‚Œã¦ã„ã¾ã™:"
+
+#: git-gui.sh:620
+msgid "Main Font"
+msgstr "主フォント"
+
+#: git-gui.sh:621
+msgid "Diff/Console Font"
+msgstr "diff/コンソール・フォント"
+
+#: git-gui.sh:635
+msgid "Cannot find git in PATH."
+msgstr "PATH 中㫠git ãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“"
+
+#: git-gui.sh:662
+msgid "Cannot parse Git version string:"
+msgstr "Git ãƒãƒ¼ã‚¸ãƒ§ãƒ³åãŒç†è§£ã§ãã¾ã›ã‚“:"
+
+#: git-gui.sh:680
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Git ã®ãƒãƒ¼ã‚¸ãƒ§ãƒ³ãŒç¢ºèªã§ãã¾ã›ã‚“。\n"
+"\n"
+"%s ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ '%s' ã¨ã®ã“ã¨ã§ã™ã€‚\n"
+"\n"
+"%s ã¯æœ€ä½Žã§ã‚‚ 1.5.0 ã‹ãれ以é™ã® Git ãŒå¿…è¦ã§ã™\n"
+"\n"
+"'%s' ã¯ãƒãƒ¼ã‚¸ãƒ§ãƒ³ 1.5.0 ã¨æ€ã£ã¦è‰¯ã„ã§ã™ã‹ï¼Ÿ\n"
+
+#: git-gui.sh:853
+msgid "Git directory not found:"
+msgstr "Git ディレクトリãŒè¦‹ã¤ã‹ã‚Šã¾ã›ã‚“:"
+
+#: git-gui.sh:860
+msgid "Cannot move to top of working directory:"
+msgstr "作業ディレクトリã®æœ€ä¸Šä½ã«ç§»å‹•ã§ãã¾ã›ã‚“"
+
+#: git-gui.sh:867
+msgid "Cannot use funny .git directory:"
+msgstr "変㪠.git ディレクトリã¯ä½¿ãˆã¾ã›ã‚“"
+
+#: git-gui.sh:872
+msgid "No working directory"
+msgstr "作業ディレクトリãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: git-gui.sh:1019
+msgid "Refreshing file status..."
+msgstr "ファイル状態を更新ã—ã¦ã„ã¾ã™â€¦"
+
+#: git-gui.sh:1084
+msgid "Scanning for modified files ..."
+msgstr "変更ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’スキャンã—ã¦ã„ã¾ã™â€¦"
+
+#: git-gui.sh:1259 lib/browser.tcl:245
+msgid "Ready."
+msgstr "準備完了"
+
+#: git-gui.sh:1525
+msgid "Unmodified"
+msgstr "変更無ã—"
+
+#: git-gui.sh:1527
+msgid "Modified, not staged"
+msgstr "変更ã‚ã‚Šã€ã‚³ãƒŸãƒƒãƒˆæœªäºˆå®š"
+
+#: git-gui.sh:1528 git-gui.sh:1533
+msgid "Staged for commit"
+msgstr "コミット予定済"
+
+#: git-gui.sh:1529 git-gui.sh:1534
+msgid "Portions staged for commit"
+msgstr "部分的ã«ã‚³ãƒŸãƒƒãƒˆäºˆå®šæ¸ˆ"
+
+#: git-gui.sh:1530 git-gui.sh:1535
+msgid "Staged for commit, missing"
+msgstr "コミット予定済ã€ãƒ•ã‚¡ã‚¤ãƒ«ç„¡ã—"
+
+#: git-gui.sh:1532
+msgid "Untracked, not staged"
+msgstr "管ç†å¤–ã€ã‚³ãƒŸãƒƒãƒˆæœªäºˆå®š"
+
+#: git-gui.sh:1537
+msgid "Missing"
+msgstr "ファイル無ã—"
+
+#: git-gui.sh:1538
+msgid "Staged for removal"
+msgstr "削除予定済"
+
+#: git-gui.sh:1539
+msgid "Staged for removal, still present"
+msgstr "削除予定済ã€ãƒ•ã‚¡ã‚¤ãƒ«æœªå‰Šé™¤"
+
+#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544
+msgid "Requires merge resolution"
+msgstr "è¦ãƒžãƒ¼ã‚¸è§£æ±º"
+
+#: git-gui.sh:1579
+msgid "Starting gitk... please wait..."
+msgstr "gitk を起動中…ãŠå¾…ã¡ä¸‹ã•ã„…"
+
+#: git-gui.sh:1588
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+"gitk ã‚’èµ·å‹•ã§ãã¾ã›ã‚“:\n"
+"\n"
+"%s ãŒã‚ã‚Šã¾ã›ã‚“"
+
+#: git-gui.sh:1788 lib/choose_repository.tcl:32
+msgid "Repository"
+msgstr "リãƒã‚¸ãƒˆãƒª"
+
+#: git-gui.sh:1789
+msgid "Edit"
+msgstr "編集"
+
+#: git-gui.sh:1791 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr "ブランãƒ"
+
+#: git-gui.sh:1794 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
+msgid "Merge"
+msgstr "マージ"
+
+#: git-gui.sh:1798 lib/choose_rev.tcl:556
+msgid "Remote"
+msgstr "リモート"
+
+#: git-gui.sh:1807
+msgid "Browse Current Branch's Files"
+msgstr "ç¾åœ¨ã®ãƒ–ランãƒã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’見る"
+
+#: git-gui.sh:1811
+msgid "Browse Branch Files..."
+msgstr "ブランãƒã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’見る…"
+
+#: git-gui.sh:1816
+msgid "Visualize Current Branch's History"
+msgstr "ç¾åœ¨ã®ãƒ–ランãƒã®å±¥æ­´ã‚’見る"
+
+#: git-gui.sh:1820
+msgid "Visualize All Branch History"
+msgstr "å…¨ã¦ã®ãƒ–ランãƒã®å±¥æ­´ã‚’見る"
+
+#: git-gui.sh:1827
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "ブランム%s ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’見る"
+
+#: git-gui.sh:1829
+#, tcl-format
+msgid "Visualize %s's History"
+msgstr "ブランム%s ã®å±¥æ­´ã‚’見る"
+
+#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr "データベース統計"
+
+#: git-gui.sh:1837 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "データベース圧縮"
+
+#: git-gui.sh:1840
+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
+msgid "Create Desktop Icon"
+msgstr "デスクトップ・アイコンを作る"
+
+#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95
+msgid "Quit"
+msgstr "終了"
+
+#: git-gui.sh:1867
+msgid "Undo"
+msgstr "å…ƒã«æˆ»ã™"
+
+#: git-gui.sh:1870
+msgid "Redo"
+msgstr "ã‚„ã‚Šç›´ã—"
+
+#: git-gui.sh:1874 git-gui.sh:2366
+msgid "Cut"
+msgstr "切りå–ã‚Š"
+
+#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr "コピー"
+
+#: git-gui.sh:1880 git-gui.sh:2372
+msgid "Paste"
+msgstr "貼り付ã‘"
+
+#: git-gui.sh:1883 git-gui.sh:2375 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
+msgid "Select All"
+msgstr "å…¨ã¦é¸æŠž"
+
+#: git-gui.sh:1896
+msgid "Create..."
+msgstr "作æˆâ€¦"
+
+#: git-gui.sh:1902
+msgid "Checkout..."
+msgstr "ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
+
+#: git-gui.sh:1908
+msgid "Rename..."
+msgstr "åå‰å¤‰æ›´â€¦"
+
+#: git-gui.sh:1913 git-gui.sh:2012
+msgid "Delete..."
+msgstr "削除…"
+
+#: git-gui.sh:1918
+msgid "Reset..."
+msgstr "リセット…"
+
+#: git-gui.sh:1930 git-gui.sh:2313
+msgid "New Commit"
+msgstr "æ–°è¦ã‚³ãƒŸãƒƒãƒˆ"
+
+#: git-gui.sh:1938 git-gui.sh:2320
+msgid "Amend Last Commit"
+msgstr "最新コミットを訂正"
+
+#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "å†ã‚¹ã‚­ãƒ£ãƒ³"
+
+#: git-gui.sh:1953
+msgid "Stage To Commit"
+msgstr "コミット予定ã™ã‚‹"
+
+#: git-gui.sh:1958
+msgid "Stage Changed Files To Commit"
+msgstr "変更ã•ã‚ŒãŸãƒ•ã‚¡ã‚¤ãƒ«ã‚’コミット予定"
+
+#: git-gui.sh:1964
+msgid "Unstage From Commit"
+msgstr "コミットã‹ã‚‰é™ã‚ã™"
+
+#: git-gui.sh:1969 lib/index.tcl:352
+msgid "Revert Changes"
+msgstr "変更を元ã«æˆ»ã™"
+
+#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390
+msgid "Sign Off"
+msgstr "ç½²å"
+
+#: git-gui.sh:1980 git-gui.sh:2296
+msgid "Commit@@verb"
+msgstr "コミット"
+
+#: git-gui.sh:1991
+msgid "Local Merge..."
+msgstr "ローカル・マージ…"
+
+#: git-gui.sh:1996
+msgid "Abort Merge..."
+msgstr "マージ中止…"
+
+#: git-gui.sh:2008
+msgid "Push..."
+msgstr "プッシュ…"
+
+#: git-gui.sh:2019 lib/choose_repository.tcl:41
+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
+#, tcl-format
+msgid "About %s"
+msgstr "%s ã«ã¤ã„ã¦"
+
+#: git-gui.sh:2026
+msgid "Preferences..."
+msgstr "設定…"
+
+#: git-gui.sh:2034 git-gui.sh:2558
+msgid "Options..."
+msgstr "オプション…"
+
+#: git-gui.sh:2040 lib/choose_repository.tcl:47
+msgid "Help"
+msgstr "ヘルプ"
+
+#: git-gui.sh:2081
+msgid "Online Documentation"
+msgstr "オンライン・ドキュメント"
+
+#: git-gui.sh:2165
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr "致命的: パス %s ㌠stat ã§ãã¾ã›ã‚“。ãã®ã‚ˆã†ãªãƒ•ã‚¡ã‚¤ãƒ«ã‚„ディレクトリã¯ã‚ã‚Šã¾ã›ã‚“"
+
+#: git-gui.sh:2198
+msgid "Current Branch:"
+msgstr "ç¾åœ¨ã®ãƒ–ランãƒ"
+
+#: git-gui.sh:2219
+msgid "Staged Changes (Will Commit)"
+msgstr "ステージングã•ã‚ŒãŸï¼ˆã‚³ãƒŸãƒƒãƒˆäºˆå®šæ¸ˆã®ï¼‰å¤‰æ›´"
+
+#: git-gui.sh:2239
+msgid "Unstaged Changes"
+msgstr "コミット予定ã«å…¥ã£ã¦ã„ãªã„変更"
+
+#: git-gui.sh:2286
+msgid "Stage Changed"
+msgstr "変更をコミット予定ã«å…¥ã‚Œã‚‹"
+
+#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "プッシュ"
+
+#: git-gui.sh:2332
+msgid "Initial Commit Message:"
+msgstr "最åˆã®ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸:"
+
+#: git-gui.sh:2333
+msgid "Amended Commit Message:"
+msgstr "訂正ã—ãŸã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸:"
+
+#: git-gui.sh:2334
+msgid "Amended Initial Commit Message:"
+msgstr "訂正ã—ãŸæœ€åˆã®ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸:"
+
+#: git-gui.sh:2335
+msgid "Amended Merge Commit Message:"
+msgstr "訂正ã—ãŸãƒžãƒ¼ã‚¸ã‚³ãƒŸãƒƒãƒˆãƒ¡ãƒƒã‚»ãƒ¼ã‚¸:"
+
+#: git-gui.sh:2336
+msgid "Merge Commit Message:"
+msgstr "マージコミットメッセージ:"
+
+#: git-gui.sh:2337
+msgid "Commit Message:"
+msgstr "コミットメッセージ:"
+
+#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71
+msgid "Copy All"
+msgstr "å…¨ã¦ã‚³ãƒ”ー"
+
+#: git-gui.sh:2406 lib/blame.tcl:104
+msgid "File:"
+msgstr "ファイル:"
+
+#: git-gui.sh:2508
+msgid "Refresh"
+msgstr "å†èª­ã¿è¾¼ã¿"
+
+#: git-gui.sh:2529
+msgid "Apply/Reverse Hunk"
+msgstr "パッãƒã‚’é©ç”¨/å–り消ã™"
+
+#: git-gui.sh:2535
+msgid "Decrease Font Size"
+msgstr "フォントをå°ã•ã"
+
+#: git-gui.sh:2539
+msgid "Increase Font Size"
+msgstr "フォントを大ãã"
+
+#: git-gui.sh:2544
+msgid "Show Less Context"
+msgstr "文脈を少ãªã"
+
+#: git-gui.sh:2551
+msgid "Show More Context"
+msgstr "文脈を多ã"
+
+#: git-gui.sh:2565
+msgid "Unstage Hunk From Commit"
+msgstr "パッãƒã‚’コミット予定ã‹ã‚‰å¤–ã™"
+
+#: git-gui.sh:2567
+msgid "Stage Hunk For Commit"
+msgstr "パッãƒã‚’コミット予定ã«åŠ ãˆã‚‹"
+
+#: git-gui.sh:2586
+msgid "Initializing..."
+msgstr "åˆæœŸåŒ–ã—ã¦ã„ã¾ã™â€¦"
+
+#: git-gui.sh:2677
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+"環境ã«å•é¡ŒãŒã‚ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™\n"
+"\n"
+"以下ã®ç’°å¢ƒå¤‰æ•°ã¯ %s ãŒèµ·å‹•ã™ã‚‹ Git サブプロセスã«ã‚ˆã£ã¦ç„¡è¦–ã•ã‚Œã‚‹ã§ã—ょã†:\n"
+"\n"
+
+#: git-gui.sh:2707
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+"\n"
+"ã“れ㯠Cygwin ã§é…布ã•ã‚Œã¦ã„ã‚‹ Tcl ãƒã‚¤ãƒŠãƒªã«\n"
+"é–¢ã—ã¦ã®æ—¢çŸ¥ã®å•é¡Œã«ã‚ˆã‚Šã¾ã™"
+
+#: git-gui.sh:2712
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+"\n"
+"\n"
+"個人的㪠~/.gitconfig ファイル内㧠user.name 㨠user.email ã®å€¤ã‚’設定\n"
+"ã™ã‚‹ã®ãŒã€%s ã®è‰¯ã„代用ã¨ãªã‚Šã¾ã™\n"
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr "Git ã®ã‚°ãƒ©ãƒ•ã‚£ã‚«ãƒ«UI git-gui"
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr "ファイルピューワ"
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr "コミット:"
+
+#: lib/blame.tcl:249
+msgid "Copy Commit"
+msgstr "コミットをコピー"
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr "%s を読んã§ã„ã¾ã™â€¦"
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr "コピー・移動追跡データを読んã§ã„ã¾ã™â€¦"
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr "行を注釈ã—ã¾ã—ãŸ"
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr "å…ƒä½ç½®è¡Œã®æ³¨é‡ˆãƒ‡ãƒ¼ã‚¿ã‚’読んã§ã„ã¾ã™â€¦"
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr "注釈完了ã—ã¾ã—ãŸ"
+
+#: lib/blame.tcl:731
+msgid "Loading annotation..."
+msgstr "注釈を読ã¿è¾¼ã‚“ã§ã„ã¾ã™â€¦"
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr "作者:"
+
+#: lib/blame.tcl:791
+msgid "Committer:"
+msgstr "コミット者:"
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr "元ファイル"
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr "原作者:"
+
+#: lib/blame.tcl:916
+msgid "In File:"
+msgstr "ファイル:"
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr "複写・移動者:"
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr "ブランãƒã‚’ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr "中止"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr "リビジョン"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+msgid "Options"
+msgstr "オプション"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "トラッキング・ブランãƒã‚’フェッãƒ"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr "ローカル・ブランãƒã‹ã‚‰å‰Šé™¤"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr "ブランãƒã‚’作æˆ"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr "ブランãƒã‚’æ–°è¦ä½œæˆ"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199
+msgid "Create"
+msgstr "作æˆ"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr "ブランãƒå"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr "åå‰:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr "トラッキング・ブランãƒåã‚’åˆã‚ã›ã‚‹"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "åˆæœŸãƒªãƒ“ジョン"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "既存ã®ãƒ–ランãƒã‚’æ›´æ–°:"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "ã„ã„ãˆ"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "æ—©é€ã‚Šã®ã¿"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr "リセット"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "作æˆã—ã¦ã™ããƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr "トラッキング・ブランãƒã‚’é¸æŠžã—ã¦ä¸‹ã•ã„。"
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr "トラッキング・ブランム%s ã¯é éš”リãƒã‚¸ãƒˆãƒªã®ãƒ–ランãƒã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr "ブランãƒåを指定ã—ã¦ä¸‹ã•ã„。"
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "'%s' ã¯ãƒ–ランãƒåã«ä½¿ãˆã¾ã›ã‚“。"
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr "ブランãƒå‰Šé™¤"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr "ローカル・ブランãƒã‚’削除"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr "ローカル・ブランãƒ"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "マージ済ã¿ã®æ™‚ã®ã¿å‰Šé™¤"
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr "ç„¡æ¡ä»¶(マージテストã—ãªã„)"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "以下ã®ãƒ–ランãƒã¯ %s ã«å®Œå…¨ã«ãƒžãƒ¼ã‚¸ã•ã‚Œã¦ã„ã¾ã›ã‚“:"
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+"ブランãƒã‚’削除ã™ã‚‹ã¨å…ƒã«æˆ»ã™ã®ã¯å›°é›£ã§ã™ã€‚ \n"
+"\n"
+" é¸æŠžã—ãŸãƒ–ランãƒã‚’削除ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"以下ã®ãƒ–ランãƒã‚’削除ã§ãã¾ã›ã‚“:\n"
+"%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr "ブランãƒã®åå‰å¤‰æ›´"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "åå‰å¤‰æ›´"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr "ブランãƒ:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "æ–°ã—ã„åå‰:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr "åå‰ã‚’変更ã™ã‚‹ãƒ–ランãƒã‚’é¸ã‚“ã§ä¸‹ã•ã„。"
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "'%s'ã¨ã„ã†ãƒ–ランãƒã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "'%s'ã®åå‰å¤‰æ›´ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "起動中…"
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "ファイル・ブラウザ"
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr "%s をロード中…"
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr "[上ä½ãƒ•ã‚©ãƒ«ãƒ€ã¸]"
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+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
+msgid "Browse"
+msgstr "ブラウズ"
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "%s ã‹ã‚‰ %s をフェッãƒã—ã¦ã„ã¾ã™"
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr "致命的エラー: %s を解決ã§ãã¾ã›ã‚“"
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr "é–‰ã˜ã‚‹"
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "ブランãƒ'%s'ã¯å­˜åœ¨ã—ã¾ã›ã‚“。"
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"ブランム'%s' ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚\n"
+"\n"
+"%s ã«æ—©é€ã‚Šã§ãã¾ã›ã‚“。\n"
+"マージãŒå¿…è¦ã§ã™ã€‚"
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr "'%s' マージ戦略ã¯ã‚µãƒãƒ¼ãƒˆã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr "'%s' ã®æ›´æ–°ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr "インデックスã¯æ—¢ã«ãƒ­ãƒƒã‚¯ã•ã‚Œã¦ã„ã¾ã™ã€‚"
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"最後ã«ã‚¹ã‚­ãƒ£ãƒ³ã—ãŸçŠ¶æ…‹ã¯ãƒªãƒã‚¸ãƒˆãƒªã®çŠ¶æ…‹ã¨åˆè‡´ã—ã¾ã›ã‚“。\n"
+"\n"
+"最後ã«ã‚¹ã‚­ãƒ£ãƒ³ã—ã¦ä»¥å¾Œã€åˆ¥ã® Git プログラムãŒãƒªãƒã‚¸ãƒˆãƒªã‚’変更ã—ã¦ã„ã¾ã™ã€‚ç¾åœ¨"
+"ã®ãƒ–ランãƒã‚’変更ã™ã‚‹å‰ã«ã€å†ã‚¹ã‚­ãƒ£ãƒ³ãŒå¿…è¦ã§ã™ã€‚\n"
+"\n"
+"自動的ã«å†ã‚¹ã‚­ãƒ£ãƒ³ã‚’開始ã—ã¾ã™ã€‚\n"
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "作業ディレクトリを '%s' ã«æ›´æ–°ã—ã¦ã„ã¾ã™â€¦"
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr "'%s' ã®ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã‚’中止ã—ã¾ã—ãŸï¼ˆãƒ•ã‚¡ã‚¤ãƒ«æ¯Žã®ãƒžãƒ¼ã‚¸ãŒå¿…è¦ã§ã™ï¼‰ã€‚"
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr "ファイル毎ã®ãƒžãƒ¼ã‚¸ãŒå¿…è¦ã§ã™ã€‚"
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "ブランム'%s' ã«æ»žã¾ã‚Šã¾ã™ã€‚"
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"ローカル・ブランãƒã‹ã‚‰é›¢ã‚Œã¾ã™ã€‚\n"
+"\n"
+"ブランãƒä¸Šã«æ»žã¾ã‚ŠãŸã„ã¨ãã¯ã€ã“ã®ã€Œåˆ†é›¢ã•ã‚ŒãŸãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã€ã‹ã‚‰æ–°è¦ãƒ–ラン"
+"ãƒã‚’開始ã—ã¦ãã ã•ã„。"
+
+#: lib/checkout_op.tcl:446
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr "'%s' ã‚’ãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã—ã¾ã—ãŸ"
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr "'%s' ã‚’ '%s' ã«ãƒªã‚»ãƒƒãƒˆã™ã‚‹ã¨ã€ä»¥ä¸‹ã®ã‚³ãƒŸãƒƒãƒˆãŒå¤±ãªã‚ã‚Œã¾ã™:"
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr "失ãªã‚ã‚ŒãŸã‚³ãƒŸãƒƒãƒˆã‚’回復ã™ã‚‹ã®ã¯ç°¡å˜ã§ã¯ã‚ã‚Šã¾ã›ã‚“。"
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "'%s' をリセットã—ã¾ã™ã‹ï¼Ÿ"
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr "å¯è¦–化"
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+"ç¾åœ¨ã®ãƒ–ランãƒã‚’設定ã§ãã¾ã›ã‚“。\n"
+"\n"
+"作業ディレクトリã¯éƒ¨åˆ†çš„ã«ã—ã‹åˆ‡ã‚Šæ›¿ã‚ã£ã¦ã„ã¾ã›ã‚“。ファイルã®æ›´æ–°ã«ã¯æˆåŠŸã—"
+"ã¾ã—ãŸãŒã€ Git ã®å†…部データを更新ã§ãã¾ã›ã‚“ã§ã—ãŸã€‚\n"
+"èµ·ã“ã‚‹ã¯ãšã®ãªã„エラーã§ã™ã€‚ã‚ãらã‚㦠%s を終了ã—ã¾ã™ã€‚"
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr "é¸æŠž"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr "フォント・ファミリー"
+
+#: lib/choose_font.tcl:73
+msgid "Font Size"
+msgstr "フォントã®å¤§ãã•"
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr "フォント・サンプル"
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"ã“ã‚Œã¯ã‚µãƒ³ãƒ—ル文ã§ã™ã€‚\n"
+"ã“ã®ãƒ•ã‚©ãƒ³ãƒˆãŒæ°—ã«å…¥ã‚Œã°ãŠä½¿ã„ã«ãªã‚Œã¾ã™ã€‚"
+
+#: lib/choose_repository.tcl:25
+msgid "Git Gui"
+msgstr "Git GUI"
+
+#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
+msgid "Create New Repository"
+msgstr "æ–°ã—ã„リãƒã‚¸ãƒˆãƒªã‚’作る"
+
+#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
+msgid "Clone Existing Repository"
+msgstr "既存リãƒã‚¸ãƒˆãƒªã‚’複製ã™ã‚‹"
+
+#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
+msgid "Open Existing Repository"
+msgstr "既存リãƒã‚¸ãƒˆãƒªã‚’é–‹ã"
+
+#: lib/choose_repository.tcl:91
+msgid "Next >"
+msgstr "次 >"
+
+#: lib/choose_repository.tcl:152
+#, tcl-format
+msgid "Location %s already exists."
+msgstr "'%s' ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
+
+#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165
+#: lib/choose_repository.tcl:172
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "リãƒã‚¸ãƒˆãƒª %s を作製ã§ãã¾ã›ã‚“:"
+
+#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
+msgid "Directory:"
+msgstr "ディレクトリ:"
+
+#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
+#: lib/choose_repository.tcl:834
+msgid "Git Repository"
+msgstr "GIT リãƒã‚¸ãƒˆãƒª"
+
+#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "ディレクトリ '%s' ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
+
+#: lib/choose_repository.tcl:265
+#, tcl-format
+msgid "File %s already exists."
+msgstr "ファイル '%s' ã¯æ—¢ã«å­˜åœ¨ã—ã¾ã™ã€‚"
+
+#: lib/choose_repository.tcl:286
+msgid "Clone"
+msgstr "複製"
+
+#: lib/choose_repository.tcl:299
+msgid "URL:"
+msgstr "URL:"
+
+#: lib/choose_repository.tcl:319
+msgid "Clone Type:"
+msgstr "複製方å¼:"
+
+#: lib/choose_repository.tcl:325
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr "標準(高速・中冗長度・ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯)"
+
+#: lib/choose_repository.tcl:331
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "全複写(低速・冗長ãƒãƒƒã‚¯ã‚¢ãƒƒãƒ—)"
+
+#: lib/choose_repository.tcl:337
+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
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr "Git リãƒã‚¸ãƒˆãƒªã§ã¯ã‚ã‚Šã¾ã›ã‚“: %s"
+
+#: lib/choose_repository.tcl:405
+msgid "Standard only available for local repository."
+msgstr "標準方å¼ã¯åŒä¸€è¨ˆç®—機上ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã®ã¿ä½¿ãˆã¾ã™ã€‚"
+
+#: lib/choose_repository.tcl:409
+msgid "Shared only available for local repository."
+msgstr "共有方å¼ã¯åŒä¸€è¨ˆç®—機上ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã®ã¿ä½¿ãˆã¾ã™ã€‚"
+
+#: lib/choose_repository.tcl:439
+msgid "Failed to configure origin"
+msgstr "origin を設定ã§ãã¾ã›ã‚“ã§ã—ãŸ"
+
+#: lib/choose_repository.tcl:451
+msgid "Counting objects"
+msgstr "オブジェクトを数ãˆã¦ã„ã¾ã™"
+
+#: lib/choose_repository.tcl:452
+msgid "buckets"
+msgstr "ãƒã‚±ãƒ„"
+
+#: lib/choose_repository.tcl:476
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr "objects/info/alternates を複写ã§ãã¾ã›ã‚“: %s"
+
+#: lib/choose_repository.tcl:512
+#, 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
+msgid "The 'master' branch has not been initialized."
+msgstr "'master' ブランãƒãŒåˆæœŸåŒ–ã•ã‚Œã¦ã„ã¾ã›ã‚“"
+
+#: lib/choose_repository.tcl:527
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr "ãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ãŒä½œã‚Œãªã„ã®ã§ã€ã‚³ãƒ”ーã—ã¾ã™"
+
+#: lib/choose_repository.tcl:539
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "%s ã‹ã‚‰è¤‡è£½ã—ã¦ã„ã¾ã™"
+
+#: lib/choose_repository.tcl:570
+msgid "Copying objects"
+msgstr "オブジェクトを複写ã—ã¦ã„ã¾ã™"
+
+#: lib/choose_repository.tcl:571
+msgid "KiB"
+msgstr "KiB"
+
+#: lib/choose_repository.tcl:595
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "オブジェクトを複写ã§ãã¾ã›ã‚“: %s"
+
+#: lib/choose_repository.tcl:605
+msgid "Linking objects"
+msgstr "オブジェクトを連çµã—ã¦ã„ã¾ã™"
+
+#: lib/choose_repository.tcl:606
+msgid "objects"
+msgstr "オブジェクト"
+
+#: lib/choose_repository.tcl:614
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr "オブジェクトをãƒãƒ¼ãƒ‰ãƒªãƒ³ã‚¯ã§ãã¾ã›ã‚“: %s"
+
+#: lib/choose_repository.tcl:669
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr "ブランãƒã‚„オブジェクトをå–å¾—ã§ãã¾ã›ã‚“。コンソール出力を見ã¦ä¸‹ã•ã„"
+
+#: lib/choose_repository.tcl:680
+msgid "Cannot fetch tags. See console output for details."
+msgstr "ã‚¿ã‚°ã‚’å–å¾—ã§ãã¾ã›ã‚“。コンソール出力を見ã¦ä¸‹ã•ã„"
+
+#: lib/choose_repository.tcl:704
+msgid "Cannot determine HEAD. See console output for details."
+msgstr "HEAD を確定ã§ãã¾ã›ã‚“。コンソール出力を見ã¦ä¸‹ã•ã„"
+
+#: lib/choose_repository.tcl:713
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr "%s を掃除ã§ãã¾ã›ã‚“"
+
+#: lib/choose_repository.tcl:719
+msgid "Clone failed."
+msgstr "複写ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+
+#: lib/choose_repository.tcl:726
+msgid "No default branch obtained."
+msgstr "デフォールト・ブランãƒãŒå–å¾—ã•ã‚Œã¾ã›ã‚“ã§ã—ãŸ"
+
+#: lib/choose_repository.tcl:737
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr "%s をコミットã¨ã—ã¦è§£é‡ˆã§ãã¾ã›ã‚“"
+
+#: lib/choose_repository.tcl:749
+msgid "Creating working directory"
+msgstr "作業ディレクトリを作æˆã—ã¦ã„ã¾ã™"
+
+#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80
+#: lib/index.tcl:149
+msgid "files"
+msgstr "ファイル"
+
+#: lib/choose_repository.tcl:779
+msgid "Initial file checkout failed."
+msgstr "åˆæœŸãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆã«å¤±æ•—ã—ã¾ã—ãŸ"
+
+#: lib/choose_repository.tcl:795
+msgid "Open"
+msgstr "é–‹ã"
+
+#: lib/choose_repository.tcl:805
+msgid "Repository:"
+msgstr "リãƒã‚¸ãƒˆãƒª:"
+
+#: lib/choose_repository.tcl:854
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "リãƒã‚¸ãƒˆãƒª %s ã‚’é–‹ã‘ã¾ã›ã‚“:"
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr "分離ã•ã‚ŒãŸãƒã‚§ãƒƒã‚¯ã‚¢ã‚¦ãƒˆ"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "リビジョンå¼:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr "ローカル・ブランãƒ"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr "トラッキング・ブランãƒ"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr "ã‚¿ã‚°"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "無効ãªãƒªãƒ“ジョン: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "リビジョンãŒæœªé¸æŠžã§ã™ã€‚"
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "リビジョンå¼ãŒç©ºã§ã™ã€‚"
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr "æ›´æ–°ã—ã¾ã—ãŸ"
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr "URL"
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"訂正ã™ã‚‹ã‚³ãƒŸãƒƒãƒˆãŒãã‚‚ãã‚‚ã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"ã“ã‚Œã‹ã‚‰ä½œã‚‹ã®ã¯æœ€åˆã®ã‚³ãƒŸãƒƒãƒˆã§ã™ã€‚ãã®å‰ã«ã¯ã¾ã è¨‚æ­£ã™ã‚‹ã‚ˆã†ãªã‚³ãƒŸãƒƒãƒˆã¯ã‚"
+"ã‚Šã¾ã›ã‚“。\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"マージ中ã«ã‚³ãƒŸãƒƒãƒˆã®è¨‚æ­£ã¯ã§ãã¾ã›ã‚“。\n"
+"\n"
+"ç¾åœ¨ã¯ã¾ã ãƒžãƒ¼ã‚¸ã®é€”中ã§ã™ã€‚å…ˆã«ã“ã®ãƒžãƒ¼ã‚¸ã‚’中止ã—ãªã„ã¨ã€å‰ã®ã‚³ãƒŸãƒƒãƒˆã®è¨‚æ­£"
+"ã¯ã§ãã¾ã›ã‚“\n"
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr "訂正ã™ã‚‹ã‚³ãƒŸãƒƒãƒˆã®ãƒ‡ãƒ¼ã‚¿ã‚’読ã‚ã¾ã›ã‚“:"
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr "ユーザã®æ­£ä½“を確èªã§ãã¾ã›ã‚“:"
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "GIT_COMMITTER_IDENT ãŒç„¡åŠ¹ã§ã™:"
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"最後ã«ã‚¹ã‚­ãƒ£ãƒ³ã—ãŸçŠ¶æ…‹ã¯ãƒªãƒã‚¸ãƒˆãƒªã®çŠ¶æ…‹ã¨åˆè‡´ã—ã¾ã›ã‚“。\n"
+"\n"
+"最後ã«ã‚¹ã‚­ãƒ£ãƒ³ã—ã¦ä»¥å¾Œã€åˆ¥ã® Git プログラムãŒãƒªãƒã‚¸ãƒˆãƒªã‚’変更ã—ã¦ã„ã¾ã™ã€‚æ–°ã—"
+"ãコミットã™ã‚‹å‰ã«ã€å†ã‚¹ã‚­ãƒ£ãƒ³ãŒå¿…è¦ã§ã™ã€‚\n"
+"\n"
+"自動的ã«å†ã‚¹ã‚­ãƒ£ãƒ³ã‚’開始ã—ã¾ã™ã€‚\n"
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"マージã—ã¦ã„ãªã„ファイルã¯ã‚³ãƒŸãƒƒãƒˆã§ãã¾ã›ã‚“。\n"
+"\n"
+"ファイル %s ã«ã¯ãƒžãƒ¼ã‚¸è¡çªãŒæ®‹ã£ã¦ã„ã¾ã™ã€‚ã¾ãšè§£æ±ºã—ã¦ã‚³ãƒŸãƒƒãƒˆäºˆå®šã«åŠ ãˆã‚‹å¿…"
+"è¦ãŒã‚ã‚Šã¾ã™ã€‚\n"
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"ä¸æ˜Žãªãƒ•ã‚¡ã‚¤ãƒ«çŠ¶æ…‹ %s ã§ã™ã€‚\n"
+"\n"
+"ファイル %s ã¯æœ¬ãƒ—ログラムã§ã¯ã‚³ãƒŸãƒƒãƒˆã§ãã¾ã›ã‚“。\n"
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"コミットã™ã‚‹å¤‰æ›´ãŒã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"最低一ã¤ã®å¤‰æ›´ã‚’コミット予定ã«åŠ ãˆã¦ã‹ã‚‰ã‚³ãƒŸãƒƒãƒˆã—ã¦ä¸‹ã•ã„。\n"
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"コミット・メッセージを入力ã—ã¦ä¸‹ã•ã„。\n"
+"\n"
+"æ­£ã—ã„コミット・メッセージã¯:\n"
+"\n"
+"- 第1行: 何をã—ãŸã‹ã€ã‚’1行ã§è¦ç´„。\n"
+"- 第2行: 空白\n"
+"- 残りã®è¡Œ: ãªãœã€ã“ã®å¤‰æ›´ãŒè‰¯ã„変更ã‹ã€ã®èª¬æ˜Žã€‚\n"
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr "write-tree ãŒå¤±æ•—ã—ã¾ã—ãŸ:"
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "コミット %s ã¯å£Šã‚Œã¦ã„ã¾ã™"
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"コミットã™ã‚‹å¤‰æ›´ãŒã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"マージã§ãªãã€ã¾ãŸã€ä¸€ã¤ã‚‚変更点ãŒã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"自動的ã«å†ã‚¹ã‚­ãƒ£ãƒ³ã‚’開始ã—ã¾ã™ã€‚\n"
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr "コミットã™ã‚‹å¤‰æ›´ãŒã‚ã‚Šã¾ã›ã‚“。"
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr "警告: Tcl ã¯ã‚¨ãƒ³ã‚³ãƒ¼ãƒ‡ã‚£ãƒ³ã‚° '%s' をサãƒãƒ¼ãƒˆã—ã¦ã„ã¾ã›ã‚“"
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr "commit-tree ãŒå¤±æ•—ã—ã¾ã—ãŸ:"
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr "update-ref ãŒå¤±æ•—ã—ã¾ã—ãŸ:"
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "コミット %s を作æˆã—ã¾ã—ãŸ: %s"
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr "実行中…ãŠå¾…ã¡ä¸‹ã•ã„…"
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr "æˆåŠŸ"
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr "エラー: コマンドãŒå¤±æ•—ã—ã¾ã—ãŸ"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "ã°ã‚‰ã°ã‚‰ãªã‚ªãƒ–ジェクトã®æ•°"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "ã°ã‚‰ã°ã‚‰ãªã‚ªãƒ–ジェクトã®ä½¿ç”¨ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯é‡"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "パックã•ã‚ŒãŸã‚ªãƒ–ジェクトã®æ•°"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "パックã®æ•°"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "パックã•ã‚ŒãŸã‚ªãƒ–ジェクトã®ä½¿ç”¨ã™ã‚‹ãƒ‡ã‚£ã‚¹ã‚¯é‡"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "パックã«å­˜åœ¨ã™ã‚‹ã®ã§æ¨ã¦ã¦è‰¯ã„オブジェクトã®æ•°"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "ゴミファイル"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "データベース圧縮"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "fsck-objects ã§ã‚ªãƒ–ジェクト・データベースを検証ã—ã¦ã„ã¾ã™"
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+"ã“ã®ãƒªãƒã‚¸ãƒˆãƒªã«ã¯ãŠãŠã‚ˆã %i 個ã®å€‹åˆ¥ã‚ªãƒ–ジェクトãŒã‚ã‚Šã¾ã™\n"
+"\n"
+"最é©ãªæ€§èƒ½ã‚’ä¿ã¤ãŸã‚ã«ã€%i 個以上ã®å€‹åˆ¥ã‚ªãƒ–ジェクトを作る毎ã«ãƒ‡ãƒ¼ã‚¿ãƒ™ãƒ¼ã‚¹ã‚’圧縮ã™ã‚‹ã“ã¨ã‚’推奨ã—ã¾ã™\n"
+"\n"
+"データベースを圧縮ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Git ã‹ã‚‰å‡ºãŸç„¡åŠ¹ãªæ—¥ä»˜: %s"
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"変更ãŒã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"%s ã«ã¯å¤‰æ›´ãŒã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®å¤‰æ›´æ™‚刻ã¯ä»–ã®ã‚¢ãƒ—リケーションã«ã‚ˆã£ã¦æ›´æ–°ã•ã‚Œã¦ã„ã¾ã™ãŒãƒ•ã‚¡ã‚¤"
+"ル内容ã«ã¯å¤‰æ›´ãŒã‚ã‚Šã¾ã›ã‚“。\n"
+"\n"
+"åŒæ§˜ãªçŠ¶æ…‹ã®ãƒ•ã‚¡ã‚¤ãƒ«ã‚’探ã™ãŸã‚ã«ã€è‡ªå‹•çš„ã«å†ã‚¹ã‚­ãƒ£ãƒ³ã‚’開始ã—ã¾ã™ã€‚"
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "%s ã®å¤‰æ›´ç‚¹ã‚’ロード中…"
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "%s を表示ã§ãã¾ã›ã‚“"
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr "ファイルを読む際ã®ã‚¨ãƒ©ãƒ¼ã§ã™:"
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr "Git リãƒã‚¸ãƒˆãƒª(サブプロジェクト)"
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr "* ãƒã‚¤ãƒŠãƒªãƒ•ã‚¡ã‚¤ãƒ«(内容ã¯è¡¨ç¤ºã—ã¾ã›ã‚“)"
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr "diff を読む際ã®ã‚¨ãƒ©ãƒ¼ã§ã™:"
+
+#: lib/diff.tcl:302
+msgid "Failed to unstage selected hunk."
+msgstr "é¸æŠžã•ã‚ŒãŸãƒ‘ッãƒã‚’コミット予定ã‹ã‚‰å¤–ã›ã¾ã›ã‚“。"
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr "é¸æŠžã•ã‚ŒãŸãƒ‘ッãƒã‚’コミット予定ã«åŠ ãˆã‚‰ã‚Œã¾ã›ã‚“。"
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr "エラー"
+
+#: lib/error.tcl:28
+msgid "warning"
+msgstr "警告"
+
+#: lib/error.tcl:81
+msgid "You must correct the above errors before committing."
+msgstr "コミットã™ã‚‹å‰ã«ã€ä»¥ä¸Šã®ã‚¨ãƒ©ãƒ¼ã‚’修正ã—ã¦ä¸‹ã•ã„"
+
+#: lib/index.tcl:241
+#, tcl-format
+msgid "Unstaging %s from commit"
+msgstr "コミットã‹ã‚‰ '%s' ã‚’é™ã‚ã™"
+
+#: lib/index.tcl:285
+#, tcl-format
+msgid "Adding %s"
+msgstr "コミット㫠%s を加ãˆã¦ã„ã¾ã™"
+
+#: lib/index.tcl:340
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "ファイル %s ã«ã—ãŸå¤‰æ›´ã‚’å…ƒã«æˆ»ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: lib/index.tcl:342
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr "ã“れら %i 個ã®ãƒ•ã‚¡ã‚¤ãƒ«ã«ã—ãŸå¤‰æ›´ã‚’å…ƒã«æˆ»ã—ã¾ã™ã‹ï¼Ÿ"
+
+#: lib/index.tcl:348
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr "変更を元ã«æˆ»ã™ã¨ã‚³ãƒŸãƒƒãƒˆäºˆå®šã—ã¦ã„ãªã„変更ã¯å…¨ã¦å¤±ã‚ã‚Œã¾ã™ã€‚"
+
+#: lib/index.tcl:351
+msgid "Do Nothing"
+msgstr "何もã—ãªã„"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"訂正中ã«ã¯ãƒžãƒ¼ã‚¸ã§ãã¾ã›ã‚“。\n"
+"\n"
+"訂正処ç†ã‚’完了ã™ã‚‹ã¾ã§ã¯æ–°ãŸã«ãƒžãƒ¼ã‚¸ã‚’開始ã§ãã¾ã›ã‚“。\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"最後ã«ã‚¹ã‚­ãƒ£ãƒ³ã—ãŸçŠ¶æ…‹ã¯ãƒªãƒã‚¸ãƒˆãƒªã®çŠ¶æ…‹ã¨åˆè‡´ã—ã¾ã›ã‚“。\n"
+"\n"
+"最後ã«ã‚¹ã‚­ãƒ£ãƒ³ã—ã¦ä»¥å¾Œã€åˆ¥ã® Git プログラムãŒãƒªãƒã‚¸ãƒˆãƒªã‚’変更ã—ã¦ã„ã¾ã™ã€‚マー"
+"ジを開始ã™ã‚‹å‰ã«ã€å†ã‚¹ã‚­ãƒ£ãƒ³ãŒå¿…è¦ã§ã™ã€‚\n"
+"\n"
+"自動的ã«å†ã‚¹ã‚­ãƒ£ãƒ³ã‚’開始ã—ã¾ã™ã€‚\n"
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"è¡çªã®ã‚ã£ãŸãƒžãƒ¼ã‚¸ã®é€”中ã§ã™ã€‚\n"
+"\n"
+"ファイル %s ã«ã¯ãƒžãƒ¼ã‚¸ä¸­ã®è¡çªãŒæ®‹ã£ã¦ã„ã¾ã™ã€‚\n"
+"\n"
+"ã“ã®ãƒ•ã‚¡ã‚¤ãƒ«ã®è¡çªã‚’解決ã—ã€ã‚³ãƒŸãƒƒãƒˆäºˆå®šã«åŠ ãˆã¦ã€ã‚³ãƒŸãƒƒãƒˆã™ã‚‹ã“ã¨ã§ãƒžãƒ¼ã‚¸ã‚’"
+"完了ã—ã¾ã™ã€‚ãã†ã‚„ã£ã¦å§‹ã‚ã¦ã€æ–°ãŸãªãƒžãƒ¼ã‚¸ã‚’開始ã§ãるよã†ã«ãªã‚Šã¾ã™ã€‚\n"
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"変更ã®é€”中ã§ã™ã€‚\n"
+"\n"
+"ファイル %s ã¯å¤‰æ›´ä¸­ã§ã™ã€‚\n"
+"\n"
+"ç¾åœ¨ã®ã‚³ãƒŸãƒƒãƒˆã‚’完了ã—ã¦ã‹ã‚‰ãƒžãƒ¼ã‚¸ã‚’開始ã—ã¦ä¸‹ã•ã„。ãã†ã™ã‚‹æ–¹ãŒãƒžãƒ¼ã‚¸ã«å¤±æ•—"
+"ã—ãŸã¨ãã®å›žå¾©ãŒæ¥½ã§ã™ã€‚\n"
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s ã® %s ブランãƒ"
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr "%s 㨠%s をマージã—ã¾ã™"
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr "マージãŒå®Œäº†ã—ã¾ã—ãŸ"
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr "マージãŒå¤±æ•—ã—ã¾ã—ãŸã€‚è¡çªã®è§£æ±ºãŒå¿…è¦ã§ã™ã€‚"
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "%s ã«ãƒžãƒ¼ã‚¸"
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr "マージã™ã‚‹ãƒªãƒ“ジョン"
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"訂正中ã«ã¯ä¸­æ­¢ã§ãã¾ã›ã‚“。\n"
+"\n"
+"ã¾ãšä»Šã®ã‚³ãƒŸãƒƒãƒˆè¨‚正を完了ã•ã›ã¦ä¸‹ã•ã„。\n"
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"マージを中断ã—ã¾ã™ã‹ï¼Ÿ\n"
+"\n"
+"ç¾åœ¨ã®ãƒžãƒ¼ã‚¸ã‚’中断ã™ã‚‹ã¨ã€ã‚³ãƒŸãƒƒãƒˆã—ã¦ã„ãªã„å…¨ã¦ã®å¤‰æ›´ãŒå¤±ã‚ã‚Œã¾ã™ã€‚\n"
+"\n"
+"マージを中断ã—ã¦ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"変更点をリセットã—ã¾ã™ã‹ï¼Ÿ\n"
+"\n"
+"変更点をリセットã™ã‚‹ã¨ã€ã‚³ãƒŸãƒƒãƒˆã—ã¦ã„ãªã„å…¨ã¦ã®å¤‰æ›´ãŒå¤±ã‚ã‚Œã¾ã™ã€‚\n"
+"\n"
+"リセットã—ã¦ã‚ˆã‚ã—ã„ã§ã™ã‹ï¼Ÿ"
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr "中断ã—ã¦ã„ã¾ã™"
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr "中断ã«å¤±æ•—ã—ã¾ã—ãŸã€‚"
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr "中断完了。"
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr "既定値ã«æˆ»ã™"
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr "ä¿å­˜"
+
+#: lib/option.tcl:96
+#, tcl-format
+msgid "%s Repository"
+msgstr "%s リãƒã‚¸ãƒˆãƒª"
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr "大域(全ã¦ã®ãƒªãƒã‚¸ãƒˆãƒªï¼‰"
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr "ユーザå"
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr "é›»å­ãƒ¡ãƒ¼ãƒ«ã‚¢ãƒ‰ãƒ¬ã‚¹"
+
+#: lib/option.tcl:106
+msgid "Summarize Merge Commits"
+msgstr "マージコミットã®è¦ç´„"
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr "マージã®å†—長度"
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr "マージ後㫠diffstat を表示"
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr "ファイル変更時刻を信頼ã™ã‚‹"
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr "フェッãƒä¸­ã«ãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°ãƒ–ランãƒã‚’刈る"
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr "トラッキングブランãƒã‚’åˆã‚ã›ã‚‹"
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr "diff ã®æ–‡è„ˆè¡Œæ•°"
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr "æ–°ã—ã„ブランãƒåã®ãƒ†ãƒ³ãƒ—レート"
+
+#: lib/option.tcl:176
+msgid "Change Font"
+msgstr "フォントを変更"
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr "%s ã‚’é¸æŠž"
+
+#: lib/option.tcl:186
+msgid "pt."
+msgstr "ãƒã‚¤ãƒ³ãƒˆ"
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr "設定"
+
+#: lib/option.tcl:235
+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 "リモート・ブランãƒã‚’削除"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "å…ƒã®ãƒªãƒã‚¸ãƒˆãƒª"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr "リモート:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr "ä»»æ„ã® URL:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr "ブランãƒ"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "æ¡ä»¶ä»˜ã§å‰Šé™¤"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "マージ先:"
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "ç„¡æ¡ä»¶ï¼ˆãƒžãƒ¼ã‚¸æ¤œæŸ»ã‚’ã—ãªã„)"
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr "'マージ先' ã«ã¯ãƒ–ランãƒãŒå¿…è¦ã§ã™ã€‚"
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"以下ã®ãƒ–ランãƒã¯ %s ã«å®Œå…¨ã«ãƒžãƒ¼ã‚¸ã•ã‚Œã¦ã„ã¾ã›ã‚“:\n"
+"\n"
+" - %s"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+"å¿…è¦ãªã‚³ãƒŸãƒƒãƒˆãŒä¸è¶³ã—ã¦ã„ã‚‹ãŸã‚ã«ã€ãƒžãƒ¼ã‚¸æ¤œæŸ»ãŒå¤±æ•—ã—ã¾ã—ãŸã€‚ã¾ãš %s ã‹ã‚‰"
+"フェッãƒã—ã¦ä¸‹ã•ã„。"
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr "削除ã™ã‚‹ãƒ–ランãƒã‚’é¸æŠžã—ã¦ä¸‹ã•ã„。"
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"削除ã—ãŸãƒ–ランãƒã‚’回復ã™ã‚‹ã®ã¯å›°é›£ã§ã™ã€‚\n"
+"\n"
+"é¸æŠžã—ãŸãƒ–ランãƒã‚’削除ã—ã¦è‰¯ã„ã§ã™ã‹ï¼Ÿ"
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "%s ã‹ã‚‰ãƒ–ランãƒã‚’削除ã—ã¦ã„ã¾ã™ã€‚"
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr "リãƒã‚¸ãƒˆãƒªãŒé¸æŠžã•ã‚Œã¦ã„ã¾ã›ã‚“。"
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+msgid "Scanning %s..."
+msgstr "%s をスキャンã—ã¦ã„ã¾ã™â€¦"
+
+#: lib/shortcut.tcl:26 lib/shortcut.tcl:74
+msgid "Cannot write script:"
+msgstr "スクリプトãŒæ›¸ã‘ã¾ã›ã‚“:"
+
+#: lib/shortcut.tcl:149
+msgid "Cannot write icon:"
+msgstr "アイコンãŒæ›¸ã‘ã¾ã›ã‚“:"
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%1$s ... %4$*i %6$s 中㮠%2$*i (%7$3i%%)"
+
+#: lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "%s ã‚’å–å¾—"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "%s ã‹ã‚‰æ–°ã—ã„変更をフェッãƒã—ã¦ã„ã¾ã™"
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "é éš”刈込 %s"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr "%s ã‹ã‚‰å‰Šé™¤ã•ã‚ŒãŸãƒˆãƒ©ãƒƒã‚­ãƒ³ã‚°ãƒ»ãƒ–ランãƒã‚’刈ã£ã¦ã„ã¾ã™"
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr "%s をプッシュ"
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "%s ã¸å¤‰æ›´ã‚’プッシュã—ã¦ã„ã¾ã™"
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "%3$s 㸠%1$s %2$s をプッシュã—ã¦ã„ã¾ã™"
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr "ブランãƒã‚’プッシュ"
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr "å…ƒã®ãƒ–ランãƒ"
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr "é€ã‚Šå…ˆãƒªãƒã‚¸ãƒˆãƒª"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr "通信オプション"
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr "既存ブランãƒã‚’上書ã(変更を破棄ã™ã‚‹å¯èƒ½æ€§ãŒã‚ã‚Šã¾ã™)"
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr "Thin Pack を使ã†ï¼ˆé…ã„ãƒãƒƒãƒˆãƒ¯ãƒ¼ã‚¯æŽ¥ç¶šï¼‰"
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr "ã‚¿ã‚°ã‚’å«ã‚ã‚‹"
+
diff --git a/git-gui/po/po2msg.sh b/git-gui/po/po2msg.sh
new file mode 100644
index 000000000..c63248e37
--- /dev/null
+++ b/git-gui/po/po2msg.sh
@@ -0,0 +1,133 @@
+#!/bin/sh
+# Tcl ignores the next line -*- tcl -*- \
+exec tclsh "$0" -- "$@"
+
+# This is a really stupid program, which serves as an alternative to
+# msgfmt. It _only_ translates to Tcl mode, does _not_ validate the
+# input, and does _not_ output any statistics.
+
+proc u2a {s} {
+ set res ""
+ foreach i [split $s ""] {
+ scan $i %c c
+ if {$c<128} {
+ # escape '[', '\' and ']'
+ if {$c == 0x5b || $c == 0x5d} {
+ append res "\\"
+ }
+ append res $i
+ } else {
+ append res \\u[format %04.4x $c]
+ }
+ }
+ return $res
+}
+
+set output_directory "."
+set lang "dummy"
+set files [list]
+set show_statistics 0
+
+# parse options
+for {set i 0} {$i < $argc} {incr i} {
+ set arg [lindex $argv $i]
+ if {$arg == "--statistics"} {
+ incr show_statistics
+ continue
+ }
+ if {$arg == "--tcl"} {
+ # we know
+ continue
+ }
+ if {$arg == "-l"} {
+ incr i
+ set lang [lindex $argv $i]
+ continue
+ }
+ if {$arg == "-d"} {
+ incr i
+ set tmp [lindex $argv $i]
+ regsub "\[^/\]$" $tmp "&/" output_directory
+ continue
+ }
+ lappend files $arg
+}
+
+proc flush_msg {} {
+ global msgid msgstr mode lang out fuzzy
+ global translated_count fuzzy_count not_translated_count
+
+ if {![info exists msgid] || $mode == ""} {
+ return
+ }
+ set mode ""
+ if {$fuzzy == 1} {
+ incr fuzzy_count
+ set fuzzy 0
+ return
+ }
+
+ if {$msgid == ""} {
+ set prefix "set ::msgcat::header"
+ } else {
+ if {$msgstr == ""} {
+ incr not_translated_count
+ return
+ }
+ set prefix "::msgcat::mcset $lang \"[u2a $msgid]\""
+ incr translated_count
+ }
+
+ puts $out "$prefix \"[u2a $msgstr]\""
+}
+
+set fuzzy 0
+set translated_count 0
+set fuzzy_count 0
+set not_translated_count 0
+foreach file $files {
+ regsub "^.*/\(\[^/\]*\)\.po$" $file "$output_directory\\1.msg" outfile
+ set in [open $file "r"]
+ fconfigure $in -encoding utf-8
+ set out [open $outfile "w"]
+
+ set mode ""
+ while {[gets $in line] >= 0} {
+ if {[regexp "^#" $line]} {
+ if {[regexp ", fuzzy" $line]} {
+ set fuzzy 1
+ } else {
+ flush_msg
+ }
+ continue
+ } elseif {[regexp "^msgid \"(.*)\"$" $line dummy match]} {
+ flush_msg
+ set msgid $match
+ set mode "msgid"
+ } elseif {[regexp "^msgstr \"(.*)\"$" $line dummy match]} {
+ set msgstr $match
+ set mode "msgstr"
+ } elseif {$line == ""} {
+ flush_msg
+ } elseif {[regexp "^\"(.*)\"$" $line dummy match]} {
+ if {$mode == "msgid"} {
+ append msgid $match
+ } elseif {$mode == "msgstr"} {
+ append msgstr $match
+ } else {
+ puts stderr "I do not know what to do: $match"
+ }
+ } else {
+ puts stderr "Cannot handle $line"
+ }
+ }
+ flush_msg
+ close $in
+ close $out
+}
+
+if {$show_statistics} {
+ puts [concat "$translated_count translated messages, " \
+ "$fuzzy_count fuzzy ones, " \
+ "$not_translated_count untranslated ones."]
+}
diff --git a/git-gui/po/ru.po b/git-gui/po/ru.po
new file mode 100644
index 000000000..6727a832e
--- /dev/null
+++ b/git-gui/po/ru.po
@@ -0,0 +1,1893 @@
+# Translation of git-gui to russian
+# Copyright (C) 2007 Shawn Pearce
+# This file is distributed under the same license as the git-gui package.
+# Irina Riesen <irina.riesen@gmail.com>, 2007.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-10-31 21:23+0100\n"
+"PO-Revision-Date: 2007-10-22 22:30-0200\n"
+"Last-Translator: Alex Riesen <raa.lkml@gmail.com>\n"
+"Language-Team: Russian Translation <git@vger.kernel.org>\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:597 git-gui.sh:611 git-gui.sh:624 git-gui.sh:707
+#: git-gui.sh:726
+msgid "git-gui: fatal error"
+msgstr "git-gui: критичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°"
+
+#: git-gui.sh:558
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Ð’ %s уÑтановлен неверный шрифт:"
+
+#: git-gui.sh:583
+msgid "Main Font"
+msgstr "Шрифт интерфейÑа"
+
+#: git-gui.sh:584
+msgid "Diff/Console Font"
+msgstr "Шрифт конÑоли и изменений (diff)"
+
+#: git-gui.sh:598
+msgid "Cannot find git in PATH."
+msgstr "git не найден в PATH."
+
+#: git-gui.sh:625
+msgid "Cannot parse Git version string:"
+msgstr "Ðевозможно раÑпознать Ñтроку верÑии Git: "
+
+#: git-gui.sh:643
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Ðевозможно определить верÑию Git\n"
+"%s указывает на верÑию '%s'.\n"
+"\n"
+"Ð´Ð»Ñ %s требуетÑÑ Ð²ÐµÑ€ÑÐ¸Ñ Git, Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ 1.5.0\n"
+"\n"
+"ПринÑÑ‚ÑŒ '%s' как верÑию 1.5.0?\n"
+
+#: git-gui.sh:881
+msgid "Git directory not found:"
+msgstr "Каталог Git не найден:"
+
+#: git-gui.sh:888
+msgid "Cannot move to top of working directory:"
+msgstr "Ðевозможно перейти к корню рабочего каталога репозиториÑ: "
+
+#: git-gui.sh:895
+msgid "Cannot use funny .git directory:"
+msgstr "Каталог.git иÑпорчен: "
+
+#: git-gui.sh:900
+msgid "No working directory"
+msgstr "ОтÑутÑтвует рабочий каталог"
+
+#: git-gui.sh:1047
+msgid "Refreshing file status..."
+msgstr "Обновление информации о ÑоÑтоÑнии файлов..."
+
+#: git-gui.sh:1112
+msgid "Scanning for modified files ..."
+msgstr "ПоиÑк измененных файлов..."
+
+#: git-gui.sh:1287 lib/browser.tcl:245
+msgid "Ready."
+msgstr "Готово."
+
+#: git-gui.sh:1553
+msgid "Unmodified"
+msgstr "Ðе изменено"
+
+#: git-gui.sh:1555
+msgid "Modified, not staged"
+msgstr "Изменено, не подготовлено"
+
+#: git-gui.sh:1556 git-gui.sh:1561
+msgid "Staged for commit"
+msgstr "Подготовлено Ð´Ð»Ñ ÑохранениÑ"
+
+#: git-gui.sh:1557 git-gui.sh:1562
+msgid "Portions staged for commit"
+msgstr "ЧаÑти, подготовленные Ð´Ð»Ñ ÑохранениÑ"
+
+#: git-gui.sh:1558 git-gui.sh:1563
+msgid "Staged for commit, missing"
+msgstr "Подготовлено Ð´Ð»Ñ ÑохранениÑ, отÑутÑтвует"
+
+#: git-gui.sh:1560
+msgid "Untracked, not staged"
+msgstr "Ðе отÑлеживаетÑÑ, не подготовлено"
+
+#: git-gui.sh:1565
+msgid "Missing"
+msgstr "ОтÑутÑтвует"
+
+#: git-gui.sh:1566
+msgid "Staged for removal"
+msgstr "Подготовлено Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ"
+
+#: git-gui.sh:1567
+msgid "Staged for removal, still present"
+msgstr "Подготовлено Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ, еще не удалено"
+
+#: git-gui.sh:1569 git-gui.sh:1570 git-gui.sh:1571 git-gui.sh:1572
+msgid "Requires merge resolution"
+msgstr "ТребуетÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ конфликта при объединении"
+
+#: git-gui.sh:1607
+msgid "Starting gitk... please wait..."
+msgstr "ЗапуÑкаетÑÑ gitk... пожалуйÑта, ждите..."
+
+#: git-gui.sh:1616
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+"Ðе удалоÑÑŒ запуÑтить gitk:\n"
+"\n"
+"%s не ÑущеÑтвует"
+
+#: git-gui.sh:1816 lib/choose_repository.tcl:35
+msgid "Repository"
+msgstr "Репозиторий"
+
+#: git-gui.sh:1817
+msgid "Edit"
+msgstr "Редактировать"
+
+#: git-gui.sh:1819 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr "Ветвь"
+
+#: git-gui.sh:1822 lib/choose_rev.tcl:547
+msgid "Commit@@noun"
+msgstr "СоÑтоÑние"
+
+#: git-gui.sh:1825 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
+msgid "Merge"
+msgstr "Объединить"
+
+#: git-gui.sh:1826 lib/choose_rev.tcl:556
+msgid "Remote"
+msgstr "Внешние репозитории"
+
+#: git-gui.sh:1835
+msgid "Browse Current Branch's Files"
+msgstr "ПроÑмотреть файлы текущей ветви"
+
+#: git-gui.sh:1839
+msgid "Browse Branch Files..."
+msgstr "Показать файлы ветви..."
+
+#: git-gui.sh:1844
+msgid "Visualize Current Branch's History"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹ ветви наглÑдно"
+
+#: git-gui.sh:1848
+msgid "Visualize All Branch History"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð²Ñех ветвей наглÑдно"
+
+#: git-gui.sh:1855
+#, tcl-format
+msgid "Browse %s's Files"
+msgstr "Показать файлы ветви %s"
+
+#: git-gui.sh:1857
+#, tcl-format
+msgid "Visualize %s's History"
+msgstr "ИÑÑ‚Ð¾Ñ€Ð¸Ñ Ð²ÐµÑ‚Ð²Ð¸ %s наглÑдно"
+
+#: git-gui.sh:1862 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr "СтатиÑтика базы данных"
+
+#: git-gui.sh:1865 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "Сжать базу данных"
+
+#: git-gui.sh:1868
+msgid "Verify Database"
+msgstr "Проверить базу данных"
+
+#: git-gui.sh:1875 git-gui.sh:1879 git-gui.sh:1883 lib/shortcut.tcl:7
+#: lib/shortcut.tcl:39 lib/shortcut.tcl:71
+msgid "Create Desktop Icon"
+msgstr "Создать Ñрлык на рабочем Ñтоле"
+
+#: git-gui.sh:1888 lib/choose_repository.tcl:176 lib/choose_repository.tcl:184
+msgid "Quit"
+msgstr "Выход"
+
+#: git-gui.sh:1895
+msgid "Undo"
+msgstr "Отменить"
+
+#: git-gui.sh:1898
+msgid "Redo"
+msgstr "Повторить"
+
+#: git-gui.sh:1902 git-gui.sh:2395
+msgid "Cut"
+msgstr "Вырезать"
+
+#: git-gui.sh:1905 git-gui.sh:2398 git-gui.sh:2469 git-gui.sh:2541
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr "Копировать"
+
+#: git-gui.sh:1908 git-gui.sh:2401
+msgid "Paste"
+msgstr "Ð’Ñтавить"
+
+#: git-gui.sh:1911 git-gui.sh:2404 lib/branch_delete.tcl:26
+#: lib/remote_branch_delete.tcl:38
+msgid "Delete"
+msgstr "Удалить"
+
+#: git-gui.sh:1915 git-gui.sh:2408 git-gui.sh:2545 lib/console.tcl:69
+msgid "Select All"
+msgstr "Выделить вÑе"
+
+#: git-gui.sh:1924
+msgid "Create..."
+msgstr "Создать..."
+
+#: git-gui.sh:1930
+msgid "Checkout..."
+msgstr "Перейти..."
+
+#: git-gui.sh:1936
+msgid "Rename..."
+msgstr "Переименовать..."
+
+#: git-gui.sh:1941 git-gui.sh:2040
+msgid "Delete..."
+msgstr "Удалить..."
+
+#: git-gui.sh:1946
+msgid "Reset..."
+msgstr "СброÑить..."
+
+#: git-gui.sh:1958 git-gui.sh:2342
+msgid "New Commit"
+msgstr "Ðовое ÑоÑтоÑние"
+
+#: git-gui.sh:1966 git-gui.sh:2349
+msgid "Amend Last Commit"
+msgstr "ИÑправить поÑледнее ÑоÑтоÑние"
+
+#: git-gui.sh:1975 git-gui.sh:2309 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "Перечитать"
+
+#: git-gui.sh:1981
+msgid "Stage To Commit"
+msgstr "Подготовить Ð´Ð»Ñ ÑохранениÑ"
+
+#: git-gui.sh:1986
+msgid "Stage Changed Files To Commit"
+msgstr "Подготовить измененные файлы Ð´Ð»Ñ ÑохранениÑ"
+
+#: git-gui.sh:1992
+msgid "Unstage From Commit"
+msgstr "Убрать из подготовленного"
+
+#: git-gui.sh:1997 lib/index.tcl:393
+msgid "Revert Changes"
+msgstr "Отменить изменениÑ"
+
+#: git-gui.sh:2004 git-gui.sh:2321 git-gui.sh:2419
+msgid "Sign Off"
+msgstr "ПодпиÑать"
+
+#: git-gui.sh:2008 git-gui.sh:2325
+msgid "Commit@@verb"
+msgstr "Сохранить"
+
+#: git-gui.sh:2019
+msgid "Local Merge..."
+msgstr "Локальное объединение..."
+
+#: git-gui.sh:2024
+msgid "Abort Merge..."
+msgstr "Прервать объединение..."
+
+#: git-gui.sh:2036
+msgid "Push..."
+msgstr "Отправить..."
+
+#: git-gui.sh:2047 lib/choose_repository.tcl:40
+msgid "Apple"
+msgstr ""
+
+#: git-gui.sh:2050 git-gui.sh:2072 lib/about.tcl:13
+#: lib/choose_repository.tcl:43 lib/choose_repository.tcl:49
+#, tcl-format
+msgid "About %s"
+msgstr "О %s"
+
+#: git-gui.sh:2054
+msgid "Preferences..."
+msgstr "ÐаÑтройки..."
+
+#: git-gui.sh:2062 git-gui.sh:2587
+msgid "Options..."
+msgstr "ÐаÑтройки..."
+
+#: git-gui.sh:2068 lib/choose_repository.tcl:46
+msgid "Help"
+msgstr "Помощь"
+
+#: git-gui.sh:2109
+msgid "Online Documentation"
+msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð² интернете"
+
+#: git-gui.sh:2193
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr "критичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°: %s: нет такого файла или каталога"
+
+#: git-gui.sh:2226
+msgid "Current Branch:"
+msgstr "Ð¢ÐµÐºÑƒÑ‰Ð°Ñ Ð²ÐµÑ‚Ð²ÑŒ:"
+
+#: git-gui.sh:2247
+msgid "Staged Changes (Will Commit)"
+msgstr "Подготовлено (будет Ñохранено)"
+
+#: git-gui.sh:2266
+msgid "Unstaged Changes"
+msgstr "Изменено (не будет Ñохранено)"
+
+#: git-gui.sh:2315
+msgid "Stage Changed"
+msgstr "Подготовить вÑе"
+
+#: git-gui.sh:2331 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "Отправить"
+
+#: git-gui.sh:2361
+msgid "Initial Commit Message:"
+msgstr "Комментарий к первому ÑоÑтоÑнию:"
+
+#: git-gui.sh:2362
+msgid "Amended Commit Message:"
+msgstr "Комментарий к иÑправленному ÑоÑтоÑнию:"
+
+#: git-gui.sh:2363
+msgid "Amended Initial Commit Message:"
+msgstr "Комментарий к иÑправленному первоначальному ÑоÑтоÑнию:"
+
+#: git-gui.sh:2364
+msgid "Amended Merge Commit Message:"
+msgstr "Комментарий к иÑправленному объединению:"
+
+#: git-gui.sh:2365
+msgid "Merge Commit Message:"
+msgstr "Комментарий к объединению:"
+
+#: git-gui.sh:2366
+msgid "Commit Message:"
+msgstr "Комментарий к ÑоÑтоÑнию:"
+
+#: git-gui.sh:2411 git-gui.sh:2549 lib/console.tcl:71
+msgid "Copy All"
+msgstr "Копировать вÑе"
+
+#: git-gui.sh:2435 lib/blame.tcl:104
+msgid "File:"
+msgstr "Файл:"
+
+#: git-gui.sh:2537
+msgid "Refresh"
+msgstr "Обновить"
+
+#: git-gui.sh:2558
+msgid "Apply/Reverse Hunk"
+msgstr "Применить/Убрать изменение"
+
+#: git-gui.sh:2564
+msgid "Decrease Font Size"
+msgstr "Уменьшить размер шрифта"
+
+#: git-gui.sh:2568
+msgid "Increase Font Size"
+msgstr "Увеличить размер шрифта"
+
+#: git-gui.sh:2573
+msgid "Show Less Context"
+msgstr "Меньше контекÑта"
+
+#: git-gui.sh:2580
+msgid "Show More Context"
+msgstr "Больше контекÑта"
+
+#: git-gui.sh:2594
+msgid "Unstage Hunk From Commit"
+msgstr "Ðе ÑохранÑÑ‚ÑŒ чаÑÑ‚ÑŒ"
+
+#: git-gui.sh:2596
+msgid "Stage Hunk For Commit"
+msgstr "Подготовить чаÑÑ‚ÑŒ Ð´Ð»Ñ ÑохранениÑ"
+
+#: git-gui.sh:2615
+msgid "Initializing..."
+msgstr "ИнициализациÑ..."
+
+#: git-gui.sh:2706
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+"Возможны ошибки в переменных окружениÑ.\n"
+"\n"
+"Переменные окружениÑ, которые возможно\n"
+"будут проигнорированы командами Git,\n"
+"запущенными из %s\n"
+"\n"
+
+#: git-gui.sh:2736
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+"\n"
+"Это извеÑÑ‚Ð½Ð°Ñ Ð¿Ñ€Ð¾Ð±Ð»ÐµÐ¼Ð° Ñ Tcl,\n"
+"раÑпроÑтранÑемым Cygwin."
+
+#: git-gui.sh:2741
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+"\n"
+"\n"
+"ВмеÑто иÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ %s можно\n"
+"Ñохранить Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸Ñ user.name и\n"
+"user.email в Вашем перÑональном\n"
+"файле ~/.gitconfig.\n"
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui - графичеÑкий пользовательÑкий Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ðº Git."
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr "ПроÑмотр файла"
+
+#: lib/blame.tcl:81
+msgid "Commit:"
+msgstr "Сохраненное ÑоÑтоÑние:"
+
+#: lib/blame.tcl:249
+msgid "Copy Commit"
+msgstr "Скопировать SHA-1"
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr "Чтение %s..."
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr "Загрузка аннотации копирований/переименований..."
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr "Ñтрок прокомментировано"
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr "Загрузка аннотаций первоначального Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¾Ð±ÑŠÐµÐºÑ‚Ð°..."
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr "ÐÐ½Ð½Ð¾Ñ‚Ð°Ñ†Ð¸Ñ Ð·Ð°Ð²ÐµÑ€ÑˆÐµÐ½Ð°."
+
+#: lib/blame.tcl:731
+msgid "Loading annotation..."
+msgstr "Загрузка аннотации..."
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr "Ðвтор:"
+
+#: lib/blame.tcl:791
+msgid "Committer:"
+msgstr "Сохранил:"
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr "ИÑходный файл:"
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr "ИÑточник:"
+
+#: lib/blame.tcl:916
+msgid "In File:"
+msgstr "Файл:"
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr "Скопировано/перемещено в:"
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
+msgstr "Перейти на ветвь"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "Перейти"
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr "Отменить"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr "ВерÑиÑ"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+msgid "Options"
+msgstr "ÐаÑтройки"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Получить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¸Ð· внешней ветви"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr "ОтÑоединить от локальной ветви"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
+msgstr "Создание ветви"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
+msgstr "Создать новую ветвь"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:375
+msgid "Create"
+msgstr "Создать"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
+msgstr "Ðазвание ветви"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr "Ðазвание:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr "ВзÑÑ‚ÑŒ из имен ветвей ÑлежениÑ"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "ÐÐ°Ñ‡Ð°Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ€ÑиÑ"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr "Обновить имеющуюÑÑ Ð²ÐµÑ‚Ð²ÑŒ:"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "Ðет"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Только Fast Forward"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+msgid "Reset"
+msgstr "СброÑ"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "ПоÑле ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñделать текущей"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr "Укажите ветвь ÑлежениÑ."
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr "Ветвь ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ %s не ÑвлÑетÑÑ Ð²ÐµÑ‚Ð²ÑŒÑŽ во внешнем репозитории."
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr "Укажите название ветви."
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr "ÐедопуÑтимое название ветви '%s'."
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
+msgstr "Удаление ветви"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr "Удалить локальную ветвь"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
+msgstr "Локальные ветви"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "Удалить только в Ñлучае, еÑли было объединение Ñ"
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr "Ð’Ñегда (не выполнÑÑ‚ÑŒ проверку на объединение)"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr "Следующие ветви объединены Ñ %s не полноÑтью:"
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+"ВоÑÑтанавливать удаленные ветви Ñложно. \n"
+"\n"
+" Удалить выбранные ветви?"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+"Ðе удалоÑÑŒ удалить ветви:\n"
+"%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
+msgstr "Переименование ветви"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "Переименовать"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
+msgstr "Ветвь:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "Ðовое название:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr "Укажите ветвь Ð´Ð»Ñ Ð¿ÐµÑ€ÐµÐ¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð¸Ñ."
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "Ветвь '%s' уже ÑущеÑтвует."
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Ðе удалоÑÑŒ переименовать '%s'. "
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr "ЗапуÑк..."
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "ПроÑмотр ÑпиÑка файлов"
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr "Загрузка %s..."
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr "[Ðа уровень выше]"
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+msgid "Browse Branch Files"
+msgstr "Показать файлы ветви"
+
+#: 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 "Показать"
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr "Получение %s из %s "
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr "критичеÑÐºÐ°Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ°: невозможно разрешить %s"
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr "Закрыть"
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr "Ветвь '%s' не ÑущеÑтвует "
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+"Ветвь '%s' уже ÑущеÑтвует.\n"
+"\n"
+"Она не может быть прокручена(fast-forward) к %s.\n"
+"ТребуетÑÑ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ðµ."
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr "Ð¡Ñ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ '%s' не поддерживаетÑÑ."
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr "Ðе удалоÑÑŒ обновить '%s'."
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr "Ð Ð°Ð±Ð¾Ñ‡Ð°Ñ Ð¾Ð±Ð»Ð°ÑÑ‚ÑŒ заблокирована другим процеÑÑом."
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"ПоÑледнее прочитанное ÑоÑтоÑние Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ ÑоответÑтвует текущему.\n"
+"\n"
+"С момента поÑледней проверки репозиторий был изменен другой программой Git. "
+"Ðеобходимо перечитать репозиторий, прежде чем изменÑÑ‚ÑŒ текущую ветвь.\n"
+"\n"
+"Это будет Ñделано ÑÐµÐ¹Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки.\n"
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr "Обновление рабочего каталога из '%s'..."
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr "Прерван переход на '%s' (требуетÑÑ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ðµ на уровне файлов)"
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr "ТребуетÑÑ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ðµ на уровне файлов."
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr "Ветвь '%s' оÑтаетÑÑ Ñ‚ÐµÐºÑƒÑ‰ÐµÐ¹."
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+"Ð’Ñ‹ находитеÑÑŒ не в локальной ветви.\n"
+"\n"
+"ЕÑли вы хотите Ñнова вернутьÑÑ Ðº какой-нибудь ветви, Ñоздайте ее ÑейчаÑ, "
+"Ð½Ð°Ñ‡Ð¸Ð½Ð°Ñ Ñ 'Текущего отÑоединенного ÑоÑтоÑниÑ'."
+
+#: lib/checkout_op.tcl:446
+#, tcl-format
+msgid "Checked out '%s'."
+msgstr "Ветвь '%s' Ñделана текущей."
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr "Ð¡Ð±Ñ€Ð¾Ñ '%s' в '%s' приведет к потере Ñледующих Ñохраненных ÑоÑтоÑний: "
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr "ВоÑÑтановить потерÑнные Ñохраненные ÑоÑтоÑÐ½Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚ Ñложно."
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr "СброÑить '%s'?"
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr "ÐаглÑдно"
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+"Ðе удалоÑÑŒ уÑтановить текущую ветвь.\n"
+"\n"
+"Ваш рабочий каталог обновлен только чаÑтично. Были обновлены вÑе файлы кроме "
+"Ñлужебных файлов Git. \n"
+"\n"
+"Этого не должно было произойти. %s завершаетÑÑ."
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr "Выбрать"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr "Шрифт"
+
+#: lib/choose_font.tcl:73
+msgid "Font Size"
+msgstr "Размер шрифта"
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr "Пример текÑта"
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+"Это пример текÑта.\n"
+"ЕÑли Вам нравитÑÑ Ñтот текÑÑ‚, Ñто может быть Ваш шрифт."
+
+#: lib/choose_repository.tcl:27
+msgid "Git Gui"
+msgstr ""
+
+#: lib/choose_repository.tcl:80 lib/choose_repository.tcl:380
+msgid "Create New Repository"
+msgstr "Создать новый репозиторий"
+
+#: 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:99
+msgid "Clone..."
+msgstr "Склонировать..."
+
+#: lib/choose_repository.tcl:106 lib/choose_repository.tcl:978
+msgid "Open Existing Repository"
+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:294
+#, tcl-format
+msgid "Location %s already exists."
+msgstr "Путь '%s' уже ÑущеÑтвует."
+
+#: 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:385 lib/choose_repository.tcl:486
+msgid "Directory:"
+msgstr "Каталог:"
+
+#: lib/choose_repository.tcl:415 lib/choose_repository.tcl:544
+#: lib/choose_repository.tcl:1013
+msgid "Git Repository"
+msgstr "Репозиторий"
+
+#: lib/choose_repository.tcl:430 lib/choose_repository.tcl:437
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "Каталог '%s' уже ÑущеÑтвует."
+
+#: lib/choose_repository.tcl:442
+#, tcl-format
+msgid "File %s already exists."
+msgstr "Файл '%s' уже ÑущеÑтвует."
+
+#: lib/choose_repository.tcl:463
+msgid "Clone"
+msgstr "Склонировать"
+
+#: lib/choose_repository.tcl:476
+msgid "URL:"
+msgstr "СÑылка:"
+
+#: lib/choose_repository.tcl:496
+msgid "Clone Type:"
+msgstr "Тип клона:"
+
+#: lib/choose_repository.tcl:502
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr "Стандартный (БыÑтрый, полуизбыточный, \"жеÑткие\" ÑÑылки)"
+
+#: lib/choose_repository.tcl:508
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "ÐŸÐ¾Ð»Ð½Ð°Ñ ÐºÐ¾Ð¿Ð¸Ñ (Медленный, Ñоздает резервную копию)"
+
+#: lib/choose_repository.tcl:514
+msgid "Shared (Fastest, Not Recommended, No Backup)"
+msgstr "Общий (Самый быÑтрый, не рекомендуетÑÑ, без резервной копии)"
+
+#: 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"
+
+#: lib/choose_repository.tcl:586
+msgid "Standard only available for local repository."
+msgstr "Стандартный клон возможен только Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ репозиториÑ."
+
+#: lib/choose_repository.tcl:590
+msgid "Shared only available for local repository."
+msgstr "Общий клон возможен только Ð´Ð»Ñ Ð»Ð¾ÐºÐ°Ð»ÑŒÐ½Ð¾Ð³Ð¾ репозиториÑ."
+
+#: lib/choose_repository.tcl:617
+msgid "Failed to configure origin"
+msgstr "Ðе могу Ñконфигурировать иÑходный репозиторий."
+
+#: lib/choose_repository.tcl:629
+msgid "Counting objects"
+msgstr "Считаю объекты"
+
+#: lib/choose_repository.tcl:630
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:654
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr "Ðе могу Ñкопировать objects/info/alternates: %s"
+
+#: lib/choose_repository.tcl:690
+#, tcl-format
+msgid "Nothing to clone from %s."
+msgstr "Ðечего клонировать Ñ %s."
+
+#: 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:705
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr "\"ЖеÑткие ÑÑылки\" не доÑтупны. Буду иÑпользовать копирование."
+
+#: lib/choose_repository.tcl:717
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "Клонирование %s"
+
+#: lib/choose_repository.tcl:748
+msgid "Copying objects"
+msgstr "Копирование objects"
+
+#: lib/choose_repository.tcl:749
+msgid "KiB"
+msgstr "КБ"
+
+#: lib/choose_repository.tcl:773
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "Ðе могу Ñкопировать объект: %s"
+
+#: lib/choose_repository.tcl:783
+msgid "Linking objects"
+msgstr "Создание ÑÑылок на objects"
+
+#: lib/choose_repository.tcl:784
+msgid "objects"
+msgstr "объекты"
+
+#: lib/choose_repository.tcl:792
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr "Ðе могу \"жеÑтко ÑвÑзать\" объект: %s"
+
+#: lib/choose_repository.tcl:847
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr ""
+"Ðе могу получить ветви и объекты. Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð° конÑоли."
+
+#: lib/choose_repository.tcl:858
+msgid "Cannot fetch tags. See console output for details."
+msgstr "Ðе могу получить метки. Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð° конÑоли."
+
+#: lib/choose_repository.tcl:882
+msgid "Cannot determine HEAD. See console output for details."
+msgstr "Ðе могу определить HEAD. Ð”Ð¾Ð¿Ð¾Ð»Ð½Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð½Ð° конÑоли."
+
+#: lib/choose_repository.tcl:891
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr "Ðе могу очиÑтить %s"
+
+#: lib/choose_repository.tcl:897
+msgid "Clone failed."
+msgstr "Клонирование не удалоÑÑŒ."
+
+#: lib/choose_repository.tcl:904
+msgid "No default branch obtained."
+msgstr "Ðе было получено ветви по умолчанию."
+
+#: lib/choose_repository.tcl:915
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr "Ðе могу раÑпознать %s как ÑоÑтоÑние."
+
+#: lib/choose_repository.tcl:927
+msgid "Creating working directory"
+msgstr "Создаю рабочий каталог"
+
+#: lib/choose_repository.tcl:928 lib/index.tcl:65 lib/index.tcl:127
+#: lib/index.tcl:193
+msgid "files"
+msgstr "файлов"
+
+#: lib/choose_repository.tcl:957
+msgid "Initial file checkout failed."
+msgstr "Ðе удалоÑÑŒ получить начальное ÑоÑтоÑние файлов репозиториÑ."
+
+#: lib/choose_repository.tcl:973
+msgid "Open"
+msgstr "Открыть"
+
+#: lib/choose_repository.tcl:983
+msgid "Repository:"
+msgstr "Репозиторий:"
+
+#: lib/choose_repository.tcl:1033
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Ðе удалоÑÑŒ открыть репозиторий %s:"
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr "Текущее отÑоединенное ÑоÑтоÑние"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Выражение Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð²ÐµÑ€Ñии:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
+msgstr "Ð›Ð¾ÐºÐ°Ð»ÑŒÐ½Ð°Ñ Ð²ÐµÑ‚Ð²ÑŒ:"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
+msgstr "Ветвь ÑлежениÑ"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr "Таг"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "ÐÐµÐ²ÐµÑ€Ð½Ð°Ñ Ð²ÐµÑ€ÑиÑ: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "ВерÑÐ¸Ñ Ð½Ðµ указана."
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "ПуÑтое выражение Ð´Ð»Ñ Ð¾Ð¿Ñ€ÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð²ÐµÑ€Ñии."
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr "Обновлено"
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr "СÑылка"
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+"ОтÑутÑтвует ÑоÑтоÑние Ð´Ð»Ñ Ð¸ÑправлениÑ.\n"
+"\n"
+"Ð’Ñ‹ Ñоздаете первое ÑоÑтоÑние в репозитории, здеÑÑŒ еще нечего иÑправлÑÑ‚ÑŒ.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+"Ðевозможно иÑправить ÑоÑтоÑние во Ð²Ñ€ÐµÐ¼Ñ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ.\n"
+"\n"
+"Текущее объединение не завершено. Ðевозможно иÑправить предыдущее "
+"Ñохраненное ÑоÑтоÑние не Ð¿Ñ€ÐµÑ€Ñ‹Ð²Ð°Ñ Ñ‚ÐµÐºÑƒÑ‰ÐµÐµ объединение.\n"
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr "Ошибка при загрузке данных Ð´Ð»Ñ Ð¸ÑÐ¿Ñ€Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ñохраненного ÑоÑтоÑниÑ:"
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr "Ðевозможно получить информацию об авторÑтве:"
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr "Ðеверный GIT_COMMITTER_IDENT:"
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"ПоÑледнее прочитанное ÑоÑтоÑние Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ ÑоответÑтвует текущему.\n"
+"\n"
+"С момента поÑледней проверки репозиторий был изменен другой программой Git. "
+"Ðеобходимо перечитать репозиторий, прежде чем изменÑÑ‚ÑŒ текущую ветвь. \n"
+"\n"
+"Это будет Ñделано ÑÐµÐ¹Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки.\n"
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+"ÐÐµÐ»ÑŒÐ·Ñ Ñохранить необъединенные файлы.\n"
+"\n"
+"Ð”Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %s возник конфликт объединениÑ. Разрешите конфликт и добавьте к "
+"подготовленным файлам перед Ñохранением.\n"
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+"Обнаружено неизвеÑтное ÑоÑтоÑние файла %s.\n"
+"\n"
+"Файл %s не может быть Ñохранен данной программой.\n"
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+"ОтÑутÑтвуют Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑохранениÑ.\n"
+"\n"
+"Подготовьте Ñ…Ð¾Ñ‚Ñ Ð±Ñ‹ один файл до ÑÐ¾Ð·Ð´Ð°Ð½Ð¸Ñ Ñохраненного ÑоÑтоÑниÑ.\n"
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+"Ðапишите комментарий к Ñохраненному ÑоÑтоÑнию.\n"
+"\n"
+"РекомендуетÑÑ Ñледующий формат комментариÑ:\n"
+"\n"
+"- Ð¿ÐµÑ€Ð²Ð°Ñ Ñтрока: краткое опиÑание Ñделанных изменений.\n"
+"- Ð²Ñ‚Ð¾Ñ€Ð°Ñ Ñтрока пуÑтаÑ\n"
+"- оÑтавшиеÑÑ Ñтроки: опишите, что дают ваши изменениÑ.\n"
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr "Программа write-tree завершилаÑÑŒ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹:"
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr "СоÑтоÑние %s выглÑдит поврежденным"
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+"ОтÑутÑтвуют Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑохранениÑ.\n"
+"\n"
+"Ðи один файл не был изменен и не было объединениÑ.\n"
+"\n"
+"Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки запуÑтитÑÑ Ð¿ÐµÑ€ÐµÑ‡Ð¸Ñ‚Ñ‹Ð²Ð°Ð½Ð¸Ðµ репозиториÑ.\n"
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr "ОтуÑтвуют Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ Ð´Ð»Ñ ÑохранениÑ."
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr "предупреждение: Tcl не поддерживает кодировку '%s'."
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr "Программа commit-tree завершилаÑÑŒ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹:"
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr "Программа update-ref завершилаÑÑŒ Ñ Ð¾ÑˆÐ¸Ð±ÐºÐ¾Ð¹:"
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr "Создано ÑоÑтоÑние %s: %s "
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr "Ð’ процеÑÑе... пожалуйÑта, ждите..."
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr "ПроцеÑÑ ÑƒÑпешно завершен"
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr "Ошибка: не удалоÑÑŒ выполнить команду"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "КоличеÑтво неÑвÑзанных объектов"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "Объем диÑкового проÑтранÑтва, занÑтый неÑвÑзанными объектами"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "КоличеÑтво упакованных объектов"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "КоличеÑтво pack-файлов"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "Объем диÑкового проÑтранÑтва, занÑтый упакованными объектами"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "ÐеÑвÑзанные объекты, которые можно удалить"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "МуÑор"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Сжатие базы объектов"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "Проверка базы объектов при помощи fsck"
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+"Этот репозиторий ÑÐµÐ¹Ñ‡Ð°Ñ Ñодержит примерно %i Ñвободных объектов\n"
+"\n"
+"Ð”Ð»Ñ Ð»ÑƒÑ‡ÑˆÐµÐ¹ производительноÑти рекомендуетÑÑ Ñжать базу данных, когда еÑÑ‚ÑŒ "
+"более %i неÑвÑзанных объектов.\n"
+"\n"
+"Сжать базу данных ÑейчаÑ?"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "ÐÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð°Ñ Ð´Ð°Ñ‚Ð° в репозитории: %s"
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Изменений не обнаружено.\n"
+"\n"
+"в %s отутÑтвуют изменениÑ.\n"
+"\n"
+"Дата Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° была обновлена другой программой, но Ñодержимое файла "
+"оÑталоÑÑŒ прежним.\n"
+"\n"
+"Ð¡ÐµÐ¹Ñ‡Ð°Ñ Ð±ÑƒÐ´ÐµÑ‚ запущено перечитывание репозиториÑ, чтобы найти подобные файлы."
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "Загрузка изменений в %s..."
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Ðе могу показать %s"
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr "Ошибка загрузки файла:"
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr "Репозиторий Git (подпроект)"
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr "* Двоичный файл (Ñодержимое не показано)"
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr "Ошибка загрузки diff:"
+
+#: lib/diff.tcl:302
+msgid "Failed to unstage selected hunk."
+msgstr "Ðе удалоÑÑŒ иÑключить выбранную чаÑÑ‚ÑŒ."
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr "Ðе удалоÑÑŒ подготовить к Ñохранению выбранную чаÑÑ‚ÑŒ."
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr "ошибка"
+
+#: lib/error.tcl:28
+msgid "warning"
+msgstr "предупреждение"
+
+#: lib/error.tcl:81
+msgid "You must correct the above errors before committing."
+msgstr "Прежде чем Ñохранить, иÑправьте вышеуказанные ошибки."
+
+#: 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. СоÑтоÑние Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð±ÑƒÐ´ÐµÑ‚"
+"перечитано автоматичеÑки."
+
+#: 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:326
+#, tcl-format
+msgid "Adding %s"
+msgstr "Добавление %s..."
+
+#: lib/index.tcl:381
+#, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "Отменить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² файле %s?"
+
+#: lib/index.tcl:383
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr "Отменить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² %i файле(-ах)?"
+
+#: lib/index.tcl:389
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr ""
+"Любые изменениÑ, не подготовленные к Ñохранению, будут потерÑны при данной "
+"операции."
+
+#: lib/index.tcl:392
+msgid "Do Nothing"
+msgstr "Ðичего не делать"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+"Ðевозможно выполнить объединение во Ð²Ñ€ÐµÐ¼Ñ Ð¸ÑправлениÑ.\n"
+"\n"
+"Завершите иÑправление данного ÑоÑтоÑÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ выполнением операции "
+"объединениÑ.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+"ПоÑледнее прочитанное ÑоÑтоÑние Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ Ð½Ðµ ÑоответÑтвует текущему.\n"
+"\n"
+"С момента поÑледней проверки репозиторий был изменен другой программой Git. "
+"Ðеобходимо перечитать репозиторий, прежде чем изменÑÑ‚ÑŒ текущую ветвь.\n"
+"\n"
+"Это будет Ñделано ÑÐµÐ¹Ñ‡Ð°Ñ Ð°Ð²Ñ‚Ð¾Ð¼Ð°Ñ‚Ð¸Ñ‡ÐµÑки.\n"
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+"Предыдущее объединение не завершено из-за конфликта.\n"
+"\n"
+"Ð”Ð»Ñ Ñ„Ð°Ð¹Ð»Ð° %s возник конфликт объединениÑ.\n"
+"\n"
+"Разрешите конфликт, подготовьте файл и Ñохраните. Только поÑле Ñтого можно "
+"начать Ñледующее объединение.\n"
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+"Ð˜Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ Ñохранены.\n"
+"\n"
+"Файл %s изменен.\n"
+"\n"
+"Подготовьте и Ñохраните Ð¸Ð·Ð¼ÐµÐ½Ð¸Ñ Ð¿ÐµÑ€ÐµÐ´ началом объединениÑ. Ð’ Ñлучае "
+"необходимоÑти Ñто позволит прервать операцию объединениÑ.\n"
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s из %s"
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr "Объединение %s и %s"
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr "Объединение уÑпешно завершено."
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr "Ðе удалоÑÑŒ завершить объединение. ТребуетÑÑ Ñ€Ð°Ð·Ñ€ÐµÑˆÐµÐ½Ð¸Ðµ конфликта."
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Объединить Ñ %s"
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr "ВерÑÐ¸Ñ Ð´Ð»Ñ Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ"
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+"Ðевозможно прервать иÑправление.\n"
+"\n"
+"Завершите текущее иÑправление Ñохраненного ÑоÑтоÑниÑ.\n"
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+"Прервать объединение?\n"
+"\n"
+"Прерывание Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÑ‚ к потере *ВСЕХ* неÑохраненных изменений.\n"
+"\n"
+"Продолжить?"
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+"Прервать объединение?\n"
+"\n"
+"Прерывание Ð¾Ð±ÑŠÐµÐ´Ð¸Ð½ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸Ð²ÐµÐ´ÐµÑ‚ к потере *ВСЕХ* неÑохраненных изменений.\n"
+"\n"
+"Продолжить?"
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr "Прерываю"
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr "Прервать не удалоÑÑŒ."
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr "Прервано."
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr "ВоÑÑтановить наÑтройки по умолчанию"
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr "Сохранить"
+
+#: lib/option.tcl:96
+#, tcl-format
+msgid "%s Repository"
+msgstr "Ð´Ð»Ñ Ñ€ÐµÐ¿Ð¾Ð·Ð¸Ñ‚Ð¾Ñ€Ð¸Ñ %s"
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr "Общие (Ð´Ð»Ñ Ð²Ñех репозиториев)"
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr "Ð˜Ð¼Ñ Ð¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ñ‚ÐµÐ»Ñ"
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr "ÐÐ´ÐµÑ Ñлектронной почты"
+
+#: lib/option.tcl:106
+msgid "Summarize Merge Commits"
+msgstr "Суммарный комментарий при объединении"
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr "Уровень детальноÑти Ñообщений при объединении"
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr "Показать отчет об изменениÑÑ… поÑле объединениÑ"
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr "ДоверÑÑ‚ÑŒ времени модификации файла"
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr "ЧиÑтка ветвей ÑÐ»ÐµÐ¶ÐµÐ½Ð¸Ñ Ð¿Ñ€Ð¸ получении изменений"
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr "Ð˜Ð¼Ñ Ð½Ð¾Ð²Ð¾Ð¹ ветви взÑÑ‚ÑŒ из имен ветвей ÑлежениÑ"
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr "ЧиÑло Ñтрок в контекÑте diff"
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr "Шаблон Ð´Ð»Ñ Ð¸Ð¼ÐµÐ½Ð¸ новой ветви"
+
+#: lib/option.tcl:176
+msgid "Change Font"
+msgstr "Изменить шрифт"
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr "Выберите %s"
+
+# carbon copy
+#: lib/option.tcl:186
+msgid "pt."
+msgstr ""
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr "ÐаÑтройки"
+
+#: lib/option.tcl:235
+msgid "Failed to completely save options:"
+msgstr "Ðе удалоÑÑŒ полноÑтью Ñохранить наÑтройки:"
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Remote Branch"
+msgstr "Удалить внешнюю ветвь"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "Из репозиториÑ"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr "внешний:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr "по указанному URL:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
+msgstr "Ветви"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "Удалить только в Ñлучае, еÑли"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "Объединено Ñ:"
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "Ð’Ñегда (не выполнÑÑ‚ÑŒ проверку объединений)"
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr "Ð”Ð»Ñ Ð¾Ð¿Ñ†Ð¸Ð¸ 'Объединено Ñ' требуетÑÑ ÑƒÐºÐ°Ð·Ð°Ñ‚ÑŒ ветвь."
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+"Следующие ветви объединены Ñ %s не полноÑтью:\n"
+" - %s"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+"Один или неÑколько теÑтов на объединение не прошли, потому что Ð’Ñ‹ не "
+"получили необходимые ÑоÑтоÑниÑ. ПопытайтеÑÑŒ получить их из %s."
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr "Укажите одну или неÑколько ветвей Ð´Ð»Ñ ÑƒÐ´Ð°Ð»ÐµÐ½Ð¸Ñ."
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+"ВоÑÑтановить удаленные ветви Ñложно.\n"
+"\n"
+"Продолжить?"
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr "Удаление ветвей из %s"
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr "Ðе указан репозиторий."
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+msgid "Scanning %s..."
+msgstr "Перечитывание %s... "
+
+#: 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:136
+msgid "Cannot write icon:"
+msgstr "Ðевозможно запиÑать значок:"
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr "%s ... %*i из %*i %s (%3i%%)"
+
+#: lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
+msgstr "получение %s"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr "Получение изменений из %s "
+
+# carbon copy
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "чиÑтка внешнего %s"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr "ЧиÑтка ветвей ÑлежениÑ, удаленных из %s"
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr "отправить %s"
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Отправка изменений в %s "
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "Отправка %s %s в %s"
+
+#: lib/transport.tcl:89
+msgid "Push Branches"
+msgstr "Отправить Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð² ветвÑÑ…"
+
+#: lib/transport.tcl:103
+msgid "Source Branches"
+msgstr "ИÑходные ветви"
+
+#: lib/transport.tcl:120
+msgid "Destination Repository"
+msgstr "Репозиторий назначениÑ"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr "ÐаÑтройки отправки"
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr "Ðамеренно перепиÑать ÑущеÑтвующую ветвь (возможна Ð¿Ð¾Ñ‚ÐµÑ€Ñ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ð¹)"
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr "ИÑпользовать thin pack (Ð´Ð»Ñ Ð¼ÐµÐ´Ð»ÐµÐ½Ð½Ñ‹Ñ… Ñетевых подключений)"
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr "Передать таги"
+
+#~ msgid "Next >"
+#~ msgstr "Дальше >"
diff --git a/git-gui/po/zh_cn.po b/git-gui/po/zh_cn.po
new file mode 100644
index 000000000..621c9479b
--- /dev/null
+++ b/git-gui/po/zh_cn.po
@@ -0,0 +1,1769 @@
+# Translation of git-gui to Chinese
+# Copyright (C) 2007 Shawn Pearce
+# This file is distributed under the same license as the git-gui package.
+# Xudong Guan <xudong.guan@gmail.com>, 2007.
+#
+#, fuzzy
+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-07-21 01:23-0700\n"
+"Last-Translator: Xudong Guan <xudong.guan@gmail.com>\n"
+"Language-Team: Chinese\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
+msgid "git-gui: fatal error"
+msgstr ""
+
+#: git-gui.sh:595
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr ""
+
+#: git-gui.sh:620
+msgid "Main Font"
+msgstr ""
+
+#: git-gui.sh:621
+msgid "Diff/Console Font"
+msgstr ""
+
+#: git-gui.sh:635
+msgid "Cannot find git in PATH."
+msgstr ""
+
+#: git-gui.sh:662
+msgid "Cannot parse Git version string:"
+msgstr ""
+
+#: git-gui.sh:680
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+
+#: git-gui.sh:853
+msgid "Git directory not found:"
+msgstr ""
+
+#: git-gui.sh:860
+msgid "Cannot move to top of working directory:"
+msgstr ""
+
+#: git-gui.sh:867
+msgid "Cannot use funny .git directory:"
+msgstr ""
+
+#: git-gui.sh:872
+msgid "No working directory"
+msgstr ""
+
+#: git-gui.sh:1019
+msgid "Refreshing file status..."
+msgstr ""
+
+#: git-gui.sh:1084
+msgid "Scanning for modified files ..."
+msgstr ""
+
+#: git-gui.sh:1259 lib/browser.tcl:245
+#, fuzzy
+msgid "Ready."
+msgstr "é‡åš"
+
+#: git-gui.sh:1525
+msgid "Unmodified"
+msgstr ""
+
+#: git-gui.sh:1527
+msgid "Modified, not staged"
+msgstr ""
+
+#: git-gui.sh:1528 git-gui.sh:1533
+#, fuzzy
+msgid "Staged for commit"
+msgstr "从本次æ交移除"
+
+#: git-gui.sh:1529 git-gui.sh:1534
+#, fuzzy
+msgid "Portions staged for commit"
+msgstr "从本次æ交移除"
+
+#: git-gui.sh:1530 git-gui.sh:1535
+msgid "Staged for commit, missing"
+msgstr ""
+
+#: git-gui.sh:1532
+msgid "Untracked, not staged"
+msgstr ""
+
+#: git-gui.sh:1537
+msgid "Missing"
+msgstr ""
+
+#: git-gui.sh:1538
+msgid "Staged for removal"
+msgstr ""
+
+#: git-gui.sh:1539
+msgid "Staged for removal, still present"
+msgstr ""
+
+#: git-gui.sh:1541 git-gui.sh:1542 git-gui.sh:1543 git-gui.sh:1544
+msgid "Requires merge resolution"
+msgstr ""
+
+#: git-gui.sh:1579
+msgid "Starting gitk... please wait..."
+msgstr ""
+
+#: git-gui.sh:1588
+#, tcl-format
+msgid ""
+"Unable to start gitk:\n"
+"\n"
+"%s does not exist"
+msgstr ""
+
+#: git-gui.sh:1788 lib/choose_repository.tcl:32
+msgid "Repository"
+msgstr "版本树"
+
+#: git-gui.sh:1789
+msgid "Edit"
+msgstr "编辑"
+
+#: git-gui.sh:1791 lib/choose_rev.tcl:560
+msgid "Branch"
+msgstr "分支"
+
+#: git-gui.sh:1794 lib/choose_rev.tcl:547
+#, fuzzy
+msgid "Commit@@noun"
+msgstr "æ交"
+
+#: git-gui.sh:1797 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
+msgid "Merge"
+msgstr "åˆå¹¶"
+
+#: git-gui.sh:1798 lib/choose_rev.tcl:556
+#, fuzzy
+msgid "Remote"
+msgstr "改å..."
+
+#: git-gui.sh:1807
+msgid "Browse Current Branch's Files"
+msgstr "æµè§ˆå½“å‰åˆ†æ”¯æ–‡ä»¶"
+
+#: git-gui.sh:1811
+#, fuzzy
+msgid "Browse Branch Files..."
+msgstr "æµè§ˆå½“å‰åˆ†æ”¯æ–‡ä»¶"
+
+#: git-gui.sh:1816
+msgid "Visualize Current Branch's History"
+msgstr "调用gitk显示当å‰åˆ†æ”¯"
+
+#: git-gui.sh:1820
+msgid "Visualize All Branch History"
+msgstr "调用gitk显示所有分支"
+
+#: git-gui.sh:1827
+#, fuzzy, tcl-format
+msgid "Browse %s's Files"
+msgstr "æµè§ˆå½“å‰åˆ†æ”¯æ–‡ä»¶"
+
+#: git-gui.sh:1829
+#, fuzzy, tcl-format
+msgid "Visualize %s's History"
+msgstr "调用gitk显示所有分支"
+
+#: git-gui.sh:1834 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr "æ•°æ®åº“统计数æ®"
+
+#: git-gui.sh:1837 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "压缩数æ®åº“"
+
+#: git-gui.sh:1840
+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
+msgid "Create Desktop Icon"
+msgstr "创建桌é¢å›¾æ ‡"
+
+#: git-gui.sh:1860 lib/choose_repository.tcl:36 lib/choose_repository.tcl:95
+msgid "Quit"
+msgstr "退出"
+
+#: git-gui.sh:1867
+msgid "Undo"
+msgstr "撤销"
+
+#: git-gui.sh:1870
+msgid "Redo"
+msgstr "é‡åš"
+
+#: git-gui.sh:1874 git-gui.sh:2366
+msgid "Cut"
+msgstr "剪切"
+
+#: git-gui.sh:1877 git-gui.sh:2369 git-gui.sh:2440 git-gui.sh:2512
+#: lib/console.tcl:67
+msgid "Copy"
+msgstr "å¤åˆ¶"
+
+#: git-gui.sh:1880 git-gui.sh:2372
+msgid "Paste"
+msgstr "粘贴"
+
+#: git-gui.sh:1883 git-gui.sh:2375 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
+msgid "Select All"
+msgstr "全选"
+
+#: git-gui.sh:1896
+msgid "Create..."
+msgstr "新建..."
+
+#: git-gui.sh:1902
+msgid "Checkout..."
+msgstr "切æ¢..."
+
+#: git-gui.sh:1908
+msgid "Rename..."
+msgstr "改å..."
+
+#: git-gui.sh:1913 git-gui.sh:2012
+msgid "Delete..."
+msgstr "删除..."
+
+#: git-gui.sh:1918
+msgid "Reset..."
+msgstr "é‡ç½®æ‰€æœ‰ä¿®åŠ¨..."
+
+#: git-gui.sh:1930 git-gui.sh:2313
+msgid "New Commit"
+msgstr "æ–°æ交"
+
+#: git-gui.sh:1938 git-gui.sh:2320
+msgid "Amend Last Commit"
+msgstr "修订上次æ交"
+
+#: git-gui.sh:1947 git-gui.sh:2280 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "é‡æ–°æ‰«æ"
+
+#: git-gui.sh:1953
+#, fuzzy
+msgid "Stage To Commit"
+msgstr "从本次æ交移除"
+
+#: git-gui.sh:1958
+#, fuzzy
+msgid "Stage Changed Files To Commit"
+msgstr "将被æ交的修改"
+
+#: git-gui.sh:1964
+msgid "Unstage From Commit"
+msgstr "从本次æ交移除"
+
+#: git-gui.sh:1969 lib/index.tcl:352
+msgid "Revert Changes"
+msgstr "æ¢å¤ä¿®æ”¹"
+
+#: git-gui.sh:1976 git-gui.sh:2292 git-gui.sh:2390
+msgid "Sign Off"
+msgstr "ç­¾å"
+
+#: git-gui.sh:1980 git-gui.sh:2296
+#, fuzzy
+msgid "Commit@@verb"
+msgstr "æ交"
+
+#: git-gui.sh:1991
+msgid "Local Merge..."
+msgstr "本地åˆå¹¶..."
+
+#: git-gui.sh:1996
+msgid "Abort Merge..."
+msgstr "å–消åˆå¹¶..."
+
+#: git-gui.sh:2008
+msgid "Push..."
+msgstr "上传..."
+
+#: git-gui.sh:2019 lib/choose_repository.tcl:41
+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
+#, tcl-format
+msgid "About %s"
+msgstr "关于%s"
+
+#: git-gui.sh:2026
+msgid "Preferences..."
+msgstr ""
+
+#: git-gui.sh:2034 git-gui.sh:2558
+msgid "Options..."
+msgstr "选项..."
+
+#: git-gui.sh:2040 lib/choose_repository.tcl:47
+msgid "Help"
+msgstr "帮助"
+
+#: git-gui.sh:2081
+msgid "Online Documentation"
+msgstr "在线文档"
+
+#: git-gui.sh:2165
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr ""
+
+#: git-gui.sh:2198
+msgid "Current Branch:"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: git-gui.sh:2219
+#, fuzzy
+msgid "Staged Changes (Will Commit)"
+msgstr "将被æ交的修改"
+
+#: git-gui.sh:2239
+msgid "Unstaged Changes"
+msgstr ""
+
+#: git-gui.sh:2286
+msgid "Stage Changed"
+msgstr ""
+
+#: git-gui.sh:2302 lib/transport.tcl:93 lib/transport.tcl:182
+msgid "Push"
+msgstr "上传"
+
+#: git-gui.sh:2332
+msgid "Initial Commit Message:"
+msgstr "åˆå§‹æ交æè¿°:"
+
+#: git-gui.sh:2333
+msgid "Amended Commit Message:"
+msgstr "修订æ交æè¿°:"
+
+#: git-gui.sh:2334
+msgid "Amended Initial Commit Message:"
+msgstr "修订åˆå§‹æ交æè¿°:"
+
+#: git-gui.sh:2335
+msgid "Amended Merge Commit Message:"
+msgstr "修订åˆå¹¶æ交æè¿°:"
+
+#: git-gui.sh:2336
+msgid "Merge Commit Message:"
+msgstr "åˆå¹¶æ交æè¿°:"
+
+#: git-gui.sh:2337
+msgid "Commit Message:"
+msgstr "æ交æè¿°:"
+
+#: git-gui.sh:2382 git-gui.sh:2520 lib/console.tcl:71
+msgid "Copy All"
+msgstr "全部å¤åˆ¶"
+
+#: git-gui.sh:2406 lib/blame.tcl:104
+msgid "File:"
+msgstr ""
+
+#: git-gui.sh:2508
+msgid "Refresh"
+msgstr "刷新"
+
+#: git-gui.sh:2529
+msgid "Apply/Reverse Hunk"
+msgstr "应用/撤消此修改å—"
+
+#: git-gui.sh:2535
+msgid "Decrease Font Size"
+msgstr "缩å°å­—体"
+
+#: git-gui.sh:2539
+msgid "Increase Font Size"
+msgstr "放大字体"
+
+#: git-gui.sh:2544
+msgid "Show Less Context"
+msgstr "显示更多diff上下文"
+
+#: git-gui.sh:2551
+msgid "Show More Context"
+msgstr "显示更少diff上下文"
+
+#: git-gui.sh:2565
+#, fuzzy
+msgid "Unstage Hunk From Commit"
+msgstr "从本次æ交移除"
+
+#: git-gui.sh:2567
+#, fuzzy
+msgid "Stage Hunk For Commit"
+msgstr "从本次æ交移除"
+
+#: git-gui.sh:2586
+msgid "Initializing..."
+msgstr ""
+
+#: git-gui.sh:2677
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+
+#: git-gui.sh:2707
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+
+#: git-gui.sh:2712
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+
+#: lib/about.tcl:25
+msgid "git-gui - a graphical user interface for Git."
+msgstr ""
+
+#: lib/blame.tcl:77
+msgid "File Viewer"
+msgstr ""
+
+#: lib/blame.tcl:81
+#, fuzzy
+msgid "Commit:"
+msgstr "æ交"
+
+#: lib/blame.tcl:249
+#, fuzzy
+msgid "Copy Commit"
+msgstr "æ交"
+
+#: lib/blame.tcl:369
+#, tcl-format
+msgid "Reading %s..."
+msgstr ""
+
+#: lib/blame.tcl:473
+msgid "Loading copy/move tracking annotations..."
+msgstr ""
+
+#: lib/blame.tcl:493
+msgid "lines annotated"
+msgstr ""
+
+#: lib/blame.tcl:674
+msgid "Loading original location annotations..."
+msgstr ""
+
+#: lib/blame.tcl:677
+msgid "Annotation complete."
+msgstr ""
+
+#: lib/blame.tcl:731
+msgid "Loading annotation..."
+msgstr ""
+
+#: lib/blame.tcl:787
+msgid "Author:"
+msgstr ""
+
+#: lib/blame.tcl:791
+#, fuzzy
+msgid "Committer:"
+msgstr "æ交"
+
+#: lib/blame.tcl:796
+msgid "Original File:"
+msgstr ""
+
+#: lib/blame.tcl:910
+msgid "Originally By:"
+msgstr ""
+
+#: lib/blame.tcl:916
+msgid "In File:"
+msgstr ""
+
+#: lib/blame.tcl:921
+msgid "Copied Or Moved Here By:"
+msgstr ""
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+#, fuzzy
+msgid "Checkout Branch"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/branch_checkout.tcl:23
+#, fuzzy
+msgid "Checkout"
+msgstr "切æ¢..."
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:281
+#: lib/checkout_op.tcl:522 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:90 lib/remote_branch_delete.tcl:42 lib/transport.tcl:97
+msgid "Cancel"
+msgstr ""
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:286
+msgid "Revision"
+msgstr ""
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:202
+#, fuzzy
+msgid "Options"
+msgstr "选项..."
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr ""
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
+msgstr ""
+
+#: lib/branch_create.tcl:22
+#, fuzzy
+msgid "Create Branch"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/branch_create.tcl:27
+#, fuzzy
+msgid "Create New Branch"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:199
+#, fuzzy
+msgid "Create"
+msgstr "新建..."
+
+#: lib/branch_create.tcl:40
+#, fuzzy
+msgid "Branch Name"
+msgstr "分支"
+
+#: lib/branch_create.tcl:43
+msgid "Name:"
+msgstr ""
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
+msgstr ""
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr ""
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
+msgstr ""
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr ""
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr ""
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:514
+#, fuzzy
+msgid "Reset"
+msgstr "é‡ç½®æ‰€æœ‰ä¿®åŠ¨..."
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr ""
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
+msgstr ""
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
+msgstr ""
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
+msgstr ""
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
+msgstr ""
+
+#: lib/branch_delete.tcl:15
+#, fuzzy
+msgid "Delete Branch"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
+msgstr ""
+
+#: lib/branch_delete.tcl:37
+#, fuzzy
+msgid "Local Branches"
+msgstr "分支"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr ""
+
+#: lib/branch_delete.tcl:54
+msgid "Always (Do not perform merge test.)"
+msgstr ""
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
+msgstr ""
+
+#: lib/branch_delete.tcl:115
+msgid ""
+"Recovering deleted branches is difficult. \n"
+"\n"
+" Delete the selected branches?"
+msgstr ""
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
+msgstr ""
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+#, fuzzy
+msgid "Rename Branch"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/branch_rename.tcl:26
+#, fuzzy
+msgid "Rename"
+msgstr "改å..."
+
+#: lib/branch_rename.tcl:36
+#, fuzzy
+msgid "Branch:"
+msgstr "分支"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr ""
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
+msgstr ""
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:179
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr ""
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr ""
+
+#: lib/browser.tcl:17
+msgid "Starting..."
+msgstr ""
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr ""
+
+#: lib/browser.tcl:125 lib/browser.tcl:142
+#, tcl-format
+msgid "Loading %s..."
+msgstr ""
+
+#: lib/browser.tcl:186
+msgid "[Up To Parent]"
+msgstr ""
+
+#: lib/browser.tcl:266 lib/browser.tcl:272
+#, fuzzy
+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
+msgid "Browse"
+msgstr ""
+
+#: lib/checkout_op.tcl:79
+#, tcl-format
+msgid "Fetching %s from %s"
+msgstr ""
+
+#: lib/checkout_op.tcl:127
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr ""
+
+#: lib/checkout_op.tcl:140 lib/console.tcl:79 lib/database.tcl:31
+msgid "Close"
+msgstr ""
+
+#: lib/checkout_op.tcl:169
+#, tcl-format
+msgid "Branch '%s' does not exist."
+msgstr ""
+
+#: lib/checkout_op.tcl:206
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
+msgstr ""
+
+#: lib/checkout_op.tcl:220
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
+msgstr ""
+
+#: lib/checkout_op.tcl:239
+#, tcl-format
+msgid "Failed to update '%s'."
+msgstr ""
+
+#: lib/checkout_op.tcl:251
+msgid "Staging area (index) is already locked."
+msgstr ""
+
+#: lib/checkout_op.tcl:266
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/checkout_op.tcl:322
+#, tcl-format
+msgid "Updating working directory to '%s'..."
+msgstr ""
+
+#: lib/checkout_op.tcl:353
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr ""
+
+#: lib/checkout_op.tcl:354
+msgid "File level merge required."
+msgstr ""
+
+#: lib/checkout_op.tcl:358
+#, tcl-format
+msgid "Staying on branch '%s'."
+msgstr ""
+
+#: lib/checkout_op.tcl:429
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
+"If you wanted to be on a branch, create one now starting from 'This Detached "
+"Checkout'."
+msgstr ""
+
+#: lib/checkout_op.tcl:446
+#, fuzzy, tcl-format
+msgid "Checked out '%s'."
+msgstr "切æ¢..."
+
+#: lib/checkout_op.tcl:478
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
+msgstr ""
+
+#: lib/checkout_op.tcl:500
+msgid "Recovering lost commits may not be easy."
+msgstr ""
+
+#: lib/checkout_op.tcl:505
+#, tcl-format
+msgid "Reset '%s'?"
+msgstr ""
+
+#: lib/checkout_op.tcl:510 lib/merge.tcl:164
+msgid "Visualize"
+msgstr ""
+
+#: lib/checkout_op.tcl:578
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
+"This working directory is only partially switched. We successfully updated "
+"your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
+msgstr ""
+
+#: lib/choose_font.tcl:39
+#, fuzzy
+msgid "Select"
+msgstr "全选"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr ""
+
+#: lib/choose_font.tcl:73
+#, fuzzy
+msgid "Font Size"
+msgstr "缩å°å­—体"
+
+#: lib/choose_font.tcl:90
+msgid "Font Example"
+msgstr ""
+
+#: lib/choose_font.tcl:101
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
+msgstr ""
+
+#: lib/choose_repository.tcl:25
+msgid "Git Gui"
+msgstr ""
+
+#: lib/choose_repository.tcl:69 lib/choose_repository.tcl:204
+#, fuzzy
+msgid "Create New Repository"
+msgstr "版本树"
+
+#: lib/choose_repository.tcl:74 lib/choose_repository.tcl:291
+#, fuzzy
+msgid "Clone Existing Repository"
+msgstr "版本树"
+
+#: lib/choose_repository.tcl:79 lib/choose_repository.tcl:800
+#, fuzzy
+msgid "Open Existing Repository"
+msgstr "版本树"
+
+#: lib/choose_repository.tcl:91
+msgid "Next >"
+msgstr ""
+
+#: lib/choose_repository.tcl:152
+#, tcl-format
+msgid "Location %s already exists."
+msgstr ""
+
+#: lib/choose_repository.tcl:158 lib/choose_repository.tcl:165
+#: lib/choose_repository.tcl:172
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr ""
+
+#: lib/choose_repository.tcl:209 lib/choose_repository.tcl:309
+msgid "Directory:"
+msgstr ""
+
+#: lib/choose_repository.tcl:238 lib/choose_repository.tcl:363
+#: lib/choose_repository.tcl:834
+#, fuzzy
+msgid "Git Repository"
+msgstr "版本树"
+
+#: lib/choose_repository.tcl:253 lib/choose_repository.tcl:260
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr ""
+
+#: lib/choose_repository.tcl:265
+#, tcl-format
+msgid "File %s already exists."
+msgstr ""
+
+#: lib/choose_repository.tcl:286
+msgid "Clone"
+msgstr ""
+
+#: lib/choose_repository.tcl:299
+msgid "URL:"
+msgstr ""
+
+#: lib/choose_repository.tcl:319
+msgid "Clone Type:"
+msgstr ""
+
+#: lib/choose_repository.tcl:325
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
+msgstr ""
+
+#: lib/choose_repository.tcl:331
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr ""
+
+#: lib/choose_repository.tcl:337
+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
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:405
+msgid "Standard only available for local repository."
+msgstr ""
+
+#: lib/choose_repository.tcl:409
+msgid "Shared only available for local repository."
+msgstr ""
+
+#: lib/choose_repository.tcl:439
+msgid "Failed to configure origin"
+msgstr ""
+
+#: lib/choose_repository.tcl:451
+msgid "Counting objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:452
+msgid "buckets"
+msgstr ""
+
+#: lib/choose_repository.tcl:476
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:512
+#, tcl-format
+msgid "Nothing to clone from %s."
+msgstr ""
+
+#: lib/choose_repository.tcl:514 lib/choose_repository.tcl:728
+#: lib/choose_repository.tcl:740
+msgid "The 'master' branch has not been initialized."
+msgstr ""
+
+#: lib/choose_repository.tcl:527
+msgid "Hardlinks are unavailable. Falling back to copying."
+msgstr ""
+
+#: lib/choose_repository.tcl:539
+#, tcl-format
+msgid "Cloning from %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:570
+#, fuzzy
+msgid "Copying objects"
+msgstr "压缩数æ®åº“"
+
+#: lib/choose_repository.tcl:571
+msgid "KiB"
+msgstr ""
+
+#: lib/choose_repository.tcl:595
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:605
+msgid "Linking objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:606
+msgid "objects"
+msgstr ""
+
+#: lib/choose_repository.tcl:614
+#, tcl-format
+msgid "Unable to hardlink object: %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:669
+msgid "Cannot fetch branches and objects. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:680
+msgid "Cannot fetch tags. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:704
+msgid "Cannot determine HEAD. See console output for details."
+msgstr ""
+
+#: lib/choose_repository.tcl:713
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr ""
+
+#: lib/choose_repository.tcl:719
+msgid "Clone failed."
+msgstr ""
+
+#: lib/choose_repository.tcl:726
+msgid "No default branch obtained."
+msgstr ""
+
+#: lib/choose_repository.tcl:737
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
+msgstr ""
+
+#: lib/choose_repository.tcl:749
+msgid "Creating working directory"
+msgstr ""
+
+#: lib/choose_repository.tcl:750 lib/index.tcl:15 lib/index.tcl:80
+#: lib/index.tcl:149
+msgid "files"
+msgstr ""
+
+#: lib/choose_repository.tcl:779
+msgid "Initial file checkout failed."
+msgstr ""
+
+#: lib/choose_repository.tcl:795
+msgid "Open"
+msgstr ""
+
+#: lib/choose_repository.tcl:805
+#, fuzzy
+msgid "Repository:"
+msgstr "版本树"
+
+#: lib/choose_repository.tcl:854
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr ""
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr ""
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr ""
+
+#: lib/choose_rev.tcl:74
+#, fuzzy
+msgid "Local Branch"
+msgstr "分支"
+
+#: lib/choose_rev.tcl:79
+#, fuzzy
+msgid "Tracking Branch"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:537
+msgid "Tag"
+msgstr ""
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr ""
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr ""
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr ""
+
+#: lib/choose_rev.tcl:530
+msgid "Updated"
+msgstr ""
+
+#: lib/choose_rev.tcl:558
+msgid "URL"
+msgstr ""
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
+"You are about to create the initial commit. There is no commit before this "
+"to amend.\n"
+msgstr ""
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
+"You are currently in the middle of a merge that has not been fully "
+"completed. You cannot amend the prior commit unless you first abort the "
+"current merge activity.\n"
+msgstr ""
+
+#: lib/commit.tcl:49
+msgid "Error loading commit data for amend:"
+msgstr ""
+
+#: lib/commit.tcl:76
+msgid "Unable to obtain your identity:"
+msgstr ""
+
+#: lib/commit.tcl:81
+msgid "Invalid GIT_COMMITTER_IDENT:"
+msgstr ""
+
+#: lib/commit.tcl:133
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/commit.tcl:154
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
+"File %s has merge conflicts. You must resolve them and stage the file "
+"before committing.\n"
+msgstr ""
+
+#: lib/commit.tcl:162
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
+msgstr ""
+
+#: lib/commit.tcl:170
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
+msgstr ""
+
+#: lib/commit.tcl:183
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentance what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
+
+#: lib/commit.tcl:257
+msgid "write-tree failed:"
+msgstr ""
+
+#: lib/commit.tcl:275
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
+msgstr ""
+
+#: lib/commit.tcl:279
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/commit.tcl:286
+msgid "No changes to commit."
+msgstr ""
+
+#: lib/commit.tcl:303
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
+msgstr ""
+
+#: lib/commit.tcl:317
+msgid "commit-tree failed:"
+msgstr ""
+
+#: lib/commit.tcl:339
+msgid "update-ref failed:"
+msgstr ""
+
+#: lib/commit.tcl:430
+#, tcl-format
+msgid "Created commit %s: %s"
+msgstr ""
+
+#: lib/console.tcl:57
+msgid "Working... please wait..."
+msgstr ""
+
+#: lib/console.tcl:183
+msgid "Success"
+msgstr ""
+
+#: lib/console.tcl:196
+msgid "Error: Command Failed"
+msgstr ""
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr ""
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr ""
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr ""
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr ""
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr ""
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr ""
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr ""
+
+#: lib/database.tcl:72
+#, fuzzy
+msgid "Compressing the object database"
+msgstr "压缩数æ®åº“"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr ""
+
+#: lib/database.tcl:108
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
+"To maintain optimal performance it is strongly recommended that you compress "
+"the database when more than %i loose objects exist.\n"
+"\n"
+"Compress the database now?"
+msgstr ""
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr ""
+
+#: lib/diff.tcl:42
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+
+#: lib/diff.tcl:81
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr ""
+
+#: lib/diff.tcl:114 lib/diff.tcl:184
+#, tcl-format
+msgid "Unable to display %s"
+msgstr ""
+
+#: lib/diff.tcl:115
+msgid "Error loading file:"
+msgstr ""
+
+#: lib/diff.tcl:122
+msgid "Git Repository (subproject)"
+msgstr ""
+
+#: lib/diff.tcl:134
+msgid "* Binary file (not showing content)."
+msgstr ""
+
+#: lib/diff.tcl:185
+msgid "Error loading diff:"
+msgstr ""
+
+#: lib/diff.tcl:302
+msgid "Failed to unstage selected hunk."
+msgstr ""
+
+#: lib/diff.tcl:309
+msgid "Failed to stage selected hunk."
+msgstr ""
+
+#: lib/error.tcl:12 lib/error.tcl:102
+msgid "error"
+msgstr ""
+
+#: lib/error.tcl:28
+msgid "warning"
+msgstr ""
+
+#: lib/error.tcl:81
+msgid "You must correct the above errors before committing."
+msgstr ""
+
+#: lib/index.tcl:241
+#, fuzzy, tcl-format
+msgid "Unstaging %s from commit"
+msgstr "从本次æ交移除"
+
+#: lib/index.tcl:285
+#, tcl-format
+msgid "Adding %s"
+msgstr ""
+
+#: lib/index.tcl:340
+#, fuzzy, tcl-format
+msgid "Revert changes in file %s?"
+msgstr "æ¢å¤ä¿®æ”¹"
+
+#: lib/index.tcl:342
+#, tcl-format
+msgid "Revert changes in these %i files?"
+msgstr ""
+
+#: lib/index.tcl:348
+msgid "Any unstaged changes will be permanently lost by the revert."
+msgstr ""
+
+#: lib/index.tcl:351
+msgid "Do Nothing"
+msgstr ""
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
+msgstr ""
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
+"Another Git program has modified this repository since the last scan. A "
+"rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
+msgstr ""
+
+#: lib/merge.tcl:44
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
+"You must resolve them, stage the file, and commit to complete the current "
+"merge. Only then can you begin another merge.\n"
+msgstr ""
+
+#: lib/merge.tcl:54
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
+"You should complete the current commit before starting a merge. Doing so "
+"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
+
+#: lib/merge.tcl:106
+#, tcl-format
+msgid "%s of %s"
+msgstr ""
+
+#: lib/merge.tcl:119
+#, tcl-format
+msgid "Merging %s and %s"
+msgstr ""
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr ""
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr ""
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr ""
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr ""
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
+msgstr ""
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
+msgstr ""
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
+msgstr ""
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr ""
+
+#: lib/merge.tcl:266
+msgid "Abort failed."
+msgstr ""
+
+#: lib/merge.tcl:268
+msgid "Abort completed. Ready."
+msgstr ""
+
+#: lib/option.tcl:82
+msgid "Restore Defaults"
+msgstr ""
+
+#: lib/option.tcl:86
+msgid "Save"
+msgstr ""
+
+#: lib/option.tcl:96
+#, fuzzy, tcl-format
+msgid "%s Repository"
+msgstr "版本树"
+
+#: lib/option.tcl:97
+msgid "Global (All Repositories)"
+msgstr ""
+
+#: lib/option.tcl:103
+msgid "User Name"
+msgstr ""
+
+#: lib/option.tcl:104
+msgid "Email Address"
+msgstr ""
+
+#: lib/option.tcl:106
+#, fuzzy
+msgid "Summarize Merge Commits"
+msgstr "修订åˆå¹¶æ交æè¿°:"
+
+#: lib/option.tcl:107
+msgid "Merge Verbosity"
+msgstr ""
+
+#: lib/option.tcl:108
+msgid "Show Diffstat After Merge"
+msgstr ""
+
+#: lib/option.tcl:110
+msgid "Trust File Modification Timestamps"
+msgstr ""
+
+#: lib/option.tcl:111
+msgid "Prune Tracking Branches During Fetch"
+msgstr ""
+
+#: lib/option.tcl:112
+msgid "Match Tracking Branches"
+msgstr ""
+
+#: lib/option.tcl:113
+msgid "Number of Diff Context Lines"
+msgstr ""
+
+#: lib/option.tcl:114
+msgid "New Branch Name Template"
+msgstr ""
+
+#: lib/option.tcl:176
+msgid "Change Font"
+msgstr ""
+
+#: lib/option.tcl:180
+#, tcl-format
+msgid "Choose %s"
+msgstr ""
+
+#: lib/option.tcl:186
+msgid "pt."
+msgstr ""
+
+#: lib/option.tcl:200
+msgid "Preferences"
+msgstr ""
+
+#: lib/option.tcl:235
+msgid "Failed to completely save options:"
+msgstr ""
+
+#: lib/remote.tcl:165
+msgid "Prune from"
+msgstr ""
+
+#: lib/remote.tcl:170
+#, fuzzy
+msgid "Fetch from"
+msgstr "导入"
+
+#: lib/remote.tcl:213
+#, fuzzy
+msgid "Push to"
+msgstr "上传"
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Remote Branch"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:47
+#, fuzzy
+msgid "From Repository"
+msgstr "版本树"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:123
+msgid "Remote:"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:138
+msgid "Arbitrary URL:"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:84
+#, fuzzy
+msgid "Branches"
+msgstr "分支"
+
+#: lib/remote_branch_delete.tcl:109
+#, fuzzy
+msgid "Delete Only If"
+msgstr "删除"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:216
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:286
+msgid "No repository selected."
+msgstr ""
+
+#: lib/remote_branch_delete.tcl:291
+#, tcl-format
+msgid "Scanning %s..."
+msgstr ""
+
+#: lib/shortcut.tcl:26 lib/shortcut.tcl:74
+msgid "Cannot write script:"
+msgstr ""
+
+#: lib/shortcut.tcl:149
+msgid "Cannot write icon:"
+msgstr ""
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
+msgstr ""
+
+#: lib/transport.tcl:6
+#, fuzzy, tcl-format
+msgid "fetch %s"
+msgstr "导入"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
+msgstr ""
+
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr ""
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
+msgstr ""
+
+#: lib/transport.tcl:25 lib/transport.tcl:71
+#, tcl-format
+msgid "push %s"
+msgstr ""
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr ""
+
+#: lib/transport.tcl:72
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr ""
+
+#: lib/transport.tcl:89
+#, fuzzy
+msgid "Push Branches"
+msgstr "分支"
+
+#: lib/transport.tcl:103
+#, fuzzy
+msgid "Source Branches"
+msgstr "当å‰åˆ†æ”¯:"
+
+#: lib/transport.tcl:120
+#, fuzzy
+msgid "Destination Repository"
+msgstr "版本树"
+
+#: lib/transport.tcl:158
+msgid "Transfer Options"
+msgstr ""
+
+#: lib/transport.tcl:160
+msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
+
+#: lib/transport.tcl:164
+msgid "Use thin pack (for slow network connections)"
+msgstr ""
+
+#: lib/transport.tcl:168
+msgid "Include tags"
+msgstr ""
+
+#~ msgid "Add To Commit"
+#~ msgstr "添加到本次æ交"
+
+#~ msgid "Add Existing To Commit"
+#~ msgstr "添加默认修改文件"
+
+#~ msgid "Unstaged Changes (Will Not Be Committed)"
+#~ msgstr "ä¸è¢«æ交的修改"
+
+#~ msgid "Add Existing"
+#~ msgstr "添加默认修改文件"
+
+#, fuzzy
+#~ msgid "Push to %s..."
+#~ msgstr "上传..."
diff --git a/git-gui/windows/git-gui.sh b/git-gui/windows/git-gui.sh
new file mode 100644
index 000000000..98f32c0a0
--- /dev/null
+++ b/git-gui/windows/git-gui.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+# Tcl ignores the next line -*- tcl -*- \
+exec wish "$0" -- "$@"
+
+if { $argc >=2 && [lindex $argv 0] == "--working-dir" } {
+ cd [lindex $argv 1]
+ set argv [lrange $argv 2 end]
+ incr argc -2
+}
+
+set gitguidir [file dirname [info script]]
+regsub -all ";" $gitguidir "\\;" gitguidir
+set env(PATH) "$gitguidir;$env(PATH)"
+unset gitguidir
+
+source [file join [file dirname [info script]] git-gui.tcl]
diff --git a/git-instaweb.sh b/git-instaweb.sh
index ada118052..8503ae403 100755
--- a/git-instaweb.sh
+++ b/git-instaweb.sh
@@ -2,9 +2,21 @@
#
# Copyright (c) 2006 Eric Wong
#
-USAGE='[--start] [--stop] [--restart]
- [--local] [--httpd=<httpd>] [--port=<port>] [--browser=<browser>]
- [--module-path=<path> (for Apache2 only)]'
+
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-instaweb [options] (--start | --stop | --restart)
+--
+l,local only bind on 127.0.0.1
+p,port= the port to bind to
+d,httpd= the command to launch
+b,browser= the browser to launch
+m,module-path= the module path (only needed for apache2)
+ Action
+stop stop the web server
+start start the web server
+restart restart the web server
+"
. git-sh-setup
@@ -78,52 +90,26 @@ do
start_httpd
exit 0
;;
- --local|-l)
+ -l|--local)
local=true
;;
- -d|--httpd|--httpd=*)
- case "$#,$1" in
- *,*=*)
- httpd=`expr "$1" : '-[^=]*=\(.*\)'` ;;
- 1,*)
- usage ;;
- *)
- httpd="$2"
- shift ;;
- esac
+ -d|--httpd)
+ shift
+ httpd="$1"
+ ;;
+ -b|--browser)
+ shift
+ browser="$1"
;;
- -b|--browser|--browser=*)
- case "$#,$1" in
- *,*=*)
- browser=`expr "$1" : '-[^=]*=\(.*\)'` ;;
- 1,*)
- usage ;;
- *)
- browser="$2"
- shift ;;
- esac
+ -p|--port)
+ shift
+ port="$1"
;;
- -p|--port|--port=*)
- case "$#,$1" in
- *,*=*)
- port=`expr "$1" : '-[^=]*=\(.*\)'` ;;
- 1,*)
- usage ;;
- *)
- port="$2"
- shift ;;
- esac
+ -m|--module-path)
+ shift
+ module_path="$1"
;;
- -m|--module-path=*|--module-path)
- case "$#,$1" in
- *,*=*)
- module_path=`expr "$1" : '-[^=]*=\(.*\)'` ;;
- 1,*)
- usage ;;
- *)
- module_path="$2"
- shift ;;
- esac
+ --)
;;
*)
usage
diff --git a/git-lost-found.sh b/git-lost-found.sh
index f2ec5d147..9cedaf80c 100755
--- a/git-lost-found.sh
+++ b/git-lost-found.sh
@@ -2,6 +2,7 @@
USAGE=''
SUBDIRECTORY_OK='Yes'
+OPTIONS_SPEC=
. git-sh-setup
echo "WARNING: '$0' is deprecated in favor of 'git fsck --lost-found'" >&2
diff --git a/git-merge.sh b/git-merge.sh
index c2092a204..1c123a37e 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -3,7 +3,19 @@
# Copyright (c) 2005 Junio C Hamano
#
-USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s <strategy>] [-m=<merge-message>] <commit>+'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-merge [options] <remote>...
+git-merge [options] <msg> HEAD <remote>
+--
+summary show a diffstat at the end of the merge
+n,no-summary don't show a diffstat at the end of the merge
+squash create a single commit instead of doing a merge
+commit perform a commit if the merge sucesses (default)
+ff allow fast forward (default)
+s,strategy= merge strategy to use
+m,message= message to be used for the merge commit (if any)
+"
SUBDIRECTORY_OK=Yes
. git-sh-setup
@@ -28,20 +40,19 @@ allow_trivial_merge=t
dropsave() {
rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
- "$GIT_DIR/MERGE_SAVE" || exit 1
+ "$GIT_DIR/MERGE_STASH" || exit 1
}
savestate() {
# Stash away any local modifications.
- git diff-index -z --name-only $head |
- cpio -0 -o >"$GIT_DIR/MERGE_SAVE"
+ git stash create >"$GIT_DIR/MERGE_STASH"
}
restorestate() {
- if test -f "$GIT_DIR/MERGE_SAVE"
+ if test -f "$GIT_DIR/MERGE_STASH"
then
git reset --hard $head >/dev/null
- cpio -iuv <"$GIT_DIR/MERGE_SAVE"
+ git stash apply $(cat "$GIT_DIR/MERGE_STASH")
git update-index --refresh >/dev/null
fi
}
@@ -133,72 +144,47 @@ merge_name () {
fi
}
-parse_option () {
- case "$1" in
- -n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
- --no-summa|--no-summar|--no-summary)
- show_diffstat=false ;;
- --summary)
- show_diffstat=t ;;
- --sq|--squ|--squa|--squas|--squash)
- allow_fast_forward=t squash=t no_commit=t ;;
- --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
- allow_fast_forward=t squash= no_commit= ;;
- --c|--co|--com|--comm|--commi|--commit)
- allow_fast_forward=t squash= no_commit= ;;
- --no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
- allow_fast_forward=t squash= no_commit=t ;;
- --ff)
- allow_fast_forward=t squash= no_commit= ;;
- --no-ff)
- allow_fast_forward=false squash= no_commit= ;;
- -s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
- --strateg=*|--strategy=*|\
- -s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
- case "$#,$1" in
- *,*=*)
- strategy=`expr "z$1" : 'z-[^=]*=\(.*\)'` ;;
- 1,*)
- usage ;;
- *)
- strategy="$2"
- shift ;;
- esac
- case " $all_strategies " in
- *" $strategy "*)
- use_strategies="$use_strategies$strategy " ;;
- *)
- die "available strategies are: $all_strategies" ;;
- esac
- ;;
- -m=*|--m=*|--me=*|--mes=*|--mess=*|--messa=*|--messag=*|--message=*)
- merge_msg=`expr "z$1" : 'z-[^=]*=\(.*\)'`
- have_message=t
- ;;
- -m|--m|--me|--mes|--mess|--messa|--messag|--message)
- shift
- case "$#" in
- 1) usage ;;
- esac
- merge_msg="$1"
- have_message=t
- ;;
- -*) usage ;;
- *) return 1 ;;
- esac
- shift
- args_left=$#
-}
-
parse_config () {
- while test $# -gt 0
- do
- parse_option "$@" || usage
- while test $args_left -lt $#
- do
+ while test $# != 0; do
+ case "$1" in
+ -n|--no-summary)
+ show_diffstat=false ;;
+ --summary)
+ show_diffstat=t ;;
+ --squash)
+ allow_fast_forward=t squash=t no_commit=t ;;
+ --no-squash)
+ allow_fast_forward=t squash= no_commit= ;;
+ --commit)
+ allow_fast_forward=t squash= no_commit= ;;
+ --no-commit)
+ allow_fast_forward=t squash= no_commit=t ;;
+ --ff)
+ allow_fast_forward=t squash= no_commit= ;;
+ --no-ff)
+ allow_fast_forward=false squash= no_commit= ;;
+ -s|--strategy)
+ shift
+ case " $all_strategies " in
+ *" $1 "*)
+ use_strategies="$use_strategies$1 " ;;
+ *)
+ die "available strategies are: $all_strategies" ;;
+ esac
+ ;;
+ -m|--message)
shift
- done
+ merge_msg="$1"
+ have_message=t
+ ;;
+ --)
+ shift
+ break ;;
+ *) usage ;;
+ esac
+ shift
done
+ args_left=$#
}
test $# != 0 || usage
@@ -210,17 +196,12 @@ then
mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions")
if test -n "$mergeopts"
then
- parse_config $mergeopts
+ parse_config $mergeopts --
fi
fi
-while parse_option "$@"
-do
- while test $args_left -lt $#
- do
- shift
- done
-done
+parse_config "$@"
+while test $args_left -lt $#; do shift; done
if test -z "$show_diffstat"; then
test "$(git config --bool merge.diffstat)" = false && show_diffstat=false
@@ -437,7 +418,7 @@ case "$use_strategies" in
single_strategy=no
;;
*)
- rm -f "$GIT_DIR/MERGE_SAVE"
+ rm -f "$GIT_DIR/MERGE_STASH"
single_strategy=yes
;;
esac
diff --git a/git-mergetool.sh b/git-mergetool.sh
index a68b40386..5587c5ece 100755
--- a/git-mergetool.sh
+++ b/git-mergetool.sh
@@ -10,6 +10,7 @@
USAGE='[--tool=tool] [file to merge] ...'
SUBDIRECTORY_OK=Yes
+OPTIONS_SPEC=
. git-sh-setup
require_work_tree
prefix=$(git rev-parse --show-prefix)
diff --git a/git-pull.sh b/git-pull.sh
index 75ec01196..30fdc5731 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -7,6 +7,7 @@
USAGE='[-n | --no-summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s strategy]... [<fetch-options>] <repo> <head>...'
LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
SUBDIRECTORY_OK=Yes
+OPTIONS_SPEC=
. git-sh-setup
set_reflog_action "pull $*"
require_work_tree
diff --git a/git-quiltimport.sh b/git-quiltimport.sh
index 880c81d12..6b0c4d2f2 100755
--- a/git-quiltimport.sh
+++ b/git-quiltimport.sh
@@ -1,5 +1,12 @@
#!/bin/sh
-USAGE='--dry-run --author <author> --patches </path/to/quilt/patch/directory>'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-quiltimport [options]
+--
+n,dry-run dry run
+author= author name and email address for patches without any
+patches= path to the quilt series and patches
+"
SUBDIRECTORY_ON=Yes
. git-sh-setup
@@ -8,39 +15,25 @@ quilt_author=""
while test $# != 0
do
case "$1" in
- --au=*|--aut=*|--auth=*|--autho=*|--author=*)
- quilt_author=$(expr "z$1" : 'z-[^=]*\(.*\)')
- shift
- ;;
-
- --au|--aut|--auth|--autho|--author)
- case "$#" in 1) usage ;; esac
+ --author)
shift
quilt_author="$1"
- shift
;;
-
- --dry-run)
- shift
+ -n|--dry-run)
dry_run=1
;;
-
- --pa=*|--pat=*|--patc=*|--patch=*|--patche=*|--patches=*)
- QUILT_PATCHES=$(expr "z$1" : 'z-[^=]*\(.*\)')
- shift
- ;;
-
- --pa|--pat|--patc|--patch|--patche|--patches)
- case "$#" in 1) usage ;; esac
+ --patches)
shift
QUILT_PATCHES="$1"
- shift
;;
-
+ --)
+ shift
+ break;;
*)
- break
+ usage
;;
esac
+ shift
done
# Quilt Author
diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index 51063776d..bf44b6af5 100755
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -13,6 +13,7 @@
USAGE='(--continue | --abort | --skip | [--preserve-merges] [--verbose]
[--onto <branch>] <upstream> [<branch>])'
+OPTIONS_SPEC=
. git-sh-setup
require_work_tree
@@ -484,8 +485,13 @@ do
SHORTUPSTREAM=$(git rev-parse --short $UPSTREAM)
SHORTHEAD=$(git rev-parse --short $HEAD)
SHORTONTO=$(git rev-parse --short $ONTO)
- cat > "$TODO" << EOF
-# Rebasing $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
+ git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
+ --abbrev=7 --reverse --left-right --cherry-pick \
+ $UPSTREAM...$HEAD | \
+ sed -n "s/^>/pick /p" > "$TODO"
+ cat >> "$TODO" << EOF
+
+# Rebase $SHORTUPSTREAM..$SHORTHEAD onto $SHORTONTO
#
# Commands:
# pick = use commit
@@ -493,12 +499,9 @@ do
# squash = use commit, but meld into previous commit
#
# If you remove a line here THAT COMMIT WILL BE LOST.
+# However, if you remove everything, the rebase will be aborted.
#
EOF
- git rev-list $MERGES_OPTION --pretty=oneline --abbrev-commit \
- --abbrev=7 --reverse --left-right --cherry-pick \
- $UPSTREAM...$HEAD | \
- sed -n "s/^>/pick /p" >> "$TODO"
has_action "$TODO" ||
die_abort "Nothing to do"
diff --git a/git-rebase.sh b/git-rebase.sh
index 224cca98e..461ca8d93 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -29,6 +29,7 @@ Example: git-rebase master~1 topic
'
SUBDIRECTORY_OK=Yes
+OPTIONS_SPEC=
. git-sh-setup
set_reflog_action rebase
require_work_tree
@@ -87,7 +88,7 @@ call_merge () {
cmt="$(cat "$dotest/cmt.$1")"
echo "$cmt" > "$dotest/current"
hd=$(git rev-parse --verify HEAD)
- cmt_name=$(git symbolic-ref HEAD)
+ cmt_name=$(git symbolic-ref HEAD 2> /dev/null || echo HEAD)
msgnum=$(cat "$dotest/msgnum")
end=$(cat "$dotest/end")
eval GITHEAD_$cmt='"${cmt_name##refs/heads/}~$(($end - $msgnum))"'
@@ -115,7 +116,24 @@ call_merge () {
esac
}
+move_to_original_branch () {
+ test -z "$head_name" &&
+ head_name="$(cat "$dotest"/head-name)" &&
+ onto="$(cat "$dotest"/onto)" &&
+ orig_head="$(cat "$dotest"/orig-head)"
+ case "$head_name" in
+ refs/*)
+ message="rebase finished: $head_name onto $onto"
+ git update-ref -m "$message" \
+ $head_name $(git rev-parse HEAD) $orig_head &&
+ git symbolic-ref HEAD $head_name ||
+ die "Could not move back to $head_name"
+ ;;
+ esac
+}
+
finish_rb_merge () {
+ move_to_original_branch
rm -r "$dotest"
echo "All done."
}
@@ -153,10 +171,15 @@ do
finish_rb_merge
exit
fi
- git am --resolved --3way --resolvemsg="$RESOLVEMSG"
+ head_name=$(cat .dotest/head-name) &&
+ onto=$(cat .dotest/onto) &&
+ orig_head=$(cat .dotest/orig-head) &&
+ git am --resolved --3way --resolvemsg="$RESOLVEMSG" &&
+ move_to_original_branch
exit
;;
--skip)
+ git reset --hard HEAD || exit $?
if test -d "$dotest"
then
git rerere clear
@@ -173,16 +196,23 @@ do
finish_rb_merge
exit
fi
- git am -3 --skip --resolvemsg="$RESOLVEMSG"
+ head_name=$(cat .dotest/head-name) &&
+ onto=$(cat .dotest/onto) &&
+ orig_head=$(cat .dotest/orig-head) &&
+ git am -3 --skip --resolvemsg="$RESOLVEMSG" &&
+ move_to_original_branch
exit
;;
--abort)
git rerere clear
if test -d "$dotest"
then
+ move_to_original_branch
rm -r "$dotest"
elif test -d .dotest
then
+ dotest=.dotest
+ move_to_original_branch
rm -r .dotest
else
die "No rebase in progress?"
@@ -318,6 +348,19 @@ then
GIT_PAGER='' git diff --stat --summary "$mb" "$onto"
fi
+# move to a detached HEAD
+orig_head=$(git rev-parse HEAD^0)
+head_name=$(git symbolic-ref HEAD 2> /dev/null)
+case "$head_name" in
+'')
+ head_name="detached HEAD"
+ ;;
+*)
+ git checkout "$orig_head" > /dev/null 2>&1 ||
+ die "could not detach HEAD"
+ ;;
+esac
+
# Rewind the head to "$onto"; this saves our current head in ORIG_HEAD.
echo "First, rewinding head to replay your work on top of it..."
git-reset --hard "$onto"
@@ -327,14 +370,21 @@ git-reset --hard "$onto"
if test "$mb" = "$branch"
then
echo >&2 "Fast-forwarded $branch_name to $onto_name."
+ move_to_original_branch
exit 0
fi
if test -z "$do_merge"
then
git format-patch -k --stdout --full-index --ignore-if-in-upstream "$upstream"..ORIG_HEAD |
- git am $git_am_opt --binary -3 -k --resolvemsg="$RESOLVEMSG"
- exit $?
+ git am $git_am_opt --binary -3 -k --resolvemsg="$RESOLVEMSG" &&
+ move_to_original_branch
+ ret=$?
+ test 0 != $ret -a -d .dotest &&
+ echo $head_name > .dotest/head-name &&
+ echo $onto > .dotest/onto &&
+ echo $orig_head > .dotest/orig-head
+ exit $ret
fi
# start doing a rebase with git-merge
@@ -343,8 +393,10 @@ fi
mkdir -p "$dotest"
echo "$onto" > "$dotest/onto"
echo "$onto_name" > "$dotest/onto_name"
-prev_head=`git rev-parse HEAD^0`
+prev_head=$orig_head
echo "$prev_head" > "$dotest/prev_head"
+echo "$orig_head" > "$dotest/orig-head"
+echo "$head_name" > "$dotest/head-name"
msgnum=0
for cmt in `git rev-list --reverse --no-merges "$upstream"..ORIG_HEAD`
diff --git a/git-repack.sh b/git-repack.sh
index 7220635c9..e18eb3f5d 100755
--- a/git-repack.sh
+++ b/git-repack.sh
@@ -3,7 +3,22 @@
# Copyright (c) 2005 Linus Torvalds
#
-USAGE='[-a|-A] [-d] [-f] [-l] [-n] [-q] [--max-pack-size=N] [--window=N] [--window-memory=N] [--depth=N]'
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-repack [options]
+--
+a pack everything in a single pack
+A same as -a, and keep unreachable objects too
+d remove redundant packs, and run git-prune-packed
+f pass --no-reuse-delta to git-pack-objects
+q,quiet be quiet
+l pass --local to git-pack-objects
+ Packing constraints
+window= size of the window used for delta compression
+window-memory= same as the above, but limit memory size instead of entries count
+depth= limits the maximum delta depth
+max-pack-size= maximum size of each packfile
+"
SUBDIRECTORY_OK='Yes'
. git-sh-setup
@@ -20,10 +35,9 @@ do
-q) quiet=-q ;;
-f) no_reuse=--no-reuse-object ;;
-l) local=--local ;;
- --max-pack-size=*) extra="$extra $1" ;;
- --window=*) extra="$extra $1" ;;
- --window-memory=*) extra="$extra $1" ;;
- --depth=*) extra="$extra $1" ;;
+ --max-pack-size|--window|--window-memory|--depth)
+ extra="$extra $1=$2"; shift ;;
+ --) shift; break;;
*) usage ;;
esac
shift
diff --git a/git-request-pull.sh b/git-request-pull.sh
index 95ad66630..068f5e0fc 100755
--- a/git-request-pull.sh
+++ b/git-request-pull.sh
@@ -8,6 +8,7 @@ USAGE='<commit> <url> [<head>]'
LONG_USAGE='Summarizes the changes since <commit> to the standard output,
and includes <url> in the message generated.'
SUBDIRECTORY_OK='Yes'
+OPTIONS_SPEC=
. git-sh-setup
. git-parse-remote
diff --git a/git-send-email.perl b/git-send-email.perl
index f9bd2e5a9..76baa8e43 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -145,6 +145,7 @@ sub format_2822_time {
my $have_email_valid = eval { require Email::Valid; 1 };
my $smtp;
+my $auth;
sub unique_email_list(@);
sub cleanup_compose_files();
@@ -514,11 +515,13 @@ $time = time - scalar $#files;
sub unquote_rfc2047 {
local ($_) = @_;
- if (s/=\?utf-8\?q\?(.*)\?=/$1/g) {
+ my $encoding;
+ if (s/=\?([^?]+)\?q\?(.*)\?=/$2/g) {
+ $encoding = $1;
s/_/ /g;
s/=([0-9A-F]{2})/chr(hex($1))/eg;
}
- return "$_";
+ return wantarray ? ($_, $encoding) : $_;
}
# use the simplest quoting being able to handle the recipient
@@ -555,7 +558,11 @@ sub sanitize_address
sub send_message
{
my @recipients = unique_email_list(@to);
- @cc = (map { sanitize_address($_) } @cc);
+ @cc = (grep { my $cc = extract_valid_address($_);
+ not grep { $cc eq $_ } @recipients
+ }
+ map { sanitize_address($_) }
+ @cc);
my $to = join (",\n\t", @recipients);
@recipients = unique_email_list(@recipients,@cc,@bcclist);
@recipients = (map { extract_valid_address($_) } @recipients);
@@ -629,7 +636,7 @@ X-Mailer: git-send-email $gitversion
}
if ((defined $smtp_authuser) && (defined $smtp_authpass)) {
- $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
+ $auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message;
}
$smtp->mail( $raw_from ) or die $smtp->message;
$smtp->to( @recipients ) or die $smtp->message;
@@ -641,7 +648,7 @@ X-Mailer: git-send-email $gitversion
if ($quiet) {
printf (($dry_run ? "Dry-" : "")."Sent %s\n", $subject);
} else {
- print (($dry_run ? "Dry-" : "")."OK. Log says:\nDate: $date\n");
+ print (($dry_run ? "Dry-" : "")."OK. Log says:\n");
if ($smtp_server !~ m#^/#) {
print "Server: $smtp_server\n";
print "MAIL FROM:<$raw_from>\n";
@@ -649,7 +656,7 @@ X-Mailer: git-send-email $gitversion
} else {
print "Sendmail: $smtp_server ".join(' ',@sendmail_parameters)."\n";
}
- print "From: $sanitized_sender\nSubject: $subject\nCc: $cc\nTo: $to\n\n";
+ print $header, "\n";
if ($smtp) {
print "Result: ", $smtp->code, ' ',
($smtp->message =~ /\n([^\n]+\n)$/s), "\n";
@@ -667,6 +674,9 @@ foreach my $t (@files) {
open(F,"<",$t) or die "can't open file $t";
my $author = undef;
+ my $author_encoding;
+ my $has_content_type;
+ my $body_encoding;
@cc = @initial_cc;
@xh = ();
my $input_format = undef;
@@ -692,12 +702,20 @@ foreach my $t (@files) {
next if ($suppress_from);
}
elsif ($1 eq 'From') {
- $author = unquote_rfc2047($2);
+ ($author, $author_encoding)
+ = unquote_rfc2047($2);
}
printf("(mbox) Adding cc: %s from line '%s'\n",
$2, $_) unless $quiet;
push @cc, $2;
}
+ elsif (/^Content-type:/i) {
+ $has_content_type = 1;
+ if (/charset="?[^ "]+/) {
+ $body_encoding = $1;
+ }
+ push @xh, $_;
+ }
elsif (!/^Date:\s/ && /^[-A-Za-z]+:\s+\S/) {
push @xh, $_;
}
@@ -756,6 +774,22 @@ foreach my $t (@files) {
if (defined $author) {
$message = "From: $author\n\n$message";
+ if (defined $author_encoding) {
+ if ($has_content_type) {
+ if ($body_encoding eq $author_encoding) {
+ # ok, we already have the right encoding
+ }
+ else {
+ # uh oh, we should re-encode
+ }
+ }
+ else {
+ push @xh,
+ 'MIME-Version: 1.0',
+ "Content-Type: text/plain; charset=$author_encoding",
+ 'Content-Transfer-Encoding: 8bit';
+ }
+ }
}
send_message();
diff --git a/git-sh-setup.sh b/git-sh-setup.sh
index 86d7d4c4e..5aa62dda1 100755
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh
@@ -16,9 +16,40 @@ die() {
exit 1
}
-usage() {
- die "Usage: $0 $USAGE"
-}
+if test -n "$OPTIONS_SPEC"; then
+ usage() {
+ exec "$0" -h
+ }
+
+ parseopt_extra=
+ [ -n "$OPTIONS_KEEPDASHDASH" ] &&
+ parseopt_extra="--keep-dashdash"
+
+ eval "$(
+ echo "$OPTIONS_SPEC" |
+ git rev-parse --parseopt $parseopt_extra -- "$@" ||
+ echo exit $?
+ )"
+else
+ usage() {
+ die "Usage: $0 $USAGE"
+ }
+
+ if [ -z "$LONG_USAGE" ]
+ then
+ LONG_USAGE="Usage: $0 $USAGE"
+ else
+ LONG_USAGE="Usage: $0 $USAGE
+
+$LONG_USAGE"
+ fi
+
+ case "$1" in
+ -h|--h|--he|--hel|--help)
+ echo "$LONG_USAGE"
+ exit
+ esac
+fi
set_reflog_action() {
if [ -z "${GIT_REFLOG_ACTION:+set}" ]
@@ -91,21 +122,6 @@ get_author_ident_from_commit () {
LANG=C LC_ALL=C sed -ne "$pick_author_script"
}
-if [ -z "$LONG_USAGE" ]
-then
- LONG_USAGE="Usage: $0 $USAGE"
-else
- LONG_USAGE="Usage: $0 $USAGE
-
-$LONG_USAGE"
-fi
-
-case "$1" in
- -h|--h|--he|--hel|--help)
- echo "$LONG_USAGE"
- exit
-esac
-
# Make sure we are in a valid repository of a vintage we understand.
if [ -z "$SUBDIRECTORY_OK" ]
then
diff --git a/git-stash.sh b/git-stash.sh
index 5bbda47b7..534eb168a 100755
--- a/git-stash.sh
+++ b/git-stash.sh
@@ -4,6 +4,7 @@
USAGE='[ | list | show | apply | clear]'
SUBDIRECTORY_OK=Yes
+OPTIONS_SPEC=
. git-sh-setup
require_work_tree
cd_to_toplevel
@@ -21,23 +22,17 @@ no_changes () {
clear_stash () {
if current=$(git rev-parse --verify $ref_stash 2>/dev/null)
then
- git update-ref -d refs/stash $current
+ git update-ref -d $ref_stash $current
fi
}
-save_stash () {
+create_stash () {
stash_msg="$1"
if no_changes
then
- echo >&2 'No local changes to save'
exit 0
fi
- test -f "$GIT_DIR/logs/$ref_stash" ||
- clear_stash || die "Cannot initialize stash"
-
- # Make sure the reflog for stash is kept.
- : >>"$GIT_DIR/logs/$ref_stash"
# state of the base commit
if b_commit=$(git rev-parse --verify HEAD)
@@ -84,6 +79,23 @@ save_stash () {
w_commit=$(printf '%s\n' "$stash_msg" |
git commit-tree $w_tree -p $b_commit -p $i_commit) ||
die "Cannot record working tree state"
+}
+
+save_stash () {
+ stash_msg="$1"
+
+ if no_changes
+ then
+ echo >&2 'No local changes to save'
+ exit 0
+ fi
+ test -f "$GIT_DIR/logs/$ref_stash" ||
+ clear_stash || die "Cannot initialize stash"
+
+ create_stash "$stash_msg"
+
+ # Make sure the reflog for stash is kept.
+ : >>"$GIT_DIR/logs/$ref_stash"
git update-ref -m "$stash_msg" $ref_stash $w_commit ||
die "Cannot save the current status"
@@ -202,6 +214,13 @@ apply)
clear)
clear_stash
;;
+create)
+ if test $# -gt 0 && test "$1" = create
+ then
+ shift
+ fi
+ create_stash "$*" && echo "$w_commit"
+ ;;
help | usage)
usage
;;
diff --git a/git-submodule.sh b/git-submodule.sh
index 5af28ecd5..82ac28fa2 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -5,6 +5,7 @@
# Copyright (c) 2007 Lars Hjemli
USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]'
+OPTIONS_SPEC=
. git-sh-setup
require_work_tree
diff --git a/git-svn.perl b/git-svn.perl
index e3e00fdcc..43e1591ce 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -48,7 +48,8 @@ BEGIN {
foreach (qw/command command_oneline command_noisy command_output_pipe
command_input_pipe command_close_pipe/) {
for my $package ( qw(SVN::Git::Editor SVN::Git::Fetcher
- Git::SVN::Migration Git::SVN::Log Git::SVN),
+ Git::SVN::Migration Git::SVN::Log Git::SVN
+ Git::SVN::Util),
__PACKAGE__) {
*{"${package}::$_"} = \&{"Git::$_"};
}
@@ -64,7 +65,7 @@ my ($_stdin, $_help, $_edit,
$_template, $_shared,
$_version, $_fetch_all, $_no_rebase,
$_merge, $_strategy, $_dry_run, $_local,
- $_prefix, $_no_checkout, $_verbose);
+ $_prefix, $_no_checkout, $_url, $_verbose);
$Git::SVN::_follow_parent = 1;
my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username,
'config-dir=s' => \$Git::SVN::Ra::config_dir,
@@ -177,6 +178,10 @@ my %cmd = (
'file|F=s' => \$_file,
'revision|r=s' => \$_revision,
%cmt_opts } ],
+ 'info' => [ \&cmd_info,
+ "Show info about the latest SVN revision
+ on the current branch",
+ { 'url' => \$_url, } ],
);
my $cmd;
@@ -391,7 +396,7 @@ sub cmd_set_tree {
sub cmd_dcommit {
my $head = shift;
git_cmd_try { command_oneline(qw/diff-index --quiet HEAD/) }
- 'Cannot dcommit with a dirty index. Commit your changes first'
+ 'Cannot dcommit with a dirty index. Commit your changes first, '
. "or stash them with `git stash'.\n";
$head ||= 'HEAD';
my @refs;
@@ -425,6 +430,9 @@ sub cmd_dcommit {
my %ed_opts = ( r => $last_rev,
log => get_commit_entry($d)->{log},
ra => Git::SVN::Ra->new($gs->full_url),
+ config => SVN::Core::config_get_config(
+ $Git::SVN::Ra::config_dir
+ ),
tree_a => "$d~1",
tree_b => $d,
editor_cb => sub {
@@ -580,6 +588,23 @@ sub cmd_create_ignore {
});
}
+sub canonicalize_path {
+ my ($path) = @_;
+ my $dot_slash_added = 0;
+ if (substr($path, 0, 1) ne "/") {
+ $path = "./" . $path;
+ $dot_slash_added = 1;
+ }
+ # File::Spec->canonpath doesn't collapse x/../y into y (for a
+ # good reason), so let's do this manually.
+ $path =~ s#/+#/#g;
+ $path =~ s#/\.(?:/|$)#/#g;
+ $path =~ s#/[^/]+/\.\.##g;
+ $path =~ s#/$##g;
+ $path =~ s#^\./## if $dot_slash_added;
+ return $path;
+}
+
# get_svnprops(PATH)
# ------------------
# Helper for cmd_propget and cmd_proplist below.
@@ -597,12 +622,7 @@ sub get_svnprops {
# canonicalize the path (otherwise libsvn will abort or fail to
# find the file)
- # File::Spec->canonpath doesn't collapse x/../y into y (for a
- # good reason), so let's do this manually.
- $path =~ s#/+#/#g;
- $path =~ s#/\.(?:/|$)#/#g;
- $path =~ s#/[^/]+/\.\.##g;
- $path =~ s#/$##g;
+ $path = canonicalize_path($path);
my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
my $props;
@@ -733,6 +753,114 @@ sub cmd_commit_diff {
}
}
+sub cmd_info {
+ my $path = canonicalize_path(shift or ".");
+ unless (scalar(@_) == 0) {
+ die "Too many arguments specified\n";
+ }
+
+ my ($file_type, $diff_status) = find_file_type_and_diff_status($path);
+
+ if (!$file_type && !$diff_status) {
+ print STDERR "$path: (Not a versioned resource)\n\n";
+ return;
+ }
+
+ my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
+ unless ($gs) {
+ die "Unable to determine upstream SVN information from ",
+ "working tree history\n";
+ }
+ my $full_url = $url . ($path eq "." ? "" : "/$path");
+
+ if ($_url) {
+ print $full_url, "\n";
+ return;
+ }
+
+ my $result = "Path: $path\n";
+ $result .= "Name: " . basename($path) . "\n" if $file_type ne "dir";
+ $result .= "URL: " . $full_url . "\n";
+
+ eval {
+ my $repos_root = $gs->repos_root;
+ Git::SVN::remove_username($repos_root);
+ $result .= "Repository Root: $repos_root\n";
+ };
+ if ($@) {
+ $result .= "Repository Root: (offline)\n";
+ }
+ $result .= "Repository UUID: $uuid\n" unless $diff_status eq "A";
+ $result .= "Revision: " . ($diff_status eq "A" ? 0 : $rev) . "\n";
+
+ $result .= "Node Kind: " .
+ ($file_type eq "dir" ? "directory" : "file") . "\n";
+
+ my $schedule = $diff_status eq "A"
+ ? "add"
+ : ($diff_status eq "D" ? "delete" : "normal");
+ $result .= "Schedule: $schedule\n";
+
+ if ($diff_status eq "A") {
+ print $result, "\n";
+ return;
+ }
+
+ my ($lc_author, $lc_rev, $lc_date_utc);
+ my @args = Git::SVN::Log::git_svn_log_cmd($rev, $rev, "--", $path);
+ my $log = command_output_pipe(@args);
+ my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
+ while (<$log>) {
+ if (/^${esc_color}author (.+) <[^>]+> (\d+) ([\-\+]?\d+)$/o) {
+ $lc_author = $1;
+ $lc_date_utc = Git::SVN::Log::parse_git_date($2, $3);
+ } elsif (/^${esc_color} (git-svn-id:.+)$/o) {
+ (undef, $lc_rev, undef) = ::extract_metadata($1);
+ }
+ }
+ close $log;
+
+ Git::SVN::Log::set_local_timezone();
+
+ $result .= "Last Changed Author: $lc_author\n";
+ $result .= "Last Changed Rev: $lc_rev\n";
+ $result .= "Last Changed Date: " .
+ Git::SVN::Log::format_svn_date($lc_date_utc) . "\n";
+
+ if ($file_type ne "dir") {
+ my $text_last_updated_date =
+ ($diff_status eq "D" ? $lc_date_utc : (stat $path)[9]);
+ $result .=
+ "Text Last Updated: " .
+ Git::SVN::Log::format_svn_date($text_last_updated_date) .
+ "\n";
+ my $checksum;
+ if ($diff_status eq "D") {
+ my ($fh, $ctx) =
+ command_output_pipe(qw(cat-file blob), "HEAD:$path");
+ if ($file_type eq "link") {
+ my $file_name = <$fh>;
+ $checksum = Git::SVN::Util::md5sum("link $file_name");
+ } else {
+ $checksum = Git::SVN::Util::md5sum($fh);
+ }
+ command_close_pipe($fh, $ctx);
+ } elsif ($file_type eq "link") {
+ my $file_name =
+ command(qw(cat-file blob), "HEAD:$path");
+ $checksum =
+ Git::SVN::Util::md5sum("link " . $file_name);
+ } else {
+ open FILE, "<", $path or die $!;
+ $checksum = Git::SVN::Util::md5sum(\*FILE);
+ close FILE or die $!;
+ }
+ $result .= "Checksum: " . $checksum . "\n";
+ }
+
+ print $result, "\n";
+}
+
########################### utility functions #########################
sub rebase_cmd {
@@ -1040,6 +1168,52 @@ sub linearize_history {
(\@linear_refs, \%parents);
}
+sub find_file_type_and_diff_status {
+ my ($path) = @_;
+ return ('dir', '') if $path eq '.';
+
+ my $diff_output =
+ command_oneline(qw(diff --cached --name-status --), $path) || "";
+ my $diff_status = (split(' ', $diff_output))[0] || "";
+
+ my $ls_tree = command_oneline(qw(ls-tree HEAD), $path) || "";
+
+ return (undef, undef) if !$diff_status && !$ls_tree;
+
+ if ($diff_status eq "A") {
+ return ("link", $diff_status) if -l $path;
+ return ("dir", $diff_status) if -d $path;
+ return ("file", $diff_status);
+ }
+
+ my $mode = (split(' ', $ls_tree))[0] || "";
+
+ return ("link", $diff_status) if $mode eq "120000";
+ return ("dir", $diff_status) if $mode eq "040000";
+ return ("file", $diff_status);
+}
+
+package Git::SVN::Util;
+use strict;
+use warnings;
+use Digest::MD5;
+
+sub md5sum {
+ my $arg = shift;
+ my $ref = ref $arg;
+ my $md5 = Digest::MD5->new();
+ if ($ref eq 'GLOB' || $ref eq 'IO::File') {
+ $md5->addfile($arg) or croak $!;
+ } elsif ($ref eq 'SCALAR') {
+ $md5->add($$arg) or croak $!;
+ } elsif (!$ref) {
+ $md5->add($arg) or croak $!;
+ } else {
+ ::fatal "Can't provide MD5 hash for unknown ref type: '", $ref, "'";
+ }
+ return $md5->hexdigest();
+}
+
package Git::SVN;
use strict;
use warnings;
@@ -1604,9 +1778,24 @@ sub ra_uuid {
$self->{ra_uuid};
}
+sub _set_repos_root {
+ my ($self, $repos_root) = @_;
+ my $k = "svn-remote.$self->{repo_id}.reposRoot";
+ $repos_root ||= $self->ra->{repos_root};
+ tmp_config($k, $repos_root);
+ $repos_root;
+}
+
+sub repos_root {
+ my ($self) = @_;
+ my $k = "svn-remote.$self->{repo_id}.reposRoot";
+ eval { tmp_config('--get', $k) } || $self->_set_repos_root;
+}
+
sub ra {
my ($self) = shift;
my $ra = Git::SVN::Ra->new($self->{url});
+ $self->_set_repos_root($ra->{repos_root});
if ($self->use_svm_props && !$self->{svm}) {
if ($self->no_metadata) {
die "Can't have both 'noMetadata' and ",
@@ -2396,10 +2585,15 @@ sub rev_db_get {
$ret;
}
+# Finds the first svn revision that exists on (if $eq_ok is true) or
+# before $rev for the current branch. It will not search any lower
+# than $min_rev. Returns the git commit hash and svn revision number
+# if found, else (undef, undef).
sub find_rev_before {
- my ($self, $rev, $eq_ok) = @_;
+ my ($self, $rev, $eq_ok, $min_rev) = @_;
--$rev unless $eq_ok;
- while ($rev > 0) {
+ $min_rev ||= 1;
+ while ($rev >= $min_rev) {
if (my $c = $self->rev_db_get($rev)) {
return ($rev, $c);
}
@@ -2408,6 +2602,23 @@ sub find_rev_before {
return (undef, undef);
}
+# Finds the first svn revision that exists on (if $eq_ok is true) or
+# after $rev for the current branch. It will not search any higher
+# than $max_rev. Returns the git commit hash and svn revision number
+# if found, else (undef, undef).
+sub find_rev_after {
+ my ($self, $rev, $eq_ok, $max_rev) = @_;
+ ++$rev unless $eq_ok;
+ $max_rev ||= $self->rev_db_max();
+ while ($rev <= $max_rev) {
+ if (my $c = $self->rev_db_get($rev)) {
+ return ($rev, $c);
+ }
+ ++$rev;
+ }
+ return (undef, undef);
+}
+
sub _new {
my ($class, $repo_id, $ref_id, $path) = @_;
unless (defined $repo_id && length $repo_id) {
@@ -2585,7 +2796,6 @@ use strict;
use warnings;
use Carp qw/croak/;
use IO::File qw//;
-use Digest::MD5;
# file baton members: path, mode_a, mode_b, pool, fh, blob, base
sub new {
@@ -2737,9 +2947,7 @@ sub apply_textdelta {
if (defined $exp) {
seek $base, 0, 0 or croak $!;
- my $md5 = Digest::MD5->new;
- $md5->addfile($base);
- my $got = $md5->hexdigest;
+ my $got = Git::SVN::Util::md5sum($base);
die "Checksum mismatch: $fb->{path} $fb->{blob}\n",
"expected: $exp\n",
" got: $got\n" if ($got ne $exp);
@@ -2758,9 +2966,7 @@ sub close_file {
if (my $fh = $fb->{fh}) {
if (defined $exp) {
seek($fh, 0, 0) or croak $!;
- my $md5 = Digest::MD5->new;
- $md5->addfile($fh);
- my $got = $md5->hexdigest;
+ my $got = Git::SVN::Util::md5sum($fh);
if ($got ne $exp) {
die "Checksum mismatch: $path\n",
"expected: $exp\n got: $got\n";
@@ -2812,7 +3018,6 @@ use strict;
use warnings;
use Carp qw/croak/;
use IO::File;
-use Digest::MD5;
sub new {
my ($class, $opts) = @_;
@@ -3116,11 +3321,9 @@ sub chg_file {
$fh->flush == 0 or croak $!;
seek $fh, 0, 0 or croak $!;
- my $md5 = Digest::MD5->new;
- $md5->addfile($fh) or croak $!;
+ my $exp = Git::SVN::Util::md5sum($fh);
seek $fh, 0, 0 or croak $!;
- my $exp = $md5->hexdigest;
my $pool = SVN::Pool->new;
my $atd = $self->apply_textdelta($fbat, undef, $pool);
my $got = SVN::TxDelta::send_stream($fh, @$atd, $pool);
@@ -3698,6 +3901,7 @@ package Git::SVN::Log;
use strict;
use warnings;
use POSIX qw/strftime/;
+use constant commit_log_separator => ('-' x 72) . "\n";
use vars qw/$TZ $limit $color $pager $non_recursive $verbose $oneline
%rusers $show_commit $incremental/;
my $l_fmt;
@@ -3791,19 +3995,19 @@ sub git_svn_log_cmd {
push @cmd, $c;
}
} elsif (defined $r_max) {
- my ($c_min, $c_max);
- $c_max = $gs->rev_db_get($r_max);
- $c_min = $gs->rev_db_get($r_min);
- if (defined $c_min && defined $c_max) {
- if ($r_max > $r_max) {
- push @cmd, "$c_min..$c_max";
- } else {
- push @cmd, "$c_max..$c_min";
- }
- } elsif ($r_max > $r_min) {
- push @cmd, $c_max;
+ if ($r_max < $r_min) {
+ ($r_min, $r_max) = ($r_max, $r_min);
+ }
+ my (undef, $c_max) = $gs->find_rev_before($r_max, 1, $r_min);
+ my (undef, $c_min) = $gs->find_rev_after($r_min, 1, $r_max);
+ # If there are no commits in the range, both $c_max and $c_min
+ # will be undefined. If there is at least 1 commit in the
+ # range, both will be defined.
+ return () if !defined $c_min || !defined $c_max;
+ if ($c_min eq $c_max) {
+ push @cmd, '--max-count=1', $c_min;
} else {
- push @cmd, $c_min;
+ push @cmd, '--boundary', "$c_min..$c_max";
}
}
return (@cmd, @files);
@@ -3833,6 +4037,29 @@ sub run_pager {
exec $pager or ::fatal "Can't run pager: $! ($pager)";
}
+sub format_svn_date {
+ return strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)", localtime(shift));
+}
+
+sub parse_git_date {
+ my ($t, $tz) = @_;
+ # Date::Parse isn't in the standard Perl distro :(
+ if ($tz =~ s/^\+//) {
+ $t += tz_to_s_offset($tz);
+ } elsif ($tz =~ s/^\-//) {
+ $t -= tz_to_s_offset($tz);
+ }
+ return $t;
+}
+
+sub set_local_timezone {
+ if (defined $TZ) {
+ $ENV{TZ} = $TZ;
+ } else {
+ delete $ENV{TZ};
+ }
+}
+
sub tz_to_s_offset {
my ($tz) = @_;
$tz =~ s/(\d\d)$//;
@@ -3853,13 +4080,7 @@ sub get_author_info {
$dest->{t} = $t;
$dest->{tz} = $tz;
$dest->{a} = $au;
- # Date::Parse isn't in the standard Perl distro :(
- if ($tz =~ s/^\+//) {
- $t += tz_to_s_offset($tz);
- } elsif ($tz =~ s/^\-//) {
- $t -= tz_to_s_offset($tz);
- }
- $dest->{t_utc} = $t;
+ $dest->{t_utc} = parse_git_date($t, $tz);
}
sub process_commit {
@@ -3911,10 +4132,9 @@ sub show_commit_changed_paths {
sub show_commit_normal {
my ($c) = @_;
- print '-' x72, "\nr$c->{r} | ";
+ print commit_log_separator, "r$c->{r} | ";
print "$c->{c} | " if $show_commit;
- print "$c->{a} | ", strftime("%Y-%m-%d %H:%M:%S %z (%a, %d %b %Y)",
- localtime($c->{t_utc})), ' | ';
+ print "$c->{a} | ", format_svn_date($c->{t_utc}), ' | ';
my $nr_line = 0;
if (my $l = $c->{l}) {
@@ -3954,11 +4174,7 @@ sub cmd_show_log {
my (@args) = @_;
my ($r_min, $r_max);
my $r_last = -1; # prevent dupes
- if (defined $TZ) {
- $ENV{TZ} = $TZ;
- } else {
- delete $ENV{TZ};
- }
+ set_local_timezone();
if (defined $::_revision) {
if ($::_revision =~ /^(\d+):(\d+)$/) {
($r_min, $r_max) = ($1, $2);
@@ -3972,12 +4188,16 @@ sub cmd_show_log {
config_pager();
@args = git_svn_log_cmd($r_min, $r_max, @args);
+ if (!@args) {
+ print commit_log_separator unless $incremental || $oneline;
+ return;
+ }
my $log = command_output_pipe(@args);
run_pager();
my (@k, $c, $d, $stat);
my $esc_color = qr/(?:\033\[(?:(?:\d+;)*\d*)?m)*/;
while (<$log>) {
- if (/^${esc_color}commit ($::sha1_short)/o) {
+ if (/^${esc_color}commit -?($::sha1_short)/o) {
my $cmt = $1;
if ($c && cmt_showable($c) && $c->{r} != $r_last) {
$r_last = $c->{r};
@@ -4020,14 +4240,12 @@ sub cmd_show_log {
process_commit($c, $r_min, $r_max, \@k);
}
if (@k) {
- my $swap = $r_max;
- $r_max = $r_min;
- $r_min = $swap;
+ ($r_min, $r_max) = ($r_max, $r_min);
process_commit($_, $r_min, $r_max) foreach reverse @k;
}
out:
close $log;
- print '-' x72,"\n" unless $incremental || $oneline;
+ print commit_log_separator unless $incremental || $oneline;
}
package Git::SVN::Migration;
diff --git a/git.c b/git.c
index 6c5f9af13..01bbbc732 100644
--- a/git.c
+++ b/git.c
@@ -256,7 +256,7 @@ static int run_command(struct cmd_struct *p, int argc, const char **argv)
status = p->fn(argc, argv, prefix);
if (status)
- return status;
+ return status & 0xff;
/* Somebody closed stdout? */
if (fstat(fileno(stdout), &st))
@@ -293,6 +293,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "check-attr", cmd_check_attr, RUN_SETUP | NEED_WORK_TREE },
{ "cherry", cmd_cherry, RUN_SETUP },
{ "cherry-pick", cmd_cherry_pick, RUN_SETUP | NEED_WORK_TREE },
+ { "clean", cmd_clean, RUN_SETUP | NEED_WORK_TREE },
{ "commit-tree", cmd_commit_tree, RUN_SETUP },
{ "config", cmd_config },
{ "count-objects", cmd_count_objects, RUN_SETUP },
@@ -326,6 +327,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "mailsplit", cmd_mailsplit },
{ "merge-base", cmd_merge_base, RUN_SETUP },
{ "merge-file", cmd_merge_file },
+ { "merge-ours", cmd_merge_ours, RUN_SETUP },
{ "mv", cmd_mv, RUN_SETUP | NEED_WORK_TREE },
{ "name-rev", cmd_name_rev, RUN_SETUP },
{ "pack-objects", cmd_pack_objects, RUN_SETUP },
@@ -340,7 +342,7 @@ static void handle_internal_command(int argc, const char **argv)
{ "rerere", cmd_rerere, RUN_SETUP },
{ "reset", cmd_reset, RUN_SETUP },
{ "rev-list", cmd_rev_list, RUN_SETUP },
- { "rev-parse", cmd_rev_parse, RUN_SETUP },
+ { "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 },
diff --git a/gitweb/gitweb.css b/gitweb/gitweb.css
index 1b8887987..446a1c333 100644
--- a/gitweb/gitweb.css
+++ b/gitweb/gitweb.css
@@ -85,6 +85,10 @@ div.title, a.title {
color: #000000;
}
+div.readme {
+ padding: 8px;
+}
+
a.title:hover {
background-color: #d9d8d1;
}
@@ -170,14 +174,10 @@ a.text:hover {
table {
padding: 8px 4px;
-}
-
-table.project_list {
border-spacing: 0;
}
table.diff_tree {
- border-spacing: 0;
font-family: monospace;
}
diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl
index e788ef90c..491a3f41d 100755
--- a/gitweb/gitweb.perl
+++ b/gitweb/gitweb.perl
@@ -3544,7 +3544,7 @@ sub git_shortlog_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
- print "<table class=\"shortlog\" cellspacing=\"0\">\n";
+ print "<table class=\"shortlog\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3590,7 +3590,7 @@ sub git_history_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} unless (defined $to && $to <= $#{$commitlist});
- print "<table class=\"history\" cellspacing=\"0\">\n";
+ print "<table class=\"history\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3650,7 +3650,7 @@ sub git_tags_body {
$from = 0 unless defined $from;
$to = $#{$taglist} if (!defined $to || $#{$taglist} < $to);
- print "<table class=\"tags\" cellspacing=\"0\">\n";
+ print "<table class=\"tags\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my $entry = $taglist->[$i];
@@ -3713,7 +3713,7 @@ sub git_heads_body {
$from = 0 unless defined $from;
$to = $#{$headlist} if (!defined $to || $#{$headlist} < $to);
- print "<table class=\"heads\" cellspacing=\"0\">\n";
+ print "<table class=\"heads\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my $entry = $headlist->[$i];
@@ -3750,7 +3750,7 @@ sub git_search_grep_body {
$from = 0 unless defined $from;
$to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to);
- print "<table class=\"grep\" cellspacing=\"0\">\n";
+ print "<table class=\"commit_search\">\n";
my $alternate = 1;
for (my $i = $from; $i <= $to; $i++) {
my %co = %{$commitlist->[$i]};
@@ -3891,7 +3891,7 @@ sub git_summary {
git_print_page_nav('summary','', $head);
print "<div class=\"title\">&nbsp;</div>\n";
- print "<table cellspacing=\"0\">\n" .
+ print "<table class=\"projects_list\">\n" .
"<tr><td>description</td><td>" . esc_html($descr) . "</td></tr>\n" .
"<tr><td>owner</td><td>" . esc_html($owner) . "</td></tr>\n";
if (defined $cd{'rfc2822'}) {
@@ -3912,8 +3912,10 @@ sub git_summary {
if (-s "$projectroot/$project/README.html") {
if (open my $fd, "$projectroot/$project/README.html") {
- print "<div class=\"title\">readme</div>\n";
+ print "<div class=\"title\">readme</div>\n" .
+ "<div class=\"readme\">\n";
print $_ while (<$fd>);
+ print "\n</div>\n"; # class="readme"
close $fd;
}
}
@@ -3965,7 +3967,7 @@ sub git_tag {
git_print_header_div('commit', esc_html($tag{'name'}), $hash);
print "<div class=\"title_text\">\n" .
- "<table cellspacing=\"0\">\n" .
+ "<table class=\"object_header\">\n" .
"<tr>\n" .
"<td>object</td>\n" .
"<td>" . $cgi->a({-class => "list", -href => href(action=>$tag{'type'}, hash=>$tag{'object'})},
@@ -4405,7 +4407,7 @@ sub git_tree {
}
git_print_page_path($file_name, 'tree', $hash_base);
print "<div class=\"page_body\">\n";
- print "<table cellspacing=\"0\">\n";
+ print "<table class=\"tree\">\n";
my $alternate = 1;
# '..' (top directory) link if possible
if (defined $hash_base &&
@@ -4627,7 +4629,7 @@ sub git_commit {
git_print_header_div('tree', esc_html($co{'title'}) . $ref, $co{'tree'}, $hash);
}
print "<div class=\"title_text\">\n" .
- "<table cellspacing=\"0\">\n";
+ "<table class=\"object_header\">\n";
print "<tr><td>author</td><td>" . esc_html($co{'author'}) . "</td></tr>\n".
"<tr>" .
"<td></td><td> $ad{'rfc2822'}";
@@ -5226,7 +5228,7 @@ sub git_search {
git_print_page_nav('','', $hash,$co{'tree'},$hash);
git_print_header_div('commit', esc_html($co{'title'}), $hash);
- print "<table cellspacing=\"0\">\n";
+ print "<table class=\"pickaxe search\">\n";
my $alternate = 1;
$/ = "\n";
my $git_command = git_cmd_str();
@@ -5293,7 +5295,7 @@ sub git_search {
git_print_page_nav('','', $hash,$co{'tree'},$hash);
git_print_header_div('commit', esc_html($co{'title'}), $hash);
- print "<table cellspacing=\"0\">\n";
+ print "<table class=\"grep_search\">\n";
my $alternate = 1;
my $matches = 0;
$/ = "\n";
diff --git a/help.c b/help.c
index 8217d9778..d340b6a1b 100644
--- a/help.c
+++ b/help.c
@@ -7,7 +7,6 @@
#include "builtin.h"
#include "exec_cmd.h"
#include "common-cmds.h"
-#include <sys/ioctl.h>
/* most GUI terminals set COLUMNS (although some don't export it) */
static int term_columns(void)
diff --git a/index-pack.c b/index-pack.c
index 3c99a1fce..9fd6982a9 100644
--- a/index-pack.c
+++ b/index-pack.c
@@ -87,9 +87,9 @@ static void *fill(int min)
die("early EOF");
die("read error on input: %s", strerror(errno));
}
- if (from_stdin)
- display_throughput(progress, ret);
input_len += ret;
+ if (from_stdin)
+ display_throughput(progress, consumed_bytes + input_len);
} while (input_len < min);
return input_buffer;
}
@@ -792,6 +792,7 @@ int main(int argc, char **argv)
flush();
} else {
if (fix_thin_pack) {
+ char msg[48];
int nr_unresolved = nr_deltas - nr_resolved_deltas;
int nr_objects_initial = nr_objects;
if (nr_unresolved <= 0)
@@ -800,12 +801,11 @@ int main(int argc, char **argv)
(nr_objects + nr_unresolved + 1)
* sizeof(*objects));
fix_unresolved_deltas(nr_unresolved);
- stop_progress(&progress);
- if (verbose)
- fprintf(stderr, "%d objects were added to complete this thin pack.\n",
- nr_objects - nr_objects_initial);
+ sprintf(msg, "completed with %d local objects",
+ nr_objects - nr_objects_initial);
+ stop_progress_msg(&progress, msg);
fixup_pack_header_footer(output_fd, sha1,
- curr_pack, nr_objects);
+ curr_pack, nr_objects);
}
if (nr_deltas != nr_resolved_deltas)
die("pack has %d unresolved deltas",
diff --git a/lockfile.c b/lockfile.c
index 9a1f64d8d..258fb3f5e 100644
--- a/lockfile.c
+++ b/lockfile.c
@@ -12,8 +12,10 @@ static void remove_lock_file(void)
while (lock_file_list) {
if (lock_file_list->owner == me &&
- lock_file_list->filename[0])
+ lock_file_list->filename[0]) {
+ close(lock_file_list->fd);
unlink(lock_file_list->filename);
+ }
lock_file_list = lock_file_list->next;
}
}
@@ -120,8 +122,6 @@ static char *resolve_symlink(char *p, size_t s)
static int lock_file(struct lock_file *lk, const char *path)
{
- int fd;
-
if (strlen(path) >= sizeof(lk->filename)) return -1;
strcpy(lk->filename, path);
/*
@@ -130,8 +130,8 @@ static int lock_file(struct lock_file *lk, const char *path)
*/
resolve_symlink(lk->filename, sizeof(lk->filename)-5);
strcat(lk->filename, ".lock");
- fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
- if (0 <= fd) {
+ lk->fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
+ if (0 <= lk->fd) {
if (!lock_file_list) {
signal(SIGINT, remove_lock_file_on_signal);
atexit(remove_lock_file);
@@ -148,7 +148,7 @@ static int lock_file(struct lock_file *lk, const char *path)
}
else
lk->filename[0] = 0;
- return fd;
+ return lk->fd;
}
int hold_lock_file_for_update(struct lock_file *lk, const char *path, int die_on_error)
@@ -163,6 +163,7 @@ int commit_lock_file(struct lock_file *lk)
{
char result_file[PATH_MAX];
int i;
+ close(lk->fd);
strcpy(result_file, lk->filename);
i = strlen(result_file) - 5; /* .lock */
result_file[i] = 0;
@@ -194,7 +195,9 @@ int commit_locked_index(struct lock_file *lk)
void rollback_lock_file(struct lock_file *lk)
{
- if (lk->filename[0])
+ if (lk->filename[0]) {
+ close(lk->fd);
unlink(lk->filename);
+ }
lk->filename[0] = 0;
}
diff --git a/log-tree.c b/log-tree.c
index a34beb0b0..1f3fcf16a 100644
--- a/log-tree.c
+++ b/log-tree.c
@@ -245,8 +245,7 @@ void show_log(struct rev_info *opt, const char *sep)
opt->diffopt.stat_sep = buffer;
}
} else if (opt->commit_format != CMIT_FMT_USERFORMAT) {
- fputs(diff_get_color(opt->diffopt.color_diff, DIFF_COMMIT),
- stdout);
+ fputs(diff_get_color_opt(&opt->diffopt, DIFF_COMMIT), stdout);
if (opt->commit_format != CMIT_FMT_ONELINE)
fputs("commit ", stdout);
if (commit->object.flags & BOUNDARY)
@@ -266,8 +265,7 @@ void show_log(struct rev_info *opt, const char *sep)
diff_unique_abbrev(parent->object.sha1,
abbrev_commit));
show_decorations(commit);
- printf("%s",
- diff_get_color(opt->diffopt.color_diff, DIFF_RESET));
+ printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET));
putchar(opt->commit_format == CMIT_FMT_ONELINE ? ' ' : '\n');
if (opt->reflog_info) {
show_reflog_message(opt->reflog_info,
diff --git a/merge-recursive.c b/merge-recursive.c
index 6c6f595fb..9a1e2f269 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -366,7 +366,7 @@ static struct path_list *get_renames(struct tree *tree,
renames = xcalloc(1, sizeof(struct path_list));
diff_setup(&opts);
- opts.recursive = 1;
+ DIFF_OPT_SET(&opts, RECURSIVE);
opts.detect_rename = DIFF_DETECT_RENAME;
opts.rename_limit = rename_limit;
opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff --git a/pager.c b/pager.c
index 8bac9d990..fb7a1a625 100644
--- a/pager.c
+++ b/pager.c
@@ -1,7 +1,5 @@
#include "cache.h"
-#include <sys/select.h>
-
/*
* This is split up from the rest of git so that we might do
* something different on Windows, for example.
diff --git a/parse-options.c b/parse-options.c
index 15b32f741..d3e608ac4 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -40,24 +40,53 @@ static int get_value(struct optparse_t *p,
const struct option *opt, int flags)
{
const char *s, *arg;
- arg = p->opt ? p->opt : (p->argc > 1 ? p->argv[1] : NULL);
+ const int unset = flags & OPT_UNSET;
- if (p->opt && (flags & OPT_UNSET))
+ if (unset && p->opt)
return opterror(opt, "takes no value", flags);
+ if (unset && (opt->flags & PARSE_OPT_NONEG))
+ return opterror(opt, "isn't available", flags);
- switch (opt->type) {
- case OPTION_BOOLEAN:
- if (!(flags & OPT_SHORT) && p->opt)
+ if (!(flags & OPT_SHORT) && p->opt) {
+ switch (opt->type) {
+ case OPTION_CALLBACK:
+ if (!(opt->flags & PARSE_OPT_NOARG))
+ break;
+ /* FALLTHROUGH */
+ case OPTION_BOOLEAN:
+ case OPTION_BIT:
+ case OPTION_SET_INT:
+ case OPTION_SET_PTR:
return opterror(opt, "takes no value", flags);
- if (flags & OPT_UNSET)
- *(int *)opt->value = 0;
+ default:
+ break;
+ }
+ }
+
+ arg = p->opt ? p->opt : (p->argc > 1 ? p->argv[1] : NULL);
+ switch (opt->type) {
+ case OPTION_BIT:
+ if (unset)
+ *(int *)opt->value &= ~opt->defval;
else
- (*(int *)opt->value)++;
+ *(int *)opt->value |= opt->defval;
+ return 0;
+
+ case OPTION_BOOLEAN:
+ *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
+ return 0;
+
+ case OPTION_SET_INT:
+ *(int *)opt->value = unset ? 0 : opt->defval;
+ return 0;
+
+ case OPTION_SET_PTR:
+ *(void **)opt->value = unset ? NULL : (void *)opt->defval;
return 0;
case OPTION_STRING:
- if (flags & OPT_UNSET) {
- *(const char **)opt->value = (const char *)NULL;
+ if (unset) {
+ *(const char **)opt->value = NULL;
return 0;
}
if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-')) {
@@ -70,13 +99,10 @@ static int get_value(struct optparse_t *p,
return 0;
case OPTION_CALLBACK:
- if (flags & OPT_UNSET)
+ if (unset)
return (*opt->callback)(opt, NULL, 1);
- if (opt->flags & PARSE_OPT_NOARG) {
- if (p->opt && !(flags & OPT_SHORT))
- return opterror(opt, "takes no value", flags);
+ if (opt->flags & PARSE_OPT_NOARG)
return (*opt->callback)(opt, NULL, 0);
- }
if (opt->flags & PARSE_OPT_OPTARG && (!arg || *arg == '-'))
return (*opt->callback)(opt, NULL, 0);
if (!arg)
@@ -84,7 +110,7 @@ static int get_value(struct optparse_t *p,
return (*opt->callback)(opt, get_arg(p), 0);
case OPTION_INTEGER:
- if (flags & OPT_UNSET) {
+ if (unset) {
*(int *)opt->value = 0;
return 0;
}
@@ -292,7 +318,7 @@ void usage_with_options(const char * const *usagestr,
pos += fprintf(stderr, " ...");
}
break;
- default:
+ default: /* OPTION_{BIT,BOOLEAN,SET_INT,SET_PTR} */
break;
}
@@ -311,6 +337,7 @@ void usage_with_options(const char * const *usagestr,
/*----- some often used options -----*/
#include "cache.h"
+
int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
{
int v;
diff --git a/parse-options.h b/parse-options.h
index 65bce6eaf..a8760ac4b 100644
--- a/parse-options.h
+++ b/parse-options.h
@@ -2,9 +2,15 @@
#define PARSE_OPTIONS_H
enum parse_opt_type {
+ /* special types */
OPTION_END,
OPTION_GROUP,
- OPTION_BOOLEAN,
+ /* options with no arguments */
+ OPTION_BIT,
+ OPTION_BOOLEAN, /* _INCR would have been a better name */
+ OPTION_SET_INT,
+ OPTION_SET_PTR,
+ /* options with arguments (usually) */
OPTION_STRING,
OPTION_INTEGER,
OPTION_CALLBACK,
@@ -17,6 +23,7 @@ enum parse_opt_flags {
enum parse_opt_option_flags {
PARSE_OPT_OPTARG = 1,
PARSE_OPT_NOARG = 2,
+ PARSE_OPT_NONEG = 4,
};
struct option;
@@ -49,12 +56,15 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
* mask of parse_opt_option_flags.
* PARSE_OPT_OPTARG: says that the argument is optionnal (not for BOOLEANs)
* PARSE_OPT_NOARG: says that this option takes no argument, for CALLBACKs
+ * PARSE_OPT_NONEG: says that this option cannot be negated
*
* `callback`::
* pointer to the callback to use for OPTION_CALLBACK.
*
* `defval`::
* default value to fill (*->value) with for PARSE_OPT_OPTARG.
+ * OPTION_{BIT,SET_INT,SET_PTR} store the {mask,integer,pointer} to put in
+ * the value when met.
* CALLBACKS can use it like they want.
*/
struct option {
@@ -72,7 +82,10 @@ struct option {
#define OPT_END() { OPTION_END }
#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) }
+#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) }
#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) }
+#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) }
+#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) }
#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) }
#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) }
#define OPT_CALLBACK(s, l, v, a, h, f) \
diff --git a/patch-ids.c b/patch-ids.c
index a288fac99..3be5d3165 100644
--- a/patch-ids.c
+++ b/patch-ids.c
@@ -121,7 +121,7 @@ int init_patch_ids(struct patch_ids *ids)
{
memset(ids, 0, sizeof(*ids));
diff_setup(&ids->diffopts);
- ids->diffopts.recursive = 1;
+ DIFF_OPT_SET(&ids->diffopts, RECURSIVE);
if (diff_setup_done(&ids->diffopts) < 0)
return error("diff_setup_done failed");
return 0;
diff --git a/pretty.c b/pretty.c
index 490cede26..9db75b4e4 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1,6 +1,5 @@
#include "cache.h"
#include "commit.h"
-#include "interpolate.h"
#include "utf8.h"
#include "diff.h"
#include "revision.h"
@@ -283,7 +282,8 @@ static char *logmsg_reencode(const struct commit *commit,
return out;
}
-static void fill_person(struct interp *table, const char *msg, int len)
+static void format_person_part(struct strbuf *sb, char part,
+ const char *msg, int len)
{
int start, end, tz = 0;
unsigned long date;
@@ -295,7 +295,10 @@ static void fill_person(struct interp *table, const char *msg, int len)
start = end + 1;
while (end > 0 && isspace(msg[end - 1]))
end--;
- table[0].value = xmemdupz(msg, end);
+ if (part == 'n') { /* name */
+ strbuf_add(sb, msg, end);
+ return;
+ }
if (start >= len)
return;
@@ -307,7 +310,10 @@ static void fill_person(struct interp *table, const char *msg, int len)
if (end >= len)
return;
- table[1].value = xmemdupz(msg + start, end - start);
+ if (part == 'e') { /* email */
+ strbuf_add(sb, msg + start, end - start);
+ return;
+ }
/* parse date */
for (start = end + 1; start < len && isspace(msg[start]); start++)
@@ -318,7 +324,10 @@ static void fill_person(struct interp *table, const char *msg, int len)
if (msg + start == ep)
return;
- table[5].value = xmemdupz(msg + start, ep - (msg + start));
+ if (part == 't') { /* date, UNIX timestamp */
+ strbuf_add(sb, msg + start, ep - (msg + start));
+ return;
+ }
/* parse tz */
for (start = ep - msg + 1; start < len && isspace(msg[start]); start++)
@@ -329,115 +338,66 @@ static void fill_person(struct interp *table, const char *msg, int len)
tz = -tz;
}
- interp_set_entry(table, 2, show_date(date, tz, DATE_NORMAL));
- interp_set_entry(table, 3, show_date(date, tz, DATE_RFC2822));
- interp_set_entry(table, 4, show_date(date, tz, DATE_RELATIVE));
- interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
+ switch (part) {
+ case 'd': /* date */
+ strbuf_addstr(sb, show_date(date, tz, DATE_NORMAL));
+ return;
+ case 'D': /* date, RFC2822 style */
+ strbuf_addstr(sb, show_date(date, tz, DATE_RFC2822));
+ return;
+ case 'r': /* date, relative */
+ strbuf_addstr(sb, show_date(date, tz, DATE_RELATIVE));
+ return;
+ case 'i': /* date, ISO 8601 */
+ strbuf_addstr(sb, show_date(date, tz, DATE_ISO8601));
+ return;
+ }
}
-void format_commit_message(const struct commit *commit,
- const void *format, struct strbuf *sb)
-{
- struct interp table[] = {
- { "%H" }, /* commit hash */
- { "%h" }, /* abbreviated commit hash */
- { "%T" }, /* tree hash */
- { "%t" }, /* abbreviated tree hash */
- { "%P" }, /* parent hashes */
- { "%p" }, /* abbreviated parent hashes */
- { "%an" }, /* author name */
- { "%ae" }, /* author email */
- { "%ad" }, /* author date */
- { "%aD" }, /* author date, RFC2822 style */
- { "%ar" }, /* author date, relative */
- { "%at" }, /* author date, UNIX timestamp */
- { "%ai" }, /* author date, ISO 8601 */
- { "%cn" }, /* committer name */
- { "%ce" }, /* committer email */
- { "%cd" }, /* committer date */
- { "%cD" }, /* committer date, RFC2822 style */
- { "%cr" }, /* committer date, relative */
- { "%ct" }, /* committer date, UNIX timestamp */
- { "%ci" }, /* committer date, ISO 8601 */
- { "%e" }, /* encoding */
- { "%s" }, /* subject */
- { "%b" }, /* body */
- { "%Cred" }, /* red */
- { "%Cgreen" }, /* green */
- { "%Cblue" }, /* blue */
- { "%Creset" }, /* reset color */
- { "%n" }, /* newline */
- { "%m" }, /* left/right/bottom */
- };
- enum interp_index {
- IHASH = 0, IHASH_ABBREV,
- ITREE, ITREE_ABBREV,
- IPARENTS, IPARENTS_ABBREV,
- IAUTHOR_NAME, IAUTHOR_EMAIL,
- IAUTHOR_DATE, IAUTHOR_DATE_RFC2822, IAUTHOR_DATE_RELATIVE,
- IAUTHOR_TIMESTAMP, IAUTHOR_ISO8601,
- ICOMMITTER_NAME, ICOMMITTER_EMAIL,
- ICOMMITTER_DATE, ICOMMITTER_DATE_RFC2822,
- ICOMMITTER_DATE_RELATIVE, ICOMMITTER_TIMESTAMP,
- ICOMMITTER_ISO8601,
- IENCODING,
- ISUBJECT,
- IBODY,
- IRED, IGREEN, IBLUE, IRESET_COLOR,
- INEWLINE,
- ILEFT_RIGHT,
- };
- struct commit_list *p;
- char parents[1024];
- unsigned long len;
- int i;
- enum { HEADER, SUBJECT, BODY } state;
- const char *msg = commit->buffer;
+struct chunk {
+ size_t off;
+ size_t len;
+};
- if (ILEFT_RIGHT + 1 != ARRAY_SIZE(table))
- die("invalid interp table!");
+struct format_commit_context {
+ const struct commit *commit;
+
+ /* These offsets are relative to the start of the commit message. */
+ int commit_header_parsed;
+ struct chunk subject;
+ struct chunk author;
+ struct chunk committer;
+ struct chunk encoding;
+ size_t body_off;
+
+ /* The following ones are relative to the result struct strbuf. */
+ struct chunk abbrev_commit_hash;
+ struct chunk abbrev_tree_hash;
+ struct chunk abbrev_parent_hashes;
+};
- /* these are independent of the commit */
- interp_set_entry(table, IRED, "\033[31m");
- interp_set_entry(table, IGREEN, "\033[32m");
- interp_set_entry(table, IBLUE, "\033[34m");
- interp_set_entry(table, IRESET_COLOR, "\033[m");
- interp_set_entry(table, INEWLINE, "\n");
+static int add_again(struct strbuf *sb, struct chunk *chunk)
+{
+ if (chunk->len) {
+ strbuf_adddup(sb, chunk->off, chunk->len);
+ return 1;
+ }
- /* these depend on the commit */
- if (!commit->object.parsed)
- parse_object(commit->object.sha1);
- interp_set_entry(table, IHASH, sha1_to_hex(commit->object.sha1));
- interp_set_entry(table, IHASH_ABBREV,
- find_unique_abbrev(commit->object.sha1,
- DEFAULT_ABBREV));
- interp_set_entry(table, ITREE, sha1_to_hex(commit->tree->object.sha1));
- interp_set_entry(table, ITREE_ABBREV,
- find_unique_abbrev(commit->tree->object.sha1,
- DEFAULT_ABBREV));
- interp_set_entry(table, ILEFT_RIGHT,
- (commit->object.flags & BOUNDARY)
- ? "-"
- : (commit->object.flags & SYMMETRIC_LEFT)
- ? "<"
- : ">");
-
- parents[1] = 0;
- for (i = 0, p = commit->parents;
- p && i < sizeof(parents) - 1;
- p = p->next)
- i += snprintf(parents + i, sizeof(parents) - i - 1, " %s",
- sha1_to_hex(p->item->object.sha1));
- interp_set_entry(table, IPARENTS, parents + 1);
-
- parents[1] = 0;
- for (i = 0, p = commit->parents;
- p && i < sizeof(parents) - 1;
- p = p->next)
- i += snprintf(parents + i, sizeof(parents) - i - 1, " %s",
- find_unique_abbrev(p->item->object.sha1,
- DEFAULT_ABBREV));
- interp_set_entry(table, IPARENTS_ABBREV, parents + 1);
+ /*
+ * We haven't seen this chunk before. Our caller is surely
+ * going to add it the hard way now. Remember the most likely
+ * start of the to-be-added chunk: the current end of the
+ * struct strbuf.
+ */
+ chunk->off = sb->len;
+ return 0;
+}
+
+static void parse_commit_header(struct format_commit_context *context)
+{
+ const char *msg = context->commit->buffer;
+ int i;
+ enum { HEADER, SUBJECT, BODY } state;
for (i = 0, state = HEADER; msg[i] && state < BODY; i++) {
int eol;
@@ -445,7 +405,8 @@ void format_commit_message(const struct commit *commit,
; /* do nothing */
if (state == SUBJECT) {
- table[ISUBJECT].value = xmemdupz(msg + i, eol - i);
+ context->subject.off = i;
+ context->subject.len = eol - i;
i = eol;
}
if (i == eol) {
@@ -453,29 +414,170 @@ void format_commit_message(const struct commit *commit,
/* strip empty lines */
while (msg[eol + 1] == '\n')
eol++;
- } else if (!prefixcmp(msg + i, "author "))
- fill_person(table + IAUTHOR_NAME,
- msg + i + 7, eol - i - 7);
- else if (!prefixcmp(msg + i, "committer "))
- fill_person(table + ICOMMITTER_NAME,
- msg + i + 10, eol - i - 10);
- else if (!prefixcmp(msg + i, "encoding "))
- table[IENCODING].value =
- xmemdupz(msg + i + 9, eol - i - 9);
+ } else if (!prefixcmp(msg + i, "author ")) {
+ context->author.off = i + 7;
+ context->author.len = eol - i - 7;
+ } else if (!prefixcmp(msg + i, "committer ")) {
+ context->committer.off = i + 10;
+ context->committer.len = eol - i - 10;
+ } else if (!prefixcmp(msg + i, "encoding ")) {
+ context->encoding.off = i + 9;
+ context->encoding.len = eol - i - 9;
+ }
i = eol;
}
- if (msg[i])
- table[IBODY].value = xstrdup(msg + i);
+ context->body_off = i;
+ context->commit_header_parsed = 1;
+}
+
+static void format_commit_item(struct strbuf *sb, const char *placeholder,
+ void *context)
+{
+ struct format_commit_context *c = context;
+ const struct commit *commit = c->commit;
+ const char *msg = commit->buffer;
+ struct commit_list *p;
+
+ /* these are independent of the commit */
+ switch (placeholder[0]) {
+ case 'C':
+ switch (placeholder[3]) {
+ case 'd': /* red */
+ strbuf_addstr(sb, "\033[31m");
+ return;
+ case 'e': /* green */
+ strbuf_addstr(sb, "\033[32m");
+ return;
+ case 'u': /* blue */
+ strbuf_addstr(sb, "\033[34m");
+ return;
+ case 's': /* reset color */
+ strbuf_addstr(sb, "\033[m");
+ return;
+ }
+ case 'n': /* newline */
+ strbuf_addch(sb, '\n');
+ return;
+ }
- len = interpolate(sb->buf + sb->len, strbuf_avail(sb),
- format, table, ARRAY_SIZE(table));
- if (len > strbuf_avail(sb)) {
- strbuf_grow(sb, len);
- interpolate(sb->buf + sb->len, strbuf_avail(sb) + 1,
- format, table, ARRAY_SIZE(table));
+ /* these depend on the commit */
+ if (!commit->object.parsed)
+ parse_object(commit->object.sha1);
+
+ switch (placeholder[0]) {
+ case 'H': /* commit hash */
+ strbuf_addstr(sb, sha1_to_hex(commit->object.sha1));
+ return;
+ case 'h': /* abbreviated commit hash */
+ if (add_again(sb, &c->abbrev_commit_hash))
+ return;
+ strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1,
+ DEFAULT_ABBREV));
+ c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off;
+ return;
+ case 'T': /* tree hash */
+ strbuf_addstr(sb, sha1_to_hex(commit->tree->object.sha1));
+ return;
+ case 't': /* abbreviated tree hash */
+ if (add_again(sb, &c->abbrev_tree_hash))
+ return;
+ strbuf_addstr(sb, find_unique_abbrev(commit->tree->object.sha1,
+ DEFAULT_ABBREV));
+ c->abbrev_tree_hash.len = sb->len - c->abbrev_tree_hash.off;
+ return;
+ case 'P': /* parent hashes */
+ for (p = commit->parents; p; p = p->next) {
+ if (p != commit->parents)
+ strbuf_addch(sb, ' ');
+ strbuf_addstr(sb, sha1_to_hex(p->item->object.sha1));
+ }
+ return;
+ case 'p': /* abbreviated parent hashes */
+ if (add_again(sb, &c->abbrev_parent_hashes))
+ return;
+ for (p = commit->parents; p; p = p->next) {
+ if (p != commit->parents)
+ strbuf_addch(sb, ' ');
+ strbuf_addstr(sb, find_unique_abbrev(
+ p->item->object.sha1, DEFAULT_ABBREV));
+ }
+ c->abbrev_parent_hashes.len = sb->len -
+ c->abbrev_parent_hashes.off;
+ return;
+ case 'm': /* left/right/bottom */
+ strbuf_addch(sb, (commit->object.flags & BOUNDARY)
+ ? '-'
+ : (commit->object.flags & SYMMETRIC_LEFT)
+ ? '<'
+ : '>');
+ return;
+ }
+
+ /* For the rest we have to parse the commit header. */
+ if (!c->commit_header_parsed)
+ parse_commit_header(c);
+
+ switch (placeholder[0]) {
+ case 's':
+ strbuf_add(sb, msg + c->subject.off, c->subject.len);
+ return;
+ case 'a':
+ format_person_part(sb, placeholder[1],
+ msg + c->author.off, c->author.len);
+ return;
+ case 'c':
+ format_person_part(sb, placeholder[1],
+ msg + c->committer.off, c->committer.len);
+ return;
+ case 'e':
+ strbuf_add(sb, msg + c->encoding.off, c->encoding.len);
+ return;
+ case 'b':
+ strbuf_addstr(sb, msg + c->body_off);
+ return;
}
- strbuf_setlen(sb, sb->len + len);
- interp_clear_table(table, ARRAY_SIZE(table));
+}
+
+void format_commit_message(const struct commit *commit,
+ const void *format, struct strbuf *sb)
+{
+ const char *placeholders[] = {
+ "H", /* commit hash */
+ "h", /* abbreviated commit hash */
+ "T", /* tree hash */
+ "t", /* abbreviated tree hash */
+ "P", /* parent hashes */
+ "p", /* abbreviated parent hashes */
+ "an", /* author name */
+ "ae", /* author email */
+ "ad", /* author date */
+ "aD", /* author date, RFC2822 style */
+ "ar", /* author date, relative */
+ "at", /* author date, UNIX timestamp */
+ "ai", /* author date, ISO 8601 */
+ "cn", /* committer name */
+ "ce", /* committer email */
+ "cd", /* committer date */
+ "cD", /* committer date, RFC2822 style */
+ "cr", /* committer date, relative */
+ "ct", /* committer date, UNIX timestamp */
+ "ci", /* committer date, ISO 8601 */
+ "e", /* encoding */
+ "s", /* subject */
+ "b", /* body */
+ "Cred", /* red */
+ "Cgreen", /* green */
+ "Cblue", /* blue */
+ "Creset", /* reset color */
+ "n", /* newline */
+ "m", /* left/right/bottom */
+ NULL
+ };
+ struct format_commit_context context;
+
+ memset(&context, 0, sizeof(context));
+ context.commit = commit;
+ strbuf_expand(sb, format, placeholders, format_commit_item, &context);
}
static void pp_header(enum cmit_fmt fmt,
diff --git a/progress.c b/progress.c
index 3f6a602a5..d19f80c0b 100644
--- a/progress.c
+++ b/progress.c
@@ -14,12 +14,12 @@
#define TP_IDX_MAX 8
struct throughput {
+ off_t curr_total;
+ off_t prev_total;
struct timeval prev_tv;
- off_t total;
- unsigned long count;
- unsigned long avg_bytes;
- unsigned long last_bytes[TP_IDX_MAX];
+ unsigned int avg_bytes;
unsigned int avg_misecs;
+ unsigned int last_bytes[TP_IDX_MAX];
unsigned int last_misecs[TP_IDX_MAX];
unsigned int idx;
char display[32];
@@ -69,9 +69,9 @@ static void clear_progress_signal(void)
progress_update = 0;
}
-static int display(struct progress *progress, unsigned n, int done)
+static int display(struct progress *progress, unsigned n, const char *done)
{
- char *eol, *tp;
+ const char *eol, *tp;
if (progress->delay) {
if (!progress_update || --progress->delay)
@@ -90,7 +90,7 @@ static int display(struct progress *progress, unsigned n, int done)
progress->last_value = n;
tp = (progress->throughput) ? progress->throughput->display : "";
- eol = done ? ", done. \n" : " \r";
+ eol = done ? done : " \r";
if (progress->total) {
unsigned percent = n * 100 / progress->total;
if (percent != progress->last_percent || progress_update) {
@@ -98,11 +98,13 @@ static int display(struct progress *progress, unsigned n, int done)
fprintf(stderr, "%s: %3u%% (%u/%u)%s%s",
progress->title, percent, n,
progress->total, tp, eol);
+ fflush(stderr);
progress_update = 0;
return 1;
}
} else if (progress_update) {
fprintf(stderr, "%s: %u%s%s", progress->title, n, tp, eol);
+ fflush(stderr);
progress_update = 0;
return 1;
}
@@ -110,7 +112,31 @@ static int display(struct progress *progress, unsigned n, int done)
return 0;
}
-void display_throughput(struct progress *progress, unsigned long n)
+static void throughput_string(struct throughput *tp, off_t total,
+ unsigned int rate)
+{
+ int l = sizeof(tp->display);
+ if (total > 1 << 30) {
+ l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
+ (int)(total >> 30),
+ (int)(total & ((1 << 30) - 1)) / 10737419);
+ } else if (total > 1 << 20) {
+ l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
+ (int)(total >> 20),
+ ((int)(total & ((1 << 20) - 1)) * 100) >> 20);
+ } else if (total > 1 << 10) {
+ l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
+ (int)(total >> 10),
+ ((int)(total & ((1 << 10) - 1)) * 100) >> 10);
+ } else {
+ l -= snprintf(tp->display, l, ", %u bytes", (int)total);
+ }
+ if (rate)
+ snprintf(tp->display + sizeof(tp->display) - l, l,
+ " | %u KiB/s", rate);
+}
+
+void display_throughput(struct progress *progress, off_t total)
{
struct throughput *tp;
struct timeval tv;
@@ -124,13 +150,13 @@ void display_throughput(struct progress *progress, unsigned long n)
if (!tp) {
progress->throughput = tp = calloc(1, sizeof(*tp));
- if (tp)
+ if (tp) {
+ tp->prev_total = tp->curr_total = total;
tp->prev_tv = tv;
+ }
return;
}
-
- tp->total += n;
- tp->count += n;
+ tp->curr_total = total;
/*
* We have x = bytes and y = microsecs. We want z = KiB/s:
@@ -151,47 +177,29 @@ void display_throughput(struct progress *progress, unsigned long n)
misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977;
if (misecs > 512) {
- int l = sizeof(tp->display);
+ unsigned int count, rate;
+
+ count = total - tp->prev_total;
+ tp->prev_total = total;
tp->prev_tv = tv;
- tp->avg_bytes += tp->count;
+ tp->avg_bytes += count;
tp->avg_misecs += misecs;
-
- if (tp->total > 1 << 30) {
- l -= snprintf(tp->display, l, ", %u.%2.2u GiB",
- (int)(tp->total >> 30),
- (int)(tp->total & ((1 << 30) - 1)) / 10737419);
- } else if (tp->total > 1 << 20) {
- l -= snprintf(tp->display, l, ", %u.%2.2u MiB",
- (int)(tp->total >> 20),
- ((int)(tp->total & ((1 << 20) - 1))
- * 100) >> 20);
- } else if (tp->total > 1 << 10) {
- l -= snprintf(tp->display, l, ", %u.%2.2u KiB",
- (int)(tp->total >> 10),
- ((int)(tp->total & ((1 << 10) - 1))
- * 100) >> 10);
- } else {
- l -= snprintf(tp->display, l, ", %u bytes",
- (int)tp->total);
- }
- snprintf(tp->display + sizeof(tp->display) - l, l,
- " | %lu KiB/s", tp->avg_bytes / tp->avg_misecs);
-
+ rate = tp->avg_bytes / tp->avg_misecs;
tp->avg_bytes -= tp->last_bytes[tp->idx];
tp->avg_misecs -= tp->last_misecs[tp->idx];
- tp->last_bytes[tp->idx] = tp->count;
+ tp->last_bytes[tp->idx] = count;
tp->last_misecs[tp->idx] = misecs;
tp->idx = (tp->idx + 1) % TP_IDX_MAX;
- tp->count = 0;
+ throughput_string(tp, total, rate);
if (progress->last_value != -1 && progress_update)
- display(progress, progress->last_value, 0);
+ display(progress, progress->last_value, NULL);
}
}
int display_progress(struct progress *progress, unsigned n)
{
- return progress ? display(progress, n, 0) : 0;
+ return progress ? display(progress, n, NULL) : 0;
}
struct progress *start_progress_delay(const char *title, unsigned total,
@@ -201,6 +209,7 @@ struct progress *start_progress_delay(const char *title, unsigned total,
if (!progress) {
/* unlikely, but here's a good fallback */
fprintf(stderr, "%s...\n", title);
+ fflush(stderr);
return NULL;
}
progress->title = title;
@@ -221,14 +230,27 @@ struct progress *start_progress(const char *title, unsigned total)
void stop_progress(struct progress **p_progress)
{
+ stop_progress_msg(p_progress, "done");
+}
+
+void stop_progress_msg(struct progress **p_progress, const char *msg)
+{
struct progress *progress = *p_progress;
if (!progress)
return;
*p_progress = NULL;
if (progress->last_value != -1) {
/* Force the last update */
+ char buf[strlen(msg) + 5];
+ struct throughput *tp = progress->throughput;
+ if (tp) {
+ unsigned int rate = !tp->avg_misecs ? 0 :
+ tp->avg_bytes / tp->avg_misecs;
+ throughput_string(tp, tp->curr_total, rate);
+ }
progress_update = 1;
- display(progress, progress->last_value, 1);
+ sprintf(buf, ", %s.\n", msg);
+ display(progress, progress->last_value, buf);
}
clear_progress_signal();
free(progress->throughput);
diff --git a/progress.h b/progress.h
index 61cb68dfa..611e4c4d4 100644
--- a/progress.h
+++ b/progress.h
@@ -3,11 +3,12 @@
struct progress;
-void display_throughput(struct progress *progress, unsigned long n);
+void display_throughput(struct progress *progress, off_t total);
int display_progress(struct progress *progress, unsigned n);
struct progress *start_progress(const char *title, unsigned total);
struct progress *start_progress_delay(const char *title, unsigned total,
unsigned percent_treshold, unsigned delay);
void stop_progress(struct progress **progress);
+void stop_progress_msg(struct progress **progress, const char *msg);
#endif
diff --git a/read-cache.c b/read-cache.c
index 056b322fb..7db55883d 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -194,11 +194,12 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
}
int ie_match_stat(struct index_state *istate,
- struct cache_entry *ce, struct stat *st, int options)
+ struct cache_entry *ce, struct stat *st,
+ unsigned int options)
{
unsigned int changed;
- int ignore_valid = options & 01;
- int assume_racy_is_modified = options & 02;
+ int ignore_valid = options & CE_MATCH_IGNORE_VALID;
+ int assume_racy_is_modified = options & CE_MATCH_RACY_IS_DIRTY;
/*
* If it's marked as always valid in the index, it's
@@ -238,10 +239,11 @@ int ie_match_stat(struct index_state *istate,
}
int ie_modified(struct index_state *istate,
- struct cache_entry *ce, struct stat *st, int really)
+ struct cache_entry *ce, struct stat *st, unsigned int options)
{
int changed, changed_fs;
- changed = ie_match_stat(istate, ce, st, really);
+
+ changed = ie_match_stat(istate, ce, st, options);
if (!changed)
return 0;
/*
@@ -387,6 +389,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
int size, namelen, pos;
struct stat st;
struct cache_entry *ce;
+ unsigned ce_option = CE_MATCH_IGNORE_VALID|CE_MATCH_RACY_IS_DIRTY;
if (lstat(path, &st))
die("%s: unable to stat (%s)", path, strerror(errno));
@@ -421,7 +424,7 @@ int add_file_to_index(struct index_state *istate, const char *path, int verbose)
pos = index_name_pos(istate, ce->name, namelen);
if (0 <= pos &&
!ce_stage(istate->cache[pos]) &&
- !ie_modified(istate, istate->cache[pos], &st, 1)) {
+ !ie_match_stat(istate, istate->cache[pos], &st, ce_option)) {
/* Nothing changed, really */
free(ce);
return 0;
@@ -783,11 +786,13 @@ int add_index_entry(struct index_state *istate, struct cache_entry *ce, int opti
* to link up the stat cache details with the proper files.
*/
static struct cache_entry *refresh_cache_ent(struct index_state *istate,
- struct cache_entry *ce, int really, int *err)
+ struct cache_entry *ce,
+ unsigned int options, int *err)
{
struct stat st;
struct cache_entry *updated;
int changed, size;
+ int ignore_valid = options & CE_MATCH_IGNORE_VALID;
if (lstat(ce->name, &st) < 0) {
if (err)
@@ -795,16 +800,23 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
return NULL;
}
- changed = ie_match_stat(istate, ce, &st, really);
+ changed = ie_match_stat(istate, ce, &st, options);
if (!changed) {
- if (really && assume_unchanged &&
+ /*
+ * The path is unchanged. If we were told to ignore
+ * valid bit, then we did the actual stat check and
+ * found that the entry is unmodified. If the entry
+ * is not marked VALID, this is the place to mark it
+ * valid again, under "assume unchanged" mode.
+ */
+ if (ignore_valid && assume_unchanged &&
!(ce->ce_flags & htons(CE_VALID)))
; /* mark this one VALID again */
else
return ce;
}
- if (ie_modified(istate, ce, &st, really)) {
+ if (ie_modified(istate, ce, &st, options)) {
if (err)
*err = EINVAL;
return NULL;
@@ -815,13 +827,14 @@ static struct cache_entry *refresh_cache_ent(struct index_state *istate,
memcpy(updated, ce, size);
fill_stat_cache_info(updated, &st);
- /* In this case, if really is not set, we should leave
- * CE_VALID bit alone. Otherwise, paths marked with
- * --no-assume-unchanged (i.e. things to be edited) will
- * reacquire CE_VALID bit automatically, which is not
- * really what we want.
+ /*
+ * If ignore_valid is not set, we should leave CE_VALID bit
+ * alone. Otherwise, paths marked with --no-assume-unchanged
+ * (i.e. things to be edited) will reacquire CE_VALID bit
+ * automatically, which is not really what we want.
*/
- if (!really && assume_unchanged && !(ce->ce_flags & htons(CE_VALID)))
+ if (!ignore_valid && assume_unchanged &&
+ !(ce->ce_flags & htons(CE_VALID)))
updated->ce_flags &= ~htons(CE_VALID);
return updated;
@@ -835,6 +848,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
int allow_unmerged = (flags & REFRESH_UNMERGED) != 0;
int quiet = (flags & REFRESH_QUIET) != 0;
int not_new = (flags & REFRESH_IGNORE_MISSING) != 0;
+ unsigned int options = really ? CE_MATCH_IGNORE_VALID : 0;
for (i = 0; i < istate->cache_nr; i++) {
struct cache_entry *ce, *new;
@@ -856,7 +870,7 @@ int refresh_index(struct index_state *istate, unsigned int flags, const char **p
if (pathspec && !match_pathspec(pathspec, ce->name, strlen(ce->name), 0, seen))
continue;
- new = refresh_cache_ent(istate, ce, really, &cache_errno);
+ new = refresh_cache_ent(istate, ce, options, &cache_errno);
if (new == ce)
continue;
if (!new) {
diff --git a/refs.c b/refs.c
index 387c588c7..54ec98d15 100644
--- a/refs.c
+++ b/refs.c
@@ -580,18 +580,6 @@ int for_each_remote_ref(each_ref_fn fn, void *cb_data)
return do_for_each_ref("refs/remotes/", fn, 13, cb_data);
}
-/* NEEDSWORK: This is only used by ssh-upload and it should go; the
- * caller should do resolve_ref or read_ref like everybody else. Or
- * maybe everybody else should use get_ref_sha1() instead of doing
- * read_ref().
- */
-int get_ref_sha1(const char *ref, unsigned char *sha1)
-{
- if (check_ref_format(ref))
- return -1;
- return read_ref(mkpath("refs/%s", ref), sha1);
-}
-
/*
* Make sure "ref" is something reasonable to have under ".git/refs/";
* We do not like it if:
diff --git a/refs.h b/refs.h
index 6eb98a4ca..9dc8aa01d 100644
--- a/refs.h
+++ b/refs.h
@@ -26,9 +26,6 @@ extern int for_each_remote_ref(each_ref_fn, void *);
extern int peel_ref(const char *, unsigned char *);
-/** Reads the refs file specified into sha1 **/
-extern int get_ref_sha1(const char *ref, unsigned char *sha1);
-
/** Locks a "refs/" ref returning the lock on success and NULL on failure. **/
extern struct ref_lock *lock_ref_sha1(const char *ref, const unsigned char *old_sha1);
diff --git a/revision.c b/revision.c
index e76da0d44..2a5903519 100644
--- a/revision.c
+++ b/revision.c
@@ -10,6 +10,8 @@
#include "reflog-walk.h"
#include "patch-ids.h"
+volatile show_early_output_fn_t show_early_output;
+
static char *path_name(struct name_path *path, const char *name)
{
struct name_path *p;
@@ -65,10 +67,17 @@ void mark_tree_uninteresting(struct tree *tree)
init_tree_desc(&desc, tree->buffer, tree->size);
while (tree_entry(&desc, &entry)) {
- if (S_ISDIR(entry.mode))
+ switch (object_type(entry.mode)) {
+ case OBJ_TREE:
mark_tree_uninteresting(lookup_tree(entry.sha1));
- else
+ break;
+ case OBJ_BLOB:
mark_blob_uninteresting(lookup_blob(entry.sha1));
+ break;
+ default:
+ /* Subproject commit - not in this repository */
+ break;
+ }
}
/*
@@ -250,7 +259,7 @@ static void file_add_remove(struct diff_options *options,
}
tree_difference = diff;
if (tree_difference == REV_TREE_DIFFERENT)
- options->has_changes = 1;
+ DIFF_OPT_SET(options, HAS_CHANGES);
}
static void file_change(struct diff_options *options,
@@ -260,7 +269,7 @@ static void file_change(struct diff_options *options,
const char *base, const char *path)
{
tree_difference = REV_TREE_DIFFERENT;
- options->has_changes = 1;
+ DIFF_OPT_SET(options, HAS_CHANGES);
}
static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree *t2)
@@ -270,7 +279,7 @@ static int rev_compare_tree(struct rev_info *revs, struct tree *t1, struct tree
if (!t2)
return REV_TREE_DIFFERENT;
tree_difference = REV_TREE_SAME;
- revs->pruning.has_changes = 0;
+ DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES);
if (diff_tree_sha1(t1->object.sha1, t2->object.sha1, "",
&revs->pruning) < 0)
return REV_TREE_DIFFERENT;
@@ -294,7 +303,7 @@ static int rev_same_tree_as_empty(struct rev_info *revs, struct tree *t1)
init_tree_desc(&empty, "", 0);
tree_difference = REV_TREE_SAME;
- revs->pruning.has_changes = 0;
+ DIFF_OPT_CLR(&revs->pruning, HAS_CHANGES);
retval = diff_tree(&empty, &real, "", &revs->pruning);
free(tree);
@@ -306,15 +315,28 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
struct commit_list **pp, *parent;
int tree_changed = 0, tree_same = 0;
+ /*
+ * If we don't do pruning, everything is interesting
+ */
+ if (!revs->prune)
+ return;
+
if (!commit->tree)
return;
if (!commit->parents) {
- if (!rev_same_tree_as_empty(revs, commit->tree))
- commit->object.flags |= TREECHANGE;
+ if (rev_same_tree_as_empty(revs, commit->tree))
+ commit->object.flags |= TREESAME;
return;
}
+ /*
+ * Normal non-merge commit? If we don't want to make the
+ * history dense, we consider it always to be a change..
+ */
+ if (!revs->dense && !commit->parents->next)
+ return;
+
pp = &commit->parents;
while ((parent = *pp) != NULL) {
struct commit *p = parent->item;
@@ -338,6 +360,7 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
}
parent->next = NULL;
commit->parents = parent;
+ commit->object.flags |= TREESAME;
return;
case REV_TREE_NEW:
@@ -366,7 +389,8 @@ static void try_to_simplify_commit(struct rev_info *revs, struct commit *commit)
die("bad tree compare for commit %s", sha1_to_hex(commit->object.sha1));
}
if (tree_changed && !tree_same)
- commit->object.flags |= TREECHANGE;
+ return;
+ commit->object.flags |= TREESAME;
}
static int add_parents_to_list(struct rev_info *revs, struct commit *commit, struct commit_list **list)
@@ -413,8 +437,7 @@ static int add_parents_to_list(struct rev_info *revs, struct commit *commit, str
* simplify the commit history and find the parent
* that has no differences in the path set if one exists.
*/
- if (revs->prune_fn)
- revs->prune_fn(revs, commit);
+ try_to_simplify_commit(revs, commit);
if (revs->no_walk)
return 0;
@@ -533,6 +556,7 @@ static int limit_list(struct rev_info *revs)
struct commit_list *entry = list;
struct commit *commit = list->item;
struct object *obj = &commit->object;
+ show_early_output_fn_t show;
list = list->next;
free(entry);
@@ -550,6 +574,13 @@ static int limit_list(struct rev_info *revs)
if (revs->min_age != -1 && (commit->date > revs->min_age))
continue;
p = &commit_list_insert(commit, p)->next;
+
+ show = show_early_output;
+ if (!show)
+ continue;
+
+ show(revs, newlist);
+ show_early_output = NULL;
}
if (revs->cherry_pick)
cherry_pick_list(newlist, revs);
@@ -662,8 +693,8 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->abbrev = DEFAULT_ABBREV;
revs->ignore_merges = 1;
revs->simplify_history = 1;
- revs->pruning.recursive = 1;
- revs->pruning.quiet = 1;
+ DIFF_OPT_SET(&revs->pruning, RECURSIVE);
+ DIFF_OPT_SET(&revs->pruning, QUIET);
revs->pruning.add_remove = file_add_remove;
revs->pruning.change = file_change;
revs->lifo = 1;
@@ -674,12 +705,6 @@ void init_revisions(struct rev_info *revs, const char *prefix)
revs->skip_count = -1;
revs->max_count = -1;
- revs->prune_fn = NULL;
- revs->prune_data = NULL;
-
- revs->topo_setter = topo_sort_default_setter;
- revs->topo_getter = topo_sort_default_getter;
-
revs->commit_format = CMIT_FMT_DEFAULT;
diff_setup(&revs->diffopt);
@@ -994,6 +1019,18 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->topo_order = 1;
continue;
}
+ if (!prefixcmp(arg, "--early-output")) {
+ int count = 100;
+ switch (arg[14]) {
+ case '=':
+ count = atoi(arg+15);
+ /* Fallthrough */
+ case 0:
+ revs->topo_order = 1;
+ revs->early_output = count;
+ continue;
+ }
+ }
if (!strcmp(arg, "--parents")) {
revs->parents = 1;
continue;
@@ -1054,13 +1091,13 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
}
if (!strcmp(arg, "-r")) {
revs->diff = 1;
- revs->diffopt.recursive = 1;
+ DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
continue;
}
if (!strcmp(arg, "-t")) {
revs->diff = 1;
- revs->diffopt.recursive = 1;
- revs->diffopt.tree_in_recursive = 1;
+ DIFF_OPT_SET(&revs->diffopt, RECURSIVE);
+ DIFF_OPT_SET(&revs->diffopt, TREE_IN_RECURSIVE);
continue;
}
if (!strcmp(arg, "-m")) {
@@ -1242,7 +1279,7 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
revs->diff = 1;
/* Pickaxe and rename following needs diffs */
- if (revs->diffopt.pickaxe || revs->diffopt.follow_renames)
+ if (revs->diffopt.pickaxe || DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
revs->diff = 1;
if (revs->topo_order)
@@ -1251,8 +1288,8 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, const ch
if (revs->prune_data) {
diff_tree_setup_paths(revs->prune_data, &revs->pruning);
/* Can't prune commits with rename following: the paths change.. */
- if (!revs->diffopt.follow_renames)
- revs->prune_fn = try_to_simplify_commit;
+ if (!DIFF_OPT_TST(&revs->diffopt, FOLLOW_RENAMES))
+ revs->prune = 1;
if (!revs->full_diff)
diff_tree_setup_paths(revs->prune_data, &revs->diffopt);
}
@@ -1303,9 +1340,7 @@ int prepare_revision_walk(struct rev_info *revs)
if (limit_list(revs) < 0)
return -1;
if (revs->topo_order)
- sort_in_topological_order_fn(&revs->commits, revs->lifo,
- revs->topo_setter,
- revs->topo_getter);
+ sort_in_topological_order(&revs->commits, revs->lifo);
return 0;
}
@@ -1324,7 +1359,9 @@ static enum rewrite_result rewrite_one(struct rev_info *revs, struct commit **pp
return rewrite_one_error;
if (p->parents && p->parents->next)
return rewrite_one_ok;
- if (p->object.flags & (TREECHANGE | UNINTERESTING))
+ if (p->object.flags & UNINTERESTING)
+ return rewrite_one_ok;
+ if (!(p->object.flags & TREESAME))
return rewrite_one_ok;
if (!p->parents)
return rewrite_one_noparents;
@@ -1381,6 +1418,36 @@ static int commit_match(struct commit *commit, struct rev_info *opt)
commit->buffer, strlen(commit->buffer));
}
+enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit)
+{
+ if (commit->object.flags & SHOWN)
+ return commit_ignore;
+ if (revs->unpacked && has_sha1_pack(commit->object.sha1, revs->ignore_packed))
+ return commit_ignore;
+ if (commit->object.flags & UNINTERESTING)
+ return commit_ignore;
+ if (revs->min_age != -1 && (commit->date > revs->min_age))
+ return commit_ignore;
+ if (revs->no_merges && commit->parents && commit->parents->next)
+ return commit_ignore;
+ if (!commit_match(commit, revs))
+ return commit_ignore;
+ if (revs->prune && revs->dense) {
+ /* Commit without changes? */
+ if (commit->object.flags & TREESAME) {
+ /* drop merges unless we want parenthood */
+ if (!revs->parents)
+ return commit_ignore;
+ /* non-merge - always ignore it */
+ if (!commit->parents || !commit->parents->next)
+ return commit_ignore;
+ }
+ if (revs->parents && rewrite_parents(revs, commit) < 0)
+ return commit_error;
+ }
+ return commit_show;
+}
+
static struct commit *get_revision_1(struct rev_info *revs)
{
if (!revs->commits)
@@ -1408,36 +1475,15 @@ static struct commit *get_revision_1(struct rev_info *revs)
if (add_parents_to_list(revs, commit, &revs->commits) < 0)
return NULL;
}
- if (commit->object.flags & SHOWN)
- continue;
- if (revs->unpacked && has_sha1_pack(commit->object.sha1,
- revs->ignore_packed))
- continue;
-
- if (commit->object.flags & UNINTERESTING)
+ switch (simplify_commit(revs, commit)) {
+ case commit_ignore:
continue;
- if (revs->min_age != -1 && (commit->date > revs->min_age))
- continue;
- if (revs->no_merges &&
- commit->parents && commit->parents->next)
- continue;
- if (!commit_match(commit, revs))
- continue;
- if (revs->prune_fn && revs->dense) {
- /* Commit without changes? */
- if (!(commit->object.flags & TREECHANGE)) {
- /* drop merges unless we want parenthood */
- if (!revs->parents)
- continue;
- /* non-merge - always ignore it */
- if (!commit->parents || !commit->parents->next)
- continue;
- }
- if (revs->parents && rewrite_parents(revs, commit) < 0)
- return NULL;
+ case commit_error:
+ return NULL;
+ default:
+ return commit;
}
- return commit;
} while (revs->commits);
return NULL;
}
diff --git a/revision.h b/revision.h
index 98a0a8f3f..992e1e9dd 100644
--- a/revision.h
+++ b/revision.h
@@ -3,19 +3,18 @@
#define SEEN (1u<<0)
#define UNINTERESTING (1u<<1)
-#define TREECHANGE (1u<<2)
+#define TREESAME (1u<<2)
#define SHOWN (1u<<3)
#define TMP_MARK (1u<<4) /* for isolated cases; clean after use */
#define BOUNDARY (1u<<5)
#define CHILD_SHOWN (1u<<6)
#define ADDED (1u<<7) /* Parents already parsed and added? */
#define SYMMETRIC_LEFT (1u<<8)
+#define TOPOSORT (1u<<9) /* In the active toposort list.. */
struct rev_info;
struct log_info;
-typedef void (prune_fn_t)(struct rev_info *revs, struct commit *commit);
-
struct rev_info {
/* Starting list */
struct commit_list *commits;
@@ -27,10 +26,11 @@ struct rev_info {
/* Basic information */
const char *prefix;
void *prune_data;
- prune_fn_t *prune_fn;
+ unsigned int early_output;
/* Traversal flags */
unsigned int dense:1,
+ prune:1,
no_merges:1,
no_walk:1,
remove_empty_trees:1,
@@ -96,9 +96,6 @@ struct rev_info {
struct diff_options diffopt;
struct diff_options pruning;
- topo_sort_set_fn_t topo_setter;
- topo_sort_get_fn_t topo_getter;
-
struct reflog_walk_info *reflog_info;
};
@@ -107,6 +104,8 @@ struct rev_info {
#define REV_TREE_DIFFERENT 2
/* revision.c */
+typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *);
+volatile show_early_output_fn_t show_early_output;
extern void init_revisions(struct rev_info *revs, const char *prefix);
extern int setup_revisions(int argc, const char **argv, struct rev_info *revs, const char *def);
@@ -131,4 +130,12 @@ extern void add_object(struct object *obj,
extern void add_pending_object(struct rev_info *revs, struct object *obj, const char *name);
+enum commit_action {
+ commit_ignore,
+ commit_show,
+ commit_error
+};
+
+extern enum commit_action simplify_commit(struct rev_info *revs, struct commit *commit);
+
#endif
diff --git a/run-command.c b/run-command.c
index d99a6c4ea..476d00c21 100644
--- a/run-command.c
+++ b/run-command.c
@@ -41,7 +41,7 @@ int start_command(struct child_process *cmd)
cmd->close_out = 1;
}
- need_err = cmd->err < 0;
+ need_err = !cmd->no_stderr && cmd->err < 0;
if (need_err) {
if (pipe(fderr) < 0) {
if (need_in)
@@ -87,7 +87,9 @@ int start_command(struct child_process *cmd)
close(cmd->out);
}
- if (need_err) {
+ if (cmd->no_stderr)
+ dup_devnull(2);
+ else if (need_err) {
dup2(fderr[1], 2);
close_pair(fderr);
}
diff --git a/run-command.h b/run-command.h
index 94e1e9d51..1fc781d76 100644
--- a/run-command.h
+++ b/run-command.h
@@ -23,6 +23,7 @@ struct child_process {
unsigned close_out:1;
unsigned no_stdin:1;
unsigned no_stdout:1;
+ unsigned no_stderr:1;
unsigned git_cmd:1; /* if this is to be git sub-command */
unsigned stdout_to_stderr:1;
};
diff --git a/sha1_file.c b/sha1_file.c
index f007874cb..560c0e0d0 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -86,7 +86,7 @@ int safe_create_leading_directories(char *path)
char *pos = path;
struct stat st;
- if (*pos == '/')
+ if (is_absolute_path(path))
pos++;
while (pos) {
@@ -253,7 +253,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
int entlen = pfxlen + 43;
int base_len = -1;
- if (*entry != '/' && relative_base) {
+ if (!is_absolute_path(entry) && relative_base) {
/* Relative alt-odb */
if (base_len < 0)
base_len = strlen(relative_base) + 1;
@@ -262,7 +262,7 @@ static int link_alt_odb_entry(const char * entry, int len, const char * relative
}
ent = xmalloc(sizeof(*ent) + entlen);
- if (*entry != '/' && relative_base) {
+ if (!is_absolute_path(entry) && relative_base) {
memcpy(ent->base, relative_base, base_len - 1);
ent->base[base_len - 1] = '/';
memcpy(ent->base + base_len, entry, len);
@@ -333,7 +333,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep,
while (cp < ep && *cp != sep)
cp++;
if (last != cp) {
- if ((*last != '/') && depth) {
+ if (!is_absolute_path(last) && depth) {
error("%s: ignoring relative alternate object store %s",
relative_base, last);
} else {
diff --git a/sideband.c b/sideband.c
index ab8a1e990..756bbc28d 100644
--- a/sideband.c
+++ b/sideband.c
@@ -11,13 +11,19 @@
* stream, aka "verbose"). A message over band #3 is a signal that
* the remote died unexpectedly. A flush() concludes the stream.
*/
+
+#define PREFIX "remote:"
+#define SUFFIX "\033[K" /* change to " " if ANSI sequences don't work */
+
int recv_sideband(const char *me, int in_stream, int out, int err)
{
- char buf[7 + LARGE_PACKET_MAX + 1];
- strcpy(buf, "remote:");
+ unsigned pf = strlen(PREFIX);
+ unsigned sf = strlen(SUFFIX);
+ char buf[pf + LARGE_PACKET_MAX + sf + 1];
+ memcpy(buf, PREFIX, pf);
while (1) {
int band, len;
- len = packet_read_line(in_stream, buf+7, LARGE_PACKET_MAX);
+ len = packet_read_line(in_stream, buf + pf, LARGE_PACKET_MAX);
if (len == 0)
break;
if (len < 1) {
@@ -25,35 +31,52 @@ int recv_sideband(const char *me, int in_stream, int out, int err)
safe_write(err, buf, len);
return SIDEBAND_PROTOCOL_ERROR;
}
- band = buf[7] & 0xff;
+ band = buf[pf] & 0xff;
len--;
switch (band) {
case 3:
- buf[7] = ' ';
- buf[8+len] = '\n';
- safe_write(err, buf, 8+len+1);
+ buf[pf] = ' ';
+ buf[pf+1+len] = '\n';
+ safe_write(err, buf, pf+1+len+1);
return SIDEBAND_REMOTE_ERROR;
case 2:
- buf[7] = ' ';
- len += 8;
+ buf[pf] = ' ';
+ len += pf+1;
while (1) {
- int brk = 8;
+ int brk = pf+1;
+
+ /* Break the buffer into separate lines. */
while (brk < len) {
brk++;
if (buf[brk-1] == '\n' ||
buf[brk-1] == '\r')
break;
}
- safe_write(err, buf, brk);
+
+ /*
+ * Let's insert a suffix to clear the end
+ * of the screen line, but only if current
+ * line data actually contains something.
+ */
+ if (brk > pf+1 + 1) {
+ char save[sf];
+ memcpy(save, buf + brk, sf);
+ buf[brk + sf - 1] = buf[brk - 1];
+ memcpy(buf + brk - 1, SUFFIX, sf);
+ safe_write(err, buf, brk + sf);
+ memcpy(buf + brk, save, sf);
+ } else
+ safe_write(err, buf, brk);
+
if (brk < len) {
- memmove(buf + 8, buf + brk, len - brk);
- len = len - brk + 8;
+ memmove(buf + pf+1, buf + brk, len - brk);
+ len = len - brk + pf+1;
} else
break;
}
continue;
case 1:
- safe_write(out, buf+8, len);
+ safe_write(out, buf + pf+1, len);
continue;
default:
len = sprintf(buf,
diff --git a/strbuf.c b/strbuf.c
index cbada946c..b9b194b32 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -106,6 +106,13 @@ void strbuf_add(struct strbuf *sb, const void *data, size_t len)
strbuf_setlen(sb, sb->len + len);
}
+void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
+{
+ strbuf_grow(sb, len);
+ memcpy(sb->buf + sb->len, sb->buf + pos, len);
+ strbuf_setlen(sb, sb->len + len);
+}
+
void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
{
int len;
@@ -130,6 +137,30 @@ void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
strbuf_setlen(sb, sb->len + len);
}
+void strbuf_expand(struct strbuf *sb, const char *format,
+ const char **placeholders, expand_fn_t fn, void *context)
+{
+ for (;;) {
+ const char *percent, **p;
+
+ percent = strchrnul(format, '%');
+ strbuf_add(sb, format, percent - format);
+ if (!*percent)
+ break;
+ format = percent + 1;
+
+ for (p = placeholders; *p; p++) {
+ if (!prefixcmp(format, *p))
+ break;
+ }
+ if (*p) {
+ fn(sb, *p, context);
+ format += strlen(*p);
+ } else
+ strbuf_addch(sb, '%');
+ }
+}
+
size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f)
{
size_t res;
diff --git a/strbuf.h b/strbuf.h
index cd7f295b6..13919123d 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -101,6 +101,10 @@ static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
static inline void strbuf_addbuf(struct strbuf *sb, struct strbuf *sb2) {
strbuf_add(sb, sb2->buf, sb2->len);
}
+extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
+
+typedef void (*expand_fn_t) (struct strbuf *sb, const char *placeholder, void *context);
+extern void strbuf_expand(struct strbuf *sb, const char *format, const char **placeholders, expand_fn_t fn, void *context);
__attribute__((format(printf,2,3)))
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
diff --git a/t/t2008-checkout-subdir.sh b/t/t2008-checkout-subdir.sh
new file mode 100755
index 000000000..f78945ed8
--- /dev/null
+++ b/t/t2008-checkout-subdir.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 David Symonds
+
+test_description='git checkout from subdirectories'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ echo "base" > file0 &&
+ git add file0 &&
+ mkdir dir1 &&
+ echo "hello" > dir1/file1 &&
+ git add dir1/file1 &&
+ mkdir dir2 &&
+ echo "bonjour" > dir2/file2 &&
+ git add dir2/file2 &&
+ test_tick &&
+ git commit -m "populate tree"
+
+'
+
+test_expect_success 'remove and restore with relative path' '
+
+ (
+ cd dir1 &&
+ rm ../file0 &&
+ git checkout HEAD -- ../file0 &&
+ test "base" = "$(cat ../file0)" &&
+ rm ../dir2/file2 &&
+ git checkout HEAD -- ../dir2/file2 &&
+ test "bonjour" = "$(cat ../dir2/file2)" &&
+ rm ../file0 ./file1 &&
+ git checkout HEAD -- .. &&
+ test "base" = "$(cat ../file0)" &&
+ test "hello" = "$(cat file1)"
+ )
+
+'
+
+test_expect_success 'checkout with empty prefix' '
+
+ rm file0 &&
+ git checkout HEAD -- file0 &&
+ test "base" = "$(cat file0)"
+
+'
+
+test_expect_success 'checkout with simple prefix' '
+
+ rm dir1/file1 &&
+ git checkout HEAD -- dir1 &&
+ test "hello" = "$(cat dir1/file1)" &&
+ rm dir1/file1 &&
+ git checkout HEAD -- dir1/file1 &&
+ test "hello" = "$(cat dir1/file1)"
+
+'
+
+# This is not expected to work as ls-files was not designed
+# to deal with such. Enable it when ls-files is updated.
+: test_expect_success 'checkout with complex relative path' '
+
+ rm file1 &&
+ git checkout HEAD -- ../dir1/../dir1/file1 && test -f ./file1
+
+'
+
+test_expect_failure 'relative path outside tree should fail' \
+ 'git checkout HEAD -- ../../Makefile'
+
+test_expect_failure 'incorrect relative path to file should fail (1)' \
+ 'git checkout HEAD -- ../file0'
+
+test_expect_failure 'incorrect relative path should fail (2)' \
+ '( cd dir1 && git checkout HEAD -- ./file0 )'
+
+test_expect_failure 'incorrect relative path should fail (3)' \
+ '( cd dir1 && git checkout HEAD -- ../../file0 )'
+
+test_done
diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh
index eb1ced3c3..24f892f79 100755
--- a/t/t2200-add-update.sh
+++ b/t/t2200-add-update.sh
@@ -1,6 +1,6 @@
#!/bin/sh
-test_description='git add -u with path limiting
+test_description='git add -u
This test creates a working tree state with three files:
@@ -9,7 +9,10 @@ This test creates a working tree state with three files:
dir/other (untracked)
and issues a git add -u with path limiting on "dir" to add
-only the updates to dir/sub.'
+only the updates to dir/sub.
+
+Also tested are "git add -u" without limiting, and "git add -u"
+without contents changes.'
. ./test-lib.sh
@@ -85,4 +88,27 @@ test_expect_success 'replace a file with a symlink' '
'
+test_expect_success 'add everything changed' '
+
+ git add -u &&
+ test -z "$(git diff-files)"
+
+'
+
+test_expect_success 'touch and then add -u' '
+
+ touch check &&
+ git add -u &&
+ test -z "$(git diff-files)"
+
+'
+
+test_expect_success 'touch and then add explicitly' '
+
+ touch check &&
+ git add check &&
+ test -z "$(git diff-files)"
+
+'
+
test_done
diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh
index 0779aaa9a..7b7d07269 100755
--- a/t/t3402-rebase-merge.sh
+++ b/t/t3402-rebase-merge.sh
@@ -48,9 +48,14 @@ test_expect_success 'reference merge' '
git merge -s recursive "reference merge" HEAD master
'
+PRE_REBASE=$(git rev-parse test-rebase)
test_expect_success rebase '
git checkout test-rebase &&
- git rebase --merge master
+ GIT_TRACE=1 git rebase --merge master
+'
+
+test_expect_success 'test-rebase@{1} is pre rebase' '
+ test $PRE_REBASE = $(git rev-parse test-rebase@{1})
'
test_expect_success 'merge and rebase should match' '
diff --git a/t/t3403-rebase-skip.sh b/t/t3403-rebase-skip.sh
index eab053c3e..657f68104 100755
--- a/t/t3403-rebase-skip.sh
+++ b/t/t3403-rebase-skip.sh
@@ -36,21 +36,36 @@ test_expect_failure 'rebase with git am -3 (default)' '
'
test_expect_success 'rebase --skip with am -3' '
- git reset --hard HEAD &&
git rebase --skip
'
+
+test_expect_success 'rebase moves back to skip-reference' '
+ test refs/heads/skip-reference = $(git symbolic-ref HEAD) &&
+ git branch post-rebase &&
+ git reset --hard pre-rebase &&
+ ! git rebase master &&
+ echo "hello" > hello &&
+ git add hello &&
+ git rebase --continue &&
+ test refs/heads/skip-reference = $(git symbolic-ref HEAD) &&
+ git reset --hard post-rebase
+'
+
test_expect_success 'checkout skip-merge' 'git checkout -f skip-merge'
test_expect_failure 'rebase with --merge' 'git rebase --merge master'
test_expect_success 'rebase --skip with --merge' '
- git reset --hard HEAD &&
git rebase --skip
'
test_expect_success 'merge and reference trees equal' \
'test -z "`git diff-tree skip-merge skip-reference`"'
+test_expect_success 'moved back to branch correctly' '
+ test refs/heads/skip-merge = $(git symbolic-ref HEAD)
+'
+
test_debug 'gitk --all & sleep 1'
test_done
diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh
index 11139048f..907c7f9f6 100755
--- a/t/t3404-rebase-interactive.sh
+++ b/t/t3404-rebase-interactive.sh
@@ -149,7 +149,8 @@ test_expect_success 'stop on conflicting pick' '
diff -u expect .git/.dotest-merge/patch &&
diff -u expect2 file1 &&
test 4 = $(grep -v "^#" < .git/.dotest-merge/done | wc -l) &&
- test 0 = $(grep -v "^#" < .git/.dotest-merge/todo | wc -l)
+ test 0 = $(grep -ve "^#" -e "^$" < .git/.dotest-merge/git-rebase-todo |
+ wc -l)
'
test_expect_success 'abort' '
diff --git a/t/t3700-add.sh b/t/t3700-add.sh
index a328bf57e..287e058e3 100755
--- a/t/t3700-add.sh
+++ b/t/t3700-add.sh
@@ -104,9 +104,33 @@ test_expect_success 'add ignored ones with -f' '
git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
'
+test_expect_success 'add ignored ones with -f' '
+ rm -f .git/index &&
+ git add -f d.?? &&
+ git ls-files --error-unmatch d.ig/d.if d.ig/d.ig
+'
+
+test_expect_success '.gitignore with subdirectory' '
+
+ rm -f .git/index &&
+ mkdir -p sub/dir &&
+ echo "!dir/a.*" >sub/.gitignore &&
+ >sub/a.ig &&
+ >sub/dir/a.ig &&
+ git add sub/dir &&
+ git ls-files --error-unmatch sub/dir/a.ig &&
+ rm -f .git/index &&
+ (
+ cd sub/dir &&
+ git add .
+ ) &&
+ git ls-files --error-unmatch sub/dir/a.ig
+'
+
mkdir 1 1/2 1/3
touch 1/2/a 1/3/b 1/2/c
test_expect_success 'check correct prefix detection' '
+ rm -f .git/index &&
git add 1/2/a 1/3/b 1/2/c
'
diff --git a/t/t3902-quoted.sh b/t/t3902-quoted.sh
index 245fb3bab..73da45f18 100755
--- a/t/t3902-quoted.sh
+++ b/t/t3902-quoted.sh
@@ -20,6 +20,13 @@ LF='
'
DQ='"'
+echo foo > "Name and an${HT}HT"
+test -f "Name and an${HT}HT" || {
+ # since FAT/NTFS does not allow tabs in filenames, skip this test
+ say 'Your filesystem does not allow tabs in filenames, test skipped.'
+ test_done
+}
+
for_each_name () {
for name in \
Name "Name and a${LF}LF" "Name and an${HT}HT" "Name${DQ}" \
diff --git a/t/t4018-diff-funcname.sh b/t/t4018-diff-funcname.sh
index f9db81d3a..f9db81d3a 100644..100755
--- a/t/t4018-diff-funcname.sh
+++ b/t/t4018-diff-funcname.sh
diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh
new file mode 100755
index 000000000..43d64bbd8
--- /dev/null
+++ b/t/t4021-format-patch-numbered.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Brian C Gernhardt
+#
+
+test_description='Format-patch numbering options'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ echo A > file &&
+ git add file &&
+ git commit -m First &&
+
+ echo B >> file &&
+ git commit -a -m Second &&
+
+ echo C >> file &&
+ git commit -a -m Third
+
+'
+
+# Each of these gets used multiple times.
+
+test_num_no_numbered() {
+ cnt=$(grep "^Subject: \[PATCH\]" $1 | wc -l) &&
+ test $cnt = $2
+}
+
+test_single_no_numbered() {
+ test_num_no_numbered $1 1
+}
+
+test_no_numbered() {
+ test_num_no_numbered $1 2
+}
+
+test_single_numbered() {
+ grep "^Subject: \[PATCH 1/1\]" $1
+}
+
+test_numbered() {
+ grep "^Subject: \[PATCH 1/2\]" $1 &&
+ grep "^Subject: \[PATCH 2/2\]" $1
+}
+
+test_expect_success 'Default: no numbered' '
+
+ git format-patch --stdout HEAD~2 >patch0 &&
+ test_no_numbered patch0
+
+'
+
+test_expect_success 'Use --numbered' '
+
+ git format-patch --numbered --stdout HEAD~2 >patch1 &&
+ test_numbered patch1
+
+'
+
+test_expect_success 'format.numbered = true' '
+
+ git config format.numbered true &&
+ git format-patch --stdout HEAD~2 >patch2 &&
+ test_numbered patch2
+
+'
+
+test_expect_success 'format.numbered && single patch' '
+
+ git format-patch --stdout HEAD^ > patch3 &&
+ test_single_numbered patch3
+
+'
+
+test_expect_success 'format.numbered && --no-numbered' '
+
+ git format-patch --no-numbered --stdout HEAD~2 >patch4 &&
+ test_no_numbered patch4
+
+'
+
+test_expect_success 'format.numbered = auto' '
+
+ git config format.numbered auto
+ git format-patch --stdout HEAD~2 > patch5 &&
+ test_numbered patch5
+
+'
+
+test_expect_success 'format.numbered = auto && single patch' '
+
+ git format-patch --stdout HEAD^ > patch6 &&
+ test_single_no_numbered patch6
+
+'
+
+test_expect_success 'format.numbered = auto && --no-numbered' '
+
+ git format-patch --no-numbered --stdout HEAD~2 > patch7 &&
+ test_no_numbered patch7
+
+'
+
+test_done
diff --git a/t/t4022-diff-rewrite.sh b/t/t4022-diff-rewrite.sh
new file mode 100755
index 000000000..6de4acbd4
--- /dev/null
+++ b/t/t4022-diff-rewrite.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+test_description='rewrite diff'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+ cat ../../COPYING >test &&
+ git add test &&
+ tr 'a-zA-Z' 'n-za-mN-ZA-M' <../../COPYING >test
+
+'
+
+test_expect_success 'detect rewrite' '
+
+ actual=$(git diff-files -B --summary test) &&
+ expr "$actual" : " rewrite test ([0-9]*%)$" || {
+ echo "Eh? <<$actual>>"
+ false
+ }
+
+'
+
+test_done
+
diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh
index ba7579c25..f1106e654 100755
--- a/t/t5300-pack-object.sh
+++ b/t/t5300-pack-object.sh
@@ -187,49 +187,51 @@ test_expect_success \
test-3-${packname_3}.idx'
test_expect_success \
- 'corrupt a pack and see if verify catches' \
+ 'verify-pack catches mismatched .idx and .pack files' \
'cat test-1-${packname_1}.idx >test-3.idx &&
cat test-2-${packname_2}.pack >test-3.pack &&
if git verify-pack test-3.idx
then false
else :;
- fi &&
+ fi'
- : PACK_SIGNATURE &&
- cat test-1-${packname_1}.pack >test-3.pack &&
+test_expect_success \
+ 'verify-pack catches a corrupted pack signature' \
+ 'cat test-1-${packname_1}.pack >test-3.pack &&
dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=2 &&
if git verify-pack test-3.idx
then false
else :;
- fi &&
+ fi'
- : PACK_VERSION &&
- cat test-1-${packname_1}.pack >test-3.pack &&
+test_expect_success \
+ 'verify-pack catches a corrupted pack version' \
+ 'cat test-1-${packname_1}.pack >test-3.pack &&
dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=7 &&
if git verify-pack test-3.idx
then false
else :;
- fi &&
+ fi'
- : TYPE/SIZE byte of the first packed object data &&
- cat test-1-${packname_1}.pack >test-3.pack &&
+test_expect_success \
+ 'verify-pack catches a corrupted type/size of the 1st packed object data' \
+ 'cat test-1-${packname_1}.pack >test-3.pack &&
dd if=/dev/zero of=test-3.pack count=1 bs=1 conv=notrunc seek=12 &&
if git verify-pack test-3.idx
then false
else :;
- fi &&
+ fi'
- : sum of the index file itself &&
- l=`wc -c <test-3.idx` &&
+test_expect_success \
+ 'verify-pack catches a corrupted sum of the index file itself' \
+ 'l=`wc -c <test-3.idx` &&
l=`expr $l - 20` &&
cat test-1-${packname_1}.pack >test-3.pack &&
dd if=/dev/zero of=test-3.idx count=20 bs=1 conv=notrunc seek=$l &&
if git verify-pack test-3.pack
then false
else :;
- fi &&
-
- :'
+ fi'
test_expect_success \
'build pack index for an existing pack' \
diff --git a/t/t5302-pack-index.sh b/t/t5302-pack-index.sh
index 4f58c4c3f..2a2878b57 100755
--- a/t/t5302-pack-index.sh
+++ b/t/t5302-pack-index.sh
@@ -61,17 +61,33 @@ test_expect_success \
test_expect_success \
'index v2: force some 64-bit offsets with pack-objects' \
- 'pack3=$(git pack-objects --index-version=2,0x40000 test-3 <obj-list) &&
- git verify-pack -v "test-3-${pack3}.pack"'
+ 'pack3=$(git pack-objects --index-version=2,0x40000 test-3 <obj-list)'
+
+have_64bits=
+if msg=$(git verify-pack -v "test-3-${pack3}.pack" 2>&1) ||
+ ! echo "$msg" | grep "pack too large .* off_t"
+then
+ have_64bits=t
+else
+ say "skipping tests concerning 64-bit offsets"
+fi
+
+test "$have_64bits" &&
+test_expect_success \
+ 'index v2: verify a pack with some 64-bit offsets' \
+ 'git verify-pack -v "test-3-${pack3}.pack"'
+test "$have_64bits" &&
test_expect_failure \
'64-bit offsets: should be different from previous index v2 results' \
'cmp "test-2-${pack2}.idx" "test-3-${pack3}.idx"'
+test "$have_64bits" &&
test_expect_success \
'index v2: force some 64-bit offsets with index-pack' \
'git-index-pack --index-version=2,0x40000 -o 3.idx "test-1-${pack1}.pack"'
+test "$have_64bits" &&
test_expect_success \
'64-bit offsets: index-pack result should match pack-objects one' \
'cmp "test-3-${pack3}.idx" "3.idx"'
@@ -116,11 +132,11 @@ test_expect_failure \
test_expect_success \
'[index v2] 1) stream pack to repository' \
'rm -f .git/objects/pack/* &&
- git-index-pack --index-version=2,0x40000 --stdin < "test-1-${pack1}.pack" &&
+ git-index-pack --index-version=2 --stdin < "test-1-${pack1}.pack" &&
git prune-packed &&
git count-objects | ( read nr rest && test "$nr" -eq 1 ) &&
cmp "test-1-${pack1}.pack" ".git/objects/pack/pack-${pack1}.pack" &&
- cmp "test-3-${pack1}.idx" ".git/objects/pack/pack-${pack1}.idx"'
+ cmp "test-2-${pack1}.idx" ".git/objects/pack/pack-${pack1}.idx"'
test_expect_success \
'[index v2] 2) create a stealth corruption in a delta base reference' \
diff --git a/t/t5502-quickfetch.sh b/t/t5502-quickfetch.sh
index b4760f2dc..16eadd6b6 100755
--- a/t/t5502-quickfetch.sh
+++ b/t/t5502-quickfetch.sh
@@ -86,4 +86,37 @@ test_expect_success 'quickfetch should not leave a corrupted repository' '
'
+test_expect_success 'quickfetch should not copy from alternate' '
+
+ (
+ mkdir quickclone &&
+ cd quickclone &&
+ git init-db &&
+ (cd ../.git/objects && pwd) >.git/objects/info/alternates &&
+ git remote add origin .. &&
+ git fetch -k -k
+ ) &&
+ obj_cnt=$( (
+ cd quickclone &&
+ git count-objects | sed -e "s/ *objects,.*//"
+ ) ) &&
+ pck_cnt=$( (
+ cd quickclone &&
+ git count-objects -v | sed -n -e "/packs:/{
+ s/packs://
+ p
+ q
+ }"
+ ) ) &&
+ origin_master=$( (
+ cd quickclone &&
+ git rev-parse origin/master
+ ) ) &&
+ echo "loose objects: $obj_cnt, packfiles: $pck_cnt" &&
+ test $obj_cnt -eq 0 &&
+ test $pck_cnt -eq 0 &&
+ test z$origin_master = z$(git rev-parse master)
+
+'
+
test_done
diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh
index aad863db7..35889c0a1 100755
--- a/t/t5510-fetch.sh
+++ b/t/t5510-fetch.sh
@@ -215,4 +215,17 @@ test_expect_success 'quoting of a strangely named repo' '
grep "fatal: '\''a\\\\!'\''b'\''" result
'
+test_expect_success 'bundle should record HEAD correctly' '
+
+ cd "$D" &&
+ git bundle create bundle5 HEAD master &&
+ git bundle list-heads bundle5 >actual &&
+ for h in HEAD refs/heads/master
+ do
+ echo "$(git rev-parse --verify $h) $h"
+ done >expect &&
+ diff -u expect actual
+
+'
+
test_done
diff --git a/t/t6008-rev-list-submodule.sh b/t/t6008-rev-list-submodule.sh
new file mode 100755
index 000000000..88e96fb91
--- /dev/null
+++ b/t/t6008-rev-list-submodule.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Johannes E. Schindelin
+#
+
+test_description='git rev-list involving submodules that this repo has'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+ : > file &&
+ git add file &&
+ test_tick &&
+ git commit -m initial &&
+ echo 1 > file &&
+ test_tick &&
+ git commit -m second file &&
+ echo 2 > file &&
+ test_tick &&
+ git commit -m third file &&
+
+ rm .git/index &&
+
+ : > super-file &&
+ git add super-file &&
+ git submodule add . sub &&
+ git symbolic-ref HEAD refs/heads/super &&
+ test_tick &&
+ git commit -m super-initial &&
+ echo 1 > super-file &&
+ test_tick &&
+ git commit -m super-first super-file &&
+ echo 2 > super-file &&
+ test_tick &&
+ git commit -m super-second super-file
+'
+
+test_expect_success "Ilari's test" '
+ git rev-list --objects super master ^super^
+'
+
+test_done
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 53956c08e..2ba4b00e5 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -71,6 +71,43 @@ test_expect_success 'bisect start with one bad and good' '
git bisect next
'
+test_expect_success 'bisect reset: back in the master branch' '
+ git bisect reset &&
+ echo "* master" > branch.expect &&
+ git branch > branch.output &&
+ cmp branch.expect branch.output
+'
+
+test_expect_success 'bisect reset: back in another branch' '
+ git checkout -b other &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH3 &&
+ git bisect reset &&
+ echo " master" > branch.expect &&
+ echo "* other" >> branch.expect &&
+ git branch > branch.output &&
+ cmp branch.expect branch.output
+'
+
+test_expect_success 'bisect reset when not bisecting' '
+ git bisect reset &&
+ git branch > branch.output &&
+ cmp branch.expect branch.output
+'
+
+test_expect_success 'bisect reset removes packed refs' '
+ git bisect reset &&
+ git bisect start &&
+ git bisect good $HASH1 &&
+ git bisect bad $HASH3 &&
+ git pack-refs --all --prune &&
+ git bisect next &&
+ git bisect reset &&
+ test -z "$(git for-each-ref "refs/bisect/*")" &&
+ test -z "$(git for-each-ref "refs/heads/bisect")"
+'
+
# $HASH1 is good, $HASH4 is bad, we skip $HASH3
# but $HASH2 is bad,
# so we should find $HASH2 as the first bad commit
@@ -167,7 +204,7 @@ test_expect_success 'bisect skip: add line and then a new test' '
git bisect skip &&
git bisect good > my_bisect_log.txt &&
grep "$HASH5 is first bad commit" my_bisect_log.txt &&
- git bisect log > log_to_replay.txt
+ git bisect log > log_to_replay.txt &&
git bisect reset
'
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 0d07bc39c..5f7e388d7 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1004,4 +1004,30 @@ test_expect_failure \
'verify signed tag fails when public key is not present' \
'git-tag -v signed-tag'
+test_expect_failure \
+ 'git-tag -a fails if tag annotation is empty' '
+ GIT_EDITOR=cat git tag -a initial-comment
+'
+
+test_expect_success \
+ 'message in editor has initial comment' '
+ GIT_EDITOR=cat git tag -a initial-comment > actual
+ # check the first line --- should be empty
+ first=$(sed -e 1q <actual) &&
+ test -z "$first" &&
+ # remove commented lines from the remainder -- should be empty
+ rest=$(sed -e 1d -e '/^#/d' <actual) &&
+ test -z "$rest"
+'
+
+get_tag_header reuse $commit commit $time >expect
+echo "An annotation to be reused" >> expect
+test_expect_success \
+ 'overwriting an annoted tag should use its previous body' '
+ git tag -a -m "An annotation to be reused" reuse &&
+ GIT_EDITOR=true git tag -f -a reuse &&
+ get_tag_msg reuse >actual &&
+ git diff expect actual
+'
+
test_done
diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh
index 01cc0c02b..44228b5ac 100755
--- a/t/t7005-editor.sh
+++ b/t/t7005-editor.sh
@@ -15,7 +15,6 @@ do
done
unset vi
mv e-vi.sh vi
-PATH=".:$PATH"
unset EDITOR VISUAL GIT_EDITOR
test_expect_success setup '
@@ -61,7 +60,7 @@ do
;;
esac
test_expect_success "Using $i" '
- git commit --amend &&
+ git --exec-path=. commit --amend &&
git show -s --pretty=oneline |
sed -e "s/^[0-9a-f]* //" >actual &&
diff actual expect
@@ -83,7 +82,7 @@ do
;;
esac
test_expect_success "Using $i (override)" '
- git commit --amend &&
+ git --exec-path=. commit --amend &&
git show -s --pretty=oneline |
sed -e "s/^[0-9a-f]* //" >actual &&
diff actual expect
diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh
index 25d3102de..f013c176e 100755
--- a/t/t7300-clean.sh
+++ b/t/t7300-clean.sh
@@ -291,4 +291,15 @@ test_expect_success 'clean.requireForce and -f' '
'
+test_expect_success 'core.excludesfile' '
+
+ echo excludes >excludes &&
+ echo included >included &&
+ git config core.excludesfile excludes &&
+ output=$(git clean -n excludes included 2>&1) &&
+ expr "$output" : ".*included" >/dev/null &&
+ ! expr "$output" : ".*excludes" >/dev/null
+
+'
+
test_done
diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh
index abbf54ba6..cf389b81d 100755
--- a/t/t7500-commit.sh
+++ b/t/t7500-commit.sh
@@ -93,4 +93,36 @@ test_expect_success 'commit message from file should override template' '
commit_msg_is "standard input msg"
'
+test_expect_success 'using alternate GIT_INDEX_FILE (1)' '
+
+ cp .git/index saved-index &&
+ (
+ echo some new content >file &&
+ GIT_INDEX_FILE=.git/another_index &&
+ export GIT_INDEX_FILE &&
+ git add file &&
+ git commit -m "commit using another index" &&
+ git diff-index --exit-code HEAD &&
+ git diff-files --exit-code
+ ) &&
+ cmp .git/index saved-index >/dev/null
+
+'
+
+test_expect_success 'using alternate GIT_INDEX_FILE (2)' '
+
+ cp .git/index saved-index &&
+ (
+ rm -f .git/no-such-index &&
+ GIT_INDEX_FILE=.git/no-such-index &&
+ export GIT_INDEX_FILE &&
+ git commit -m "commit using nonexistent index" &&
+ test -z "$(git ls-files)" &&
+ test -z "$(git ls-tree HEAD)"
+
+ ) &&
+ cmp .git/index saved-index >/dev/null
+
+'
+
test_done
diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh
index 4dc35bdf5..31a6f6339 100644..100755
--- a/t/t7501-commit.sh
+++ b/t/t7501-commit.sh
@@ -34,6 +34,16 @@ test_expect_failure \
"git-commit -C HEAD -m illegal"
test_expect_failure \
+ "using paths with -a" \
+ "echo King of the bongo >file &&
+ git-commit -m foo -a file"
+
+test_expect_failure \
+ "using paths with --interactive" \
+ "echo bong-o-bong >file &&
+ echo 7 | git-commit -m foo --interactive file"
+
+test_expect_failure \
"using invalid commit with -C" \
"git-commit -C bogus"
@@ -69,7 +79,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/a file/an amend commit/g" $1
+sed -e "s/a file/an amend commit/g" < $1 > $1-
+mv $1- $1
EOF
chmod 755 editor
@@ -88,7 +99,8 @@ test_expect_success \
cat >editor <<\EOF
#!/bin/sh
-sed -i -e "s/amend/older/g" $1
+sed -e "s/amend/older/g" < $1 > $1-
+mv $1- $1
EOF
chmod 755 editor
diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh
index 83f947020..659f9c758 100755
--- a/t/t9001-send-email.sh
+++ b/t/t9001-send-email.sh
@@ -41,4 +41,41 @@ test_expect_success \
'Verify commandline' \
'diff commandline expected'
+cat >expected-show-all-headers <<\EOF
+0001-Second.patch
+(mbox) Adding cc: A <author@example.com> from line 'From: A <author@example.com>'
+Dry-OK. Log says:
+Server: relay.example.com
+MAIL FROM:<from@example.com>
+RCPT TO:<to@example.com>,<cc@example.com>,<author@example.com>,<bcc@example.com>
+From: Example <from@example.com>
+To: to@example.com
+Cc: cc@example.com, A <author@example.com>
+Subject: [PATCH 1/1] Second.
+Date: DATE-STRING
+Message-Id: MESSAGE-ID-STRING
+X-Mailer: X-MAILER-STRING
+In-Reply-To: <unique-message-id@example.com>
+References: <unique-message-id@example.com>
+
+Result: OK
+EOF
+
+test_expect_success 'Show all headers' '
+ git send-email \
+ --dry-run \
+ --from="Example <from@example.com>" \
+ --to=to@example.com \
+ --cc=cc@example.com \
+ --bcc=bcc@example.com \
+ --in-reply-to="<unique-message-id@example.com>" \
+ --smtp-server relay.example.com \
+ $patches |
+ sed -e "s/^\(Date:\).*/\1 DATE-STRING/" \
+ -e "s/^\(Message-Id:\).*/\1 MESSAGE-ID-STRING/" \
+ -e "s/^\(X-Mailer:\).*/\1 X-MAILER-STRING/" \
+ >actual-show-all-headers &&
+ diff -u expected-show-all-headers actual-show-all-headers
+'
+
test_done
diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh
index 3c83127a0..d7a704754 100755
--- a/t/t9101-git-svn-props.sh
+++ b/t/t9101-git-svn-props.sh
@@ -48,7 +48,7 @@ EOF
printf "\r\n" > empty_crlf
a_empty_crlf=`git-hash-object -w empty_crlf`
- svn import -m 'import for git-svn' . "$svnrepo" >/dev/null
+ svn import --no-auto-props -m 'import for git-svn' . "$svnrepo" >/dev/null
cd ..
rm -rf import
diff --git a/t/t9106-git-svn-dcommit-clobber-series.sh b/t/t9106-git-svn-dcommit-clobber-series.sh
index d59acc8d1..745254665 100755
--- a/t/t9106-git-svn-dcommit-clobber-series.sh
+++ b/t/t9106-git-svn-dcommit-clobber-series.sh
@@ -22,6 +22,7 @@ test_expect_success '(supposedly) non-conflicting change from SVN' "
cd tmp &&
perl -i -p -e 's/^58\$/5588/' file &&
perl -i -p -e 's/^61\$/6611/' file &&
+ poke file &&
test x\"\`sed -n -e 58p < file\`\" = x5588 &&
test x\"\`sed -n -e 61p < file\`\" = x6611 &&
svn commit -m '58 => 5588, 61 => 6611' &&
diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh
index 0d4e6b3f0..902ed4145 100755
--- a/t/t9116-git-svn-log.sh
+++ b/t/t9116-git-svn-log.sh
@@ -30,6 +30,12 @@ test_expect_success 'setup repository and import' "
git reset --hard trunk &&
echo aye >> README &&
git commit -a -m aye &&
+ git svn dcommit &&
+ git reset --hard b &&
+ echo spy >> README &&
+ git commit -a -m spy &&
+ echo try >> README &&
+ git commit -a -m try &&
git svn dcommit
"
@@ -45,4 +51,78 @@ test_expect_success 'run log against a from trunk' "
git svn log -r3 a | grep ^r3
"
+printf 'r1 \nr2 \nr4 \n' > expected-range-r1-r2-r4
+
+test_expect_success 'test ascending revision range' "
+ git reset --hard trunk &&
+ git svn log -r 1:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2-r4 -
+ "
+
+printf 'r4 \nr2 \nr1 \n' > expected-range-r4-r2-r1
+
+test_expect_success 'test descending revision range' "
+ git reset --hard trunk &&
+ git svn log -r 4:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4-r2-r1 -
+ "
+
+printf 'r1 \nr2 \n' > expected-range-r1-r2
+
+test_expect_success 'test ascending revision range with unreachable revision' "
+ git reset --hard trunk &&
+ git svn log -r 1:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r1-r2 -
+ "
+
+printf 'r2 \nr1 \n' > expected-range-r2-r1
+
+test_expect_success 'test descending revision range with unreachable revision' "
+ git reset --hard trunk &&
+ git svn log -r 3:1 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2-r1 -
+ "
+
+printf 'r2 \n' > expected-range-r2
+
+test_expect_success 'test ascending revision range with unreachable upper boundary revision and 1 commit' "
+ git reset --hard trunk &&
+ git svn log -r 2:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+ "
+
+test_expect_success 'test descending revision range with unreachable upper boundary revision and 1 commit' "
+ git reset --hard trunk &&
+ git svn log -r 3:2 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r2 -
+ "
+
+printf 'r4 \n' > expected-range-r4
+
+test_expect_success 'test ascending revision range with unreachable lower boundary revision and 1 commit' "
+ git reset --hard trunk &&
+ git svn log -r 3:4 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ "
+
+test_expect_success 'test descending revision range with unreachable lower boundary revision and 1 commit' "
+ git reset --hard trunk &&
+ git svn log -r 4:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ "
+
+printf -- '------------------------------------------------------------------------\n' > expected-separator
+
+test_expect_success 'test ascending revision range with unreachable boundary revisions and no commits' "
+ git reset --hard trunk &&
+ git svn log -r 5:6 | diff -u expected-separator -
+ "
+
+test_expect_success 'test descending revision range with unreachable boundary revisions and no commits' "
+ git reset --hard trunk &&
+ git svn log -r 6:5 | diff -u expected-separator -
+ "
+
+test_expect_success 'test ascending revision range with unreachable boundary revisions and 1 commit' "
+ git reset --hard trunk &&
+ git svn log -r 3:5 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ "
+
+test_expect_success 'test descending revision range with unreachable boundary revisions and 1 commit' "
+ git reset --hard trunk &&
+ git svn log -r 5:3 | grep '^r[0-9]' | cut -d'|' -f1 | diff -u expected-range-r4 -
+ "
+
test_done
diff --git a/t/t9117-git-svn-init-clone.sh b/t/t9117-git-svn-init-clone.sh
new file mode 100755
index 000000000..d482b407f
--- /dev/null
+++ b/t/t9117-git-svn-init-clone.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 Eric Wong
+#
+
+test_description='git-svn init/clone tests'
+
+. ./lib-git-svn.sh
+
+# setup, run inside tmp so we don't have any conflicts with $svnrepo
+set -e
+rm -r .git
+mkdir tmp
+cd tmp
+
+test_expect_success 'setup svnrepo' "
+ mkdir project project/trunk project/branches project/tags &&
+ echo foo > project/trunk/foo &&
+ svn import -m '$test_description' project $svnrepo/project &&
+ rm -rf project
+ "
+
+test_expect_success 'basic clone' "
+ test ! -d trunk &&
+ git svn clone $svnrepo/project/trunk &&
+ test -d trunk/.git/svn &&
+ test -e trunk/foo &&
+ rm -rf trunk
+ "
+
+test_expect_success 'clone to target directory' "
+ test ! -d target &&
+ git svn clone $svnrepo/project/trunk target &&
+ test -d target/.git/svn &&
+ test -e target/foo &&
+ rm -rf target
+ "
+
+test_expect_success 'clone with --stdlayout' "
+ test ! -d project &&
+ git svn clone -s $svnrepo/project &&
+ test -d project/.git/svn &&
+ test -e project/foo &&
+ rm -rf project
+ "
+
+test_expect_success 'clone to target directory with --stdlayout' "
+ test ! -d target &&
+ git svn clone -s $svnrepo/project target &&
+ test -d target/.git/svn &&
+ test -e target/foo &&
+ rm -rf target
+ "
+
+test_done
diff --git a/t/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
new file mode 100755
index 000000000..439bd93c8
--- /dev/null
+++ b/t/t9119-git-svn-info.sh
@@ -0,0 +1,368 @@
+#!/bin/sh
+#
+# Copyright (c) 2007 David D. Kilzer
+
+test_description='git-svn info'
+
+. ./lib-git-svn.sh
+
+ptouch() {
+ perl -w -e '
+ use strict;
+ die "ptouch requires exactly 2 arguments" if @ARGV != 2;
+ die "$ARGV[0] does not exist" if ! -e $ARGV[0];
+ my @s = stat $ARGV[0];
+ utime $s[8], $s[9], $ARGV[1];
+ ' "$1" "$2"
+}
+
+test_expect_success 'setup repository and import' "
+ mkdir info &&
+ cd info &&
+ echo FIRST > A &&
+ echo one > file &&
+ ln -s file symlink-file &&
+ mkdir directory &&
+ touch directory/.placeholder &&
+ ln -s directory symlink-directory &&
+ svn import -m 'initial' . $svnrepo &&
+ cd .. &&
+ mkdir gitwc &&
+ cd gitwc &&
+ git-svn init $svnrepo &&
+ git-svn fetch &&
+ cd .. &&
+ svn co $svnrepo svnwc &&
+ ptouch svnwc/file gitwc/file &&
+ ptouch svnwc/directory gitwc/directory &&
+ ptouch svnwc/symlink-file gitwc/symlink-file &&
+ ptouch svnwc/symlink-directory gitwc/symlink-directory
+ "
+
+test_expect_success 'info' "
+ (cd svnwc; svn info) > expected.info &&
+ (cd gitwc; git-svn info) > actual.info &&
+ git-diff expected.info actual.info
+ "
+
+test_expect_success 'info --url' '
+ test $(cd gitwc; git-svn info --url) = $svnrepo
+ '
+
+test_expect_success 'info .' "
+ (cd svnwc; svn info .) > expected.info-dot &&
+ (cd gitwc; git-svn info .) > actual.info-dot &&
+ git-diff expected.info-dot actual.info-dot
+ "
+
+test_expect_success 'info --url .' '
+ test $(cd gitwc; git-svn info --url .) = $svnrepo
+ '
+
+test_expect_success 'info file' "
+ (cd svnwc; svn info file) > expected.info-file &&
+ (cd gitwc; git-svn info file) > actual.info-file &&
+ git-diff expected.info-file actual.info-file
+ "
+
+test_expect_success 'info --url file' '
+ test $(cd gitwc; git-svn info --url file) = "$svnrepo/file"
+ '
+
+test_expect_success 'info directory' "
+ (cd svnwc; svn info directory) > expected.info-directory &&
+ (cd gitwc; git-svn info directory) > actual.info-directory &&
+ git-diff expected.info-directory actual.info-directory
+ "
+
+test_expect_success 'info --url directory' '
+ test $(cd gitwc; git-svn info --url directory) = "$svnrepo/directory"
+ '
+
+test_expect_success 'info symlink-file' "
+ (cd svnwc; svn info symlink-file) > expected.info-symlink-file &&
+ (cd gitwc; git-svn info symlink-file) > actual.info-symlink-file &&
+ git-diff expected.info-symlink-file actual.info-symlink-file
+ "
+
+test_expect_success 'info --url symlink-file' '
+ test $(cd gitwc; git-svn info --url symlink-file) \
+ = "$svnrepo/symlink-file"
+ '
+
+test_expect_success 'info symlink-directory' "
+ (cd svnwc; svn info symlink-directory) \
+ > expected.info-symlink-directory &&
+ (cd gitwc; git-svn info symlink-directory) \
+ > actual.info-symlink-directory &&
+ git-diff expected.info-symlink-directory actual.info-symlink-directory
+ "
+
+test_expect_success 'info --url symlink-directory' '
+ test $(cd gitwc; git-svn info --url symlink-directory) \
+ = "$svnrepo/symlink-directory"
+ '
+
+test_expect_success 'info added-file' "
+ echo two > gitwc/added-file &&
+ cd gitwc &&
+ git add added-file &&
+ cd .. &&
+ cp gitwc/added-file svnwc/added-file &&
+ ptouch gitwc/added-file svnwc/added-file &&
+ cd svnwc &&
+ svn add added-file > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info added-file) > expected.info-added-file &&
+ (cd gitwc; git-svn info added-file) > actual.info-added-file &&
+ git-diff expected.info-added-file actual.info-added-file
+ "
+
+test_expect_success 'info --url added-file' '
+ test $(cd gitwc; git-svn info --url added-file) \
+ = "$svnrepo/added-file"
+ '
+
+test_expect_success 'info added-directory' "
+ mkdir gitwc/added-directory svnwc/added-directory &&
+ ptouch gitwc/added-directory svnwc/added-directory &&
+ touch gitwc/added-directory/.placeholder &&
+ cd svnwc &&
+ svn add added-directory > /dev/null &&
+ cd .. &&
+ cd gitwc &&
+ git add added-directory &&
+ cd .. &&
+ (cd svnwc; svn info added-directory) \
+ > expected.info-added-directory &&
+ (cd gitwc; git-svn info added-directory) \
+ > actual.info-added-directory &&
+ git-diff expected.info-added-directory actual.info-added-directory
+ "
+
+test_expect_success 'info --url added-directory' '
+ test $(cd gitwc; git-svn info --url added-directory) \
+ = "$svnrepo/added-directory"
+ '
+
+test_expect_success 'info added-symlink-file' "
+ cd gitwc &&
+ ln -s added-file added-symlink-file &&
+ git add added-symlink-file &&
+ cd .. &&
+ cd svnwc &&
+ ln -s added-file added-symlink-file &&
+ svn add added-symlink-file > /dev/null &&
+ cd .. &&
+ ptouch gitwc/added-symlink-file svnwc/added-symlink-file &&
+ (cd svnwc; svn info added-symlink-file) \
+ > expected.info-added-symlink-file &&
+ (cd gitwc; git-svn info added-symlink-file) \
+ > actual.info-added-symlink-file &&
+ git-diff expected.info-added-symlink-file \
+ actual.info-added-symlink-file
+ "
+
+test_expect_success 'info --url added-symlink-file' '
+ test $(cd gitwc; git-svn info --url added-symlink-file) \
+ = "$svnrepo/added-symlink-file"
+ '
+
+test_expect_success 'info added-symlink-directory' "
+ cd gitwc &&
+ ln -s added-directory added-symlink-directory &&
+ git add added-symlink-directory &&
+ cd .. &&
+ cd svnwc &&
+ ln -s added-directory added-symlink-directory &&
+ svn add added-symlink-directory > /dev/null &&
+ cd .. &&
+ ptouch gitwc/added-symlink-directory svnwc/added-symlink-directory &&
+ (cd svnwc; svn info added-symlink-directory) \
+ > expected.info-added-symlink-directory &&
+ (cd gitwc; git-svn info added-symlink-directory) \
+ > actual.info-added-symlink-directory &&
+ git-diff expected.info-added-symlink-directory \
+ actual.info-added-symlink-directory
+ "
+
+test_expect_success 'info --url added-symlink-directory' '
+ test $(cd gitwc; git-svn info --url added-symlink-directory) \
+ = "$svnrepo/added-symlink-directory"
+ '
+
+# The next few tests replace the "Text Last Updated" value with a
+# placeholder since git doesn't have a way to know the date that a
+# now-deleted file was last checked out locally. Internally it
+# simply reuses the Last Changed Date.
+
+test_expect_success 'info deleted-file' "
+ cd gitwc &&
+ git rm -f file > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force file > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-file &&
+ (cd gitwc; git-svn info file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-file &&
+ git-diff expected.info-deleted-file actual.info-deleted-file
+ "
+
+test_expect_success 'info --url file (deleted)' '
+ test $(cd gitwc; git-svn info --url file) \
+ = "$svnrepo/file"
+ '
+
+test_expect_success 'info deleted-directory' "
+ cd gitwc &&
+ git rm -r -f directory > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force directory > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-directory &&
+ (cd gitwc; git-svn info directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-directory &&
+ git-diff expected.info-deleted-directory actual.info-deleted-directory
+ "
+
+test_expect_success 'info --url directory (deleted)' '
+ test $(cd gitwc; git-svn info --url directory) \
+ = "$svnrepo/directory"
+ '
+
+test_expect_success 'info deleted-symlink-file' "
+ cd gitwc &&
+ git rm -f symlink-file > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force symlink-file > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info symlink-file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-symlink-file &&
+ (cd gitwc; git-svn info symlink-file) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-symlink-file &&
+ git-diff expected.info-deleted-symlink-file \
+ actual.info-deleted-symlink-file
+ "
+
+test_expect_success 'info --url symlink-file (deleted)' '
+ test $(cd gitwc; git-svn info --url symlink-file) \
+ = "$svnrepo/symlink-file"
+ '
+
+test_expect_success 'info deleted-symlink-directory' "
+ cd gitwc &&
+ git rm -f symlink-directory > /dev/null &&
+ cd .. &&
+ cd svnwc &&
+ svn rm --force symlink-directory > /dev/null &&
+ cd .. &&
+ (cd svnwc; svn info symlink-directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > expected.info-deleted-symlink-directory &&
+ (cd gitwc; git-svn info symlink-directory) |
+ sed -e 's/^\(Text Last Updated:\).*/\1 TEXT-LAST-UPDATED-STRING/' \
+ > actual.info-deleted-symlink-directory &&
+ git-diff expected.info-deleted-symlink-directory \
+ actual.info-deleted-symlink-directory
+ "
+
+test_expect_success 'info --url symlink-directory (deleted)' '
+ test $(cd gitwc; git-svn info --url symlink-directory) \
+ = "$svnrepo/symlink-directory"
+ '
+
+# NOTE: git does not have the concept of replaced objects,
+# so we can't test for files in that state.
+
+test_expect_success 'info unknown-file' "
+ echo two > gitwc/unknown-file &&
+ cp gitwc/unknown-file svnwc/unknown-file &&
+ ptouch gitwc/unknown-file svnwc/unknown-file &&
+ (cd svnwc; svn info unknown-file) 2> expected.info-unknown-file &&
+ (cd gitwc; git-svn info unknown-file) 2> actual.info-unknown-file &&
+ git-diff expected.info-unknown-file actual.info-unknown-file
+ "
+
+test_expect_success 'info --url unknown-file' '
+ test -z $(cd gitwc; git-svn info --url unknown-file \
+ 2> ../actual.info--url-unknown-file) &&
+ git-diff expected.info-unknown-file actual.info--url-unknown-file
+ '
+
+test_expect_success 'info unknown-directory' "
+ mkdir gitwc/unknown-directory svnwc/unknown-directory &&
+ ptouch gitwc/unknown-directory svnwc/unknown-directory &&
+ touch gitwc/unknown-directory/.placeholder &&
+ (cd svnwc; svn info unknown-directory) \
+ 2> expected.info-unknown-directory &&
+ (cd gitwc; git-svn info unknown-directory) \
+ 2> actual.info-unknown-directory &&
+ git-diff expected.info-unknown-directory actual.info-unknown-directory
+ "
+
+test_expect_success 'info --url unknown-directory' '
+ test -z $(cd gitwc; git-svn info --url unknown-directory \
+ 2> ../actual.info--url-unknown-directory) &&
+ git-diff expected.info-unknown-directory \
+ actual.info--url-unknown-directory
+ '
+
+test_expect_success 'info unknown-symlink-file' "
+ cd gitwc &&
+ ln -s unknown-file unknown-symlink-file &&
+ cd .. &&
+ cd svnwc &&
+ ln -s unknown-file unknown-symlink-file &&
+ cd .. &&
+ ptouch gitwc/unknown-symlink-file svnwc/unknown-symlink-file &&
+ (cd svnwc; svn info unknown-symlink-file) \
+ 2> expected.info-unknown-symlink-file &&
+ (cd gitwc; git-svn info unknown-symlink-file) \
+ 2> actual.info-unknown-symlink-file &&
+ git-diff expected.info-unknown-symlink-file \
+ actual.info-unknown-symlink-file
+ "
+
+test_expect_success 'info --url unknown-symlink-file' '
+ test -z $(cd gitwc; git-svn info --url unknown-symlink-file \
+ 2> ../actual.info--url-unknown-symlink-file) &&
+ git-diff expected.info-unknown-symlink-file \
+ actual.info--url-unknown-symlink-file
+ '
+
+test_expect_success 'info unknown-symlink-directory' "
+ cd gitwc &&
+ ln -s unknown-directory unknown-symlink-directory &&
+ cd .. &&
+ cd svnwc &&
+ ln -s unknown-directory unknown-symlink-directory &&
+ cd .. &&
+ ptouch gitwc/unknown-symlink-directory \
+ svnwc/unknown-symlink-directory &&
+ (cd svnwc; svn info unknown-symlink-directory) \
+ 2> expected.info-unknown-symlink-directory &&
+ (cd gitwc; git-svn info unknown-symlink-directory) \
+ 2> actual.info-unknown-symlink-directory &&
+ git-diff expected.info-unknown-symlink-directory \
+ actual.info-unknown-symlink-directory
+ "
+
+test_expect_success 'info --url unknown-symlink-directory' '
+ test -z $(cd gitwc; git-svn info --url unknown-symlink-directory \
+ 2> ../actual.info--url-unknown-symlink-directory) &&
+ git-diff expected.info-unknown-symlink-directory \
+ actual.info--url-unknown-symlink-directory
+ '
+
+test_done
diff --git a/templates/hooks--pre-commit b/templates/hooks--pre-commit
index a19279b3e..7092bae26 100644
--- a/templates/hooks--pre-commit
+++ b/templates/hooks--pre-commit
@@ -13,7 +13,7 @@
if git-rev-parse --verify HEAD 2>/dev/null
then
- git-diff-index -p -M --cached HEAD
+ git-diff-index -p -M --cached HEAD --
else
# NEEDSWORK: we should produce a diff with an empty tree here
# if we want to do the same verification for the initial import.
diff --git a/transport.c b/transport.c
index 8d9bdbe8d..50db9807d 100644
--- a/transport.c
+++ b/transport.c
@@ -348,6 +348,7 @@ static int rsync_transport_push(struct transport *transport,
/* Generic functions for using commit walkers */
+#ifndef NO_CURL /* http fetch is the only user */
static int fetch_objs_via_walker(struct transport *transport,
int nr_objs, struct ref **to_fetch)
{
@@ -374,6 +375,7 @@ static int fetch_objs_via_walker(struct transport *transport,
free(dest);
return 0;
}
+#endif /* NO_CURL */
static int disconnect_walker(struct transport *transport)
{
diff --git a/tree-diff.c b/tree-diff.c
index 7c261fd7c..aa0a10029 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -39,7 +39,7 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
show_entry(opt, "+", t2, base, baselen);
return 1;
}
- if (!opt->find_copies_harder && !hashcmp(sha1, sha2) && mode1 == mode2)
+ if (!DIFF_OPT_TST(opt, FIND_COPIES_HARDER) && !hashcmp(sha1, sha2) && mode1 == mode2)
return 0;
/*
@@ -52,10 +52,10 @@ static int compare_tree_entry(struct tree_desc *t1, struct tree_desc *t2, const
return 0;
}
- if (opt->recursive && S_ISDIR(mode1)) {
+ if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode1)) {
int retval;
char *newbase = malloc_base(base, baselen, path1, pathlen1);
- if (opt->tree_in_recursive)
+ if (DIFF_OPT_TST(opt, TREE_IN_RECURSIVE))
opt->change(opt, mode1, mode2,
sha1, sha2, base, path1);
retval = diff_tree_sha1(sha1, sha2, newbase, opt);
@@ -206,7 +206,7 @@ static void show_entry(struct diff_options *opt, const char *prefix, struct tree
const char *path;
const unsigned char *sha1 = tree_entry_extract(desc, &path, &mode);
- if (opt->recursive && S_ISDIR(mode)) {
+ if (DIFF_OPT_TST(opt, RECURSIVE) && S_ISDIR(mode)) {
enum object_type type;
int pathlen = tree_entry_len(path, sha1);
char *newbase = malloc_base(base, baselen, path, pathlen);
@@ -257,7 +257,7 @@ int diff_tree(struct tree_desc *t1, struct tree_desc *t2, const char *base, stru
int baselen = strlen(base);
for (;;) {
- if (opt->quiet && opt->has_changes)
+ if (DIFF_OPT_TST(opt, QUIET) && DIFF_OPT_TST(opt, HAS_CHANGES))
break;
if (opt->nr_paths) {
skip_uninteresting(t1, base, baselen, opt);
@@ -315,7 +315,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
q->nr = 0;
diff_setup(&diff_opts);
- diff_opts.recursive = 1;
+ DIFF_OPT_SET(&diff_opts, RECURSIVE);
diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = opt->paths[0];
@@ -380,7 +380,7 @@ int diff_tree_sha1(const unsigned char *old, const unsigned char *new, const cha
init_tree_desc(&t1, tree1, size1);
init_tree_desc(&t2, tree2, size2);
retval = diff_tree(&t1, &t2, base, opt);
- if (opt->follow_renames && diff_might_be_rename()) {
+ if (DIFF_OPT_TST(opt, FOLLOW_RENAMES) && diff_might_be_rename()) {
init_tree_desc(&t1, tree1, size1);
init_tree_desc(&t2, tree2, size2);
try_to_follow_renames(&t1, &t2, base, opt);
diff --git a/tree-walk.h b/tree-walk.h
index db0fbdc70..903a7b0f4 100644
--- a/tree-walk.h
+++ b/tree-walk.h
@@ -7,6 +7,13 @@ struct name_entry {
unsigned int mode;
};
+static inline enum object_type object_type(unsigned int mode)
+{
+ return S_ISDIR(mode) ? OBJ_TREE :
+ S_ISGITLINK(mode) ? OBJ_COMMIT :
+ OBJ_BLOB;
+}
+
struct tree_desc {
const void *buffer;
struct name_entry entry;
diff --git a/unpack-trees.c b/unpack-trees.c
index c527d7d04..aea16adde 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -404,7 +404,7 @@ static void verify_uptodate(struct cache_entry *ce,
return;
if (!lstat(ce->name, &st)) {
- unsigned changed = ce_match_stat(ce, &st, 1);
+ unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
if (!changed)
return;
/*
@@ -925,7 +925,7 @@ int oneway_merge(struct cache_entry **src,
if (o->reset) {
struct stat st;
if (lstat(old->name, &st) ||
- ce_match_stat(old, &st, 1))
+ ce_match_stat(old, &st, CE_MATCH_IGNORE_VALID))
old->ce_flags |= htons(CE_UPDATE);
}
return keep_entry(old, o);
diff --git a/utf8.c b/utf8.c
index 8095a71d3..9efcdb9c0 100644
--- a/utf8.c
+++ b/utf8.c
@@ -284,7 +284,6 @@ int print_wrapped_text(const char *text, int indent, int indent2, int width)
text++;
}
}
- return w;
}
int is_encoding_utf8(const char *name)
diff --git a/wt-status.c b/wt-status.c
index 03b5ec448..9a6ef4a89 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -22,7 +22,6 @@ static const char use_add_rm_msg[] =
"use \"git add/rm <file>...\" to update what will be committed";
static const char use_add_to_include_msg[] =
"use \"git add <file>...\" to include in what will be committed";
-static const char *excludes_file;
static int parse_status_slot(const char *var, int offset)
{
@@ -251,22 +250,16 @@ static void wt_status_print_changed(struct wt_status *s)
static void wt_status_print_untracked(struct wt_status *s)
{
struct dir_struct dir;
- const char *x;
int i;
int shown_header = 0;
memset(&dir, 0, sizeof(dir));
- dir.exclude_per_dir = ".gitignore";
if (!s->untracked) {
dir.show_other_directories = 1;
dir.hide_empty_directories = 1;
}
- x = git_path("info/exclude");
- if (file_exists(x))
- add_excludes_from_file(&dir, x);
- if (excludes_file && file_exists(excludes_file))
- add_excludes_from_file(&dir, excludes_file);
+ setup_standard_excludes(&dir);
read_directory(&dir, ".", "", 0, NULL);
for(i = 0; i < dir.nr; i++) {
@@ -364,11 +357,5 @@ int git_status_config(const char *k, const char *v)
int slot = parse_status_slot(k, 13);
color_parse(v, k, wt_status_colors[slot]);
}
- if (!strcmp(k, "core.excludesfile")) {
- if (!v)
- die("core.excludesfile without value");
- excludes_file = xstrdup(v);
- return 0;
- }
return git_default_config(k, v);
}
diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c
index 5cb7171a8..1bad8462f 100644
--- a/xdiff/xdiffi.c
+++ b/xdiff/xdiffi.c
@@ -257,8 +257,6 @@ static long xdl_split(unsigned long const *ha1, long off1, long lim1,
return ec;
}
}
-
- return -1;
}
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 2ade97b25..d7974d1a3 100644
--- a/xdiff/xutils.c
+++ b/xdiff/xutils.c
@@ -232,8 +232,6 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags)
return i1 >= s1 && i2 >= s2;
} else
return s1 == s2 && !memcmp(l1, l2, s1);
-
- return 0;
}
static unsigned long xdl_hash_record_with_whitespace(char const **data,