Merge branch 'work/steffen/shawn-git-gui' into devel

This commit is contained in:
Steffen Prohaska
2007-10-11 13:39:57 +02:00
50 changed files with 16106 additions and 822 deletions

4
git-gui/.gitignore vendored
View File

@@ -1,5 +1,7 @@
.DS_Store
Git Gui.app*
git-gui.tcl
GIT-VERSION-FILE
GIT-GUI-VARS
git-citool
git-gui
lib/tclIndex

View File

@@ -2,16 +2,21 @@ 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
@@ -31,22 +36,34 @@ ifndef INSTALL
INSTALL = install
endif
RM_RF ?= rm -rf
RMDIR ?= rmdir
INSTALL_D0 = $(INSTALL) -d -m755 # space is required here
INSTALL_D1 =
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 =
INSTALL_L3 =
REMOVE_D0 = $(RMDIR) # space is required here
REMOVE_D1 = || true
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=
@@ -55,19 +72,27 @@ 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=
INSTALL_L2 = && dst=
INSTALL_L3 = && echo ' ' 'LINK ' `basename "$$dst"` '->' `basename "$$src"` && rm -f "$$dst" && ln "$$src" "$$dst"
CLEAN_DST = echo ' ' UNINSTALL
REMOVE_D0 = dir=
REMOVE_D1 = && echo ' ' REMOVE $$dir && test -d "$$dir" && $(RMDIR) "$$dir" || true
REMOVE_F0 = 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
DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
@@ -75,35 +100,115 @@ 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)))
libdir ?= $(sharedir)/git-gui/lib
libdir_SQ = $(subst ','\'',$(libdir))
gg_libdir ?= $(sharedir)/git-gui/lib
libdir_SQ = $(subst ','\'',$(gg_libdir))
libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir)))
exedir = $(dir $(gitexecdir))share/git-gui/lib
exedir = $(dir $(gitexecdir))share/git-gui/lib
exedir_SQ = $(subst ','\'',$(exedir))
GITGUI_SCRIPT := $$0
GITGUI_RELATIVE :=
GITGUI_MACOSXAPP :=
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh
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 $@ $@+ && \
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 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
-e 's|@@GITGUI_RELATIVE@@|'$$GITGUI_RELATIVE'|' \
-e $$GITGUI_RELATIVE's|@@GITGUI_LIBDIR@@|$(libdir_SQ)|' \
$@.sh >$@+ && \
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 $@+ $@
$(GITGUI_BUILT_INS): git-gui
$(QUIET_BUILT_IN)rm -f $@ && ln git-gui $@
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
lib/tclIndex: $(ALL_LIBFILES)
ifdef GITGUI_WINDOWS_WRAPPER
GITGUI_MAIN := git-gui.tcl
git-gui: windows/git-gui.sh
cp $< $@
endif
$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-VARS
$(QUIET_GEN)rm -f $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-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_SED)|' \
git-gui.sh >$@+ && \
chmod +x $@+ && \
mv $@+ $@
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) GIT-GUI-VARS
$(QUIET_INDEX)if echo \
$(foreach p,$(PRELOAD_FILES),source $p\;) \
auto_mkindex lib '*.tcl' \
@@ -117,16 +222,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 ','\'',libdir='$(libdir_SQ)') \
$(subst ','\'',gg_libdir='$(libdir_SQ)') \
GITGUI_MACOSXAPP=$(GITGUI_MACOSXAPP) \
#end TRACK_VARS
GIT-GUI-VARS: .FORCE-GIT-GUI-VARS
@@ -136,24 +238,68 @@ 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)$(INSTALL_R0)lib/git-gui.ico $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)'
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), $(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)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.ico $(REMOVE_F1)
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), $(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)
dist-version:
@mkdir -p $(TARDIR)
@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 dist-version clean
.PHONY: all install uninstall dist-version clean
.PHONY: .FORCE-GIT-VERSION-FILE
.PHONY: .FORCE-GIT-GUI-VARS

209
git-gui/README Normal file
View File

@@ -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.

1704
git-gui/git-gui.pot Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -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) ; )

181
git-gui/glossary/de.po Normal file
View File

@@ -0,0 +1,181 @@
# 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-05 22:30+0200\n"
"PO-Revision-Date: 2007-10-05 22:32+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)"
#. ""
msgid "prune"
msgstr "löschen"
#. "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 "ausliefern (hochladen? verschicken? schieben?)"
#. ""
msgid "redo"
msgstr "wiederholen"
#. "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"

View File

@@ -0,0 +1,160 @@
# 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-05 22:30+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 ""
#. ""
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 ""
#. "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 ""

View File

@@ -0,0 +1,36 @@
"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" ""
"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" ""
"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."

View File

@@ -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

170
git-gui/glossary/zh_cn.po Normal file
View File

@@ -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 "工作副本,工作源码树"

81
git-gui/lib/about.tcl Normal file
View File

@@ -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
}

View 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
}

View 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

View 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
}

View 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

View 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
}

View 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
@@ -47,9 +47,7 @@ constructor new {commit {path {}}} {
-width 70 \
-xscrollcommand [list $w.list.sbx set] \
-yscrollcommand [list $w.list.sby set]
$w_list tag conf in_sel \
-background [$w_list cget -foreground] \
-foreground [$w_list cget -background]
rmsel_tag $w_list
scrollbar $w.list.sbx -orient h -command [list $w_list xview]
scrollbar $w.list.sby -orient v -command [list $w_list yview]
pack $w.list.sbx -side bottom -fill x
@@ -124,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]
}
}
@@ -141,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
}
@@ -185,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]
@@ -244,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} {
@@ -265,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

View 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
@@ -396,7 +396,7 @@ method _after_readtree {} {
set is_detached 0
}
} else {
if {$new_hash ne $HEAD} {
if {!$is_detached || $new_hash ne $HEAD} {
append log " to $new_expr"
if {[catch {
_detach_HEAD $log $new_hash
@@ -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
}

166
git-gui/lib/choose_font.tcl Normal file
View File

@@ -0,0 +1,166 @@
# git-gui font chooser
# Copyright (C) 2007 Shawn Pearce
class choose_font {
field w
field w_family ; # UI widget of all known family names
field w_example ; # Example to showcase the chosen font
field f_family ; # Currently chosen family name
field f_size ; # Currently chosen point size
field v_family ; # Name of global variable for family
field v_size ; # Name of global variable for size
variable all_families [list] ; # All fonts known to Tk
constructor pick {path title a_family a_size} {
variable all_families
set v_family $a_family
set v_size $a_size
upvar #0 $v_family pv_family
upvar #0 $v_size pv_size
set f_family $pv_family
set f_size $pv_size
make_toplevel top w
wm title $top "[appname] ([reponame]): $title"
wm geometry $top "+[winfo rootx $path]+[winfo rooty $path]"
label $w.header -text $title -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
button $w.buttons.select \
-text [mc Select] \
-default active \
-command [cb _select]
button $w.buttons.cancel \
-text [mc Cancel] \
-command [list destroy $w]
pack $w.buttons.select -side right
pack $w.buttons.cancel -side right -padx 5
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
frame $w.inner
frame $w.inner.family
label $w.inner.family.l \
-text [mc "Font Family"] \
-anchor w
set w_family $w.inner.family.v
text $w_family \
-background white \
-borderwidth 1 \
-relief sunken \
-cursor $::cursor_ptr \
-wrap none \
-width 30 \
-height 10 \
-yscrollcommand [list $w.inner.family.sby set]
rmsel_tag $w_family
scrollbar $w.inner.family.sby -command [list $w_family yview]
pack $w.inner.family.l -side top -fill x
pack $w.inner.family.sby -side right -fill y
pack $w_family -fill both -expand 1
frame $w.inner.size
label $w.inner.size.l \
-text [mc "Font Size"] \
-anchor w
spinbox $w.inner.size.v \
-textvariable @f_size \
-from 2 -to 80 -increment 1 \
-width 3
bind $w.inner.size.v <FocusIn> {%W selection range 0 end}
pack $w.inner.size.l -fill x -side top
pack $w.inner.size.v -fill x -padx 2
grid configure $w.inner.family $w.inner.size -sticky nsew
grid rowconfigure $w.inner 0 -weight 1
grid columnconfigure $w.inner 0 -weight 1
pack $w.inner -fill both -expand 1 -padx 5 -pady 5
frame $w.example
label $w.example.l \
-text [mc "Font Example"] \
-anchor w
set w_example $w.example.t
text $w_example \
-background white \
-borderwidth 1 \
-relief sunken \
-height 3 \
-width 40
rmsel_tag $w_example
$w_example tag conf example -justify center
$w_example insert end [mc "This is example text.\nIf you like this text, it can be your font."] example
$w_example conf -state disabled
pack $w.example.l -fill x
pack $w_example -fill x
pack $w.example -fill x -padx 5
if {$all_families eq {}} {
set all_families [lsort [font families]]
}
$w_family tag conf pick
$w_family tag bind pick <Button-1> [cb _pick_family %x %y]\;break
foreach f $all_families {
set sel [list pick]
if {$f eq $f_family} {
lappend sel in_sel
}
$w_family insert end "$f\n" $sel
}
$w_family conf -state disabled
_update $this
trace add variable @f_size write [cb _update]
bind $w <Key-Escape> [list destroy $w]
bind $w <Key-Return> [cb _select]\;break
bind $w <Visibility> "
grab $w
focus $w
"
tkwait window $w
}
method _select {} {
upvar #0 $v_family pv_family
upvar #0 $v_size pv_size
set pv_family $f_family
set pv_size $f_size
destroy $w
}
method _pick_family {x y} {
variable all_families
set i [lindex [split [$w_family index @$x,$y] .] 0]
set n [lindex $all_families [expr {$i - 1}]]
if {$n ne {}} {
$w_family tag remove in_sel 0.0 end
$w_family tag add in_sel $i.0 [expr {$i + 1}].0
set f_family $n
_update $this
}
}
method _update {args} {
variable all_families
set i [lsearch -exact $all_families $f_family]
if {$i < 0} return
$w_example tag conf example -font [list $f_family $f_size]
$w_family see [expr {$i + 1}].0
}
}

View File

@@ -0,0 +1,864 @@
# 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 o_cons ; # Console object (if active)
field w_types ; # List of type buttons in clone
field action new ; # What action are we going to perform?
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)
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
$w.mbar add cascade \
-label [mc Repository] \
-menu $w.mbar.repository
menu $w.mbar.repository
$w.mbar.repository add command \
-label [mc Quit] \
-command exit \
-accelerator $M1T-Q
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]
}
pack [git_logo $w.git_logo] -side left -fill y -padx 10 -pady 10
set w_body $w.body
frame $w_body
radiobutton $w_body.new \
-anchor w \
-text [mc "Create New Repository"] \
-variable @action \
-value new
radiobutton $w_body.clone \
-anchor w \
-text [mc "Clone Existing Repository"] \
-variable @action \
-value clone
radiobutton $w_body.open \
-anchor w \
-text [mc "Open Existing Repository"] \
-variable @action \
-value open
pack $w_body.new -anchor w -fill x
pack $w_body.clone -anchor w -fill x
pack $w_body.open -anchor w -fill x
pack $w_body -fill x -padx 10 -pady 10
frame $w.buttons
set w_next $w.buttons.next
button $w_next \
-default active \
-text [mc "Next >"] \
-command [cb _next]
pack $w_next -side right -padx 5
button $w.buttons.quit \
-text [mc "Quit"] \
-command exit
pack $w.buttons.quit -side right -padx 5
pack $w.buttons -side bottom -fill x -padx 10 -pady 10
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]
}
}
method _next {} {
destroy $w_body
_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
}
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
}
return 0
}
######################################################################
##
## 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]
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]
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 [file join $origin_url .git objects]
if {![file isdirectory $objdir]} {
set objdir [file join $origin_url objects]
if {![file isdirectory $objdir]} {
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]
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
}
set ::_gitdir .git
set ::_prefix {}
set done 1
}
}

View 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

View 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 {$tree_id eq {} || [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]
}

View 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 $cr]
$w_t delete $console_cr end
$w_t insert end "\n"
$w_t insert end [string range $buf $c $cr]
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
}
}

View 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
}
}

53
git-gui/lib/date.tcl Normal file
View File

@@ -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]]
}

View 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,27 +78,50 @@ 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!
#
if {$m eq {_O}} {
set max_sz [expr {128 * 1024}]
set type unknown
if {[catch {
set fd [open $path r]
fconfigure $fd -eofchar {}
set content [read $fd $max_sz]
close $fd
set sz [file size $path]
set type [file type $path]
switch -- $type {
directory {
set type submodule
set content {}
set sz 0
}
link {
set content [file readlink $path]
set sz [string length $content]
}
file {
set fd [open $path r]
fconfigure $fd -eofchar {}
set content [read $fd $max_sz]
close $fd
set sz [file size $path]
}
default {
error "'$type' not supported"
}
}
} 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 {![catch {set type [exec file $path]}]} {
if {$type eq {submodule}} {
$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]} {
set type [string range $type $n end]
@@ -108,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} {
@@ -158,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
}
@@ -198,6 +221,7 @@ proc read_diff {fd} {
if {[string match {mode *} $line]
|| [string match {new file *} $line]
|| [string match {deleted file *} $line]
|| [string match {deleted symlink} $line]
|| [string match {Binary files * and * differ} $line]
|| $line eq {\ No newline at end of file}
|| [regexp {^\* Unmerged path } $line]} {
@@ -275,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
@@ -307,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
}

View 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
}

BIN
git-gui/lib/git-gui.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

View File

@@ -12,11 +12,7 @@ proc update_indexinfo {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
ui_status [format \
"$msg... %i/%i files (%.2f%%)" \
$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 \
@@ -30,18 +26,18 @@ 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
$::main_status stop
uplevel #0 $after
return
}
@@ -67,11 +63,7 @@ proc write_update_indexinfo {fd pathList totalCnt batch msg after} {
display_file $path $new
}
ui_status [format \
"$msg... %i/%i files (%.2f%%)" \
$update_index_cp \
$totalCnt \
[expr {100.0 * $update_index_cp / $totalCnt}]]
$::main_status update $update_index_cp $totalCnt
}
proc update_index {msg pathList after} {
@@ -85,11 +77,7 @@ proc update_index {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
ui_status [format \
"$msg... %i/%i files (%.2f%%)" \
$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 \
@@ -103,18 +91,18 @@ 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
$::main_status stop
uplevel #0 $after
return
}
@@ -144,11 +132,7 @@ proc write_update_index {fd pathList totalCnt batch msg after} {
display_file $path $new
}
ui_status [format \
"$msg... %i/%i files (%.2f%%)" \
$update_index_cp \
$totalCnt \
[expr {100.0 * $update_index_cp / $totalCnt}]]
$::main_status update $update_index_cp $totalCnt
}
proc checkout_index {msg pathList after} {
@@ -162,11 +146,7 @@ proc checkout_index {msg pathList after} {
set batch [expr {int($totalCnt * .01) + 1}]
if {$batch > 25} {set batch 25}
ui_status [format \
"$msg... %i/%i files (%.2f%%)" \
$update_index_cp \
$totalCnt \
0.0]
$::main_status start $msg [mc "files"]
set fd [git_write checkout-index \
--index \
--quiet \
@@ -186,18 +166,18 @@ 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
$::main_status stop
uplevel #0 $after
return
}
@@ -217,11 +197,7 @@ proc write_checkout_index {fd pathList totalCnt batch msg after} {
}
}
ui_status [format \
"$msg... %i/%i files (%.2f%%)" \
$update_index_cp \
$totalCnt \
[expr {100.0 * $update_index_cp / $totalCnt}]]
$::main_status update $update_index_cp $totalCnt
}
proc unstage_helper {txt paths} {
@@ -262,7 +238,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]
}
}
@@ -306,7 +282,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]
}
}
@@ -345,26 +321,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 \

43
git-gui/lib/logo.tcl Normal file
View File

@@ -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
}

View 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
}

View 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}}
{t user.name {mc "User Name"}}
{t user.email {mc "Email Address"}}
{b merge.summary {Summarize Merge Commits}}
{i-1..5 merge.verbosity {Merge Verbosity}}
{b merge.diffstat {Show Diffstat After Merge}}
{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 {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}}
{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]
@@ -255,24 +172,36 @@ proc do_options {} {
frame $w.global.$name
label $w.global.$name.l -text "$text:"
pack $w.global.$name.l -side left -anchor w -fill x
eval tk_optionMenu $w.global.$name.family \
global_config_new(gui.$font^^family) \
$all_fonts
spinbox $w.global.$name.size \
-textvariable global_config_new(gui.$font^^size) \
-from 2 -to 80 -increment 1 \
-width 3
bind $w.global.$name.size <FocusIn> {%W selection range 0 end}
pack $w.global.$name.size -side right -anchor e
pack $w.global.$name.family -side right -anchor e
button $w.global.$name.b \
-text [mc "Change Font"] \
-command [list \
choose_font::pick \
$w \
[mc "Choose %s" $text] \
global_config_new(gui.$font^^family) \
global_config_new(gui.$font^^size) \
]
label $w.global.$name.f -textvariable global_config_new(gui.$font^^family)
label $w.global.$name.s -textvariable global_config_new(gui.$font^^size)
label $w.global.$name.pt -text [mc "pt."]
pack $w.global.$name.l -side left -anchor w
pack $w.global.$name.b -side right -anchor e
pack $w.global.$name.pt -side right -anchor w
pack $w.global.$name.s -side right -anchor w
pack $w.global.$name.f -side right -anchor w
pack $w.global.$name -side top -anchor w -fill x
}
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
}
@@ -303,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

View 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..." \
-command [list fetch_from $r]
}
}
if {![winfo exists $fetch_m]} {
menu $prune_m
$remote_m insert 0 cascade \
-label [mc "Prune from"] \
-menu $prune_m
if {$prune_list ne {}} {
$m add separator
}
foreach r $prune_list {
$m add command \
-label "Prune from $r..." \
-command [list prune_from $r]
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]
}
}
}
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
}
}
}

View 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]

View File

@@ -6,7 +6,7 @@ proc do_windows_shortcut {} {
set fn [tk_getSaveFile \
-parent . \
-title "[appname] ([reponame]): Create Desktop Icon" \
-title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
-initialfile "Git [reponame].bat"]
if {$fn != {}} {
if {[file extension $fn] ne {.bat}} {
@@ -23,7 +23,7 @@ proc do_windows_shortcut {} {
puts $fd " \"[file normalize $argv0]\""
close $fd
} err]} {
error_popup "Cannot write script:\n\n$err"
error_popup [strcat [mc "Cannot write script:"] "\n\n$err"]
}
}
}
@@ -42,7 +42,7 @@ 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"]
if {$fn != {}} {
@@ -71,7 +71,7 @@ proc do_cygwin_shortcut {} {
puts $fd " &\""
close $fd
} err]} {
error_popup "Cannot write script:\n\n$err"
error_popup [strcat [mc "Cannot write script:"] "\n\n$err"]
}
}
}
@@ -81,7 +81,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 +146,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"]
}
}
}

View 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} {

View 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
}

View File

@@ -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

28
git-gui/macosx/Info.plist Normal file
View File

@@ -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>

BIN
git-gui/macosx/git-gui.icns Normal file

Binary file not shown.

2
git-gui/po/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.msg
*~

1864
git-gui/po/de.po Normal file

File diff suppressed because it is too large Load Diff

1895
git-gui/po/hu.po Normal file

File diff suppressed because it is too large Load Diff

1867
git-gui/po/it.po Normal file

File diff suppressed because it is too large Load Diff

1854
git-gui/po/ja.po Normal file

File diff suppressed because it is too large Load Diff

103
git-gui/po/po2msg.sh Normal file
View File

@@ -0,0 +1,103 @@
#!/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]
# parse options
for {set i 1} {$i < $argc} {incr i} {
set arg [lindex $argv $i]
if {$arg == "--statistics" || $arg == "--tcl"} {
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
if {![info exists msgid] || $mode == ""} {
return
}
set mode ""
if {$msgid == ""} {
set prefix "set ::msgcat::header"
} else {
set prefix "::msgcat::mcset $lang \"[u2a $msgid]\""
}
puts $out "$prefix \"[u2a $msgstr]\""
}
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]} {
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
}

1884
git-gui/po/ru.po Normal file

File diff suppressed because it is too large Load Diff

1769
git-gui/po/zh_cn.po Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -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]