Merge branch 'jc/move-gitk'
authorJunio C Hamano <gitster@pobox.com>
Sat, 1 Dec 2007 21:58:57 +0000 (13:58 -0800)
committerJunio C Hamano <gitster@pobox.com>
Sat, 1 Dec 2007 21:58:57 +0000 (13:58 -0800)
* jc/move-gitk:
Move gitk to its own subdirectory

173 files changed:
Documentation/RelNotes-1.5.3.7.txt [new file with mode: 0644]
Documentation/RelNotes-1.5.4.txt
Documentation/cmd-list.perl
Documentation/config.txt
Documentation/git-branch.txt
Documentation/git-get-tar-commit-id.txt
Documentation/git-peek-remote.txt
Documentation/git-push.txt
Documentation/git-reflog.txt
Documentation/git-remote.txt
Documentation/git-svn.txt
Documentation/git-tag.txt
Documentation/git.txt
Documentation/howto/maintain-git.txt [new file with mode: 0644]
Documentation/user-manual.txt
Makefile
builtin-branch.c
builtin-clean.c [new file with mode: 0644]
builtin-config.c
builtin-fetch--tool.c
builtin-fetch-pack.c
builtin-fetch.c
builtin-init-db.c
builtin-ls-remote.c [new file with mode: 0644]
builtin-merge-ours.c [new file with mode: 0644]
builtin-push.c
builtin-revert.c
builtin-send-pack.c [new file with mode: 0644]
builtin-tag.c
builtin.h
bundle.c
cache.h
config.c
config.mak.in
configure.ac
connect.c
contrib/completion/git-completion.bash
contrib/examples/git-clean.sh [new file with mode: 0755]
contrib/examples/git-ls-remote.sh [new file with mode: 0755]
contrib/examples/git-merge-ours.sh [new file with mode: 0755]
contrib/fast-import/git-p4
contrib/gitview/gitview
diff-lib.c
diff.c
diffcore-rename.c
dir.c
dir.h
git-add--interactive.perl
git-am.sh
git-bisect.sh
git-checkout.sh
git-clean.sh [deleted file]
git-compat-util.h
git-cvsimport.perl
git-filter-branch.sh
git-gui/.gitignore
git-gui/GIT-VERSION-GEN
git-gui/Makefile
git-gui/git-gui.sh
git-gui/lib/about.tcl [new file with mode: 0644]
git-gui/lib/blame.tcl
git-gui/lib/branch_checkout.tcl
git-gui/lib/branch_create.tcl
git-gui/lib/branch_delete.tcl
git-gui/lib/branch_rename.tcl
git-gui/lib/browser.tcl
git-gui/lib/checkout_op.tcl
git-gui/lib/choose_repository.tcl [new file with mode: 0644]
git-gui/lib/choose_rev.tcl
git-gui/lib/commit.tcl
git-gui/lib/console.tcl
git-gui/lib/database.tcl
git-gui/lib/date.tcl [new file with mode: 0644]
git-gui/lib/diff.tcl
git-gui/lib/error.tcl
git-gui/lib/git-gui.ico [new file with mode: 0644]
git-gui/lib/index.tcl
git-gui/lib/logo.tcl [new file with mode: 0644]
git-gui/lib/merge.tcl
git-gui/lib/option.tcl
git-gui/lib/remote.tcl
git-gui/lib/remote_branch_delete.tcl
git-gui/lib/shortcut.tcl
git-gui/lib/status_bar.tcl
git-gui/lib/transport.tcl
git-gui/lib/win32.tcl [new file with mode: 0644]
git-gui/lib/win32_shortcut.js [new file with mode: 0644]
git-gui/macosx/AppMain.tcl [new file with mode: 0644]
git-gui/macosx/Info.plist [new file with mode: 0644]
git-gui/macosx/git-gui.icns [new file with mode: 0644]
git-gui/po/.gitignore [new file with mode: 0644]
git-gui/po/README [new file with mode: 0644]
git-gui/po/de.po [new file with mode: 0644]
git-gui/po/git-gui.pot [new file with mode: 0644]
git-gui/po/glossary/Makefile [new file with mode: 0644]
git-gui/po/glossary/de.po [new file with mode: 0644]
git-gui/po/glossary/git-gui-glossary.pot [new file with mode: 0644]
git-gui/po/glossary/git-gui-glossary.txt [new file with mode: 0644]
git-gui/po/glossary/it.po [new file with mode: 0644]
git-gui/po/glossary/txt-to-pot.sh [new file with mode: 0755]
git-gui/po/glossary/zh_cn.po [new file with mode: 0644]
git-gui/po/hu.po [new file with mode: 0644]
git-gui/po/it.po [new file with mode: 0644]
git-gui/po/ja.po [new file with mode: 0644]
git-gui/po/po2msg.sh [new file with mode: 0644]
git-gui/po/ru.po [new file with mode: 0644]
git-gui/po/zh_cn.po [new file with mode: 0644]
git-gui/windows/git-gui.sh [new file with mode: 0644]
git-ls-remote.sh [deleted file]
git-merge-ours.sh [deleted file]
git-rebase--interactive.sh
git-rebase.sh
git-send-email.perl
git-stash.sh
git-svn.perl
git.c
gitweb/gitweb.css
gitweb/gitweb.perl
help.c
http-push.c
http-walker.c
lockfile.c
pager.c
parse-options.c
parse-options.h
peek-remote.c [deleted file]
perl/Git.pm
progress.c
receive-pack.c
refs.c
remote.c
remote.h
send-pack.c [deleted file]
send-pack.h [new file with mode: 0644]
server-info.c
setup.c
sha1_file.c
t/t3201-branch-contains.sh [new file with mode: 0755]
t/t3403-rebase-skip.sh
t/t3404-rebase-interactive.sh
t/t3902-quoted.sh
t/t4000-diff-format.sh
t/t4001-diff-rename.sh
t/t4008-diff-break-rewrite.sh
t/t4018-diff-funcname.sh [changed mode: 0644->0755]
t/t4022-diff-rewrite.sh [new file with mode: 0755]
t/t4100/t-apply-1.patch
t/t4100/t-apply-2.patch
t/t4100/t-apply-5.patch
t/t4100/t-apply-6.patch
t/t4119-apply-config.sh
t/t5300-pack-object.sh
t/t5302-pack-index.sh
t/t5404-tracking-branches.sh [new file with mode: 0755]
t/t5405-send-pack-rewind.sh [new file with mode: 0755]
t/t5406-remote-rejects.sh [new file with mode: 0755]
t/t5510-fetch.sh
t/t5512-ls-remote.sh [new file with mode: 0755]
t/t5516-fetch-push.sh
t/t5517-push-mirror.sh [new file with mode: 0755]
t/t6030-bisect-porcelain.sh
t/t7003-filter-branch.sh
t/t7004-tag.sh
t/t7501-commit.sh [changed mode: 0644->0755]
t/t9001-send-email.sh
t/t9106-git-svn-dcommit-clobber-series.sh
t/t9119-git-svn-info.sh [new file with mode: 0755]
t/t9600-cvsimport.sh [new file with mode: 0755]
templates/hooks--pre-commit
trace.c
transport.c
transport.h
unpack-trees.c
diff --git a/Documentation/RelNotes-1.5.3.7.txt b/Documentation/RelNotes-1.5.3.7.txt
new file mode 100644 (file)
index 0000000..2f69061
--- /dev/null
@@ -0,0 +1,45 @@
+GIT v1.5.3.7 Release Notes
+==========================
+
+Fixes since v1.5.3.6
+--------------------
+
+ * git-send-email added 8-bit contents to the payload without
+   marking it as 8-bit in a CTE header.
+
+ * "git-bundle create a.bndl HEAD" dereferenced the symref and
+   did not record the ref as 'HEAD'; this prevented a bundle
+   from being used as a normal source of git-clone.
+
+ * The code to reject nonsense command line of the form
+   "git-commit -a paths..." and "git-commit --interactive
+   paths..." were broken.
+
+ * Adding a signature that is not ASCII-only to an original
+   commit that is ASCII-only would make the result non-ASCII.
+   "git-format-patch -s" did not mark such a message correctly
+   with MIME encoding header.
+
+ * git-add sometimes did not mark the resulting index entry
+   stat-clean.  This affected only cases when adding the
+   contents with the same length as the previously staged
+   contents, and the previous staging made the index entry
+   "racily clean".
+
+ * git-commit did not honor GIT_INDEX_FILE the user had in the
+   environment.
+
+ * When checking out a revision, git-checkout did not report where the
+   updated HEAD is if you happened to have a file called HEAD in the
+   work tree.
+
+ * "git-rev-list --objects" mishandled a tree that points at a
+   submodule.
+
+ * "git cvsimport" was not ready for packed refs that "git gc" can
+   produce and gave incorrect results.
+
+ * Many scripted Porcelains were confused when you happened to have a
+   file called "HEAD" in your work tree.
+
+Also it contains updates to the user manual and documentation.
index 96ec55eb1c2b931b9be174a484e5e8063fa5c34f..192766f868f4669b7cedc5baa4c119a39fc602b5 100644 (file)
@@ -1,20 +1,70 @@
 GIT v1.5.4 Release Notes
 ========================
 
+Deprecation notices
+-------------------
+
+ * Next feature release of git (this change is scheduled for v1.5.5 but
+   it could slip) will by default install dashed form of commands
+   (e.g. "git-commit") outside of users' normal $PATH, and will install
+   only selected commands ("git" itself, and "gitk") in $PATH.  This
+   implies:
+
+   - Using dashed form of git commands (e.g. "git-commit") from the
+     command line has been informally deprecated since early 2006, but
+     now it officially is, and will be removed in the future.  Use
+     dashless form (e.g. "git commit") instead.
+
+   - Using dashed from from your scripts, without first prepending the
+     return value from "git --exec-path" to the scripts' PATH, has been
+     informally deprecated since early 2006, but now it officially is.
+
+   - Use of dashed form with "PATH=$(git --exec-path):$PATH; export
+     PATH" early in your script is not deprecated with this change.
+
+  Users are strongly encouraged to adjust their habits and scripts now
+  to prepare for this.
+
+ * The post-receive hook was introduced in March 2007 to supersede
+   post-update hook, primarily to overcome the command line length
+   limitation of the latter.  Use of post-update hook will be deprecated
+   in future versions of git, perhaps in v1.5.5.
+
+
 Updates since v1.5.3
 --------------------
 
  * Comes with much improved gitk.
 
+ * Comes with git-gui 0.9.0 with i18n.
+
+ * git-lost-found was deprecated in favor of git-fsck's --lost-found
+   option.
+
+ * git-peek-remote is deprecated, as git-ls-remote was written in C and
+   works for all transports.
+
+ * git-cherry-pick made a misguided attempt to repeat the original
+   command line in the generated log message, when told to cherry-pick a
+   commit by naming a tag that points at it.  It does not anymore.
+
  * "progress display" from many commands are a lot nicer to the
    eye.  Transfer commands show throughput data.
 
+ * many commands that pay attention to per-directory .gitignore now do
+   so lazily, which makes the usual case go much faster.
+
  * git-reset is now built-in and its output can be squelched with -q.
 
  * git-send-email can optionally talk over ssmtp and use SMTP-AUTH.
 
  * git-rebase learned --whitespace option.
 
+ * In git-rebase, when you decide not to replay a particular change
+   after the command stopped with a conflict, you can say "git-rebase
+   --skip" without first running "git reset --hard", as the command now
+   runs it for you.
+
  * git-remote knows --mirror mode.
 
  * git-merge can call the "post-merge" hook.
@@ -33,14 +83,24 @@ Updates since v1.5.3
    too many loose objects.
 
  * You need to explicitly set clean.requireForce to "false" to allow
-   git-clean to do any damage (lack of the configuration variable
-   used to mean "do not require", but we now use the safer default).
+   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-clean has been rewritten in C.
 
  * git-push has been rewritten in C.
 
  * git-push learned --dry-run option to show what would happen
    if a push is run.
 
+ * git-push does not update a tracking ref on the pushing side when the
+   remote refused to update the corresponding ref.
+
+ * git-push learned --mirror option.  This is to push the local refs
+   one-to-one to the remote, and deletes refs from the remote that do
+   not exist anymore in the repository on the pushing side.
+
  * git-remote learned "rm" subcommand.
 
  * git-rebase --interactive mode can now work on detached HEAD.
@@ -53,9 +113,6 @@ Updates since v1.5.3
 
  * Various Perforce importer updates.
 
- * 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.
 
@@ -85,14 +142,41 @@ Updates since v1.5.3
    to allow checking out a path outside the current directory
    without cd'ing up.
 
+ * "git send-email --dry-run" shows full headers for easier
+   diagnosis.
+
+ * "git merge-ours" is built-in.
+
+ * "git svn" learned "info" and "show-externals" subcommands.
+
+ * calling "git svn" from a subdirectory failed read settings from the
+   .git/config.
+
+ * "git svn" learned --use-log-author option, which picks up more
+   descriptive name from From: and Signed-off-by: lines in the commit
+   message.
+
+ * "git status" from a subdirectory now shows relative paths
+   which makes copy-and-pasting for git-checkout/git-add/git-rm
+   easier.
+
+ * "git checkout" from and to detached HEAD leaves a bit more
+   information in the reflog.
+
  * Output processing for '--pretty=format:<user format>' has
    been optimized.
 
- * Rename detection diff family, while detecting exact matches,
-   has been greatly optimized.
+ * Rename detection of diff family, while detecting exact matches, has
+   been greatly optimized.
+
+ * Rename detection of diff family tries to make more naturally looking
+   pairing.  Earlier if more than one identical rename sources were
+   found in the preimage, they were picked pretty much at random.
 
  * Example update and post-receive hooks have been improved.
 
+ * A corrupt ref at the remote site can be removed via "git push".
+
  * In addition there are quite a few internal clean-ups. Notably
 
    - many fork/exec have been replaced with run-command API,
@@ -118,6 +202,6 @@ this release, unless otherwise noted.
 
 --
 exec >/var/tmp/1
-O=v1.5.3.6-727-g5d3d1ca
+O=v1.5.3.7-948-gb52e985
 echo O=`git describe refs/heads/master`
 git shortlog --no-merges $O..refs/heads/master ^refs/heads/maint
index 57a790df63b884b5ece790422bedacaab0a4ba3b..b709551726989036c7232cb2a5f72b9578b5e4af 100755 (executable)
@@ -151,7 +151,7 @@ sub format_one {
 git-pack-refs                           ancillarymanipulators
 git-parse-remote                        synchelpers
 git-patch-id                            purehelpers
-git-peek-remote                         purehelpers
+git-peek-remote                         purehelpers    deprecated
 git-prune                               ancillarymanipulators
 git-prune-packed                        plumbingmanipulators
 git-pull                                mainporcelain
index 6dc9f3ed02b2dd4a3fe439c28df7b2ba6778244d..39d1ef5298bd81868079b8d82ba56157e4785b5d 100644 (file)
@@ -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
@@ -648,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
index 5ce905de862253aa2bd2ed619819306165e978f0..d3f21c797596e9dc633293e0cca4a172940bd4af 100644 (file)
@@ -10,6 +10,7 @@ SYNOPSIS
 [verse]
 'git-branch' [--color | --no-color] [-r | -a]
           [-v [--abbrev=<length> | --no-abbrev]]
+          [--contains <commit>]
 'git-branch' [--track | --no-track] [-l] [-f] <branchname> [<start-point>]
 'git-branch' (-m | -M) [<oldbranch>] <newbranch>
 'git-branch' (-d | -D) [-r] <branchname>...
@@ -20,6 +21,9 @@ With no arguments given a list of existing branches
 will be shown, the current branch will be highlighted with an asterisk.
 Option `-r` causes the remote-tracking branches to be listed,
 and option `-a` shows both.
+With `--contains <commit>`, shows only the branches that
+contains the named commit (in other words, the branches whose
+tip commits are descendant of the named commit).
 
 In its second form, a new branch named <branchname> will be created.
 It will start out with a head equal to the one given as <start-point>.
@@ -45,17 +49,22 @@ to happen.
 
 With a `-d` or `-D` option, `<branchname>` will be deleted.  You may
 specify more than one branch for deletion.  If the branch currently
-has a reflog then the reflog will also be deleted. Use -r together with -d
-to delete remote-tracking branches.
+has a reflog then the reflog will also be deleted.
+
+Use -r together with -d to delete remote-tracking branches. Note, that it
+only makes sense to delete remote-tracking branches if they no longer exist
+in remote repository or if gitlink:git-fetch[1] was configured not to fetch
+them again. See also 'prune' subcommand of gitlink:git-remote[1] for way to
+clean up all obsolete remote-tracking branches.
 
 
 OPTIONS
 -------
 -d::
-       Delete a branch. The branch must be fully merged.
+       Delete a branch. The branch must be fully merged in HEAD.
 
 -D::
-       Delete a branch irrespective of its index status.
+       Delete a branch irrespective of its merged status.
 
 -l::
        Create the branch's reflog.  This activates recording of
@@ -153,9 +162,11 @@ $ git branch -d -r origin/todo origin/html origin/man   <1>
 $ git branch -D test                                    <2>
 ------------
 +
-<1> Delete remote-tracking branches "todo", "html", "man"
-<2> Delete "test" branch even if the "master" branch does not have all
-commits from test branch.
+<1> Delete remote-tracking branches "todo", "html", "man". Next 'fetch' or
+'pull' will create them again unless you configure them not to. See
+gitlink:git-fetch[1].
+<2> Delete "test" branch even if the "master" branch (or whichever branch is
+currently checked out) does not have all commits from test branch.
 
 
 Notes
index 76316bbc9e3265dc9e5dca7562b7c79357c77931..60d1c52f449ec9e37c2f3d02bc79aa98af86a325 100644 (file)
@@ -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.
 
 
index abc171266a35299159308d0653bb0c659b8bdc77..38a5325af79b8ecdd7893f7cbd5a27da325cb1a5 100644 (file)
@@ -12,8 +12,7 @@ SYNOPSIS
 
 DESCRIPTION
 -----------
-Lists the references the remote repository has, and optionally
-stores them in the local repository under the same name.
+This command is deprecated; use `git-ls-remote` instead.
 
 OPTIONS
 -------
index 4a68aaba342bd1155beb2ae72fd81c701e6c80eb..b8003c63c7e51dc1e3907645b267805dfb5f38d6 100644 (file)
@@ -63,6 +63,14 @@ the remote repository.
        Instead of naming each ref to push, specifies that all
        refs under `$GIT_DIR/refs/heads/` be pushed.
 
+\--mirror::
+       Instead of naming each ref to push, specifies that all
+       refs under `$GIT_DIR/refs/heads/` and `$GIT_DIR/refs/tags/`
+       be mirrored to the remote repository.  Newly created local
+       refs will be pushed to the remote end, locally updated refs
+       will be force updated on the remote end, and deleted refs
+       will be removed from the remote end.
+
 \--dry-run::
        Do everything except actually send the updates.
 
index 5c7316ceb82fbedc1413dfd8a4b1d8095b4d7a06..25003c38667940528422aab735ec0a4e9a4d5b97 100644 (file)
@@ -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
index 0da8704a25f7010d84008396ab1bb0be5b4a4da1..4b263c249cd93695b1c373887600d335685e82bb 100644 (file)
@@ -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
index 488e4b1caf8097de4ab53bf89a03f80173a2cf52..918a9928b1c82225256e18f4d7847f6622a2324b 100644 (file)
@@ -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
index 10d3e3fa950e00b6004f968ff2c41477e1d57612..784ec6d4c29879e48c13834819048d4a640dc32d 100644 (file)
@@ -65,7 +65,9 @@ OPTIONS
        Typing "git tag" without arguments, also lists all tags.
 
 -m <msg>::
-       Use the given tag message (instead of prompting)
+       Use the given tag message (instead of prompting).
+       If multiple `-m` options are given, there values are
+       concatenated as separate paragraphs.
 
 -F <file>::
        Take the tag message from the given file.  Use '-' to
index 546020100a533b99126adb1635299e7d025bca4b..9ff4659d8c021465758332270aeaa2c88a593b14 100644 (file)
@@ -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.7.txt[1.5.3.7],
   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],
diff --git a/Documentation/howto/maintain-git.txt b/Documentation/howto/maintain-git.txt
new file mode 100644 (file)
index 0000000..4357e26
--- /dev/null
@@ -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.
index 518b7b5c9e283eccd20ce2d84ea85f107c98ca39..93a47b439b4504467fc5ba7612b8205367f347c2 100644 (file)
@@ -56,11 +56,12 @@ $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
 The initial clone may be time-consuming for a large project, but you
 will only need to clone once.
 
-The clone command creates a new directory named after the project
-("git" or "linux-2.6" in the examples above).  After you cd into this
+The clone command creates a new directory named after the project ("git"
+or "linux-2.6" in the examples above).  After you cd into this
 directory, you will see that it contains a copy of the project files,
-together with a special top-level directory named ".git", which
-contains all the information about the history of the project.
+called the <<def_working_tree,working tree>>, together with a special
+top-level directory named ".git", which contains all the information
+about the history of the project.
 
 [[how-to-check-out]]
 How to check out a different version of a project
@@ -71,8 +72,13 @@ of files.  It stores the history as a compressed collection of
 interrelated snapshots of the project's contents.  In git each such
 version is called a <<def_commit,commit>>.
 
-A single git repository may contain multiple branches.  It keeps track
-of them by keeping a list of <<def_head,heads>> which reference the
+Those snapshots aren't necessarily all arranged in a single line from
+oldest to newest; instead, work may simultaneously proceed along
+parallel lines of development, called <def_branch,branches>>, which may
+merge and diverge.
+
+A single git repository can track development on multiple branches.  It
+does this by keeping a list of <<def_head,heads>> which reference the
 latest commit on each branch; the gitlink:git-branch[1] command shows
 you the list of branch heads:
 
@@ -658,16 +664,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
@@ -1403,8 +1416,8 @@ with the changes to be reverted, then you will be asked to fix
 conflicts manually, just as in the case of <<resolving-a-merge,
 resolving a merge>>.
 
-[[fixing-a-mistake-by-editing-history]]
-Fixing a mistake by editing history
+[[fixing-a-mistake-by-rewriting-history]]
+Fixing a mistake by rewriting history
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 If the problematic commit is the most recent commit, and you have not
@@ -1427,7 +1440,7 @@ Again, you should never do this to a commit that may already have
 been merged into another branch; use gitlink:git-revert[1] instead in
 that case.
 
-It is also possible to edit commits further back in the history, but
+It is also possible to replace commits further back in the history, but
 this is an advanced topic to be left for
 <<cleaning-up-history,another chapter>>.
 
@@ -1547,6 +1560,11 @@ This may be time-consuming.  Unlike most other git operations (including
 git-gc when run without any options), it is not safe to prune while
 other git operations are in progress in the same repository.
 
+If gitlink:git-fsck[1] complains about sha1 mismatches or missing
+objects, you may have a much more serious problem; your best option is
+probably restoring from backups.  See
+<<recovering-from-repository-corruption>> for a detailed discussion.
+
 [[recovering-lost-changes]]
 Recovering lost changes
 ~~~~~~~~~~~~~~~~~~~~~~~
@@ -1916,15 +1934,9 @@ or just
 $ git push ssh://yourserver.com/~you/proj.git master
 -------------------------------------------------
 
-As with git-fetch, git-push will complain if this does not result in
-a <<fast-forwards,fast forward>>.  Normally this is a sign of
-something wrong.  However, if you are sure you know what you're
-doing, you may force git-push to perform the update anyway by
-preceding the branch name by a plus sign:
-
--------------------------------------------------
-$ git push ssh://yourserver.com/~you/proj.git +master
--------------------------------------------------
+As with git-fetch, git-push will complain if this does not result in a
+<<fast-forwards,fast forward>>; see the following section for details on
+handling this case.
 
 Note that the target of a "push" is normally a
 <<def_bare_repository,bare>> repository.  You can also push to a
@@ -1952,6 +1964,52 @@ See the explanations of the remote.<name>.url, branch.<name>.remote,
 and remote.<name>.push options in gitlink:git-config[1] for
 details.
 
+[[forcing-push]]
+What to do when a push fails
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If a push would not result in a <<fast-forwards,fast forward>> of the
+remote branch, then it will fail with an error like:
+
+-------------------------------------------------
+error: remote 'refs/heads/master' is not an ancestor of
+ local  'refs/heads/master'.
+ Maybe you are not up-to-date and need to pull first?
+error: failed to push to 'ssh://yourserver.com/~you/proj.git'
+-------------------------------------------------
+
+This can happen, for example, if you:
+
+       - use `git reset --hard` to remove already-published commits, or
+       - use `git commit --amend` to replace already-published commits
+         (as in <<fixing-a-mistake-by-rewriting-history>>), or
+       - use `git rebase` to rebase any already-published commits (as
+         in <<using-git-rebase>>).
+
+You may force git-push to perform the update anyway by preceding the
+branch name with a plus sign:
+
+-------------------------------------------------
+$ git push ssh://yourserver.com/~you/proj.git +master
+-------------------------------------------------
+
+Normally whenever a branch head in a public repository is modified, it
+is modified to point to a descendent of the commit that it pointed to
+before.  By forcing a push in this situation, you break that convention.
+(See <<problems-with-rewriting-history>>.)
+
+Nevertheless, this is a common practice for people that need a simple
+way to publish a work-in-progress patch series, and it is an acceptable
+compromise as long as you warn other developers that this is how you
+intend to manage the branch.
+
+It's also possible for a push to fail in this way when other people have
+the right to push to the same repository.  In that case, the correct
+solution is to retry the push after first updating your work by either a
+pull or a fetch followed by a rebase; see the
+<<setting-up-a-shared-repository,next section>> and
+link:cvs-migration.html[git for CVS users] for more.
+
 [[setting-up-a-shared-repository]]
 Setting up a shared repository
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2419,11 +2477,11 @@ return mywork to the state it had before you started the rebase:
 $ git rebase --abort
 -------------------------------------------------
 
-[[modifying-one-commit]]
-Modifying a single commit
+[[rewriting-one-commit]]
+Rewriting a single commit
 -------------------------
 
-We saw in <<fixing-a-mistake-by-editing-history>> that you can replace the
+We saw in <<fixing-a-mistake-by-rewriting-history>> that you can replace the
 most recent commit using
 
 -------------------------------------------------
@@ -2433,8 +2491,10 @@ $ git commit --amend
 which will replace the old commit by a new commit incorporating your
 changes, giving you a chance to edit the old commit message first.
 
-You can also use a combination of this and gitlink:git-rebase[1] to edit
-commits further back in your history.  First, tag the problematic commit with
+You can also use a combination of this and gitlink:git-rebase[1] to
+replace a commit further back in your history and recreate the
+intervening changes on top of it.  First, tag the problematic commit
+with
 
 -------------------------------------------------
 $ git tag bad mywork~5
@@ -2554,6 +2614,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
 ==========================
@@ -3099,6 +3225,127 @@ confusing and scary messages, but it won't actually do anything bad. In
 contrast, running "git prune" while somebody is actively changing the
 repository is a *BAD* idea).
 
+[[recovering-from-repository-corruption]]
+Recovering from repository corruption
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By design, git treats data trusted to it with caution.  However, even in
+the absence of bugs in git itself, it is still possible that hardware or
+operating system errors could corrupt data.
+
+The first defense against such problems is backups.  You can back up a
+git directory using clone, or just using cp, tar, or any other backup
+mechanism.
+
+As a last resort, you can search for the corrupted objects and attempt
+to replace them by hand.  Back up your repository before attempting this
+in case you corrupt things even more in the process.
+
+We'll assume that the problem is a single missing or corrupted blob,
+which is sometimes a solveable problem.  (Recovering missing trees and
+especially commits is *much* harder).
+
+Before starting, verify that there is corruption, and figure out where
+it is with gitlink:git-fsck[1]; this may be time-consuming.
+
+Assume the output looks like this:
+
+------------------------------------------------
+$ git-fsck --full
+broken link from    tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
+              to    blob 4b9458b3786228369c63936db65827de3cc06200
+missing blob 4b9458b3786228369c63936db65827de3cc06200
+------------------------------------------------
+
+(Typically there will be some "dangling object" messages too, but they
+aren't interesting.)
+
+Now you know that blob 4b9458b3 is missing, and that the tree 2d9263c6
+points to it.  If you could find just one copy of that missing blob
+object, possibly in some other repository, you could move it into
+.git/objects/4b/9458b3... and be done.  Suppose you can't.  You can
+still examine the tree that pointed to it with gitlink:git-ls-tree[1],
+which might output something like:
+
+------------------------------------------------
+$ git ls-tree 2d9263c6d23595e7cb2a21e5ebbb53655278dff8
+100644 blob 8d14531846b95bfa3564b58ccfb7913a034323b8   .gitignore
+100644 blob ebf9bf84da0aab5ed944264a5db2a65fe3a3e883   .mailmap
+100644 blob ca442d313d86dc67e0a2e5d584b465bd382cbf5c   COPYING
+...
+100644 blob 4b9458b3786228369c63936db65827de3cc06200   myfile
+...
+------------------------------------------------
+
+So now you know that the missing blob was the data for a file named
+"myfile".  And chances are you can also identify the directory--let's
+say it's in "somedirectory".  If you're lucky the missing copy might be
+the same as the copy you have checked out in your working tree at
+"somedirectory/myfile"; you can test whether that's right with
+gitlink:git-hash-object[1]:
+
+------------------------------------------------
+$ git hash-object -w somedirectory/myfile
+------------------------------------------------
+
+which will create and store a blob object with the contents of
+somedirectory/myfile, and output the sha1 of that object.  if you're
+extremely lucky it might be 4b9458b3786228369c63936db65827de3cc06200, in
+which case you've guessed right, and the corruption is fixed!
+
+Otherwise, you need more information.  How do you tell which version of
+the file has been lost?
+
+The easiest way to do this is with:
+
+------------------------------------------------
+$ git log --raw --all --full-history -- somedirectory/myfile
+------------------------------------------------
+
+Because you're asking for raw output, you'll now get something like
+
+------------------------------------------------
+commit abc
+Author:
+Date:
+...
+:100644 100644 4b9458b... newsha... M somedirectory/myfile
+
+
+commit xyz
+Author:
+Date:
+
+...
+:100644 100644 oldsha... 4b9458b... M somedirectory/myfile
+------------------------------------------------
+
+This tells you that the immediately preceding version of the file was
+"newsha", and that the immediately following version was "oldsha".
+You also know the commit messages that went with the change from oldsha
+to 4b9458b and with the change from 4b9458b to newsha.
+
+If you've been committing small enough changes, you may now have a good
+shot at reconstructing the contents of the in-between state 4b9458b.
+
+If you can do that, you can now recreate the missing object with
+
+------------------------------------------------
+$ git hash-object -w <recreated-file>
+------------------------------------------------
+
+and your repository is good again!
+
+(Btw, you could have ignored the fsck, and started with doing a
+
+------------------------------------------------
+$ git log --raw --all
+------------------------------------------------
+
+and just looked for the sha of the missing object (4b9458b..) in that
+whole thing. It's up to you - git does *have* a lot of information, it is
+just missing one particular blob version.
+
 [[the-index]]
 The index
 -----------
@@ -3460,7 +3707,7 @@ should use the `--remove` and `--add` flags respectively.
 NOTE! A `--remove` flag does 'not' mean that subsequent filenames will
 necessarily be removed: if the files still exist in your directory
 structure, the index will be updated with their new status, not
-removed. The only thing `--remove` means is that update-cache will be
+removed. The only thing `--remove` means is that update-index will be
 considering a removed file to be a valid thing, and if the file really
 does not exist any more, it will update the index accordingly.
 
@@ -4309,4 +4556,7 @@ Write a chapter on using plumbing and writing scripts.
 
 Alternates, clone -reference, etc.
 
-git unpack-objects -r for recovery
+More on recovery from repository corruption.  See:
+       http://marc.theaimsgroup.com/?l=git&m=117263864820799&w=2
+       http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2
+       http://marc.theaimsgroup.com/?l=git&m=117147855503798&w=2
index 251244ecd18adff0a0b4cbf6bd8596cb2bda3056..a7e44a3d75456688acc2d33b407ceff23021fd37 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -111,7 +111,7 @@ all::
 # times (my ext3 doesn't).
 #
 # Define USE_STDEV below if you want git to care about the underlying device
-# change being considered an inode change from the update-cache perspective.
+# change being considered an inode change from the update-index perspective.
 #
 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
 #
@@ -213,15 +213,14 @@ BASIC_LDFLAGS =
 
 SCRIPT_SH = \
        git-bisect.sh git-checkout.sh \
-       git-clean.sh git-clone.sh git-commit.sh \
-       git-ls-remote.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
@@ -243,7 +242,7 @@ PROGRAMS = \
        git-fast-import$X \
        git-daemon$X \
        git-merge-index$X git-mktag$X git-mktree$X git-patch-id$X \
-       git-peek-remote$X git-receive-pack$X \
+       git-receive-pack$X \
        git-send-pack$X git-shell$X \
        git-show-index$X \
        git-unpack-file$X \
@@ -327,6 +326,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 \
@@ -346,10 +346,12 @@ BUILTIN_OBJS = \
        builtin-log.o \
        builtin-ls-files.o \
        builtin-ls-tree.o \
+       builtin-ls-remote.o \
        builtin-mailinfo.o \
        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 \
@@ -358,6 +360,7 @@ BUILTIN_OBJS = \
        builtin-push.o \
        builtin-read-tree.o \
        builtin-reflog.o \
+       builtin-send-pack.o \
        builtin-config.o \
        builtin-rerere.o \
        builtin-reset.o \
@@ -750,7 +753,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)
@@ -894,6 +897,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)"' $<
 
index 2694c9cf497bb0f20c771a560d65eae5702bf931..c64768beb2c112fc32a65fb4070f01331ebf1540 100644 (file)
@@ -184,9 +184,30 @@ struct ref_item {
 struct ref_list {
        int index, alloc, maxwidth;
        struct ref_item *list;
+       struct commit_list *with_commit;
        int kinds;
 };
 
+static int has_commit(const unsigned char *sha1, struct commit_list *with_commit)
+{
+       struct commit *commit;
+
+       if (!with_commit)
+               return 1;
+       commit = lookup_commit_reference_gently(sha1, 1);
+       if (!commit)
+               return 0;
+       while (with_commit) {
+               struct commit *other;
+
+               other = with_commit->item;
+               with_commit = with_commit->next;
+               if (in_merge_bases(other, &commit, 1))
+                       return 1;
+       }
+       return 0;
+}
+
 static int append_ref(const char *refname, const unsigned char *sha1, int flags, void *cb_data)
 {
        struct ref_list *ref_list = (struct ref_list*)(cb_data);
@@ -206,6 +227,10 @@ static int append_ref(const char *refname, const unsigned char *sha1, int flags,
                refname += 10;
        }
 
+       /* Filter with with_commit if specified */
+       if (!has_commit(sha1, ref_list->with_commit))
+               return 0;
+
        /* Don't add types the caller doesn't want */
        if ((kind & ref_list->kinds) == 0)
                return 0;
@@ -296,19 +321,20 @@ static void print_ref_item(struct ref_item *item, int maxwidth, int verbose,
        }
 }
 
-static void print_ref_list(int kinds, int detached, int verbose, int abbrev)
+static void print_ref_list(int kinds, int detached, int verbose, int abbrev, struct commit_list *with_commit)
 {
        int i;
        struct ref_list ref_list;
 
        memset(&ref_list, 0, sizeof(ref_list));
        ref_list.kinds = kinds;
+       ref_list.with_commit = with_commit;
        for_each_ref(append_ref, &ref_list);
 
        qsort(ref_list.list, ref_list.index, sizeof(struct ref_item), ref_cmp);
 
        detached = (detached && (kinds & REF_LOCAL_BRANCH));
-       if (detached) {
+       if (detached && has_commit(head_sha1, with_commit)) {
                struct ref_item item;
                item.name = xstrdup("(no branch)");
                item.kind = REF_LOCAL_BRANCH;
@@ -505,12 +531,29 @@ static void rename_branch(const char *oldname, const char *newname, int force)
                die("Branch is renamed, but update of config-file failed");
 }
 
+static int opt_parse_with_commit(const struct option *opt, const char *arg, int unset)
+{
+       unsigned char sha1[20];
+       struct commit *commit;
+
+       if (!arg)
+               return -1;
+       if (get_sha1(arg, sha1))
+               die("malformed object name %s", arg);
+       commit = lookup_commit_reference(sha1);
+       if (!commit)
+               die("no such commit %s", arg);
+       commit_list_insert(commit, opt->value);
+       return 0;
+}
+
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
        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;
+       struct commit_list *with_commit = NULL;
 
        struct option options[] = {
                OPT_GROUP("Generic options"),
@@ -519,6 +562,14 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
                OPT_BOOLEAN( 0 , "color",  &branch_use_color, "use colored output"),
                OPT_SET_INT('r', NULL,     &kinds, "act on remote-tracking branches",
                        REF_REMOTE_BRANCH),
+               OPT_CALLBACK(0, "contains", &with_commit, "commit",
+                            "print only branches that contain the commit",
+                            opt_parse_with_commit),
+               {
+                       OPTION_CALLBACK, 0, "with", &with_commit, "commit",
+                       "print only branches that contain the commit",
+                       PARSE_OPT_HIDDEN, opt_parse_with_commit,
+               },
                OPT__ABBREV(&abbrev),
 
                OPT_GROUP("Specific git-branch actions:"),
@@ -554,7 +605,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
        if (delete)
                return delete_branches(argc, argv, delete > 1, kinds);
        else if (argc == 0)
-               print_ref_list(kinds, detached, verbose, abbrev);
+               print_ref_list(kinds, detached, verbose, abbrev, with_commit);
        else if (rename && (argc == 1))
                rename_branch(head, argv[0], rename > 1);
        else if (rename && (argc == 2))
diff --git a/builtin-clean.c b/builtin-clean.c
new file mode 100644 (file)
index 0000000..56ae4eb
--- /dev/null
@@ -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;
+}
index e5e243f27cb7ecab11ac0933a361d066f5b35ea9..f672c9cccaeb460a0f0c55ad3e9d2ada95ed1e81 100644 (file)
@@ -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);
index ed60847d9fcd0ad8803c432af8d0bc2dd3567768..7460ab7fce2a4e6a7e014f448819140e2204ccb7 100644 (file)
@@ -511,10 +511,14 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
        if (!strcmp("append-fetch-head", argv[1])) {
                int result;
                FILE *fp;
+               char *filename;
 
                if (argc != 8)
                        return error("append-fetch-head takes 6 args");
-               fp = fopen(git_path("FETCH_HEAD"), "a");
+               filename = git_path("FETCH_HEAD");
+               fp = fopen(filename, "a");
+               if (!fp)
+                       return error("cannot open %s: %s\n", filename, strerror(errno));
                result = append_fetch_head(fp, argv[2], argv[3],
                                           argv[4], argv[5],
                                           argv[6], !!argv[7][0],
@@ -525,10 +529,14 @@ int cmd_fetch__tool(int argc, const char **argv, const char *prefix)
        if (!strcmp("native-store", argv[1])) {
                int result;
                FILE *fp;
+               char *filename;
 
                if (argc != 5)
                        return error("fetch-native-store takes 3 args");
-               fp = fopen(git_path("FETCH_HEAD"), "a");
+               filename = git_path("FETCH_HEAD");
+               fp = fopen(filename, "a");
+               if (!fp)
+                       return error("cannot open %s: %s\n", filename, strerror(errno));
                result = fetch_native_store(fp, argv[2], argv[3], argv[4],
                                            verbose, force);
                fclose(fp);
index bb1742f1a267042a00f0a81bca32a4eefe87fd5d..807fa93b53ad16552b7d869470f2ab59a325808a 100644 (file)
@@ -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);
 
index be9e3ea2bcea0d0ab88a51d396aff5714822b77a..de9947e7ac2cc1236909fab813198b3df93bd39e 100644 (file)
@@ -31,7 +31,7 @@ static void unlock_pack_on_signal(int signo)
 }
 
 static void add_merge_config(struct ref **head,
-                          struct ref *remote_refs,
+                          const struct ref *remote_refs,
                           struct branch *branch,
                           struct ref ***tail)
 {
@@ -79,7 +79,7 @@ static struct ref *get_ref_map(struct transport *transport,
        struct ref *ref_map = NULL;
        struct ref **tail = &ref_map;
 
-       struct ref *remote_refs = transport_get_remote_refs(transport);
+       const struct ref *remote_refs = transport_get_remote_refs(transport);
 
        if (ref_count || tags) {
                for (i = 0; i < ref_count; i++) {
@@ -255,7 +255,7 @@ static int update_local_ref(struct ref *ref,
        }
 }
 
-static void store_updated_refs(const char *url, struct ref *ref_map)
+static int store_updated_refs(const char *url, struct ref *ref_map)
 {
        FILE *fp;
        struct commit *commit;
@@ -263,8 +263,11 @@ static void store_updated_refs(const char *url, struct ref *ref_map)
        char note[1024];
        const char *what, *kind;
        struct ref *rm;
+       char *filename = git_path("FETCH_HEAD");
 
-       fp = fopen(git_path("FETCH_HEAD"), "a");
+       fp = fopen(filename, "a");
+       if (!fp)
+               return error("cannot open %s: %s\n", filename, strerror(errno));
        for (rm = ref_map; rm; rm = rm->next) {
                struct ref *ref = NULL;
 
@@ -335,6 +338,7 @@ static void store_updated_refs(const char *url, struct ref *ref_map)
                }
        }
        fclose(fp);
+       return 0;
 }
 
 /*
@@ -404,7 +408,7 @@ static int fetch_refs(struct transport *transport, struct ref *ref_map)
        if (ret)
                ret = transport_fetch_refs(transport, ref_map);
        if (!ret)
-               store_updated_refs(transport->url, ref_map);
+               ret |= store_updated_refs(transport->url, ref_map);
        transport_unlock_pack(transport);
        return ret;
 }
@@ -424,12 +428,12 @@ static struct ref *find_non_local_tags(struct transport *transport,
        struct path_list new_refs = { NULL, 0, 0, 1 };
        char *ref_name;
        int ref_name_len;
-       unsigned char *ref_sha1;
-       struct ref *tag_ref;
+       const unsigned char *ref_sha1;
+       const struct ref *tag_ref;
        struct ref *rm = NULL;
        struct ref *ref_map = NULL;
        struct ref **tail = &ref_map;
-       struct ref *ref;
+       const struct ref *ref;
 
        for_each_ref(add_existing, &existing_refs);
        for (ref = transport_get_remote_refs(transport); ref; ref = ref->next) {
@@ -487,8 +491,13 @@ static int do_fetch(struct transport *transport,
                die("Don't know how to fetch from %s", transport->url);
 
        /* if not appending, truncate FETCH_HEAD */
-       if (!append)
-               fclose(fopen(git_path("FETCH_HEAD"), "w"));
+       if (!append) {
+               char *filename = git_path("FETCH_HEAD");
+               FILE *fp = fopen(filename, "w");
+               if (!fp)
+                       return error("cannot open %s: %s\n", filename, strerror(errno));
+               fclose(fp);
+       }
 
        ref_map = get_ref_map(transport, refs, ref_count, tags, &autotags);
 
index 763fa55e76ef5b7e2f244f11199b5925382dac92..e1393b8d1e74c03ff2b45ec93e268daa2e286fd8 100644 (file)
@@ -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-ls-remote.c b/builtin-ls-remote.c
new file mode 100644 (file)
index 0000000..56f3f88
--- /dev/null
@@ -0,0 +1,74 @@
+#include "builtin.h"
+#include "cache.h"
+#include "transport.h"
+#include "remote.h"
+
+static const char ls_remote_usage[] =
+"git-ls-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
+
+int cmd_ls_remote(int argc, const char **argv, const char *prefix)
+{
+       int i;
+       const char *dest = NULL;
+       int nongit = 0;
+       unsigned flags = 0;
+       const char *uploadpack = NULL;
+
+       struct remote *remote;
+       struct transport *transport;
+       const struct ref *ref;
+
+       setup_git_directory_gently(&nongit);
+
+       for (i = 1; i < argc; i++) {
+               const char *arg = argv[i];
+
+               if (*arg == '-') {
+                       if (!prefixcmp(arg, "--upload-pack=")) {
+                               uploadpack = arg + 14;
+                               continue;
+                       }
+                       if (!prefixcmp(arg, "--exec=")) {
+                               uploadpack = arg + 7;
+                               continue;
+                       }
+                       if (!strcmp("--tags", arg)) {
+                               flags |= REF_TAGS;
+                               continue;
+                       }
+                       if (!strcmp("--heads", arg)) {
+                               flags |= REF_HEADS;
+                               continue;
+                       }
+                       if (!strcmp("--refs", arg)) {
+                               flags |= REF_NORMAL;
+                               continue;
+                       }
+                       usage(ls_remote_usage);
+               }
+               dest = arg;
+               break;
+       }
+
+       if (!dest || i != argc - 1)
+               usage(ls_remote_usage);
+
+       remote = nongit ? NULL : remote_get(dest);
+       if (remote && !remote->url_nr)
+               die("remote %s has no configured URL", dest);
+       transport = transport_get(remote, remote ? remote->url[0] : dest);
+       if (uploadpack != NULL)
+               transport_set_option(transport, TRANS_OPT_UPLOADPACK, uploadpack);
+
+       ref = transport_get_remote_refs(transport);
+
+       if (!ref)
+               return 1;
+
+       while (ref) {
+               if (check_ref_type(ref, flags))
+                       printf("%s      %s\n", sha1_to_hex(ref->old_sha1), ref->name);
+               ref = ref->next;
+       }
+       return 0;
+}
diff --git a/builtin-merge-ours.c b/builtin-merge-ours.c
new file mode 100644 (file)
index 0000000..8f5bbaf
--- /dev/null
@@ -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);
+}
index 6d1da07c46704f3de837044652f0a1fd149327ad..41df717f847ecc41bf0a695fa09fbb926b42f720 100644 (file)
@@ -10,7 +10,7 @@
 #include "parse-options.h"
 
 static const char * const push_usage[] = {
-       "git-push [--all] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
+       "git-push [--all | --mirror] [--dry-run] [--tags] [--receive-pack=<git-receive-pack>] [--repo=all] [-f | --force] [-v] [<repository> <refspec>...]",
        NULL,
 };
 
@@ -91,6 +91,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
 {
        int flags = 0;
        int all = 0;
+       int mirror = 0;
        int dry_run = 0;
        int force = 0;
        int tags = 0;
@@ -100,6 +101,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                OPT__VERBOSE(&verbose),
                OPT_STRING( 0 , "repo", &repo, "repository", "repository"),
                OPT_BOOLEAN( 0 , "all", &all, "push all refs"),
+               OPT_BOOLEAN( 0 , "mirror", &mirror, "mirror all refs"),
                OPT_BOOLEAN( 0 , "tags", &tags, "push tags"),
                OPT_BOOLEAN( 0 , "dry-run", &dry_run, "dry run"),
                OPT_BOOLEAN('f', "force", &force, "force updates"),
@@ -121,13 +123,21 @@ int cmd_push(int argc, const char **argv, const char *prefix)
                add_refspec("refs/tags/*");
        if (all)
                flags |= TRANSPORT_PUSH_ALL;
+       if (mirror)
+               flags |= (TRANSPORT_PUSH_MIRROR|TRANSPORT_PUSH_FORCE);
 
        if (argc > 0) {
                repo = argv[0];
                set_refspecs(argv + 1, argc - 1);
        }
-       if ((flags & TRANSPORT_PUSH_ALL) && refspec)
+       if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) && refspec)
                usage_with_options(push_usage, options);
 
+       if ((flags & (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) ==
+                               (TRANSPORT_PUSH_ALL|TRANSPORT_PUSH_MIRROR)) {
+               error("--all and --mirror are incompatible");
+               usage_with_options(push_usage, options);
+       }
+
        return do_push(repo, flags);
 }
index 365b330f9e1f2989683611077d260fa49abcb889..a0586f9753189d13d5af1c790ea875a5f383f34f 100644 (file)
@@ -30,7 +30,7 @@ static const char * const cherry_pick_usage[] = {
        NULL
 };
 
-static int edit, no_replay, no_commit, needed_deref, mainline;
+static int edit, no_replay, no_commit, mainline;
 static enum { REVERT, CHERRY_PICK } action;
 static struct commit *commit;
 
@@ -66,7 +66,6 @@ static void parse_args(int argc, const char **argv)
        if (commit->object.type == OBJ_TAG) {
                commit = (struct commit *)
                        deref_tag((struct object *)commit, arg, strlen(arg));
-               needed_deref = 1;
        }
        if (commit->object.type != OBJ_COMMIT)
                die ("'%s' does not point to a commit", arg);
@@ -333,17 +332,6 @@ static int revert_or_cherry_pick(int argc, const char **argv)
                        add_to_msg(")\n");
                }
        }
-       if (needed_deref) {
-               add_to_msg("(original 'git ");
-               add_to_msg(me);
-               add_to_msg("' arguments: ");
-               for (i = 0; i < argc; i++) {
-                       if (i)
-                               add_to_msg(" ");
-                       add_to_msg(argv[i]);
-               }
-               add_to_msg(")\n");
-       }
 
        if (merge_recursive(sha1_to_hex(base->object.sha1),
                                sha1_to_hex(head), "HEAD",
diff --git a/builtin-send-pack.c b/builtin-send-pack.c
new file mode 100644 (file)
index 0000000..25ae1fe
--- /dev/null
@@ -0,0 +1,652 @@
+#include "cache.h"
+#include "commit.h"
+#include "tag.h"
+#include "refs.h"
+#include "pkt-line.h"
+#include "run-command.h"
+#include "remote.h"
+#include "send-pack.h"
+
+static const char send_pack_usage[] =
+"git-send-pack [--all | --mirror] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
+"  --all and explicit <ref> specification are mutually exclusive.";
+
+static struct send_pack_args args = {
+       /* .receivepack = */ "git-receive-pack",
+};
+
+/*
+ * Make a pack stream and spit it out into file descriptor fd
+ */
+static int pack_objects(int fd, struct ref *refs)
+{
+       /*
+        * The child becomes pack-objects --revs; we feed
+        * the revision parameters to it via its stdin and
+        * let its stdout go back to the other end.
+        */
+       const char *argv[] = {
+               "pack-objects",
+               "--all-progress",
+               "--revs",
+               "--stdout",
+               NULL,
+               NULL,
+       };
+       struct child_process po;
+
+       if (args.use_thin_pack)
+               argv[4] = "--thin";
+       memset(&po, 0, sizeof(po));
+       po.argv = argv;
+       po.in = -1;
+       po.out = fd;
+       po.git_cmd = 1;
+       if (start_command(&po))
+               die("git-pack-objects failed (%s)", strerror(errno));
+
+       /*
+        * We feed the pack-objects we just spawned with revision
+        * parameters by writing to the pipe.
+        */
+       while (refs) {
+               char buf[42];
+
+               if (!is_null_sha1(refs->old_sha1) &&
+                   has_sha1_file(refs->old_sha1)) {
+                       memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
+                       buf[0] = '^';
+                       buf[41] = '\n';
+                       if (!write_or_whine(po.in, buf, 42,
+                                               "send-pack: send refs"))
+                               break;
+               }
+               if (!is_null_sha1(refs->new_sha1)) {
+                       memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
+                       buf[40] = '\n';
+                       if (!write_or_whine(po.in, buf, 41,
+                                               "send-pack: send refs"))
+                               break;
+               }
+               refs = refs->next;
+       }
+
+       if (finish_command(&po))
+               return error("pack-objects died with strange error");
+       return 0;
+}
+
+static void unmark_and_free(struct commit_list *list, unsigned int mark)
+{
+       while (list) {
+               struct commit_list *temp = list;
+               temp->item->object.flags &= ~mark;
+               list = temp->next;
+               free(temp);
+       }
+}
+
+static int ref_newer(const unsigned char *new_sha1,
+                    const unsigned char *old_sha1)
+{
+       struct object *o;
+       struct commit *old, *new;
+       struct commit_list *list, *used;
+       int found = 0;
+
+       /* Both new and old must be commit-ish and new is descendant of
+        * old.  Otherwise we require --force.
+        */
+       o = deref_tag(parse_object(old_sha1), NULL, 0);
+       if (!o || o->type != OBJ_COMMIT)
+               return 0;
+       old = (struct commit *) o;
+
+       o = deref_tag(parse_object(new_sha1), NULL, 0);
+       if (!o || o->type != OBJ_COMMIT)
+               return 0;
+       new = (struct commit *) o;
+
+       if (parse_commit(new) < 0)
+               return 0;
+
+       used = list = NULL;
+       commit_list_insert(new, &list);
+       while (list) {
+               new = pop_most_recent_commit(&list, 1);
+               commit_list_insert(new, &used);
+               if (new == old) {
+                       found = 1;
+                       break;
+               }
+       }
+       unmark_and_free(list, 1);
+       unmark_and_free(used, 1);
+       return found;
+}
+
+static struct ref *local_refs, **local_tail;
+static struct ref *remote_refs, **remote_tail;
+
+static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
+{
+       struct ref *ref;
+       int len = strlen(refname) + 1;
+       ref = xcalloc(1, sizeof(*ref) + len);
+       hashcpy(ref->new_sha1, sha1);
+       memcpy(ref->name, refname, len);
+       *local_tail = ref;
+       local_tail = &ref->next;
+       return 0;
+}
+
+static void get_local_heads(void)
+{
+       local_tail = &local_refs;
+       for_each_ref(one_local_ref, NULL);
+}
+
+static int receive_status(int in, struct ref *refs)
+{
+       struct ref *hint;
+       char line[1000];
+       int ret = 0;
+       int len = packet_read_line(in, line, sizeof(line));
+       if (len < 10 || memcmp(line, "unpack ", 7))
+               return error("did not receive remote status");
+       if (memcmp(line, "unpack ok\n", 10)) {
+               char *p = line + strlen(line) - 1;
+               if (*p == '\n')
+                       *p = '\0';
+               error("unpack failed: %s", line + 7);
+               ret = -1;
+       }
+       hint = NULL;
+       while (1) {
+               char *refname;
+               char *msg;
+               len = packet_read_line(in, line, sizeof(line));
+               if (!len)
+                       break;
+               if (len < 3 ||
+                   (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) {
+                       fprintf(stderr, "protocol error: %s\n", line);
+                       ret = -1;
+                       break;
+               }
+
+               line[strlen(line)-1] = '\0';
+               refname = line + 3;
+               msg = strchr(refname, ' ');
+               if (msg)
+                       *msg++ = '\0';
+
+               /* first try searching at our hint, falling back to all refs */
+               if (hint)
+                       hint = find_ref_by_name(hint, refname);
+               if (!hint)
+                       hint = find_ref_by_name(refs, refname);
+               if (!hint) {
+                       warning("remote reported status on unknown ref: %s",
+                                       refname);
+                       continue;
+               }
+               if (hint->status != REF_STATUS_EXPECTING_REPORT) {
+                       warning("remote reported status on unexpected ref: %s",
+                                       refname);
+                       continue;
+               }
+
+               if (line[0] == 'o' && line[1] == 'k')
+                       hint->status = REF_STATUS_OK;
+               else {
+                       hint->status = REF_STATUS_REMOTE_REJECT;
+                       ret = -1;
+               }
+               if (msg)
+                       hint->remote_status = xstrdup(msg);
+               /* start our next search from the next ref */
+               hint = hint->next;
+       }
+       return ret;
+}
+
+static void update_tracking_ref(struct remote *remote, struct ref *ref)
+{
+       struct refspec rs;
+
+       if (ref->status != REF_STATUS_OK)
+               return;
+
+       rs.src = ref->name;
+       rs.dst = NULL;
+
+       if (!remote_find_tracking(remote, &rs)) {
+               if (args.verbose)
+                       fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
+               if (ref->deletion) {
+                       if (delete_ref(rs.dst, NULL))
+                               error("Failed to delete");
+               } else
+                       update_ref("update by push", rs.dst,
+                                       ref->new_sha1, NULL, 0, 0);
+               free(rs.dst);
+       }
+}
+
+static const char *prettify_ref(const struct ref *ref)
+{
+       const char *name = ref->name;
+       return name + (
+               !prefixcmp(name, "refs/heads/") ? 11 :
+               !prefixcmp(name, "refs/tags/") ? 10 :
+               !prefixcmp(name, "refs/remotes/") ? 13 :
+               0);
+}
+
+#define SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3)
+
+static void print_ref_status(char flag, const char *summary, struct ref *to, struct ref *from, const char *msg)
+{
+       fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
+       if (from)
+               fprintf(stderr, "%s -> %s", prettify_ref(from), prettify_ref(to));
+       else
+               fputs(prettify_ref(to), stderr);
+       if (msg) {
+               fputs(" (", stderr);
+               fputs(msg, stderr);
+               fputc(')', stderr);
+       }
+       fputc('\n', stderr);
+}
+
+static const char *status_abbrev(unsigned char sha1[20])
+{
+       const char *abbrev;
+       abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV);
+       return abbrev ? abbrev : sha1_to_hex(sha1);
+}
+
+static void print_ok_ref_status(struct ref *ref)
+{
+       if (ref->deletion)
+               print_ref_status('-', "[deleted]", ref, NULL, NULL);
+       else if (is_null_sha1(ref->old_sha1))
+               print_ref_status('*',
+                       (!prefixcmp(ref->name, "refs/tags/") ? "[new tag]" :
+                         "[new branch]"),
+                       ref, ref->peer_ref, NULL);
+       else {
+               char quickref[84];
+               char type;
+               const char *msg;
+
+               strcpy(quickref, status_abbrev(ref->old_sha1));
+               if (ref->nonfastforward) {
+                       strcat(quickref, "...");
+                       type = '+';
+                       msg = "forced update";
+               } else {
+                       strcat(quickref, "..");
+                       type = ' ';
+                       msg = NULL;
+               }
+               strcat(quickref, status_abbrev(ref->new_sha1));
+
+               print_ref_status(type, quickref, ref, ref->peer_ref, msg);
+       }
+}
+
+static int print_one_push_status(struct ref *ref, const char *dest, int count)
+{
+       if (!count)
+               fprintf(stderr, "To %s\n", dest);
+
+       switch(ref->status) {
+       case REF_STATUS_NONE:
+               print_ref_status('X', "[no match]", ref, NULL, NULL);
+               break;
+       case REF_STATUS_REJECT_NODELETE:
+               print_ref_status('!', "[rejected]", ref, NULL,
+                               "remote does not support deleting refs");
+               break;
+       case REF_STATUS_UPTODATE:
+               print_ref_status('=', "[up to date]", ref,
+                               ref->peer_ref, NULL);
+               break;
+       case REF_STATUS_REJECT_NONFASTFORWARD:
+               print_ref_status('!', "[rejected]", ref, ref->peer_ref,
+                               "non-fast forward");
+               break;
+       case REF_STATUS_REMOTE_REJECT:
+               print_ref_status('!', "[remote rejected]", ref,
+                               ref->deletion ? NULL : ref->peer_ref,
+                               ref->remote_status);
+               break;
+       case REF_STATUS_EXPECTING_REPORT:
+               print_ref_status('!', "[remote failure]", ref,
+                               ref->deletion ? NULL : ref->peer_ref,
+                               "remote failed to report status");
+               break;
+       case REF_STATUS_OK:
+               print_ok_ref_status(ref);
+               break;
+       }
+
+       return 1;
+}
+
+static void print_push_status(const char *dest, struct ref *refs)
+{
+       struct ref *ref;
+       int n = 0;
+
+       if (args.verbose) {
+               for (ref = refs; ref; ref = ref->next)
+                       if (ref->status == REF_STATUS_UPTODATE)
+                               n += print_one_push_status(ref, dest, n);
+       }
+
+       for (ref = refs; ref; ref = ref->next)
+               if (ref->status == REF_STATUS_OK)
+                       n += print_one_push_status(ref, dest, n);
+
+       for (ref = refs; ref; ref = ref->next) {
+               if (ref->status != REF_STATUS_NONE &&
+                   ref->status != REF_STATUS_UPTODATE &&
+                   ref->status != REF_STATUS_OK)
+                       n += print_one_push_status(ref, dest, n);
+       }
+}
+
+static int refs_pushed(struct ref *ref)
+{
+       for (; ref; ref = ref->next) {
+               switch(ref->status) {
+               case REF_STATUS_NONE:
+               case REF_STATUS_UPTODATE:
+                       break;
+               default:
+                       return 1;
+               }
+       }
+       return 0;
+}
+
+static int do_send_pack(int in, int out, struct remote *remote, const char *dest, int nr_refspec, const char **refspec)
+{
+       struct ref *ref;
+       int new_refs;
+       int ask_for_status_report = 0;
+       int allow_deleting_refs = 0;
+       int expect_status_report = 0;
+       int flags = MATCH_REFS_NONE;
+       int ret;
+
+       if (args.send_all)
+               flags |= MATCH_REFS_ALL;
+       if (args.send_mirror)
+               flags |= MATCH_REFS_MIRROR;
+
+       /* No funny business with the matcher */
+       remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
+       get_local_heads();
+
+       /* Does the other end support the reporting? */
+       if (server_supports("report-status"))
+               ask_for_status_report = 1;
+       if (server_supports("delete-refs"))
+               allow_deleting_refs = 1;
+
+       /* match them up */
+       if (!remote_tail)
+               remote_tail = &remote_refs;
+       if (match_refs(local_refs, remote_refs, &remote_tail,
+                                              nr_refspec, refspec, flags))
+               return -1;
+
+       if (!remote_refs) {
+               fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
+                       "Perhaps you should specify a branch such as 'master'.\n");
+               return 0;
+       }
+
+       /*
+        * Finally, tell the other end!
+        */
+       new_refs = 0;
+       for (ref = remote_refs; ref; ref = ref->next) {
+               const unsigned char *new_sha1;
+
+               if (!ref->peer_ref) {
+                       if (!args.send_mirror)
+                               continue;
+                       new_sha1 = null_sha1;
+               }
+               else
+                       new_sha1 = ref->peer_ref->new_sha1;
+
+
+               ref->deletion = is_null_sha1(new_sha1);
+               if (ref->deletion && !allow_deleting_refs) {
+                       ref->status = REF_STATUS_REJECT_NODELETE;
+                       continue;
+               }
+               if (!ref->deletion &&
+                   !hashcmp(ref->old_sha1, new_sha1)) {
+                       ref->status = REF_STATUS_UPTODATE;
+                       continue;
+               }
+
+               /* This part determines what can overwrite what.
+                * The rules are:
+                *
+                * (0) you can always use --force or +A:B notation to
+                *     selectively force individual ref pairs.
+                *
+                * (1) if the old thing does not exist, it is OK.
+                *
+                * (2) if you do not have the old thing, you are not allowed
+                *     to overwrite it; you would not know what you are losing
+                *     otherwise.
+                *
+                * (3) if both new and old are commit-ish, and new is a
+                *     descendant of old, it is OK.
+                *
+                * (4) regardless of all of the above, removing :B is
+                *     always allowed.
+                */
+
+               ref->nonfastforward =
+                   !ref->deletion &&
+                   !is_null_sha1(ref->old_sha1) &&
+                   (!has_sha1_file(ref->old_sha1)
+                     || !ref_newer(new_sha1, ref->old_sha1));
+
+               if (ref->nonfastforward && !ref->force && !args.force_update) {
+                       ref->status = REF_STATUS_REJECT_NONFASTFORWARD;
+                       continue;
+               }
+
+               hashcpy(ref->new_sha1, new_sha1);
+               if (!ref->deletion)
+                       new_refs++;
+
+               if (!args.dry_run) {
+                       char *old_hex = sha1_to_hex(ref->old_sha1);
+                       char *new_hex = sha1_to_hex(ref->new_sha1);
+
+                       if (ask_for_status_report) {
+                               packet_write(out, "%s %s %s%c%s",
+                                       old_hex, new_hex, ref->name, 0,
+                                       "report-status");
+                               ask_for_status_report = 0;
+                               expect_status_report = 1;
+                       }
+                       else
+                               packet_write(out, "%s %s %s",
+                                       old_hex, new_hex, ref->name);
+               }
+               ref->status = expect_status_report ?
+                       REF_STATUS_EXPECTING_REPORT :
+                       REF_STATUS_OK;
+       }
+
+       packet_flush(out);
+       if (new_refs && !args.dry_run) {
+               if (pack_objects(out, remote_refs) < 0) {
+                       close(out);
+                       return -1;
+               }
+       }
+       close(out);
+
+       if (expect_status_report)
+               ret = receive_status(in, remote_refs);
+       else
+               ret = 0;
+
+       print_push_status(dest, remote_refs);
+
+       if (!args.dry_run && remote) {
+               for (ref = remote_refs; ref; ref = ref->next)
+                       update_tracking_ref(remote, ref);
+       }
+
+       if (!refs_pushed(remote_refs))
+               fprintf(stderr, "Everything up-to-date\n");
+       if (ret < 0)
+               return ret;
+       for (ref = remote_refs; ref; ref = ref->next) {
+               switch (ref->status) {
+               case REF_STATUS_NONE:
+               case REF_STATUS_UPTODATE:
+               case REF_STATUS_OK:
+                       break;
+               default:
+                       return -1;
+               }
+       }
+       return 0;
+}
+
+static void verify_remote_names(int nr_heads, const char **heads)
+{
+       int i;
+
+       for (i = 0; i < nr_heads; i++) {
+               const char *remote = strchr(heads[i], ':');
+
+               remote = remote ? (remote + 1) : heads[i];
+               switch (check_ref_format(remote)) {
+               case 0: /* ok */
+               case -2: /* ok but a single level -- that is fine for
+                         * a match pattern.
+                         */
+               case -3: /* ok but ends with a pattern-match character */
+                       continue;
+               }
+               die("remote part of refspec is not a valid name in %s",
+                   heads[i]);
+       }
+}
+
+int cmd_send_pack(int argc, const char **argv, const char *prefix)
+{
+       int i, nr_heads = 0;
+       const char **heads = NULL;
+       const char *remote_name = NULL;
+       struct remote *remote = NULL;
+       const char *dest = NULL;
+
+       argv++;
+       for (i = 1; i < argc; i++, argv++) {
+               const char *arg = *argv;
+
+               if (*arg == '-') {
+                       if (!prefixcmp(arg, "--receive-pack=")) {
+                               args.receivepack = arg + 15;
+                               continue;
+                       }
+                       if (!prefixcmp(arg, "--exec=")) {
+                               args.receivepack = arg + 7;
+                               continue;
+                       }
+                       if (!prefixcmp(arg, "--remote=")) {
+                               remote_name = arg + 9;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--all")) {
+                               args.send_all = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--dry-run")) {
+                               args.dry_run = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--mirror")) {
+                               args.send_mirror = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--force")) {
+                               args.force_update = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--verbose")) {
+                               args.verbose = 1;
+                               continue;
+                       }
+                       if (!strcmp(arg, "--thin")) {
+                               args.use_thin_pack = 1;
+                               continue;
+                       }
+                       usage(send_pack_usage);
+               }
+               if (!dest) {
+                       dest = arg;
+                       continue;
+               }
+               heads = (const char **) argv;
+               nr_heads = argc - i;
+               break;
+       }
+       if (!dest)
+               usage(send_pack_usage);
+       /*
+        * --all and --mirror are incompatible; neither makes sense
+        * with any refspecs.
+        */
+       if ((heads && (args.send_all || args.send_mirror)) ||
+                                       (args.send_all && args.send_mirror))
+               usage(send_pack_usage);
+
+       if (remote_name) {
+               remote = remote_get(remote_name);
+               if (!remote_has_url(remote, dest)) {
+                       die("Destination %s is not a uri for %s",
+                           dest, remote_name);
+               }
+       }
+
+       return send_pack(&args, dest, remote, nr_heads, heads);
+}
+
+int send_pack(struct send_pack_args *my_args,
+             const char *dest, struct remote *remote,
+             int nr_heads, const char **heads)
+{
+       int fd[2], ret;
+       struct child_process *conn;
+
+       memcpy(&args, my_args, sizeof(args));
+
+       verify_remote_names(nr_heads, heads);
+
+       conn = git_connect(fd, dest, args.receivepack, args.verbose ? CONNECT_VERBOSE : 0);
+       ret = do_send_pack(fd[0], fd[1], remote, dest, nr_heads, heads);
+       close(fd[0]);
+       close(fd[1]);
+       ret |= finish_connect(conn);
+       return !!ret;
+}
index cbb0f04e85627a5509bb2ba8cbf04a54d4d20c41..114c684d246e975852bb5446ea2e7ab682ea036c 100644 (file)
 #include "refs.h"
 #include "tag.h"
 #include "run-command.h"
-
-static const char builtin_tag_usage[] =
-  "git-tag [-n [<num>]] -l [<pattern>] | [-a | -s | -u <key-id>] [-f | -d | -v] [-m <msg> | -F <file>] <tagname> [<head>]";
+#include "parse-options.h"
+
+static const char * const git_tag_usage[] = {
+       "git-tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
+       "git-tag -d <tagname>...",
+       "git-tag [-n [<num>]] -l [<pattern>]",
+       "git-tag -v <tagname>...",
+       NULL
+};
 
 static char signingkey[1000];
 
@@ -276,7 +282,7 @@ static void write_tag_body(int fd, const unsigned char *sha1)
 
 static void create_tag(const unsigned char *object, const char *tag,
                       struct strbuf *buf, int message, int sign,
-                          unsigned char *prev, unsigned char *result)
+                      unsigned char *prev, unsigned char *result)
 {
        enum object_type type;
        char header_buf[1024];
@@ -335,105 +341,101 @@ static void create_tag(const unsigned char *object, const char *tag,
                die("unable to write tag file");
 }
 
+struct msg_arg {
+       int given;
+       struct strbuf buf;
+};
+
+static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
+{
+       struct msg_arg *msg = opt->value;
+
+       if (!arg)
+               return -1;
+       if (msg->buf.len)
+               strbuf_addstr(&(msg->buf), "\n\n");
+       strbuf_addstr(&(msg->buf), arg);
+       msg->given = 1;
+       return 0;
+}
+
 int cmd_tag(int argc, const char **argv, const char *prefix)
 {
        struct strbuf buf;
        unsigned char object[20], prev[20];
-       int annotate = 0, sign = 0, force = 0, lines = 0, message = 0;
        char ref[PATH_MAX];
        const char *object_ref, *tag;
-       int i;
        struct ref_lock *lock;
 
+       int annotate = 0, sign = 0, force = 0, lines = 0,
+                                       delete = 0, verify = 0;
+       char *list = NULL, *msgfile = NULL, *keyid = NULL;
+       const char *no_pattern = "NO_PATTERN";
+       struct msg_arg msg = { 0, STRBUF_INIT };
+       struct option options[] = {
+               { OPTION_STRING, 'l', NULL, &list, "pattern", "list tag names",
+                       PARSE_OPT_OPTARG, NULL, (intptr_t) no_pattern },
+               { OPTION_INTEGER, 'n', NULL, &lines, NULL,
+                               "print n lines of each tag message",
+                               PARSE_OPT_OPTARG, NULL, 1 },
+               OPT_BOOLEAN('d', NULL, &delete, "delete tags"),
+               OPT_BOOLEAN('v', NULL, &verify, "verify tags"),
+
+               OPT_GROUP("Tag creation options"),
+               OPT_BOOLEAN('a', NULL, &annotate,
+                                       "annotated tag, needs a message"),
+               OPT_CALLBACK('m', NULL, &msg, "msg",
+                            "message for the tag", parse_msg_arg),
+               OPT_STRING('F', NULL, &msgfile, "file", "message in a file"),
+               OPT_BOOLEAN('s', NULL, &sign, "annotated and GPG-signed tag"),
+               OPT_STRING('u', NULL, &keyid, "key-id",
+                                       "use another key to sign the tag"),
+               OPT_BOOLEAN('f', NULL, &force, "replace the tag if exists"),
+               OPT_END()
+       };
+
        git_config(git_tag_config);
-       strbuf_init(&buf, 0);
 
-       for (i = 1; i < argc; i++) {
-               const char *arg = argv[i];
+       argc = parse_options(argc, argv, options, git_tag_usage, 0);
 
-               if (arg[0] != '-')
-                       break;
-               if (!strcmp(arg, "-a")) {
-                       annotate = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-s")) {
-                       annotate = 1;
-                       sign = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-f")) {
-                       force = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-n")) {
-                       if (i + 1 == argc || *argv[i + 1] == '-')
-                               /* no argument */
-                               lines = 1;
-                       else
-                               lines = isdigit(*argv[++i]) ?
-                                       atoi(argv[i]) : 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-m")) {
-                       annotate = 1;
-                       i++;
-                       if (i == argc)
-                               die("option -m needs an argument.");
-                       if (message)
-                               die("only one -F or -m option is allowed.");
-                       strbuf_addstr(&buf, argv[i]);
-                       message = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-F")) {
-                       annotate = 1;
-                       i++;
-                       if (i == argc)
-                               die("option -F needs an argument.");
-                       if (message)
-                               die("only one -F or -m option is allowed.");
-
-                       if (!strcmp(argv[i], "-")) {
+       if (sign)
+               annotate = 1;
+
+       if (list)
+               return list_tags(list == no_pattern ? NULL : list, lines);
+       if (delete)
+               return for_each_tag_name(argv, delete_tag);
+       if (verify)
+               return for_each_tag_name(argv, verify_tag);
+
+       strbuf_init(&buf, 0);
+       if (msg.given || msgfile) {
+               if (msg.given && msgfile)
+                       die("only one -F or -m option is allowed.");
+               annotate = 1;
+               if (msg.given)
+                       strbuf_addbuf(&buf, &(msg.buf));
+               else {
+                       if (!strcmp(msgfile, "-")) {
                                if (strbuf_read(&buf, 0, 1024) < 0)
-                                       die("cannot read %s", argv[i]);
+                                       die("cannot read %s", msgfile);
                        } else {
-                               if (strbuf_read_file(&buf, argv[i], 1024) < 0)
+                               if (strbuf_read_file(&buf, msgfile, 1024) < 0)
                                        die("could not open or read '%s': %s",
-                                               argv[i], strerror(errno));
+                                               msgfile, strerror(errno));
                        }
-                       message = 1;
-                       continue;
-               }
-               if (!strcmp(arg, "-u")) {
-                       annotate = 1;
-                       sign = 1;
-                       i++;
-                       if (i == argc)
-                               die("option -u needs an argument.");
-                       if (strlcpy(signingkey, argv[i], sizeof(signingkey))
-                                                       >= sizeof(signingkey))
-                               die("argument to option -u too long");
-                       continue;
                }
-               if (!strcmp(arg, "-l"))
-                       return list_tags(argv[i + 1], lines);
-               if (!strcmp(arg, "-d"))
-                       return for_each_tag_name(argv + i + 1, delete_tag);
-               if (!strcmp(arg, "-v"))
-                       return for_each_tag_name(argv + i + 1, verify_tag);
-               usage(builtin_tag_usage);
        }
 
-       if (i == argc) {
+       if (argc == 0) {
                if (annotate)
-                       usage(builtin_tag_usage);
+                       usage_with_options(git_tag_usage, options);
                return list_tags(NULL, lines);
        }
-       tag = argv[i++];
+       tag = argv[0];
 
-       object_ref = i < argc ? argv[i] : "HEAD";
-       if (i + 1 < argc)
+       object_ref = argc == 2 ? argv[1] : "HEAD";
+       if (argc > 2)
                die("too many params");
 
        if (get_sha1(object_ref, object))
@@ -450,7 +452,8 @@ 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, prev, object);
+               create_tag(object, tag, &buf, msg.given || msgfile,
+                          sign, prev, object);
 
        lock = lock_any_ref_for_update(ref, prev, 0);
        if (!lock)
index 9a6213af126212dc131133cc2e9bf8b8d7a34557..98ada7b7f705d70ad27cccfaaf3c21c13f66dcc4 100644 (file)
--- 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);
@@ -48,9 +49,11 @@ extern int cmd_log(int argc, const char **argv, const char *prefix);
 extern int cmd_log_reflog(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_files(int argc, const char **argv, const char *prefix);
 extern int cmd_ls_tree(int argc, const char **argv, const char *prefix);
+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);
@@ -69,6 +72,7 @@ extern int cmd_rev_parse(int argc, const char **argv, const char *prefix);
 extern int cmd_revert(int argc, const char **argv, const char *prefix);
 extern int cmd_rm(int argc, const char **argv, const char *prefix);
 extern int cmd_runstatus(int argc, const char **argv, const char *prefix);
+extern int cmd_send_pack(int argc, const char **argv, const char *prefix);
 extern int cmd_shortlog(int argc, const char **argv, const char *prefix);
 extern int cmd_show(int argc, const char **argv, const char *prefix);
 extern int cmd_show_branch(int argc, const char **argv, const char *prefix);
index e4d60cde6f1b9dd7a2aab36ebc4f2a97a9d61b22..9b9b9166df05e984dc571462f333aeaee9cdcd23 100644 (file)
--- 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 33ebccf48d0d8963ab5b262bfb87312e6542ed75..aaa135bfde23cd2529e3707e4499be7f75917336 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -290,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];
@@ -499,8 +500,20 @@ struct ref {
        struct ref *next;
        unsigned char old_sha1[20];
        unsigned char new_sha1[20];
-       unsigned char force;
-       unsigned char merge;
+       unsigned int force:1,
+               merge:1,
+               nonfastforward:1,
+               deletion:1;
+       enum {
+               REF_STATUS_NONE = 0,
+               REF_STATUS_OK,
+               REF_STATUS_REJECT_NONFASTFORWARD,
+               REF_STATUS_REJECT_NODELETE,
+               REF_STATUS_UPTODATE,
+               REF_STATUS_REMOTE_REJECT,
+               REF_STATUS_EXPECTING_REPORT,
+       } status;
+       char *remote_status;
        struct ref *peer_ref; /* when renaming */
        char name[FLEX_ARRAY]; /* more */
 };
@@ -509,8 +522,10 @@ struct ref {
 #define REF_HEADS      (1u << 1)
 #define REF_TAGS       (1u << 2)
 
+extern struct ref *find_ref_by_name(struct ref *list, const char *name);
+
 #define CONNECT_VERBOSE       (1u << 0)
-extern struct child_process *git_connect(int fd[2], char *url, const char *prog, int flags);
+extern struct child_process *git_connect(int fd[2], const char *url, const char *prog, int flags);
 extern int finish_connect(struct child_process *conn);
 extern int path_match(const char *path, int nr, char **match);
 extern int get_ack(int fd, unsigned char *result_sha1);
@@ -556,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)
index 56e99fc0f4750174299303b27237737e09549933..ed96213c44265289c26d46edaaf740cebd0b4c86 100644 (file)
--- a/config.c
+++ b/config.c
@@ -6,6 +6,7 @@
  *
  */
 #include "cache.h"
+#include "exec_cmd.h"
 
 #define MAXNAME (256)
 
@@ -459,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;
@@ -471,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)
index 776b80565902af3de1c2a33af062dd4de719a267..11d256e9cf5b51154a3bf0084f9e3bcea5702352 100644 (file)
@@ -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@
index 53e9a17c737e10a51b8b33b9cf258744817e6e9a..5f8a15b9f9580bea6f350e8af468f81cf2535c9e 100644 (file)
@@ -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.
@@ -397,7 +415,7 @@ GIT_PARSE_WITH(iconv))
 # times (my ext3 doesn't).
 #
 # Define USE_STDEV below if you want git to care about the underlying device
-# change being considered an inode change from the update-cache perspective.
+# change being considered an inode change from the update-index perspective.
 
 
 ## Output files
index 44e423dafd5c5e6566124fd1bb05f3d419b19a40..3aefd4ace590082b85bd3c4b9b41b8d1f1c72268 100644 (file)
--- a/connect.c
+++ b/connect.c
@@ -36,6 +36,11 @@ static int check_ref(const char *name, int len, unsigned int flags)
        return !(flags & ~REF_NORMAL);
 }
 
+int check_ref_type(const struct ref *ref, int flags)
+{
+       return check_ref(ref->name, strlen(ref->name), flags);
+}
+
 /*
  * Read all the refs from the other end
  */
@@ -476,9 +481,10 @@ char *get_port(char *host)
  *
  * If it returns, the connect is successful; it just dies on errors.
  */
-struct child_process *git_connect(int fd[2], char *url,
+struct child_process *git_connect(int fd[2], const char *url_orig,
                                  const char *prog, int flags)
 {
+       char *url = xstrdup(url_orig);
        char *host, *path = url;
        char *end;
        int c;
@@ -568,6 +574,7 @@ struct child_process *git_connect(int fd[2], char *url,
                             prog, path, 0,
                             target_host, 0);
                free(target_host);
+               free(url);
                if (free_path)
                        free(path);
                return NULL;
@@ -619,6 +626,7 @@ struct child_process *git_connect(int fd[2], char *url,
        fd[0] = conn->out; /* read from child's stdout */
        fd[1] = conn->in;  /* write to child's stdin */
        strbuf_release(&cmd);
+       free(url);
        if (free_path)
                free(path);
        return conn;
index 599b2fc5711bf6022fdb635b08baac16068de7dd..58e0e53cd6f6382e9665d20b53b26cd1da42fc88 100755 (executable)
@@ -551,6 +551,20 @@ _git_describe ()
 
 _git_diff ()
 {
+       local cur="${COMP_WORDS[COMP_CWORD]}"
+       case "$cur" in
+       --*)
+               __gitcomp "--cached --stat --numstat --shortstat --summary
+                       --patch-with-stat --name-only --name-status --color
+                       --no-color --color-words --no-renames --check
+                       --full-index --binary --abbrev --diff-filter
+                       --find-copies-harder --pickaxe-all --pickaxe-regex
+                       --text --ignore-space-at-eol --ignore-space-change
+                       --ignore-all-space --exit-code --quiet --ext-diff
+                       --no-ext-diff"
+               return
+               ;;
+       esac
        __git_complete_file
 }
 
diff --git a/contrib/examples/git-clean.sh b/contrib/examples/git-clean.sh
new file mode 100755 (executable)
index 0000000..01c95e9
--- /dev/null
@@ -0,0 +1,118 @@
+#!/bin/sh
+#
+# Copyright (c) 2005-2006 Pavel Roskin
+#
+
+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.
+--
+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
+
+ignored=
+ignoredonly=
+cleandir=
+rmf="rm -f --"
+rmrf="rm -rf --"
+rm_refuse="echo Not removing"
+echo1="echo"
+
+disabled=$(git config --bool clean.requireForce)
+
+while test $# != 0
+do
+       case "$1" in
+       -d)
+               cleandir=1
+               ;;
+       -f)
+               disabled=false
+               ;;
+       -n)
+               disabled=false
+               rmf="echo Would remove"
+               rmrf="echo Would remove"
+               rm_refuse="echo Would not remove"
+               echo1=":"
+               ;;
+       -q)
+               echo1=":"
+               ;;
+       -x)
+               ignored=1
+               ;;
+       -X)
+               ignoredonly=1
+               ;;
+       --)
+               shift
+               break
+               ;;
+       *)
+               usage # should not happen
+               ;;
+       esac
+       shift
+done
+
+# requireForce used to default to false but now it defaults to true.
+# IOW, lack of explicit "clean.requireForce = false" is taken as
+# "clean.requireForce = true".
+case "$disabled" in
+"")
+       die "clean.requireForce not set and -n or -f not given; refusing to clean"
+       ;;
+"true")
+       die "clean.requireForce set and -n or -f not given; refusing to clean"
+       ;;
+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"} ${excludes_file:+"$excludes_file"} \
+       -- "$@" |
+while read -r file; do
+       if [ -d "$file" -a ! -L "$file" ]; then
+               if [ -z "$cleandir" ]; then
+                       $rm_refuse "$file"
+                       continue
+               fi
+               $echo1 "Removing $file"
+               $rmrf "$file"
+       else
+               $echo1 "Removing $file"
+               $rmf "$file"
+       fi
+done
diff --git a/contrib/examples/git-ls-remote.sh b/contrib/examples/git-ls-remote.sh
new file mode 100755 (executable)
index 0000000..fec70bb
--- /dev/null
@@ -0,0 +1,142 @@
+#!/bin/sh
+#
+
+usage () {
+    echo >&2 "usage: $0 [--heads] [--tags] [-u|--upload-pack <upload-pack>]"
+    echo >&2 "          <repository> <refs>..."
+    exit 1;
+}
+
+die () {
+    echo >&2 "$*"
+    exit 1
+}
+
+exec=
+while test $# != 0
+do
+  case "$1" in
+  -h|--h|--he|--hea|--head|--heads)
+  heads=heads; shift ;;
+  -t|--t|--ta|--tag|--tags)
+  tags=tags; shift ;;
+  -u|--u|--up|--upl|--uploa|--upload|--upload-|--upload-p|--upload-pa|\
+  --upload-pac|--upload-pack)
+       shift
+       exec="--upload-pack=$1"
+       shift;;
+  -u=*|--u=*|--up=*|--upl=*|--uplo=*|--uploa=*|--upload=*|\
+  --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
+       exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)')
+       shift;;
+  --)
+  shift; break ;;
+  -*)
+  usage ;;
+  *)
+  break ;;
+  esac
+done
+
+case "$#" in 0) usage ;; esac
+
+case ",$heads,$tags," in
+,,,) heads=heads tags=tags other=other ;;
+esac
+
+. git-parse-remote
+peek_repo="$(get_remote_url "$@")"
+shift
+
+tmp=.ls-remote-$$
+trap "rm -fr $tmp-*" 0 1 2 3 15
+tmpdir=$tmp-d
+
+case "$peek_repo" in
+http://* | https://* | ftp://* )
+       if [ -n "$GIT_SSL_NO_VERIFY" -o \
+               "`git config --bool http.sslVerify`" = false ]; then
+               curl_extra_args="-k"
+       fi
+       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
+               "`git config --bool http.noEPSV`" = true ]; then
+               curl_extra_args="${curl_extra_args} --disable-epsv"
+       fi
+       curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" ||
+               echo "failed    slurping"
+       ;;
+
+rsync://* )
+       mkdir $tmpdir &&
+       rsync -rlq "$peek_repo/HEAD" $tmpdir &&
+       rsync -rq "$peek_repo/refs" $tmpdir || {
+               echo "failed    slurping"
+               exit
+       }
+       head=$(cat "$tmpdir/HEAD") &&
+       case "$head" in
+       ref:' '*)
+               head=$(expr "z$head" : 'zref: \(.*\)') &&
+               head=$(cat "$tmpdir/$head") || exit
+       esac &&
+       echo "$head     HEAD"
+       (cd $tmpdir && find refs -type f) |
+       while read path
+       do
+               tr -d '\012' <"$tmpdir/$path"
+               echo "  $path"
+       done &&
+       rm -fr $tmpdir
+       ;;
+
+* )
+       if test -f "$peek_repo" ; then
+               git bundle list-heads "$peek_repo" ||
+               echo "failed    slurping"
+       else
+               git-peek-remote $exec "$peek_repo" ||
+               echo "failed    slurping"
+       fi
+       ;;
+esac |
+sort -t '      ' -k 2 |
+while read sha1 path
+do
+       case "$sha1" in
+       failed)
+               exit 1 ;;
+       esac
+       case "$path" in
+       refs/heads/*)
+               group=heads ;;
+       refs/tags/*)
+               group=tags ;;
+       *)
+               group=other ;;
+       esac
+       case ",$heads,$tags,$other," in
+       *,$group,*)
+               ;;
+       *)
+               continue;;
+       esac
+       case "$#" in
+       0)
+               match=yes ;;
+       *)
+               match=no
+               for pat
+               do
+                       case "/$path" in
+                       */$pat )
+                               match=yes
+                               break ;;
+                       esac
+               done
+       esac
+       case "$match" in
+       no)
+               continue ;;
+       esac
+       echo "$sha1     $path"
+done
diff --git a/contrib/examples/git-merge-ours.sh b/contrib/examples/git-merge-ours.sh
new file mode 100755 (executable)
index 0000000..29dba4b
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Copyright (c) 2005 Junio C Hamano
+#
+# Pretend we resolved the heads, but declare our tree trumps everybody else.
+#
+
+# 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.
+
+git diff-index --quiet --cached HEAD -- || exit 2
+
+exit 0
index c869bb88643d67a7954db026ce9ebb50c0f89be0..c80a6da2522b690e15f84fedf52a132078cd265a 100755 (executable)
@@ -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"]
index 449ee69bf48d41424e058b7bc61fd8ccc69c341d..4c99dfb9038ca034d86b72cbe342373d12ae8cc6 100755 (executable)
@@ -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})')
 
index f8e936ae1008fdb7ef8e1722afb839d84c724f6c..d85d8f34ba055ad7e02bf5d61ae4a675ce0be1d3 100644 (file)
@@ -231,7 +231,7 @@ static int handle_diff_files_args(struct rev_info *revs,
 static int is_outside_repo(const char *path, int nongit, const char *prefix)
 {
        int i;
-       if (nongit || !strcmp(path, "-") || path[0] == '/')
+       if (nongit || !strcmp(path, "-") || is_absolute_path(path))
                return 1;
        if (prefixcmp(path, "../"))
                return 0;
diff --git a/diff.c b/diff.c
index b08d28a5780cf242a4de78e0f5c4007b7041f392..6b54959610db604bfabc15e6edd2b212f16d0c62 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -2716,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));
                }
index f9ebea56406090af207f79951618742dcd7d397f..3d377251bef8ea843b7a7fa41f98d611daecbcc1 100644 (file)
@@ -244,28 +244,35 @@ static int find_identical_files(struct file_similarity *src,
         * Walk over all the destinations ...
         */
        do {
-               struct diff_filespec *one = dst->filespec;
+               struct diff_filespec *target = dst->filespec;
                struct file_similarity *p, *best;
-               int i = 100;
+               int i = 100, best_score = -1;
 
                /*
                 * .. to find the best source match
                 */
                best = NULL;
                for (p = src; p; p = p->next) {
-                       struct diff_filespec *two = p->filespec;
+                       int score;
+                       struct diff_filespec *source = p->filespec;
 
                        /* False hash collission? */
-                       if (hashcmp(one->sha1, two->sha1))
+                       if (hashcmp(source->sha1, target->sha1))
                                continue;
                        /* Non-regular files? If so, the modes must match! */
-                       if (!S_ISREG(one->mode) || !S_ISREG(two->mode)) {
-                               if (one->mode != two->mode)
+                       if (!S_ISREG(source->mode) || !S_ISREG(target->mode)) {
+                               if (source->mode != target->mode)
                                        continue;
                        }
-                       best = p;
-                       if (basename_same(one, two))
-                               break;
+                       /* Give higher scores to sources that haven't been used already */
+                       score = !source->rename_used;
+                       score += basename_same(source, target);
+                       if (score > best_score) {
+                               best = p;
+                               best_score = score;
+                               if (score == 2)
+                                       break;
+                       }
 
                        /* Too many identical alternatives? Pick one */
                        if (!--i)
@@ -488,6 +495,19 @@ void diffcore_rename(struct diff_options *options)
        }
        /* cost matrix sorted by most to least similar pair */
        qsort(mx, num_create * num_src, sizeof(*mx), score_compare);
+       for (i = 0; i < num_create * num_src; i++) {
+               struct diff_rename_dst *dst = &rename_dst[mx[i].dst];
+               struct diff_filespec *src;
+               if (dst->pair)
+                       continue; /* already done, either exact or fuzzy. */
+               if (mx[i].score < minimum_score)
+                       break; /* there is no more usable pair. */
+               src = rename_src[mx[i].src].one;
+               if (src->rename_used)
+                       continue;
+               record_rename_pair(mx[i].dst, mx[i].src, mx[i].score);
+               rename_count++;
+       }
        for (i = 0; i < num_create * num_src; i++) {
                struct diff_rename_dst *dst = &rename_dst[mx[i].dst];
                if (dst->pair)
diff --git a/dir.c b/dir.c
index 225fdfb52c432b7af1af1cdf9aa9a31f8022e3ec..d448902909a7da216fbd49cecc505e68c0ba5e5f 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -144,17 +144,14 @@ void add_exclude(const char *string, const char *base,
                x->flags |= EXC_FLAG_NOWILDCARD;
        if (*string == '*' && no_wildcard(string+1))
                x->flags |= EXC_FLAG_ENDSWITH;
-       if (which->nr == which->alloc) {
-               which->alloc = alloc_nr(which->alloc);
-               which->excludes = xrealloc(which->excludes,
-                                          which->alloc * sizeof(x));
-       }
+       ALLOC_GROW(which->excludes, which->nr + 1, which->alloc);
        which->excludes[which->nr++] = x;
 }
 
 static int add_excludes_from_file_1(const char *fname,
                                    const char *base,
                                    int baselen,
+                                   char **buf_p,
                                    struct exclude_list *which)
 {
        struct stat st;
@@ -175,6 +172,8 @@ static int add_excludes_from_file_1(const char *fname,
                goto err;
        close(fd);
 
+       if (buf_p)
+               *buf_p = buf;
        buf[size++] = '\n';
        entry = buf;
        for (i = 0; i < size; i++) {
@@ -196,31 +195,63 @@ static int add_excludes_from_file_1(const char *fname,
 
 void add_excludes_from_file(struct dir_struct *dir, const char *fname)
 {
-       if (add_excludes_from_file_1(fname, "", 0,
+       if (add_excludes_from_file_1(fname, "", 0, NULL,
                                     &dir->exclude_list[EXC_FILE]) < 0)
                die("cannot use %s as an exclude file", fname);
 }
 
-int push_exclude_per_directory(struct dir_struct *dir, const char *base, int baselen)
+static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 {
-       char exclude_file[PATH_MAX];
-       struct exclude_list *el = &dir->exclude_list[EXC_DIRS];
-       int current_nr = el->nr;
-
-       if (dir->exclude_per_dir) {
-               memcpy(exclude_file, base, baselen);
-               strcpy(exclude_file + baselen, dir->exclude_per_dir);
-               add_excludes_from_file_1(exclude_file, base, baselen, el);
+       struct exclude_list *el;
+       struct exclude_stack *stk = NULL;
+       int current;
+
+       if ((!dir->exclude_per_dir) ||
+           (baselen + strlen(dir->exclude_per_dir) >= PATH_MAX))
+               return; /* too long a path -- ignore */
+
+       /* Pop the ones that are not the prefix of the path being checked. */
+       el = &dir->exclude_list[EXC_DIRS];
+       while ((stk = dir->exclude_stack) != NULL) {
+               if (stk->baselen <= baselen &&
+                   !strncmp(dir->basebuf, base, stk->baselen))
+                       break;
+               dir->exclude_stack = stk->prev;
+               while (stk->exclude_ix < el->nr)
+                       free(el->excludes[--el->nr]);
+               free(stk->filebuf);
+               free(stk);
        }
-       return current_nr;
-}
 
-void pop_exclude_per_directory(struct dir_struct *dir, int stk)
-{
-       struct exclude_list *el = &dir->exclude_list[EXC_DIRS];
+       /* Read from the parent directories and push them down. */
+       current = stk ? stk->baselen : -1;
+       while (current < baselen) {
+               struct exclude_stack *stk = xcalloc(1, sizeof(*stk));
+               const char *cp;
 
-       while (stk < el->nr)
-               free(el->excludes[--el->nr]);
+               if (current < 0) {
+                       cp = base;
+                       current = 0;
+               }
+               else {
+                       cp = strchr(base + current + 1, '/');
+                       if (!cp)
+                               die("oops in prep_exclude");
+                       cp++;
+               }
+               stk->prev = dir->exclude_stack;
+               stk->baselen = cp - base;
+               stk->exclude_ix = el->nr;
+               memcpy(dir->basebuf + current, base + current,
+                      stk->baselen - current);
+               strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
+               add_excludes_from_file_1(dir->basebuf,
+                                        dir->basebuf, stk->baselen,
+                                        &stk->filebuf, el);
+               dir->exclude_stack = stk;
+               current = stk->baselen;
+       }
+       dir->basebuf[baselen] = '\0';
 }
 
 /* Scan the list and let the last match determines the fate.
@@ -287,6 +318,7 @@ int excluded(struct dir_struct *dir, const char *pathname)
        const char *basename = strrchr(pathname, '/');
        basename = (basename) ? basename+1 : pathname;
 
+       prep_exclude(dir, pathname, basename-pathname);
        for (st = EXC_CMDL; st <= EXC_FILE; st++) {
                switch (excluded_1(pathname, pathlen, basename, &dir->exclude_list[st])) {
                case 0:
@@ -504,13 +536,10 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
        int contents = 0;
 
        if (fdir) {
-               int exclude_stk;
                struct dirent *de;
                char fullname[PATH_MAX + 1];
                memcpy(fullname, base, baselen);
 
-               exclude_stk = push_exclude_per_directory(dir, base, baselen);
-
                while ((de = readdir(fdir)) != NULL) {
                        int len, dtype;
                        int exclude;
@@ -584,8 +613,6 @@ static int read_directory_recursive(struct dir_struct *dir, const char *path, co
                }
 exit_early:
                closedir(fdir);
-
-               pop_exclude_per_directory(dir, exclude_stk);
        }
 
        return contents;
@@ -654,47 +681,18 @@ 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
-        * directories leading up to our base.
-        */
-       if (baselen) {
-               if (dir->exclude_per_dir) {
-                       char *p;
-                       pp = xmalloc(baselen+1);
-                       memcpy(pp, base, baselen+1);
-                       p = pp;
-                       while (1) {
-                               char save = *p;
-                               *p = 0;
-                               push_exclude_per_directory(dir, pp, p-pp);
-                               *p++ = save;
-                               if (!save)
-                                       break;
-                               p = strchr(p, '/');
-                               if (p)
-                                       p++;
-                               else
-                                       p = pp + baselen;
-                       }
-               }
-       }
 
        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;
 }
 
-int
-file_exists(const char *f)
+int file_exists(const char *f)
 {
-  struct stat sb;
-  return stat(f, &sb) == 0;
+       struct stat sb;
+       return stat(f, &sb) == 0;
 }
 
 /*
diff --git a/dir.h b/dir.h
index 82009dc13e4b685bc6f4f6e9206d621c7d361c65..d8814dccb2dd57af21d75c91a52026e09fdf1b95 100644 (file)
--- a/dir.h
+++ b/dir.h
@@ -1,17 +1,6 @@
 #ifndef DIR_H
 #define DIR_H
 
-/*
- * We maintain three exclude pattern lists:
- * EXC_CMDL lists patterns explicitly given on the command line.
- * EXC_DIRS lists patterns obtained from per-directory ignore files.
- * EXC_FILE lists patterns from fallback ignore files.
- */
-#define EXC_CMDL 0
-#define EXC_DIRS 1
-#define EXC_FILE 2
-
-
 struct dir_entry {
        unsigned int len;
        char name[FLEX_ARRAY]; /* more */
@@ -34,6 +23,13 @@ struct exclude_list {
        } **excludes;
 };
 
+struct exclude_stack {
+       struct exclude_stack *prev;
+       char *filebuf;
+       int baselen;
+       int exclude_ix;
+};
+
 struct dir_struct {
        int nr, alloc;
        int ignored_nr, ignored_alloc;
@@ -48,6 +44,18 @@ struct dir_struct {
        /* Exclude info */
        const char *exclude_per_dir;
        struct exclude_list exclude_list[3];
+       /*
+        * We maintain three exclude pattern lists:
+        * EXC_CMDL lists patterns explicitly given on the command line.
+        * EXC_DIRS lists patterns obtained from per-directory ignore files.
+        * EXC_FILE lists patterns from fallback ignore files.
+        */
+#define EXC_CMDL 0
+#define EXC_DIRS 1
+#define EXC_FILE 2
+
+       struct exclude_stack *exclude_stack;
+       char basebuf[PATH_MAX];
 };
 
 extern int common_prefix(const char **pathspec);
@@ -58,8 +66,6 @@ extern int common_prefix(const char **pathspec);
 extern int match_pathspec(const char **pathspec, const char *name, int namelen, int prefix, char *seen);
 
 extern int read_directory(struct dir_struct *, const char *path, const char *base, int baselen, const char **pathspec);
-extern int push_exclude_per_directory(struct dir_struct *, const char *, int);
-extern void pop_exclude_per_directory(struct dir_struct *, int);
 
 extern int excluded(struct dir_struct *, const char *);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
index 0317ad9127b374a9ded536e6fb2c825a3b13828c..fb1e92a7664f77aa5ca4ca30b4711bafaf155466 100755 (executable)
@@ -564,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;
index 4126f0e857bad273d6f44cabe34565de860bd119..76c1c844a95d8af19f64a3278706daf907dace01 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -218,7 +218,7 @@ fi
 
 case "$resolved" in
 '')
-       files=$(git diff-index --cached --name-only HEAD) || exit
+       files=$(git diff-index --cached --name-only HEAD --) || exit
        if [ "$files" ]; then
           echo "Dirty index: cannot apply patches (dirty: $files)" >&2
           exit 1
@@ -352,7 +352,7 @@ do
                case "$resolved$interactive" in
                tt)
                        # This is used only for interactive view option.
-                       git diff-index -p --cached HEAD >"$dotest/patch"
+                       git diff-index -p --cached HEAD -- >"$dotest/patch"
                        ;;
                esac
        esac
@@ -411,7 +411,7 @@ do
                # trust what the user has in the index file and the
                # working tree.
                resolved=
-               git diff-index --quiet --cached HEAD && {
+               git diff-index --quiet --cached HEAD -- && {
                        echo "No changes - did you forget to use 'git add'?"
                        stop_here_user_resolve $this
                }
@@ -433,7 +433,7 @@ do
                then
                    # Applying the patch to an earlier tree and merging the
                    # result may have produced the same tree as ours.
-                   git diff-index --quiet --cached HEAD && {
+                   git diff-index --quiet --cached HEAD -- && {
                        echo No changes -- Patch already applied.
                        go_next
                        continue
index 3aac8164c62c1f4af8df76832322df9f25a05b38..7a6521ec3c62b04fe6d4c3e80c418ccc02b4ec65 100755 (executable)
@@ -37,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
@@ -72,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"
@@ -83,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.
@@ -131,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"
 }
@@ -192,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 '
                }
@@ -276,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
@@ -318,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"`
@@ -351,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"
index aa724ac1a3859791187d257da6445d2b4adc1de8..f6d58ac044e5afb09855d687d3c1bcc8e2273be3 100755 (executable)
@@ -175,7 +175,7 @@ detach_warn=
 describe_detached_head () {
        test -n "$quiet" || {
                printf >&2 "$1 "
-               GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2"
+               GIT_PAGER= git log >&2 -1 --pretty=oneline --abbrev-commit "$2" --
        }
 }
 
@@ -266,7 +266,7 @@ if [ "$?" -eq 0 ]; then
        if test -n "$branch"
        then
                old_branch_name=`expr "z$oldbranch" : 'zrefs/heads/\(.*\)'`
-               GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from $old_branch_name to $branch" HEAD "refs/heads/$branch"
+               GIT_DIR="$GIT_DIR" git symbolic-ref -m "checkout: moving from ${old_branch_name:-$old} to $branch" HEAD "refs/heads/$branch"
                if test -n "$quiet"
                then
                        true    # nothing
@@ -278,7 +278,8 @@ if [ "$?" -eq 0 ]; then
                fi
        elif test -n "$detached"
        then
-               git update-ref --no-deref -m "checkout: moving to $arg" HEAD "$detached" ||
+               old_branch_name=`expr "z$oldbranch" : 'zrefs/heads/\(.*\)'`
+               git update-ref --no-deref -m "checkout: moving from ${old_branch_name:-$old} to $arg" HEAD "$detached" ||
                        die "Cannot detach HEAD"
                if test -n "$detach_warn"
                then
diff --git a/git-clean.sh b/git-clean.sh
deleted file mode 100755 (executable)
index 01c95e9..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005-2006 Pavel Roskin
-#
-
-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.
---
-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
-
-ignored=
-ignoredonly=
-cleandir=
-rmf="rm -f --"
-rmrf="rm -rf --"
-rm_refuse="echo Not removing"
-echo1="echo"
-
-disabled=$(git config --bool clean.requireForce)
-
-while test $# != 0
-do
-       case "$1" in
-       -d)
-               cleandir=1
-               ;;
-       -f)
-               disabled=false
-               ;;
-       -n)
-               disabled=false
-               rmf="echo Would remove"
-               rmrf="echo Would remove"
-               rm_refuse="echo Would not remove"
-               echo1=":"
-               ;;
-       -q)
-               echo1=":"
-               ;;
-       -x)
-               ignored=1
-               ;;
-       -X)
-               ignoredonly=1
-               ;;
-       --)
-               shift
-               break
-               ;;
-       *)
-               usage # should not happen
-               ;;
-       esac
-       shift
-done
-
-# requireForce used to default to false but now it defaults to true.
-# IOW, lack of explicit "clean.requireForce = false" is taken as
-# "clean.requireForce = true".
-case "$disabled" in
-"")
-       die "clean.requireForce not set and -n or -f not given; refusing to clean"
-       ;;
-"true")
-       die "clean.requireForce set and -n or -f not given; refusing to clean"
-       ;;
-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"} ${excludes_file:+"$excludes_file"} \
-       -- "$@" |
-while read -r file; do
-       if [ -d "$file" -a ! -L "$file" ]; then
-               if [ -z "$cleandir" ]; then
-                       $rm_refuse "$file"
-                       continue
-               fi
-               $echo1 "Removing $file"
-               $rmrf "$file"
-       else
-               $echo1 "Removing $file"
-               $rmf "$file"
-       fi
-done
index 276a43724d91781a6c6d79b283ef526e09917c87..79eb10eacba955e0c58a0a540c4ac577f84953e9 100644 (file)
@@ -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
 
@@ -53,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>
index efa6a0c41ad5a253047789e8ac2a30bf57f8646d..92648f40c98096d624a3a80feab4d3a818089b5a 100755 (executable)
@@ -108,10 +108,6 @@ sub read_repo_config {
             }
                }
        }
-    if (@ARGV == 0) {
-        chomp(my $module = `git-repo-config --get cvsimport.module`);
-        push(@ARGV, $module);
-    }
 }
 
 my $opts = "haivmkuo:d:p:r:C:z:s:M:P:A:S:L:";
@@ -119,6 +115,10 @@ sub read_repo_config {
 getopts($opts) or usage();
 usage if $opt_h;
 
+if (@ARGV == 0) {
+               chomp(my $module = `git-repo-config --get cvsimport.module`);
+               push(@ARGV, $module) if $? == 0;
+}
 @ARGV <= 1 or usage("You can't specify more than one CVS module");
 
 if ($opt_d) {
@@ -527,18 +527,12 @@ sub is_sha1 {
        return $s =~ /^[a-f0-9]{40}$/;
 }
 
-sub get_headref ($$) {
-    my $name    = shift;
-    my $git_dir = shift;
-
-    my $f = "$git_dir/$remote/$name";
-    if (open(my $fh, $f)) {
-           chomp(my $r = <$fh>);
-           is_sha1($r) or die "Cannot get head id for $name ($r): $!";
-           return $r;
-    }
-    die "unable to open $f: $!" unless $! == POSIX::ENOENT;
-    return undef;
+sub get_headref ($) {
+       my $name = shift;
+       my $r = `git rev-parse --verify '$name' 2>/dev/null`;
+       return undef unless $? == 0;
+       chomp $r;
+       return $r;
 }
 
 -d $git_tree
@@ -698,7 +692,8 @@ ()
 $ignorebranch{'#CVSPS_NO_BRANCH'} = 1;
 
 sub commit {
-       if ($branch eq $opt_o && !$index{branch} && !get_headref($branch, $git_dir)) {
+       if ($branch eq $opt_o && !$index{branch} &&
+               !get_headref("$remote/$branch")) {
            # looks like an initial commit
            # use the index primed by git-init
            $ENV{GIT_INDEX_FILE} = "$git_dir/index";
@@ -722,7 +717,7 @@ sub commit {
        update_index(@old, @new);
        @old = @new = ();
        my $tree = write_tree();
-       my $parent = get_headref($last_branch, $git_dir);
+       my $parent = get_headref("$remote/$last_branch");
        print "Parent ID " . ($parent ? $parent : "(empty)") . "\n" if $opt_v;
 
        my @commit_args;
@@ -733,7 +728,7 @@ sub commit {
        foreach my $rx (@mergerx) {
                next unless $logmsg =~ $rx && $1;
                my $mparent = $1 eq 'HEAD' ? $opt_o : $1;
-               if (my $sha1 = get_headref($mparent, $git_dir)) {
+               if (my $sha1 = get_headref("$remote/$mparent")) {
                        push @commit_args, '-p', $mparent;
                        print "Merge parent branch: $mparent\n" if $opt_v;
                }
@@ -870,29 +865,27 @@ sub commit {
                                print STDERR "Branch $branch erroneously stems from itself -- changed ancestor to $opt_o\n";
                                $ancestor = $opt_o;
                        }
-                       if (-f "$git_dir/$remote/$branch") {
+                       if (defined get_headref("$remote/$branch")) {
                                print STDERR "Branch $branch already exists!\n";
                                $state=11;
                                next;
                        }
-                       unless (open(H,"$git_dir/$remote/$ancestor")) {
+                       my $id = get_headref("$remote/$ancestor");
+                       if (!$id) {
                                print STDERR "Branch $ancestor does not exist!\n";
                                $ignorebranch{$branch} = 1;
                                $state=11;
                                next;
                        }
-                       chomp(my $id = <H>);
-                       close(H);
-                       unless (open(H,"> $git_dir/$remote/$branch")) {
-                               print STDERR "Could not create branch $branch: $!\n";
+
+                       system(qw(git update-ref -m cvsimport),
+                               "$remote/$branch", $id);
+                       if($? != 0) {
+                               print STDERR "Could not create branch $branch\n";
                                $ignorebranch{$branch} = 1;
                                $state=11;
                                next;
                        }
-                       print H "$id\n"
-                               or die "Could not write branch $branch: $!";
-                       close(H)
-                               or die "Could not write branch $branch: $!";
                }
                $last_branch = $branch if $branch ne $last_branch;
                $state = 9;
@@ -1004,7 +997,7 @@ sub commit {
        $orig_branch = "master";
        print "DONE; creating $orig_branch branch\n" if $opt_v;
        system("git-update-ref", "refs/heads/master", "$remote/$opt_o")
-               unless -f "$git_dir/refs/heads/master";
+               unless defined get_headref('refs/heads/master');
        system("git-symbolic-ref", "$remote/HEAD", "$remote/$opt_o")
                if ($opt_r && $opt_o ne 'HEAD');
        system('git-update-ref', 'HEAD', "$orig_branch");
index c9f515d0ee0f36fc44f667f17674462ced7c2c9e..674a25d27e50b421e516e8ca6e1190d04e323e9c 100755 (executable)
@@ -8,6 +8,9 @@
 # a new branch. You can specify a number of filters to modify the commits,
 # files and trees.
 
+# The following functions will also be available in the commit filter:
+
+functions=$(cat << \EOF
 warn () {
         echo "$*" >&2
 }
@@ -46,6 +49,10 @@ die()
        echo "$*" >&2
        exit 1
 }
+EOF
+)
+
+eval "$functions"
 
 # When piped a commit, output a script to set the ident of either
 # "author" or "committer
@@ -80,11 +87,6 @@ set_ident () {
        echo "[ -n \"\$GIT_${uid}_NAME\" ] || export GIT_${uid}_NAME=\"\${GIT_${uid}_EMAIL%%@*}\""
 }
 
-# This script can be sourced by the commit filter to get the functions
-test "a$SOURCE_FUNCTIONS" = a1 && return
-this_script="$(cd "$(dirname "$0")"; pwd)"/$(basename "$0")
-export this_script
-
 USAGE="[--env-filter <command>] [--tree-filter <command>] \
 [--index-filter <command>] [--parent-filter <command>] \
 [--msg-filter <command>] [--commit-filter <command>] \
@@ -96,7 +98,7 @@ OPTIONS_SPEC=
 . git-sh-setup
 
 git diff-files --quiet &&
-       git diff-index --cached --quiet HEAD ||
+       git diff-index --cached --quiet HEAD -- ||
        die "Cannot rewrite branch(es) with a dirty working directory."
 
 tempdir=.git-rewrite
@@ -156,7 +158,7 @@ do
                filter_msg="$OPTARG"
                ;;
        --commit-filter)
-               filter_commit='SOURCE_FUNCTIONS=1 . "$this_script";'" $OPTARG"
+               filter_commit="$functions; $OPTARG"
                ;;
        --tag-name-filter)
                filter_tag_name="$OPTARG"
index 020b86deae9ee5e258ac42b2b44c8baae7015938..6483b21cbfc73601602d628a2c609d3ca84f9e53 100644 (file)
@@ -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
index 9770b0bc27ae4dfd44f4bfcfc74946fabefdc127..cfe46a857e5fd319fa6eb49474ddbb37bd47c537 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 GVF=GIT-VERSION-FILE
-DEF_VER=0.8.GITGUI
+DEF_VER=0.9.GITGUI
 
 LF='
 '
index 18e67501375c10beebd5ec3a4d73a07aedaca81f..e8603192788fb0d8c83ff5ad33eb947cd77252b4 100644 (file)
@@ -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
index 9335a9761b458f5e8d75abf342630672751c7f2a..1fca11f278a89bb4d224738ed6dfca9822775a32 100755 (executable)
@@ -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,13 +38,31 @@ 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
 }
 
 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?
@@ -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 (file)
index 0000000..719fc54
--- /dev/null
@@ -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
+}
index 96072847a2ffeec814f499657744e5ed4f8988c0..00ecf21333c976d4c6002cd66a055803362f3523 100644 (file)
@@ -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
        }
 
index 72c45b45541749699460de1122c711888b389403..6603703ea163d830c7de1478aa2dd737c4d9d499 100644 (file)
@@ -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
 
index def615d19d6a0ba4fd76553146f29129be5baf17..53dfb4ce6bb053349fbed39af8ffaf5a143b6567 100644 (file)
@@ -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
        }
index c7573c6c7215cd4cd11f322ae3dba5b77b938078..86c4f73370a76ffa0196be0c58f11092b101cf0b 100644 (file)
@@ -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
index 1cadc31d207c49eca39bdfaa2e1c19e790d323e5..166538808f461275075e2b03c56ddc15b5813e1a 100644 (file)
@@ -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
        }
 
index 31349009aebcd769472fa4b912d1068b27b770af..53d5a628165a29c592ab14c234a000a56d7c6a12 100644 (file)
@@ -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
 
index 76f04f2854e85d51caface604d4fc10627f67620..f24396692474e3da66f9502b2f06f13583a3deeb 100644 (file)
@@ -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 (file)
index 0000000..2bac50e
--- /dev/null
@@ -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
+}
+
+}
index ec064b3e13a6b2e6ab0e3ee05ab7a55cab8aa4bc..a063c5bc49fc9bad58f7fd78e7446a097ce86b88 100644 (file)
@@ -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
index 57238129e420a313c34e2a99b9f9bdb87ecce39d..10b0430f54863111268a4b67364cbc678b0eb50d 100644 (file)
@@ -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]
 }
index b038a783581d4fcc92b030669b8a8fb3c09a623e..5597188d803a1c8217011412a39c14fbbeaf0b3a 100644 (file)
@@ -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
 }
 
 }
index 0657cc2245cec67bbb6d3399935a40247bd0c402..d66aa3fe3367e0a8db0ee5c90925352a3a143198 100644 (file)
@@ -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 (file)
index 0000000..abe8299
--- /dev/null
@@ -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]]
+}
index 694834ab7a515667dbd14b38165fbe74b37a0349..43565e412fa6c3c96487051c3997424e7d144b22 100644 (file)
@@ -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
        }
index 16a22187b26760963069bef14673b1791b311c12..13565b7ab02b22123f0b7b9000dc1f4a993994b0 100644 (file)
@@ -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 (file)
index 0000000..563dd66
Binary files /dev/null and b/git-gui/lib/git-gui.ico differ
index 44689ab63b6c4563985b42c0ff20b8427f37cadc..a0b22f2945c7293f62baf4c497fe6e8119b1df0a 100644 (file)
@@ -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 (file)
index 0000000..5ff7669
--- /dev/null
@@ -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
+}
index 0e50919d4c272e1e071e08c58b30d2c688c8d111..63e14279c183b1d0b8a62926816bb44ab6dc519c 100644 (file)
@@ -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
        }
index 063f5df6f7cd709e25a8f9c0ede263a3d10f5d8d..f812e5e89a1f21e2ee96a90e83958a472539bdd5 100644 (file)
@@ -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
index cf9b9d582959e62c805a92a86c33e0f3ae7f304e..0e86ddac0981fbb575a7dd5294ddaed29f7c3917 100644 (file)
@@ -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
                }
        }
 }
index c88a360db5daa136e2cea63323f85882ca26068a..c7b81486984d46a9dca59867c406a8e247d76313 100644 (file)
@@ -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]
index c36be2f3cd29b4b0426c312536dca6f697593305..38c3151b05c732d919943e44629bfc0a8c9fb617 100644 (file)
@@ -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"]
                }
        }
 }
index 3bf79eb6e0608560d00aab82bc1d691db83881af..51d4177551b911c35cfd8004a36fca4259367d24 100644 (file)
@@ -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} {
index 3a22bd40d4df6f18204afc154cef82d5e3d52f58..8e6a9d0a6010cf5efee069a2d488124bcbdb54cd 100644 (file)
@@ -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 (file)
index 0000000..d7f93d0
--- /dev/null
@@ -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 (file)
index 0000000..117923f
--- /dev/null
@@ -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 (file)
index 0000000..41ca08e
--- /dev/null
@@ -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 (file)
index 0000000..99913ec
--- /dev/null
@@ -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 (file)
index 0000000..77d88a7
Binary files /dev/null and b/git-gui/macosx/git-gui.icns differ
diff --git a/git-gui/po/.gitignore b/git-gui/po/.gitignore
new file mode 100644 (file)
index 0000000..a89cf44
--- /dev/null
@@ -0,0 +1,2 @@
+*.msg
+*~
diff --git a/git-gui/po/README b/git-gui/po/README
new file mode 100644 (file)
index 0000000..9d8b736
--- /dev/null
@@ -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 (file)
index 0000000..3df30ed
--- /dev/null
@@ -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 (file)
index 0000000..00f0f59
--- /dev/null
@@ -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 (file)
index 0000000..749aa2e
--- /dev/null
@@ -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 (file)
index 0000000..c94786c
--- /dev/null
@@ -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 (file)
index 0000000..48af803
--- /dev/null
@@ -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 (file)
index 0000000..500d0a0
--- /dev/null
@@ -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 (file)
index 0000000..8e3d9a2
--- /dev/null
@@ -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 (executable)
index 0000000..49bf7c5
--- /dev/null
@@ -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 (file)
index 0000000..158835b
--- /dev/null
@@ -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 (file)
index 0000000..e8c04f7
--- /dev/null
@@ -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 (file)
index 0000000..7668414
--- /dev/null
@@ -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 (file)
index 0000000..f3a547b
--- /dev/null
@@ -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 (file)
index 0000000..c63248e
--- /dev/null
@@ -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 (file)
index 0000000..6727a83
--- /dev/null
@@ -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 (file)
index 0000000..621c947
--- /dev/null
@@ -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 (file)
index 0000000..98f32c0
--- /dev/null
@@ -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-ls-remote.sh b/git-ls-remote.sh
deleted file mode 100755 (executable)
index fec70bb..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh
-#
-
-usage () {
-    echo >&2 "usage: $0 [--heads] [--tags] [-u|--upload-pack <upload-pack>]"
-    echo >&2 "          <repository> <refs>..."
-    exit 1;
-}
-
-die () {
-    echo >&2 "$*"
-    exit 1
-}
-
-exec=
-while test $# != 0
-do
-  case "$1" in
-  -h|--h|--he|--hea|--head|--heads)
-  heads=heads; shift ;;
-  -t|--t|--ta|--tag|--tags)
-  tags=tags; shift ;;
-  -u|--u|--up|--upl|--uploa|--upload|--upload-|--upload-p|--upload-pa|\
-  --upload-pac|--upload-pack)
-       shift
-       exec="--upload-pack=$1"
-       shift;;
-  -u=*|--u=*|--up=*|--upl=*|--uplo=*|--uploa=*|--upload=*|\
-  --upload-=*|--upload-p=*|--upload-pa=*|--upload-pac=*|--upload-pack=*)
-       exec=--upload-pack=$(expr "z$1" : 'z-[^=]*=\(.*\)')
-       shift;;
-  --)
-  shift; break ;;
-  -*)
-  usage ;;
-  *)
-  break ;;
-  esac
-done
-
-case "$#" in 0) usage ;; esac
-
-case ",$heads,$tags," in
-,,,) heads=heads tags=tags other=other ;;
-esac
-
-. git-parse-remote
-peek_repo="$(get_remote_url "$@")"
-shift
-
-tmp=.ls-remote-$$
-trap "rm -fr $tmp-*" 0 1 2 3 15
-tmpdir=$tmp-d
-
-case "$peek_repo" in
-http://* | https://* | ftp://* )
-       if [ -n "$GIT_SSL_NO_VERIFY" -o \
-               "`git config --bool http.sslVerify`" = false ]; then
-               curl_extra_args="-k"
-       fi
-       if [ -n "$GIT_CURL_FTP_NO_EPSV" -o \
-               "`git config --bool http.noEPSV`" = true ]; then
-               curl_extra_args="${curl_extra_args} --disable-epsv"
-       fi
-       curl -nsf $curl_extra_args --header "Pragma: no-cache" "$peek_repo/info/refs" ||
-               echo "failed    slurping"
-       ;;
-
-rsync://* )
-       mkdir $tmpdir &&
-       rsync -rlq "$peek_repo/HEAD" $tmpdir &&
-       rsync -rq "$peek_repo/refs" $tmpdir || {
-               echo "failed    slurping"
-               exit
-       }
-       head=$(cat "$tmpdir/HEAD") &&
-       case "$head" in
-       ref:' '*)
-               head=$(expr "z$head" : 'zref: \(.*\)') &&
-               head=$(cat "$tmpdir/$head") || exit
-       esac &&
-       echo "$head     HEAD"
-       (cd $tmpdir && find refs -type f) |
-       while read path
-       do
-               tr -d '\012' <"$tmpdir/$path"
-               echo "  $path"
-       done &&
-       rm -fr $tmpdir
-       ;;
-
-* )
-       if test -f "$peek_repo" ; then
-               git bundle list-heads "$peek_repo" ||
-               echo "failed    slurping"
-       else
-               git-peek-remote $exec "$peek_repo" ||
-               echo "failed    slurping"
-       fi
-       ;;
-esac |
-sort -t '      ' -k 2 |
-while read sha1 path
-do
-       case "$sha1" in
-       failed)
-               exit 1 ;;
-       esac
-       case "$path" in
-       refs/heads/*)
-               group=heads ;;
-       refs/tags/*)
-               group=tags ;;
-       *)
-               group=other ;;
-       esac
-       case ",$heads,$tags,$other," in
-       *,$group,*)
-               ;;
-       *)
-               continue;;
-       esac
-       case "$#" in
-       0)
-               match=yes ;;
-       *)
-               match=no
-               for pat
-               do
-                       case "/$path" in
-                       */$pat )
-                               match=yes
-                               break ;;
-                       esac
-               done
-       esac
-       case "$match" in
-       no)
-               continue ;;
-       esac
-       echo "$sha1     $path"
-done
diff --git a/git-merge-ours.sh b/git-merge-ours.sh
deleted file mode 100755 (executable)
index c81a790..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/sh
-#
-# Copyright (c) 2005 Junio C Hamano
-#
-# Pretend we resolved the heads, but declare our tree trumps everybody else.
-#
-
-# 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.
-
-git diff-index --quiet --cached HEAD || exit 2
-
-exit 0
index 66c80d4e16e3217b93b9de12a4b02d107a2eeb71..e9cd6fd999695daa1c5ba49835f53041d4131f3a 100755 (executable)
@@ -53,7 +53,7 @@ require_clean_work_tree () {
        git rev-parse --verify HEAD > /dev/null &&
        git update-index --refresh &&
        git diff-files --quiet &&
-       git diff-index --cached --quiet HEAD ||
+       git diff-index --cached --quiet HEAD -- ||
        die "Working tree is dirty"
 }
 
@@ -356,7 +356,7 @@ do
                git rev-parse --verify HEAD > /dev/null &&
                git update-index --refresh &&
                git diff-files --quiet &&
-               ! git diff-index --cached --quiet HEAD &&
+               ! git diff-index --cached --quiet HEAD -- &&
                . "$DOTEST"/author-script && {
                        test ! -f "$DOTEST"/amend || git reset --soft HEAD^
                } &&
@@ -485,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
@@ -494,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"
index df5fd65d56bde3ed046c9ed40e62e8a17ede2e8e..bdcea0ed703057e08fd4204245f4f0c8a308f8d0 100755 (executable)
@@ -61,7 +61,7 @@ continue_merge () {
        fi
 
        cmt=`cat "$dotest/current"`
-       if ! git diff-index --quiet HEAD
+       if ! git diff-index --quiet HEAD --
        then
                if ! git-commit -C "$cmt"
                then
@@ -179,6 +179,7 @@ do
                exit
                ;;
        --skip)
+               git reset --hard HEAD || exit $?
                if test -d "$dotest"
                then
                        git rerere clear
@@ -284,7 +285,7 @@ fi
 
 # The tree must be really really clean.
 git update-index --refresh || exit
-diff=$(git diff-index --cached --name-status -r HEAD)
+diff=$(git diff-index --cached --name-status -r HEAD --)
 case "$diff" in
 ?*)    echo "cannot rebase: your index is not up-to-date"
        echo "$diff"
index fd0a4ad0c24dfedd2fea278733d8f6cff59b2eb5..76baa8e431e082c1e36eb9c78125094de0b8a85e 100755 (executable)
@@ -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();
@@ -557,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);
@@ -631,7 +636,7 @@ sub send_message
                }
 
                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;
@@ -643,7 +648,7 @@ sub send_message
        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";
@@ -651,7 +656,7 @@ sub send_message
                } 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";
@@ -781,7 +786,8 @@ sub send_message
                        else {
                                push @xh,
                                  'MIME-Version: 1.0',
-                                 "Content-Type: text/plain; charset=$author_encoding";
+                                 "Content-Type: text/plain; charset=$author_encoding",
+                                 'Content-Transfer-Encoding: 8bit';
                        }
                }
        }
index 534eb168abf8b0b8ae5c2195bf85b66d9cb6b21e..b1529e28b1c4eb8b236bd497c83690c20621d369 100755 (executable)
@@ -15,7 +15,7 @@ trap 'rm -f "$TMP-*"' 0
 ref_stash=refs/stash
 
 no_changes () {
-       git diff-index --quiet --cached HEAD &&
+       git diff-index --quiet --cached HEAD -- &&
        git diff-files --quiet
 }
 
@@ -37,7 +37,7 @@ create_stash () {
        # state of the base commit
        if b_commit=$(git rev-parse --verify HEAD)
        then
-               head=$(git log --abbrev-commit --pretty=oneline -n 1 HEAD)
+               head=$(git log --no-color --abbrev-commit --pretty=oneline -n 1 HEAD --)
        else
                die "You do not have the initial commit yet"
        fi
@@ -108,7 +108,7 @@ have_stash () {
 
 list_stash () {
        have_stash || return 0
-       git log --pretty=oneline -g "$@" $ref_stash |
+       git log --no-color --pretty=oneline -g "$@" $ref_stash -- |
        sed -n -e 's/^[.0-9a-f]* refs\///p'
 }
 
index 5b1deeab942aa2a63a6cbe6a92792dbbe6f17d01..9f884eb2132c76b86475b97256e0ed565f84bb2e 100755 (executable)
@@ -35,6 +35,7 @@
 push @SVN::Git::Editor::ISA, 'SVN::Delta::Editor';
 push @SVN::Git::Fetcher::ISA, 'SVN::Delta::Editor';
 use Carp qw/croak/;
+use Digest::MD5;
 use IO::File qw//;
 use File::Basename qw/dirname basename/;
 use File::Path qw/mkpath/;
@@ -64,7 +65,7 @@ BEGIN
        $_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,
@@ -80,6 +81,7 @@ BEGIN
                'quiet|q' => \$_q,
                'repack-flags|repack-args|repack-opts=s' =>
                   \$Git::SVN::_repack_flags,
+               'use-log-author' => \$Git::SVN::_use_log_author,
                %remote_opts );
 
 my ($_trunk, $_tags, $_branches, $_stdlayout);
@@ -141,6 +143,9 @@ BEGIN
        'show-ignore' => [ \&cmd_show_ignore, "Show svn:ignore listings",
                        { 'revision|r=i' => \$_revision
                        } ],
+       'show-externals' => [ \&cmd_show_externals, "Show svn:externals listings",
+                       { 'revision|r=i' => \$_revision
+                       } ],
        'multi-fetch' => [ \&cmd_multi_fetch,
                           "Deprecated alias for $0 fetch --all",
                           { 'revision|r=s' => \$_revision, %fc_opts } ],
@@ -177,6 +182,10 @@ BEGIN
                          '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;
@@ -188,23 +197,6 @@ BEGIN
        }
 };
 
-my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
-
-read_repo_config(\%opts);
-Getopt::Long::Configure('pass_through') if ($cmd && $cmd eq 'log');
-my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
-                    'minimize-connections' => \$Git::SVN::Migration::_minimize,
-                    'id|i=s' => \$Git::SVN::default_ref_id,
-                    'svn-remote|remote|R=s' => sub {
-                       $Git::SVN::no_reuse_existing = 1;
-                       $Git::SVN::default_repo_id = $_[1] });
-exit 1 if (!$rv && $cmd && $cmd ne 'log');
-
-usage(0) if $_help;
-version() if $_version;
-usage(1) unless defined $cmd;
-load_authors() if $_authors;
-
 # make sure we're always running
 unless ($cmd =~ /(?:clone|init|multi-init)$/) {
        unless (-d $ENV{GIT_DIR}) {
@@ -226,6 +218,24 @@ BEGIN
                $ENV{GIT_DIR} = $git_dir;
        }
 }
+
+my %opts = %{$cmd{$cmd}->[2]} if (defined $cmd);
+
+read_repo_config(\%opts);
+Getopt::Long::Configure('pass_through') if ($cmd && $cmd eq 'log');
+my $rv = GetOptions(%opts, 'help|H|h' => \$_help, 'version|V' => \$_version,
+                    'minimize-connections' => \$Git::SVN::Migration::_minimize,
+                    'id|i=s' => \$Git::SVN::default_ref_id,
+                    'svn-remote|remote|R=s' => sub {
+                       $Git::SVN::no_reuse_existing = 1;
+                       $Git::SVN::default_repo_id = $_[1] });
+exit 1 if (!$rv && $cmd && $cmd ne 'log');
+
+usage(0) if $_help;
+version() if $_version;
+usage(1) unless defined $cmd;
+load_authors() if $_authors;
+
 unless ($cmd =~ /^(?:clone|init|multi-init|commit-diff)$/) {
        Git::SVN::Migration::migration_check();
 }
@@ -540,6 +550,8 @@ sub cmd_rebase {
                exit 1;
        }
        unless ($_local) {
+               # rebase will checkout for us, so no need to do it explicitly
+               $_no_checkout = 'true';
                $_fetch_all ? $gs->fetch_all : $gs->fetch;
        }
        command_noisy(rebase_cmd(), $gs->refname);
@@ -560,6 +572,21 @@ sub cmd_show_ignore {
        });
 }
 
+sub cmd_show_externals {
+       my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
+       $gs ||= Git::SVN->new;
+       my $r = (defined $_revision ? $_revision : $gs->ra->get_latest_revnum);
+       $gs->prop_walk($gs->{path}, $r, sub {
+               my ($gs, $path, $props) = @_;
+               print STDOUT "\n# $path\n";
+               my $s = $props->{'svn:externals'} or return;
+               $s =~ s/[\r\n]+/\n/g;
+               chomp $s;
+               $s =~ s#^#$path#gm;
+               print STDOUT "$s\n";
+       });
+}
+
 sub cmd_create_ignore {
        my ($url, $rev, $uuid, $gs) = working_head_info('HEAD');
        $gs ||= Git::SVN->new;
@@ -583,6 +610,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.
@@ -600,12 +644,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;
@@ -736,6 +775,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 = md5sum("link $file_name");
+                       } else {
+                               $checksum = md5sum($fh);
+                       }
+                       command_close_pipe($fh, $ctx);
+               } elsif ($file_type eq "link") {
+                       my $file_name =
+                           command(qw(cat-file blob), "HEAD:$path");
+                       $checksum =
+                           md5sum("link " . $file_name);
+               } else {
+                       open FILE, "<", $path or die $!;
+                       $checksum = md5sum(\*FILE);
+                       close FILE or die $!;
+               }
+               $result .= "Checksum: " . $checksum . "\n";
+       }
+
+       print $result, "\n";
+}
+
 ########################### utility functions #########################
 
 sub rebase_cmd {
@@ -1043,12 +1190,54 @@ 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);
+}
+
+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;
 use vars qw/$default_repo_id $default_ref_id $_no_metadata $_follow_parent
             $_repack $_repack_flags $_use_svm_props $_head
-            $_use_svnsync_props $no_reuse_existing $_minimize_url/;
+            $_use_svnsync_props $no_reuse_existing $_minimize_url
+           $_use_log_author/;
 use Carp qw/croak/;
 use File::Path qw/mkpath/;
 use File::Copy qw/copy/;
@@ -1607,9 +1796,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 ",
@@ -1873,11 +2077,17 @@ sub do_git_commit {
                croak "$log_entry->{revision} = $c already exists! ",
                      "Why are we refetching it?\n";
        }
-       $ENV{GIT_AUTHOR_NAME} = $ENV{GIT_COMMITTER_NAME} = $log_entry->{name};
-       $ENV{GIT_AUTHOR_EMAIL} = $ENV{GIT_COMMITTER_EMAIL} =
-                                                         $log_entry->{email};
+       $ENV{GIT_AUTHOR_NAME} = $log_entry->{name};
+       $ENV{GIT_AUTHOR_EMAIL} = $log_entry->{email};
        $ENV{GIT_AUTHOR_DATE} = $ENV{GIT_COMMITTER_DATE} = $log_entry->{date};
 
+       $ENV{GIT_COMMITTER_NAME} = (defined $log_entry->{commit_name})
+                                               ? $log_entry->{commit_name}
+                                               : $log_entry->{name};
+       $ENV{GIT_COMMITTER_EMAIL} = (defined $log_entry->{commit_email})
+                                               ? $log_entry->{commit_email}
+                                               : $log_entry->{email};
+
        my $tree = $log_entry->{tree};
        if (!defined $tree) {
                $tree = $self->tmp_index_do(sub {
@@ -2165,7 +2375,17 @@ sub make_log_entry {
        $log_entry{log} .= "\n";
        my $author = $log_entry{author} = check_author($log_entry{author});
        my ($name, $email) = defined $::users{$author} ? @{$::users{$author}}
-                                                      : ($author, undef);
+                                                      : ($author, undef);
+
+       my ($commit_name, $commit_email) = ($name, $email);
+       if ($_use_log_author) {
+               if ($log_entry{log} =~ /From:\s+(.*?)\s+<(.*)>\s*\n/) {
+                       ($name, $email) = ($1, $2);
+               } elsif ($log_entry{log} =~
+                                     /Signed-off-by:\s+(.*?)\s+<(.*)>\s*\n/) {
+                       ($name, $email) = ($1, $2);
+               }
+       }
        if (defined $headrev && $self->use_svm_props) {
                if ($self->rewrite_root) {
                        die "Can't have both 'useSvmProps' and 'rewriteRoot' ",
@@ -2188,23 +2408,28 @@ sub make_log_entry {
                remove_username($full_url);
                $log_entry{metadata} = "$full_url\@$r $uuid";
                $log_entry{svm_revision} = $r;
-               $email ||= "$author\@$uuid"
+               $email ||= "$author\@$uuid";
+               $commit_email ||= "$author\@$uuid";
        } elsif ($self->use_svnsync_props) {
                my $full_url = $self->svnsync->{url};
                $full_url .= "/$self->{path}" if length $self->{path};
                remove_username($full_url);
                my $uuid = $self->svnsync->{uuid};
                $log_entry{metadata} = "$full_url\@$rev $uuid";
-               $email ||= "$author\@$uuid"
+               $email ||= "$author\@$uuid";
+               $commit_email ||= "$author\@$uuid";
        } else {
                my $url = $self->metadata_url;
                remove_username($url);
                $log_entry{metadata} = "$url\@$rev " .
                                       $self->ra->get_uuid;
                $email ||= "$author\@" . $self->ra->get_uuid;
+               $commit_email ||= "$author\@" . $self->ra->get_uuid;
        }
        $log_entry{name} = $name;
        $log_entry{email} = $email;
+       $log_entry{commit_name} = $commit_name;
+       $log_entry{commit_email} = $commit_email;
        \%log_entry;
 }
 
@@ -2610,7 +2835,6 @@ package SVN::Git::Fetcher;
 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 {
@@ -2762,9 +2986,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 = ::md5sum($base);
                        die "Checksum mismatch: $fb->{path} $fb->{blob}\n",
                            "expected: $exp\n",
                            "     got: $got\n" if ($got ne $exp);
@@ -2783,9 +3005,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 = ::md5sum($fh);
                        if ($got ne $exp) {
                                die "Checksum mismatch: $path\n",
                                    "expected: $exp\n    got: $got\n";
@@ -2837,7 +3057,6 @@ package SVN::Git::Editor;
 use warnings;
 use Carp qw/croak/;
 use IO::File;
-use Digest::MD5;
 
 sub new {
        my ($class, $opts) = @_;
@@ -3141,11 +3360,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 = ::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);
@@ -3859,6 +4076,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)$//;
@@ -3879,13 +4119,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 {
@@ -3939,8 +4173,7 @@ sub show_commit_normal {
        my ($c) = @_;
        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}) {
@@ -3980,11 +4213,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);
diff --git a/git.c b/git.c
index 7604319b5a9e8c12b2f00b4d5e6480445e02daa6..01bbbc73258dc66d8d3a8253cc9328b5b18346aa 100644 (file)
--- 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 },
@@ -321,13 +322,16 @@ static void handle_internal_command(int argc, const char **argv)
                { "log", cmd_log, RUN_SETUP | USE_PAGER },
                { "ls-files", cmd_ls_files, RUN_SETUP },
                { "ls-tree", cmd_ls_tree, RUN_SETUP },
+               { "ls-remote", cmd_ls_remote },
                { "mailinfo", cmd_mailinfo },
                { "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 },
+               { "peek-remote", cmd_ls_remote },
                { "pickaxe", cmd_blame, RUN_SETUP },
                { "prune", cmd_prune, RUN_SETUP },
                { "prune-packed", cmd_prune_packed, RUN_SETUP },
@@ -342,6 +346,7 @@ static void handle_internal_command(int argc, const char **argv)
                { "revert", cmd_revert, RUN_SETUP | NEED_WORK_TREE },
                { "rm", cmd_rm, RUN_SETUP },
                { "runstatus", cmd_runstatus, RUN_SETUP | NEED_WORK_TREE },
+               { "send-pack", cmd_send_pack, RUN_SETUP },
                { "shortlog", cmd_shortlog, RUN_SETUP | USE_PAGER },
                { "show-branch", cmd_show_branch, RUN_SETUP },
                { "show", cmd_show, RUN_SETUP | USE_PAGER },
index 1b8887987fc0888db6e7548e9561745efee790d8..446a1c333bd55bb25db5e53794277e9e6d2c51da 100644 (file)
@@ -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;
 }
 
index e788ef90c981e93f59400332da8bb7de1c2b3952..491a3f41d20deafa6513e7f574108022b762507b 100755 (executable)
@@ -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 8217d97787b2ba38a5327c1204797044b2b4cd72..d340b6a1b6c4ecb8132e81fe306883aa18feb090 100644 (file)
--- 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)
index 9314621a11030e66eeba7f0da6b88a813e1ba759..78283b4de3b9111d87368df747daa96b5f6c09c3 100644 (file)
@@ -78,7 +78,7 @@ static struct curl_slist *no_pragma_header;
 static struct curl_slist *default_headers;
 
 static int push_verbosely;
-static int push_all;
+static int push_all = MATCH_REFS_NONE;
 static int force_all;
 static int dry_run;
 
@@ -433,7 +433,7 @@ static void start_fetch_packed(struct transfer_request *request)
        packfile = fopen(request->tmpfile, "a");
        if (!packfile) {
                fprintf(stderr, "Unable to open local file %s for pack",
-                       filename);
+                       request->tmpfile);
                remote->can_update_info_refs = 0;
                free(url);
                return;
@@ -941,7 +941,7 @@ static int fetch_index(unsigned char *sha1)
        indexfile = fopen(tmpfile, "a");
        if (!indexfile)
                return error("Unable to open local file %s for pack index",
-                            filename);
+                            tmpfile);
 
        slot = get_active_slot();
        slot->results = &results;
@@ -2300,7 +2300,7 @@ int main(int argc, char **argv)
 
                if (*arg == '-') {
                        if (!strcmp(arg, "--all")) {
-                               push_all = 1;
+                               push_all = MATCH_REFS_ALL;
                                continue;
                        }
                        if (!strcmp(arg, "--force")) {
@@ -2393,7 +2393,7 @@ int main(int argc, char **argv)
        if (!remote_tail)
                remote_tail = &remote_refs;
        if (match_refs(local_refs, remote_refs, &remote_tail,
-                      nr_refspec, refspec, push_all))
+                      nr_refspec, (const char **) refspec, push_all))
                return -1;
        if (!remote_refs) {
                fprintf(stderr, "No refs in common and none specified; doing nothing.\n");
index 444aebf5268c982255f73b151ff5c03bdffecdbe..a3fb596542eea6d85a6cb32add100e8d71e7713a 100644 (file)
@@ -405,7 +405,7 @@ static int fetch_index(struct walker *walker, struct alt_base *repo, unsigned ch
        indexfile = fopen(tmpfile, "a");
        if (!indexfile)
                return error("Unable to open local file %s for pack index",
-                            filename);
+                            tmpfile);
 
        slot = get_active_slot();
        slot->results = &results;
@@ -770,7 +770,7 @@ static int fetch_pack(struct walker *walker, struct alt_base *repo, unsigned cha
        packfile = fopen(tmpfile, "a");
        if (!packfile)
                return error("Unable to open local file %s for pack",
-                            filename);
+                            tmpfile);
 
        slot = get_active_slot();
        slot->results = &results;
index 9a1f64d8d71d13ee6be48c539d79764066288f07..f45d3ed54454635b84cfe9b8c1e7d99d33ffd4d9 100644 (file)
@@ -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;
        }
 }
@@ -92,7 +94,7 @@ static char *resolve_symlink(char *p, size_t s)
                        return p;
                }
 
-               if (link[0] == '/') {
+               if (is_absolute_path(link)) {
                        /* absolute path simply replaces p */
                        if (link_len < s)
                                strcpy(p, link);
@@ -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/pager.c b/pager.c
index 8bac9d990381f5664333a92f68b0b8cd97d43855..fb7a1a625abf07b0d896a270286ee422a700c14c 100644 (file)
--- 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.
index d3e608ac45e2a0c6accb9d27ed8d407619cb70d2..e12b428c0a76a635041f678a3eaf05300d780061 100644 (file)
@@ -216,6 +216,9 @@ static int parse_long_opt(struct optparse_t *p, const char *arg,
        return error("unknown option `%s'", arg);
 }
 
+static NORETURN void usage_with_options_internal(const char * const *,
+                                                 const struct option *, int);
+
 int parse_options(int argc, const char **argv, const struct option *options,
                   const char * const usagestr[], int flags)
 {
@@ -249,6 +252,8 @@ int parse_options(int argc, const char **argv, const struct option *options,
                        break;
                }
 
+               if (!strcmp(arg + 2, "help-all"))
+                       usage_with_options_internal(usagestr, options, 1);
                if (!strcmp(arg + 2, "help"))
                        usage_with_options(usagestr, options);
                if (parse_long_opt(&args, arg + 2, options))
@@ -263,8 +268,8 @@ int parse_options(int argc, const char **argv, const struct option *options,
 #define USAGE_OPTS_WIDTH 24
 #define USAGE_GAP         2
 
-void usage_with_options(const char * const *usagestr,
-                        const struct option *opts)
+void usage_with_options_internal(const char * const *usagestr,
+                                 const struct option *opts, int full)
 {
        fprintf(stderr, "usage: %s\n", *usagestr++);
        while (*usagestr && **usagestr)
@@ -285,6 +290,8 @@ void usage_with_options(const char * const *usagestr,
                                fprintf(stderr, "%s\n", opts->help);
                        continue;
                }
+               if (!full && (opts->flags & PARSE_OPT_HIDDEN))
+                       continue;
 
                pos = fprintf(stderr, "    ");
                if (opts->short_name)
@@ -335,6 +342,12 @@ void usage_with_options(const char * const *usagestr,
        exit(129);
 }
 
+void usage_with_options(const char * const *usagestr,
+                        const struct option *opts)
+{
+       usage_with_options_internal(usagestr, opts, 0);
+}
+
 /*----- some often used options -----*/
 #include "cache.h"
 
index a8760ac4b288a44d6404d0550b9640b49789d39d..102ac31fb727acfdc3c2159e1525c7bcca94e1ef 100644 (file)
@@ -24,6 +24,7 @@ enum parse_opt_option_flags {
        PARSE_OPT_OPTARG  = 1,
        PARSE_OPT_NOARG   = 2,
        PARSE_OPT_NONEG   = 4,
+       PARSE_OPT_HIDDEN  = 8,
 };
 
 struct option;
@@ -57,6 +58,8 @@ typedef int parse_opt_cb(const struct option *, const char *arg, int unset);
  *   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
+ *   PARSE_OPT_HIDDEN this option is skipped in the default usage, showed in
+ *                    the long one.
  *
  * `callback`::
  *   pointer to the callback to use for OPTION_CALLBACK.
diff --git a/peek-remote.c b/peek-remote.c
deleted file mode 100644 (file)
index 8d20f7c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-#include "cache.h"
-#include "refs.h"
-#include "pkt-line.h"
-
-static const char peek_remote_usage[] =
-"git-peek-remote [--upload-pack=<git-upload-pack>] [<host>:]<directory>";
-static const char *uploadpack = "git-upload-pack";
-
-static int peek_remote(int fd[2], unsigned flags)
-{
-       struct ref *ref;
-
-       get_remote_heads(fd[0], &ref, 0, NULL, flags);
-       packet_flush(fd[1]);
-
-       while (ref) {
-               printf("%s      %s\n", sha1_to_hex(ref->old_sha1), ref->name);
-               ref = ref->next;
-       }
-       return 0;
-}
-
-int main(int argc, char **argv)
-{
-       int i, ret;
-       char *dest = NULL;
-       int fd[2];
-       struct child_process *conn;
-       int nongit = 0;
-       unsigned flags = 0;
-
-       setup_git_directory_gently(&nongit);
-
-       for (i = 1; i < argc; i++) {
-               char *arg = argv[i];
-
-               if (*arg == '-') {
-                       if (!prefixcmp(arg, "--upload-pack=")) {
-                               uploadpack = arg + 14;
-                               continue;
-                       }
-                       if (!prefixcmp(arg, "--exec=")) {
-                               uploadpack = arg + 7;
-                               continue;
-                       }
-                       if (!strcmp("--tags", arg)) {
-                               flags |= REF_TAGS;
-                               continue;
-                       }
-                       if (!strcmp("--heads", arg)) {
-                               flags |= REF_HEADS;
-                               continue;
-                       }
-                       if (!strcmp("--refs", arg)) {
-                               flags |= REF_NORMAL;
-                               continue;
-                       }
-                       usage(peek_remote_usage);
-               }
-               dest = arg;
-               break;
-       }
-
-       if (!dest || i != argc - 1)
-               usage(peek_remote_usage);
-
-       conn = git_connect(fd, dest, uploadpack, 0);
-       ret = peek_remote(fd, flags);
-       close(fd[0]);
-       close(fd[1]);
-       ret |= finish_connect(conn);
-       return !!ret;
-}
index dca92c8adb52e212ef96410d3efd4deaa28e385f..7468460f9a6d29d5c4bf14db4921bf28e23b6814 100644 (file)
@@ -549,6 +549,37 @@ sub config_bool {
        };
 }
 
+=item config_int ( VARIABLE )
+
+Retrieve the integer configuration C<VARIABLE>. The return value
+is simple decimal number.  An optional value suffix of 'k', 'm',
+or 'g' in the config file will cause the value to be multiplied
+by 1024, 1048576 (1024^2), or 1073741824 (1024^3) prior to output.
+It would return C<undef> if configuration variable is not defined,
+
+Must be called on a repository instance.
+
+This currently wraps command('config') so it is not so fast.
+
+=cut
+
+sub config_int {
+       my ($self, $var) = @_;
+       $self->repo_path()
+               or throw Error::Simple("not a repository");
+
+       try {
+               return $self->command_oneline('config', '--int', '--get', $var);
+       } catch Git::Error::Command with {
+               my $E = shift;
+               if ($E->value() == 1) {
+                       # Key not found.
+                       return undef;
+               } else {
+                       throw $E;
+               }
+       };
+}
 
 =item ident ( TYPE | IDENTSTR )
 
index 4bd650f9ba496786029791bc8a0a40b611bdeb63..d19f80c0bb25928383f8a1aff3f6f49f9a65131c 100644 (file)
@@ -98,11 +98,13 @@ static int display(struct progress *progress, unsigned n, const char *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;
        }
@@ -207,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;
index 38e35c06b9e73376adde597c4fe28490a2e886b1..fba4cf82353ff43eae7430c863680f481e03dcb0 100644 (file)
@@ -200,12 +200,14 @@ static const char *update(struct command *cmd)
        }
 
        if (is_null_sha1(new_sha1)) {
+               if (!parse_object(old_sha1)) {
+                       warning ("Allowing deletion of corrupt ref.");
+                       old_sha1 = NULL;
+               }
                if (delete_ref(name, old_sha1)) {
                        error("failed to delete %s", name);
                        return "failed to delete";
                }
-               fprintf(stderr, "%s: %s -> deleted\n", name,
-                       sha1_to_hex(old_sha1));
                return NULL; /* good */
        }
        else {
@@ -217,8 +219,6 @@ static const char *update(struct command *cmd)
                if (write_ref_sha1(lock, new_sha1, "push")) {
                        return "failed to write"; /* error() already called */
                }
-               fprintf(stderr, "%s: %s -> %s\n", name,
-                       sha1_to_hex(old_sha1), sha1_to_hex(new_sha1));
                return NULL; /* good */
        }
 }
diff --git a/refs.c b/refs.c
index ae532540cf2592aee2be7610ac811082c3a9b6be..54ec98d153889f40313dba9a5ee8f07ddd0e160a 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -1433,3 +1433,11 @@ int update_ref(const char *action, const char *refname,
        }
        return 0;
 }
+
+struct ref *find_ref_by_name(struct ref *list, const char *name)
+{
+       for ( ; list; list = list->next)
+               if (!strcmp(list->name, name))
+                       return list;
+       return NULL;
+}
index bec2ba1adbed02af54572be924dcfbb47bf9c423..bb010590837fd6ea188e64c5263bb1fe12ab93f4 100644 (file)
--- a/remote.c
+++ b/remote.c
@@ -485,7 +485,7 @@ struct ref *alloc_ref(unsigned namelen)
        return ret;
 }
 
-static struct ref *copy_ref(struct ref *ref)
+static struct ref *copy_ref(const struct ref *ref)
 {
        struct ref *ret = xmalloc(sizeof(struct ref) + strlen(ref->name) + 1);
        memcpy(ret, ref, sizeof(struct ref) + strlen(ref->name) + 1);
@@ -493,6 +493,18 @@ static struct ref *copy_ref(struct ref *ref)
        return ret;
 }
 
+struct ref *copy_ref_list(const struct ref *ref)
+{
+       struct ref *ret = NULL;
+       struct ref **tail = &ret;
+       while (ref) {
+               *tail = copy_ref(ref);
+               ref = ref->next;
+               tail = &((*tail)->next);
+       }
+       return ret;
+}
+
 void free_refs(struct ref *ref)
 {
        struct ref *next;
@@ -684,14 +696,6 @@ static int match_explicit_refs(struct ref *src, struct ref *dst,
        return -errs;
 }
 
-static struct ref *find_ref_by_name(struct ref *list, const char *name)
-{
-       for ( ; list; list = list->next)
-               if (!strcmp(list->name, name))
-                       return list;
-       return NULL;
-}
-
 static const struct refspec *check_pattern_match(const struct refspec *rs,
                                                 int rs_nr,
                                                 const struct ref *src)
@@ -710,10 +714,12 @@ static const struct refspec *check_pattern_match(const struct refspec *rs,
  * without thinking.
  */
 int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
-              int nr_refspec, char **refspec, int all)
+              int nr_refspec, const char **refspec, int flags)
 {
        struct refspec *rs =
                parse_ref_spec(nr_refspec, (const char **) refspec);
+       int send_all = flags & MATCH_REFS_ALL;
+       int send_mirror = flags & MATCH_REFS_MIRROR;
 
        if (match_explicit_refs(src, dst, dst_tail, rs, nr_refspec))
                return -1;
@@ -730,7 +736,7 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
                        if (!pat)
                                continue;
                }
-               else if (prefixcmp(src->name, "refs/heads/"))
+               else if (!send_mirror && prefixcmp(src->name, "refs/heads/"))
                        /*
                         * "matching refs"; traditionally we pushed everything
                         * including refs outside refs/heads/ hierarchy, but
@@ -751,10 +757,13 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
                if (dst_peer && dst_peer->peer_ref)
                        /* We're already sending something to this ref. */
                        goto free_name;
-               if (!dst_peer && !nr_refspec && !all)
-                       /* Remote doesn't have it, and we have no
+
+               if (!dst_peer && !nr_refspec && !(send_all || send_mirror))
+                       /*
+                        * Remote doesn't have it, and we have no
                         * explicit pattern, and we don't have
-                        * --all. */
+                        * --all nor --mirror.
+                        */
                        goto free_name;
                if (!dst_peer) {
                        /* Create a new one and link it */
@@ -810,10 +819,10 @@ int branch_merge_matches(struct branch *branch,
        return ref_matches_abbrev(branch->merge[i]->src, refname);
 }
 
-static struct ref *get_expanded_map(struct ref *remote_refs,
+static struct ref *get_expanded_map(const struct ref *remote_refs,
                                    const struct refspec *refspec)
 {
-       struct ref *ref;
+       const struct ref *ref;
        struct ref *ret = NULL;
        struct ref **tail = &ret;
 
@@ -824,7 +833,7 @@ static struct ref *get_expanded_map(struct ref *remote_refs,
                if (strchr(ref->name, '^'))
                        continue; /* a dereference item */
                if (!prefixcmp(ref->name, refspec->src)) {
-                       char *match;
+                       const char *match;
                        struct ref *cpy = copy_ref(ref);
                        match = ref->name + remote_prefix_len;
 
@@ -842,9 +851,9 @@ static struct ref *get_expanded_map(struct ref *remote_refs,
        return ret;
 }
 
-static struct ref *find_ref_by_name_abbrev(struct ref *refs, const char *name)
+static const struct ref *find_ref_by_name_abbrev(const struct ref *refs, const char *name)
 {
-       struct ref *ref;
+       const struct ref *ref;
        for (ref = refs; ref; ref = ref->next) {
                if (ref_matches_abbrev(name, ref->name))
                        return ref;
@@ -852,9 +861,9 @@ static struct ref *find_ref_by_name_abbrev(struct ref *refs, const char *name)
        return NULL;
 }
 
-struct ref *get_remote_ref(struct ref *remote_refs, const char *name)
+struct ref *get_remote_ref(const struct ref *remote_refs, const char *name)
 {
-       struct ref *ref = find_ref_by_name_abbrev(remote_refs, name);
+       const struct ref *ref = find_ref_by_name_abbrev(remote_refs, name);
 
        if (!ref)
                return NULL;
@@ -887,7 +896,7 @@ static struct ref *get_local_ref(const char *name)
        return ret;
 }
 
-int get_fetch_map(struct ref *remote_refs,
+int get_fetch_map(const struct ref *remote_refs,
                  const struct refspec *refspec,
                  struct ref ***tail,
                  int missing_ok)
index 878b4ecc32a2a4b5be4e0444ae4510e1a7ab01cb..b10036cae6f89e087da56979e2248e1e5c5d42d3 100644 (file)
--- a/remote.h
+++ b/remote.h
@@ -44,6 +44,10 @@ struct refspec {
 
 struct ref *alloc_ref(unsigned namelen);
 
+struct ref *copy_ref_list(const struct ref *ref);
+
+int check_ref_type(const struct ref *ref, int flags);
+
 /*
  * Frees the entire list and peers of elements.
  */
@@ -57,7 +61,7 @@ void ref_remove_duplicates(struct ref *ref_map);
 struct refspec *parse_ref_spec(int nr_refspec, const char **refspec);
 
 int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
-              int nr_refspec, char **refspec, int all);
+              int nr_refspec, const char **refspec, int all);
 
 /*
  * Given a list of the remote refs and the specification of things to
@@ -71,10 +75,10 @@ int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
  * missing_ok is usually false, but when we are adding branch.$name.merge
  * it is Ok if the branch is not at the remote anymore.
  */
-int get_fetch_map(struct ref *remote_refs, const struct refspec *refspec,
+int get_fetch_map(const struct ref *remote_refs, const struct refspec *refspec,
                  struct ref ***tail, int missing_ok);
 
-struct ref *get_remote_ref(struct ref *remote_refs, const char *name);
+struct ref *get_remote_ref(const struct ref *remote_refs, const char *name);
 
 /*
  * For the given remote, reads the refspec's src and sets the other fields.
@@ -98,4 +102,11 @@ struct branch *branch_get(const char *name);
 int branch_has_merge_config(struct branch *branch);
 int branch_merge_matches(struct branch *, int n, const char *);
 
+/* Flags to match_refs. */
+enum match_refs_flags {
+       MATCH_REFS_NONE         = 0,
+       MATCH_REFS_ALL          = (1 << 0),
+       MATCH_REFS_MIRROR       = (1 << 1),
+};
+
 #endif
diff --git a/send-pack.c b/send-pack.c
deleted file mode 100644 (file)
index b74fd45..0000000
+++ /dev/null
@@ -1,461 +0,0 @@
-#include "cache.h"
-#include "commit.h"
-#include "tag.h"
-#include "refs.h"
-#include "pkt-line.h"
-#include "run-command.h"
-#include "remote.h"
-
-static const char send_pack_usage[] =
-"git-send-pack [--all] [--dry-run] [--force] [--receive-pack=<git-receive-pack>] [--verbose] [--thin] [<host>:]<directory> [<ref>...]\n"
-"  --all and explicit <ref> specification are mutually exclusive.";
-static const char *receivepack = "git-receive-pack";
-static int verbose;
-static int send_all;
-static int force_update;
-static int use_thin_pack;
-static int dry_run;
-
-/*
- * Make a pack stream and spit it out into file descriptor fd
- */
-static int pack_objects(int fd, struct ref *refs)
-{
-       /*
-        * The child becomes pack-objects --revs; we feed
-        * the revision parameters to it via its stdin and
-        * let its stdout go back to the other end.
-        */
-       const char *args[] = {
-               "pack-objects",
-               "--all-progress",
-               "--revs",
-               "--stdout",
-               NULL,
-               NULL,
-       };
-       struct child_process po;
-
-       if (use_thin_pack)
-               args[4] = "--thin";
-       memset(&po, 0, sizeof(po));
-       po.argv = args;
-       po.in = -1;
-       po.out = fd;
-       po.git_cmd = 1;
-       if (start_command(&po))
-               die("git-pack-objects failed (%s)", strerror(errno));
-
-       /*
-        * We feed the pack-objects we just spawned with revision
-        * parameters by writing to the pipe.
-        */
-       while (refs) {
-               char buf[42];
-
-               if (!is_null_sha1(refs->old_sha1) &&
-                   has_sha1_file(refs->old_sha1)) {
-                       memcpy(buf + 1, sha1_to_hex(refs->old_sha1), 40);
-                       buf[0] = '^';
-                       buf[41] = '\n';
-                       if (!write_or_whine(po.in, buf, 42,
-                                               "send-pack: send refs"))
-                               break;
-               }
-               if (!is_null_sha1(refs->new_sha1)) {
-                       memcpy(buf, sha1_to_hex(refs->new_sha1), 40);
-                       buf[40] = '\n';
-                       if (!write_or_whine(po.in, buf, 41,
-                                               "send-pack: send refs"))
-                               break;
-               }
-               refs = refs->next;
-       }
-
-       if (finish_command(&po))
-               return error("pack-objects died with strange error");
-       return 0;
-}
-
-static void unmark_and_free(struct commit_list *list, unsigned int mark)
-{
-       while (list) {
-               struct commit_list *temp = list;
-               temp->item->object.flags &= ~mark;
-               list = temp->next;
-               free(temp);
-       }
-}
-
-static int ref_newer(const unsigned char *new_sha1,
-                    const unsigned char *old_sha1)
-{
-       struct object *o;
-       struct commit *old, *new;
-       struct commit_list *list, *used;
-       int found = 0;
-
-       /* Both new and old must be commit-ish and new is descendant of
-        * old.  Otherwise we require --force.
-        */
-       o = deref_tag(parse_object(old_sha1), NULL, 0);
-       if (!o || o->type != OBJ_COMMIT)
-               return 0;
-       old = (struct commit *) o;
-
-       o = deref_tag(parse_object(new_sha1), NULL, 0);
-       if (!o || o->type != OBJ_COMMIT)
-               return 0;
-       new = (struct commit *) o;
-
-       if (parse_commit(new) < 0)
-               return 0;
-
-       used = list = NULL;
-       commit_list_insert(new, &list);
-       while (list) {
-               new = pop_most_recent_commit(&list, 1);
-               commit_list_insert(new, &used);
-               if (new == old) {
-                       found = 1;
-                       break;
-               }
-       }
-       unmark_and_free(list, 1);
-       unmark_and_free(used, 1);
-       return found;
-}
-
-static struct ref *local_refs, **local_tail;
-static struct ref *remote_refs, **remote_tail;
-
-static int one_local_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data)
-{
-       struct ref *ref;
-       int len = strlen(refname) + 1;
-       ref = xcalloc(1, sizeof(*ref) + len);
-       hashcpy(ref->new_sha1, sha1);
-       memcpy(ref->name, refname, len);
-       *local_tail = ref;
-       local_tail = &ref->next;
-       return 0;
-}
-
-static void get_local_heads(void)
-{
-       local_tail = &local_refs;
-       for_each_ref(one_local_ref, NULL);
-}
-
-static int receive_status(int in)
-{
-       char line[1000];
-       int ret = 0;
-       int len = packet_read_line(in, line, sizeof(line));
-       if (len < 10 || memcmp(line, "unpack ", 7)) {
-               fprintf(stderr, "did not receive status back\n");
-               return -1;
-       }
-       if (memcmp(line, "unpack ok\n", 10)) {
-               fputs(line, stderr);
-               ret = -1;
-       }
-       while (1) {
-               len = packet_read_line(in, line, sizeof(line));
-               if (!len)
-                       break;
-               if (len < 3 ||
-                   (memcmp(line, "ok", 2) && memcmp(line, "ng", 2))) {
-                       fprintf(stderr, "protocol error: %s\n", line);
-                       ret = -1;
-                       break;
-               }
-               if (!memcmp(line, "ok", 2))
-                       continue;
-               fputs(line, stderr);
-               ret = -1;
-       }
-       return ret;
-}
-
-static void update_tracking_ref(struct remote *remote, struct ref *ref)
-{
-       struct refspec rs;
-       int will_delete_ref;
-
-       rs.src = ref->name;
-       rs.dst = NULL;
-
-       if (!ref->peer_ref)
-               return;
-
-       will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
-
-       if (!will_delete_ref &&
-                       !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1))
-               return;
-
-       if (!remote_find_tracking(remote, &rs)) {
-               fprintf(stderr, "updating local tracking ref '%s'\n", rs.dst);
-               if (is_null_sha1(ref->peer_ref->new_sha1)) {
-                       if (delete_ref(rs.dst, NULL))
-                               error("Failed to delete");
-               } else
-                       update_ref("update by push", rs.dst,
-                                       ref->new_sha1, NULL, 0, 0);
-               free(rs.dst);
-       }
-}
-
-static int send_pack(int in, int out, struct remote *remote, int nr_refspec, char **refspec)
-{
-       struct ref *ref;
-       int new_refs;
-       int ret = 0;
-       int ask_for_status_report = 0;
-       int allow_deleting_refs = 0;
-       int expect_status_report = 0;
-
-       /* No funny business with the matcher */
-       remote_tail = get_remote_heads(in, &remote_refs, 0, NULL, REF_NORMAL);
-       get_local_heads();
-
-       /* Does the other end support the reporting? */
-       if (server_supports("report-status"))
-               ask_for_status_report = 1;
-       if (server_supports("delete-refs"))
-               allow_deleting_refs = 1;
-
-       /* match them up */
-       if (!remote_tail)
-               remote_tail = &remote_refs;
-       if (match_refs(local_refs, remote_refs, &remote_tail,
-                      nr_refspec, refspec, send_all))
-               return -1;
-
-       if (!remote_refs) {
-               fprintf(stderr, "No refs in common and none specified; doing nothing.\n"
-                       "Perhaps you should specify a branch such as 'master'.\n");
-               return 0;
-       }
-
-       /*
-        * Finally, tell the other end!
-        */
-       new_refs = 0;
-       for (ref = remote_refs; ref; ref = ref->next) {
-               char old_hex[60], *new_hex;
-               int will_delete_ref;
-
-               if (!ref->peer_ref)
-                       continue;
-
-
-               will_delete_ref = is_null_sha1(ref->peer_ref->new_sha1);
-               if (will_delete_ref && !allow_deleting_refs) {
-                       error("remote does not support deleting refs");
-                       ret = -2;
-                       continue;
-               }
-               if (!will_delete_ref &&
-                   !hashcmp(ref->old_sha1, ref->peer_ref->new_sha1)) {
-                       if (verbose)
-                               fprintf(stderr, "'%s': up-to-date\n", ref->name);
-                       continue;
-               }
-
-               /* This part determines what can overwrite what.
-                * The rules are:
-                *
-                * (0) you can always use --force or +A:B notation to
-                *     selectively force individual ref pairs.
-                *
-                * (1) if the old thing does not exist, it is OK.
-                *
-                * (2) if you do not have the old thing, you are not allowed
-                *     to overwrite it; you would not know what you are losing
-                *     otherwise.
-                *
-                * (3) if both new and old are commit-ish, and new is a
-                *     descendant of old, it is OK.
-                *
-                * (4) regardless of all of the above, removing :B is
-                *     always allowed.
-                */
-
-               if (!force_update &&
-                   !will_delete_ref &&
-                   !is_null_sha1(ref->old_sha1) &&
-                   !ref->force) {
-                       if (!has_sha1_file(ref->old_sha1) ||
-                           !ref_newer(ref->peer_ref->new_sha1,
-                                      ref->old_sha1)) {
-                               /* We do not have the remote ref, or
-                                * we know that the remote ref is not
-                                * an ancestor of what we are trying to
-                                * push.  Either way this can be losing
-                                * commits at the remote end and likely
-                                * we were not up to date to begin with.
-                                */
-                               error("remote '%s' is not an ancestor of\n"
-                                     " local  '%s'.\n"
-                                     " Maybe you are not up-to-date and "
-                                     "need to pull first?",
-                                     ref->name,
-                                     ref->peer_ref->name);
-                               ret = -2;
-                               continue;
-                       }
-               }
-               hashcpy(ref->new_sha1, ref->peer_ref->new_sha1);
-               if (!will_delete_ref)
-                       new_refs++;
-               strcpy(old_hex, sha1_to_hex(ref->old_sha1));
-               new_hex = sha1_to_hex(ref->new_sha1);
-
-               if (!dry_run) {
-                       if (ask_for_status_report) {
-                               packet_write(out, "%s %s %s%c%s",
-                                       old_hex, new_hex, ref->name, 0,
-                                       "report-status");
-                               ask_for_status_report = 0;
-                               expect_status_report = 1;
-                       }
-                       else
-                               packet_write(out, "%s %s %s",
-                                       old_hex, new_hex, ref->name);
-               }
-               if (will_delete_ref)
-                       fprintf(stderr, "deleting '%s'\n", ref->name);
-               else {
-                       fprintf(stderr, "updating '%s'", ref->name);
-                       if (strcmp(ref->name, ref->peer_ref->name))
-                               fprintf(stderr, " using '%s'",
-                                       ref->peer_ref->name);
-                       fprintf(stderr, "\n  from %s\n  to   %s\n",
-                               old_hex, new_hex);
-               }
-       }
-
-       packet_flush(out);
-       if (new_refs && !dry_run)
-               ret = pack_objects(out, remote_refs);
-       close(out);
-
-       if (expect_status_report) {
-               if (receive_status(in))
-                       ret = -4;
-       }
-
-       if (!dry_run && remote && ret == 0) {
-               for (ref = remote_refs; ref; ref = ref->next)
-                       update_tracking_ref(remote, ref);
-       }
-
-       if (!new_refs && ret == 0)
-               fprintf(stderr, "Everything up-to-date\n");
-       return ret;
-}
-
-static void verify_remote_names(int nr_heads, char **heads)
-{
-       int i;
-
-       for (i = 0; i < nr_heads; i++) {
-               const char *remote = strchr(heads[i], ':');
-
-               remote = remote ? (remote + 1) : heads[i];
-               switch (check_ref_format(remote)) {
-               case 0: /* ok */
-               case -2: /* ok but a single level -- that is fine for
-                         * a match pattern.
-                         */
-               case -3: /* ok but ends with a pattern-match character */
-                       continue;
-               }
-               die("remote part of refspec is not a valid name in %s",
-                   heads[i]);
-       }
-}
-
-int main(int argc, char **argv)
-{
-       int i, nr_heads = 0;
-       char *dest = NULL;
-       char **heads = NULL;
-       int fd[2], ret;
-       struct child_process *conn;
-       char *remote_name = NULL;
-       struct remote *remote = NULL;
-
-       setup_git_directory();
-       git_config(git_default_config);
-
-       argv++;
-       for (i = 1; i < argc; i++, argv++) {
-               char *arg = *argv;
-
-               if (*arg == '-') {
-                       if (!prefixcmp(arg, "--receive-pack=")) {
-                               receivepack = arg + 15;
-                               continue;
-                       }
-                       if (!prefixcmp(arg, "--exec=")) {
-                               receivepack = arg + 7;
-                               continue;
-                       }
-                       if (!prefixcmp(arg, "--remote=")) {
-                               remote_name = arg + 9;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--all")) {
-                               send_all = 1;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--dry-run")) {
-                               dry_run = 1;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--force")) {
-                               force_update = 1;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--verbose")) {
-                               verbose = 1;
-                               continue;
-                       }
-                       if (!strcmp(arg, "--thin")) {
-                               use_thin_pack = 1;
-                               continue;
-                       }
-                       usage(send_pack_usage);
-               }
-               if (!dest) {
-                       dest = arg;
-                       continue;
-               }
-               heads = argv;
-               nr_heads = argc - i;
-               break;
-       }
-       if (!dest)
-               usage(send_pack_usage);
-       if (heads && send_all)
-               usage(send_pack_usage);
-       verify_remote_names(nr_heads, heads);
-
-       if (remote_name) {
-               remote = remote_get(remote_name);
-               if (!remote_has_url(remote, dest)) {
-                       die("Destination %s is not a uri for %s",
-                           dest, remote_name);
-               }
-       }
-
-       conn = git_connect(fd, dest, receivepack, verbose ? CONNECT_VERBOSE : 0);
-       ret = send_pack(fd[0], fd[1], remote, nr_heads, heads);
-       close(fd[0]);
-       close(fd[1]);
-       ret |= finish_connect(conn);
-       return !!ret;
-}
diff --git a/send-pack.h b/send-pack.h
new file mode 100644 (file)
index 0000000..8ff1dc3
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef SEND_PACK_H
+#define SEND_PACK_H
+
+struct send_pack_args {
+       const char *receivepack;
+       unsigned verbose:1,
+               send_all:1,
+               send_mirror:1,
+               force_update:1,
+               use_thin_pack:1,
+               dry_run:1;
+};
+
+int send_pack(struct send_pack_args *args,
+             const char *dest, struct remote *remote,
+             int nr_heads, const char **heads);
+
+#endif
index 0d1312ca56d52daa3fc692984d4d3abaf3425791..a051e49a9ea2f605bdc278394de731ff4c55e627 100644 (file)
@@ -35,7 +35,7 @@ static int update_info_refs(int force)
        safe_create_leading_directories(path0);
        info_ref_fp = fopen(path1, "w");
        if (!info_ref_fp)
-               return error("unable to update %s", path0);
+               return error("unable to update %s", path1);
        for_each_ref(add_info_ref, NULL);
        fclose(info_ref_fp);
        adjust_shared_perm(path1);
diff --git a/setup.c b/setup.c
index 43cd3f94ea31a7a2a8f8a07cbb67598bb1e52c39..2c7b5cb200414a0fa3f2727c68ea60e51b39c261 100644 (file)
--- a/setup.c
+++ b/setup.c
@@ -59,7 +59,7 @@ const char *prefix_path(const char *prefix, int len, const char *path)
 const char *prefix_filename(const char *pfx, int pfx_len, const char *arg)
 {
        static char path[PATH_MAX];
-       if (!pfx || !*pfx || arg[0] == '/')
+       if (!pfx || !*pfx || is_absolute_path(arg))
                return arg;
        memcpy(path, pfx, pfx_len);
        strcpy(path + pfx_len, arg);
index f007874cbb034ec9efa7f73c42831e0037d452fa..b0c24356ae7358561300c9bb3a3f56ba502b2a3b 100644 (file)
 
 #ifdef NO_C99_FORMAT
 #define SZ_FMT "lu"
+static unsigned long sz_fmt(size_t s) { return (unsigned long)s; }
 #else
 #define SZ_FMT "zu"
+static size_t sz_fmt(size_t s) { return s; }
 #endif
 
 const unsigned char null_sha1[20];
@@ -86,7 +88,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 +255,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 +264,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 +335,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 {
@@ -423,9 +425,9 @@ void pack_report(void)
                "pack_report: getpagesize()            = %10" SZ_FMT "\n"
                "pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
                "pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
-               (size_t) getpagesize(),
-               packed_git_window_size,
-               packed_git_limit);
+               sz_fmt(getpagesize()),
+               sz_fmt(packed_git_window_size),
+               sz_fmt(packed_git_limit));
        fprintf(stderr,
                "pack_report: pack_used_ctr            = %10u\n"
                "pack_report: pack_mmap_calls          = %10u\n"
@@ -435,7 +437,7 @@ void pack_report(void)
                pack_used_ctr,
                pack_mmap_calls,
                pack_open_windows, peak_pack_open_windows,
-               pack_mapped, peak_pack_mapped);
+               sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped));
 }
 
 static int check_packed_git_idx(const char *path,  struct packed_git *p)
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
new file mode 100755 (executable)
index 0000000..9ef593f
--- /dev/null
@@ -0,0 +1,58 @@
+#!/bin/sh
+
+test_description='branch --contains <commit>'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       >file &&
+       git add file &&
+       test_tick &&
+       git commit -m initial &&
+       git branch side &&
+
+       echo 1 >file &&
+       test_tick &&
+       git commit -a -m "second on master" &&
+
+       git checkout side &&
+       echo 1 >file &&
+       test_tick &&
+       git commit -a -m "second on side" &&
+
+       git merge master
+
+'
+
+test_expect_success 'branch --contains=master' '
+
+       git branch --contains=master >actual &&
+       {
+               echo "  master" && echo "* side"
+       } >expect &&
+       diff -u expect actual
+
+'
+
+test_expect_success 'branch --contains master' '
+
+       git branch --contains master >actual &&
+       {
+               echo "  master" && echo "* side"
+       } >expect &&
+       diff -u expect actual
+
+'
+
+test_expect_success 'branch --contains=side' '
+
+       git branch --contains=side >actual &&
+       {
+               echo "* side"
+       } >expect &&
+       diff -u expect actual
+
+'
+
+test_done
index 2ee5a00ea794e31946ee3228bc66ecc8e7d3b38f..657f68104d52558668119234a0637ac2bca33c0a 100755 (executable)
@@ -36,7 +36,6 @@ test_expect_failure 'rebase with git am -3 (default)' '
 '
 
 test_expect_success 'rebase --skip with am -3' '
-       git reset --hard HEAD &&
        git rebase --skip
        '
 
@@ -57,7 +56,6 @@ 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
        '
 
index f1039d1a2146ed68217d849d7588d9ca65af785b..907c7f9f6bccb0ddcf4d9862467a938369a07519 100755 (executable)
@@ -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/git-rebase-todo | wc -l)
+       test 0 = $(grep -ve "^#" -e "^$" < .git/.dotest-merge/git-rebase-todo |
+               wc -l)
 '
 
 test_expect_success 'abort' '
index 245fb3babddfeaeb361d9822780915460dfe1bab..73da45f18c2c5a58828c56c561e27012aa901a9a 100755 (executable)
@@ -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}" \
index 7d92ae3e996b31f8fa9e0b62f40a04ec1940cf70..c44b27aeb24816a346f0aa84d70546a0ffd83b2a 100755 (executable)
@@ -16,7 +16,7 @@ cat path0 >path1
 chmod +x path1
 
 test_expect_success \
-    'update-cache --add two files with and without +x.' \
+    'update-index --add two files with and without +x.' \
     'git update-index --add path0 path1'
 
 mv path0 path0-
index 063e79257a6e96d9021fa41d18a632560a272776..2fe50bc7ce050f32affa287c5c6e3ab7b1a66f45 100755 (executable)
@@ -27,7 +27,7 @@ Line 15
 '
 
 test_expect_success \
-    'update-cache --add a file.' \
+    'update-index --add a file.' \
     'git update-index --add path0'
 
 test_expect_success \
index 5836e3a899d62c3c86482ea254eb53c015a52823..1287d2ad175fffe342386eaf1c04bc8d26fd72f4 100755 (executable)
@@ -119,7 +119,7 @@ test_expect_success \
     'compare_diff_raw expected current'
 
 test_expect_success \
-    'run diff with -B' \
+    'run diff with -B -M' \
     'git diff-index -B -M "$tree" >current'
 
 # This should not mistake file0 as the copy source of new file1
old mode 100644 (file)
new mode 100755 (executable)
diff --git a/t/t4022-diff-rewrite.sh b/t/t4022-diff-rewrite.sh
new file mode 100755 (executable)
index 0000000..6de4acb
--- /dev/null
@@ -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
+
index de587517f434d3801d5e0aad94d4e084cbdd5b06..90ab54f0f586c87ace077be87fba396c8f2781a0 100644 (file)
@@ -90,7 +90,7 @@ diff --git a/Documentation/git.txt b/Documentation/git.txt
 diff --git a/Makefile b/Makefile
 --- a/Makefile
 +++ b/Makefile
-@@ -30,7 +30,7 @@ PROG=   git-update-cache git-diff-files 
+@@ -30,7 +30,7 @@ PROG=   git-update-index git-diff-files
        git-checkout-cache git-diff-tree git-rev-tree git-ls-files \
        git-check-files git-ls-tree git-merge-base git-merge-cache \
        git-unpack-file git-export git-diff-cache git-convert-cache \
index cfdc80885b30a8b9b184004072886adc1f88457a..f5c7d601fc955b15d15012a5b49df83364b6ebf4 100644 (file)
@@ -9,7 +9,7 @@ diff --git a/Makefile b/Makefile
 -      git-deltafy-script
 +      git-deltafy-script git-fetch-script
  
- PROG=   git-update-cache git-diff-files git-init-db git-write-tree \
+ PROG=   git-update-index git-diff-files git-init-db git-write-tree \
        git-read-tree git-commit-tree git-cat-file git-fsck-cache \
 diff --git a/git-pull-script b/git-fetch-script
 similarity index 87%
index de11623d1babf50952e45b46015ae45bb07ac2bf..5f6ddc105950eac20bcacb7987fabff015320ee3 100644 (file)
@@ -200,7 +200,7 @@ diff a/Documentation/git.txt b/Documentation/git.txt
 diff a/Makefile b/Makefile
 --- a/Makefile
 +++ b/Makefile
-@@ -30,7 +30,7 @@ PROG=   git-update-cache git-diff-files 
+@@ -30,7 +30,7 @@ PROG=   git-update-index git-diff-files
        git-checkout-cache git-diff-tree git-rev-tree git-ls-files \
        git-check-files git-ls-tree git-merge-base git-merge-cache \
        git-unpack-file git-export git-diff-cache git-convert-cache \
index d9753637fc23822795bca72c26b71d0ba71e6552..a72729a712038dc64f55d154eb9a94713e3269c9 100644 (file)
@@ -8,7 +8,7 @@ diff a/Makefile b/Makefile
 -      git-deltafy-script
 +      git-deltafy-script git-fetch-script
  
- PROG=   git-update-cache git-diff-files git-init-db git-write-tree \
+ PROG=   git-update-index git-diff-files git-init-db git-write-tree \
        git-read-tree git-commit-tree git-cat-file git-fsck-cache \
 diff a/git-fetch-script b/git-fetch-script
 --- /dev/null
index 65571e05496eb3710cb89d93f5b95d34b77d1998..b540f7295a1bb48bf044d297201b07aca9fb5005 100755 (executable)
@@ -24,7 +24,7 @@ cat >gpatch.file <<\EOF &&
 +++ file1+     2007-02-21 01:07:44.000000000 -0800
 @@ -1 +1 @@
 -A
-+B
++B 
 EOF
 
 sed -e 's|file1|sub/&|' gpatch.file >gpatch-sub.file &&
index ba7579c2510fc4a4d2de4d79037640b5df644bd6..f1106e65422823288f25add874d366afa5ea99f1 100755 (executable)
@@ -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' \
index 4f58c4c3f93b1629a564f8b23ad672100d64798d..2a2878b57229016ad473ccfd65ff7f609ba7d966 100755 (executable)
@@ -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/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh
new file mode 100755 (executable)
index 0000000..1493a92
--- /dev/null
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+test_description='tracking branch update checks for git push'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       echo 1 >file &&
+       git add file &&
+       git commit -m 1 &&
+       git branch b1 &&
+       git branch b2 &&
+       git clone . aa &&
+       git checkout b1 &&
+       echo b1 >>file &&
+       git commit -a -m b1 &&
+       git checkout b2 &&
+       echo b2 >>file &&
+       git commit -a -m b2
+'
+
+test_expect_success 'prepare pushable branches' '
+       cd aa &&
+       b1=$(git rev-parse origin/b1) &&
+       b2=$(git rev-parse origin/b2) &&
+       git checkout -b b1 origin/b1 &&
+       echo aa-b1 >>file &&
+       git commit -a -m aa-b1 &&
+       git checkout -b b2 origin/b2 &&
+       echo aa-b2 >>file &&
+       git commit -a -m aa-b2 &&
+       git checkout master &&
+       echo aa-master >>file &&
+       git commit -a -m aa-master
+'
+
+test_expect_success 'mixed-success push returns error' '! git push'
+
+test_expect_success 'check tracking branches updated correctly after push' '
+       test "$(git rev-parse origin/master)" = "$(git rev-parse master)"
+'
+
+test_expect_success 'check tracking branches not updated for failed refs' '
+       test "$(git rev-parse origin/b1)" = "$b1" &&
+       test "$(git rev-parse origin/b2)" = "$b2"
+'
+
+test_expect_success 'deleted branches have their tracking branches removed' '
+       git push origin :b1 &&
+       test "$(git rev-parse origin/b1)" = "origin/b1"
+'
+
+test_done
diff --git a/t/t5405-send-pack-rewind.sh b/t/t5405-send-pack-rewind.sh
new file mode 100755 (executable)
index 0000000..86abc62
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+test_description='forced push to replace commit we do not have'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       >file1 && git add file1 && test_tick &&
+       git commit -m Initial &&
+
+       mkdir another && (
+               cd another &&
+               git init &&
+               git fetch .. master:master
+       ) &&
+
+       >file2 && git add file2 && test_tick &&
+       git commit -m Second
+
+'
+
+test_expect_success 'non forced push should die not segfault' '
+
+       (
+               cd another &&
+               git push .. master:master
+               test $? = 1
+       )
+
+'
+
+test_expect_success 'forced push should succeed' '
+
+       (
+               cd another &&
+               git push .. +master:master
+       )
+
+'
+
+test_done
diff --git a/t/t5406-remote-rejects.sh b/t/t5406-remote-rejects.sh
new file mode 100755 (executable)
index 0000000..46b2cb4
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+test_description='remote push rejects are reported by client'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+       mkdir .git/hooks &&
+       (echo "#!/bin/sh" ; echo "exit 1") >.git/hooks/update &&
+       chmod +x .git/hooks/update &&
+       echo 1 >file &&
+       git add file &&
+       git commit -m 1 &&
+       git clone . child &&
+       cd child &&
+       echo 2 >file &&
+       git commit -a -m 2
+'
+
+test_expect_success 'push reports error' '! git push 2>stderr'
+
+test_expect_success 'individual ref reports error' 'grep rejected stderr'
+
+test_done
index aad863db7ad74ed217b3bcc76de43556f9fe7a07..35889c0a125fffdfb556ec521d61c18ac4e96c17 100755 (executable)
@@ -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/t5512-ls-remote.sh b/t/t5512-ls-remote.sh
new file mode 100755 (executable)
index 0000000..6ec5f7c
--- /dev/null
@@ -0,0 +1,52 @@
+#!/bin/sh
+
+test_description='git ls-remote'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+
+       >file &&
+       git add file &&
+       test_tick &&
+       git commit -m initial &&
+       git tag mark &&
+       git show-ref --tags -d | sed -e "s/ /   /" >expected.tag &&
+       (
+               echo "$(git rev-parse HEAD)     HEAD"
+               git show-ref -d | sed -e "s/ /  /"
+       ) >expected.all &&
+
+       git remote add self $(pwd)/.git
+
+'
+
+test_expect_success 'ls-remote --tags .git' '
+
+       git ls-remote --tags .git >actual &&
+       diff -u expected.tag actual
+
+'
+
+test_expect_success 'ls-remote .git' '
+
+       git ls-remote .git >actual &&
+       diff -u expected.all actual
+
+'
+
+test_expect_success 'ls-remote --tags self' '
+
+       git ls-remote --tags self >actual &&
+       diff -u expected.tag actual
+
+'
+
+test_expect_success 'ls-remote self' '
+
+       git ls-remote self >actual &&
+       diff -u expected.all actual
+
+'
+
+test_done
index 86f9b5346a0d7d8807d8c37c063690540873813a..987c9d21caf2a3d7653157f5e6d74f0841863c8b 100755 (executable)
@@ -247,9 +247,8 @@ test_expect_success 'push with colon-less refspec (4)' '
 test_expect_success 'push with dry-run' '
 
        mk_test heads/master &&
-       cd testrepo &&
-       old_commit=$(git show-ref -s --verify refs/heads/master) &&
-       cd .. &&
+       (cd testrepo &&
+        old_commit=$(git show-ref -s --verify refs/heads/master)) &&
        git push --dry-run testrepo &&
        check_push_result $old_commit heads/master
 '
@@ -257,28 +256,40 @@ test_expect_success 'push with dry-run' '
 test_expect_success 'push updates local refs' '
 
        rm -rf parent child &&
-       mkdir parent && cd parent && git init &&
-               echo one >foo && git add foo && git commit -m one &&
-       cd .. &&
-       git clone parent child && cd child &&
+       mkdir parent &&
+       (cd parent && git init &&
+               echo one >foo && git add foo && git commit -m one) &&
+       git clone parent child &&
+       (cd child &&
                echo two >foo && git commit -a -m two &&
                git push &&
-       test $(git rev-parse master) = $(git rev-parse remotes/origin/master)
+       test $(git rev-parse master) = $(git rev-parse remotes/origin/master))
 
 '
 
 test_expect_success 'push does not update local refs on failure' '
 
        rm -rf parent child &&
-       mkdir parent && cd parent && git init &&
+       mkdir parent &&
+       (cd parent && git init &&
                echo one >foo && git add foo && git commit -m one &&
                echo exit 1 >.git/hooks/pre-receive &&
-               chmod +x .git/hooks/pre-receive &&
-       cd .. &&
-       git clone parent child && cd child &&
-               echo two >foo && git commit -a -m two || exit 1
-               git push && exit 1
-       test $(git rev-parse master) != $(git rev-parse remotes/origin/master)
+               chmod +x .git/hooks/pre-receive) &&
+       git clone parent child &&
+       (cd child &&
+               echo two >foo && git commit -a -m two &&
+               ! git push &&
+               test $(git rev-parse master) != \
+                       $(git rev-parse remotes/origin/master))
+
+'
+
+test_expect_success 'allow deleting an invalid remote ref' '
+
+       pwd &&
+       rm -f testrepo/.git/objects/??/* &&
+       git push testrepo :refs/heads/master &&
+       (cd testrepo && ! git rev-parse --verify refs/heads/master)
 
 '
 
diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh
new file mode 100755 (executable)
index 0000000..ed3fec1
--- /dev/null
@@ -0,0 +1,228 @@
+#!/bin/sh
+
+test_description='pushing to a mirror repository'
+
+. ./test-lib.sh
+
+D=`pwd`
+
+invert () {
+       if "$@"; then
+               return 1
+       else
+               return 0
+       fi
+}
+
+mk_repo_pair () {
+       rm -rf master mirror &&
+       mkdir mirror &&
+       (
+               cd mirror &&
+               git init
+       ) &&
+       mkdir master &&
+       (
+               cd master &&
+               git init &&
+               git config remote.up.url ../mirror
+       )
+}
+
+
+# BRANCH tests
+test_expect_success 'push mirror creates new branches' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+       test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror updates existing branches' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git push --mirror up &&
+               echo two >foo && git add foo && git commit -m two &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+       test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror force updates existing branches' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git push --mirror up &&
+               echo two >foo && git add foo && git commit -m two &&
+               git push --mirror up &&
+               git reset --hard HEAD^
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+       test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror removes branches' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git branch remove master &&
+               git push --mirror up &&
+               git branch -D remove
+               git push --mirror up
+       ) &&
+       (
+               cd mirror &&
+               invert git show-ref -s --verify refs/heads/remove
+       )
+
+'
+
+test_expect_success 'push mirror adds, updates and removes branches together' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git branch remove master &&
+               git push --mirror up &&
+               git branch -D remove &&
+               git branch add master &&
+               echo two >foo && git add foo && git commit -m two &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/heads/master) &&
+       master_add=$(cd master && git show-ref -s --verify refs/heads/add) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/heads/master) &&
+       mirror_add=$(cd mirror && git show-ref -s --verify refs/heads/add) &&
+       test "$master_master" = "$mirror_master" &&
+       test "$master_add" = "$mirror_add" &&
+       (
+               cd mirror &&
+               invert git show-ref -s --verify refs/heads/remove
+       )
+
+'
+
+
+# TAG tests
+test_expect_success 'push mirror creates new tags' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git tag -f tmaster master &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+       test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror updates existing tags' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git tag -f tmaster master &&
+               git push --mirror up &&
+               echo two >foo && git add foo && git commit -m two &&
+               git tag -f tmaster master &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+       test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror force updates existing tags' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git tag -f tmaster master &&
+               git push --mirror up &&
+               echo two >foo && git add foo && git commit -m two &&
+               git tag -f tmaster master &&
+               git push --mirror up &&
+               git reset --hard HEAD^
+               git tag -f tmaster master &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+       test "$master_master" = "$mirror_master"
+
+'
+
+test_expect_success 'push mirror removes tags' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git tag -f tremove master &&
+               git push --mirror up &&
+               git tag -d tremove
+               git push --mirror up
+       ) &&
+       (
+               cd mirror &&
+               invert git show-ref -s --verify refs/tags/tremove
+       )
+
+'
+
+test_expect_success 'push mirror adds, updates and removes tags together' '
+
+       mk_repo_pair &&
+       (
+               cd master &&
+               echo one >foo && git add foo && git commit -m one &&
+               git tag -f tmaster master &&
+               git tag -f tremove master &&
+               git push --mirror up &&
+               git tag -d tremove &&
+               git tag tadd master &&
+               echo two >foo && git add foo && git commit -m two &&
+               git tag -f tmaster master &&
+               git push --mirror up
+       ) &&
+       master_master=$(cd master && git show-ref -s --verify refs/tags/tmaster) &&
+       master_add=$(cd master && git show-ref -s --verify refs/tags/tadd) &&
+       mirror_master=$(cd mirror && git show-ref -s --verify refs/tags/tmaster) &&
+       mirror_add=$(cd mirror && git show-ref -s --verify refs/tags/tadd) &&
+       test "$master_master" = "$mirror_master" &&
+       test "$master_add" = "$mirror_add" &&
+       (
+               cd mirror &&
+               invert git show-ref -s --verify refs/tags/tremove
+       )
+
+'
+
+test_done
index 53956c08e2754eb68a2a8311b26e16f5ee891308..2ba4b00e526eb00c5d236777f896772c6cad538b 100755 (executable)
@@ -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
 '
 
index 2089351f7d157ce96a07ed1c6c1465fc58819ec0..5f60b22d872b5d034e137e0c6c7c5a9d664e57ee 100755 (executable)
@@ -114,7 +114,7 @@ test_expect_success 'use index-filter to move into a subdirectory' '
 
 test_expect_success 'stops when msg filter fails' '
        old=$(git rev-parse HEAD) &&
-       ! git-filter-branch -f --msg-filter false &&
+       ! git-filter-branch -f --msg-filter false HEAD &&
        test $old = $(git rev-parse HEAD) &&
        rm -rf .git-rewrite
 '
index 5f7e388d7add06b8392997037a86c4d0f8524ceb..c7130c4dcc31dda1f70160c81804096676943af4 100755 (executable)
@@ -339,20 +339,14 @@ test_expect_success \
 '
 
 test_expect_success \
-       'trying to create tags giving many -m or -F options should fail' '
+       'trying to create tags giving both -m or -F options should fail' '
        echo "message file 1" >msgfile1 &&
        echo "message file 2" >msgfile2 &&
        ! tag_exists msgtag &&
-       ! git-tag -m "message 1" -m "message 2" msgtag &&
-       ! tag_exists msgtag &&
-       ! git-tag -F msgfile1 -F msgfile2 msgtag &&
-       ! tag_exists msgtag &&
        ! git-tag -m "message 1" -F msgfile1 msgtag &&
        ! tag_exists msgtag &&
        ! git-tag -F msgfile1 -m "message 1" msgtag &&
        ! tag_exists msgtag &&
-       ! git-tag -F msgfile1 -m "message 1" -F msgfile2 msgtag &&
-       ! tag_exists msgtag &&
        ! git-tag -m "message 1" -F msgfile1 -m "message 2" msgtag &&
        ! tag_exists msgtag
 '
@@ -673,6 +667,22 @@ test_expect_success 'creating a signed tag with -F - should succeed' '
        git diff expect actual
 '
 
+cat >fakeeditor <<'EOF'
+#!/bin/sh
+test -n "$1" && exec >"$1"
+echo A signed tag message
+echo from a fake editor.
+EOF
+chmod +x fakeeditor
+get_tag_header implied-annotate $commit commit $time >expect
+./fakeeditor >>expect
+echo '-----BEGIN PGP SIGNATURE-----' >>expect
+test_expect_success '-s implies annotated tag' '
+       GIT_EDITOR=./fakeeditor git-tag -s implied-annotate &&
+       get_tag_msg implied-annotate >actual &&
+       git diff expect actual
+'
+
 test_expect_success \
        'trying to create a signed tag with non-existing -F file should fail' '
        ! test -f nonexistingfile &&
old mode 100644 (file)
new mode 100755 (executable)
index 9dba104..31a6f63
@@ -79,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
 
@@ -98,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
 
index 83f94702025276ffea4400490630e64c9eef068b..659f9c758fd9abbae8aa657a4729059335dd92cd 100755 (executable)
@@ -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
index d59acc8d1ade041d01d5a45aa993b26919a0170c..745254665dd2d8f73b8c511b39aca82682bf1bbb 100755 (executable)
@@ -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/t9119-git-svn-info.sh b/t/t9119-git-svn-info.sh
new file mode 100755 (executable)
index 0000000..439bd93
--- /dev/null
@@ -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/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh
new file mode 100755 (executable)
index 0000000..29fee2d
--- /dev/null
@@ -0,0 +1,122 @@
+#!/bin/sh
+
+test_description='git-cvsimport basic tests'
+. ./test-lib.sh
+
+if ! ( type cvs && type cvsps ) >/dev/null 2>&1
+then
+       test_expect_success 'skipping cvsimport tests, cvs/cvsps not found' ''
+       test_done
+       exit
+fi
+
+CVSROOT=$(pwd)/cvsroot
+export CVSROOT
+# for clean cvsps cache
+HOME=$(pwd)
+export HOME
+
+test_expect_success 'setup cvsroot' 'cvs init'
+
+test_expect_success 'setup a cvs module' '
+
+       mkdir $CVSROOT/module &&
+       cvs co -d module-cvs module &&
+       cd module-cvs &&
+       cat <<EOF >o_fortuna &&
+O Fortuna
+velut luna
+statu variabilis,
+
+semper crescis
+aut decrescis;
+vita detestabilis
+
+nunc obdurat
+et tunc curat
+ludo mentis aciem,
+
+egestatem,
+potestatem
+dissolvit ut glaciem.
+EOF
+       cvs add o_fortuna &&
+       cat <<EOF >message &&
+add "O Fortuna" lyrics
+
+These public domain lyrics make an excellent sample text.
+EOF
+       cvs commit -F message &&
+       cd ..
+'
+
+test_expect_success 'import a trivial module' '
+
+       git cvsimport -a -z 0 -C module-git module &&
+       git diff module-cvs/o_fortuna module-git/o_fortuna
+
+'
+
+test_expect_success 'pack refs' 'cd module-git && git gc && cd ..'
+
+test_expect_success 'update cvs module' '
+
+       cd module-cvs &&
+       cat <<EOF >o_fortuna &&
+O Fortune,
+like the moon
+you are changeable,
+
+ever waxing
+and waning;
+hateful life
+
+first oppresses
+and then soothes
+as fancy takes it;
+
+poverty
+and power
+it melts them like ice.
+EOF
+       cat <<EOF >message &&
+translate to English
+
+My Latin is terrible.
+EOF
+       cvs commit -F message &&
+       cd ..
+'
+
+test_expect_success 'update git module' '
+
+       cd module-git &&
+       git cvsimport -a -z 0 module &&
+       git merge origin &&
+       cd .. &&
+       git diff module-cvs/o_fortuna module-git/o_fortuna
+
+'
+
+test_expect_success 'update cvs module' '
+
+       cd module-cvs &&
+               echo 1 >tick &&
+               cvs add tick &&
+               cvs commit -m 1
+       cd ..
+
+'
+
+test_expect_success 'cvsimport.module config works' '
+
+       cd module-git &&
+               git config cvsimport.module module &&
+               git cvsimport -a -z0 &&
+               git merge origin &&
+       cd .. &&
+       git diff module-cvs/tick module-git/tick
+
+'
+
+test_done
index a19279b3e41653b519b8c3b266bc7845f3648c4b..7092bae26342d273f28d52ac330c270a22067f65 100644 (file)
@@ -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/trace.c b/trace.c
index 0d89dbe7794dcdfb8519e6d083f74bf792976c6a..d3d1b6d55e86aab94ddb9712f5eee743b3bfa9a8 100644 (file)
--- a/trace.c
+++ b/trace.c
@@ -37,7 +37,7 @@ static int get_trace_fd(int *need_close)
                return STDERR_FILENO;
        if (strlen(trace) == 1 && isdigit(*trace))
                return atoi(trace);
-       if (*trace == '/') {
+       if (is_absolute_path(trace)) {
                int fd = open(trace, O_WRONLY | O_APPEND | O_CREAT, 0666);
                if (fd == -1) {
                        fprintf(stderr,
index e8a2608372de06ef3f77d9a450776e3095057c9f..50db9807d003162c81f391e08f247bac7ce410c9 100644 (file)
@@ -6,6 +6,7 @@
 #endif
 #include "pkt-line.h"
 #include "fetch-pack.h"
+#include "send-pack.h"
 #include "walker.h"
 #include "bundle.h"
 #include "dir.h"
@@ -141,7 +142,7 @@ static void insert_packed_refs(const char *packed_refs, struct ref **list)
        }
 }
 
-static struct ref *get_refs_via_rsync(const struct transport *transport)
+static struct ref *get_refs_via_rsync(struct transport *transport)
 {
        struct strbuf buf = STRBUF_INIT, temp_dir = STRBUF_INIT;
        struct ref dummy, *tail = &dummy;
@@ -283,6 +284,9 @@ static int rsync_transport_push(struct transport *transport,
        struct child_process rsync;
        const char *args[10];
 
+       if (flags & TRANSPORT_PUSH_MIRROR)
+               return error("rsync transport does not support mirror mode");
+
        /* first push the objects */
 
        strbuf_addstr(&buf, transport->url);
@@ -344,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)
 {
@@ -370,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)
 {
@@ -386,6 +392,9 @@ static int curl_transport_push(struct transport *transport, int refspec_nr, cons
        int argc;
        int err;
 
+       if (flags & TRANSPORT_PUSH_MIRROR)
+               return error("http transport does not support mirror mode");
+
        argv = xmalloc((refspec_nr + 12) * sizeof(char *));
        argv[0] = "http-push";
        argc = 1;
@@ -430,7 +439,7 @@ static int missing__target(int code, int result)
 
 #define missing_target(a) missing__target((a)->http_code, (a)->curl_result)
 
-static struct ref *get_refs_via_curl(const struct transport *transport)
+static struct ref *get_refs_via_curl(struct transport *transport)
 {
        struct buffer buffer;
        char *data, *start, *mid;
@@ -527,7 +536,7 @@ struct bundle_transport_data {
        struct bundle_header header;
 };
 
-static struct ref *get_refs_from_bundle(const struct transport *transport)
+static struct ref *get_refs_from_bundle(struct transport *transport)
 {
        struct bundle_transport_data *data = transport->data;
        struct ref *result = NULL;
@@ -599,7 +608,7 @@ static int set_git_option(struct transport *connection,
        return 1;
 }
 
-static struct ref *get_refs_via_connect(const struct transport *transport)
+static struct ref *get_refs_via_connect(struct transport *transport)
 {
        struct git_transport_data *data = transport->data;
        struct ref *refs;
@@ -652,50 +661,17 @@ static int fetch_refs_via_pack(struct transport *transport,
 static int git_transport_push(struct transport *transport, int refspec_nr, const char **refspec, int flags)
 {
        struct git_transport_data *data = transport->data;
-       const char **argv;
-       char *rem;
-       int argc;
-       int err;
+       struct send_pack_args args;
 
-       argv = xmalloc((refspec_nr + 12) * sizeof(char *));
-       argv[0] = "send-pack";
-       argc = 1;
-       if (flags & TRANSPORT_PUSH_ALL)
-               argv[argc++] = "--all";
-       if (flags & TRANSPORT_PUSH_FORCE)
-               argv[argc++] = "--force";
-       if (flags & TRANSPORT_PUSH_DRY_RUN)
-               argv[argc++] = "--dry-run";
-       if (flags & TRANSPORT_PUSH_VERBOSE)
-               argv[argc++] = "--verbose";
-       if (data->receivepack) {
-               char *rp = xmalloc(strlen(data->receivepack) + 16);
-               sprintf(rp, "--receive-pack=%s", data->receivepack);
-               argv[argc++] = rp;
-       }
-       if (data->thin)
-               argv[argc++] = "--thin";
-       rem = xmalloc(strlen(transport->remote->name) + 10);
-       sprintf(rem, "--remote=%s", transport->remote->name);
-       argv[argc++] = rem;
-       argv[argc++] = transport->url;
-       while (refspec_nr--)
-               argv[argc++] = *refspec++;
-       argv[argc] = NULL;
-       err = run_command_v_opt(argv, RUN_GIT_CMD);
-       switch (err) {
-       case -ERR_RUN_COMMAND_FORK:
-               error("unable to fork for %s", argv[0]);
-       case -ERR_RUN_COMMAND_EXEC:
-               error("unable to exec %s", argv[0]);
-               break;
-       case -ERR_RUN_COMMAND_WAITPID:
-       case -ERR_RUN_COMMAND_WAITPID_WRONG_PID:
-       case -ERR_RUN_COMMAND_WAITPID_SIGNAL:
-       case -ERR_RUN_COMMAND_WAITPID_NOEXIT:
-               error("%s died with strange error", argv[0]);
-       }
-       return !!err;
+       args.receivepack = data->receivepack;
+       args.send_all = !!(flags & TRANSPORT_PUSH_ALL);
+       args.send_mirror = !!(flags & TRANSPORT_PUSH_MIRROR);
+       args.force_update = !!(flags & TRANSPORT_PUSH_FORCE);
+       args.use_thin_pack = data->thin;
+       args.verbose = !!(flags & TRANSPORT_PUSH_VERBOSE);
+       args.dry_run = !!(flags & TRANSPORT_PUSH_DRY_RUN);
+
+       return send_pack(&args, transport->url, transport->remote, refspec_nr, refspec);
 }
 
 static int disconnect_git(struct transport *transport)
@@ -787,7 +763,7 @@ int transport_push(struct transport *transport,
        return transport->push(transport, refspec_nr, refspec, flags);
 }
 
-struct ref *transport_get_remote_refs(struct transport *transport)
+const struct ref *transport_get_remote_refs(struct transport *transport)
 {
        if (!transport->remote_refs)
                transport->remote_refs = transport->get_refs_list(transport);
index 2f80ab4b03df181dc8b041b1aace5832aa84deb1..6fb4526cda5fc1ee1178fdf1d0840c90b88aa26c 100644 (file)
@@ -8,7 +8,7 @@ struct transport {
        struct remote *remote;
        const char *url;
        void *data;
-       struct ref *remote_refs;
+       const struct ref *remote_refs;
 
        /**
         * Returns 0 if successful, positive if the option is not
@@ -18,7 +18,7 @@ struct transport {
        int (*set_option)(struct transport *connection, const char *name,
                          const char *value);
 
-       struct ref *(*get_refs_list)(const struct transport *transport);
+       struct ref *(*get_refs_list)(struct transport *transport);
        int (*fetch)(struct transport *transport, int refs_nr, struct ref **refs);
        int (*push)(struct transport *connection, int refspec_nr, const char **refspec, int flags);
 
@@ -30,7 +30,8 @@ struct transport {
 #define TRANSPORT_PUSH_ALL 1
 #define TRANSPORT_PUSH_FORCE 2
 #define TRANSPORT_PUSH_DRY_RUN 4
-#define TRANSPORT_PUSH_VERBOSE 8
+#define TRANSPORT_PUSH_MIRROR 8
+#define TRANSPORT_PUSH_VERBOSE 16
 
 /* Returns a transport suitable for the url */
 struct transport *transport_get(struct remote *, const char *);
@@ -62,7 +63,7 @@ int transport_set_option(struct transport *transport, const char *name,
 int transport_push(struct transport *connection,
                   int refspec_nr, const char **refspec, int flags);
 
-struct ref *transport_get_remote_refs(struct transport *transport);
+const struct ref *transport_get_remote_refs(struct transport *transport);
 
 int transport_fetch_refs(struct transport *transport, struct ref *refs);
 void transport_unlock_pack(struct transport *transport);
index aea16adde846b404900555f5f0dd6d87daea8bbf..e9eb795d64b9cd6a6940995d41dd9c3f3239df02 100644 (file)
@@ -71,12 +71,8 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
        int remove;
        int baselen = strlen(base);
        int src_size = len + 1;
-       int i_stk = i_stk;
        int retval = 0;
 
-       if (o->dir)
-               i_stk = push_exclude_per_directory(o->dir, base, strlen(base));
-
        do {
                int i;
                const char *first;
@@ -255,8 +251,6 @@ static int unpack_trees_rec(struct tree_entry_list **posns, int len,
        } while (1);
 
  leave_directory:
-       if (o->dir)
-               pop_exclude_per_directory(o->dir, i_stk);
        return retval;
 }