--- /dev/null
- DEF_VER=0.20.GITGUI
+#!/bin/sh
+
+GVF=GIT-VERSION-FILE
++DEF_VER=0.21.GITGUI
+
+LF='
+'
+
+tree_search ()
+{
+ head=$1
+ tree=$2
+ for p in $(git rev-list --parents --max-count=1 $head 2>/dev/null)
+ do
+ test $tree = $(git rev-parse $p^{tree} 2>/dev/null) &&
+ vn=$(git describe --abbrev=4 $p 2>/dev/null) &&
+ case "$vn" in
+ gitgui-[0-9]*) echo $vn; break;;
+ esac
+ done
+}
+
+# Always use the tarball version file if found, just
+# in case we are somehow contained in a larger git
+# repository that doesn't actually track our state.
+# (At least one package manager is doing this.)
+#
+# We may be a subproject, so try looking for the merge
+# commit that supplied this directory content if we are
+# not at the toplevel. We probably will always be the
+# second parent in the commit, but we shouldn't rely on
+# that fact.
+#
+# If we are at the toplevel or the merge assumption fails
+# try looking for a gitgui-* tag.
+
+if test -f version &&
+ VN=$(cat version)
+then
+ : happy
+elif prefix="$(git rev-parse --show-prefix 2>/dev/null)"
+ test -n "$prefix" &&
+ head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) &&
+ tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) &&
+ VN=$(tree_search $head $tree)
+ case "$VN" in
+ gitgui-[0-9]*) : happy ;;
+ *) (exit 1) ;;
+ esac
+then
+ VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g');
+elif VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
+ case "$VN" in
+ gitgui-[0-9]*) : happy ;;
+ *) (exit 1) ;;
+ esac
+then
+ VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g');
+else
+ VN="$DEF_VER"
+fi
+
+dirty=$(sh -c 'git diff-index --name-only HEAD' 2>/dev/null) || dirty=
+case "$dirty" in
+'')
+ ;;
+*)
+ VN="$VN-dirty" ;;
+esac
+
+if test -r $GVF
+then
+ VC=$(sed -e 's/^GITGUI_VERSION = //' <$GVF)
+else
+ VC=unset
+fi
+test "$VN" = "$VC" || {
+ echo >&2 "GITGUI_VERSION = $VN"
+ echo "GITGUI_VERSION = $VN" >$GVF
+}
--- /dev/null
- $(foreach p,$(PRELOAD_FILES) $(ALL_LIBFILES),echo '$(subst lib/,,$p)' >>$@ &&) \
+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 valid for this to work.
+#
+
+GIT-VERSION-FILE: FORCE
+ @$(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')
+uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not')
+
+SCRIPT_SH = git-gui.sh
+GITGUI_MAIN := git-gui
+GITGUI_BUILT_INS = git-citool
+ALL_LIBFILES = $(wildcard lib/*.tcl)
+PRELOAD_FILES = lib/class.tcl
+NONTCL_LIBFILES = \
+ lib/git-gui.ico \
+ $(wildcard lib/win32_*.js) \
+#end NONTCL_LIBFILES
+
+ifndef SHELL_PATH
+ SHELL_PATH = /bin/sh
+endif
+
+ifndef gitexecdir
+ gitexecdir := $(shell git --exec-path)
+endif
+
+ifndef sharedir
+ifeq (git-core,$(notdir $(gitexecdir)))
+ sharedir := $(dir $(patsubst %/,%,$(dir $(gitexecdir))))share
+else
+ sharedir := $(dir $(gitexecdir))share
+endif
+endif
+
+ifndef INSTALL
+ INSTALL = install
+endif
+
+RM_RF ?= rm -rf
+RMDIR ?= rmdir
+
+INSTALL_D0 = $(INSTALL) -d -m 755 # space is required here
+INSTALL_D1 =
+INSTALL_R0 = $(INSTALL) -m 644 # space is required here
+INSTALL_R1 =
+INSTALL_X0 = $(INSTALL) -m 755 # 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_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=
+ INSTALL_D1 = && echo ' ' DEST $$dir && $(INSTALL) -d -m 755 "$$dir"
+ INSTALL_R0 = src=
+ INSTALL_R1 = && echo ' ' INSTALL 644 `basename $$src` && $(INSTALL) -m 644 $$src
+ INSTALL_X0 = src=
+ INSTALL_X1 = && echo ' ' INSTALL 755 `basename $$src` && $(INSTALL) -m 755 $$src
+ INSTALL_A0 = src=
+ INSTALL_A1 = && echo ' ' INSTALL ' ' `basename "$$src"` && find "$$src" | cpio -pud
+
+ 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
+
+TCLTK_PATH ?= wish
+ifeq (./,$(dir $(TCLTK_PATH)))
+ TCL_PATH ?= $(subst wish,tclsh,$(TCLTK_PATH))
+else
+ TCL_PATH ?= $(dir $(TCLTK_PATH))$(notdir $(subst wish,tclsh,$(TCLTK_PATH)))
+endif
+
+ifeq ($(uname_S),Darwin)
+ TKFRAMEWORK = /Library/Frameworks/Tk.framework/Resources/Wish.app
+ ifeq ($(shell echo "$(uname_R)" | awk -F. '{if ($$1 >= 9) print "y"}')_$(shell test -d $(TKFRAMEWORK) || echo n),y_n)
+ TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish.app
+ ifeq ($(shell test -d $(TKFRAMEWORK) || echo n),n)
+ TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish\ Shell.app
+ endif
+ endif
+ TKEXECUTABLE = $(shell basename "$(TKFRAMEWORK)" .app)
+endif
+
+ifeq ($(findstring $(MAKEFLAGS),s),s)
+QUIET_GEN =
+endif
+
+-include config.mak
+
+DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
+gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
+SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
+TCL_PATH_SQ = $(subst ','\'',$(TCL_PATH))
+TCLTK_PATH_SQ = $(subst ','\'',$(TCLTK_PATH))
+TCLTK_PATH_SED = $(subst ','\'',$(subst \,\\,$(TCLTK_PATH)))
+
+gg_libdir ?= $(sharedir)/git-gui/lib
+libdir_SQ = $(subst ','\'',$(gg_libdir))
+libdir_SED = $(subst ','\'',$(subst \,\\,$(gg_libdir_sed_in)))
+exedir = $(dir $(gitexecdir))share/git-gui/lib
+
+GITGUI_SCRIPT := $$0
+GITGUI_RELATIVE :=
+GITGUI_MACOSXAPP :=
+
+ifeq ($(uname_O),Cygwin)
+ GITGUI_SCRIPT := `cygpath --windows --absolute "$(GITGUI_SCRIPT)"`
+
+ # Is this a Cygwin Tcl/Tk binary? If so it knows how to do
+ # POSIX path translation just like cygpath does and we must
+ # keep libdir in POSIX format so Cygwin packages of git-gui
+ # work no matter where the user installs them.
+ #
+ ifeq ($(shell echo 'puts [file normalize /]' | '$(TCL_PATH_SQ)'),$(shell cygpath --mixed --absolute /))
+ gg_libdir_sed_in := $(gg_libdir)
+ else
+ gg_libdir_sed_in := $(shell cygpath --windows --absolute "$(gg_libdir)")
+ endif
+else
+ ifeq ($(exedir),$(gg_libdir))
+ GITGUI_RELATIVE := 1
+ endif
+ gg_libdir_sed_in := $(gg_libdir)
+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
+ GITGUI_RELATIVE := 1
+endif
+
+ifdef GITGUI_MACOSXAPP
+GITGUI_MAIN := git-gui.tcl
+
+git-gui: GIT-VERSION-FILE GIT-GUI-VARS
+ $(QUIET_GEN)rm -f $@ $@+ && \
+ echo '#!$(SHELL_PATH_SQ)' >$@+ && \
+ echo 'if test "z$$*" = zversion ||' >>$@+ && \
+ echo ' test "z$$*" = z--version' >>$@+ && \
+ echo then >>$@+ && \
+ echo ' 'echo \'git-gui version '$(GITGUI_VERSION)'\' >>$@+ && \
+ echo else >>$@+ && \
+ echo ' libdir="$${GIT_GUI_LIB_DIR:-$(libdir_SQ)}"' >>$@+ && \
+ echo ' 'exec \"'$$libdir/Git Gui.app/Contents/MacOS/$(subst \,,$(TKEXECUTABLE))'\" \
+ '"$$0" "$$@"' >>$@+ && \
+ echo fi >>$@+ && \
+ chmod +x $@+ && \
+ mv $@+ $@
+
+Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-VARS \
+ macosx/Info.plist \
+ macosx/git-gui.icns \
+ macosx/AppMain.tcl \
+ $(TKFRAMEWORK)/Contents/MacOS/$(TKEXECUTABLE)
+ $(QUIET_GEN)rm -rf '$@' '$@'+ && \
+ mkdir -p '$@'+/Contents/MacOS && \
+ mkdir -p '$@'+/Contents/Resources/Scripts && \
+ cp '$(subst ','\'',$(subst \,,$(TKFRAMEWORK)/Contents/MacOS/$(TKEXECUTABLE)))' \
+ '$@'+/Contents/MacOS && \
+ cp macosx/git-gui.icns '$@'+/Contents/Resources && \
+ sed -e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
+ -e 's/@@GITGUI_TKEXECUTABLE@@/$(TKEXECUTABLE)/g' \
+ macosx/Info.plist \
+ >'$@'+/Contents/Info.plist && \
+ sed -e 's|@@gitexecdir@@|$(gitexecdir_SQ)|' \
+ -e 's|@@GITGUI_LIBDIR@@|$(libdir_SED)|' \
+ macosx/AppMain.tcl \
+ >'$@'+/Contents/Resources/Scripts/AppMain.tcl && \
+ mv '$@'+ '$@'
+endif
+
+ifdef GITGUI_WINDOWS_WRAPPER
+GITGUI_MAIN := git-gui.tcl
+
+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 's|@@SHELL_PATH@@|$(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
+ ifneq ($(shell $(MSGFMT) --tcl -l C -d . /dev/null 2>/dev/null; echo $$?),0)
+ MSGFMT := $(TCL_PATH) po/po2msg.sh
+ endif
+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' \
+ | $(TCL_PATH) $(QUIET_2DEVNULL); then : ok; \
+ else \
+ echo >&2 " * $(TCL_PATH) failed; using unoptimized loading"; \
+ rm -f $@ ; \
+ echo '# Autogenerated by git-gui Makefile' >$@ && \
+ echo >>$@ && \
++ $(foreach p,$(PRELOAD_FILES) $(sort $(ALL_LIBFILES)),echo '$(subst lib/,,$p)' >>$@ &&) \
+ echo >>$@ ; \
+ fi
+
+TRACK_VARS = \
+ $(subst ','\'',SHELL_PATH='$(SHELL_PATH_SQ)') \
+ $(subst ','\'',TCL_PATH='$(TCL_PATH_SQ)') \
+ $(subst ','\'',TCLTK_PATH='$(TCLTK_PATH_SQ)') \
+ $(subst ','\'',gitexecdir='$(gitexecdir_SQ)') \
+ $(subst ','\'',gg_libdir='$(libdir_SQ)') \
+ GITGUI_MACOSXAPP=$(GITGUI_MACOSXAPP) \
+#end TRACK_VARS
+
+GIT-GUI-VARS: FORCE
+ @VARS='$(TRACK_VARS)'; \
+ if test x"$$VARS" != x"`cat $@ 2>/dev/null`" ; then \
+ echo >&2 " * new locations or Tcl/Tk interpreter"; \
+ echo >$@ "$$VARS"; \
+ fi
+
+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)$(INSTALL_X0)git-gui--askpass $(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)'
+ifdef GITGUI_MACOSXAPP
+ $(QUIET)$(INSTALL_A0)'Git Gui.app' $(INSTALL_A1) '$(DESTDIR_SQ)$(libdir_SQ)'
+ $(QUIET)$(INSTALL_X0)git-gui.tcl $(INSTALL_X1) '$(DESTDIR_SQ)$(libdir_SQ)'
+endif
+ $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true
+ $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(INSTALL_D1)
+ $(QUIET)$(foreach p,$(ALL_MSGFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true
+
+uninstall:
+ $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(gitexecdir_SQ)'
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui $(REMOVE_F1)
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(gitexecdir_SQ)'/git-gui--askpass $(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)
+ifdef GITGUI_MACOSXAPP
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)/Git Gui.app' $(REMOVE_F1)
+ $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.tcl $(REMOVE_F1)
+endif
+ $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
+ $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(msgsdir_SQ)'
+ $(QUIET)$(foreach p,$(ALL_MSGFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(msgsdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true
+ $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(REMOVE_D1)
+ $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(REMOVE_D1)
+ $(QUIET)$(REMOVE_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(REMOVE_D1)
+ $(QUIET)$(REMOVE_D0)`dirname '$(DESTDIR_SQ)$(libdir_SQ)'` $(REMOVE_D1)
+
+dist-version:
+ @mkdir -p $(TARDIR)
+ @echo $(GITGUI_VERSION) > $(TARDIR)/version
+
+clean::
+ $(RM_RF) $(GITGUI_MAIN) lib/tclIndex po/*.msg
+ $(RM_RF) GIT-VERSION-FILE GIT-GUI-VARS
+ifdef GITGUI_MACOSXAPP
+ $(RM_RF) 'Git Gui.app'* git-gui
+endif
+ifdef GITGUI_WINDOWS_WRAPPER
+ $(RM_RF) git-gui
+endif
+
+.PHONY: all install uninstall dist-version clean
+.PHONY: FORCE
--- /dev/null
- set opt [list]
-
- while {1} {
- switch -- [lindex $args 0] {
- --nice {
- _lappend_nice opt
- }
-
- default {
- break
- }
-
- }
-
- set args [lrange $args 1 end]
- }
-
- set cmdp [_git_cmd [lindex $args 0]]
- set args [lrange $args 1 end]
-
- _trace_exec [concat $opt $cmdp $args]
- set result [eval exec $opt $cmdp $args]
+#!/bin/sh
+# Tcl ignores the next line -*- tcl -*- \
+ if test "z$*" = zversion \
+ || test "z$*" = z--version; \
+ then \
+ echo 'git-gui version @@GITGUI_VERSION@@'; \
+ exit; \
+ fi; \
+ argv0=$0; \
+ exec wish "$argv0" -- "$@"
+
+set appvers {@@GITGUI_VERSION@@}
+set copyright [string map [list (c) \u00a9] {
+Copyright (c) 2006-2010 Shawn Pearce, et. al.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}]
+
+######################################################################
+##
+## Tcl/Tk sanity check
+
+if {[catch {package require Tcl 8.4} err]
+ || [catch {package require Tk 8.4} err]
+} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title "git-gui: fatal error" \
+ -message $err
+ exit 1
+}
+
+catch {rename send {}} ; # What an evil concept...
+
+######################################################################
+##
+## locate our library
+
+if { [info exists ::env(GIT_GUI_LIB_DIR) ] } {
+ set oguilib $::env(GIT_GUI_LIB_DIR)
+} else {
+ set oguilib {@@GITGUI_LIBDIR@@}
+}
+set oguirel {@@GITGUI_RELATIVE@@}
+if {$oguirel eq {1}} {
+ set oguilib [file dirname [file normalize $argv0]]
+ if {[file tail $oguilib] eq {git-core}} {
+ set oguilib [file dirname $oguilib]
+ }
+ set oguilib [file dirname $oguilib]
+ set oguilib [file join $oguilib share git-gui lib]
+ set oguimsg [file join $oguilib msgs]
+} elseif {[string match @@* $oguirel]} {
+ set oguilib [file join [file dirname [file normalize $argv0]] lib]
+ set oguimsg [file join [file dirname [file normalize $argv0]] po]
+} else {
+ set oguimsg [file join $oguilib msgs]
+}
+unset oguirel
+
+######################################################################
+##
+## enable verbose loading?
+
+if {![catch {set _verbose $env(GITGUI_VERBOSE)}]} {
+ unset _verbose
+ rename auto_load real__auto_load
+ proc auto_load {name args} {
+ puts stderr "auto_load $name"
+ return [uplevel 1 real__auto_load $name $args]
+ }
+ rename source real__source
+ proc source {args} {
+ puts stderr "source $args"
+ uplevel 1 [linsert $args 0 real__source]
+ }
+ if {[tk windowingsystem] eq "win32"} { console show }
+}
+
+######################################################################
+##
+## Internationalization (i18n) through msgcat and gettext. See
+## http://www.gnu.org/software/gettext/manual/html_node/Tcl.html
+
+package require msgcat
+
+# Check for Windows 7 MUI language pack (missed by msgcat < 1.4.4)
+if {[tk windowingsystem] eq "win32"
+ && [package vcompare [package provide msgcat] 1.4.4] < 0
+} then {
+ proc _mc_update_locale {} {
+ set key {HKEY_CURRENT_USER\Control Panel\Desktop}
+ if {![catch {
+ package require registry
+ set uilocale [registry get $key "PreferredUILanguages"]
+ msgcat::ConvertLocale [string map {- _} [lindex $uilocale 0]]
+ } uilocale]} {
+ if {[string length $uilocale] > 0} {
+ msgcat::mclocale $uilocale
+ }
+ }
+ }
+ _mc_update_locale
+}
+
+proc _mc_trim {fmt} {
+ set cmk [string first @@ $fmt]
+ if {$cmk > 0} {
+ return [string range $fmt 0 [expr {$cmk - 1}]]
+ }
+ return $fmt
+}
+
+proc mc {en_fmt args} {
+ set fmt [_mc_trim [::msgcat::mc $en_fmt]]
+ if {[catch {set msg [eval [list format $fmt] $args]} err]} {
+ set msg [eval [list format [_mc_trim $en_fmt]] $args]
+ }
+ return $msg
+}
+
+proc strcat {args} {
+ return [join $args {}]
+}
+
+::msgcat::mcload $oguimsg
+unset oguimsg
+
+######################################################################
+##
+## On Mac, bring the current Wish process window to front
+
+if {[tk windowingsystem] eq "aqua"} {
+ catch {
+ exec osascript -e [format {
+ tell application "System Events"
+ set frontmost of processes whose unix id is %d to true
+ end tell
+ } [pid]]
+ }
+}
+
+######################################################################
+##
+## read only globals
+
+set _appname {Git Gui}
+set _gitdir {}
+set _gitworktree {}
+set _isbare {}
+set _gitexec {}
+set _githtmldir {}
+set _reponame {}
+set _iscygwin {}
+set _search_path {}
+set _shellpath {@@SHELL_PATH@@}
+
+set _trace [lsearch -exact $argv --trace]
+if {$_trace >= 0} {
+ set argv [lreplace $argv $_trace $_trace]
+ set _trace 1
+ if {[tk windowingsystem] eq "win32"} { console show }
+} else {
+ set _trace 0
+}
+
+# variable for the last merged branch (useful for a default when deleting
+# branches).
+set _last_merged_branch {}
+
+proc shellpath {} {
+ global _shellpath env
+ if {[string match @@* $_shellpath]} {
+ if {[info exists env(SHELL)]} {
+ return $env(SHELL)
+ } else {
+ return /bin/sh
+ }
+ }
+ return $_shellpath
+}
+
+proc appname {} {
+ global _appname
+ return $_appname
+}
+
+proc gitdir {args} {
+ global _gitdir
+ if {$args eq {}} {
+ return $_gitdir
+ }
+ return [eval [list file join $_gitdir] $args]
+}
+
+proc gitexec {args} {
+ global _gitexec
+ if {$_gitexec eq {}} {
+ if {[catch {set _gitexec [git --exec-path]} err]} {
+ error "Git not installed?\n\n$err"
+ }
+ if {[is_Cygwin]} {
+ set _gitexec [exec cygpath \
+ --windows \
+ --absolute \
+ $_gitexec]
+ } else {
+ set _gitexec [file normalize $_gitexec]
+ }
+ }
+ if {$args eq {}} {
+ return $_gitexec
+ }
+ return [eval [list file join $_gitexec] $args]
+}
+
+proc githtmldir {args} {
+ global _githtmldir
+ if {$_githtmldir eq {}} {
+ if {[catch {set _githtmldir [git --html-path]}]} {
+ # Git not installed or option not yet supported
+ return {}
+ }
+ if {[is_Cygwin]} {
+ set _githtmldir [exec cygpath \
+ --windows \
+ --absolute \
+ $_githtmldir]
+ } else {
+ set _githtmldir [file normalize $_githtmldir]
+ }
+ }
+ if {$args eq {}} {
+ return $_githtmldir
+ }
+ return [eval [list file join $_githtmldir] $args]
+}
+
+proc reponame {} {
+ return $::_reponame
+}
+
+proc is_MacOSX {} {
+ if {[tk windowingsystem] eq {aqua}} {
+ return 1
+ }
+ return 0
+}
+
+proc is_Windows {} {
+ if {$::tcl_platform(platform) eq {windows}} {
+ return 1
+ }
+ return 0
+}
+
+proc is_Cygwin {} {
+ global _iscygwin
+ if {$_iscygwin eq {}} {
+ if {$::tcl_platform(platform) eq {windows}} {
+ if {[catch {set p [exec cygpath --windir]} err]} {
+ set _iscygwin 0
+ } else {
+ set _iscygwin 1
++ # Handle MSys2 which is only cygwin when MSYSTEM is MSYS.
++ if {[info exists ::env(MSYSTEM)] && $::env(MSYSTEM) ne "MSYS"} {
++ set _iscygwin 0
++ }
+ }
+ } else {
+ set _iscygwin 0
+ }
+ }
+ return $_iscygwin
+}
+
+proc is_enabled {option} {
+ global enabled_options
+ if {[catch {set on $enabled_options($option)}]} {return 0}
+ return $on
+}
+
+proc enable_option {option} {
+ global enabled_options
+ set enabled_options($option) 1
+}
+
+proc disable_option {option} {
+ global enabled_options
+ set enabled_options($option) 0
+}
+
+######################################################################
+##
+## config
+
+proc is_many_config {name} {
+ switch -glob -- $name {
+ gui.recentrepo -
+ remote.*.fetch -
+ remote.*.push
+ {return 1}
+ *
+ {return 0}
+ }
+}
+
+proc is_config_true {name} {
+ global repo_config
+ if {[catch {set v $repo_config($name)}]} {
+ return 0
+ }
+ set v [string tolower $v]
+ if {$v eq {} || $v eq {true} || $v eq {1} || $v eq {yes} || $v eq {on}} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc is_config_false {name} {
+ global repo_config
+ if {[catch {set v $repo_config($name)}]} {
+ return 0
+ }
+ set v [string tolower $v]
+ if {$v eq {false} || $v eq {0} || $v eq {no} || $v eq {off}} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc get_config {name} {
+ global repo_config
+ if {[catch {set v $repo_config($name)}]} {
+ return {}
+ } else {
+ return $v
+ }
+}
+
+proc is_bare {} {
+ global _isbare
+ global _gitdir
+ global _gitworktree
+
+ if {$_isbare eq {}} {
+ if {[catch {
+ set _bare [git rev-parse --is-bare-repository]
+ switch -- $_bare {
+ true { set _isbare 1 }
+ false { set _isbare 0}
+ default { throw }
+ }
+ }]} {
+ if {[is_config_true core.bare]
+ || ($_gitworktree eq {}
+ && [lindex [file split $_gitdir] end] ne {.git})} {
+ set _isbare 1
+ } else {
+ set _isbare 0
+ }
+ }
+ }
+ return $_isbare
+}
+
+######################################################################
+##
+## handy utils
+
+proc _trace_exec {cmd} {
+ if {!$::_trace} return
+ set d {}
+ foreach v $cmd {
+ if {$d ne {}} {
+ append d { }
+ }
+ if {[regexp {[ \t\r\n'"$?*]} $v]} {
+ set v [sq $v]
+ }
+ append d $v
+ }
+ puts stderr $d
+}
+
+#'" fix poor old emacs font-lock mode
+
+proc _git_cmd {name} {
+ global _git_cmd_path
+
+ if {[catch {set v $_git_cmd_path($name)}]} {
+ switch -- $name {
+ version -
+ --version -
+ --exec-path { return [list $::_git $name] }
+ }
+
+ set p [gitexec git-$name$::_search_exe]
+ if {[file exists $p]} {
+ set v [list $p]
+ } elseif {[is_Windows] && [file exists [gitexec git-$name]]} {
+ # Try to determine what sort of magic will make
+ # git-$name go and do its thing, because native
+ # Tcl on Windows doesn't know it.
+ #
+ set p [gitexec git-$name]
+ set f [open $p r]
+ set s [gets $f]
+ close $f
+
+ switch -glob -- [lindex $s 0] {
+ #!*sh { set i sh }
+ #!*perl { set i perl }
+ #!*python { set i python }
+ default { error "git-$name is not supported: $s" }
+ }
+
+ upvar #0 _$i interp
+ if {![info exists interp]} {
+ set interp [_which $i]
+ }
+ if {$interp eq {}} {
+ error "git-$name requires $i (not in PATH)"
+ }
+ set v [concat [list $interp] [lrange $s 1 end] [list $p]]
+ } else {
+ # Assume it is builtin to git somehow and we
+ # aren't actually able to see a file for it.
+ #
+ set v [list $::_git $name]
+ }
+ set _git_cmd_path($name) $v
+ }
+ return $v
+}
+
+proc _which {what args} {
+ global env _search_exe _search_path
+
+ if {$_search_path eq {}} {
+ if {[is_Cygwin] && [regexp {^(/|\.:)} $env(PATH)]} {
+ set _search_path [split [exec cygpath \
+ --windows \
+ --path \
+ --absolute \
+ $env(PATH)] {;}]
+ set _search_exe .exe
+ } elseif {[is_Windows]} {
+ set gitguidir [file dirname [info script]]
+ regsub -all ";" $gitguidir "\\;" gitguidir
+ set env(PATH) "$gitguidir;$env(PATH)"
+ set _search_path [split $env(PATH) {;}]
+ set _search_exe .exe
+ } else {
+ set _search_path [split $env(PATH) :]
+ set _search_exe {}
+ }
+ }
+
+ if {[is_Windows] && [lsearch -exact $args -script] >= 0} {
+ set suffix {}
+ } else {
+ set suffix $_search_exe
+ }
+
+ foreach p $_search_path {
+ set p [file join $p $what$suffix]
+ if {[file exists $p]} {
+ return [file normalize $p]
+ }
+ }
+ return {}
+}
+
+# Test a file for a hashbang to identify executable scripts on Windows.
+proc is_shellscript {filename} {
+ if {![file exists $filename]} {return 0}
+ set f [open $filename r]
+ fconfigure $f -encoding binary
+ set magic [read $f 2]
+ close $f
+ return [expr {$magic eq "#!"}]
+}
+
+# Run a command connected via pipes on stdout.
+# This is for use with textconv filters and uses sh -c "..." to allow it to
+# contain a command with arguments. On windows we must check for shell
+# scripts specifically otherwise just call the filter command.
+proc open_cmd_pipe {cmd path} {
+ global env
+ if {![file executable [shellpath]]} {
+ set exe [auto_execok [lindex $cmd 0]]
+ if {[is_shellscript [lindex $exe 0]]} {
+ set run [linsert [auto_execok sh] end -c "$cmd \"\$0\"" $path]
+ } else {
+ set run [concat $exe [lrange $cmd 1 end] $path]
+ }
+ } else {
+ set run [list [shellpath] -c "$cmd \"\$0\"" $path]
+ }
+ return [open |$run r]
+}
+
+proc _lappend_nice {cmd_var} {
+ global _nice
+ upvar $cmd_var cmd
+
+ if {![info exists _nice]} {
+ set _nice [_which nice]
+ if {[catch {exec $_nice git version}]} {
+ set _nice {}
+ } elseif {[is_Windows] && [file dirname $_nice] ne [file dirname $::_git]} {
+ set _nice {}
+ }
+ }
+ if {$_nice ne {}} {
+ lappend cmd $_nice
+ }
+}
+
+proc git {args} {
- fconfigure $fd_rc -translation binary
++ set fd [eval [list git_read] $args]
++ fconfigure $fd -translation binary -encoding utf-8
++ set result [string trimright [read $fd] "\n"]
++ close $fd
+ if {$::_trace} {
+ puts stderr "< $result"
+ }
+ return $result
+}
+
+proc _open_stdout_stderr {cmd} {
+ _trace_exec $cmd
+ if {[catch {
+ set fd [open [concat [list | ] $cmd] r]
+ } err]} {
+ if { [lindex $cmd end] eq {2>@1}
+ && $err eq {can not find channel named "1"}
+ } {
+ # Older versions of Tcl 8.4 don't have this 2>@1 IO
+ # redirect operator. Fallback to |& cat for those.
+ # The command was not actually started, so its safe
+ # to try to start it a second time.
+ #
+ set fd [open [concat \
+ [list | ] \
+ [lrange $cmd 0 end-1] \
+ [list |& cat] \
+ ] r]
+ } else {
+ error $err
+ }
+ }
+ fconfigure $fd -eofchar {}
+ return $fd
+}
+
+proc git_read {args} {
+ set opt [list]
+
+ while {1} {
+ switch -- [lindex $args 0] {
+ --nice {
+ _lappend_nice opt
+ }
+
+ --stderr {
+ lappend args 2>@1
+ }
+
+ default {
+ break
+ }
+
+ }
+
+ set args [lrange $args 1 end]
+ }
+
+ set cmdp [_git_cmd [lindex $args 0]]
+ set args [lrange $args 1 end]
+
+ return [_open_stdout_stderr [concat $opt $cmdp $args]]
+}
+
+proc git_write {args} {
+ set opt [list]
+
+ while {1} {
+ switch -- [lindex $args 0] {
+ --nice {
+ _lappend_nice opt
+ }
+
+ default {
+ break
+ }
+
+ }
+
+ set args [lrange $args 1 end]
+ }
+
+ set cmdp [_git_cmd [lindex $args 0]]
+ set args [lrange $args 1 end]
+
+ _trace_exec [concat $opt $cmdp $args]
+ return [open [concat [list | ] $opt $cmdp $args] w]
+}
+
+proc githook_read {hook_name args} {
+ set pchook [gitdir hooks $hook_name]
+ lappend args 2>@1
+
+ # On Windows [file executable] might lie so we need to ask
+ # the shell if the hook is executable. Yes that's annoying.
+ #
+ if {[is_Windows]} {
+ upvar #0 _sh interp
+ if {![info exists interp]} {
+ set interp [_which sh]
+ }
+ if {$interp eq {}} {
+ error "hook execution requires sh (not in PATH)"
+ }
+
+ set scr {if test -x "$1";then exec "$@";fi}
+ set sh_c [list $interp -c $scr $interp $pchook]
+ return [_open_stdout_stderr [concat $sh_c $args]]
+ }
+
+ if {[file executable $pchook]} {
+ return [_open_stdout_stderr [concat [list $pchook] $args]]
+ }
+
+ return {}
+}
+
+proc kill_file_process {fd} {
+ set process [pid $fd]
+
+ catch {
+ if {[is_Windows]} {
+ exec taskkill /pid $process
+ } else {
+ exec kill $process
+ }
+ }
+}
+
+proc gitattr {path attr default} {
+ if {[catch {set r [git check-attr $attr -- $path]}]} {
+ set r unspecified
+ } else {
+ set r [join [lrange [split $r :] 2 end] :]
+ regsub {^ } $r {} r
+ }
+ if {$r eq {unspecified}} {
+ return $default
+ }
+ return $r
+}
+
+proc sq {value} {
+ regsub -all ' $value "'\\''" value
+ return "'$value'"
+}
+
+proc load_current_branch {} {
+ global current_branch is_detached
+
+ set fd [open [gitdir HEAD] r]
+ if {[gets $fd ref] < 1} {
+ set ref {}
+ }
+ close $fd
+
+ set pfx {ref: refs/heads/}
+ set len [string length $pfx]
+ if {[string equal -length $len $pfx $ref]} {
+ # We're on a branch. It might not exist. But
+ # HEAD looks good enough to be a branch.
+ #
+ set current_branch [string range $ref $len end]
+ set is_detached 0
+ } else {
+ # Assume this is a detached head.
+ #
+ set current_branch HEAD
+ set is_detached 1
+ }
+}
+
+auto_load tk_optionMenu
+rename tk_optionMenu real__tkOptionMenu
+proc tk_optionMenu {w varName args} {
+ set m [eval real__tkOptionMenu $w $varName $args]
+ $m configure -font font_ui
+ $w configure -font font_ui
+ return $m
+}
+
+proc rmsel_tag {text} {
+ $text tag conf sel \
+ -background [$text cget -background] \
+ -foreground [$text cget -foreground] \
+ -borderwidth 0
+ $text tag conf in_sel -background lightgray
+ bind $text <Motion> break
+ return $text
+}
+
+wm withdraw .
+set root_exists 0
+bind . <Visibility> {
+ bind . <Visibility> {}
+ set root_exists 1
+}
+
+if {[is_Windows]} {
+ wm iconbitmap . -default $oguilib/git-gui.ico
+ set ::tk::AlwaysShowSelection 1
+ bind . <Control-F2> {console show}
+
+ # Spoof an X11 display for SSH
+ if {![info exists env(DISPLAY)]} {
+ set env(DISPLAY) :9999
+ }
+} else {
+ catch {
+ image create photo gitlogo -width 16 -height 16
+
+ gitlogo put #33CC33 -to 7 0 9 2
+ gitlogo put #33CC33 -to 4 2 12 4
+ gitlogo put #33CC33 -to 7 4 9 6
+ gitlogo put #CC3333 -to 4 6 12 8
+ gitlogo put gray26 -to 4 9 6 10
+ gitlogo put gray26 -to 3 10 6 12
+ gitlogo put gray26 -to 8 9 13 11
+ gitlogo put gray26 -to 8 11 10 12
+ gitlogo put gray26 -to 11 11 13 14
+ gitlogo put gray26 -to 3 12 5 14
+ gitlogo put gray26 -to 5 13
+ gitlogo put gray26 -to 10 13
+ gitlogo put gray26 -to 4 14 12 15
+ gitlogo put gray26 -to 5 15 11 16
+ gitlogo redither
+
+ image create photo gitlogo32 -width 32 -height 32
+ gitlogo32 copy gitlogo -zoom 2 2
+
+ wm iconphoto . -default gitlogo gitlogo32
+ }
+}
+
+######################################################################
+##
+## config defaults
+
+set cursor_ptr arrow
+font create font_ui
+if {[lsearch -exact [font names] TkDefaultFont] != -1} {
+ eval [linsert [font actual TkDefaultFont] 0 font configure font_ui]
+ eval [linsert [font actual TkFixedFont] 0 font create font_diff]
+} else {
+ font create font_diff -family Courier -size 10
+ catch {
+ label .dummy
+ eval font configure font_ui [font actual [.dummy cget -font]]
+ destroy .dummy
+ }
+}
+
+font create font_uiitalic
+font create font_uibold
+font create font_diffbold
+font create font_diffitalic
+
+foreach class {Button Checkbutton Entry Label
+ Labelframe Listbox Message
+ Radiobutton Spinbox Text} {
+ option add *$class.font font_ui
+}
+if {![is_MacOSX]} {
+ option add *Menu.font font_ui
+ option add *Entry.borderWidth 1 startupFile
+ option add *Entry.relief sunken startupFile
+ option add *RadioButton.anchor w startupFile
+}
+unset class
+
+if {[is_Windows] || [is_MacOSX]} {
+ option add *Menu.tearOff 0
+}
+
+if {[is_MacOSX]} {
+ set M1B M1
+ set M1T Cmd
+} else {
+ set M1B Control
+ set M1T Ctrl
+}
+
+proc bind_button3 {w cmd} {
+ bind $w <Any-Button-3> $cmd
+ if {[is_MacOSX]} {
+ # Mac OS X sends Button-2 on right click through three-button mouse,
+ # or through trackpad right-clicking (two-finger touch + click).
+ bind $w <Any-Button-2> $cmd
+ bind $w <Control-Button-1> $cmd
+ }
+}
+
+proc apply_config {} {
+ global repo_config font_descs
+
+ foreach option $font_descs {
+ set name [lindex $option 0]
+ set font [lindex $option 1]
+ if {[catch {
+ set need_weight 1
+ foreach {cn cv} $repo_config(gui.$name) {
+ if {$cn eq {-weight}} {
+ set need_weight 0
+ }
+ font configure $font $cn $cv
+ }
+ if {$need_weight} {
+ font configure $font -weight normal
+ }
+ } err]} {
+ error_popup [strcat [mc "Invalid font specified in %s:" "gui.$name"] "\n\n$err"]
+ }
+ foreach {cn cv} [font configure $font] {
+ font configure ${font}bold $cn $cv
+ font configure ${font}italic $cn $cv
+ }
+ font configure ${font}bold -weight bold
+ font configure ${font}italic -slant italic
+ }
+
+ global use_ttk NS
+ set use_ttk 0
+ set NS {}
+ if {$repo_config(gui.usettk)} {
+ set use_ttk [package vsatisfies [package provide Tk] 8.5]
+ if {$use_ttk} {
+ set NS ttk
+ bind [winfo class .] <<ThemeChanged>> [list InitTheme]
+ pave_toplevel .
+ }
+ }
+}
+
+set default_config(branch.autosetupmerge) true
+set default_config(merge.tool) {}
+set default_config(mergetool.keepbackup) true
+set default_config(merge.diffstat) true
+set default_config(merge.summary) false
+set default_config(merge.verbosity) 2
+set default_config(user.name) {}
+set default_config(user.email) {}
+
+set default_config(gui.encoding) [encoding system]
+set default_config(gui.matchtrackingbranch) false
+set default_config(gui.textconv) true
+set default_config(gui.pruneduringfetch) false
+set default_config(gui.trustmtime) false
+set default_config(gui.fastcopyblame) false
+set default_config(gui.maxrecentrepo) 10
+set default_config(gui.copyblamethreshold) 40
+set default_config(gui.blamehistoryctx) 7
+set default_config(gui.diffcontext) 5
+set default_config(gui.diffopts) {}
+set default_config(gui.commitmsgwidth) 75
+set default_config(gui.newbranchtemplate) {}
+set default_config(gui.spellingdictionary) {}
+set default_config(gui.fontui) [font configure font_ui]
+set default_config(gui.fontdiff) [font configure font_diff]
+# TODO: this option should be added to the git-config documentation
+set default_config(gui.maxfilesdisplayed) 5000
+set default_config(gui.usettk) 1
+set default_config(gui.warndetachedcommit) 1
+set default_config(gui.tabsize) 8
+set font_descs {
+ {fontui font_ui {mc "Main Font"}}
+ {fontdiff font_diff {mc "Diff/Console Font"}}
+}
+set default_config(gui.stageuntracked) ask
+set default_config(gui.displayuntracked) true
+
+######################################################################
+##
+## find git
+
+set _git [_which git]
+if {$_git eq {}} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "git-gui: fatal error"] \
+ -message [mc "Cannot find git in PATH."]
+ exit 1
+}
+
+######################################################################
+##
+## version check
+
+if {[catch {set _git_version [git --version]} err]} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "git-gui: fatal error"] \
+ -message "Cannot determine Git version:
+
+$err
+
+[appname] requires Git 1.5.0 or later."
+ exit 1
+}
+if {![regsub {^git version } $_git_version {} _git_version]} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "git-gui: fatal error"] \
+ -message [strcat [mc "Cannot parse Git version string:"] "\n\n$_git_version"]
+ exit 1
+}
+
+proc get_trimmed_version {s} {
+ set r {}
+ foreach x [split $s -._] {
+ if {[string is integer -strict $x]} {
+ lappend r $x
+ } else {
+ break
+ }
+ }
+ return [join $r .]
+}
+set _real_git_version $_git_version
+set _git_version [get_trimmed_version $_git_version]
+
+if {![regexp {^[1-9]+(\.[0-9]+)+$} $_git_version]} {
+ catch {wm withdraw .}
+ if {[tk_messageBox \
+ -icon warning \
+ -type yesno \
+ -default no \
+ -title "[appname]: warning" \
+ -message [mc "Git version cannot be determined.
+
+%s claims it is version '%s'.
+
+%s requires at least Git 1.5.0 or later.
+
+Assume '%s' is version 1.5.0?
+" $_git $_real_git_version [appname] $_real_git_version]] eq {yes}} {
+ set _git_version 1.5.0
+ } else {
+ exit 1
+ }
+}
+unset _real_git_version
+
+proc git-version {args} {
+ global _git_version
+
+ switch [llength $args] {
+ 0 {
+ return $_git_version
+ }
+
+ 2 {
+ set op [lindex $args 0]
+ set vr [lindex $args 1]
+ set cm [package vcompare $_git_version $vr]
+ return [expr $cm $op 0]
+ }
+
+ 4 {
+ set type [lindex $args 0]
+ set name [lindex $args 1]
+ set parm [lindex $args 2]
+ set body [lindex $args 3]
+
+ if {($type ne {proc} && $type ne {method})} {
+ error "Invalid arguments to git-version"
+ }
+ if {[llength $body] < 2 || [lindex $body end-1] ne {default}} {
+ error "Last arm of $type $name must be default"
+ }
+
+ foreach {op vr cb} [lrange $body 0 end-2] {
+ if {[git-version $op $vr]} {
+ return [uplevel [list $type $name $parm $cb]]
+ }
+ }
+
+ return [uplevel [list $type $name $parm [lindex $body end]]]
+ }
+
+ default {
+ error "git-version >= x"
+ }
+
+ }
+}
+
+if {[git-version < 1.5]} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "git-gui: fatal error"] \
+ -message "[appname] requires Git 1.5.0 or later.
+
+You are using [git-version]:
+
+[git --version]"
+ exit 1
+}
+
+######################################################################
+##
+## configure our library
+
+set idx [file join $oguilib tclIndex]
+if {[catch {set fd [open $idx r]} err]} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "git-gui: fatal error"] \
+ -message $err
+ exit 1
+}
+if {[gets $fd] eq {# Autogenerated by git-gui Makefile}} {
+ set idx [list]
+ while {[gets $fd n] >= 0} {
+ if {$n ne {} && ![string match #* $n]} {
+ lappend idx $n
+ }
+ }
+} else {
+ set idx {}
+}
+close $fd
+
+if {$idx ne {}} {
+ set loaded [list]
+ foreach p $idx {
+ if {[lsearch -exact $loaded $p] >= 0} continue
+ source [file join $oguilib $p]
+ lappend loaded $p
+ }
+ unset loaded p
+} else {
+ set auto_path [concat [list $oguilib] $auto_path]
+}
+unset -nocomplain idx fd
+
+######################################################################
+##
+## config file parsing
+
+git-version proc _parse_config {arr_name args} {
+ >= 1.5.3 {
+ upvar $arr_name arr
+ array unset arr
+ set buf {}
+ catch {
+ set fd_rc [eval \
+ [list git_read config] \
+ $args \
+ [list --null --list]]
- [encoding convertfrom $p] \
++ fconfigure $fd_rc -translation binary -encoding utf-8
+ set buf [read $fd_rc]
+ close $fd_rc
+ }
+ foreach line [split $buf "\0"] {
+ if {[regexp {^([^\n]+)\n(.*)$} $line line name value]} {
+ if {[is_many_config $name]} {
+ lappend arr($name) $value
+ } else {
+ set arr($name) $value
+ }
+ } elseif {[regexp {^([^\n]+)$} $line line name]} {
+ # no value given, but interpreting them as
+ # boolean will be handled as true
+ set arr($name) {}
+ }
+ }
+ }
+ default {
+ upvar $arr_name arr
+ array unset arr
+ catch {
+ set fd_rc [eval [list git_read config --list] $args]
+ while {[gets $fd_rc line] >= 0} {
+ if {[regexp {^([^=]+)=(.*)$} $line line name value]} {
+ if {[is_many_config $name]} {
+ lappend arr($name) $value
+ } else {
+ set arr($name) $value
+ }
+ } elseif {[regexp {^([^=]+)$} $line line name]} {
+ # no value given, but interpreting them as
+ # boolean will be handled as true
+ set arr($name) {}
+ }
+ }
+ close $fd_rc
+ }
+ }
+}
+
+proc load_config {include_global} {
+ global repo_config global_config system_config default_config
+
+ if {$include_global} {
+ _parse_config system_config --system
+ _parse_config global_config --global
+ }
+ _parse_config repo_config
+
+ foreach name [array names default_config] {
+ if {[catch {set v $system_config($name)}]} {
+ set system_config($name) $default_config($name)
+ }
+ }
+ foreach name [array names system_config] {
+ if {[catch {set v $global_config($name)}]} {
+ set global_config($name) $system_config($name)
+ }
+ if {[catch {set v $repo_config($name)}]} {
+ set repo_config($name) $system_config($name)
+ }
+ }
+}
+
+######################################################################
+##
+## feature option selection
+
+if {[regexp {^git-(.+)$} [file tail $argv0] _junk subcommand]} {
+ unset _junk
+} else {
+ set subcommand gui
+}
+if {$subcommand eq {gui.sh}} {
+ set subcommand gui
+}
+if {$subcommand eq {gui} && [llength $argv] > 0} {
+ set subcommand [lindex $argv 0]
+ set argv [lrange $argv 1 end]
+}
+
+enable_option multicommit
+enable_option branch
+enable_option transport
+disable_option bare
+
+switch -- $subcommand {
+browser -
+blame {
+ enable_option bare
+
+ disable_option multicommit
+ disable_option branch
+ disable_option transport
+}
+citool {
+ enable_option singlecommit
+ enable_option retcode
+
+ disable_option multicommit
+ disable_option branch
+ disable_option transport
+
+ while {[llength $argv] > 0} {
+ set a [lindex $argv 0]
+ switch -- $a {
+ --amend {
+ enable_option initialamend
+ }
+ --nocommit {
+ enable_option nocommit
+ enable_option nocommitmsg
+ }
+ --commitmsg {
+ disable_option nocommitmsg
+ }
+ default {
+ break
+ }
+ }
+
+ set argv [lrange $argv 1 end]
+ }
+}
+}
+
+######################################################################
+##
+## execution environment
+
+set have_tk85 [expr {[package vcompare $tk_version "8.5"] >= 0}]
+
+# Suggest our implementation of askpass, if none is set
+if {![info exists env(SSH_ASKPASS)]} {
+ set env(SSH_ASKPASS) [gitexec git-gui--askpass]
+}
+
+######################################################################
+##
+## repository setup
+
+set picked 0
+if {[catch {
+ set _gitdir $env(GIT_DIR)
+ set _prefix {}
+ }]
+ && [catch {
+ # beware that from the .git dir this sets _gitdir to .
+ # and _prefix to the empty string
+ set _gitdir [git rev-parse --git-dir]
+ set _prefix [git rev-parse --show-prefix]
+ } err]} {
+ load_config 1
+ apply_config
+ choose_repository::pick
+ set picked 1
+}
+
+# we expand the _gitdir when it's just a single dot (i.e. when we're being
+# run from the .git dir itself) lest the routines to find the worktree
+# get confused
+if {$_gitdir eq "."} {
+ set _gitdir [pwd]
+}
+
+if {![file isdirectory $_gitdir] && [is_Cygwin]} {
+ catch {set _gitdir [exec cygpath --windows $_gitdir]}
+}
+if {![file isdirectory $_gitdir]} {
+ catch {wm withdraw .}
+ error_popup [strcat [mc "Git directory not found:"] "\n\n$_gitdir"]
+ exit 1
+}
+# _gitdir exists, so try loading the config
+load_config 0
+apply_config
+
+# v1.7.0 introduced --show-toplevel to return the canonical work-tree
+if {[package vcompare $_git_version 1.7.0] >= 0} {
+ if { [is_Cygwin] } {
+ catch {set _gitworktree [exec cygpath --windows [git rev-parse --show-toplevel]]}
+ } else {
+ set _gitworktree [git rev-parse --show-toplevel]
+ }
+} else {
+ # try to set work tree from environment, core.worktree or use
+ # cdup to obtain a relative path to the top of the worktree. If
+ # run from the top, the ./ prefix ensures normalize expands pwd.
+ if {[catch { set _gitworktree $env(GIT_WORK_TREE) }]} {
+ set _gitworktree [get_config core.worktree]
+ if {$_gitworktree eq ""} {
+ set _gitworktree [file normalize ./[git rev-parse --show-cdup]]
+ }
+ }
+}
+
+if {$_prefix ne {}} {
+ if {$_gitworktree eq {}} {
+ regsub -all {[^/]+/} $_prefix ../ cdup
+ } else {
+ set cdup $_gitworktree
+ }
+ if {[catch {cd $cdup} err]} {
+ catch {wm withdraw .}
+ error_popup [strcat [mc "Cannot move to top of working directory:"] "\n\n$err"]
+ exit 1
+ }
+ set _gitworktree [pwd]
+ unset cdup
+} elseif {![is_enabled bare]} {
+ if {[is_bare]} {
+ catch {wm withdraw .}
+ error_popup [strcat [mc "Cannot use bare repository:"] "\n\n$_gitdir"]
+ exit 1
+ }
+ if {$_gitworktree eq {}} {
+ set _gitworktree [file dirname $_gitdir]
+ }
+ if {[catch {cd $_gitworktree} err]} {
+ catch {wm withdraw .}
+ error_popup [strcat [mc "No working directory"] " $_gitworktree:\n\n$err"]
+ exit 1
+ }
+ set _gitworktree [pwd]
+}
+set _reponame [file split [file normalize $_gitdir]]
+if {[lindex $_reponame end] eq {.git}} {
+ set _reponame [lindex $_reponame end-1]
+} else {
+ set _reponame [lindex $_reponame end]
+}
+
+set env(GIT_DIR) $_gitdir
+set env(GIT_WORK_TREE) $_gitworktree
+
+######################################################################
+##
+## global init
+
+set current_diff_path {}
+set current_diff_side {}
+set diff_actions [list]
+
+set HEAD {}
+set PARENT {}
+set MERGE_HEAD [list]
+set commit_type {}
+set empty_tree {}
+set current_branch {}
+set is_detached 0
+set current_diff_path {}
+set is_3way_diff 0
+set is_submodule_diff 0
+set is_conflict_diff 0
+set selected_commit_type new
+set diff_empty_count 0
+
+set nullid "0000000000000000000000000000000000000000"
+set nullid2 "0000000000000000000000000000000000000001"
+
+######################################################################
+##
+## task management
+
+set rescan_active 0
+set diff_active 0
+set last_clicked {}
+
+set disable_on_lock [list]
+set index_lock_type none
+
+proc lock_index {type} {
+ global index_lock_type disable_on_lock
+
+ if {$index_lock_type eq {none}} {
+ set index_lock_type $type
+ foreach w $disable_on_lock {
+ uplevel #0 $w disabled
+ }
+ return 1
+ } elseif {$index_lock_type eq "begin-$type"} {
+ set index_lock_type $type
+ return 1
+ }
+ return 0
+}
+
+proc unlock_index {} {
+ global index_lock_type disable_on_lock
+
+ set index_lock_type none
+ foreach w $disable_on_lock {
+ uplevel #0 $w normal
+ }
+}
+
+######################################################################
+##
+## status
+
+proc repository_state {ctvar hdvar mhvar} {
+ global current_branch
+ upvar $ctvar ct $hdvar hd $mhvar mh
+
+ set mh [list]
+
+ load_current_branch
+ if {[catch {set hd [git rev-parse --verify HEAD]}]} {
+ set hd {}
+ set ct initial
+ return
+ }
+
+ set merge_head [gitdir MERGE_HEAD]
+ if {[file exists $merge_head]} {
+ set ct merge
+ set fd_mh [open $merge_head r]
+ while {[gets $fd_mh line] >= 0} {
+ lappend mh $line
+ }
+ close $fd_mh
+ return
+ }
+
+ set ct normal
+}
+
+proc PARENT {} {
+ global PARENT empty_tree
+
+ set p [lindex $PARENT 0]
+ if {$p ne {}} {
+ return $p
+ }
+ if {$empty_tree eq {}} {
+ set empty_tree [git mktree << {}]
+ }
+ return $empty_tree
+}
+
+proc force_amend {} {
+ global selected_commit_type
+ global HEAD PARENT MERGE_HEAD commit_type
+
+ repository_state newType newHEAD newMERGE_HEAD
+ set HEAD $newHEAD
+ set PARENT $newHEAD
+ set MERGE_HEAD $newMERGE_HEAD
+ set commit_type $newType
+
+ set selected_commit_type amend
+ do_select_commit_type
+}
+
+proc rescan {after {honor_trustmtime 1}} {
+ global HEAD PARENT MERGE_HEAD commit_type
+ global ui_index ui_workdir ui_comm
+ global rescan_active file_states
+ global repo_config
+
+ if {$rescan_active > 0 || ![lock_index read]} return
+
+ repository_state newType newHEAD newMERGE_HEAD
+ if {[string match amend* $commit_type]
+ && $newType eq {normal}
+ && $newHEAD eq $HEAD} {
+ } else {
+ set HEAD $newHEAD
+ set PARENT $newHEAD
+ set MERGE_HEAD $newMERGE_HEAD
+ set commit_type $newType
+ }
+
+ array unset file_states
+
+ if {!$::GITGUI_BCK_exists &&
+ (![$ui_comm edit modified]
+ || [string trim [$ui_comm get 0.0 end]] eq {})} {
+ if {[string match amend* $commit_type]} {
+ } elseif {[load_message GITGUI_MSG utf-8]} {
+ } elseif {[run_prepare_commit_msg_hook]} {
+ } elseif {[load_message MERGE_MSG]} {
+ } elseif {[load_message SQUASH_MSG]} {
+ }
+ $ui_comm edit reset
+ $ui_comm edit modified false
+ }
+
+ if {$honor_trustmtime && $repo_config(gui.trustmtime) eq {true}} {
+ rescan_stage2 {} $after
+ } else {
+ set rescan_active 1
+ ui_status [mc "Refreshing file status..."]
+ set fd_rf [git_read update-index \
+ -q \
+ --unmerged \
+ --ignore-missing \
+ --refresh \
+ ]
+ fconfigure $fd_rf -blocking 0 -translation binary
+ fileevent $fd_rf readable \
+ [list rescan_stage2 $fd_rf $after]
+ }
+}
+
+if {[is_Cygwin]} {
+ set is_git_info_exclude {}
+ proc have_info_exclude {} {
+ global is_git_info_exclude
+
+ if {$is_git_info_exclude eq {}} {
+ if {[catch {exec test -f [gitdir info exclude]}]} {
+ set is_git_info_exclude 0
+ } else {
+ set is_git_info_exclude 1
+ }
+ }
+ return $is_git_info_exclude
+ }
+} else {
+ proc have_info_exclude {} {
+ return [file readable [gitdir info exclude]]
+ }
+}
+
+proc rescan_stage2 {fd after} {
+ global rescan_active buf_rdi buf_rdf buf_rlo
+
+ if {$fd ne {}} {
+ read $fd
+ if {![eof $fd]} return
+ close $fd
+ }
+
+ if {[package vcompare $::_git_version 1.6.3] >= 0} {
+ set ls_others [list --exclude-standard]
+ } else {
+ set ls_others [list --exclude-per-directory=.gitignore]
+ if {[have_info_exclude]} {
+ lappend ls_others "--exclude-from=[gitdir info exclude]"
+ }
+ set user_exclude [get_config core.excludesfile]
+ if {$user_exclude ne {} && [file readable $user_exclude]} {
+ lappend ls_others "--exclude-from=[file normalize $user_exclude]"
+ }
+ }
+
+ set buf_rdi {}
+ set buf_rdf {}
+ set buf_rlo {}
+
+ set rescan_active 2
+ ui_status [mc "Scanning for modified files ..."]
+ if {[git-version >= "1.7.2"]} {
+ set fd_di [git_read diff-index --cached --ignore-submodules=dirty -z [PARENT]]
+ } else {
+ set fd_di [git_read diff-index --cached -z [PARENT]]
+ }
+ set fd_df [git_read diff-files -z]
+
+ fconfigure $fd_di -blocking 0 -translation binary -encoding binary
+ fconfigure $fd_df -blocking 0 -translation binary -encoding binary
+
+ fileevent $fd_di readable [list read_diff_index $fd_di $after]
+ fileevent $fd_df readable [list read_diff_files $fd_df $after]
+
+ if {[is_config_true gui.displayuntracked]} {
+ set fd_lo [eval git_read ls-files --others -z $ls_others]
+ fconfigure $fd_lo -blocking 0 -translation binary -encoding binary
+ fileevent $fd_lo readable [list read_ls_others $fd_lo $after]
+ incr rescan_active
+ }
+}
+
+proc load_message {file {encoding {}}} {
+ global ui_comm
+
+ set f [gitdir $file]
+ if {[file isfile $f]} {
+ if {[catch {set fd [open $f r]}]} {
+ return 0
+ }
+ fconfigure $fd -eofchar {}
+ if {$encoding ne {}} {
+ fconfigure $fd -encoding $encoding
+ }
+ set content [string trim [read $fd]]
+ close $fd
+ regsub -all -line {[ \r\t]+$} $content {} content
+ $ui_comm delete 0.0 end
+ $ui_comm insert end $content
+ return 1
+ }
+ return 0
+}
+
+proc run_prepare_commit_msg_hook {} {
+ global pch_error
+
+ # prepare-commit-msg requires PREPARE_COMMIT_MSG exist. From git-gui
+ # it will be .git/MERGE_MSG (merge), .git/SQUASH_MSG (squash), or an
+ # empty file but existent file.
+
+ set fd_pcm [open [gitdir PREPARE_COMMIT_MSG] a]
+
+ if {[file isfile [gitdir MERGE_MSG]]} {
+ set pcm_source "merge"
+ set fd_mm [open [gitdir MERGE_MSG] r]
++ fconfigure $fd_mm -encoding utf-8
+ puts -nonewline $fd_pcm [read $fd_mm]
+ close $fd_mm
+ } elseif {[file isfile [gitdir SQUASH_MSG]]} {
+ set pcm_source "squash"
+ set fd_sm [open [gitdir SQUASH_MSG] r]
++ fconfigure $fd_sm -encoding utf-8
+ puts -nonewline $fd_pcm [read $fd_sm]
+ close $fd_sm
+ } else {
+ set pcm_source ""
+ }
+
+ close $fd_pcm
+
+ set fd_ph [githook_read prepare-commit-msg \
+ [gitdir PREPARE_COMMIT_MSG] $pcm_source]
+ if {$fd_ph eq {}} {
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ return 0;
+ }
+
+ ui_status [mc "Calling prepare-commit-msg hook..."]
+ set pch_error {}
+
+ fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
+ fileevent $fd_ph readable \
+ [list prepare_commit_msg_hook_wait $fd_ph]
+
+ return 1;
+}
+
+proc prepare_commit_msg_hook_wait {fd_ph} {
+ global pch_error
+
+ append pch_error [read $fd_ph]
+ fconfigure $fd_ph -blocking 1
+ if {[eof $fd_ph]} {
+ if {[catch {close $fd_ph}]} {
+ ui_status [mc "Commit declined by prepare-commit-msg hook."]
+ hook_failed_popup prepare-commit-msg $pch_error
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ exit 1
+ } else {
+ load_message PREPARE_COMMIT_MSG
+ }
+ set pch_error {}
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+ return
+ }
+ fconfigure $fd_ph -blocking 0
+ catch {file delete [gitdir PREPARE_COMMIT_MSG]}
+}
+
+proc read_diff_index {fd after} {
+ global buf_rdi
+
+ append buf_rdi [read $fd]
+ set c 0
+ set n [string length $buf_rdi]
+ while {$c < $n} {
+ set z1 [string first "\0" $buf_rdi $c]
+ if {$z1 == -1} break
+ incr z1
+ set z2 [string first "\0" $buf_rdi $z1]
+ if {$z2 == -1} break
+
+ incr c
+ set i [split [string range $buf_rdi $c [expr {$z1 - 2}]] { }]
+ set p [string range $buf_rdi $z1 [expr {$z2 - 1}]]
+ merge_state \
- [encoding convertfrom $p] \
++ [encoding convertfrom utf-8 $p] \
+ [lindex $i 4]? \
+ [list [lindex $i 0] [lindex $i 2]] \
+ [list]
+ set c $z2
+ incr c
+ }
+ if {$c < $n} {
+ set buf_rdi [string range $buf_rdi $c end]
+ } else {
+ set buf_rdi {}
+ }
+
+ rescan_done $fd buf_rdi $after
+}
+
+proc read_diff_files {fd after} {
+ global buf_rdf
+
+ append buf_rdf [read $fd]
+ set c 0
+ set n [string length $buf_rdf]
+ while {$c < $n} {
+ set z1 [string first "\0" $buf_rdf $c]
+ if {$z1 == -1} break
+ incr z1
+ set z2 [string first "\0" $buf_rdf $z1]
+ if {$z2 == -1} break
+
+ incr c
+ set i [split [string range $buf_rdf $c [expr {$z1 - 2}]] { }]
+ set p [string range $buf_rdf $z1 [expr {$z2 - 1}]]
+ merge_state \
- set p [encoding convertfrom $p]
++ [encoding convertfrom utf-8 $p] \
+ ?[lindex $i 4] \
+ [list] \
+ [list [lindex $i 0] [lindex $i 2]]
+ set c $z2
+ incr c
+ }
+ if {$c < $n} {
+ set buf_rdf [string range $buf_rdf $c end]
+ } else {
+ set buf_rdf {}
+ }
+
+ rescan_done $fd buf_rdf $after
+}
+
+proc read_ls_others {fd after} {
+ global buf_rlo
+
+ append buf_rlo [read $fd]
+ set pck [split $buf_rlo "\0"]
+ set buf_rlo [lindex $pck end]
+ foreach p [lrange $pck 0 end-1] {
- proc toggle_or_diff {w x y} {
++ set p [encoding convertfrom utf-8 $p]
+ if {[string index $p end] eq {/}} {
+ set p [string range $p 0 end-1]
+ }
+ merge_state $p ?O
+ }
+ rescan_done $fd buf_rlo $after
+}
+
+proc rescan_done {fd buf after} {
+ global rescan_active current_diff_path
+ global file_states repo_config
+ upvar $buf to_clear
+
+ if {![eof $fd]} return
+ set to_clear {}
+ close $fd
+ if {[incr rescan_active -1] > 0} return
+
+ prune_selection
+ unlock_index
+ display_all_files
+ if {$current_diff_path ne {}} { reshow_diff $after }
+ if {$current_diff_path eq {}} { select_first_diff $after }
+}
+
+proc prune_selection {} {
+ global file_states selected_paths
+
+ foreach path [array names selected_paths] {
+ if {[catch {set still_here $file_states($path)}]} {
+ unset selected_paths($path)
+ }
+ }
+}
+
+######################################################################
+##
+## ui helpers
+
+proc mapicon {w state path} {
+ global all_icons
+
+ if {[catch {set r $all_icons($state$w)}]} {
+ puts "error: no icon for $w state={$state} $path"
+ return file_plain
+ }
+ return $r
+}
+
+proc mapdesc {state path} {
+ global all_descs
+
+ if {[catch {set r $all_descs($state)}]} {
+ puts "error: no desc for state={$state} $path"
+ return $state
+ }
+ return $r
+}
+
+proc ui_status {msg} {
+ global main_status
+ if {[info exists main_status]} {
+ $main_status show $msg
+ }
+}
+
+proc ui_ready {{test {}}} {
+ global main_status
+ if {[info exists main_status]} {
+ $main_status show [mc "Ready."] $test
+ }
+}
+
+proc escape_path {path} {
+ regsub -all {\\} $path "\\\\" path
+ regsub -all "\n" $path "\\n" path
+ return $path
+}
+
+proc short_path {path} {
+ return [escape_path [lindex [file split $path] end]]
+}
+
+set next_icon_id 0
+set null_sha1 [string repeat 0 40]
+
+proc merge_state {path new_state {head_info {}} {index_info {}}} {
+ global file_states next_icon_id null_sha1
+
+ set s0 [string index $new_state 0]
+ set s1 [string index $new_state 1]
+
+ if {[catch {set info $file_states($path)}]} {
+ set state __
+ set icon n[incr next_icon_id]
+ } else {
+ set state [lindex $info 0]
+ set icon [lindex $info 1]
+ if {$head_info eq {}} {set head_info [lindex $info 2]}
+ if {$index_info eq {}} {set index_info [lindex $info 3]}
+ }
+
+ if {$s0 eq {?}} {set s0 [string index $state 0]} \
+ elseif {$s0 eq {_}} {set s0 _}
+
+ if {$s1 eq {?}} {set s1 [string index $state 1]} \
+ elseif {$s1 eq {_}} {set s1 _}
+
+ if {$s0 eq {A} && $s1 eq {_} && $head_info eq {}} {
+ set head_info [list 0 $null_sha1]
+ } elseif {$s0 ne {_} && [string index $state 0] eq {_}
+ && $head_info eq {}} {
+ set head_info $index_info
+ } elseif {$s0 eq {_} && [string index $state 0] ne {_}} {
+ set index_info $head_info
+ set head_info {}
+ }
+
+ set file_states($path) [list $s0$s1 $icon \
+ $head_info $index_info \
+ ]
+ return $state
+}
+
+proc display_file_helper {w path icon_name old_m new_m} {
+ global file_lists
+
+ if {$new_m eq {_}} {
+ set lno [lsearch -sorted -exact $file_lists($w) $path]
+ if {$lno >= 0} {
+ set file_lists($w) [lreplace $file_lists($w) $lno $lno]
+ incr lno
+ $w conf -state normal
+ $w delete $lno.0 [expr {$lno + 1}].0
+ $w conf -state disabled
+ }
+ } elseif {$old_m eq {_} && $new_m ne {_}} {
+ lappend file_lists($w) $path
+ set file_lists($w) [lsort -unique $file_lists($w)]
+ set lno [lsearch -sorted -exact $file_lists($w) $path]
+ incr lno
+ $w conf -state normal
+ $w image create $lno.0 \
+ -align center -padx 5 -pady 1 \
+ -name $icon_name \
+ -image [mapicon $w $new_m $path]
+ $w insert $lno.1 "[escape_path $path]\n"
+ $w conf -state disabled
+ } elseif {$old_m ne $new_m} {
+ $w conf -state normal
+ $w image conf $icon_name -image [mapicon $w $new_m $path]
+ $w conf -state disabled
+ }
+}
+
+proc display_file {path state} {
+ global file_states selected_paths
+ global ui_index ui_workdir
+
+ set old_m [merge_state $path $state]
+ set s $file_states($path)
+ set new_m [lindex $s 0]
+ set icon_name [lindex $s 1]
+
+ set o [string index $old_m 0]
+ set n [string index $new_m 0]
+ if {$o eq {U}} {
+ set o _
+ }
+ if {$n eq {U}} {
+ set n _
+ }
+ display_file_helper $ui_index $path $icon_name $o $n
+
+ if {[string index $old_m 0] eq {U}} {
+ set o U
+ } else {
+ set o [string index $old_m 1]
+ }
+ if {[string index $new_m 0] eq {U}} {
+ set n U
+ } else {
+ set n [string index $new_m 1]
+ }
+ display_file_helper $ui_workdir $path $icon_name $o $n
+
+ if {$new_m eq {__}} {
+ unset file_states($path)
+ catch {unset selected_paths($path)}
+ }
+}
+
+proc display_all_files_helper {w path icon_name m} {
+ global file_lists
+
+ lappend file_lists($w) $path
+ set lno [expr {[lindex [split [$w index end] .] 0] - 1}]
+ $w image create end \
+ -align center -padx 5 -pady 1 \
+ -name $icon_name \
+ -image [mapicon $w $m $path]
+ $w insert end "[escape_path $path]\n"
+}
+
+set files_warning 0
+proc display_all_files {} {
+ global ui_index ui_workdir
+ global file_states file_lists
+ global last_clicked
+ global files_warning
+
+ $ui_index conf -state normal
+ $ui_workdir conf -state normal
+
+ $ui_index delete 0.0 end
+ $ui_workdir delete 0.0 end
+ set last_clicked {}
+
+ set file_lists($ui_index) [list]
+ set file_lists($ui_workdir) [list]
+
+ set to_display [lsort [array names file_states]]
+ set display_limit [get_config gui.maxfilesdisplayed]
+ set displayed 0
+ foreach path $to_display {
+ set s $file_states($path)
+ set m [lindex $s 0]
+ set icon_name [lindex $s 1]
+
+ if {$displayed > $display_limit && [string index $m 1] eq {O} } {
+ if {!$files_warning} {
+ # do not repeatedly warn:
+ set files_warning 1
+ info_popup [mc "Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s files." \
+ $display_limit [llength $to_display]]
+ }
+ continue
+ }
+
+ set s [string index $m 0]
+ if {$s ne {U} && $s ne {_}} {
+ display_all_files_helper $ui_index $path \
+ $icon_name $s
+ }
+
+ if {[string index $m 0] eq {U}} {
+ set s U
+ } else {
+ set s [string index $m 1]
+ }
+ if {$s ne {_}} {
+ display_all_files_helper $ui_workdir $path \
+ $icon_name $s
+ incr displayed
+ }
+ }
+
+ $ui_index conf -state disabled
+ $ui_workdir conf -state disabled
+}
+
+######################################################################
+##
+## icons
+
+set filemask {
+#define mask_width 14
+#define mask_height 15
+static unsigned char mask_bits[] = {
+ 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
+ 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f,
+ 0xfe, 0x1f, 0xfe, 0x1f, 0xfe, 0x1f};
+}
+
+image create bitmap file_plain -background white -foreground black -data {
+#define plain_width 14
+#define plain_height 15
+static unsigned char plain_bits[] = {
+ 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
+ 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10, 0x02, 0x10,
+ 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+image create bitmap file_mod -background white -foreground blue -data {
+#define mod_width 14
+#define mod_height 15
+static unsigned char mod_bits[] = {
+ 0xfe, 0x01, 0x02, 0x03, 0x7a, 0x05, 0x02, 0x09, 0x7a, 0x1f, 0x02, 0x10,
+ 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
+ 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+image create bitmap file_fulltick -background white -foreground "#007000" -data {
+#define file_fulltick_width 14
+#define file_fulltick_height 15
+static unsigned char file_fulltick_bits[] = {
+ 0xfe, 0x01, 0x02, 0x1a, 0x02, 0x0c, 0x02, 0x0c, 0x02, 0x16, 0x02, 0x16,
+ 0x02, 0x13, 0x00, 0x13, 0x86, 0x11, 0x8c, 0x11, 0xd8, 0x10, 0xf2, 0x10,
+ 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+image create bitmap file_question -background white -foreground black -data {
+#define file_question_width 14
+#define file_question_height 15
+static unsigned char file_question_bits[] = {
+ 0xfe, 0x01, 0x02, 0x02, 0xe2, 0x04, 0xf2, 0x09, 0x1a, 0x1b, 0x0a, 0x13,
+ 0x82, 0x11, 0xc2, 0x10, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10, 0x62, 0x10,
+ 0x62, 0x10, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+image create bitmap file_removed -background white -foreground red -data {
+#define file_removed_width 14
+#define file_removed_height 15
+static unsigned char file_removed_bits[] = {
+ 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x02, 0x10,
+ 0x1a, 0x16, 0x32, 0x13, 0xe2, 0x11, 0xc2, 0x10, 0xe2, 0x11, 0x32, 0x13,
+ 0x1a, 0x16, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+image create bitmap file_merge -background white -foreground blue -data {
+#define file_merge_width 14
+#define file_merge_height 15
+static unsigned char file_merge_bits[] = {
+ 0xfe, 0x01, 0x02, 0x03, 0x62, 0x05, 0x62, 0x09, 0x62, 0x1f, 0x62, 0x10,
+ 0xfa, 0x11, 0xf2, 0x10, 0x62, 0x10, 0x02, 0x10, 0xfa, 0x17, 0x02, 0x10,
+ 0xfa, 0x17, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+image create bitmap file_statechange -background white -foreground green -data {
+#define file_statechange_width 14
+#define file_statechange_height 15
+static unsigned char file_statechange_bits[] = {
+ 0xfe, 0x01, 0x02, 0x03, 0x02, 0x05, 0x02, 0x09, 0x02, 0x1f, 0x62, 0x10,
+ 0x62, 0x10, 0xba, 0x11, 0xba, 0x11, 0x62, 0x10, 0x62, 0x10, 0x02, 0x10,
+ 0x02, 0x10, 0x02, 0x10, 0xfe, 0x1f};
+} -maskdata $filemask
+
+set ui_index .vpane.files.index.list
+set ui_workdir .vpane.files.workdir.list
+
+set all_icons(_$ui_index) file_plain
+set all_icons(A$ui_index) file_plain
+set all_icons(M$ui_index) file_fulltick
+set all_icons(D$ui_index) file_removed
+set all_icons(U$ui_index) file_merge
+set all_icons(T$ui_index) file_statechange
+
+set all_icons(_$ui_workdir) file_plain
+set all_icons(M$ui_workdir) file_mod
+set all_icons(D$ui_workdir) file_question
+set all_icons(U$ui_workdir) file_merge
+set all_icons(O$ui_workdir) file_plain
+set all_icons(T$ui_workdir) file_statechange
+
+set max_status_desc 0
+foreach i {
+ {__ {mc "Unmodified"}}
+
+ {_M {mc "Modified, not staged"}}
+ {M_ {mc "Staged for commit"}}
+ {MM {mc "Portions staged for commit"}}
+ {MD {mc "Staged for commit, missing"}}
+
+ {_T {mc "File type changed, not staged"}}
+ {MT {mc "File type changed, old type staged for commit"}}
+ {AT {mc "File type changed, old type staged for commit"}}
+ {T_ {mc "File type changed, staged"}}
+ {TM {mc "File type change staged, modification not staged"}}
+ {TD {mc "File type change staged, file missing"}}
+
+ {_O {mc "Untracked, not staged"}}
+ {A_ {mc "Staged for commit"}}
+ {AM {mc "Portions staged for commit"}}
+ {AD {mc "Staged for commit, missing"}}
+
+ {_D {mc "Missing"}}
+ {D_ {mc "Staged for removal"}}
+ {DO {mc "Staged for removal, still present"}}
+
+ {_U {mc "Requires merge resolution"}}
+ {U_ {mc "Requires merge resolution"}}
+ {UU {mc "Requires merge resolution"}}
+ {UM {mc "Requires merge resolution"}}
+ {UD {mc "Requires merge resolution"}}
+ {UT {mc "Requires merge resolution"}}
+ } {
+ set text [eval [lindex $i 1]]
+ if {$max_status_desc < [string length $text]} {
+ set max_status_desc [string length $text]
+ }
+ set all_descs([lindex $i 0]) $text
+}
+unset i
+
+######################################################################
+##
+## util
+
+proc scrollbar2many {list mode args} {
+ foreach w $list {eval $w $mode $args}
+}
+
+proc many2scrollbar {list mode sb top bottom} {
+ $sb set $top $bottom
+ foreach w $list {$w $mode moveto $top}
+}
+
+proc incr_font_size {font {amt 1}} {
+ set sz [font configure $font -size]
+ incr sz $amt
+ font configure $font -size $sz
+ font configure ${font}bold -size $sz
+ font configure ${font}italic -size $sz
+}
+
+######################################################################
+##
+## ui commands
+
+set starting_gitk_msg [mc "Starting gitk... please wait..."]
+
+proc do_gitk {revs {is_submodule false}} {
+ global current_diff_path file_states current_diff_side ui_index
+ global _gitdir _gitworktree
+
+ # -- Always start gitk through whatever we were loaded with. This
+ # lets us bypass using shell process on Windows systems.
+ #
+ set exe [_which gitk -script]
+ set cmd [list [info nameofexecutable] $exe]
+ if {$exe eq {}} {
+ error_popup [mc "Couldn't find gitk in PATH"]
+ } else {
+ global env
+
+ set pwd [pwd]
+
+ if {!$is_submodule} {
+ if {![is_bare]} {
+ cd $_gitworktree
+ }
+ } else {
+ cd $current_diff_path
+ if {$revs eq {--}} {
+ set s $file_states($current_diff_path)
+ set old_sha1 {}
+ set new_sha1 {}
+ switch -glob -- [lindex $s 0] {
+ M_ { set old_sha1 [lindex [lindex $s 2] 1] }
+ _M { set old_sha1 [lindex [lindex $s 3] 1] }
+ MM {
+ if {$current_diff_side eq $ui_index} {
+ set old_sha1 [lindex [lindex $s 2] 1]
+ set new_sha1 [lindex [lindex $s 3] 1]
+ } else {
+ set old_sha1 [lindex [lindex $s 3] 1]
+ }
+ }
+ }
+ set revs $old_sha1...$new_sha1
+ }
+ # GIT_DIR and GIT_WORK_TREE for the submodule are not the ones
+ # we've been using for the main repository, so unset them.
+ # TODO we could make life easier (start up faster?) for gitk
+ # by setting these to the appropriate values to allow gitk
+ # to skip the heuristics to find their proper value
+ unset env(GIT_DIR)
+ unset env(GIT_WORK_TREE)
+ }
+ eval exec $cmd $revs "--" "--" &
+
+ set env(GIT_DIR) $_gitdir
+ set env(GIT_WORK_TREE) $_gitworktree
+ cd $pwd
+
+ ui_status $::starting_gitk_msg
+ after 10000 {
+ ui_ready $starting_gitk_msg
+ }
+ }
+}
+
+proc do_git_gui {} {
+ global current_diff_path
+
+ # -- Always start git gui through whatever we were loaded with. This
+ # lets us bypass using shell process on Windows systems.
+ #
+ set exe [list [_which git]]
+ if {$exe eq {}} {
+ error_popup [mc "Couldn't find git gui in PATH"]
+ } else {
+ global env
+ global _gitdir _gitworktree
+
+ # see note in do_gitk about unsetting these vars when
+ # running tools in a submodule
+ unset env(GIT_DIR)
+ unset env(GIT_WORK_TREE)
+
+ set pwd [pwd]
+ cd $current_diff_path
+
+ eval exec $exe gui &
+
+ set env(GIT_DIR) $_gitdir
+ set env(GIT_WORK_TREE) $_gitworktree
+ cd $pwd
+
+ ui_status $::starting_gitk_msg
+ after 10000 {
+ ui_ready $starting_gitk_msg
+ }
+ }
+}
+
+proc do_explore {} {
+ global _gitworktree
+ set explorer {}
+ if {[is_Cygwin] || [is_Windows]} {
+ set explorer "explorer.exe"
+ } elseif {[is_MacOSX]} {
+ set explorer "open"
+ } else {
+ # freedesktop.org-conforming system is our best shot
+ set explorer "xdg-open"
+ }
+ eval exec $explorer [list [file nativename $_gitworktree]] &
+}
+
+set is_quitting 0
+set ret_code 1
+
+proc terminate_me {win} {
+ global ret_code
+ if {$win ne {.}} return
+ exit $ret_code
+}
+
+proc do_quit {{rc {1}}} {
+ global ui_comm is_quitting repo_config commit_type
+ global GITGUI_BCK_exists GITGUI_BCK_i
+ global ui_comm_spell
+ global ret_code use_ttk
+
+ if {$is_quitting} return
+ set is_quitting 1
+
+ if {[winfo exists $ui_comm]} {
+ # -- Stash our current commit buffer.
+ #
+ set save [gitdir GITGUI_MSG]
+ if {$GITGUI_BCK_exists && ![$ui_comm edit modified]} {
+ file rename -force [gitdir GITGUI_BCK] $save
+ set GITGUI_BCK_exists 0
+ } else {
+ set msg [string trim [$ui_comm get 0.0 end]]
+ regsub -all -line {[ \r\t]+$} $msg {} msg
+ if {(![string match amend* $commit_type]
+ || [$ui_comm edit modified])
+ && $msg ne {}} {
+ catch {
+ set fd [open $save w]
+ fconfigure $fd -encoding utf-8
+ puts -nonewline $fd $msg
+ close $fd
+ }
+ } else {
+ catch {file delete $save}
+ }
+ }
+
+ # -- Cancel our spellchecker if its running.
+ #
+ if {[info exists ui_comm_spell]} {
+ $ui_comm_spell stop
+ }
+
+ # -- Remove our editor backup, its not needed.
+ #
+ after cancel $GITGUI_BCK_i
+ if {$GITGUI_BCK_exists} {
+ catch {file delete [gitdir GITGUI_BCK]}
+ }
+
+ # -- Stash our current window geometry into this repository.
+ #
+ set cfg_wmstate [wm state .]
+ if {[catch {set rc_wmstate $repo_config(gui.wmstate)}]} {
+ set rc_wmstate {}
+ }
+ if {$cfg_wmstate ne $rc_wmstate} {
+ catch {git config gui.wmstate $cfg_wmstate}
+ }
+ if {$cfg_wmstate eq {zoomed}} {
+ # on Windows wm geometry will lie about window
+ # position (but not size) when window is zoomed
+ # restore the window before querying wm geometry
+ wm state . normal
+ }
+ set cfg_geometry [list]
+ lappend cfg_geometry [wm geometry .]
+ if {$use_ttk} {
+ lappend cfg_geometry [.vpane sashpos 0]
+ lappend cfg_geometry [.vpane.files sashpos 0]
+ } else {
+ lappend cfg_geometry [lindex [.vpane sash coord 0] 0]
+ lappend cfg_geometry [lindex [.vpane.files sash coord 0] 1]
+ }
+ if {[catch {set rc_geometry $repo_config(gui.geometry)}]} {
+ set rc_geometry {}
+ }
+ if {$cfg_geometry ne $rc_geometry} {
+ catch {git config gui.geometry $cfg_geometry}
+ }
+ }
+
+ set ret_code $rc
+
+ # Briefly enable send again, working around Tk bug
+ # http://sourceforge.net/tracker/?func=detail&atid=112997&aid=1821174&group_id=12997
+ tk appname [appname]
+
+ destroy .
+}
+
+proc do_rescan {} {
+ rescan ui_ready
+}
+
+proc ui_do_rescan {} {
+ rescan {force_first_diff ui_ready}
+}
+
+proc do_commit {} {
+ commit_tree
+}
+
+proc next_diff {{after {}}} {
+ global next_diff_p next_diff_w next_diff_i
+ show_diff $next_diff_p $next_diff_w {} {} $after
+}
+
+proc find_anchor_pos {lst name} {
+ set lid [lsearch -sorted -exact $lst $name]
+
+ if {$lid == -1} {
+ set lid 0
+ foreach lname $lst {
+ if {$lname >= $name} break
+ incr lid
+ }
+ }
+
+ return $lid
+}
+
+proc find_file_from {flist idx delta path mmask} {
+ global file_states
+
+ set len [llength $flist]
+ while {$idx >= 0 && $idx < $len} {
+ set name [lindex $flist $idx]
+
+ if {$name ne $path && [info exists file_states($name)]} {
+ set state [lindex $file_states($name) 0]
+
+ if {$mmask eq {} || [regexp $mmask $state]} {
+ return $idx
+ }
+ }
+
+ incr idx $delta
+ }
+
+ return {}
+}
+
+proc find_next_diff {w path {lno {}} {mmask {}}} {
+ global next_diff_p next_diff_w next_diff_i
+ global file_lists ui_index ui_workdir
+
+ set flist $file_lists($w)
+ if {$lno eq {}} {
+ set lno [find_anchor_pos $flist $path]
+ } else {
+ incr lno -1
+ }
+
+ if {$mmask ne {} && ![regexp {(^\^)|(\$$)} $mmask]} {
+ if {$w eq $ui_index} {
+ set mmask "^$mmask"
+ } else {
+ set mmask "$mmask\$"
+ }
+ }
+
+ set idx [find_file_from $flist $lno 1 $path $mmask]
+ if {$idx eq {}} {
+ incr lno -1
+ set idx [find_file_from $flist $lno -1 $path $mmask]
+ }
+
+ if {$idx ne {}} {
+ set next_diff_w $w
+ set next_diff_p [lindex $flist $idx]
+ set next_diff_i [expr {$idx+1}]
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc next_diff_after_action {w path {lno {}} {mmask {}}} {
+ global current_diff_path
+
+ if {$path ne $current_diff_path} {
+ return {}
+ } elseif {[find_next_diff $w $path $lno $mmask]} {
+ return {next_diff;}
+ } else {
+ return {reshow_diff;}
+ }
+}
+
+proc select_first_diff {after} {
+ global ui_workdir
+
+ if {[find_next_diff $ui_workdir {} 1 {^_?U}] ||
+ [find_next_diff $ui_workdir {} 1 {[^O]$}]} {
+ next_diff $after
+ } else {
+ uplevel #0 $after
+ }
+}
+
+proc force_first_diff {after} {
+ global ui_workdir current_diff_path file_states
+
+ if {[info exists file_states($current_diff_path)]} {
+ set state [lindex $file_states($current_diff_path) 0]
+ } else {
+ set state {OO}
+ }
+
+ set reselect 0
+ if {[string first {U} $state] >= 0} {
+ # Already a conflict, do nothing
+ } elseif {[find_next_diff $ui_workdir $current_diff_path {} {^_?U}]} {
+ set reselect 1
+ } elseif {[string index $state 1] ne {O}} {
+ # Already a diff & no conflicts, do nothing
+ } elseif {[find_next_diff $ui_workdir $current_diff_path {} {[^O]$}]} {
+ set reselect 1
+ }
+
+ if {$reselect} {
+ next_diff $after
+ } else {
+ uplevel #0 $after
+ }
+}
+
- set pos [split [$w index @$x,$y] .]
- set lno [lindex $pos 0]
- set col [lindex $pos 1]
++proc toggle_or_diff {mode w args} {
+ global file_states file_lists current_diff_path ui_index ui_workdir
+ global last_clicked selected_paths
+
- toggle_or_diff $w $x $y
++ if {$mode eq "click"} {
++ foreach {x y} $args break
++ set pos [split [$w index @$x,$y] .]
++ foreach {lno col} $pos break
++ } else {
++ if {$last_clicked ne {}} {
++ set lno [lindex $last_clicked 1]
++ } else {
++ set lno [expr {int([lindex [$w tag ranges in_diff] 0])}]
++ }
++ if {$mode eq "toggle"} {
++ set col 0; set y 2
++ } else {
++ incr lno [expr {$mode eq "up" ? -1 : 1}]
++ set col 1
++ }
++ }
++
+ set path [lindex $file_lists($w) [expr {$lno - 1}]]
+ if {$path eq {}} {
+ set last_clicked {}
+ return
+ }
+
+ set last_clicked [list $w $lno]
++ focus $w
+ array unset selected_paths
+ $ui_index tag remove in_sel 0.0 end
+ $ui_workdir tag remove in_sel 0.0 end
+
+ # Determine the state of the file
+ if {[info exists file_states($path)]} {
+ set state [lindex $file_states($path) 0]
+ } else {
+ set state {__}
+ }
+
+ # Restage the file, or simply show the diff
+ if {$col == 0 && $y > 1} {
+ # Conflicts need special handling
+ if {[string first {U} $state] >= 0} {
+ # $w must always be $ui_workdir, but...
+ if {$w ne $ui_workdir} { set lno {} }
+ merge_stage_workdir $path $lno
+ return
+ }
+
+ if {[string index $state 1] eq {O}} {
+ set mmask {}
+ } else {
+ set mmask {[^O]}
+ }
+
+ set after [next_diff_after_action $w $path $lno $mmask]
+
+ if {$w eq $ui_index} {
+ update_indexinfo \
+ "Unstaging [short_path $path] from commit" \
+ [list $path] \
+ [concat $after [list ui_ready]]
+ } elseif {$w eq $ui_workdir} {
+ update_index \
+ "Adding [short_path $path]" \
+ [list $path] \
+ [concat $after [list ui_ready]]
+ }
+ } else {
+ set selected_paths($path) 1
+ show_diff $path $w $lno
+ }
+}
+
+proc add_one_to_selection {w x y} {
+ global file_lists last_clicked selected_paths
+
+ set lno [lindex [split [$w index @$x,$y] .] 0]
+ set path [lindex $file_lists($w) [expr {$lno - 1}]]
+ if {$path eq {}} {
+ set last_clicked {}
+ return
+ }
+
+ if {$last_clicked ne {}
+ && [lindex $last_clicked 0] ne $w} {
+ array unset selected_paths
+ [lindex $last_clicked 0] tag remove in_sel 0.0 end
+ }
+
+ set last_clicked [list $w $lno]
+ if {[catch {set in_sel $selected_paths($path)}]} {
+ set in_sel 0
+ }
+ if {$in_sel} {
+ unset selected_paths($path)
+ $w tag remove in_sel $lno.0 [expr {$lno + 1}].0
+ } else {
+ set selected_paths($path) 1
+ $w tag add in_sel $lno.0 [expr {$lno + 1}].0
+ }
+}
+
+proc add_range_to_selection {w x y} {
+ global file_lists last_clicked selected_paths
+
+ if {[lindex $last_clicked 0] ne $w} {
- set s "usage: $::argv0 $::subcommand $::subcommand_args"
++ toggle_or_diff click $w $x $y
+ return
+ }
+
+ set lno [lindex [split [$w index @$x,$y] .] 0]
+ set lc [lindex $last_clicked 1]
+ if {$lc < $lno} {
+ set begin $lc
+ set end $lno
+ } else {
+ set begin $lno
+ set end $lc
+ }
+
+ foreach path [lrange $file_lists($w) \
+ [expr {$begin - 1}] \
+ [expr {$end - 1}]] {
+ set selected_paths($path) 1
+ }
+ $w tag add in_sel $begin.0 [expr {$end + 1}].0
+}
+
+proc show_more_context {} {
+ global repo_config
+ if {$repo_config(gui.diffcontext) < 99} {
+ incr repo_config(gui.diffcontext)
+ reshow_diff
+ }
+}
+
+proc show_less_context {} {
+ global repo_config
+ if {$repo_config(gui.diffcontext) > 1} {
+ incr repo_config(gui.diffcontext) -1
+ reshow_diff
+ }
+}
+
+######################################################################
+##
+## ui construction
+
+set ui_comm {}
+
+# -- Menu Bar
+#
+menu .mbar -tearoff 0
+if {[is_MacOSX]} {
+ # -- Apple Menu (Mac OS X only)
+ #
+ .mbar add cascade -label Apple -menu .mbar.apple
+ menu .mbar.apple
+}
+.mbar add cascade -label [mc Repository] -menu .mbar.repository
+.mbar add cascade -label [mc Edit] -menu .mbar.edit
+if {[is_enabled branch]} {
+ .mbar add cascade -label [mc Branch] -menu .mbar.branch
+}
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+ .mbar add cascade -label [mc Commit@@noun] -menu .mbar.commit
+}
+if {[is_enabled transport]} {
+ .mbar add cascade -label [mc Merge] -menu .mbar.merge
+ .mbar add cascade -label [mc Remote] -menu .mbar.remote
+}
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+ .mbar add cascade -label [mc Tools] -menu .mbar.tools
+}
+
+# -- Repository Menu
+#
+menu .mbar.repository
+
+if {![is_bare]} {
+ .mbar.repository add command \
+ -label [mc "Explore Working Copy"] \
+ -command {do_explore}
+}
+
+if {[is_Windows]} {
+ .mbar.repository add command \
+ -label [mc "Git Bash"] \
+ -command {eval exec [auto_execok start] \
+ [list "Git Bash" bash --login -l &]}
+}
+
+if {[is_Windows] || ![is_bare]} {
+ .mbar.repository add separator
+}
+
+.mbar.repository add command \
+ -label [mc "Browse Current Branch's Files"] \
+ -command {browser::new $current_branch}
+set ui_browse_current [.mbar.repository index last]
+.mbar.repository add command \
+ -label [mc "Browse Branch Files..."] \
+ -command browser_open::dialog
+.mbar.repository add separator
+
+.mbar.repository add command \
+ -label [mc "Visualize Current Branch's History"] \
+ -command {do_gitk $current_branch}
+set ui_visualize_current [.mbar.repository index last]
+.mbar.repository add command \
+ -label [mc "Visualize All Branch History"] \
+ -command {do_gitk --all}
+.mbar.repository add separator
+
+proc current_branch_write {args} {
+ global current_branch
+ .mbar.repository entryconf $::ui_browse_current \
+ -label [mc "Browse %s's Files" $current_branch]
+ .mbar.repository entryconf $::ui_visualize_current \
+ -label [mc "Visualize %s's History" $current_branch]
+}
+trace add variable current_branch write current_branch_write
+
+if {[is_enabled multicommit]} {
+ .mbar.repository add command -label [mc "Database Statistics"] \
+ -command do_stats
+
+ .mbar.repository add command -label [mc "Compress Database"] \
+ -command do_gc
+
+ .mbar.repository add command -label [mc "Verify Database"] \
+ -command do_fsck_objects
+
+ .mbar.repository add separator
+
+ if {[is_Cygwin]} {
+ .mbar.repository add command \
+ -label [mc "Create Desktop Icon"] \
+ -command do_cygwin_shortcut
+ } elseif {[is_Windows]} {
+ .mbar.repository add command \
+ -label [mc "Create Desktop Icon"] \
+ -command do_windows_shortcut
+ } elseif {[is_MacOSX]} {
+ .mbar.repository add command \
+ -label [mc "Create Desktop Icon"] \
+ -command do_macosx_app
+ }
+}
+
+if {[is_MacOSX]} {
+ proc ::tk::mac::Quit {args} { do_quit }
+} else {
+ .mbar.repository add command -label [mc Quit] \
+ -command do_quit \
+ -accelerator $M1T-Q
+}
+
+# -- Edit Menu
+#
+menu .mbar.edit
+.mbar.edit add command -label [mc Undo] \
+ -command {catch {[focus] edit undo}} \
+ -accelerator $M1T-Z
+.mbar.edit add command -label [mc Redo] \
+ -command {catch {[focus] edit redo}} \
+ -accelerator $M1T-Y
+.mbar.edit add separator
+.mbar.edit add command -label [mc Cut] \
+ -command {catch {tk_textCut [focus]}} \
+ -accelerator $M1T-X
+.mbar.edit add command -label [mc Copy] \
+ -command {catch {tk_textCopy [focus]}} \
+ -accelerator $M1T-C
+.mbar.edit add command -label [mc Paste] \
+ -command {catch {tk_textPaste [focus]; [focus] see insert}} \
+ -accelerator $M1T-V
+.mbar.edit add command -label [mc Delete] \
+ -command {catch {[focus] delete sel.first sel.last}} \
+ -accelerator Del
+.mbar.edit add separator
+.mbar.edit add command -label [mc "Select All"] \
+ -command {catch {[focus] tag add sel 0.0 end}} \
+ -accelerator $M1T-A
+
+# -- Branch Menu
+#
+if {[is_enabled branch]} {
+ menu .mbar.branch
+
+ .mbar.branch add command -label [mc "Create..."] \
+ -command branch_create::dialog \
+ -accelerator $M1T-N
+ lappend disable_on_lock [list .mbar.branch entryconf \
+ [.mbar.branch index last] -state]
+
+ .mbar.branch add command -label [mc "Checkout..."] \
+ -command branch_checkout::dialog \
+ -accelerator $M1T-O
+ lappend disable_on_lock [list .mbar.branch entryconf \
+ [.mbar.branch index last] -state]
+
+ .mbar.branch add command -label [mc "Rename..."] \
+ -command branch_rename::dialog
+ lappend disable_on_lock [list .mbar.branch entryconf \
+ [.mbar.branch index last] -state]
+
+ .mbar.branch add command -label [mc "Delete..."] \
+ -command branch_delete::dialog
+ lappend disable_on_lock [list .mbar.branch entryconf \
+ [.mbar.branch index last] -state]
+
+ .mbar.branch add command -label [mc "Reset..."] \
+ -command merge::reset_hard
+ lappend disable_on_lock [list .mbar.branch entryconf \
+ [.mbar.branch index last] -state]
+}
+
+# -- Commit Menu
+#
+proc commit_btn_caption {} {
+ if {[is_enabled nocommit]} {
+ return [mc "Done"]
+ } else {
+ return [mc Commit@@verb]
+ }
+}
+
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+ menu .mbar.commit
+
+ if {![is_enabled nocommit]} {
+ .mbar.commit add radiobutton \
+ -label [mc "New Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value new
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add radiobutton \
+ -label [mc "Amend Last Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value amend
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add separator
+ }
+
+ .mbar.commit add command -label [mc Rescan] \
+ -command ui_do_rescan \
+ -accelerator F5
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add command -label [mc "Stage To Commit"] \
+ -command do_add_selection \
+ -accelerator $M1T-T
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add command -label [mc "Stage Changed Files To Commit"] \
+ -command do_add_all \
+ -accelerator $M1T-I
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add command -label [mc "Unstage From Commit"] \
+ -command do_unstage_selection \
+ -accelerator $M1T-U
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add command -label [mc "Revert Changes"] \
+ -command do_revert_selection \
+ -accelerator $M1T-J
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+
+ .mbar.commit add separator
+
+ .mbar.commit add command -label [mc "Show Less Context"] \
+ -command show_less_context \
+ -accelerator $M1T-\-
+
+ .mbar.commit add command -label [mc "Show More Context"] \
+ -command show_more_context \
+ -accelerator $M1T-=
+
+ .mbar.commit add separator
+
+ if {![is_enabled nocommitmsg]} {
+ .mbar.commit add command -label [mc "Sign Off"] \
+ -command do_signoff \
+ -accelerator $M1T-S
+ }
+
+ .mbar.commit add command -label [commit_btn_caption] \
+ -command do_commit \
+ -accelerator $M1T-Return
+ lappend disable_on_lock \
+ [list .mbar.commit entryconf [.mbar.commit index last] -state]
+}
+
+# -- Merge Menu
+#
+if {[is_enabled branch]} {
+ menu .mbar.merge
+ .mbar.merge add command -label [mc "Local Merge..."] \
+ -command merge::dialog \
+ -accelerator $M1T-M
+ lappend disable_on_lock \
+ [list .mbar.merge entryconf [.mbar.merge index last] -state]
+ .mbar.merge add command -label [mc "Abort Merge..."] \
+ -command merge::reset_hard
+ lappend disable_on_lock \
+ [list .mbar.merge entryconf [.mbar.merge index last] -state]
+}
+
+# -- Transport Menu
+#
+if {[is_enabled transport]} {
+ menu .mbar.remote
+
+ .mbar.remote add command \
+ -label [mc "Add..."] \
+ -command remote_add::dialog \
+ -accelerator $M1T-A
+ .mbar.remote add command \
+ -label [mc "Push..."] \
+ -command do_push_anywhere \
+ -accelerator $M1T-P
+ .mbar.remote add command \
+ -label [mc "Delete Branch..."] \
+ -command remote_branch_delete::dialog
+}
+
+if {[is_MacOSX]} {
+ proc ::tk::mac::ShowPreferences {} {do_options}
+} else {
+ # -- Edit Menu
+ #
+ .mbar.edit add separator
+ .mbar.edit add command -label [mc "Options..."] \
+ -command do_options
+}
+
+# -- Tools Menu
+#
+if {[is_enabled multicommit] || [is_enabled singlecommit]} {
+ set tools_menubar .mbar.tools
+ menu $tools_menubar
+ $tools_menubar add separator
+ $tools_menubar add command -label [mc "Add..."] -command tools_add::dialog
+ $tools_menubar add command -label [mc "Remove..."] -command tools_remove::dialog
+ set tools_tailcnt 3
+ if {[array names repo_config guitool.*.cmd] ne {}} {
+ tools_populate_all
+ }
+}
+
+# -- Help Menu
+#
+.mbar add cascade -label [mc Help] -menu .mbar.help
+menu .mbar.help
+
+if {[is_MacOSX]} {
+ .mbar.apple add command -label [mc "About %s" [appname]] \
+ -command do_about
+ .mbar.apple add separator
+} else {
+ .mbar.help add command -label [mc "About %s" [appname]] \
+ -command do_about
+}
+. configure -menu .mbar
+
+set doc_path [githtmldir]
+if {$doc_path ne {}} {
+ set doc_path [file join $doc_path index.html]
+
+ if {[is_Cygwin]} {
+ set doc_path [exec cygpath --mixed $doc_path]
+ }
+}
+
+if {[file isfile $doc_path]} {
+ set doc_url "file:$doc_path"
+} else {
+ set doc_url {http://www.kernel.org/pub/software/scm/git/docs/}
+}
+
+proc start_browser {url} {
+ git "web--browse" $url
+}
+
+.mbar.help add command -label [mc "Online Documentation"] \
+ -command [list start_browser $doc_url]
+
+.mbar.help add command -label [mc "Show SSH Key"] \
+ -command do_ssh_key
+
+unset doc_path doc_url
+
+# -- Standard bindings
+#
+wm protocol . WM_DELETE_WINDOW do_quit
+bind all <$M1B-Key-q> do_quit
+bind all <$M1B-Key-Q> do_quit
+bind all <$M1B-Key-w> {destroy [winfo toplevel %W]}
+bind all <$M1B-Key-W> {destroy [winfo toplevel %W]}
+
+set subcommand_args {}
+proc usage {} {
- set err "usage: $argv0 \[{blame|browser|citool}\]"
++ set s "[mc usage:] $::argv0 $::subcommand $::subcommand_args"
+ if {[tk windowingsystem] eq "win32"} {
+ wm withdraw .
+ tk_messageBox -icon info -message $s \
+ -title [mc "Usage"]
+ } else {
+ puts stderr $s
+ }
+ exit 1
+}
+
+proc normalize_relpath {path} {
+ set elements {}
+ foreach item [file split $path] {
+ if {$item eq {.}} continue
+ if {$item eq {..} && [llength $elements] > 0
+ && [lindex $elements end] ne {..}} {
+ set elements [lrange $elements 0 end-1]
+ continue
+ }
+ lappend elements $item
+ }
+ return [eval file join $elements]
+}
+
+# -- Not a normal commit type invocation? Do that instead!
+#
+switch -- $subcommand {
+browser -
+blame {
+ if {$subcommand eq "blame"} {
+ set subcommand_args {[--line=<num>] rev? path}
+ } else {
+ set subcommand_args {rev? path}
+ }
+ if {$argv eq {}} usage
+ set head {}
+ set path {}
+ set jump_spec {}
+ set is_path 0
+ foreach a $argv {
+ set p [file join $_prefix $a]
+
+ if {$is_path || [file exists $p]} {
+ if {$path ne {}} usage
+ set path [normalize_relpath $p]
+ break
+ } elseif {$a eq {--}} {
+ if {$path ne {}} {
+ if {$head ne {}} usage
+ set head $path
+ set path {}
+ }
+ set is_path 1
+ } elseif {[regexp {^--line=(\d+)$} $a a lnum]} {
+ if {$jump_spec ne {} || $head ne {}} usage
+ set jump_spec [list $lnum]
+ } elseif {$head eq {}} {
+ if {$head ne {}} usage
+ set head $a
+ set is_path 1
+ } else {
+ usage
+ }
+ }
+ unset is_path
+
+ if {$head ne {} && $path eq {}} {
+ if {[string index $head 0] eq {/}} {
+ set path [normalize_relpath $head]
+ set head {}
+ } else {
+ set path [normalize_relpath $_prefix$head]
+ set head {}
+ }
+ }
+
+ if {$head eq {}} {
+ load_current_branch
+ } else {
+ if {[regexp {^[0-9a-f]{1,39}$} $head]} {
+ if {[catch {
+ set head [git rev-parse --verify $head]
+ } err]} {
+ if {[tk windowingsystem] eq "win32"} {
+ tk_messageBox -icon error -title [mc Error] -message $err
+ } else {
+ puts stderr $err
+ }
+ exit 1
+ }
+ }
+ set current_branch $head
+ }
+
+ wm deiconify .
+ switch -- $subcommand {
+ browser {
+ if {$jump_spec ne {}} usage
+ if {$head eq {}} {
+ if {$path ne {} && [file isdirectory $path]} {
+ set head $current_branch
+ } else {
+ set head $path
+ set path {}
+ }
+ }
+ browser::new $head $path
+ }
+ blame {
+ if {$head eq {} && ![file exists $path]} {
+ catch {wm withdraw .}
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "git-gui: fatal error"] \
+ -message [mc "fatal: cannot stat path %s: No such file or directory" $path]
+ exit 1
+ }
+ blame::new $head $path $jump_spec
+ }
+ }
+ return
+}
+citool -
+gui {
+ if {[llength $argv] != 0} {
+ usage
+ }
+ # fall through to setup UI for commits
+}
+default {
- ${NS}::frame .vpane.files.index -height 100 -width 200
++ set err "[mc usage:] $argv0 \[{blame|browser|citool}\]"
+ if {[tk windowingsystem] eq "win32"} {
+ wm withdraw .
+ tk_messageBox -icon error -message $err \
+ -title [mc "Usage"]
+ } else {
+ puts stderr $err
+ }
+ exit 1
+}
+}
+
+# -- Branch Control
+#
+${NS}::frame .branch
+if {!$use_ttk} {.branch configure -borderwidth 1 -relief sunken}
+${NS}::label .branch.l1 \
+ -text [mc "Current Branch:"] \
+ -anchor w \
+ -justify left
+${NS}::label .branch.cb \
+ -textvariable current_branch \
+ -anchor w \
+ -justify left
+pack .branch.l1 -side left
+pack .branch.cb -side left -fill x
+pack .branch -side top -fill x
+
+# -- Main Window Layout
+#
+${NS}::panedwindow .vpane -orient horizontal
+${NS}::panedwindow .vpane.files -orient vertical
+if {$use_ttk} {
+ .vpane add .vpane.files
+} else {
+ .vpane add .vpane.files -sticky nsew -height 100 -width 200
+}
+pack .vpane -anchor n -side top -fill both -expand 1
+
++# -- Working Directory File List
++
++textframe .vpane.files.workdir -height 100 -width 200
++tlabel .vpane.files.workdir.title -text [mc "Unstaged Changes"] \
++ -background lightsalmon -foreground black
++ttext $ui_workdir -background white -foreground black \
++ -borderwidth 0 \
++ -width 20 -height 10 \
++ -wrap none \
++ -takefocus 1 -highlightthickness 1\
++ -cursor $cursor_ptr \
++ -xscrollcommand {.vpane.files.workdir.sx set} \
++ -yscrollcommand {.vpane.files.workdir.sy set} \
++ -state disabled
++${NS}::scrollbar .vpane.files.workdir.sx -orient h -command [list $ui_workdir xview]
++${NS}::scrollbar .vpane.files.workdir.sy -orient v -command [list $ui_workdir yview]
++pack .vpane.files.workdir.title -side top -fill x
++pack .vpane.files.workdir.sx -side bottom -fill x
++pack .vpane.files.workdir.sy -side right -fill y
++pack $ui_workdir -side left -fill both -expand 1
++
+# -- Index File List
+#
- text $ui_index -background white -foreground black \
++textframe .vpane.files.index -height 100 -width 200
+tlabel .vpane.files.index.title \
+ -text [mc "Staged Changes (Will Commit)"] \
+ -background lightgreen -foreground black
- # -- Working Directory File List
++ttext $ui_index -background white -foreground black \
+ -borderwidth 0 \
+ -width 20 -height 10 \
+ -wrap none \
++ -takefocus 1 -highlightthickness 1\
+ -cursor $cursor_ptr \
+ -xscrollcommand {.vpane.files.index.sx set} \
+ -yscrollcommand {.vpane.files.index.sy set} \
+ -state disabled
+${NS}::scrollbar .vpane.files.index.sx -orient h -command [list $ui_index xview]
+${NS}::scrollbar .vpane.files.index.sy -orient v -command [list $ui_index yview]
+pack .vpane.files.index.title -side top -fill x
+pack .vpane.files.index.sx -side bottom -fill x
+pack .vpane.files.index.sy -side right -fill y
+pack $ui_index -side left -fill both -expand 1
+
- ${NS}::frame .vpane.files.workdir -height 100 -width 200
- tlabel .vpane.files.workdir.title -text [mc "Unstaged Changes"] \
- -background lightsalmon -foreground black
- text $ui_workdir -background white -foreground black \
- -borderwidth 0 \
- -width 20 -height 10 \
- -wrap none \
- -cursor $cursor_ptr \
- -xscrollcommand {.vpane.files.workdir.sx set} \
- -yscrollcommand {.vpane.files.workdir.sy set} \
- -state disabled
- ${NS}::scrollbar .vpane.files.workdir.sx -orient h -command [list $ui_workdir xview]
- ${NS}::scrollbar .vpane.files.workdir.sy -orient v -command [list $ui_workdir yview]
- pack .vpane.files.workdir.title -side top -fill x
- pack .vpane.files.workdir.sx -side bottom -fill x
- pack .vpane.files.workdir.sy -side right -fill y
- pack $ui_workdir -side left -fill both -expand 1
-
++# -- Insert the workdir and index into the panes
+#
- set ui_comm .vpane.lower.commarea.buffer.t
+.vpane.files add .vpane.files.workdir
+.vpane.files add .vpane.files.index
+if {!$use_ttk} {
+ .vpane.files paneconfigure .vpane.files.workdir -sticky news
+ .vpane.files paneconfigure .vpane.files.index -sticky news
+}
+
+foreach i [list $ui_index $ui_workdir] {
+ rmsel_tag $i
+ $i tag conf in_diff -background [$i tag cget in_sel -background]
+}
+unset i
+
+# -- Diff and Commit Area
+#
+if {$have_tk85} {
+ ${NS}::panedwindow .vpane.lower -orient vertical
+ ${NS}::frame .vpane.lower.commarea
+ ${NS}::frame .vpane.lower.diff -relief sunken -borderwidth 1 -height 500
+ .vpane.lower add .vpane.lower.diff
+ .vpane.lower add .vpane.lower.commarea
+ .vpane add .vpane.lower
+ if {$use_ttk} {
+ .vpane.lower pane .vpane.lower.diff -weight 1
+ .vpane.lower pane .vpane.lower.commarea -weight 0
+ } else {
+ .vpane.lower paneconfigure .vpane.lower.diff -stretch always
+ .vpane.lower paneconfigure .vpane.lower.commarea -stretch never
+ }
+} else {
+ frame .vpane.lower -height 300 -width 400
+ frame .vpane.lower.commarea
+ frame .vpane.lower.diff -relief sunken -borderwidth 1
+ pack .vpane.lower.diff -fill both -expand 1
+ pack .vpane.lower.commarea -side bottom -fill x
+ .vpane add .vpane.lower
+ .vpane paneconfigure .vpane.lower -sticky nsew
+}
+
+# -- Commit Area Buttons
+#
+${NS}::frame .vpane.lower.commarea.buttons
+${NS}::label .vpane.lower.commarea.buttons.l -text {} \
+ -anchor w \
+ -justify left
+pack .vpane.lower.commarea.buttons.l -side top -fill x
+pack .vpane.lower.commarea.buttons -side left -fill y
+
+${NS}::button .vpane.lower.commarea.buttons.rescan -text [mc Rescan] \
+ -command ui_do_rescan
+pack .vpane.lower.commarea.buttons.rescan -side top -fill x
+lappend disable_on_lock \
+ {.vpane.lower.commarea.buttons.rescan conf -state}
+
+${NS}::button .vpane.lower.commarea.buttons.incall -text [mc "Stage Changed"] \
+ -command do_add_all
+pack .vpane.lower.commarea.buttons.incall -side top -fill x
+lappend disable_on_lock \
+ {.vpane.lower.commarea.buttons.incall conf -state}
+
+if {![is_enabled nocommitmsg]} {
+ ${NS}::button .vpane.lower.commarea.buttons.signoff -text [mc "Sign Off"] \
+ -command do_signoff
+ pack .vpane.lower.commarea.buttons.signoff -side top -fill x
+}
+
+${NS}::button .vpane.lower.commarea.buttons.commit -text [commit_btn_caption] \
+ -command do_commit
+pack .vpane.lower.commarea.buttons.commit -side top -fill x
+lappend disable_on_lock \
+ {.vpane.lower.commarea.buttons.commit conf -state}
+
+if {![is_enabled nocommit]} {
+ ${NS}::button .vpane.lower.commarea.buttons.push -text [mc Push] \
+ -command do_push_anywhere
+ pack .vpane.lower.commarea.buttons.push -side top -fill x
+}
+
+# -- Commit Message Buffer
+#
+${NS}::frame .vpane.lower.commarea.buffer
+${NS}::frame .vpane.lower.commarea.buffer.header
- text $ui_comm -background white -foreground black \
++set ui_comm .vpane.lower.commarea.buffer.frame.t
+set ui_coml .vpane.lower.commarea.buffer.header.l
+
+if {![is_enabled nocommit]} {
+ ${NS}::radiobutton .vpane.lower.commarea.buffer.header.new \
+ -text [mc "New Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value new
+ lappend disable_on_lock \
+ [list .vpane.lower.commarea.buffer.header.new conf -state]
+ ${NS}::radiobutton .vpane.lower.commarea.buffer.header.amend \
+ -text [mc "Amend Last Commit"] \
+ -command do_select_commit_type \
+ -variable selected_commit_type \
+ -value amend
+ lappend disable_on_lock \
+ [list .vpane.lower.commarea.buffer.header.amend conf -state]
+}
+
+${NS}::label $ui_coml \
+ -anchor w \
+ -justify left
+proc trace_commit_type {varname args} {
+ global ui_coml commit_type
+ switch -glob -- $commit_type {
+ initial {set txt [mc "Initial Commit Message:"]}
+ amend {set txt [mc "Amended Commit Message:"]}
+ amend-initial {set txt [mc "Amended Initial Commit Message:"]}
+ amend-merge {set txt [mc "Amended Merge Commit Message:"]}
+ merge {set txt [mc "Merge Commit Message:"]}
+ * {set txt [mc "Commit Message:"]}
+ }
+ $ui_coml conf -text $txt
+}
+trace add variable commit_type write trace_commit_type
+pack $ui_coml -side left -fill x
+
+if {![is_enabled nocommit]} {
+ pack .vpane.lower.commarea.buffer.header.amend -side right
+ pack .vpane.lower.commarea.buffer.header.new -side right
+}
+
- -yscrollcommand {.vpane.lower.commarea.buffer.sby set}
- ${NS}::scrollbar .vpane.lower.commarea.buffer.sby \
++textframe .vpane.lower.commarea.buffer.frame
++ttext $ui_comm -background white -foreground black \
+ -borderwidth 1 \
+ -undo true \
+ -maxundo 20 \
+ -autoseparators true \
++ -takefocus 1 \
++ -highlightthickness 1 \
+ -relief sunken \
+ -width $repo_config(gui.commitmsgwidth) -height 9 -wrap none \
+ -font font_diff \
- pack .vpane.lower.commarea.buffer.header -side top -fill x
- pack .vpane.lower.commarea.buffer.sby -side right -fill y
++ -yscrollcommand {.vpane.lower.commarea.buffer.frame.sby set}
++${NS}::scrollbar .vpane.lower.commarea.buffer.frame.sby \
+ -command [list $ui_comm yview]
- ${NS}::frame .vpane.lower.diff.body
++
++pack .vpane.lower.commarea.buffer.frame.sby -side right -fill y
+pack $ui_comm -side left -fill y
++pack .vpane.lower.commarea.buffer.header -side top -fill x
++pack .vpane.lower.commarea.buffer.frame -side left -fill y
+pack .vpane.lower.commarea.buffer -side left -fill y
+
+# -- Commit Message Buffer Context Menu
+#
+set ctxm .vpane.lower.commarea.buffer.ctxm
+menu $ctxm -tearoff 0
+$ctxm add command \
+ -label [mc Cut] \
+ -command {tk_textCut $ui_comm}
+$ctxm add command \
+ -label [mc Copy] \
+ -command {tk_textCopy $ui_comm}
+$ctxm add command \
+ -label [mc Paste] \
+ -command {tk_textPaste $ui_comm}
+$ctxm add command \
+ -label [mc Delete] \
+ -command {catch {$ui_comm delete sel.first sel.last}}
+$ctxm add separator
+$ctxm add command \
+ -label [mc "Select All"] \
+ -command {focus $ui_comm;$ui_comm tag add sel 0.0 end}
+$ctxm add command \
+ -label [mc "Copy All"] \
+ -command {
+ $ui_comm tag add sel 0.0 end
+ tk_textCopy $ui_comm
+ $ui_comm tag remove sel 0.0 end
+ }
+$ctxm add separator
+$ctxm add command \
+ -label [mc "Sign Off"] \
+ -command do_signoff
+set ui_comm_ctxm $ctxm
+
+# -- Diff Header
+#
+proc trace_current_diff_path {varname args} {
+ global current_diff_path diff_actions file_states
+ if {$current_diff_path eq {}} {
+ set s {}
+ set f {}
+ set p {}
+ set o disabled
+ } else {
+ set p $current_diff_path
+ set s [mapdesc [lindex $file_states($p) 0] $p]
+ set f [mc "File:"]
+ set p [escape_path $p]
+ set o normal
+ }
+
+ .vpane.lower.diff.header.status configure -text $s
+ .vpane.lower.diff.header.file configure -text $f
+ .vpane.lower.diff.header.path configure -text $p
+ foreach w $diff_actions {
+ uplevel #0 $w $o
+ }
+}
+trace add variable current_diff_path write trace_current_diff_path
+
+gold_frame .vpane.lower.diff.header
+tlabel .vpane.lower.diff.header.status \
+ -background gold \
+ -foreground black \
+ -width $max_status_desc \
+ -anchor w \
+ -justify left
+tlabel .vpane.lower.diff.header.file \
+ -background gold \
+ -foreground black \
+ -anchor w \
+ -justify left
+tlabel .vpane.lower.diff.header.path \
+ -background gold \
+ -foreground black \
+ -anchor w \
+ -justify left
+pack .vpane.lower.diff.header.status -side left
+pack .vpane.lower.diff.header.file -side left
+pack .vpane.lower.diff.header.path -fill x
+set ctxm .vpane.lower.diff.header.ctxm
+menu $ctxm -tearoff 0
+$ctxm add command \
+ -label [mc Copy] \
+ -command {
+ clipboard clear
+ clipboard append \
+ -format STRING \
+ -type STRING \
+ -- $current_diff_path
+ }
+lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+bind_button3 .vpane.lower.diff.header.path "tk_popup $ctxm %X %Y"
+
+# -- Diff Body
+#
- text $ui_diff -background white -foreground black \
++textframe .vpane.lower.diff.body
+set ui_diff .vpane.lower.diff.body.t
- bind . <$M1B-Key-t> do_add_selection
- bind . <$M1B-Key-T> do_add_selection
- bind . <$M1B-Key-u> do_unstage_selection
- bind . <$M1B-Key-U> do_unstage_selection
++ttext $ui_diff -background white -foreground black \
+ -borderwidth 0 \
+ -width 80 -height 5 -wrap none \
+ -font font_diff \
++ -takefocus 1 -highlightthickness 1 \
+ -xscrollcommand {.vpane.lower.diff.body.sbx set} \
+ -yscrollcommand {.vpane.lower.diff.body.sby set} \
+ -state disabled
+catch {$ui_diff configure -tabstyle wordprocessor}
+${NS}::scrollbar .vpane.lower.diff.body.sbx -orient horizontal \
+ -command [list $ui_diff xview]
+${NS}::scrollbar .vpane.lower.diff.body.sby -orient vertical \
+ -command [list $ui_diff yview]
+pack .vpane.lower.diff.body.sbx -side bottom -fill x
+pack .vpane.lower.diff.body.sby -side right -fill y
+pack $ui_diff -side left -fill both -expand 1
+pack .vpane.lower.diff.header -side top -fill x
+pack .vpane.lower.diff.body -side bottom -fill both -expand 1
+
+foreach {n c} {0 black 1 red4 2 green4 3 yellow4 4 blue4 5 magenta4 6 cyan4 7 grey60} {
+ $ui_diff tag configure clr4$n -background $c
+ $ui_diff tag configure clri4$n -foreground $c
+ $ui_diff tag configure clr3$n -foreground $c
+ $ui_diff tag configure clri3$n -background $c
+}
+$ui_diff tag configure clr1 -font font_diffbold
+$ui_diff tag configure clr4 -underline 1
+
+$ui_diff tag conf d_info -foreground blue -font font_diffbold
+
+$ui_diff tag conf d_cr -elide true
+$ui_diff tag conf d_@ -font font_diffbold
+$ui_diff tag conf d_+ -foreground {#00a000}
+$ui_diff tag conf d_- -foreground red
+
+$ui_diff tag conf d_++ -foreground {#00a000}
+$ui_diff tag conf d_-- -foreground red
+$ui_diff tag conf d_+s \
+ -foreground {#00a000} \
+ -background {#e2effa}
+$ui_diff tag conf d_-s \
+ -foreground red \
+ -background {#e2effa}
+$ui_diff tag conf d_s+ \
+ -foreground {#00a000} \
+ -background ivory1
+$ui_diff tag conf d_s- \
+ -foreground red \
+ -background ivory1
+
+$ui_diff tag conf d< \
+ -foreground orange \
+ -font font_diffbold
+$ui_diff tag conf d= \
+ -foreground orange \
+ -font font_diffbold
+$ui_diff tag conf d> \
+ -foreground orange \
+ -font font_diffbold
+
+$ui_diff tag raise sel
+
+# -- Diff Body Context Menu
+#
+
+proc create_common_diff_popup {ctxm} {
+ $ctxm add command \
+ -label [mc Refresh] \
+ -command reshow_diff
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add command \
+ -label [mc Copy] \
+ -command {tk_textCopy $ui_diff}
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add command \
+ -label [mc "Select All"] \
+ -command {focus $ui_diff;$ui_diff tag add sel 0.0 end}
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add command \
+ -label [mc "Copy All"] \
+ -command {
+ $ui_diff tag add sel 0.0 end
+ tk_textCopy $ui_diff
+ $ui_diff tag remove sel 0.0 end
+ }
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add separator
+ $ctxm add command \
+ -label [mc "Decrease Font Size"] \
+ -command {incr_font_size font_diff -1}
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add command \
+ -label [mc "Increase Font Size"] \
+ -command {incr_font_size font_diff 1}
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add separator
+ set emenu $ctxm.enc
+ menu $emenu
+ build_encoding_menu $emenu [list force_diff_encoding]
+ $ctxm add cascade \
+ -label [mc "Encoding"] \
+ -menu $emenu
+ lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+ $ctxm add separator
+ $ctxm add command -label [mc "Options..."] \
+ -command do_options
+}
+
+set ctxm .vpane.lower.diff.body.ctxm
+menu $ctxm -tearoff 0
+$ctxm add command \
+ -label [mc "Apply/Reverse Hunk"] \
+ -command {apply_hunk $cursorX $cursorY}
+set ui_diff_applyhunk [$ctxm index last]
+lappend diff_actions [list $ctxm entryconf $ui_diff_applyhunk -state]
+$ctxm add command \
+ -label [mc "Apply/Reverse Line"] \
+ -command {apply_range_or_line $cursorX $cursorY; do_rescan}
+set ui_diff_applyline [$ctxm index last]
+lappend diff_actions [list $ctxm entryconf $ui_diff_applyline -state]
+$ctxm add separator
+$ctxm add command \
+ -label [mc "Show Less Context"] \
+ -command show_less_context
+lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+$ctxm add command \
+ -label [mc "Show More Context"] \
+ -command show_more_context
+lappend diff_actions [list $ctxm entryconf [$ctxm index last] -state]
+$ctxm add separator
+create_common_diff_popup $ctxm
+
+set ctxmmg .vpane.lower.diff.body.ctxmmg
+menu $ctxmmg -tearoff 0
+$ctxmmg add command \
+ -label [mc "Run Merge Tool"] \
+ -command {merge_resolve_tool}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add separator
+$ctxmmg add command \
+ -label [mc "Use Remote Version"] \
+ -command {merge_resolve_one 3}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add command \
+ -label [mc "Use Local Version"] \
+ -command {merge_resolve_one 2}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add command \
+ -label [mc "Revert To Base"] \
+ -command {merge_resolve_one 1}
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add separator
+$ctxmmg add command \
+ -label [mc "Show Less Context"] \
+ -command show_less_context
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add command \
+ -label [mc "Show More Context"] \
+ -command show_more_context
+lappend diff_actions [list $ctxmmg entryconf [$ctxmmg index last] -state]
+$ctxmmg add separator
+create_common_diff_popup $ctxmmg
+
+set ctxmsm .vpane.lower.diff.body.ctxmsm
+menu $ctxmsm -tearoff 0
+$ctxmsm add command \
+ -label [mc "Visualize These Changes In The Submodule"] \
+ -command {do_gitk -- true}
+lappend diff_actions [list $ctxmsm entryconf [$ctxmsm index last] -state]
+$ctxmsm add command \
+ -label [mc "Visualize Current Branch History In The Submodule"] \
+ -command {do_gitk {} true}
+lappend diff_actions [list $ctxmsm entryconf [$ctxmsm index last] -state]
+$ctxmsm add command \
+ -label [mc "Visualize All Branch History In The Submodule"] \
+ -command {do_gitk --all true}
+lappend diff_actions [list $ctxmsm entryconf [$ctxmsm index last] -state]
+$ctxmsm add separator
+$ctxmsm add command \
+ -label [mc "Start git gui In The Submodule"] \
+ -command {do_git_gui}
+lappend diff_actions [list $ctxmsm entryconf [$ctxmsm index last] -state]
+$ctxmsm add separator
+create_common_diff_popup $ctxmsm
+
+proc has_textconv {path} {
+ if {[is_config_false gui.textconv]} {
+ return 0
+ }
+ set filter [gitattr $path diff set]
+ set textconv [get_config [join [list diff $filter textconv] .]]
+ if {$filter ne {set} && $textconv ne {}} {
+ return 1
+ } else {
+ return 0
+ }
+}
+
+proc popup_diff_menu {ctxm ctxmmg ctxmsm x y X Y} {
+ global current_diff_path file_states
+ set ::cursorX $x
+ set ::cursorY $y
+ if {[info exists file_states($current_diff_path)]} {
+ set state [lindex $file_states($current_diff_path) 0]
+ } else {
+ set state {__}
+ }
+ if {[string first {U} $state] >= 0} {
+ tk_popup $ctxmmg $X $Y
+ } elseif {$::is_submodule_diff} {
+ tk_popup $ctxmsm $X $Y
+ } else {
+ set has_range [expr {[$::ui_diff tag nextrange sel 0.0] != {}}]
+ if {$::ui_index eq $::current_diff_side} {
+ set l [mc "Unstage Hunk From Commit"]
+ if {$has_range} {
+ set t [mc "Unstage Lines From Commit"]
+ } else {
+ set t [mc "Unstage Line From Commit"]
+ }
+ } else {
+ set l [mc "Stage Hunk For Commit"]
+ if {$has_range} {
+ set t [mc "Stage Lines For Commit"]
+ } else {
+ set t [mc "Stage Line For Commit"]
+ }
+ }
+ if {$::is_3way_diff
+ || $current_diff_path eq {}
+ || {__} eq $state
+ || {_O} eq $state
+ || [string match {?T} $state]
+ || [string match {T?} $state]
+ || [has_textconv $current_diff_path]} {
+ set s disabled
+ } else {
+ set s normal
+ }
+ $ctxm entryconf $::ui_diff_applyhunk -state $s -label $l
+ $ctxm entryconf $::ui_diff_applyline -state $s -label $t
+ tk_popup $ctxm $X $Y
+ }
+}
+bind_button3 $ui_diff [list popup_diff_menu $ctxm $ctxmmg $ctxmsm %x %y %X %Y]
+
+# -- Status Bar
+#
+set main_status [::status_bar::new .status]
+pack .status -anchor w -side bottom -fill x
+$main_status show [mc "Initializing..."]
+
+# -- Load geometry
+#
+proc on_ttk_pane_mapped {w pane pos} {
+ bind $w <Map> {}
+ after 0 [list after idle [list $w sashpos $pane $pos]]
+}
+proc on_tk_pane_mapped {w pane x y} {
+ bind $w <Map> {}
+ after 0 [list after idle [list $w sash place $pane $x $y]]
+}
+proc on_application_mapped {} {
+ global repo_config use_ttk
+ bind . <Map> {}
+ set gm $repo_config(gui.geometry)
+ if {$use_ttk} {
+ bind .vpane <Map> \
+ [list on_ttk_pane_mapped %W 0 [lindex $gm 1]]
+ bind .vpane.files <Map> \
+ [list on_ttk_pane_mapped %W 0 [lindex $gm 2]]
+ } else {
+ bind .vpane <Map> \
+ [list on_tk_pane_mapped %W 0 \
+ [lindex $gm 1] \
+ [lindex [.vpane sash coord 0] 1]]
+ bind .vpane.files <Map> \
+ [list on_tk_pane_mapped %W 0 \
+ [lindex [.vpane.files sash coord 0] 0] \
+ [lindex $gm 2]]
+ }
+ wm geometry . [lindex $gm 0]
+}
+if {[info exists repo_config(gui.geometry)]} {
+ bind . <Map> [list on_application_mapped]
+ wm geometry . [lindex $repo_config(gui.geometry) 0]
+}
+
+# -- Load window state
+#
+if {[info exists repo_config(gui.wmstate)]} {
+ catch {wm state . $repo_config(gui.wmstate)}
+}
+
+# -- Key Bindings
+#
+bind $ui_comm <$M1B-Key-Return> {do_commit;break}
+bind $ui_comm <$M1B-Key-t> {do_add_selection;break}
+bind $ui_comm <$M1B-Key-T> {do_add_selection;break}
+bind $ui_comm <$M1B-Key-u> {do_unstage_selection;break}
+bind $ui_comm <$M1B-Key-U> {do_unstage_selection;break}
+bind $ui_comm <$M1B-Key-j> {do_revert_selection;break}
+bind $ui_comm <$M1B-Key-J> {do_revert_selection;break}
+bind $ui_comm <$M1B-Key-i> {do_add_all;break}
+bind $ui_comm <$M1B-Key-I> {do_add_all;break}
+bind $ui_comm <$M1B-Key-x> {tk_textCut %W;break}
+bind $ui_comm <$M1B-Key-X> {tk_textCut %W;break}
+bind $ui_comm <$M1B-Key-c> {tk_textCopy %W;break}
+bind $ui_comm <$M1B-Key-C> {tk_textCopy %W;break}
+bind $ui_comm <$M1B-Key-v> {tk_textPaste %W; %W see insert; break}
+bind $ui_comm <$M1B-Key-V> {tk_textPaste %W; %W see insert; break}
+bind $ui_comm <$M1B-Key-a> {%W tag add sel 0.0 end;break}
+bind $ui_comm <$M1B-Key-A> {%W tag add sel 0.0 end;break}
+bind $ui_comm <$M1B-Key-minus> {show_less_context;break}
+bind $ui_comm <$M1B-Key-KP_Subtract> {show_less_context;break}
+bind $ui_comm <$M1B-Key-equal> {show_more_context;break}
+bind $ui_comm <$M1B-Key-plus> {show_more_context;break}
+bind $ui_comm <$M1B-Key-KP_Add> {show_more_context;break}
+
+bind $ui_diff <$M1B-Key-x> {tk_textCopy %W;break}
+bind $ui_diff <$M1B-Key-X> {tk_textCopy %W;break}
+bind $ui_diff <$M1B-Key-c> {tk_textCopy %W;break}
+bind $ui_diff <$M1B-Key-C> {tk_textCopy %W;break}
+bind $ui_diff <$M1B-Key-v> {break}
+bind $ui_diff <$M1B-Key-V> {break}
+bind $ui_diff <$M1B-Key-a> {%W tag add sel 0.0 end;break}
+bind $ui_diff <$M1B-Key-A> {%W tag add sel 0.0 end;break}
+bind $ui_diff <$M1B-Key-j> {do_revert_selection;break}
+bind $ui_diff <$M1B-Key-J> {do_revert_selection;break}
+bind $ui_diff <Key-Up> {catch {%W yview scroll -1 units};break}
+bind $ui_diff <Key-Down> {catch {%W yview scroll 1 units};break}
+bind $ui_diff <Key-Left> {catch {%W xview scroll -1 units};break}
+bind $ui_diff <Key-Right> {catch {%W xview scroll 1 units};break}
+bind $ui_diff <Key-k> {catch {%W yview scroll -1 units};break}
+bind $ui_diff <Key-j> {catch {%W yview scroll 1 units};break}
+bind $ui_diff <Key-h> {catch {%W xview scroll -1 units};break}
+bind $ui_diff <Key-l> {catch {%W xview scroll 1 units};break}
+bind $ui_diff <Control-Key-b> {catch {%W yview scroll -1 pages};break}
+bind $ui_diff <Control-Key-f> {catch {%W yview scroll 1 pages};break}
+bind $ui_diff <Button-1> {focus %W}
+
+if {[is_enabled branch]} {
+ bind . <$M1B-Key-n> branch_create::dialog
+ bind . <$M1B-Key-N> branch_create::dialog
+ bind . <$M1B-Key-o> branch_checkout::dialog
+ bind . <$M1B-Key-O> branch_checkout::dialog
+ bind . <$M1B-Key-m> merge::dialog
+ bind . <$M1B-Key-M> merge::dialog
+}
+if {[is_enabled transport]} {
+ bind . <$M1B-Key-p> do_push_anywhere
+ bind . <$M1B-Key-P> do_push_anywhere
+}
+
+bind . <Key-F5> ui_do_rescan
+bind . <$M1B-Key-r> ui_do_rescan
+bind . <$M1B-Key-R> ui_do_rescan
+bind . <$M1B-Key-s> do_signoff
+bind . <$M1B-Key-S> do_signoff
- bind $i <Button-1> "toggle_or_diff $i %x %y; break"
- bind $i <$M1B-Button-1> "add_one_to_selection $i %x %y; break"
- bind $i <Shift-Button-1> "add_range_to_selection $i %x %y; break"
++bind . <$M1B-Key-t> { toggle_or_diff toggle %W }
++bind . <$M1B-Key-T> { toggle_or_diff toggle %W }
++bind . <$M1B-Key-u> { toggle_or_diff toggle %W }
++bind . <$M1B-Key-U> { toggle_or_diff toggle %W }
+bind . <$M1B-Key-j> do_revert_selection
+bind . <$M1B-Key-J> do_revert_selection
+bind . <$M1B-Key-i> do_add_all
+bind . <$M1B-Key-I> do_add_all
+bind . <$M1B-Key-minus> {show_less_context;break}
+bind . <$M1B-Key-KP_Subtract> {show_less_context;break}
+bind . <$M1B-Key-equal> {show_more_context;break}
+bind . <$M1B-Key-plus> {show_more_context;break}
+bind . <$M1B-Key-KP_Add> {show_more_context;break}
+bind . <$M1B-Key-Return> do_commit
+foreach i [list $ui_index $ui_workdir] {
++ bind $i <Button-1> { toggle_or_diff click %W %x %y; break }
++ bind $i <$M1B-Button-1> { add_one_to_selection %W %x %y; break }
++ bind $i <Shift-Button-1> { add_range_to_selection %W %x %y; break }
++ bind $i <Key-Up> { toggle_or_diff up %W; break }
++ bind $i <Key-Down> { toggle_or_diff down %W; break }
+}
+unset i
+
+set file_lists($ui_index) [list]
+set file_lists($ui_workdir) [list]
+
+wm title . "[appname] ([reponame]) [file normalize $_gitworktree]"
+focus -force $ui_comm
+
+# -- Warn the user about environmental problems. Cygwin's Tcl
+# does *not* pass its env array onto any processes it spawns.
+# This means that git processes get none of our environment.
+#
+if {[is_Cygwin]} {
+ set ignored_env 0
+ set suggest_user {}
+ set msg [mc "Possible environment issues exist.
+
+The following environment variables are probably
+going to be ignored by any Git subprocess run
+by %s:
+
+" [appname]]
+ foreach name [array names env] {
+ switch -regexp -- $name {
+ {^GIT_INDEX_FILE$} -
+ {^GIT_OBJECT_DIRECTORY$} -
+ {^GIT_ALTERNATE_OBJECT_DIRECTORIES$} -
+ {^GIT_DIFF_OPTS$} -
+ {^GIT_EXTERNAL_DIFF$} -
+ {^GIT_PAGER$} -
+ {^GIT_TRACE$} -
+ {^GIT_CONFIG$} -
+ {^GIT_(AUTHOR|COMMITTER)_DATE$} {
+ append msg " - $name\n"
+ incr ignored_env
+ }
+ {^GIT_(AUTHOR|COMMITTER)_(NAME|EMAIL)$} {
+ append msg " - $name\n"
+ incr ignored_env
+ set suggest_user $name
+ }
+ }
+ }
+ if {$ignored_env > 0} {
+ append msg [mc "
+This is due to a known issue with the
+Tcl binary distributed by Cygwin."]
+
+ if {$suggest_user ne {}} {
+ append msg [mc "
+
+A good replacement for %s
+is placing values for the user.name and
+user.email settings into your personal
+~/.gitconfig file.
+" $suggest_user]
+ }
+ warn_popup $msg
+ }
+ unset ignored_env msg suggest_user name
+}
+
+# -- Only initialize complex UI if we are going to stay running.
+#
+if {[is_enabled transport]} {
+ load_all_remotes
+
+ set n [.mbar.remote index end]
+ populate_remotes_menu
+ set n [expr {[.mbar.remote index end] - $n}]
+ if {$n > 0} {
+ if {[.mbar.remote type 0] eq "tearoff"} { incr n }
+ .mbar.remote insert $n separator
+ }
+ unset n
+}
+
+if {[winfo exists $ui_comm]} {
+ set GITGUI_BCK_exists [load_message GITGUI_BCK utf-8]
+
+ # -- If both our backup and message files exist use the
+ # newer of the two files to initialize the buffer.
+ #
+ if {$GITGUI_BCK_exists} {
+ set m [gitdir GITGUI_MSG]
+ if {[file isfile $m]} {
+ if {[file mtime [gitdir GITGUI_BCK]] > [file mtime $m]} {
+ catch {file delete [gitdir GITGUI_MSG]}
+ } else {
+ $ui_comm delete 0.0 end
+ $ui_comm edit reset
+ $ui_comm edit modified false
+ catch {file delete [gitdir GITGUI_BCK]}
+ set GITGUI_BCK_exists 0
+ }
+ }
+ unset m
+ }
+
+ proc backup_commit_buffer {} {
+ global ui_comm GITGUI_BCK_exists
+
+ set m [$ui_comm edit modified]
+ if {$m || $GITGUI_BCK_exists} {
+ set msg [string trim [$ui_comm get 0.0 end]]
+ regsub -all -line {[ \r\t]+$} $msg {} msg
+
+ if {$msg eq {}} {
+ if {$GITGUI_BCK_exists} {
+ catch {file delete [gitdir GITGUI_BCK]}
+ set GITGUI_BCK_exists 0
+ }
+ } elseif {$m} {
+ catch {
+ set fd [open [gitdir GITGUI_BCK] w]
+ fconfigure $fd -encoding utf-8
+ puts -nonewline $fd $msg
+ close $fd
+ set GITGUI_BCK_exists 1
+ }
+ }
+
+ $ui_comm edit modified false
+ }
+
+ set ::GITGUI_BCK_i [after 2000 backup_commit_buffer]
+ }
+
+ backup_commit_buffer
+
+ # -- If the user has aspell available we can drive it
+ # in pipe mode to spellcheck the commit message.
+ #
+ set spell_cmd [list |]
+ set spell_dict [get_config gui.spellingdictionary]
+ lappend spell_cmd aspell
+ if {$spell_dict ne {}} {
+ lappend spell_cmd --master=$spell_dict
+ }
+ lappend spell_cmd --mode=none
+ lappend spell_cmd --encoding=utf-8
+ lappend spell_cmd pipe
+ if {$spell_dict eq {none}
+ || [catch {set spell_fd [open $spell_cmd r+]} spell_err]} {
+ bind_button3 $ui_comm [list tk_popup $ui_comm_ctxm %X %Y]
+ } else {
+ set ui_comm_spell [spellcheck::init \
+ $spell_fd \
+ $ui_comm \
+ $ui_comm_ctxm \
+ ]
+ }
+ unset -nocomplain spell_cmd spell_fd spell_err spell_dict
+}
+
+lock_index begin-read
+if {![winfo ismapped .]} {
+ wm deiconify .
+}
+after 1 {
+ if {[is_enabled initialamend]} {
+ force_amend
+ } else {
+ do_rescan
+ }
+
+ if {[is_enabled nocommitmsg]} {
+ $ui_comm configure -state disabled -background gray
+ }
+}
+if {[is_enabled multicommit] && ![is_config_false gui.gcwarning]} {
+ after 1000 hint_gc
+}
+if {[is_enabled retcode]} {
+ bind . <Destroy> {+terminate_me %W}
+}
+if {$picked && [is_config_true gui.autoexplore]} {
+ do_explore
+}
+
+# Local variables:
+# mode: tcl
+# indent-tabs-mode: t
+# tab-width: 4
+# End:
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "File Viewer"]]
+# git-gui blame viewer
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+class blame {
+
+image create photo ::blame::img_back_arrow -data {R0lGODlhGAAYAIUAAPwCBEzKXFTSZIz+nGzmhGzqfGTidIT+nEzGXHTqhGzmfGzifFzadETCVES+VARWDFzWbHzyjAReDGTadFTOZDSyRDyyTCymPARaFGTedFzSbDy2TCyqRCyqPARaDAyCHES6VDy6VCyiPAR6HCSeNByWLARyFARiDARqFGTifARiFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAYABgAAAajQIBwSCwaj8ikcsk0BppJwRPqHEypQwHBis0WDAdEFyBIKBaMAKLBdjQeSkFBYTBAIvgEoS6JmhUTEwIUDQ4VFhcMGEhyCgoZExoUaxsWHB0THkgfAXUGAhoBDSAVFR0XBnCbDRmgog0hpSIiDJpJIyEQhBUcJCIlwA22SSYVogknEg8eD82qSigdDSknY0IqJQXPYxIl1dZCGNvWw+Dm510GQQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
+
+# Persistent data (survives loads)
+#
+field history {}; # viewer history: {commit path}
+field header ; # array commit,key -> header field
+
+# Tk UI control paths
+#
+field w ; # top window in this viewer
+field w_back ; # our back button
+field w_path ; # label showing the current file path
+field w_columns ; # list of all column widgets in the viewer
+field w_line ; # text column: all line numbers
+field w_amov ; # text column: annotations + move tracking
+field w_asim ; # text column: annotations (simple computation)
+field w_file ; # text column: actual file data
+field w_cviewer ; # pane showing commit message
+field finder ; # find mini-dialog frame
+field gotoline ; # line goto mini-dialog frame
+field status ; # status mega-widget instance
+field old_height ; # last known height of $w.file_pane
+
+
+# Tk UI colors
+#
+variable active_color #c0edc5
+variable group_colors {
+ #d6d6d6
+ #e1e1e1
+ #ececec
+}
+
+# Current blame data; cleared/reset on each load
+#
+field commit ; # input commit to blame
+field path ; # input filename to view in $commit
+
+field current_fd {} ; # background process running
+field highlight_line -1 ; # current line selected
+field highlight_column {} ; # current commit column selected
+field highlight_commit {} ; # sha1 of commit selected
+
+field total_lines 0 ; # total length of file
+field blame_lines 0 ; # number of lines computed
+field amov_data ; # list of {commit origfile origline}
+field asim_data ; # list of {commit origfile origline}
+
+field r_commit ; # commit currently being parsed
+field r_orig_line ; # original line number
+field r_final_line ; # final line number
+field r_line_count ; # lines in this region
+
+field tooltip_wm {} ; # Current tooltip toplevel, if open
+field tooltip_t {} ; # Text widget in $tooltip_wm
+field tooltip_timer {} ; # Current timer event for our tooltip
+field tooltip_commit {} ; # Commit(s) in tooltip
+
+constructor new {i_commit i_path i_jump} {
+ global cursor_ptr M1B M1T have_tk85 use_ttk NS
+ variable active_color
+ variable group_colors
+
+ set commit $i_commit
+ set path $i_path
+
+ make_toplevel top w
++ wm title $top [mc "%s (%s): File Viewer" [appname] [reponame]]
+
+ set font_w [font measure font_diff "0"]
+
+ gold_frame $w.header
+ tlabel $w.header.commit_l \
+ -text [mc "Commit:"] \
+ -background gold \
+ -foreground black \
+ -anchor w \
+ -justify left
+ set w_back $w.header.commit_b
+ tlabel $w_back \
+ -image ::blame::img_back_arrow \
+ -borderwidth 0 \
+ -relief flat \
+ -state disabled \
+ -background gold \
+ -foreground black \
+ -activebackground gold
+ bind $w_back <Button-1> "
+ if {\[$w_back cget -state\] eq {normal}} {
+ [cb _history_menu]
+ }
+ "
+ tlabel $w.header.commit \
+ -textvariable @commit \
+ -background gold \
+ -foreground black \
+ -anchor w \
+ -justify left
+ tlabel $w.header.path_l \
+ -text [mc "File:"] \
+ -background gold \
+ -foreground black \
+ -anchor w \
+ -justify left
+ set w_path $w.header.path
+ tlabel $w_path \
+ -background gold \
+ -foreground black \
+ -anchor w \
+ -justify left
+ pack $w.header.commit_l -side left
+ pack $w_back -side left
+ pack $w.header.commit -side left
+ pack $w_path -fill x -side right
+ pack $w.header.path_l -side right
+
+ panedwindow $w.file_pane -orient vertical -borderwidth 0 -sashwidth 3
+ frame $w.file_pane.out -relief flat -borderwidth 1
+ frame $w.file_pane.cm -relief sunken -borderwidth 1
+ $w.file_pane add $w.file_pane.out \
+ -sticky nsew \
+ -minsize 100 \
+ -height 100 \
+ -width 100
+ $w.file_pane add $w.file_pane.cm \
+ -sticky nsew \
+ -minsize 25 \
+ -height 25 \
+ -width 100
+
+ set w_line $w.file_pane.out.linenumber_t
+ text $w_line \
+ -takefocus 0 \
+ -highlightthickness 0 \
+ -padx 0 -pady 0 \
+ -background white \
+ -foreground black \
+ -borderwidth 0 \
+ -state disabled \
+ -wrap none \
+ -height 40 \
+ -width 6 \
+ -font font_diff
+ $w_line tag conf linenumber -justify right -rmargin 5
+
+ set w_amov $w.file_pane.out.amove_t
+ text $w_amov \
+ -takefocus 0 \
+ -highlightthickness 0 \
+ -padx 0 -pady 0 \
+ -background white \
+ -foreground black \
+ -borderwidth 0 \
+ -state disabled \
+ -wrap none \
+ -height 40 \
+ -width 5 \
+ -font font_diff
+ $w_amov tag conf author_abbr -justify right -rmargin 5
+ $w_amov tag conf curr_commit
+ $w_amov tag conf prior_commit -foreground blue -underline 1
+ $w_amov tag bind prior_commit \
+ <Button-1> \
+ "[cb _load_commit $w_amov @amov_data @%x,%y];break"
+
+ set w_asim $w.file_pane.out.asimple_t
+ text $w_asim \
+ -takefocus 0 \
+ -highlightthickness 0 \
+ -padx 0 -pady 0 \
+ -background white \
+ -foreground black \
+ -borderwidth 0 \
+ -state disabled \
+ -wrap none \
+ -height 40 \
+ -width 4 \
+ -font font_diff
+ $w_asim tag conf author_abbr -justify right
+ $w_asim tag conf curr_commit
+ $w_asim tag conf prior_commit -foreground blue -underline 1
+ $w_asim tag bind prior_commit \
+ <Button-1> \
+ "[cb _load_commit $w_asim @asim_data @%x,%y];break"
+
+ set w_file $w.file_pane.out.file_t
+ text $w_file \
+ -takefocus 0 \
+ -highlightthickness 0 \
+ -padx 0 -pady 0 \
+ -background white \
+ -foreground black \
+ -borderwidth 0 \
+ -state disabled \
+ -wrap none \
+ -height 40 \
+ -width 80 \
+ -xscrollcommand [list $w.file_pane.out.sbx set] \
+ -font font_diff
+ if {$have_tk85} {
+ $w_file configure -inactiveselectbackground darkblue
+ }
+ $w_file tag conf found \
+ -background yellow
+
+ set w_columns [list $w_amov $w_asim $w_line $w_file]
+
+ ${NS}::scrollbar $w.file_pane.out.sbx \
+ -orient h \
+ -command [list $w_file xview]
+ ${NS}::scrollbar $w.file_pane.out.sby \
+ -orient v \
+ -command [list scrollbar2many $w_columns yview]
+ eval grid $w_columns $w.file_pane.out.sby -sticky nsew
+ grid conf \
+ $w.file_pane.out.sbx \
+ -column 0 \
+ -columnspan [expr {[llength $w_columns] + 1}] \
+ -sticky we
+ grid columnconfigure \
+ $w.file_pane.out \
+ [expr {[llength $w_columns] - 1}] \
+ -weight 1
+ grid rowconfigure $w.file_pane.out 0 -weight 1
+
+ set finder [::searchbar::new \
+ $w.file_pane.out.ff $w_file \
+ -column 0 \
+ -columnspan [expr {[llength $w_columns] + 1}] \
+ ]
+
+ set gotoline [::linebar::new \
+ $w.file_pane.out.lf $w_file \
+ -column 0 \
+ -columnspan [expr {[llength $w_columns] + 1}] \
+ ]
+
+ set w_cviewer $w.file_pane.cm.t
+ text $w_cviewer \
+ -background white \
+ -foreground black \
+ -borderwidth 0 \
+ -state disabled \
+ -wrap none \
+ -height 10 \
+ -width 80 \
+ -xscrollcommand [list $w.file_pane.cm.sbx set] \
+ -yscrollcommand [list $w.file_pane.cm.sby set] \
+ -font font_diff
+ $w_cviewer tag conf still_loading \
+ -font font_uiitalic \
+ -justify center
+ $w_cviewer tag conf header_key \
+ -tabs {3c} \
+ -background $active_color \
+ -font font_uibold
+ $w_cviewer tag conf header_val \
+ -background $active_color \
+ -font font_ui
+ $w_cviewer tag raise sel
+ ${NS}::scrollbar $w.file_pane.cm.sbx \
+ -orient h \
+ -command [list $w_cviewer xview]
+ ${NS}::scrollbar $w.file_pane.cm.sby \
+ -orient v \
+ -command [list $w_cviewer yview]
+ pack $w.file_pane.cm.sby -side right -fill y
+ pack $w.file_pane.cm.sbx -side bottom -fill x
+ pack $w_cviewer -expand 1 -fill both
+
+ set status [::status_bar::new $w.status]
+
+ menu $w.ctxm -tearoff 0
+ $w.ctxm add command \
+ -label [mc "Copy Commit"] \
+ -command [cb _copycommit]
+ $w.ctxm add separator
+ $w.ctxm add command \
+ -label [mc "Find Text..."] \
+ -accelerator F7 \
+ -command [cb _show_finder]
+ $w.ctxm add command \
+ -label [mc "Goto Line..."] \
+ -accelerator "Ctrl-G" \
+ -command [cb _show_linebar]
+ menu $w.ctxm.enc
+ build_encoding_menu $w.ctxm.enc [cb _setencoding]
+ $w.ctxm add cascade \
+ -label [mc "Encoding"] \
+ -menu $w.ctxm.enc
+ $w.ctxm add command \
+ -label [mc "Do Full Copy Detection"] \
+ -command [cb _fullcopyblame]
+ $w.ctxm add separator
+ $w.ctxm add command \
+ -label [mc "Show History Context"] \
+ -command [cb _gitkcommit]
+ $w.ctxm add command \
+ -label [mc "Blame Parent Commit"] \
+ -command [cb _blameparent]
+
+ foreach i $w_columns {
+ for {set g 0} {$g < [llength $group_colors]} {incr g} {
+ $i tag conf color$g -background [lindex $group_colors $g]
+ }
+
+ if {$i eq $w_file} {
+ $w_file tag raise found
+ }
+ $i tag raise sel
+
+ $i conf -cursor $cursor_ptr
+ $i conf -yscrollcommand \
+ "[list ::searchbar::scrolled $finder]
+ [list many2scrollbar $w_columns yview $w.file_pane.out.sby]"
+ bind $i <Button-1> "
+ [cb _hide_tooltip]
+ [cb _click $i @%x,%y]
+ focus $i
+ "
+ bind $i <Any-Motion> [cb _show_tooltip $i @%x,%y]
+ bind $i <Any-Enter> [cb _hide_tooltip]
+ bind $i <Any-Leave> [cb _hide_tooltip]
+ bind_button3 $i "
+ [cb _hide_tooltip]
+ set cursorX %x
+ set cursorY %y
+ set cursorW %W
+ tk_popup $w.ctxm %X %Y
+ "
+ bind $i <Shift-Tab> "[list focus $w_cviewer];break"
+ bind $i <Tab> "[cb _focus_search $w_cviewer];break"
+ }
+
+ foreach i [concat $w_columns $w_cviewer] {
+ bind $i <Key-Up> {catch {%W yview scroll -1 units};break}
+ bind $i <Key-Down> {catch {%W yview scroll 1 units};break}
+ bind $i <Key-Left> {catch {%W xview scroll -1 units};break}
+ bind $i <Key-Right> {catch {%W xview scroll 1 units};break}
+ bind $i <Key-k> {catch {%W yview scroll -1 units};break}
+ bind $i <Key-j> {catch {%W yview scroll 1 units};break}
+ bind $i <Key-h> {catch {%W xview scroll -1 units};break}
+ bind $i <Key-l> {catch {%W xview scroll 1 units};break}
+ bind $i <Control-Key-b> {catch {%W yview scroll -1 pages};break}
+ bind $i <Control-Key-f> {catch {%W yview scroll 1 pages};break}
+ }
+
+ bind $w_cviewer <Shift-Tab> "[cb _focus_search $w_file];break"
+ bind $w_cviewer <Tab> "[list focus $w_file];break"
+ bind $w_cviewer <Button-1> [list focus $w_cviewer]
+ bind $w_file <Visibility> [cb _focus_search $w_file]
+ bind $top <F7> [cb _show_finder]
+ bind $top <Key-slash> [cb _show_finder]
+ bind $top <Control-Key-s> [cb _show_finder]
+ bind $top <Escape> [list searchbar::hide $finder]
+ bind $top <F3> [list searchbar::find_next $finder]
+ bind $top <Shift-F3> [list searchbar::find_prev $finder]
+ bind $top <Control-Key-g> [cb _show_linebar]
+ catch { bind $top <Shift-Key-XF86_Switch_VT_3> [list searchbar::find_prev $finder] }
+
+ grid configure $w.header -sticky ew
+ grid configure $w.file_pane -sticky nsew
+ grid configure $w.status -sticky ew
+ grid columnconfigure $top 0 -weight 1
+ grid rowconfigure $top 0 -weight 0
+ grid rowconfigure $top 1 -weight 1
+ grid rowconfigure $top 2 -weight 0
+
+ set req_w [winfo reqwidth $top]
+ set req_h [winfo reqheight $top]
+ set scr_w [expr {[winfo screenwidth $top] - 40}]
+ set scr_h [expr {[winfo screenheight $top] - 120}]
+ set opt_w [expr {$font_w * (80 + 5*3 + 3)}]
+ if {$req_w < $opt_w} {set req_w $opt_w}
+ if {$req_w > $scr_w} {set req_w $scr_w}
+ set opt_h [expr {$req_w*4/3}]
+ if {$req_h < $scr_h} {set req_h $scr_h}
+ if {$req_h > $opt_h} {set req_h $opt_h}
+ set g "${req_w}x${req_h}"
+ wm geometry $top $g
+ update
+
+ set old_height [winfo height $w.file_pane]
+ $w.file_pane sash place 0 \
+ [lindex [$w.file_pane sash coord 0] 0] \
+ [expr {int($old_height * 0.80)}]
+ bind $w.file_pane <Configure> \
+ "if {{$w.file_pane} eq {%W}} {[cb _resize %h]}"
+
+ wm protocol $top WM_DELETE_WINDOW "destroy $top"
+ bind $top <Destroy> [cb _handle_destroy %W]
+
+ _load $this $i_jump
+}
+
+method _focus_search {win} {
+ if {[searchbar::visible $finder]} {
+ focus [searchbar::editor $finder]
+ } else {
+ focus $win
+ }
+}
+
+method _handle_destroy {win} {
+ if {$win eq $w} {
+ _kill $this
+ delete_this
+ }
+}
+
+method _kill {} {
+ if {$current_fd ne {}} {
+ kill_file_process $current_fd
+ catch {close $current_fd}
+ set current_fd {}
+ }
+}
+
+method _load {jump} {
+ variable group_colors
+
+ _hide_tooltip $this
+
+ if {$total_lines != 0 || $current_fd ne {}} {
+ _kill $this
+
+ foreach i $w_columns {
+ $i conf -state normal
+ $i delete 0.0 end
+ foreach g [$i tag names] {
+ if {[regexp {^g[0-9a-f]{40}$} $g]} {
+ $i tag delete $g
+ }
+ }
+ $i conf -state disabled
+ }
+
+ $w_cviewer conf -state normal
+ $w_cviewer delete 0.0 end
+ $w_cviewer conf -state disabled
+
+ set highlight_line -1
+ set highlight_column {}
+ set highlight_commit {}
+ set total_lines 0
+ }
+
+ if {$history eq {}} {
+ $w_back conf -state disabled
+ } else {
+ $w_back conf -state normal
+ }
+
+ # Index 0 is always empty. There is never line 0 as
+ # we use only 1 based lines, as that matches both with
+ # git-blame output and with Tk's text widget.
+ #
+ set amov_data [list [list]]
+ set asim_data [list [list]]
+
+ $status show [mc "Reading %s..." "$commit:[escape_path $path]"]
+ $w_path conf -text [escape_path $path]
+
+ set do_textconv 0
+ if {![is_config_false gui.textconv] && [git-version >= 1.7.2]} {
+ set filter [gitattr $path diff set]
+ set textconv [get_config [join [list diff $filter textconv] .]]
+ if {$filter ne {set} && $textconv ne {}} {
+ set do_textconv 1
+ }
+ }
+ if {$commit eq {}} {
+ if {$do_textconv ne 0} {
+ set fd [open_cmd_pipe $textconv $path]
+ } else {
+ set fd [open $path r]
+ }
+ fconfigure $fd -eofchar {}
+ } else {
+ if {$do_textconv ne 0} {
+ set fd [git_read cat-file --textconv "$commit:$path"]
+ } else {
+ set fd [git_read cat-file blob "$commit:$path"]
+ }
+ }
+ fconfigure $fd \
+ -blocking 0 \
+ -translation lf \
+ -encoding [get_path_encoding $path]
+ fileevent $fd readable [cb _read_file $fd $jump]
+ set current_fd $fd
+}
+
+method _history_menu {} {
+ set m $w.backmenu
+ if {[winfo exists $m]} {
+ $m delete 0 end
+ } else {
+ menu $m -tearoff 0
+ }
+
+ for {set i [expr {[llength $history] - 1}]
+ } {$i >= 0} {incr i -1} {
+ set e [lindex $history $i]
+ set c [lindex $e 0]
+ set f [lindex $e 1]
+
+ if {[regexp {^[0-9a-f]{40}$} $c]} {
+ set t [string range $c 0 8]...
+ } elseif {$c eq {}} {
+ set t {Working Directory}
+ } else {
+ set t $c
+ }
+ if {![catch {set summary $header($c,summary)}]} {
+ append t " $summary"
+ if {[string length $t] > 70} {
+ set t [string range $t 0 66]...
+ }
+ }
+
+ $m add command -label $t -command [cb _goback $i]
+ }
+ set X [winfo rootx $w_back]
+ set Y [expr {[winfo rooty $w_back] + [winfo height $w_back]}]
+ tk_popup $m $X $Y
+}
+
+method _goback {i} {
+ set dat [lindex $history $i]
+ set history [lrange $history 0 [expr {$i - 1}]]
+ set commit [lindex $dat 0]
+ set path [lindex $dat 1]
+ _load $this [lrange $dat 2 5]
+}
+
+method _read_file {fd jump} {
+ if {$fd ne $current_fd} {
+ catch {close $fd}
+ return
+ }
+
+ foreach i $w_columns {$i conf -state normal}
+ while {[gets $fd line] >= 0} {
+ regsub "\r\$" $line {} line
+ incr total_lines
+ lappend amov_data {}
+ lappend asim_data {}
+
+ if {$total_lines > 1} {
+ foreach i $w_columns {$i insert end "\n"}
+ }
+
+ $w_line insert end "$total_lines" linenumber
+ $w_file insert end "$line"
+ }
+
+ set ln_wc [expr {[string length $total_lines] + 2}]
+ if {[$w_line cget -width] < $ln_wc} {
+ $w_line conf -width $ln_wc
+ }
+
+ foreach i $w_columns {$i conf -state disabled}
+
+ if {[eof $fd]} {
+ fconfigure $fd -blocking 1; # enable error reporting on close
+ if {[catch {close $fd} err]} {
+ tk_messageBox -icon error -title [mc Error] \
+ -message $err
+ }
+
+ # If we don't force Tk to update the widgets *right now*
+ # none of our jump commands will cause a change in the UI.
+ #
+ update
+
+ if {[llength $jump] == 1} {
+ set highlight_line [lindex $jump 0]
+ $w_file see "$highlight_line.0"
+ } elseif {[llength $jump] == 4} {
+ set highlight_column [lindex $jump 0]
+ set highlight_line [lindex $jump 1]
+ $w_file xview moveto [lindex $jump 2]
+ $w_file yview moveto [lindex $jump 3]
+ }
+
+ _exec_blame $this $w_asim @asim_data \
+ [list] \
+ [mc "Loading copy/move tracking annotations..."]
+ }
+} ifdeleted { catch {close $fd} }
+
+method _exec_blame {cur_w cur_d options cur_s} {
+ lappend options --incremental --encoding=utf-8
+ if {$commit eq {}} {
+ lappend options --contents $path
+ } else {
+ lappend options $commit
+ }
+ lappend options -- $path
+ set fd [eval git_read --nice blame $options]
+ fconfigure $fd -blocking 0 -translation lf -encoding utf-8
+ fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d]
+ set current_fd $fd
+ set blame_lines 0
+
+ $status start \
+ $cur_s \
+ [mc "lines annotated"]
+}
+
+method _read_blame {fd cur_w cur_d} {
+ upvar #0 $cur_d line_data
+ variable group_colors
+
+ if {$fd ne $current_fd} {
+ catch {close $fd}
+ return
+ }
+
+ $cur_w conf -state normal
+ while {[gets $fd line] >= 0} {
+ if {[regexp {^([a-z0-9]{40}) (\d+) (\d+) (\d+)$} $line line \
+ cmit original_line final_line line_count]} {
+ set r_commit $cmit
+ set r_orig_line $original_line
+ set r_final_line $final_line
+ set r_line_count $line_count
+ } elseif {[string match {filename *} $line]} {
+ set file [string range $line 9 end]
+ set n $r_line_count
+ set lno $r_final_line
+ set oln $r_orig_line
+ set cmit $r_commit
+
+ if {[regexp {^0{40}$} $cmit]} {
+ set commit_abbr work
+ set commit_type curr_commit
+ } elseif {$cmit eq $commit} {
+ set commit_abbr this
+ set commit_type curr_commit
+ } else {
+ set commit_type prior_commit
+ set commit_abbr [string range $cmit 0 3]
+ }
+
+ set author_abbr {}
+ set a_name {}
+ catch {set a_name $header($cmit,author)}
+ while {$a_name ne {}} {
+ if {$author_abbr ne {}
+ && [string index $a_name 0] eq {'}} {
+ regsub {^'[^']+'\s+} $a_name {} a_name
+ }
+ if {![regexp {^([[:upper:]])} $a_name _a]} break
+ append author_abbr $_a
+ unset _a
+ if {![regsub \
+ {^[[:upper:]][^\s]*\s+} \
+ $a_name {} a_name ]} break
+ }
+ if {$author_abbr eq {}} {
+ set author_abbr { |}
+ } else {
+ set author_abbr [string range $author_abbr 0 3]
+ }
+ unset a_name
+
+ set first_lno $lno
+ while {
+ $first_lno > 1
+ && $cmit eq [lindex $line_data [expr {$first_lno - 1}] 0]
+ && $file eq [lindex $line_data [expr {$first_lno - 1}] 1]
+ } {
+ incr first_lno -1
+ }
+
+ set color {}
+ if {$first_lno < $lno} {
+ foreach g [$w_file tag names $first_lno.0] {
+ if {[regexp {^color[0-9]+$} $g]} {
+ set color $g
+ break
+ }
+ }
+ } else {
+ set i [lsort [concat \
+ [$w_file tag names "[expr {$first_lno - 1}].0"] \
+ [$w_file tag names "[expr {$lno + $n}].0"] \
+ ]]
+ for {set g 0} {$g < [llength $group_colors]} {incr g} {
+ if {[lsearch -sorted -exact $i color$g] == -1} {
+ set color color$g
+ break
+ }
+ }
+ }
+ if {$color eq {}} {
+ set color color0
+ }
+
+ while {$n > 0} {
+ set lno_e "$lno.0 lineend + 1c"
+ if {[lindex $line_data $lno] ne {}} {
+ set g [lindex $line_data $lno 0]
+ foreach i $w_columns {
+ $i tag remove g$g $lno.0 $lno_e
+ }
+ }
+ lset line_data $lno [list $cmit $file $oln]
+
+ $cur_w delete $lno.0 "$lno.0 lineend"
+ if {$lno == $first_lno} {
+ $cur_w insert $lno.0 $commit_abbr $commit_type
+ } elseif {$lno == [expr {$first_lno + 1}]} {
+ $cur_w insert $lno.0 $author_abbr author_abbr
+ } else {
+ $cur_w insert $lno.0 { |}
+ }
+
+ foreach i $w_columns {
+ if {$cur_w eq $w_amov} {
+ for {set g 0} \
+ {$g < [llength $group_colors]} \
+ {incr g} {
+ $i tag remove color$g $lno.0 $lno_e
+ }
+ $i tag add $color $lno.0 $lno_e
+ }
+ $i tag add g$cmit $lno.0 $lno_e
+ }
+
+ if {$highlight_column eq $cur_w} {
+ if {$highlight_line == -1
+ && [lindex [$w_file yview] 0] == 0} {
+ $w_file see $lno.0
+ set highlight_line $lno
+ }
+ if {$highlight_line == $lno} {
+ _showcommit $this $cur_w $lno
+ }
+ }
+
+ incr n -1
+ incr lno
+ incr oln
+ incr blame_lines
+ }
+
+ while {
+ $cmit eq [lindex $line_data $lno 0]
+ && $file eq [lindex $line_data $lno 1]
+ } {
+ $cur_w delete $lno.0 "$lno.0 lineend"
+
+ if {$lno == $first_lno} {
+ $cur_w insert $lno.0 $commit_abbr $commit_type
+ } elseif {$lno == [expr {$first_lno + 1}]} {
+ $cur_w insert $lno.0 $author_abbr author_abbr
+ } else {
+ $cur_w insert $lno.0 { |}
+ }
+
+ if {$cur_w eq $w_amov} {
+ foreach i $w_columns {
+ for {set g 0} \
+ {$g < [llength $group_colors]} \
+ {incr g} {
+ $i tag remove color$g $lno.0 $lno_e
+ }
+ $i tag add $color $lno.0 $lno_e
+ }
+ }
+
+ incr lno
+ }
+
+ } elseif {[regexp {^([a-z-]+) (.*)$} $line line key data]} {
+ set header($r_commit,$key) $data
+ }
+ }
+ $cur_w conf -state disabled
+
+ if {[eof $fd]} {
+ close $fd
+ if {$cur_w eq $w_asim} {
+ # Switches for original location detection
+ set threshold [get_config gui.copyblamethreshold]
+ set original_options [list "-C$threshold"]
+
+ if {![is_config_true gui.fastcopyblame]} {
+ # thorough copy search; insert before the threshold
+ set original_options [linsert $original_options 0 -C]
+ }
+ if {[git-version >= 1.5.3]} {
+ lappend original_options -w ; # ignore indentation changes
+ }
+
+ _exec_blame $this $w_amov @amov_data \
+ $original_options \
+ [mc "Loading original location annotations..."]
+ } else {
+ set current_fd {}
+ $status stop [mc "Annotation complete."]
+ }
+ } else {
+ $status update $blame_lines $total_lines
+ }
+} ifdeleted { catch {close $fd} }
+
+method _find_commit_bound {data_list start_idx delta} {
+ upvar #0 $data_list line_data
+ set pos $start_idx
+ set limit [expr {[llength $line_data] - 1}]
+ set base_commit [lindex $line_data $pos 0]
+
+ while {$pos > 0 && $pos < $limit} {
+ set new_pos [expr {$pos + $delta}]
+ if {[lindex $line_data $new_pos 0] ne $base_commit} {
+ return $pos
+ }
+
+ set pos $new_pos
+ }
+
+ return $pos
+}
+
+method _fullcopyblame {} {
+ if {$current_fd ne {}} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [mc "Busy"] \
+ -message [mc "Annotation process is already running."]
+
+ return
+ }
+
+ # Switches for original location detection
+ set threshold [get_config gui.copyblamethreshold]
+ set original_options [list -C -C "-C$threshold"]
+
+ if {[git-version >= 1.5.3]} {
+ lappend original_options -w ; # ignore indentation changes
+ }
+
+ # Find the line range
+ set pos @$::cursorX,$::cursorY
+ set lno [lindex [split [$::cursorW index $pos] .] 0]
+ set min_amov_lno [_find_commit_bound $this @amov_data $lno -1]
+ set max_amov_lno [_find_commit_bound $this @amov_data $lno 1]
+ set min_asim_lno [_find_commit_bound $this @asim_data $lno -1]
+ set max_asim_lno [_find_commit_bound $this @asim_data $lno 1]
+
+ if {$min_asim_lno < $min_amov_lno} {
+ set min_amov_lno $min_asim_lno
+ }
+
+ if {$max_asim_lno > $max_amov_lno} {
+ set max_amov_lno $max_asim_lno
+ }
+
+ lappend original_options -L "$min_amov_lno,$max_amov_lno"
+
+ # Clear lines
+ for {set i $min_amov_lno} {$i <= $max_amov_lno} {incr i} {
+ lset amov_data $i [list ]
+ }
+
+ # Start the back-end process
+ _exec_blame $this $w_amov @amov_data \
+ $original_options \
+ [mc "Running thorough copy detection..."]
+}
+
+method _click {cur_w pos} {
+ set lno [lindex [split [$cur_w index $pos] .] 0]
+ _showcommit $this $cur_w $lno
+}
+
+method _setencoding {enc} {
+ force_path_encoding $path $enc
+ _load $this [list \
+ $highlight_column \
+ $highlight_line \
+ [lindex [$w_file xview] 0] \
+ [lindex [$w_file yview] 0] \
+ ]
+}
+
+method _load_commit {cur_w cur_d pos} {
+ upvar #0 $cur_d line_data
+ set lno [lindex [split [$cur_w index $pos] .] 0]
+ set dat [lindex $line_data $lno]
+ if {$dat ne {}} {
+ _load_new_commit $this \
+ [lindex $dat 0] \
+ [lindex $dat 1] \
+ [list [lindex $dat 2]]
+ }
+}
+
+method _load_new_commit {new_commit new_path jump} {
+ lappend history [list \
+ $commit $path \
+ $highlight_column \
+ $highlight_line \
+ [lindex [$w_file xview] 0] \
+ [lindex [$w_file yview] 0] \
+ ]
+
+ set commit $new_commit
+ set path $new_path
+ _load $this $jump
+}
+
+method _showcommit {cur_w lno} {
+ global repo_config
+ variable active_color
+
+ if {$highlight_commit ne {}} {
+ foreach i $w_columns {
+ $i tag conf g$highlight_commit -background {}
+ $i tag lower g$highlight_commit
+ }
+ }
+
+ if {$cur_w eq $w_asim} {
+ set dat [lindex $asim_data $lno]
+ set highlight_column $w_asim
+ } else {
+ set dat [lindex $amov_data $lno]
+ set highlight_column $w_amov
+ }
+
+ $w_cviewer conf -state normal
+ $w_cviewer delete 0.0 end
+
+ if {$dat eq {}} {
+ set cmit {}
+ $w_cviewer insert end [mc "Loading annotation..."] still_loading
+ } else {
+ set cmit [lindex $dat 0]
+ set file [lindex $dat 1]
+
+ foreach i $w_columns {
+ $i tag conf g$cmit -background $active_color
+ $i tag raise g$cmit
+ if {$i eq $w_file} {
+ $w_file tag raise found
+ }
+ $i tag raise sel
+ }
+
+ set author_name {}
+ set author_email {}
+ set author_time {}
+ catch {set author_name $header($cmit,author)}
+ catch {set author_email $header($cmit,author-mail)}
+ 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 [format_date $header($cmit,committer-time)]}
+
+ if {[catch {set msg $header($cmit,message)}]} {
+ set msg {}
+ catch {
+ set fd [git_read cat-file commit $cmit]
+ fconfigure $fd -encoding binary -translation lf
+ # By default commits are assumed to be in utf-8
+ set enc utf-8
+ while {[gets $fd line] > 0} {
+ if {[string match {encoding *} $line]} {
+ set enc [string tolower [string range $line 9 end]]
+ }
+ }
+ set msg [read $fd]
+ close $fd
+
+ set enc [tcl_encoding $enc]
+ if {$enc ne {}} {
+ set msg [encoding convertfrom $enc $msg]
+ }
+ set msg [string trim $msg]
+ }
+ set header($cmit,message) $msg
+ }
+
+ $w_cviewer insert end "commit $cmit\n" 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 [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 [strcat [mc "Original File:"] "\t"] header_key
+ $w_cviewer insert end "[escape_path $file]\n" header_val
+ }
+
+ $w_cviewer insert end "\n$msg"
+ }
+ $w_cviewer conf -state disabled
+
+ set highlight_line $lno
+ set highlight_commit $cmit
+
+ if {[lsearch -exact $tooltip_commit $highlight_commit] != -1} {
+ _hide_tooltip $this
+ }
+}
+
+method _get_click_amov_info {} {
+ set pos @$::cursorX,$::cursorY
+ set lno [lindex [split [$::cursorW index $pos] .] 0]
+ return [lindex $amov_data $lno]
+}
+
+method _copycommit {} {
+ set dat [_get_click_amov_info $this]
+ if {$dat ne {}} {
+ clipboard clear
+ clipboard append \
+ -format STRING \
+ -type STRING \
+ -- [lindex $dat 0]
+ }
+}
+
+method _format_offset_date {base offset} {
+ set exval [expr {$base + $offset*24*60*60}]
+ return [clock format $exval -format {%Y-%m-%d}]
+}
+
+method _gitkcommit {} {
+ global nullid
+
+ set dat [_get_click_amov_info $this]
+ if {$dat ne {}} {
+ set cmit [lindex $dat 0]
+
+ # If the line belongs to the working copy, use HEAD instead
+ if {$cmit eq $nullid} {
+ if {[catch {set cmit [git rev-parse --verify HEAD]} err]} {
+ error_popup [strcat [mc "Cannot find HEAD commit:"] "\n\n$err"]
+ return;
+ }
+ }
+
+ set radius [get_config gui.blamehistoryctx]
+ set cmdline [list --select-commit=$cmit]
+
+ if {$radius > 0} {
+ set author_time {}
+ set committer_time {}
+
+ catch {set author_time $header($cmit,author-time)}
+ catch {set committer_time $header($cmit,committer-time)}
+
+ if {$committer_time eq {}} {
+ set committer_time $author_time
+ }
+
+ set after_time [_format_offset_date $this $committer_time [expr {-$radius}]]
+ set before_time [_format_offset_date $this $committer_time $radius]
+
+ lappend cmdline --after=$after_time --before=$before_time
+ }
+
+ lappend cmdline $cmit
+
+ set base_rev "HEAD"
+ if {$commit ne {}} {
+ set base_rev $commit
+ }
+
+ if {$base_rev ne $cmit} {
+ lappend cmdline $base_rev
+ }
+
+ do_gitk $cmdline
+ }
+}
+
+method _blameparent {} {
+ global nullid
+
+ set dat [_get_click_amov_info $this]
+ if {$dat ne {}} {
+ set cmit [lindex $dat 0]
+ set new_path [lindex $dat 1]
+
+ # Allow using Blame Parent on lines modified in the working copy
+ if {$cmit eq $nullid} {
+ set parent_ref "HEAD"
+ } else {
+ set parent_ref "$cmit^"
+ }
+ if {[catch {set cparent [git rev-parse --verify $parent_ref]} err]} {
+ error_popup [strcat [mc "Cannot find parent commit:"] "\n\n$err"]
+ return;
+ }
+
+ _kill $this
+
+ # Generate a diff between the commit and its parent,
+ # and use the hunks to update the line number.
+ # Request zero context to simplify calculations.
+ if {$cmit eq $nullid} {
+ set diffcmd [list diff-index --unified=0 $cparent -- $new_path]
+ } else {
+ set diffcmd [list diff-tree --unified=0 $cparent $cmit -- $new_path]
+ }
+ if {[catch {set fd [eval git_read $diffcmd]} err]} {
+ $status stop [mc "Unable to display parent"]
+ error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
+ return
+ }
+
+ set r_orig_line [lindex $dat 2]
+
+ fconfigure $fd \
+ -blocking 0 \
+ -encoding binary \
+ -translation binary
+ fileevent $fd readable [cb _read_diff_load_commit \
+ $fd $cparent $new_path $r_orig_line]
+ set current_fd $fd
+ }
+}
+
+method _read_diff_load_commit {fd cparent new_path tline} {
+ if {$fd ne $current_fd} {
+ catch {close $fd}
+ return
+ }
+
+ while {[gets $fd line] >= 0} {
+ if {[regexp {^@@ -(\d+)(,(\d+))? \+(\d+)(,(\d+))? @@} $line line \
+ old_line osz old_size new_line nsz new_size]} {
+
+ if {$osz eq {}} { set old_size 1 }
+ if {$nsz eq {}} { set new_size 1 }
+
+ if {$new_line <= $tline} {
+ if {[expr {$new_line + $new_size}] > $tline} {
+ # Target line within the hunk
+ set line_shift [expr {
+ ($new_size-$old_size)*($tline-$new_line)/$new_size
+ }]
+ } else {
+ set line_shift [expr {$new_size-$old_size}]
+ }
+
+ set r_orig_line [expr {$r_orig_line - $line_shift}]
+ }
+ }
+ }
+
+ if {[eof $fd]} {
+ close $fd
+ set current_fd {}
+
+ _load_new_commit $this \
+ $cparent \
+ $new_path \
+ [list $r_orig_line]
+ }
+} ifdeleted { catch {close $fd} }
+
+method _show_tooltip {cur_w pos} {
+ if {$tooltip_wm ne {}} {
+ _open_tooltip $this $cur_w
+ } elseif {$tooltip_timer eq {}} {
+ set tooltip_timer [after 1000 [cb _open_tooltip $cur_w]]
+ }
+}
+
+method _open_tooltip {cur_w} {
+ set tooltip_timer {}
+ set pos_x [winfo pointerx $cur_w]
+ set pos_y [winfo pointery $cur_w]
+ if {[winfo containing $pos_x $pos_y] ne $cur_w} {
+ _hide_tooltip $this
+ return
+ }
+
+ if {$tooltip_wm ne "$cur_w.tooltip"} {
+ _hide_tooltip $this
+
+ set tooltip_wm [toplevel $cur_w.tooltip -borderwidth 1]
+ catch {wm attributes $tooltip_wm -type tooltip}
+ wm overrideredirect $tooltip_wm 1
+ wm transient $tooltip_wm [winfo toplevel $cur_w]
+ set tooltip_t $tooltip_wm.label
+ text $tooltip_t \
+ -takefocus 0 \
+ -highlightthickness 0 \
+ -relief flat \
+ -borderwidth 0 \
+ -wrap none \
+ -background lightyellow \
+ -foreground black
+ $tooltip_t tag conf section_header -font font_uibold
+ pack $tooltip_t
+ } else {
+ $tooltip_t conf -state normal
+ $tooltip_t delete 0.0 end
+ }
+
+ set pos @[join [list \
+ [expr {$pos_x - [winfo rootx $cur_w]}] \
+ [expr {$pos_y - [winfo rooty $cur_w]}]] ,]
+ set lno [lindex [split [$cur_w index $pos] .] 0]
+ if {$cur_w eq $w_amov} {
+ set dat [lindex $amov_data $lno]
+ set org {}
+ } else {
+ set dat [lindex $asim_data $lno]
+ set org [lindex $amov_data $lno]
+ }
+
+ if {$dat eq {}} {
+ _hide_tooltip $this
+ return
+ }
+
+ set cmit [lindex $dat 0]
+ set tooltip_commit [list $cmit]
+
+ set author_name {}
+ set summary {}
+ set author_time {}
+ catch {set author_name $header($cmit,author)}
+ catch {set summary $header($cmit,summary)}
+ 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"
+ $tooltip_t insert end "$summary"
+
+ if {$org ne {} && [lindex $org 0] ne $cmit} {
+ set save [$tooltip_t get 0.0 end]
+ $tooltip_t delete 0.0 end
+
+ set cmit [lindex $org 0]
+ set file [lindex $org 1]
+ lappend tooltip_commit $cmit
+
+ set author_name {}
+ set summary {}
+ set author_time {}
+ catch {set author_name $header($cmit,author)}
+ catch {set summary $header($cmit,summary)}
+ catch {set author_time [format_date $header($cmit,author-time)]}
+
+ $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 [strcat [mc "In File:"] " "] section_header
+ $tooltip_t insert end "$file\n"
+ }
+
+ $tooltip_t insert end "\n"
+ $tooltip_t insert end [strcat [mc "Copied Or Moved Here By:"] "\n"] section_header
+ $tooltip_t insert end $save
+ }
+
+ $tooltip_t conf -state disabled
+ _position_tooltip $this
+
+ # On MacOS raising a window causes it to acquire focus.
+ # Tk 8.5 on MacOS seems to properly support wm transient,
+ # so we can safely counter the effect there.
+ if {$::have_tk85 && [is_MacOSX]} {
+ update
+ if {$w eq {}} {
+ raise .
+ } else {
+ raise $w
+ }
+ }
+}
+
+method _position_tooltip {} {
+ set max_h [lindex [split [$tooltip_t index end] .] 0]
+ set max_w 0
+ for {set i 1} {$i <= $max_h} {incr i} {
+ set c [lindex [split [$tooltip_t index "$i.0 lineend"] .] 1]
+ if {$c > $max_w} {set max_w $c}
+ }
+ $tooltip_t conf -width $max_w -height $max_h
+
+ set req_w [winfo reqwidth $tooltip_t]
+ set req_h [winfo reqheight $tooltip_t]
+ set pos_x [expr {[winfo pointerx .] + 5}]
+ set pos_y [expr {[winfo pointery .] + 10}]
+
+ set g "${req_w}x${req_h}"
+ if {[tk windowingsystem] eq "win32" || $pos_x >= 0} {append g +}
+ append g $pos_x
+ if {[tk windowingsystem] eq "win32" || $pos_y >= 0} {append g +}
+ append g $pos_y
+
+ wm geometry $tooltip_wm $g
+ if {![is_MacOSX]} {
+ raise $tooltip_wm
+ }
+}
+
+method _hide_tooltip {} {
+ if {$tooltip_wm ne {}} {
+ destroy $tooltip_wm
+ set tooltip_wm {}
+ set tooltip_commit {}
+ }
+ if {$tooltip_timer ne {}} {
+ after cancel $tooltip_timer
+ set tooltip_timer {}
+ }
+}
+
+method _resize {new_height} {
+ set diff [expr {$new_height - $old_height}]
+ if {$diff == 0} return
+
+ set my [expr {[winfo height $w.file_pane] - 25}]
+ set o [$w.file_pane sash coord 0]
+ set ox [lindex $o 0]
+ set oy [expr {[lindex $o 1] + $diff}]
+ if {$oy < 0} {set oy 0}
+ if {$oy > $my} {set oy $my}
+ $w.file_pane sash place 0 $ox $oy
+
+ set old_height $new_height
+}
+
+method _show_finder {} {
+ linebar::hide $gotoline
+ searchbar::show $finder
+}
+
+method _show_linebar {} {
+ searchbar::hide $finder
+ linebar::show $gotoline
+}
+
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Checkout Branch"]]
+# git-gui branch checkout support
+# Copyright (C) 2007 Shawn Pearce
+
+class branch_checkout {
+
+field w ; # widget path
+field w_rev ; # mega-widget to pick the initial revision
+
+field opt_fetch 1; # refetch tracking branch if used?
+field opt_detach 0; # force a detached head case?
+
+constructor dialog {} {
+ global use_ttk NS
+ make_dialog top w
+ wm withdraw $w
++ wm title $top [mc "%s (%s): Checkout Branch" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ ${NS}::label $w.header -text [mc "Checkout Branch"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.create -text [mc Checkout] \
+ -default active \
+ -command [cb _checkout]
+ pack $w.buttons.create -side right
+ ${NS}::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 [mc Revision]]
+ $w_rev bind_listbox <Double-Button-1> [cb _checkout]
+ pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
+
+ ${NS}::labelframe $w.options -text [mc Options]
+
+ ${NS}::checkbutton $w.options.fetch \
+ -text [mc "Fetch Tracking Branch"] \
+ -variable @opt_fetch
+ pack $w.options.fetch -anchor nw
+
+ ${NS}::checkbutton $w.options.detach \
+ -text [mc "Detach From Local Branch"] \
+ -variable @opt_detach
+ pack $w.options.detach -anchor nw
+
+ pack $w.options -anchor nw -fill x -pady 5 -padx 5
+
+ bind $w <Visibility> [cb _visible]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _checkout]\;break
+ wm deiconify $w
+ tkwait window $w
+}
+
+method _checkout {} {
+ set spec [$w_rev get_tracking_branch]
+ if {$spec ne {} && $opt_fetch} {
+ set new {}
+ } elseif {[catch {set new [$w_rev commit_or_die]}]} {
+ return
+ }
+
+ if {$opt_detach} {
+ set ref {}
+ } else {
+ set ref [$w_rev get_local_branch]
+ }
+
+ set co [::checkout_op::new [$w_rev get] $new $ref]
+ $co parent $w
+ $co enable_checkout 1
+ if {$spec ne {} && $opt_fetch} {
+ $co enable_fetch $spec
+ }
+
+ if {[$co run]} {
+ destroy $w
+ } else {
+ $w_rev focus_filter
+ }
+}
+
+method _visible {} {
+ grab $w
+ $w_rev focus_filter
+}
+
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Create Branch"]]
+# git-gui branch create support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+class branch_create {
+
+field w ; # widget path
+field w_rev ; # mega-widget to pick the initial revision
+field w_name ; # new branch name widget
+
+field name {}; # name of the branch the user has chosen
+field name_type user; # type of branch name to use
+
+field opt_merge ff; # type of merge to apply to existing branch
+field opt_checkout 1; # automatically checkout the new branch?
+field opt_fetch 1; # refetch tracking branch if used?
+field reset_ok 0; # did the user agree to reset?
+
+constructor dialog {} {
+ global repo_config use_ttk NS
+
+ make_dialog top w
+ wm withdraw $w
++ wm title $top [mc "%s (%s): Create Branch" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ ${NS}::label $w.header -text [mc "Create New Branch"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.create -text [mc Create] \
+ -default active \
+ -command [cb _create]
+ pack $w.buttons.create -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.desc -text [mc "Branch Name"]
+ ${NS}::radiobutton $w.desc.name_r \
+ -text [mc "Name:"] \
+ -value user \
+ -variable @name_type
+ if {!$use_ttk} {$w.desc.name_r configure -anchor w}
+ set w_name $w.desc.name_t
+ ${NS}::entry $w_name \
+ -width 40 \
+ -textvariable @name \
+ -validate key \
+ -validatecommand [cb _validate %d %S]
+ grid $w.desc.name_r $w_name -sticky we -padx {0 5}
+
+ ${NS}::radiobutton $w.desc.match_r \
+ -text [mc "Match Tracking Branch Name"] \
+ -value match \
+ -variable @name_type
+ if {!$use_ttk} {$w.desc.match_r configure -anchor w}
+ grid $w.desc.match_r -sticky we -padx {0 5} -columnspan 2
+
+ 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 [mc "Starting Revision"]]
+ pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
+
+ ${NS}::labelframe $w.options -text [mc Options]
+
+ ${NS}::frame $w.options.merge
+ ${NS}::label $w.options.merge.l -text [mc "Update Existing Branch:"]
+ pack $w.options.merge.l -side left
+ ${NS}::radiobutton $w.options.merge.no \
+ -text [mc No] \
+ -value none \
+ -variable @opt_merge
+ pack $w.options.merge.no -side left
+ ${NS}::radiobutton $w.options.merge.ff \
+ -text [mc "Fast Forward Only"] \
+ -value ff \
+ -variable @opt_merge
+ pack $w.options.merge.ff -side left
+ ${NS}::radiobutton $w.options.merge.reset \
+ -text [mc Reset] \
+ -value reset \
+ -variable @opt_merge
+ pack $w.options.merge.reset -side left
+ pack $w.options.merge -anchor nw
+
+ ${NS}::checkbutton $w.options.fetch \
+ -text [mc "Fetch Tracking Branch"] \
+ -variable @opt_fetch
+ pack $w.options.fetch -anchor nw
+
+ ${NS}::checkbutton $w.options.checkout \
+ -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
+
+ trace add variable @name_type write [cb _select]
+
+ set name $repo_config(gui.newbranchtemplate)
+ if {[is_config_true gui.matchtrackingbranch]} {
+ set name_type match
+ }
+
+ bind $w <Visibility> [cb _visible]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _create]\;break
+ wm deiconify $w
+ tkwait window $w
+}
+
+method _create {} {
+ global repo_config
+ global M1B
+
+ set spec [$w_rev get_tracking_branch]
+ switch -- $name_type {
+ user {
+ set newbranch $name
+ }
+ match {
+ if {$spec eq {}} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Please select a tracking branch."]
+ return
+ }
+ if {![regsub ^refs/heads/ [lindex $spec 2] {} newbranch]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Tracking branch %s is not a branch in the remote repository." [$w get]]
+ return
+ }
+ }
+ }
+
+ if {$newbranch eq {}
+ || $newbranch eq $repo_config(gui.newbranchtemplate)} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Please supply a branch name."]
+ focus $w_name
+ return
+ }
+
+ if {[catch {git check-ref-format "heads/$newbranch"}]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "'%s' is not an acceptable branch name." $newbranch]
+ focus $w_name
+ return
+ }
+
+ if {$spec ne {} && $opt_fetch} {
+ set new {}
+ } elseif {[catch {set new [$w_rev commit_or_die]}]} {
+ return
+ }
+
+ set co [::checkout_op::new \
+ [$w_rev get] \
+ $new \
+ refs/heads/$newbranch]
+ $co parent $w
+ $co enable_create 1
+ $co enable_merge $opt_merge
+ $co enable_checkout $opt_checkout
+ if {$spec ne {} && $opt_fetch} {
+ $co enable_fetch $spec
+ }
+ if {$spec ne {}} {
+ $co remote_source $spec
+ }
+
+ if {[$co run]} {
+ destroy $w
+ } else {
+ focus $w_name
+ }
+}
+
+method _validate {d S} {
+ if {$d == 1} {
+ if {[regexp {[~^:?*\[\0- ]} $S]} {
+ return 0
+ }
+ if {[string length $S] > 0} {
+ set name_type user
+ }
+ }
+ return 1
+}
+
+method _select {args} {
+ if {$name_type eq {match}} {
+ $w_rev pick_tracking_branch
+ }
+}
+
+method _visible {} {
+ grab $w
+ if {$name_type eq {user}} {
+ $w_name icursor end
+ focus $w_name
+ }
+}
+
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Delete Branch"]]
+# git-gui branch delete support
+# Copyright (C) 2007 Shawn Pearce
+
+class branch_delete {
+
+field w ; # widget path
+field w_heads ; # listbox of local head names
+field w_check ; # revision picker for merge test
+field w_delete ; # delete button
+
+constructor dialog {} {
+ global current_branch use_ttk NS
+
+ make_dialog top w
+ wm withdraw $w
- append failed " - $b: $err\n"
++ wm title $top [mc "%s (%s): Delete Branch" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ ${NS}::label $w.header -text [mc "Delete Local Branch"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ set w_delete $w.buttons.delete
+ ${NS}::button $w_delete \
+ -text [mc Delete] \
+ -default active \
+ -state disabled \
+ -command [cb _delete]
+ pack $w_delete -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.list -text [mc "Local Branches"]
+ set w_heads $w.list.l
+ slistbox $w_heads \
+ -height 10 \
+ -width 70 \
+ -selectmode extended \
+ -exportselection false
+ pack $w.list.l -side left -fill both -expand 1
+ pack $w.list -fill both -expand 1 -pady 5 -padx 5
+
+ set w_check [choose_rev::new \
+ $w.check \
+ [mc "Delete Only If Merged Into"] \
+ ]
+ $w_check none [mc "Always (Do not perform merge checks)"]
+ pack $w.check -anchor nw -fill x -pady 5 -padx 5
+
+ foreach h [load_all_heads] {
+ if {$h ne $current_branch} {
+ $w_heads insert end $h
+ }
+ }
+
+ bind $w_heads <<ListboxSelect>> [cb _select]
+ bind $w <Visibility> "
+ grab $w
+ focus $w
+ "
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _delete]\;break
+ wm deiconify $w
+ tkwait window $w
+}
+
+method _select {} {
+ if {[$w_heads curselection] eq {}} {
+ $w_delete configure -state disabled
+ } else {
+ $w_delete configure -state normal
+ }
+}
+
+method _delete {} {
+ if {[catch {set check_cmt [$w_check commit_or_die]}]} {
+ return
+ }
+
+ set to_delete [list]
+ set not_merged [list]
+ foreach i [$w_heads curselection] {
+ set b [$w_heads get $i]
+ if {[catch {
+ set o [git rev-parse --verify "refs/heads/$b"]
+ }]} continue
+ if {$check_cmt ne {}} {
+ if {[catch {set m [git merge-base $o $check_cmt]}]} continue
+ if {$o ne $m} {
+ lappend not_merged $b
+ continue
+ }
+ }
+ lappend to_delete [list $b $o]
+ }
+ if {$not_merged ne {}} {
+ set msg "[mc "The following branches are not completely merged into %s:" [$w_check get]]
+
+ - [join $not_merged "\n - "]"
+ tk_messageBox \
+ -icon info \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message $msg
+ }
+ if {$to_delete eq {}} return
+ if {$check_cmt eq {}} {
+ set msg [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"]
+ if {[tk_messageBox \
+ -icon warning \
+ -type yesno \
+ -title [wm title $w] \
+ -parent $w \
+ -message $msg] ne yes} {
+ return
+ }
+ }
+
+ set failed {}
+ foreach i $to_delete {
+ set b [lindex $i 0]
+ set o [lindex $i 1]
+ if {[catch {git branch -D $b} err]} {
++ append failed [mc " - %s:" $b] " $err\n"
+ }
+ }
+
+ if {$failed ne {}} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Failed to delete branches:\n%s" $failed]
+ }
+
+ destroy $w
+}
+
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Rename Branch"]]
+# git-gui branch rename support
+# Copyright (C) 2007 Shawn Pearce
+
+class branch_rename {
+
+field w
+field oldname
+field newname
+
+constructor dialog {} {
+ global current_branch use_ttk NS
+
+ make_dialog top w
+ wm withdraw $w
++ wm title $top [mc "%s (%s): Rename Branch" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ set oldname $current_branch
+ set newname [get_config gui.newbranchtemplate]
+
+ ${NS}::label $w.header -text [mc "Rename Branch"]\
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.rename -text [mc Rename] \
+ -default active \
+ -command [cb _rename]
+ pack $w.buttons.rename -side right
+ ${NS}::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
+
+ ${NS}::frame $w.rename
+ ${NS}::label $w.rename.oldname_l -text [mc "Branch:"]
+ if {$use_ttk} {
+ ttk::combobox $w.rename.oldname_m -textvariable @oldname \
+ -values [load_all_heads] -state readonly
+ } else {
+ eval tk_optionMenu $w.rename.oldname_m @oldname [load_all_heads]
+ }
+
+ ${NS}::label $w.rename.newname_l -text [mc "New Name:"]
+ ${NS}::entry $w.rename.newname_t \
+ -width 40 \
+ -textvariable @newname \
+ -validate key \
+ -validatecommand {
+ if {%d == 1 && [regexp {[~^:?*\[\0- ]} %S]} {return 0}
+ return 1
+ }
+
+ grid $w.rename.oldname_l $w.rename.oldname_m -sticky we -padx {0 5}
+ grid $w.rename.newname_l $w.rename.newname_t -sticky we -padx {0 5}
+ grid columnconfigure $w.rename 1 -weight 1
+ pack $w.rename -anchor nw -fill x -pady 5 -padx 5
+
+ bind $w <Key-Return> [cb _rename]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Visibility> "
+ grab $w
+ $w.rename.newname_t icursor end
+ focus $w.rename.newname_t
+ "
+ wm deiconify $w
+ tkwait window $w
+}
+
+method _rename {} {
+ global current_branch
+
+ if {$oldname eq {}} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Please select a branch to rename."]
+ focus $w.rename.oldname_m
+ return
+ }
+ if {$newname eq {}
+ || $newname eq [get_config gui.newbranchtemplate]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Please supply a branch name."]
+ focus $w.rename.newname_t
+ return
+ }
+ if {![catch {git show-ref --verify -- "refs/heads/$newname"}]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Branch '%s' already exists." $newname]
+ focus $w.rename.newname_t
+ return
+ }
+ if {[catch {git check-ref-format "heads/$newname"}]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "'%s' is not an acceptable branch name." $newname]
+ focus $w.rename.newname_t
+ return
+ }
+
+ if {[catch {git branch -m $oldname $newname} err]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [strcat [mc "Failed to rename '%s'." $oldname] "\n\n$err"]
+ return
+ }
+
+ if {$current_branch eq $oldname} {
+ set current_branch $newname
+ }
+
+ destroy $w
+}
+
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "File Browser"]]
+# git-gui tree browser
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+class browser {
+
+image create photo ::browser::img_parent -data {R0lGODlhEAAQAIUAAPwCBBxSHBxOHMTSzNzu3KzCtBRGHCSKFIzCjLzSxBQ2FAxGHDzCLCyeHBQ+FHSmfAwuFBxKLDSCNMzizISyjJzOnDSyLAw+FAQSDAQeDBxWJAwmDAQOBKzWrDymNAQaDAQODAwaDDyKTFSyXFTGTEy6TAQCBAQKDAwiFBQyHAwSFAwmHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAZ1QIBwSCwaj0hiQCBICpcDQsFgGAaIguhhi0gohIsrQEDYMhiNrRfgeAQC5fMCAolIDhD2hFI5WC4YRBkaBxsOE2l/RxsHHA4dHmkfRyAbIQ4iIyQlB5NFGCAACiakpSZEJyinTgAcKSesACorgU4mJ6uxR35BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=}
+image create photo ::browser::img_rblob -data {R0lGODlhEAAQAIUAAPwCBFxaXNze3Ly2rJSWjPz+/Ozq7GxqbJyanPT29HRydMzOzDQyNIyKjERCROTi3Pz69PTy7Pzy7PTu5Ozm3LyqlJyWlJSSjJSOhOzi1LyulPz27PTq3PTm1OzezLyqjIyKhJSKfOzaxPz29OzizLyidIyGdIyCdOTOpLymhOzavOTStMTCtMS+rMS6pMSynMSulLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAaQQIAQECgajcNkQMBkDgKEQFK4LFgLhkMBIVUKroWEYlEgMLxbBKLQUBwc52HgAQ4LBo049atWQyIPA3pEdFcQEhMUFYNVagQWFxgZGoxfYRsTHB0eH5UJCJAYICEinUoPIxIcHCQkIiIllQYEGCEhJicoKYwPmiQeKisrKLFKLCwtLi8wHyUlMYwM0tPUDH5BACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=}
+image create photo ::browser::img_xblob -data {R0lGODlhEAAQAIYAAPwCBFRWVFxaXNza3OTi3Nze3Ly2tJyanPz+/Ozq7GxubNzSxMzOzMTGxHRybDQyNLy+vHRydHx6fKSipISChIyKjGxqbERCRCwuLLy6vGRiZExKTCQiJAwKDLSytLy2rJSSlHx+fDw6PKyqrBQWFPTu5Ozm3LyulLS2tCQmJAQCBPTq3Ozi1MSynCwqLAQGBOTazOzizOzezLyqjBweHNzSvOzaxKyurHRuZNzOtLymhDw+PIyCdOzWvOTOpLyidNzKtOTStLyifMTCtMS+rLyedAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfZgACCAAEChYeGg4oCAwQFjgYBBwGKggEECJkICQoIkwADCwwNDY2mDA4Lng8QDhESsLARExQVDhYXGBkWExIaGw8cHR4SCQQfFQ8eFgUgIQEiwiMSBMYfGB4atwEXDyQd0wQlJicPKAHoFyIpJCoeDgMrLC0YKBsX6i4kL+4OMDEyZijr5oLGNxUqUCioEcPGDAwjPNyI6MEDChQjcOSwsUDHgw07RIgI4KCkAgs8cvTw8eOBogAxQtXIASTISiEuBwUYMoRIixYnZggpUgTDywdIkWJIitRPIAAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
+image create photo ::browser::img_tree -data {R0lGODlhEAAQAIYAAPwCBAQCBExKTBwWHMzKzOzq7ERCRExGTCwqLARqnAQ+ZHR2dKyqrNTOzHx2fCQiJMTi9NTu9HzC3AxmnAQ+XPTm7Dy67DymzITC3IzG5AxypHRydKymrMzOzOzu7BweHByy9AyGtFyy1IzG3NTu/ARupFRSVByazBR6rAyGvFyuzJTK3MTm9BR+tAxWhHS61MTi7Pz+/IymvCxulBRelAx2rHS63Pz6/PTy9PTu9Nza3ISitBRupFSixNTS1CxqnDQyNMzGzOTi5MTCxMTGxGxubGxqbLy2vLSutGRiZLy6vLSytKyurDQuNFxaXKSipDw6PAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAfDgACCAAECg4eIAAMEBQYHCImDBgkKCwwNBQIBBw4Bhw8QERITFJYEFQUFnoIPFhcYoRkaFBscHR4Ggh8gIRciEiMQJBkltCa6JyUoKSkXKhIrLCQYuQAPLS4TEyUhKb0qLzDVAjEFMjMuNBMoNcw21QY3ODkFOjs82RM1PfDzFRU3fOggcM7Fj2pAgggRokOHDx9DhhAZUqQaISBGhjwMEvEIkiIHEgUAkgSJkiNLmFSMJChAEydPGBSBwvJQgAc0/QQCACH+aENyZWF0ZWQgYnkgQk1QVG9HSUYgUHJvIHZlcnNpb24gMi41DQqpIERldmVsQ29yIDE5OTcsMTk5OC4gQWxsIHJpZ2h0cyByZXNlcnZlZC4NCmh0dHA6Ly93d3cuZGV2ZWxjb3IuY29tADs=}
+image create photo ::browser::img_symlink -data {R0lGODlhEAAQAIQAAPwCBCwqLLSytLy+vERGRFRWVDQ2NKSmpAQCBKyurMTGxISChJyanHR2dIyKjGxubHRydGRmZIyOjFxeXHx6fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAVbICACwWieY1CibCCsrBkMb0zchSEcNYskCtqBBzshFkOGQFk0IRqOxqPBODRHCMhCQKteRc9FI/KQWGOIyFYgkDC+gPR4snCcfRGKOIKIgSMQE31+f4OEYCZ+IQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
+image create photo ::browser::img_unknown -data {R0lGODlhEAAQAIUAAPwCBFxaXIyKjNTW1Nze3LS2tJyanER2RGS+VPz+/PTu5GxqbPz69BQ6BCxeLFSqRPT29HRydMzOzDQyNERmPKSypCRWHIyKhERCRDyGPKz2nESiLBxGHCyCHGxubPz6/PTy7Ozi1Ly2rKSipOzm3LyqlKSWhCRyFOzizLymhNTKtNzOvOzaxOTStPz27OzWvOTOpLSupLyedMS+rMS6pMSulLyqjLymfLyifAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAEAAAAALAAAAAAQABAAAAamQIAQECgajcOkYEBoDgoBQyAJOCCuiENCsWBIh9aGw9F4HCARiXciRDQoBUnlYRlcIgsMG5CxXAgMGhscBRAEBRd7AB0eBBoIgxUfICEiikSPgyMMIAokJZcBkBybJgomIaBJAZoMpyCmqkMBFCcVCrgKKAwpoSorKqchKCwtvasIFBIhLiYvLzDHsxQNMcMKLDAwMqEz3jQ1NTY3ONyrE+jp6hN+QQAh/mhDcmVhdGVkIGJ5IEJNUFRvR0lGIFBybyB2ZXJzaW9uIDIuNQ0KqSBEZXZlbENvciAxOTk3LDE5OTguIEFsbCByaWdodHMgcmVzZXJ2ZWQuDQpodHRwOi8vd3d3LmRldmVsY29yLmNvbQA7}
+
+field w
+field browser_commit
+field browser_path
+field browser_files {}
+field browser_status [mc "Starting..."]
+field browser_stack {}
+field browser_busy 1
+
+field ls_buf {}; # Buffered record output from ls-tree
+
+constructor new {commit {path {}}} {
+ global cursor_ptr M1B use_ttk NS
+ make_dialog top w
+ wm withdraw $top
- fconfigure $fd -blocking 0 -translation binary -encoding binary
++ wm title $top [mc "%s (%s): File Browser" [appname] [reponame]]
+
+ if {$path ne {}} {
+ if {[string index $path end] ne {/}} {
+ append path /
+ }
+ }
+
+ set browser_commit $commit
+ set browser_path "$browser_commit:[escape_path $path]"
+
+ ${NS}::label $w.path \
+ -textvariable @browser_path \
+ -anchor w \
+ -justify left \
+ -font font_uibold
+ if {!$use_ttk} { $w.path configure -borderwidth 1 -relief sunken}
+ pack $w.path -anchor w -side top -fill x
+
+ ${NS}::frame $w.list
+ set w_list $w.list.l
+ text $w_list -background white -foreground black \
+ -borderwidth 0 \
+ -cursor $cursor_ptr \
+ -state disabled \
+ -wrap none \
+ -height 20 \
+ -width 70 \
+ -xscrollcommand [list $w.list.sbx set] \
+ -yscrollcommand [list $w.list.sby set]
+ rmsel_tag $w_list
+ ${NS}::scrollbar $w.list.sbx -orient h -command [list $w_list xview]
+ ${NS}::scrollbar $w.list.sby -orient v -command [list $w_list yview]
+ pack $w.list.sbx -side bottom -fill x
+ pack $w.list.sby -side right -fill y
+ pack $w_list -side left -fill both -expand 1
+ pack $w.list -side top -fill both -expand 1
+
+ ${NS}::label $w.status \
+ -textvariable @browser_status \
+ -anchor w \
+ -justify left
+ if {!$use_ttk} { $w.status configure -borderwidth 1 -relief sunken}
+ pack $w.status -anchor w -side bottom -fill x
+
+ bind $w_list <Button-1> "[cb _click 0 @%x,%y];break"
+ bind $w_list <Double-Button-1> "[cb _click 1 @%x,%y];break"
+ bind $w_list <$M1B-Up> "[cb _parent] ;break"
+ bind $w_list <$M1B-Left> "[cb _parent] ;break"
+ bind $w_list <Up> "[cb _move -1] ;break"
+ bind $w_list <Down> "[cb _move 1] ;break"
+ bind $w_list <$M1B-Right> "[cb _enter] ;break"
+ bind $w_list <Return> "[cb _enter] ;break"
+ bind $w_list <Prior> "[cb _page -1] ;break"
+ bind $w_list <Next> "[cb _page 1] ;break"
+ bind $w_list <Left> break
+ bind $w_list <Right> break
+
+ bind $w_list <Visibility> [list focus $w_list]
+ wm deiconify $top
+ set w $w_list
+ if {$path ne {}} {
+ _ls $this $browser_commit:$path $path
+ } else {
+ _ls $this $browser_commit $path
+ }
+ return $this
+}
+
+method _move {dir} {
+ if {$browser_busy} return
+ set lno [lindex [split [$w index in_sel.first] .] 0]
+ incr lno $dir
+ if {[lindex $browser_files [expr {$lno - 1}]] ne {}} {
+ $w tag remove in_sel 0.0 end
+ $w tag add in_sel $lno.0 [expr {$lno + 1}].0
+ $w see $lno.0
+ }
+}
+
+method _page {dir} {
+ if {$browser_busy} return
+ $w yview scroll $dir pages
+ set lno [expr {int(
+ [lindex [$w yview] 0]
+ * [llength $browser_files]
+ + 1)}]
+ if {[lindex $browser_files [expr {$lno - 1}]] ne {}} {
+ $w tag remove in_sel 0.0 end
+ $w tag add in_sel $lno.0 [expr {$lno + 1}].0
+ $w see $lno.0
+ }
+}
+
+method _parent {} {
+ if {$browser_busy} return
+ set info [lindex $browser_files 0]
+ if {[lindex $info 0] eq {parent}} {
+ set parent [lindex $browser_stack end-1]
+ set browser_stack [lrange $browser_stack 0 end-2]
+ if {$browser_stack eq {}} {
+ regsub {:.*$} $browser_path {:} browser_path
+ } else {
+ regsub {/[^/]+/$} $browser_path {/} browser_path
+ }
+ set browser_status [mc "Loading %s..." $browser_path]
+ _ls $this [lindex $parent 0] [lindex $parent 1]
+ }
+}
+
+method _enter {} {
+ if {$browser_busy} return
+ set lno [lindex [split [$w index in_sel.first] .] 0]
+ set info [lindex $browser_files [expr {$lno - 1}]]
+ if {$info ne {}} {
+ switch -- [lindex $info 0] {
+ parent {
+ _parent $this
+ }
+ tree {
+ set name [lindex $info 2]
+ set escn [escape_path $name]
+ set browser_status [mc "Loading %s..." $escn]
+ append browser_path $escn
+ _ls $this [lindex $info 1] $name
+ }
+ blob {
+ set name [lindex $info 2]
+ set p {}
+ foreach n $browser_stack {
+ append p [lindex $n 1]
+ }
+ append p $name
+ blame::new $browser_commit $p {}
+ }
+ }
+ }
+}
+
+method _click {was_double_click pos} {
+ if {$browser_busy} return
+ set lno [lindex [split [$w index $pos] .] 0]
+ focus $w
+
+ if {[lindex $browser_files [expr {$lno - 1}]] ne {}} {
+ $w tag remove in_sel 0.0 end
+ $w tag add in_sel $lno.0 [expr {$lno + 1}].0
+ if {$was_double_click} {
+ _enter $this
+ }
+ }
+}
+
+method _ls {tree_id {name {}}} {
+ set ls_buf {}
+ set browser_files {}
+ set browser_busy 1
+
+ $w conf -state normal
+ $w tag remove in_sel 0.0 end
+ $w delete 0.0 end
+ if {$browser_stack ne {}} {
+ $w image create end \
+ -align center -padx 5 -pady 1 \
+ -name icon0 \
+ -image ::browser::img_parent
+ $w insert end [mc "\[Up To Parent\]"]
+ lappend browser_files parent
+ }
+ lappend browser_stack [list $tree_id $name]
+ $w conf -state disabled
+
+ set fd [git_read ls-tree -z $tree_id]
- wm title $top [append "[appname] ([reponame]): " [mc "Browse Branch Files"]]
++ fconfigure $fd -blocking 0 -translation binary -encoding utf-8
+ fileevent $fd readable [cb _read $fd]
+}
+
+method _read {fd} {
+ append ls_buf [read $fd]
+ set pck [split $ls_buf "\0"]
+ set ls_buf [lindex $pck end]
+
+ set n [llength $browser_files]
+ $w conf -state normal
+ foreach p [lrange $pck 0 end-1] {
+ set tab [string first "\t" $p]
+ if {$tab == -1} continue
+
+ set info [split [string range $p 0 [expr {$tab - 1}]] { }]
+ set path [string range $p [expr {$tab + 1}] end]
+ set type [lindex $info 1]
+ set object [lindex $info 2]
+
+ switch -- $type {
+ blob {
+ scan [lindex $info 0] %o mode
+ if {$mode == 0120000} {
+ set image ::browser::img_symlink
+ } elseif {($mode & 0100) != 0} {
+ set image ::browser::img_xblob
+ } else {
+ set image ::browser::img_rblob
+ }
+ }
+ tree {
+ set image ::browser::img_tree
+ append path /
+ }
+ default {
+ set image ::browser::img_unknown
+ }
+ }
+
+ if {$n > 0} {$w insert end "\n"}
+ $w image create end \
+ -align center -padx 5 -pady 1 \
+ -name icon[incr n] \
+ -image $image
+ $w insert end [escape_path $path]
+ lappend browser_files [list $type $object $path]
+ }
+ $w conf -state disabled
+
+ if {[eof $fd]} {
+ close $fd
+ set browser_status [mc "Ready."]
+ set browser_busy 0
+ set ls_buf {}
+ if {$n > 0} {
+ $w tag add in_sel 1.0 2.0
+ focus -force $w
+ }
+ }
+} ifdeleted {
+ catch {close $fd}
+}
+
+}
+
+class browser_open {
+
+field w ; # widget path
+field w_rev ; # mega-widget to pick the initial revision
+
+constructor dialog {} {
+ global use_ttk NS
+ make_dialog top w
+ wm withdraw $top
++ wm title $top [mc "%s (%s): Browse Branch Files" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ wm transient $top .
+ }
+
+ ${NS}::label $w.header \
+ -text [mc "Browse Branch Files"] \
+ -font font_uibold \
+ -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.browse -text [mc Browse] \
+ -default active \
+ -command [cb _open]
+ pack $w.buttons.browse -side right
+ ${NS}::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 [mc Revision]]
+ $w_rev bind_listbox <Double-Button-1> [cb _open]
+ pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
+
+ bind $w <Visibility> [cb _visible]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _open]\;break
+ wm deiconify $top
+ tkwait window $w
+}
+
+method _open {} {
+ if {[catch {$w_rev commit_or_die} err]} {
+ return
+ }
+ set name [$w_rev get]
+ destroy $w
+ browser::new $name
+}
+
+method _visible {} {
+ grab $w
+ $w_rev focus_filter
+}
+
+}
--- /dev/null
- global HEAD PARENT MERGE_HEAD commit_type ui_comm
+# git-gui misc. commit reading/writing support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc load_last_commit {} {
- global commit_type ui_comm
++ global HEAD PARENT MERGE_HEAD commit_type ui_comm commit_author
+ global repo_config
+
+ if {[llength $PARENT] == 0} {
+ 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 [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
+ }
+
+ set msg {}
+ set parents [list]
+ if {[catch {
+ set fd [git_read cat-file commit $curHEAD]
+ fconfigure $fd -encoding binary -translation lf
+ # By default commits are assumed to be in utf-8
+ set enc utf-8
+ while {[gets $fd line] > 0} {
+ if {[string match {parent *} $line]} {
+ lappend parents [string range $line 7 end]
+ } elseif {[string match {encoding *} $line]} {
+ set enc [string tolower [string range $line 9 end]]
++ } elseif {[regexp "author (.*)\\s<(.*)>\\s(\\d.*$)" $line all name email time]} {
++ set commit_author [list name $name email $email date $time]
+ }
+ }
+ set msg [read $fd]
+ close $fd
+
+ set enc [tcl_encoding $enc]
+ if {$enc ne {}} {
+ set msg [encoding convertfrom $enc $msg]
+ }
+ set msg [string trim $msg]
+ } err]} {
+ error_popup [strcat [mc "Error loading commit data for amend:"] "\n\n$err"]
+ return
+ }
+
+ set HEAD $curHEAD
+ set PARENT $parents
+ set MERGE_HEAD [list]
+ switch -- [llength $parents] {
+ 0 {set commit_type amend-initial}
+ 1 {set commit_type amend}
+ default {set commit_type amend-merge}
+ }
+
+ $ui_comm delete 0.0 end
+ $ui_comm insert end $msg
+ $ui_comm edit reset
+ $ui_comm edit modified false
+ rescan ui_ready
+}
+
+set GIT_COMMITTER_IDENT {}
+
+proc committer_ident {} {
+ global GIT_COMMITTER_IDENT
+
+ if {$GIT_COMMITTER_IDENT eq {}} {
+ if {[catch {set me [git var GIT_COMMITTER_IDENT]} 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 [strcat [mc "Invalid GIT_COMMITTER_IDENT:"] "\n\n$me"]
+ return {}
+ }
+ }
+
+ return $GIT_COMMITTER_IDENT
+}
+
+proc do_signoff {} {
+ global ui_comm
+
+ set me [committer_ident]
+ if {$me eq {}} return
+
+ set sob "Signed-off-by: $me"
+ set last [$ui_comm get {end -1c linestart} {end -1c}]
+ if {$last ne $sob} {
+ $ui_comm edit separator
+ if {$last ne {}
+ && ![regexp {^[A-Z][A-Za-z]*-[A-Za-z-]+: *} $last]} {
+ $ui_comm insert end "\n"
+ }
+ $ui_comm insert end "\n$sob"
+ $ui_comm edit separator
+ $ui_comm see end
+ }
+}
+
+proc create_new_commit {} {
- global HEAD PARENT MERGE_HEAD commit_type
++ global commit_type ui_comm commit_author
+
+ set commit_type normal
++ unset -nocomplain commit_author
+ $ui_comm delete 0.0 end
+ $ui_comm edit reset
+ $ui_comm edit modified false
+ rescan ui_ready
+}
+
+proc setup_commit_encoding {msg_wt {quiet 0}} {
+ global repo_config
+
+ if {[catch {set enc $repo_config(i18n.commitencoding)}]} {
+ set enc utf-8
+ }
+ set use_enc [tcl_encoding $enc]
+ if {$use_enc ne {}} {
+ fconfigure $msg_wt -encoding $use_enc
+ } else {
+ if {!$quiet} {
+ error_popup [mc "warning: Tcl does not support encoding '%s'." $enc]
+ }
+ fconfigure $msg_wt -encoding utf-8
+ }
+}
+
+proc commit_tree {} {
+ global HEAD commit_type file_states ui_comm repo_config
+ global pch_error
+
+ if {[committer_ident] eq {}} return
+ if {![lock_index update]} return
+
+ # -- Our in memory state should match the repository.
+ #
+ repository_state curType curHEAD curMERGE_HEAD
+ if {[string match amend* $commit_type]
+ && $curType eq {normal}
+ && $curHEAD eq $HEAD} {
+ } elseif {$commit_type ne $curType || $HEAD ne $curHEAD} {
+ 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
+ }
+
+ # -- At least one file should differ in the index.
+ #
+ set files_ready 0
+ foreach path [array names file_states] {
+ set s $file_states($path)
+ switch -glob -- [lindex $s 0] {
+ _? {continue}
+ A? -
+ D? -
+ T? -
+ M? {set files_ready 1}
+ _U -
+ U? {
+ error_popup [mc "Unmerged files cannot be committed.
+
+File %s has merge conflicts. You must resolve them and stage the file before committing.
+" [short_path $path]]
+ unlock_index
+ return
+ }
+ default {
+ error_popup [mc "Unknown file state %s detected.
+
+File %s cannot be committed by this program.
+" [lindex $s 0] [short_path $path]]
+ }
+ }
+ }
+ if {!$files_ready && ![string match *merge $curType] && ![is_enabled nocommit]} {
+ info_popup [mc "No changes to commit.
+
+You must stage at least 1 file before you can commit.
+"]
+ unlock_index
+ return
+ }
+
+ if {[is_enabled nocommitmsg]} { do_quit 0 }
+
+ # -- A message is required.
+ #
+ set msg [string trim [$ui_comm get 1.0 end]]
+ regsub -all -line {[ \t\r]+$} $msg {} msg
+ if {$msg eq {}} {
+ error_popup [mc "Please supply a commit message.
+
+A good commit message has the following format:
+
+- First line: Describe in one sentence what you did.
+- Second line: Blank
+- Remaining lines: Describe why this change is good.
+"]
+ unlock_index
+ return
+ }
+
+ # -- Build the message file.
+ #
+ set msg_p [gitdir GITGUI_EDITMSG]
+ set msg_wt [open $msg_p w]
+ fconfigure $msg_wt -translation lf
+ setup_commit_encoding $msg_wt
+ puts $msg_wt $msg
+ close $msg_wt
+
+ if {[is_enabled nocommit]} { do_quit 0 }
+
+ # -- Run the pre-commit hook.
+ #
+ set fd_ph [githook_read pre-commit]
+ if {$fd_ph eq {}} {
+ commit_commitmsg $curHEAD $msg_p
+ return
+ }
+
+ ui_status [mc "Calling pre-commit hook..."]
+ set pch_error {}
+ fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
+ fileevent $fd_ph readable \
+ [list commit_prehook_wait $fd_ph $curHEAD $msg_p]
+}
+
+proc commit_prehook_wait {fd_ph curHEAD msg_p} {
+ global pch_error
+
+ append pch_error [read $fd_ph]
+ fconfigure $fd_ph -blocking 1
+ if {[eof $fd_ph]} {
+ if {[catch {close $fd_ph}]} {
+ catch {file delete $msg_p}
+ ui_status [mc "Commit declined by pre-commit hook."]
+ hook_failed_popup pre-commit $pch_error
+ unlock_index
+ } else {
+ commit_commitmsg $curHEAD $msg_p
+ }
+ set pch_error {}
+ return
+ }
+ fconfigure $fd_ph -blocking 0
+}
+
+proc commit_commitmsg {curHEAD msg_p} {
+ global is_detached repo_config
+ global pch_error
+
+ if {$is_detached
+ && ![file exists [gitdir rebase-merge head-name]]
+ && [is_config_true gui.warndetachedcommit]} {
+ set msg [mc "You are about to commit on a detached head.\
+This is a potentially dangerous thing to do because if you switch\
+to another branch you will lose your changes and it can be difficult\
+to retrieve them later from the reflog. You should probably cancel this\
+commit and create a new branch to continue.\n\
+\n\
+Do you really want to proceed with your Commit?"]
+ if {[ask_popup $msg] ne yes} {
+ unlock_index
+ return
+ }
+ }
+
+ # -- Run the commit-msg hook.
+ #
+ set fd_ph [githook_read commit-msg $msg_p]
+ if {$fd_ph eq {}} {
+ commit_writetree $curHEAD $msg_p
+ return
+ }
+
+ ui_status [mc "Calling commit-msg hook..."]
+ set pch_error {}
+ fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
+ fileevent $fd_ph readable \
+ [list commit_commitmsg_wait $fd_ph $curHEAD $msg_p]
+}
+
+proc commit_commitmsg_wait {fd_ph curHEAD msg_p} {
+ global pch_error
+
+ append pch_error [read $fd_ph]
+ fconfigure $fd_ph -blocking 1
+ if {[eof $fd_ph]} {
+ if {[catch {close $fd_ph}]} {
+ catch {file delete $msg_p}
+ ui_status [mc "Commit declined by commit-msg hook."]
+ hook_failed_popup commit-msg $pch_error
+ unlock_index
+ } else {
+ commit_writetree $curHEAD $msg_p
+ }
+ set pch_error {}
+ return
+ }
+ fconfigure $fd_ph -blocking 0
+}
+
+proc commit_writetree {curHEAD msg_p} {
+ ui_status [mc "Committing changes..."]
+ set fd_wt [git_read write-tree]
+ fileevent $fd_wt readable \
+ [list commit_committree $fd_wt $curHEAD $msg_p]
+}
+
+proc commit_committree {fd_wt curHEAD msg_p} {
++ global HEAD PARENT MERGE_HEAD commit_type commit_author
+ global current_branch
+ global ui_comm selected_commit_type
+ global file_states selected_paths rescan_active
+ global repo_config
++ global env
+
+ gets $fd_wt tree_id
+ if {[catch {close $fd_wt} err]} {
+ catch {file delete $msg_p}
+ error_popup [strcat [mc "write-tree failed:"] "\n\n$err"]
+ ui_status [mc "Commit failed."]
+ unlock_index
+ return
+ }
+
+ # -- Verify this wasn't an empty change.
+ #
+ if {$commit_type eq {normal}} {
+ set fd_ot [git_read cat-file commit $PARENT]
+ fconfigure $fd_ot -encoding binary -translation lf
+ set old_tree [gets $fd_ot]
+ close $fd_ot
+
+ if {[string equal -length 5 {tree } $old_tree]
+ && [string length $old_tree] == 45} {
+ set old_tree [string range $old_tree 5 end]
+ } else {
+ error [mc "Commit %s appears to be corrupt" $PARENT]
+ }
+
+ if {$tree_id eq $old_tree} {
+ catch {file delete $msg_p}
+ 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 [mc "No changes to commit."]}
+ return
+ }
+ }
+
++ if {[info exists commit_author]} {
++ set old_author [commit_author_ident $commit_author]
++ }
+ # -- Create the commit.
+ #
+ set cmd [list commit-tree $tree_id]
+ if {[is_config_true commit.gpgsign]} {
+ lappend cmd -S
+ }
+ foreach p [concat $PARENT $MERGE_HEAD] {
+ lappend cmd -p $p
+ }
+ lappend cmd <$msg_p
+ if {[catch {set cmt_id [eval git $cmd]} err]} {
+ catch {file delete $msg_p}
+ error_popup [strcat [mc "commit-tree failed:"] "\n\n$err"]
+ ui_status [mc "Commit failed."]
+ unlock_index
++ unset -nocomplain commit_author
++ commit_author_reset $old_author
+ return
+ }
++ if {[info exists commit_author]} {
++ unset -nocomplain commit_author
++ commit_author_reset $old_author
++ }
+
+ # -- Update the HEAD ref.
+ #
+ set reflogm commit
+ if {$commit_type ne {normal}} {
+ append reflogm " ($commit_type)"
+ }
+ set msg_fd [open $msg_p r]
+ setup_commit_encoding $msg_fd 1
+ gets $msg_fd subject
+ close $msg_fd
+ append reflogm {: } $subject
+ if {[catch {
+ git update-ref -m $reflogm HEAD $cmt_id $curHEAD
+ } err]} {
+ catch {file delete $msg_p}
+ error_popup [strcat [mc "update-ref failed:"] "\n\n$err"]
+ ui_status [mc "Commit failed."]
+ unlock_index
+ return
+ }
+
+ # -- Cleanup after ourselves.
+ #
+ catch {file delete $msg_p}
+ catch {file delete [gitdir MERGE_HEAD]}
+ catch {file delete [gitdir MERGE_MSG]}
+ catch {file delete [gitdir SQUASH_MSG]}
+ catch {file delete [gitdir GITGUI_MSG]}
+ catch {file delete [gitdir CHERRY_PICK_HEAD]}
+
+ # -- Let rerere do its thing.
+ #
+ if {[get_config rerere.enabled] eq {}} {
+ set rerere [file isdirectory [gitdir rr-cache]]
+ } else {
+ set rerere [is_config_true rerere.enabled]
+ }
+ if {$rerere} {
+ catch {git rerere}
+ }
+
+ # -- Run the post-commit hook.
+ #
+ set fd_ph [githook_read post-commit]
+ if {$fd_ph ne {}} {
+ global pch_error
+ set pch_error {}
+ fconfigure $fd_ph -blocking 0 -translation binary -eofchar {}
+ fileevent $fd_ph readable \
+ [list commit_postcommit_wait $fd_ph $cmt_id]
+ }
+
+ $ui_comm delete 0.0 end
+ $ui_comm edit reset
+ $ui_comm edit modified false
+ if {$::GITGUI_BCK_exists} {
+ catch {file delete [gitdir GITGUI_BCK]}
+ set ::GITGUI_BCK_exists 0
+ }
+
+ if {[is_enabled singlecommit]} { do_quit 0 }
+
+ # -- Update in memory status
+ #
+ set selected_commit_type new
+ set commit_type normal
+ set HEAD $cmt_id
+ set PARENT $cmt_id
+ set MERGE_HEAD [list]
+
+ foreach path [array names file_states] {
+ set s $file_states($path)
+ set m [lindex $s 0]
+ switch -glob -- $m {
+ _O -
+ _M -
+ _D {continue}
+ __ -
+ A_ -
+ M_ -
+ T_ -
+ D_ {
+ unset file_states($path)
+ catch {unset selected_paths($path)}
+ }
+ DO {
+ set file_states($path) [list _O [lindex $s 1] {} {}]
+ }
+ AM -
+ AD -
+ AT -
+ TM -
+ TD -
+ MM -
+ MT -
+ MD {
+ set file_states($path) [list \
+ _[string index $m 1] \
+ [lindex $s 1] \
+ [lindex $s 3] \
+ {}]
+ }
+ }
+ }
+
+ display_all_files
+ unlock_index
+ reshow_diff
+ ui_status [mc "Created commit %s: %s" [string range $cmt_id 0 7] $subject]
+}
+
+proc commit_postcommit_wait {fd_ph cmt_id} {
+ global pch_error
+
+ append pch_error [read $fd_ph]
+ fconfigure $fd_ph -blocking 1
+ if {[eof $fd_ph]} {
+ if {[catch {close $fd_ph}]} {
+ hook_failed_popup post-commit $pch_error 0
+ }
+ unset pch_error
+ return
+ }
+ fconfigure $fd_ph -blocking 0
+}
++
++proc commit_author_ident {details} {
++ global env
++ array set author $details
++ set old [array get env GIT_AUTHOR_*]
++ set env(GIT_AUTHOR_NAME) $author(name)
++ set env(GIT_AUTHOR_EMAIL) $author(email)
++ set env(GIT_AUTHOR_DATE) $author(date)
++ return $old
++}
++proc commit_author_reset {details} {
++ global env
++ unset env(GIT_AUTHOR_NAME) env(GIT_AUTHOR_EMAIL) env(GIT_AUTHOR_DATE)
++ if {$details ne {}} {
++ array set env $details
++ }
++}
--- /dev/null
- ${NS}::label $w.stat.l_$name -text "$label:" -anchor w
+# git-gui object database management support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc do_stats {} {
+ global use_ttk NS
+ set fd [git_read count-objects -v]
+ while {[gets $fd line] > 0} {
+ if {[regexp {^([^:]+): (\d+)$} $line _ name value]} {
+ set stats($name) $value
+ }
+ }
+ close $fd
+
+ set packed_sz 0
+ foreach p [glob -directory [gitdir objects pack] \
+ -type f \
+ -nocomplain -- *] {
+ incr packed_sz [file size $p]
+ }
+ if {$packed_sz > 0} {
+ set stats(size-pack) [expr {$packed_sz / 1024}]
+ }
+
+ set w .stats_view
+ Dialog $w
+ wm withdraw $w
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.close -text [mc Close] \
+ -default active \
+ -command [list destroy $w]
+ ${NS}::button $w.buttons.gc -text [mc "Compress Database"] \
+ -default normal \
+ -command "destroy $w;do_gc"
+ pack $w.buttons.close -side right
+ pack $w.buttons.gc -side left
+ pack $w.buttons -side bottom -fill x -pady 10 -padx 10
+
+ ${NS}::labelframe $w.stat -text [mc "Database Statistics"]
+ foreach s {
+ {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 [eval [lindex $s 1]]
+ if {[catch {set value $stats($name)}]} continue
+ if {[llength $s] > 2} {
+ set value "$value[lindex $s 2]"
+ }
+
- wm title $w [append "[appname] ([reponame]): " [mc "Database Statistics"]]
++ ${NS}::label $w.stat.l_$name -text [mc "%s:" $label] -anchor w
+ ${NS}::label $w.stat.v_$name -text $value -anchor w
+ grid $w.stat.l_$name $w.stat.v_$name -sticky we -padx {0 5}
+ }
+ pack $w.stat -pady 10 -padx 10
+
+ 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 [mc "%s (%s): Database Statistics" [appname] [reponame]]
+ wm deiconify $w
+ tkwait window $w
+}
+
+proc do_gc {} {
+ set w [console::new {gc} [mc "Compressing the object database"]]
+ console::chain $w {
+ {exec git pack-refs --prune}
+ {exec git reflog expire --all}
+ {exec git repack -a -d -l}
+ {exec git rerere gc}
+ }
+}
+
+proc do_fsck_objects {} {
+ set w [console::new {fsck-objects} \
+ [mc "Verifying the object database with fsck-objects"]]
+ set cmd [list git fsck-objects]
+ lappend cmd --full
+ lappend cmd --cache
+ lappend cmd --strict
+ console::exec $w $cmd
+}
+
+proc hint_gc {} {
+ set ndirs 1
+ set limit 8
+ if {[is_Windows]} {
+ set ndirs 4
+ set limit 1
+ }
+
+ set count [llength [glob \
+ -nocomplain \
+ -- \
+ [gitdir objects 4\[0-[expr {$ndirs-1}]\]/*]]]
+
+ if {$count >= $limit * $ndirs} {
+ set objects_current [expr {$count * 256/$ndirs}]
+ if {[ask_popup \
+ [mc "This repository currently has approximately %i loose objects.
+
+To maintain optimal performance it is strongly recommended that you compress the database.
+
+Compress the database now?" $objects_current]] eq yes} {
+ do_gc
+ }
+ }
+}
--- /dev/null
- $ui_diff insert end [append \
- "* " \
- [mc "Git Repository (subproject)"] \
- "\n"] d_info
+# git-gui diff viewer
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc apply_tab_size {{firsttab {}}} {
+ global have_tk85 repo_config ui_diff
+
+ set w [font measure font_diff "0"]
+ if {$have_tk85 && $firsttab != 0} {
+ $ui_diff configure -tabs [list [expr {$firsttab * $w}] [expr {($firsttab + $repo_config(gui.tabsize)) * $w}]]
+ } elseif {$have_tk85 || $repo_config(gui.tabsize) != 8} {
+ $ui_diff configure -tabs [expr {$repo_config(gui.tabsize) * $w}]
+ } else {
+ $ui_diff configure -tabs {}
+ }
+}
+
+proc clear_diff {} {
+ global ui_diff current_diff_path current_diff_header
+ global ui_index ui_workdir
+
+ $ui_diff conf -state normal
+ $ui_diff delete 0.0 end
+ $ui_diff conf -state disabled
+
+ set current_diff_path {}
+ set current_diff_header {}
+
+ $ui_index tag remove in_diff 0.0 end
+ $ui_workdir tag remove in_diff 0.0 end
+}
+
+proc reshow_diff {{after {}}} {
+ global file_states file_lists
+ global current_diff_path current_diff_side
+ global ui_diff
+
+ set p $current_diff_path
+ if {$p eq {}} {
+ # No diff is being shown.
+ } elseif {$current_diff_side eq {}} {
+ clear_diff
+ } elseif {[catch {set s $file_states($p)}]
+ || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
+
+ if {[find_next_diff $current_diff_side $p {} {[^O]}]} {
+ next_diff $after
+ } else {
+ clear_diff
+ }
+ } else {
+ set save_pos [lindex [$ui_diff yview] 0]
+ show_diff $p $current_diff_side {} $save_pos $after
+ }
+}
+
+proc force_diff_encoding {enc} {
+ global current_diff_path
+
+ if {$current_diff_path ne {}} {
+ force_path_encoding $current_diff_path $enc
+ reshow_diff
+ }
+}
+
+proc handle_empty_diff {} {
+ global current_diff_path file_states file_lists
+ global diff_empty_count
+
+ set path $current_diff_path
+ set s $file_states($path)
+ if {[lindex $s 0] ne {_M} || [has_textconv $path]} return
+
+ # Prevent infinite rescan loops
+ incr diff_empty_count
+ if {$diff_empty_count > 1} return
+
+ info_popup [mc "No differences detected.
+
+%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." [short_path $path]]
+
+ clear_diff
+ display_file $path __
+ rescan ui_ready 0
+}
+
+proc show_diff {path w {lno {}} {scroll_pos {}} {callback {}}} {
+ global file_states file_lists
+ global is_3way_diff is_conflict_diff diff_active repo_config
+ global ui_diff ui_index ui_workdir
+ global current_diff_path current_diff_side current_diff_header
+ global current_diff_queue
+
+ if {$diff_active || ![lock_index read]} return
+
+ clear_diff
+ if {$lno == {}} {
+ set lno [lsearch -sorted -exact $file_lists($w) $path]
+ if {$lno >= 0} {
+ incr lno
+ }
+ }
+ if {$lno >= 1} {
+ $w tag add in_diff $lno.0 [expr {$lno + 1}].0
+ $w see $lno.0
+ }
+
+ set s $file_states($path)
+ set m [lindex $s 0]
+ set is_conflict_diff 0
+ set current_diff_path $path
+ set current_diff_side $w
+ set current_diff_queue {}
+ ui_status [mc "Loading diff of %s..." [escape_path $path]]
+
+ set cont_info [list $scroll_pos $callback]
+
+ apply_tab_size 0
+
+ if {[string first {U} $m] >= 0} {
+ merge_load_stages $path [list show_unmerged_diff $cont_info]
+ } elseif {$m eq {_O}} {
+ show_other_diff $path $w $m $cont_info
+ } else {
+ start_show_diff $cont_info
+ }
++
++ global current_diff_path selected_paths
++ set selected_paths($current_diff_path) 1
+}
+
+proc show_unmerged_diff {cont_info} {
+ global current_diff_path current_diff_side
+ global merge_stages ui_diff is_conflict_diff
+ global current_diff_queue
+
+ if {$merge_stages(2) eq {}} {
+ set is_conflict_diff 1
+ lappend current_diff_queue \
+ [list [mc "LOCAL: deleted\nREMOTE:\n"] d= \
+ [list ":1:$current_diff_path" ":3:$current_diff_path"]]
+ } elseif {$merge_stages(3) eq {}} {
+ set is_conflict_diff 1
+ lappend current_diff_queue \
+ [list [mc "REMOTE: deleted\nLOCAL:\n"] d= \
+ [list ":1:$current_diff_path" ":2:$current_diff_path"]]
+ } elseif {[lindex $merge_stages(1) 0] eq {120000}
+ || [lindex $merge_stages(2) 0] eq {120000}
+ || [lindex $merge_stages(3) 0] eq {120000}} {
+ set is_conflict_diff 1
+ lappend current_diff_queue \
+ [list [mc "LOCAL:\n"] d= \
+ [list ":1:$current_diff_path" ":2:$current_diff_path"]]
+ lappend current_diff_queue \
+ [list [mc "REMOTE:\n"] d= \
+ [list ":1:$current_diff_path" ":3:$current_diff_path"]]
+ } else {
+ start_show_diff $cont_info
+ return
+ }
+
+ advance_diff_queue $cont_info
+}
+
+proc advance_diff_queue {cont_info} {
+ global current_diff_queue ui_diff
+
+ set item [lindex $current_diff_queue 0]
+ set current_diff_queue [lrange $current_diff_queue 1 end]
+
+ $ui_diff conf -state normal
+ $ui_diff insert end [lindex $item 0] [lindex $item 1]
+ $ui_diff conf -state disabled
+
+ start_show_diff $cont_info [lindex $item 2]
+}
+
+proc show_other_diff {path w m cont_info} {
+ global file_states file_lists
+ global is_3way_diff diff_active repo_config
+ global ui_diff ui_index ui_workdir
+ global current_diff_path current_diff_side current_diff_header
+
+ # - Git won't give us the diff, there's nothing to compare to!
+ #
+ if {$m eq {_O}} {
+ set max_sz 100000
+ set type unknown
+ if {[catch {
+ 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 {} \
+ -encoding [get_path_encoding $path]
+ 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 [mc "Unable to display %s" [escape_path $path]]
+ error_popup [strcat [mc "Error loading file:"] "\n\n$err"]
+ return
+ }
+ $ui_diff conf -state normal
+ if {$type eq {submodule}} {
- error_popup [append $failed_msg "\n\n$err"]
++ $ui_diff insert end \
++ "* [mc "Git Repository (subproject)"]\n" \
++ d_info
+ } 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]
+ regsub {^:?\s*} $type {} type
+ }
+ $ui_diff insert end "* $type\n" d_info
+ }
+ if {[string first "\0" $content] != -1} {
+ $ui_diff insert end \
+ [mc "* Binary file (not showing content)."] \
+ d_info
+ } else {
+ if {$sz > $max_sz} {
+ $ui_diff insert end [mc \
+"* Untracked file is %d bytes.
+* Showing only first %d bytes.
+" $sz $max_sz] d_info
+ }
+ $ui_diff insert end $content
+ if {$sz > $max_sz} {
+ $ui_diff insert end [mc "
+* Untracked file clipped here by %s.
+* To see the entire file, use an external editor.
+" [appname]] d_info
+ }
+ }
+ $ui_diff conf -state disabled
+ set diff_active 0
+ unlock_index
+ set scroll_pos [lindex $cont_info 0]
+ if {$scroll_pos ne {}} {
+ update
+ $ui_diff yview moveto $scroll_pos
+ }
+ ui_ready
+ set callback [lindex $cont_info 1]
+ if {$callback ne {}} {
+ eval $callback
+ }
+ return
+ }
+}
+
+proc get_conflict_marker_size {path} {
+ set size 7
+ catch {
+ set fd_rc [eval [list git_read check-attr "conflict-marker-size" -- $path]]
+ set ret [gets $fd_rc line]
+ close $fd_rc
+ if {$ret > 0} {
+ regexp {.*: conflict-marker-size: (\d+)$} $line line size
+ }
+ }
+ return $size
+}
+
+proc start_show_diff {cont_info {add_opts {}}} {
+ global file_states file_lists
+ global is_3way_diff is_submodule_diff diff_active repo_config
+ global ui_diff ui_index ui_workdir
+ global current_diff_path current_diff_side current_diff_header
+
+ set path $current_diff_path
+ set w $current_diff_side
+
+ set s $file_states($path)
+ set m [lindex $s 0]
+ set is_3way_diff 0
+ set is_submodule_diff 0
+ set diff_active 1
+ set current_diff_header {}
+ set conflict_size [get_conflict_marker_size $path]
+
+ set cmd [list]
+ if {$w eq $ui_index} {
+ lappend cmd diff-index
+ lappend cmd --cached
+ if {[git-version >= "1.7.2"]} {
+ lappend cmd --ignore-submodules=dirty
+ }
+ } elseif {$w eq $ui_workdir} {
+ if {[string first {U} $m] >= 0} {
+ lappend cmd diff
+ } else {
+ lappend cmd diff-files
+ }
+ }
+ if {![is_config_false gui.textconv] && [git-version >= 1.6.1]} {
+ lappend cmd --textconv
+ }
+
+ if {[string match {160000 *} [lindex $s 2]]
+ || [string match {160000 *} [lindex $s 3]]} {
+ set is_submodule_diff 1
+
+ if {[git-version >= "1.6.6"]} {
+ lappend cmd --submodule
+ }
+ }
+
+ lappend cmd -p
+ lappend cmd --color
+ set cmd [concat $cmd $repo_config(gui.diffopts)]
+ if {$repo_config(gui.diffcontext) >= 1} {
+ lappend cmd "-U$repo_config(gui.diffcontext)"
+ }
+ if {$w eq $ui_index} {
+ lappend cmd [PARENT]
+ }
+ if {$add_opts ne {}} {
+ eval lappend cmd $add_opts
+ } else {
+ lappend cmd --
+ lappend cmd $path
+ }
+
+ if {$is_submodule_diff && [git-version < "1.6.6"]} {
+ if {$w eq $ui_index} {
+ set cmd [list submodule summary --cached -- $path]
+ } else {
+ set cmd [list submodule summary --files -- $path]
+ }
+ }
+
+ if {[catch {set fd [eval git_read --nice $cmd]} err]} {
+ set diff_active 0
+ unlock_index
+ ui_status [mc "Unable to display %s" [escape_path $path]]
+ error_popup [strcat [mc "Error loading diff:"] "\n\n$err"]
+ return
+ }
+
+ set ::current_diff_inheader 1
+ fconfigure $fd \
+ -blocking 0 \
+ -encoding [get_path_encoding $path] \
+ -translation lf
+ fileevent $fd readable [list read_diff $fd $conflict_size $cont_info]
+}
+
+proc parse_color_line {line} {
+ set start 0
+ set result ""
+ set markup [list]
+ set regexp {\033\[((?:\d+;)*\d+)?m}
+ set need_reset 0
+ while {[regexp -indices -start $start $regexp $line match code]} {
+ foreach {begin end} $match break
+ append result [string range $line $start [expr {$begin - 1}]]
+ set pos [string length $result]
+ set col [eval [linsert $code 0 string range $line]]
+ set start [incr end]
+ if {$col eq "0" || $col eq ""} {
+ if {!$need_reset} continue
+ set need_reset 0
+ } else {
+ set need_reset 1
+ }
+ lappend markup $pos $col
+ }
+ append result [string range $line $start end]
+ if {[llength $markup] < 4} {set markup {}}
+ return [list $result $markup]
+}
+
+proc read_diff {fd conflict_size cont_info} {
+ global ui_diff diff_active is_submodule_diff
+ global is_3way_diff is_conflict_diff current_diff_header
+ global current_diff_queue
+ global diff_empty_count
+
+ $ui_diff conf -state normal
+ while {[gets $fd line] >= 0} {
+ foreach {line markup} [parse_color_line $line] break
+ set line [string map {\033 ^} $line]
+
+ set tags {}
+
+ # -- Check for start of diff header.
+ if { [string match {diff --git *} $line]
+ || [string match {diff --cc *} $line]
+ || [string match {diff --combined *} $line]} {
+ set ::current_diff_inheader 1
+ }
+
+ # -- Check for end of diff header (any hunk line will do this).
+ #
+ if {[regexp {^@@+ } $line]} {set ::current_diff_inheader 0}
+
+ # -- Automatically detect if this is a 3 way diff.
+ #
+ if {[string match {@@@ *} $line]} {
+ set is_3way_diff 1
+ apply_tab_size 1
+ }
+
+ if {$::current_diff_inheader} {
+
+ # -- These two lines stop a diff header and shouldn't be in there
+ if { [string match {Binary files * and * differ} $line]
+ || [regexp {^\* Unmerged path } $line]} {
+ set ::current_diff_inheader 0
+ } else {
+ append current_diff_header $line "\n"
+ }
+
+ # -- Cleanup uninteresting diff header lines.
+ #
+ if { [string match {diff --git *} $line]
+ || [string match {diff --cc *} $line]
+ || [string match {diff --combined *} $line]
+ || [string match {--- *} $line]
+ || [string match {+++ *} $line]
+ || [string match {index *} $line]} {
+ continue
+ }
+
+ # -- Name it symlink, not 120000
+ # Note, that the original line is in $current_diff_header
+ regsub {^(deleted|new) file mode 120000} $line {\1 symlink} line
+
+ } elseif { $line eq {\ No newline at end of file}} {
+ # -- Handle some special lines
+ } elseif {$is_3way_diff} {
+ set op [string range $line 0 1]
+ switch -- $op {
+ { } {set tags {}}
+ {@@} {set tags d_@}
+ { +} {set tags d_s+}
+ { -} {set tags d_s-}
+ {+ } {set tags d_+s}
+ {- } {set tags d_-s}
+ {--} {set tags d_--}
+ {++} {
+ set regexp [string map [list %conflict_size $conflict_size]\
+ {^\+\+([<>=]){%conflict_size}(?: |$)}]
+ if {[regexp $regexp $line _g op]} {
+ set is_conflict_diff 1
+ set line [string replace $line 0 1 { }]
+ set tags d$op
+ } else {
+ set tags d_++
+ }
+ }
+ default {
+ puts "error: Unhandled 3 way diff marker: {$op}"
+ set tags {}
+ }
+ }
+ } elseif {$is_submodule_diff} {
+ if {$line == ""} continue
+ if {[regexp {^Submodule } $line]} {
+ set tags d_info
+ } elseif {[regexp {^\* } $line]} {
+ set line [string replace $line 0 1 {Submodule }]
+ set tags d_info
+ } else {
+ set op [string range $line 0 2]
+ switch -- $op {
+ { <} {set tags d_-}
+ { >} {set tags d_+}
+ { W} {set tags {}}
+ default {
+ puts "error: Unhandled submodule diff marker: {$op}"
+ set tags {}
+ }
+ }
+ }
+ } else {
+ set op [string index $line 0]
+ switch -- $op {
+ { } {set tags {}}
+ {@} {set tags d_@}
+ {-} {set tags d_-}
+ {+} {
+ set regexp [string map [list %conflict_size $conflict_size]\
+ {^\+([<>=]){%conflict_size}(?: |$)}]
+ if {[regexp $regexp $line _g op]} {
+ set is_conflict_diff 1
+ set tags d$op
+ } else {
+ set tags d_+
+ }
+ }
+ default {
+ puts "error: Unhandled 2 way diff marker: {$op}"
+ set tags {}
+ }
+ }
+ }
+ set mark [$ui_diff index "end - 1 line linestart"]
+ $ui_diff insert end $line $tags
+ if {[string index $line end] eq "\r"} {
+ $ui_diff tag add d_cr {end - 2c}
+ }
+ $ui_diff insert end "\n" $tags
+
+ foreach {posbegin colbegin posend colend} $markup {
+ set prefix clr
+ foreach style [lsort -integer [split $colbegin ";"]] {
+ if {$style eq "7"} {append prefix i; continue}
+ if {$style != 4 && ($style < 30 || $style > 47)} {continue}
+ set a "$mark linestart + $posbegin chars"
+ set b "$mark linestart + $posend chars"
+ catch {$ui_diff tag add $prefix$style $a $b}
+ }
+ }
+ }
+ $ui_diff conf -state disabled
+
+ if {[eof $fd]} {
+ close $fd
+
+ if {$current_diff_queue ne {}} {
+ advance_diff_queue $cont_info
+ return
+ }
+
+ set diff_active 0
+ unlock_index
+ set scroll_pos [lindex $cont_info 0]
+ if {$scroll_pos ne {}} {
+ update
+ $ui_diff yview moveto $scroll_pos
+ }
+ ui_ready
+
+ if {[$ui_diff index end] eq {2.0}} {
+ handle_empty_diff
+ } else {
+ set diff_empty_count 0
+ }
+
+ set callback [lindex $cont_info 1]
+ if {$callback ne {}} {
+ eval $callback
+ }
+ }
+}
+
+proc apply_hunk {x y} {
+ global current_diff_path current_diff_header current_diff_side
+ global ui_diff ui_index file_states
+
+ if {$current_diff_path eq {} || $current_diff_header eq {}} return
+ if {![lock_index apply_hunk]} return
+
+ set apply_cmd {apply --cached --whitespace=nowarn}
+ set mi [lindex $file_states($current_diff_path) 0]
+ if {$current_diff_side eq $ui_index} {
+ 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 failed_msg [mc "Failed to stage selected hunk."]
+ if {[string index $mi 1] ne {M}} {
+ unlock_index
+ return
+ }
+ }
+
+ set s_lno [lindex [split [$ui_diff index @$x,$y] .] 0]
+ set s_lno [$ui_diff search -backwards -regexp ^@@ $s_lno.0 0.0]
+ if {$s_lno eq {}} {
+ unlock_index
+ return
+ }
+
+ set e_lno [$ui_diff search -forwards -regexp ^@@ "$s_lno + 1 lines" end]
+ if {$e_lno eq {}} {
+ set e_lno end
+ }
+
+ if {[catch {
+ set enc [get_path_encoding $current_diff_path]
+ set p [eval git_write $apply_cmd]
+ fconfigure $p -translation binary -encoding $enc
+ puts -nonewline $p $current_diff_header
+ puts -nonewline $p [$ui_diff get $s_lno $e_lno]
+ close $p} err]} {
- error_popup [append $failed_msg "\n\n$err"]
++ error_popup "$failed_msg\n\n$err"
+ unlock_index
+ return
+ }
+
+ $ui_diff conf -state normal
+ $ui_diff delete $s_lno $e_lno
+ $ui_diff conf -state disabled
+
+ if {[$ui_diff get 1.0 end] eq "\n"} {
+ set o _
+ } else {
+ set o ?
+ }
+
+ if {$current_diff_side eq $ui_index} {
+ set mi ${o}M
+ } elseif {[string index $mi 0] eq {_}} {
+ set mi M$o
+ } else {
+ set mi ?$o
+ }
+ unlock_index
+ display_file $current_diff_path $mi
+ # This should trigger shift to the next changed file
+ if {$o eq {_}} {
+ reshow_diff
+ }
+}
+
+proc apply_range_or_line {x y} {
+ global current_diff_path current_diff_header current_diff_side
+ global ui_diff ui_index file_states
+
+ set selected [$ui_diff tag nextrange sel 0.0]
+
+ if {$selected == {}} {
+ set first [$ui_diff index "@$x,$y"]
+ set last $first
+ } else {
+ set first [lindex $selected 0]
+ set last [lindex $selected 1]
+ }
+
+ set first_l [$ui_diff index "$first linestart"]
+ set last_l [$ui_diff index "$last lineend"]
+
+ if {$current_diff_path eq {} || $current_diff_header eq {}} return
+ if {![lock_index apply_hunk]} return
+
+ set apply_cmd {apply --cached --whitespace=nowarn}
+ set mi [lindex $file_states($current_diff_path) 0]
+ if {$current_diff_side eq $ui_index} {
+ set failed_msg [mc "Failed to unstage selected line."]
+ set to_context {+}
+ lappend apply_cmd --reverse
+ if {[string index $mi 0] ne {M}} {
+ unlock_index
+ return
+ }
+ } else {
+ set failed_msg [mc "Failed to stage selected line."]
+ set to_context {-}
+ if {[string index $mi 1] ne {M}} {
+ unlock_index
+ return
+ }
+ }
+
+ set wholepatch {}
+
+ while {$first_l < $last_l} {
+ set i_l [$ui_diff search -backwards -regexp ^@@ $first_l 0.0]
+ if {$i_l eq {}} {
+ # If there's not a @@ above, then the selected range
+ # must have come before the first_l @@
+ set i_l [$ui_diff search -regexp ^@@ $first_l $last_l]
+ }
+ if {$i_l eq {}} {
+ unlock_index
+ return
+ }
+ # $i_l is now at the beginning of a line
+
+ # pick start line number from hunk header
+ set hh [$ui_diff get $i_l "$i_l + 1 lines"]
+ set hh [lindex [split $hh ,] 0]
+ set hln [lindex [split $hh -] 1]
+
+ # There is a special situation to take care of. Consider this
+ # hunk:
+ #
+ # @@ -10,4 +10,4 @@
+ # context before
+ # -old 1
+ # -old 2
+ # +new 1
+ # +new 2
+ # context after
+ #
+ # We used to keep the context lines in the order they appear in
+ # the hunk. But then it is not possible to correctly stage only
+ # "-old 1" and "+new 1" - it would result in this staged text:
+ #
+ # context before
+ # old 2
+ # new 1
+ # context after
+ #
+ # (By symmetry it is not possible to *un*stage "old 2" and "new
+ # 2".)
+ #
+ # We resolve the problem by introducing an asymmetry, namely,
+ # when a "+" line is *staged*, it is moved in front of the
+ # context lines that are generated from the "-" lines that are
+ # immediately before the "+" block. That is, we construct this
+ # patch:
+ #
+ # @@ -10,4 +10,5 @@
+ # context before
+ # +new 1
+ # old 1
+ # old 2
+ # context after
+ #
+ # But we do *not* treat "-" lines that are *un*staged in a
+ # special way.
+ #
+ # With this asymmetry it is possible to stage the change "old
+ # 1" -> "new 1" directly, and to stage the change "old 2" ->
+ # "new 2" by first staging the entire hunk and then unstaging
+ # the change "old 1" -> "new 1".
+ #
+ # Applying multiple lines adds complexity to the special
+ # situation. The pre_context must be moved after the entire
+ # first block of consecutive staged "+" lines, so that
+ # staging both additions gives the following patch:
+ #
+ # @@ -10,4 +10,6 @@
+ # context before
+ # +new 1
+ # +new 2
+ # old 1
+ # old 2
+ # context after
+
+ # This is non-empty if and only if we are _staging_ changes;
+ # then it accumulates the consecutive "-" lines (after
+ # converting them to context lines) in order to be moved after
+ # "+" change lines.
+ set pre_context {}
+
+ set n 0
+ set m 0
+ set i_l [$ui_diff index "$i_l + 1 lines"]
+ set patch {}
+ while {[$ui_diff compare $i_l < "end - 1 chars"] &&
+ [$ui_diff get $i_l "$i_l + 2 chars"] ne {@@}} {
+ set next_l [$ui_diff index "$i_l + 1 lines"]
+ set c1 [$ui_diff get $i_l]
+ if {[$ui_diff compare $first_l <= $i_l] &&
+ [$ui_diff compare $i_l < $last_l] &&
+ ($c1 eq {-} || $c1 eq {+})} {
+ # a line to stage/unstage
+ set ln [$ui_diff get $i_l $next_l]
+ if {$c1 eq {-}} {
+ set n [expr $n+1]
+ set patch "$patch$pre_context$ln"
+ set pre_context {}
+ } else {
+ set m [expr $m+1]
+ set patch "$patch$ln"
+ }
+ } elseif {$c1 ne {-} && $c1 ne {+}} {
+ # context line
+ set ln [$ui_diff get $i_l $next_l]
+ set patch "$patch$pre_context$ln"
+ # Skip the "\ No newline at end of
+ # file". Depending on the locale setting
+ # we don't know what this line looks
+ # like exactly. The only thing we do
+ # know is that it starts with "\ "
+ if {![string match {\\ *} $ln]} {
+ set n [expr $n+1]
+ set m [expr $m+1]
+ }
+ set pre_context {}
+ } elseif {$c1 eq $to_context} {
+ # turn change line into context line
+ set ln [$ui_diff get "$i_l + 1 chars" $next_l]
+ if {$c1 eq {-}} {
+ set pre_context "$pre_context $ln"
+ } else {
+ set patch "$patch $ln"
+ }
+ set n [expr $n+1]
+ set m [expr $m+1]
+ } else {
+ # a change in the opposite direction of
+ # to_context which is outside the range of
+ # lines to apply.
+ set patch "$patch$pre_context"
+ set pre_context {}
+ }
+ set i_l $next_l
+ }
+ set patch "$patch$pre_context"
+ set wholepatch "$wholepatch@@ -$hln,$n +$hln,$m @@\n$patch"
+ set first_l [$ui_diff index "$next_l + 1 lines"]
+ }
+
+ if {[catch {
+ set enc [get_path_encoding $current_diff_path]
+ set p [eval git_write $apply_cmd]
+ fconfigure $p -translation binary -encoding $enc
+ puts -nonewline $p $current_diff_header
+ puts -nonewline $p $wholepatch
+ close $p} err]} {
++ error_popup "$failed_msg\n\n$err"
+ }
+
+ unlock_index
+}
--- /dev/null
- -title [append "$title: " [mc "error"]] \
+# git-gui branch (create/delete) support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc _error_parent {} {
+ set p [grab current .]
+ if {$p eq {}} {
+ return .
+ }
+ return $p
+}
+
+proc error_popup {msg} {
+ set title [appname]
+ if {[reponame] ne {}} {
+ append title " ([reponame])"
+ }
+ set cmd [list tk_messageBox \
+ -icon error \
+ -type ok \
- -title [append "$title: " [mc "warning"]] \
++ -title [mc "%s: error" $title] \
+ -message $msg]
+ if {[winfo ismapped [_error_parent]]} {
+ lappend cmd -parent [_error_parent]
+ }
+ eval $cmd
+}
+
+proc warn_popup {msg} {
+ set title [appname]
+ if {[reponame] ne {}} {
+ append title " ([reponame])"
+ }
+ set cmd [list tk_messageBox \
+ -icon warning \
+ -type ok \
- ${NS}::label $w.m.l1 -text "$hook hook failed:" \
++ -title [mc "%s: warning" $title] \
+ -message $msg]
+ if {[winfo ismapped [_error_parent]]} {
+ lappend cmd -parent [_error_parent]
+ }
+ eval $cmd
+}
+
+proc info_popup {msg} {
+ set title [appname]
+ if {[reponame] ne {}} {
+ append title " ([reponame])"
+ }
+ tk_messageBox \
+ -parent [_error_parent] \
+ -icon info \
+ -type ok \
+ -title $title \
+ -message $msg
+}
+
+proc ask_popup {msg} {
+ set title [appname]
+ if {[reponame] ne {}} {
+ append title " ([reponame])"
+ }
+ set cmd [list tk_messageBox \
+ -icon question \
+ -type yesno \
+ -title $title \
+ -message $msg]
+ if {[winfo ismapped [_error_parent]]} {
+ lappend cmd -parent [_error_parent]
+ }
+ eval $cmd
+}
+
+proc hook_failed_popup {hook msg {is_fatal 1}} {
+ global use_ttk NS
+ set w .hookfail
+ Dialog $w
+ wm withdraw $w
+
+ ${NS}::frame $w.m
- wm title $w [strcat "[appname] ([reponame]): " [mc "error"]]
++ ${NS}::label $w.m.l1 -text [mc "%s hook failed:" $hook] \
+ -anchor w \
+ -justify left \
+ -font font_uibold
+ text $w.m.t \
+ -background white \
+ -foreground black \
+ -borderwidth 1 \
+ -relief sunken \
+ -width 80 -height 10 \
+ -font font_diff \
+ -yscrollcommand [list $w.m.sby set]
+ ${NS}::scrollbar $w.m.sby -command [list $w.m.t yview]
+ pack $w.m.l1 -side top -fill x
+ if {$is_fatal} {
+ ${NS}::label $w.m.l2 \
+ -text [mc "You must correct the above errors before committing."] \
+ -anchor w \
+ -justify left \
+ -font font_uibold
+ pack $w.m.l2 -side bottom -fill x
+ }
+ pack $w.m.sby -side right -fill y
+ pack $w.m.t -side left -fill both -expand 1
+ pack $w.m -side top -fill both -expand 1 -padx 5 -pady 10
+
+ $w.m.t insert 1.0 $msg
+ $w.m.t conf -state disabled
+
+ ${NS}::button $w.ok -text OK \
+ -width 15 \
+ -command "destroy $w"
+ pack $w.ok -side bottom -anchor e -pady 10 -padx 10
+
+ bind $w <Visibility> "grab $w; focus $w"
+ bind $w <Key-Return> "destroy $w"
++ wm title $w [mc "%s (%s): error" [appname] [reponame]]
+ wm deiconify $w
+ tkwait window $w
+}
--- /dev/null
- puts -nonewline $fd "$info\t[encoding convertto $path]\0"
+# git-gui index (add/remove) support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc _delete_indexlock {} {
+ if {[catch {file delete -- [gitdir index.lock]} err]} {
+ error_popup [strcat [mc "Unable to unlock the index."] "\n\n$err"]
+ }
+}
+
+proc _close_updateindex {fd after} {
+ global use_ttk NS
+ fconfigure $fd -blocking 1
+ if {[catch {close $fd} err]} {
+ set w .indexfried
+ Dialog $w
+ wm withdraw $w
+ wm title $w [strcat "[appname] ([reponame]): " [mc "Index Error"]]
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+ set s [mc "Updating the Git index failed. A rescan will be automatically started to resynchronize git-gui."]
+ text $w.msg -yscrollcommand [list $w.vs set] \
+ -width [string length $s] -relief flat \
+ -borderwidth 0 -highlightthickness 0 \
+ -background [get_bg_color $w]
+ $w.msg tag configure bold -font font_uibold -justify center
+ ${NS}::scrollbar $w.vs -command [list $w.msg yview]
+ $w.msg insert end $s bold \n\n$err {}
+ $w.msg configure -state disabled
+
+ ${NS}::button $w.continue \
+ -text [mc "Continue"] \
+ -command [list destroy $w]
+ ${NS}::button $w.unlock \
+ -text [mc "Unlock Index"] \
+ -command "destroy $w; _delete_indexlock"
+ grid $w.msg - $w.vs -sticky news
+ grid $w.unlock $w.continue - -sticky se -padx 2 -pady 2
+ grid columnconfigure $w 0 -weight 1
+ grid rowconfigure $w 0 -weight 1
+
+ wm protocol $w WM_DELETE_WINDOW update
+ bind $w.continue <Visibility> "
+ grab $w
+ focus %W
+ "
+ wm deiconify $w
+ tkwait window $w
+
+ $::main_status stop
+ unlock_index
+ rescan $after 0
+ return
+ }
+
+ $::main_status stop
+ unlock_index
+ uplevel #0 $after
+}
+
+proc update_indexinfo {msg pathList after} {
+ global update_index_cp
+
+ if {![lock_index update]} return
+
+ set update_index_cp 0
+ set pathList [lsort $pathList]
+ set totalCnt [llength $pathList]
+ set batch [expr {int($totalCnt * .01) + 1}]
+ if {$batch > 25} {set batch 25}
+
+ $::main_status start $msg [mc "files"]
+ set fd [git_write update-index -z --index-info]
+ fconfigure $fd \
+ -blocking 0 \
+ -buffering full \
+ -buffersize 512 \
+ -encoding binary \
+ -translation binary
+ fileevent $fd writable [list \
+ write_update_indexinfo \
+ $fd \
+ $pathList \
+ $totalCnt \
+ $batch \
+ $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_updateindex $fd $after
+ return
+ }
+
+ for {set i $batch} \
+ {$update_index_cp < $totalCnt && $i > 0} \
+ {incr i -1} {
+ set path [lindex $pathList $update_index_cp]
+ incr update_index_cp
+
+ set s $file_states($path)
+ switch -glob -- [lindex $s 0] {
+ A? {set new _O}
+ MT -
+ TM -
+ T_ {set new _T}
+ M? {set new _M}
+ TD -
+ D_ {set new _D}
+ D? {set new _?}
+ ?? {continue}
+ }
+ set info [lindex $s 2]
+ if {$info eq {}} continue
+
- puts -nonewline $fd "[encoding convertto $path]\0"
++ puts -nonewline $fd "$info\t[encoding convertto utf-8 $path]\0"
+ display_file $path $new
+ }
+
+ $::main_status update $update_index_cp $totalCnt
+}
+
+proc update_index {msg pathList after} {
+ global update_index_cp
+
+ if {![lock_index update]} return
+
+ set update_index_cp 0
+ set pathList [lsort $pathList]
+ set totalCnt [llength $pathList]
+ set batch [expr {int($totalCnt * .01) + 1}]
+ if {$batch > 25} {set batch 25}
+
+ $::main_status start $msg [mc "files"]
+ set fd [git_write update-index --add --remove -z --stdin]
+ fconfigure $fd \
+ -blocking 0 \
+ -buffering full \
+ -buffersize 512 \
+ -encoding binary \
+ -translation binary
+ fileevent $fd writable [list \
+ write_update_index \
+ $fd \
+ $pathList \
+ $totalCnt \
+ $batch \
+ $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_updateindex $fd $after
+ return
+ }
+
+ for {set i $batch} \
+ {$update_index_cp < $totalCnt && $i > 0} \
+ {incr i -1} {
+ set path [lindex $pathList $update_index_cp]
+ incr update_index_cp
+
+ switch -glob -- [lindex $file_states($path) 0] {
+ AD {set new __}
+ ?D {set new D_}
+ _O -
+ AT -
+ AM {set new A_}
+ TM -
+ MT -
+ _T {set new T_}
+ _U -
+ U? {
+ if {[file exists $path]} {
+ set new M_
+ } else {
+ set new D_
+ }
+ }
+ ?M {set new M_}
+ ?? {continue}
+ }
- puts -nonewline $fd "[encoding convertto $path]\0"
++ puts -nonewline $fd "[encoding convertto utf-8 $path]\0"
+ display_file $path $new
+ }
+
+ $::main_status update $update_index_cp $totalCnt
+}
+
+proc checkout_index {msg pathList after} {
+ global update_index_cp
+
+ if {![lock_index update]} return
+
+ set update_index_cp 0
+ set pathList [lsort $pathList]
+ set totalCnt [llength $pathList]
+ set batch [expr {int($totalCnt * .01) + 1}]
+ if {$batch > 25} {set batch 25}
+
+ $::main_status start $msg [mc "files"]
+ set fd [git_write checkout-index \
+ --index \
+ --quiet \
+ --force \
+ -z \
+ --stdin \
+ ]
+ fconfigure $fd \
+ -blocking 0 \
+ -buffering full \
+ -buffersize 512 \
+ -encoding binary \
+ -translation binary
+ fileevent $fd writable [list \
+ write_checkout_index \
+ $fd \
+ $pathList \
+ $totalCnt \
+ $batch \
+ $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_updateindex $fd $after
+ return
+ }
+
+ for {set i $batch} \
+ {$update_index_cp < $totalCnt && $i > 0} \
+ {incr i -1} {
+ set path [lindex $pathList $update_index_cp]
+ incr update_index_cp
+ switch -glob -- [lindex $file_states($path) 0] {
+ U? {continue}
+ ?M -
+ ?T -
+ ?D {
++ puts -nonewline $fd "[encoding convertto utf-8 $path]\0"
+ display_file $path ?_
+ }
+ }
+ }
+
+ $::main_status update $update_index_cp $totalCnt
+}
+
+proc unstage_helper {txt paths} {
+ global file_states current_diff_path
+
+ if {![lock_index begin-update]} return
+
+ set pathList [list]
+ set after {}
+ foreach path $paths {
+ switch -glob -- [lindex $file_states($path) 0] {
+ A? -
+ M? -
+ T? -
+ D? {
+ lappend pathList $path
+ if {$path eq $current_diff_path} {
+ set after {reshow_diff;}
+ }
+ }
+ }
+ }
+ if {$pathList eq {}} {
+ unlock_index
+ } else {
+ update_indexinfo \
+ $txt \
+ $pathList \
+ [concat $after [list ui_ready]]
+ }
+}
+
+proc do_unstage_selection {} {
+ global current_diff_path selected_paths
+
+ if {[array size selected_paths] > 0} {
+ unstage_helper \
+ [mc "Unstaging selected files from commit"] \
+ [array names selected_paths]
+ } elseif {$current_diff_path ne {}} {
+ unstage_helper \
+ [mc "Unstaging %s from commit" [short_path $current_diff_path]] \
+ [list $current_diff_path]
+ }
+}
+
+proc add_helper {txt paths} {
+ global file_states current_diff_path
+
+ if {![lock_index begin-update]} return
+
+ set pathList [list]
+ set after {}
+ foreach path $paths {
+ switch -glob -- [lindex $file_states($path) 0] {
+ _U -
+ U? {
+ if {$path eq $current_diff_path} {
+ unlock_index
+ merge_stage_workdir $path
+ return
+ }
+ }
+ _O -
+ ?M -
+ ?D -
+ ?T {
+ lappend pathList $path
+ if {$path eq $current_diff_path} {
+ set after {reshow_diff;}
+ }
+ }
+ }
+ }
+ if {$pathList eq {}} {
+ unlock_index
+ } else {
+ update_index \
+ $txt \
+ $pathList \
+ [concat $after {ui_status [mc "Ready to commit."]}]
+ }
+}
+
+proc do_add_selection {} {
+ global current_diff_path selected_paths
+
+ if {[array size selected_paths] > 0} {
+ add_helper \
+ [mc "Adding selected files"] \
+ [array names selected_paths]
+ } elseif {$current_diff_path ne {}} {
+ add_helper \
+ [mc "Adding %s" [short_path $current_diff_path]] \
+ [list $current_diff_path]
+ }
+}
+
+proc do_add_all {} {
+ global file_states
+
+ set paths [list]
+ set untracked_paths [list]
+ foreach path [array names file_states] {
+ switch -glob -- [lindex $file_states($path) 0] {
+ U? {continue}
+ ?M -
+ ?T -
+ ?D {lappend paths $path}
+ ?O {lappend untracked_paths $path}
+ }
+ }
+ if {[llength $untracked_paths]} {
+ set reply 0
+ switch -- [get_config gui.stageuntracked] {
+ no {
+ set reply 0
+ }
+ yes {
+ set reply 1
+ }
+ ask -
+ default {
+ set reply [ask_popup [mc "Stage %d untracked files?" \
+ [llength $untracked_paths]]]
+ }
+ }
+ if {$reply} {
+ set paths [concat $paths $untracked_paths]
+ }
+ }
+ add_helper [mc "Adding all changed files"] $paths
+}
+
+proc revert_helper {txt paths} {
+ global file_states current_diff_path
+
+ if {![lock_index begin-update]} return
+
+ set pathList [list]
+ set after {}
+ foreach path $paths {
+ switch -glob -- [lindex $file_states($path) 0] {
+ U? {continue}
+ ?M -
+ ?T -
+ ?D {
+ lappend pathList $path
+ if {$path eq $current_diff_path} {
+ set after {reshow_diff;}
+ }
+ }
+ }
+ }
+
+
+ # 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 different 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 query [mc "Revert changes in file %s?" [short_path [lindex $pathList]]]
+ } else {
+ set query [mc "Revert changes in these %i files?" $n]
+ }
+
+ set reply [tk_dialog \
+ .confirm_revert \
+ "[appname] ([reponame])" \
+ "$query
+
+[mc "Any unstaged changes will be permanently lost by the revert."]" \
+ question \
+ 1 \
+ [mc "Do Nothing"] \
+ [mc "Revert Changes"] \
+ ]
+ if {$reply == 1} {
+ checkout_index \
+ $txt \
+ $pathList \
+ [concat $after [list ui_ready]]
+ } else {
+ unlock_index
+ }
+}
+
+proc do_revert_selection {} {
+ global current_diff_path selected_paths
+
+ if {[array size selected_paths] > 0} {
+ revert_helper \
+ [mc "Reverting selected files"] \
+ [array names selected_paths]
+ } elseif {$current_diff_path ne {}} {
+ revert_helper \
+ [mc "Reverting %s" [short_path $current_diff_path]] \
+ [list $current_diff_path]
+ }
+}
+
+proc do_select_commit_type {} {
+ global commit_type selected_commit_type
+
+ if {$selected_commit_type eq {new}
+ && [string match amend* $commit_type]} {
+ create_new_commit
+ } elseif {$selected_commit_type eq {amend}
+ && ![string match amend* $commit_type]} {
+ load_last_commit
+
+ # The amend request was rejected...
+ #
+ if {![string match amend* $commit_type]} {
+ set selected_commit_type new
+ }
+ }
+}
--- /dev/null
- set cmd [list git merge --strategy=recursive FETCH_HEAD]
+# git-gui branch merge support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+class merge {
+
+field w ; # top level window
+field w_rev ; # mega-widget to pick the revision to merge
+
+method _can_merge {} {
+ global HEAD commit_type file_states
+
+ if {[string match amend* $commit_type]} {
+ info_popup [mc "Cannot merge while amending.
+
+You must finish amending this commit before starting any type of merge.
+"]
+ return 0
+ }
+
+ if {[committer_ident] eq {}} {return 0}
+ if {![lock_index merge]} {return 0}
+
+ # -- Our in memory state should match the repository.
+ #
+ repository_state curType curHEAD curMERGE_HEAD
+ if {$commit_type ne $curType || $HEAD ne $curHEAD} {
+ 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
+ }
+
+ foreach path [array names file_states] {
+ switch -glob -- [lindex $file_states($path) 0] {
+ _O {
+ continue; # and pray it works!
+ }
+ _U -
+ U? {
+ error_popup [mc "You are in the middle of a conflicted merge.
+
+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 [mc "You are in the middle of a change.
+
+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
+ }
+ }
+ }
+
+ return 1
+}
+
+method _rev {} {
+ if {[catch {$w_rev commit_or_die}]} {
+ return {}
+ }
+ return [$w_rev get]
+}
+
+method _visualize {} {
+ set rev [_rev $this]
+ if {$rev ne {}} {
+ do_gitk [list $rev --not HEAD]
+ }
+}
+
+method _start {} {
+ global HEAD current_branch remote_url
+ global _last_merged_branch
+
+ set name [_rev $this]
+ if {$name eq {}} {
+ return
+ }
+
+ set spec [$w_rev get_tracking_branch]
+ set cmit [$w_rev get_commit]
+
+ set fh [open [gitdir FETCH_HEAD] w]
+ fconfigure $fh -translation lf
+ if {$spec eq {}} {
+ set remote .
+ set branch $name
+ set stitle $branch
+ } else {
+ set remote $remote_url([lindex $spec 1])
+ if {[regexp {^[^:@]*@[^:]*:/} $remote]} {
+ regsub {^[^:@]*@} $remote {} remote
+ }
+ set branch [lindex $spec 2]
+ set stitle [mc "%s of %s" $branch $remote]
+ }
+ regsub ^refs/heads/ $branch {} branch
+ puts $fh "$cmit\t\tbranch '$branch' of $remote"
+ close $fh
+ set _last_merged_branch $branch
+
- wm title $top [append "[appname] ([reponame]): " [mc "Merge"]]
++ if {[git-version >= "2.5.0"]} {
++ set cmd [list git merge --strategy=recursive FETCH_HEAD]
++ } else {
++ set cmd [list git]
++ lappend cmd merge
++ lappend cmd --strategy=recursive
++ lappend cmd [git fmt-merge-msg <[gitdir FETCH_HEAD]]
++ lappend cmd HEAD
++ lappend cmd $name
++ }
+
+ ui_status [mc "Merging %s and %s..." $current_branch $stitle]
+ set cons [console::new [mc "Merge"] "merge $stitle"]
+ console::exec $cons $cmd [cb _finish $cons]
+
+ wm protocol $w WM_DELETE_WINDOW {}
+ destroy $w
+}
+
+method _finish {cons ok} {
+ console::done $cons $ok
+ if {$ok} {
+ set msg [mc "Merge completed successfully."]
+ } else {
+ set msg [mc "Merge failed. Conflict resolution is required."]
+ }
+ unlock_index
+ rescan [list ui_status $msg]
+ delete_this
+}
+
+constructor dialog {} {
+ global current_branch
+ global M1B use_ttk NS
+
+ if {![_can_merge $this]} {
+ delete_this
+ return
+ }
+
+ make_dialog top w
++ wm title $top [mc "%s (%s): Merge" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ set _start [cb _start]
+
+ ${NS}::label $w.header \
+ -text [mc "Merge Into %s" $current_branch] \
+ -font font_uibold
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.visualize \
+ -text [mc Visualize] \
+ -command [cb _visualize]
+ pack $w.buttons.visualize -side left
+ ${NS}::button $w.buttons.merge \
+ -text [mc Merge] \
+ -command $_start
+ pack $w.buttons.merge -side right
+ ${NS}::button $w.buttons.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 [mc "Revision To Merge"]]
+ pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
+
+ bind $w <$M1B-Key-Return> $_start
+ bind $w <Key-Return> $_start
+ bind $w <Key-Escape> [cb _cancel]
+ wm protocol $w WM_DELETE_WINDOW [cb _cancel]
+
+ bind $w.buttons.merge <Visibility> [cb _visible]
+ tkwait window $w
+}
+
+method _visible {} {
+ grab $w
+ if {[is_config_true gui.matchtrackingbranch]} {
+ $w_rev pick_tracking_branch
+ }
+ $w_rev focus_filter
+}
+
+method _cancel {} {
+ wm protocol $w WM_DELETE_WINDOW {}
+ unlock_index
+ destroy $w
+ delete_this
+}
+
+}
+
+namespace eval merge {
+
+proc reset_hard {} {
+ global HEAD commit_type file_states
+
+ if {[string match amend* $commit_type]} {
+ 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 [mc "Abort merge?
+
+Aborting the current merge will cause *ALL* uncommitted changes to be lost.
+
+Continue with aborting the current merge?"]
+ } else {
+ set op_question [mc "Reset changes?
+
+Resetting the changes will cause *ALL* uncommitted changes to be lost.
+
+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 [mc "Aborting"] [mc "files reset"]
+ } else {
+ unlock_index
+ }
+}
+
+proc _reset_wait {fd} {
+ global ui_comm
+
+ $::main_status update_meter [read $fd]
+
+ fconfigure $fd -blocking 1
+ if {[eof $fd]} {
+ set fail [catch {close $fd} err]
+ $::main_status stop
+ unlock_index
+
+ $ui_comm delete 0.0 end
+ $ui_comm edit modified false
+
+ catch {file delete [gitdir MERGE_HEAD]}
+ catch {file delete [gitdir rr-cache MERGE_RR]}
+ catch {file delete [gitdir MERGE_RR]}
+ catch {file delete [gitdir SQUASH_MSG]}
+ catch {file delete [gitdir MERGE_MSG]}
+ catch {file delete [gitdir GITGUI_MSG]}
+
+ if {$fail} {
+ warn_popup "[mc "Abort failed."]\n\n$err"
+ }
+ rescan {ui_status [mc "Abort completed. Ready."]}
+ } else {
+ fconfigure $fd -blocking 0
+ }
+}
+
+}
--- /dev/null
- ${NS}::label $w.$f.$optid.l -text "$text:"
+# git-gui options editor
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc config_check_encodings {} {
+ global repo_config_new global_config_new
+
+ set enc $global_config_new(gui.encoding)
+ if {$enc eq {}} {
+ set global_config_new(gui.encoding) [encoding system]
+ } elseif {[tcl_encoding $enc] eq {}} {
+ error_popup [mc "Invalid global encoding '%s'" $enc]
+ return 0
+ }
+
+ set enc $repo_config_new(gui.encoding)
+ if {$enc eq {}} {
+ set repo_config_new(gui.encoding) [encoding system]
+ } elseif {[tcl_encoding $enc] eq {}} {
+ error_popup [mc "Invalid repo encoding '%s'" $enc]
+ return 0
+ }
+
+ return 1
+}
+
+proc save_config {} {
+ global default_config font_descs
+ global repo_config global_config system_config
+ global repo_config_new global_config_new
+ global ui_comm_spell
+
+ foreach option $font_descs {
+ set name [lindex $option 0]
+ set font [lindex $option 1]
+ font configure $font \
+ -family $global_config_new(gui.$font^^family) \
+ -size $global_config_new(gui.$font^^size)
+ font configure ${font}bold \
+ -family $global_config_new(gui.$font^^family) \
+ -size $global_config_new(gui.$font^^size)
+ font configure ${font}italic \
+ -family $global_config_new(gui.$font^^family) \
+ -size $global_config_new(gui.$font^^size)
+ set global_config_new(gui.$name) [font configure $font]
+ unset global_config_new(gui.$font^^family)
+ unset global_config_new(gui.$font^^size)
+ }
+
+ foreach name [array names default_config] {
+ set value $global_config_new($name)
+ if {$value ne $global_config($name)} {
+ if {$value eq $system_config($name)} {
+ catch {git config --global --unset $name}
+ } else {
+ regsub -all "\[{}\]" $value {"} value
+ git config --global $name $value
+ }
+ set global_config($name) $value
+ if {$value eq $repo_config($name)} {
+ catch {git config --unset $name}
+ set repo_config($name) $value
+ }
+ }
+ }
+
+ foreach name [array names default_config] {
+ set value $repo_config_new($name)
+ if {$value ne $repo_config($name)} {
+ if {$value eq $global_config($name)} {
+ catch {git config --unset $name}
+ } else {
+ regsub -all "\[{}\]" $value {"} value
+ git config $name $value
+ }
+ set repo_config($name) $value
+ }
+ }
+
+ if {[info exists repo_config(gui.spellingdictionary)]} {
+ set value $repo_config(gui.spellingdictionary)
+ if {$value eq {none}} {
+ if {[info exists ui_comm_spell]} {
+ $ui_comm_spell stop
+ }
+ } elseif {[info exists ui_comm_spell]} {
+ $ui_comm_spell lang $value
+ }
+ }
+}
+
+proc do_options {} {
+ global repo_config global_config font_descs
+ global repo_config_new global_config_new
+ global ui_comm_spell use_ttk NS
+
+ array unset repo_config_new
+ array unset global_config_new
+ foreach name [array names repo_config] {
+ set repo_config_new($name) $repo_config($name)
+ }
+ load_config 1
+ foreach name [array names repo_config] {
+ switch -- $name {
+ gui.diffcontext {continue}
+ }
+ set repo_config_new($name) $repo_config($name)
+ }
+ foreach name [array names global_config] {
+ set global_config_new($name) $global_config($name)
+ }
+
+ set w .options_editor
+ Dialog $w
+ wm withdraw $w
+ wm transient $w [winfo parent $w]
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.restore -text [mc "Restore Defaults"] \
+ -default normal \
+ -command do_restore_defaults
+ pack $w.buttons.restore -side left
+ ${NS}::button $w.buttons.save -text [mc Save] \
+ -default active \
+ -command [list do_save_config $w]
+ pack $w.buttons.save -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.repo -text [mc "%s Repository" [reponame]]
+ ${NS}::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 {mc "User Name"}}
+ {t user.email {mc "Email Address"}}
+
+ {b merge.summary {mc "Summarize Merge Commits"}}
+ {i-1..5 merge.verbosity {mc "Merge Verbosity"}}
+ {b merge.diffstat {mc "Show Diffstat After Merge"}}
+ {t merge.tool {mc "Use Merge Tool"}}
+
+ {b gui.trustmtime {mc "Trust File Modification Timestamps"}}
+ {b gui.pruneduringfetch {mc "Prune Tracking Branches During Fetch"}}
+ {b gui.matchtrackingbranch {mc "Match Tracking Branches"}}
+ {b gui.textconv {mc "Use Textconv For Diffs and Blames"}}
+ {b gui.fastcopyblame {mc "Blame Copy Only On Changed Files"}}
+ {i-0..100 gui.maxrecentrepo {mc "Maximum Length of Recent Repositories List"}}
+ {i-20..200 gui.copyblamethreshold {mc "Minimum Letters To Blame Copy On"}}
+ {i-0..300 gui.blamehistoryctx {mc "Blame History Context Radius (days)"}}
+ {i-1..99 gui.diffcontext {mc "Number of Diff Context Lines"}}
+ {t gui.diffopts {mc "Additional Diff Parameters"}}
+ {i-0..99 gui.commitmsgwidth {mc "Commit Message Text Width"}}
+ {t gui.newbranchtemplate {mc "New Branch Name Template"}}
+ {c gui.encoding {mc "Default File Contents Encoding"}}
+ {b gui.warndetachedcommit {mc "Warn before committing to a detached head"}}
+ {s gui.stageuntracked {mc "Staging of untracked files"} {list "yes" "no" "ask"}}
+ {b gui.displayuntracked {mc "Show untracked files"}}
+ {i-1..99 gui.tabsize {mc "Tab spacing"}}
+ } {
+ set type [lindex $option 0]
+ set name [lindex $option 1]
+ set text [eval [lindex $option 2]]
+ incr optid
+ foreach f {repo global} {
+ switch -glob -- $type {
+ b {
+ ${NS}::checkbutton $w.$f.$optid -text $text \
+ -variable ${f}_config_new($name) \
+ -onvalue true \
+ -offvalue false
+ pack $w.$f.$optid -side top -anchor w
+ }
+ i-* {
+ regexp -- {-(\d+)\.\.(\d+)$} $type _junk min max
+ ${NS}::frame $w.$f.$optid
- ${NS}::label $w.$f.$optid.l -text "$text:"
++ ${NS}::label $w.$f.$optid.l -text [mc "%s:" $text]
+ pack $w.$f.$optid.l -side left -anchor w -fill x
+ tspinbox $w.$f.$optid.v \
+ -textvariable ${f}_config_new($name) \
+ -from $min \
+ -to $max \
+ -increment 1 \
+ -width [expr {1 + [string length $max]}]
+ bind $w.$f.$optid.v <FocusIn> {%W selection range 0 end}
+ pack $w.$f.$optid.v -side right -anchor e -padx 5
+ pack $w.$f.$optid -side top -anchor w -fill x
+ }
+ c -
+ t {
+ ${NS}::frame $w.$f.$optid
- ${NS}::label $w.$f.$optid.l -text "$text:"
++ ${NS}::label $w.$f.$optid.l -text [mc "%s:" $text]
+ ${NS}::entry $w.$f.$optid.v \
+ -width 20 \
+ -textvariable ${f}_config_new($name)
+ pack $w.$f.$optid.l -side left -anchor w
+ pack $w.$f.$optid.v -side left -anchor w \
+ -fill x -expand 1 \
+ -padx 5
+ if {$type eq {c}} {
+ menu $w.$f.$optid.m
+ build_encoding_menu $w.$f.$optid.m \
+ [list set ${f}_config_new($name)] 1
+ ${NS}::button $w.$f.$optid.b \
+ -text [mc "Change"] \
+ -command [list popup_btn_menu \
+ $w.$f.$optid.m $w.$f.$optid.b]
+ pack $w.$f.$optid.b -side left -anchor w
+ }
+ pack $w.$f.$optid -side top -anchor w -fill x
+ }
+ s {
+ set opts [eval [lindex $option 3]]
+ ${NS}::frame $w.$f.$optid
- ${NS}::label $w.global.$name.l -text "$text:"
++ ${NS}::label $w.$f.$optid.l -text [mc "%s:" $text]
+ if {$use_ttk} {
+ ttk::combobox $w.$f.$optid.v \
+ -textvariable ${f}_config_new($name) \
+ -values $opts -state readonly
+ } else {
+ eval tk_optionMenu $w.$f.$optid.v \
+ ${f}_config_new($name) \
+ $opts
+ }
+ pack $w.$f.$optid.l -side left -anchor w -fill x
+ pack $w.$f.$optid.v -side right -anchor e -padx 5
+ pack $w.$f.$optid -side top -anchor w -fill x
+ }
+ }
+ }
+ }
+
+ set all_dicts [linsert \
+ [spellcheck::available_langs] \
+ 0 \
+ none]
+ incr optid
+ foreach f {repo global} {
+ if {![info exists ${f}_config_new(gui.spellingdictionary)]} {
+ if {[info exists ui_comm_spell]} {
+ set value [$ui_comm_spell lang]
+ } else {
+ set value none
+ }
+ set ${f}_config_new(gui.spellingdictionary) $value
+ }
+
+ ${NS}::frame $w.$f.$optid
+ ${NS}::label $w.$f.$optid.l -text [mc "Spelling Dictionary:"]
+ if {$use_ttk} {
+ ttk::combobox $w.$f.$optid.v \
+ -textvariable ${f}_config_new(gui.spellingdictionary) \
+ -values $all_dicts -state readonly
+ } else {
+ eval tk_optionMenu $w.$f.$optid.v \
+ ${f}_config_new(gui.spellingdictionary) \
+ $all_dicts
+ }
+ pack $w.$f.$optid.l -side left -anchor w -fill x
+ pack $w.$f.$optid.v -side right -anchor e -padx 5
+ pack $w.$f.$optid -side top -anchor w -fill x
+ }
+ unset all_dicts
+
+ set all_fonts [lsort [font families]]
+ foreach option $font_descs {
+ set name [lindex $option 0]
+ set font [lindex $option 1]
+ set text [eval [lindex $option 2]]
+
+ set global_config_new(gui.$font^^family) \
+ [font configure $font -family]
+ set global_config_new(gui.$font^^size) \
+ [font configure $font -size]
+
+ ${NS}::frame $w.global.$name
++ ${NS}::label $w.global.$name.l -text [mc "%s:" $text]
+ ${NS}::button $w.global.$name.b \
+ -text [mc "Change Font"] \
+ -command [list \
+ tchoosefont \
+ $w \
+ [mc "Choose %s" $text] \
+ global_config_new(gui.$font^^family) \
+ global_config_new(gui.$font^^size) \
+ ]
+ ${NS}::label $w.global.$name.f -textvariable global_config_new(gui.$font^^family)
+ ${NS}::label $w.global.$name.s -textvariable global_config_new(gui.$font^^size)
+ ${NS}::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]
+
+ if {[is_MacOSX]} {
+ set t [mc "Preferences"]
+ } else {
+ set t [mc "Options"]
+ }
+ wm title $w "[appname] ([reponame]): $t"
+ wm deiconify $w
+ tkwait window $w
+}
+
+proc do_restore_defaults {} {
+ global font_descs default_config repo_config system_config
+ global repo_config_new global_config_new
+
+ foreach name [array names default_config] {
+ set repo_config_new($name) $system_config($name)
+ set global_config_new($name) $system_config($name)
+ }
+
+ foreach option $font_descs {
+ set name [lindex $option 0]
+ set repo_config(gui.$name) $system_config(gui.$name)
+ }
+ apply_config
+
+ foreach option $font_descs {
+ set name [lindex $option 0]
+ set font [lindex $option 1]
+ set global_config_new(gui.$font^^family) \
+ [font configure $font -family]
+ set global_config_new(gui.$font^^size) \
+ [font configure $font -size]
+ }
+}
+
+proc do_save_config {w} {
+ if {![config_check_encodings]} return
+ if {[catch {save_config} err]} {
+ error_popup [strcat [mc "Failed to completely save options:"] "\n\n$err"]
+ }
+ reshow_diff
+ destroy $w
+}
--- /dev/null
- && [$fetch_m entrycget end -label] ne "All"} {
+# git-gui remote management
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+set some_heads_tracking 0; # assume not
+
+proc is_tracking_branch {name} {
+ global tracking_branches
+ foreach spec $tracking_branches {
+ set t [lindex $spec 0]
+ if {$t eq $name || [string match $t $name]} {
+ return 1
+ }
+ }
+ return 0
+}
+
+proc all_tracking_branches {} {
+ global tracking_branches
+
+ set all [list]
+ set pat [list]
+ set cmd [list]
+
+ foreach spec $tracking_branches {
+ set dst [lindex $spec 0]
+ if {[string range $dst end-1 end] eq {/*}} {
+ lappend pat $spec
+ lappend cmd [string range $dst 0 end-2]
+ } else {
+ lappend all $spec
+ }
+ }
+
+ if {$pat ne {}} {
+ set fd [eval git_read for-each-ref --format=%(refname) $cmd]
+ while {[gets $fd n] > 0} {
+ foreach spec $pat {
+ set dst [string range [lindex $spec 0] 0 end-2]
+ set len [string length $dst]
+ if {[string equal -length $len $dst $n]} {
+ set src [string range [lindex $spec 2] 0 end-2]
+ set spec [list \
+ $n \
+ [lindex $spec 1] \
+ $src[string range $n $len end] \
+ ]
+ lappend all $spec
+ }
+ }
+ }
+ close $fd
+ }
+
+ return [lsort -index 0 -unique $all]
+}
+
+proc load_all_remotes {} {
+ global repo_config
+ global all_remotes tracking_branches some_heads_tracking
+ global remote_url
+
+ set some_heads_tracking 0
+ set all_remotes [list]
+ set trck [list]
+
+ set rh_str refs/heads/
+ set rh_len [string length $rh_str]
+ set rm_dir [gitdir remotes]
+ if {[file isdirectory $rm_dir]} {
+ set all_remotes [glob \
+ -types f \
+ -tails \
+ -nocomplain \
+ -directory $rm_dir *]
+
+ foreach name $all_remotes {
+ catch {
+ set fd [open [file join $rm_dir $name] r]
+ while {[gets $fd line] >= 0} {
+ if {[regexp {^URL:[ ]*(.+)$} $line line url]} {
+ set remote_url($name) $url
+ continue
+ }
+ if {![regexp {^Pull:[ ]*([^:]+):(.+)$} \
+ $line line src dst]} continue
+ if {[string index $src 0] eq {+}} {
+ set src [string range $src 1 end]
+ }
+ if {![string equal -length 5 refs/ $src]} {
+ set src $rh_str$src
+ }
+ if {![string equal -length 5 refs/ $dst]} {
+ set dst $rh_str$dst
+ }
+ if {[string equal -length $rh_len $rh_str $dst]} {
+ set some_heads_tracking 1
+ }
+ lappend trck [list $dst $name $src]
+ }
+ close $fd
+ }
+ }
+ }
+
+ foreach line [array names repo_config remote.*.url] {
+ if {![regexp ^remote\.(.*)\.url\$ $line line name]} continue
+ lappend all_remotes $name
+ set remote_url($name) $repo_config(remote.$name.url)
+
+ if {[catch {set fl $repo_config(remote.$name.fetch)}]} {
+ set fl {}
+ }
+ foreach line $fl {
+ if {![regexp {^([^:]+):(.+)$} $line line src dst]} continue
+ if {[string index $src 0] eq {+}} {
+ set src [string range $src 1 end]
+ }
+ if {![string equal -length 5 refs/ $src]} {
+ set src $rh_str$src
+ }
+ if {![string equal -length 5 refs/ $dst]} {
+ set dst $rh_str$dst
+ }
+ if {[string equal -length $rh_len $rh_str $dst]} {
+ set some_heads_tracking 1
+ }
+ lappend trck [list $dst $name $src]
+ }
+ }
+
+ set tracking_branches [lsort -index 0 -unique $trck]
+ set all_remotes [lsort -unique $all_remotes]
+}
+
+proc add_fetch_entry {r} {
+ global repo_config
+ set remote_m .mbar.remote
+ set fetch_m $remote_m.fetch
+ set prune_m $remote_m.prune
+ set remove_m $remote_m.remove
+ set enable 0
+ if {![catch {set a $repo_config(remote.$r.url)}]} {
+ if {![catch {set a $repo_config(remote.$r.fetch)}]} {
+ set enable 1
+ }
+ } else {
+ catch {
+ set fd [open [gitdir remotes $r] r]
+ while {[gets $fd n] >= 0} {
+ if {[regexp {^Pull:[ \t]*([^:]+):} $n]} {
+ set enable 1
+ break
+ }
+ }
+ close $fd
+ }
+ }
+
+ if {$enable} {
+ make_sure_remote_submenues_exist $remote_m
+
+ $fetch_m add command \
+ -label $r \
+ -command [list fetch_from $r]
+ $prune_m add command \
+ -label $r \
+ -command [list prune_from $r]
+ $remove_m add command \
+ -label $r \
+ -command [list remove_remote $r]
+ }
+}
+
+proc add_push_entry {r} {
+ global repo_config
+ set remote_m .mbar.remote
+ set push_m $remote_m.push
+ set enable 0
+ if {![catch {set a $repo_config(remote.$r.url)}]} {
+ if {![catch {set a $repo_config(remote.$r.push)}]} {
+ set enable 1
+ }
+ } else {
+ catch {
+ set fd [open [gitdir remotes $r] r]
+ while {[gets $fd n] >= 0} {
+ if {[regexp {^Push:[ \t]*([^:]+):} $n]} {
+ set enable 1
+ break
+ }
+ }
+ close $fd
+ }
+ }
+
+ if {$enable} {
+ if {![winfo exists $push_m]} {
+ menu $push_m
+ $remote_m insert 0 cascade \
+ -label [mc "Push to"] \
+ -menu $push_m
+ }
+
+ $push_m add command \
+ -label $r \
+ -command [list push_to $r]
+ }
+}
+
+proc make_sure_remote_submenues_exist {remote_m} {
+ set fetch_m $remote_m.fetch
+ set prune_m $remote_m.prune
+ set remove_m $remote_m.remove
+
+ if {![winfo exists $fetch_m]} {
+ menu $remove_m
+ $remote_m insert 0 cascade \
+ -label [mc "Remove Remote"] \
+ -menu $remove_m
+
+ menu $prune_m
+ $remote_m insert 0 cascade \
+ -label [mc "Prune from"] \
+ -menu $prune_m
+
+ menu $fetch_m
+ $remote_m insert 0 cascade \
+ -label [mc "Fetch from"] \
+ -menu $fetch_m
+ }
+}
+
+proc update_all_remotes_menu_entry {} {
+ global all_remotes
+
+ if {[git-version < 1.6.6]} { return }
+
+ set have_remote 0
+ foreach r $all_remotes {
+ incr have_remote
+ }
+
+ set remote_m .mbar.remote
+ set fetch_m $remote_m.fetch
+ set prune_m $remote_m.prune
+ if {$have_remote > 1} {
+ make_sure_remote_submenues_exist $remote_m
+ if {[$fetch_m type end] eq "command" \
- -label "All" \
++ && [$fetch_m entrycget end -label] ne [mc "All"]} {
+
+ $fetch_m insert end separator
+ $fetch_m insert end command \
- -label "All" \
++ -label [mc "All"] \
+ -command fetch_from_all
+
+ $prune_m insert end separator
+ $prune_m insert end command \
- && [$fetch_m entrycget end -label] eq "All"} {
++ -label [mc "All"] \
+ -command prune_from_all
+ }
+ } else {
+ if {[winfo exists $fetch_m]} {
+ if {[$fetch_m type end] eq "command" \
++ && [$fetch_m entrycget end -label] eq [mc "All"]} {
+
+ delete_from_menu $fetch_m end
+ delete_from_menu $fetch_m end
+
+ delete_from_menu $prune_m end
+ delete_from_menu $prune_m end
+ }
+ }
+ }
+}
+
+proc populate_remotes_menu {} {
+ global all_remotes
+
+ foreach r $all_remotes {
+ add_fetch_entry $r
+ add_push_entry $r
+ }
+
+ update_all_remotes_menu_entry
+}
+
+proc add_single_remote {name location} {
+ global all_remotes repo_config
+ lappend all_remotes $name
+
+ git remote add $name $location
+
+ # XXX: Better re-read the config so that we will never get out
+ # of sync with git remote implementation?
+ set repo_config(remote.$name.url) $location
+ set repo_config(remote.$name.fetch) "+refs/heads/*:refs/remotes/$name/*"
+
+ add_fetch_entry $name
+ add_push_entry $name
+
+ update_all_remotes_menu_entry
+}
+
+proc delete_from_menu {menu name} {
+ if {[winfo exists $menu]} {
+ $menu delete $name
+ }
+}
+
+proc remove_remote {name} {
+ global all_remotes repo_config
+
+ git remote rm $name
+
+ catch {
+ # Missing values are ok
+ unset repo_config(remote.$name.url)
+ unset repo_config(remote.$name.fetch)
+ unset repo_config(remote.$name.push)
+ }
+
+ set i [lsearch -exact $all_remotes $name]
+ set all_remotes [lreplace $all_remotes $i $i]
+
+ set remote_m .mbar.remote
+ delete_from_menu $remote_m.fetch $name
+ delete_from_menu $remote_m.prune $name
+ delete_from_menu $remote_m.remove $name
+ # Not all remotes are in the push menu
+ catch { delete_from_menu $remote_m.push $name }
+
+ update_all_remotes_menu_entry
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Add Remote"]]
+# git-gui remote adding support
+# Copyright (C) 2008 Petr Baudis
+
+class remote_add {
+
+field w ; # widget path
+field w_name ; # new remote name widget
+field w_loc ; # new remote location widget
+
+field name {}; # name of the remote the user has chosen
+field location {}; # location of the remote the user has chosen
+
+field opt_action fetch; # action to do after registering the remote locally
+
+constructor dialog {} {
+ global repo_config use_ttk NS
+
+ make_dialog top w
+ wm withdraw $top
++ wm title $top [mc "%s (%s): Add Remote" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ ${NS}::label $w.header -text [mc "Add New Remote"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.create -text [mc Add] \
+ -default active \
+ -command [cb _add]
+ pack $w.buttons.create -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.desc -text [mc "Remote Details"]
+
+ ${NS}::label $w.desc.name_l -text [mc "Name:"]
+ set w_name $w.desc.name_t
+ ${NS}::entry $w_name \
+ -width 40 \
+ -textvariable @name \
+ -validate key \
+ -validatecommand [cb _validate_name %d %S]
+ grid $w.desc.name_l $w_name -sticky we -padx {0 5}
+
+ ${NS}::label $w.desc.loc_l -text [mc "Location:"]
+ set w_loc $w.desc.loc_t
+ ${NS}::entry $w_loc \
+ -width 40 \
+ -textvariable @location
+ grid $w.desc.loc_l $w_loc -sticky we -padx {0 5}
+
+ grid columnconfigure $w.desc 1 -weight 1
+ pack $w.desc -anchor nw -fill x -pady 5 -padx 5
+
+ ${NS}::labelframe $w.action -text [mc "Further Action"]
+
+ ${NS}::radiobutton $w.action.fetch \
+ -text [mc "Fetch Immediately"] \
+ -value fetch \
+ -variable @opt_action
+ pack $w.action.fetch -anchor nw
+
+ ${NS}::radiobutton $w.action.push \
+ -text [mc "Initialize Remote Repository and Push"] \
+ -value push \
+ -variable @opt_action
+ pack $w.action.push -anchor nw
+
+ ${NS}::radiobutton $w.action.none \
+ -text [mc "Do Nothing Else Now"] \
+ -value none \
+ -variable @opt_action
+ pack $w.action.none -anchor nw
+
+ grid columnconfigure $w.action 1 -weight 1
+ pack $w.action -anchor nw -fill x -pady 5 -padx 5
+
+ bind $w <Visibility> [cb _visible]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _add]\;break
+ wm deiconify $top
+ tkwait window $w
+}
+
+method _add {} {
+ global repo_config env
+ global M1B
+
+ if {$name eq {}} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Please supply a remote name."]
+ focus $w_name
+ return
+ }
+
+ # XXX: We abuse check-ref-format here, but
+ # that should be ok.
+ if {[catch {git check-ref-format "remotes/$name"}]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "'%s' is not an acceptable remote name." $name]
+ focus $w_name
+ return
+ }
+
+ if {[catch {add_single_remote $name $location}]} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Failed to add remote '%s' of location '%s'." $name $location]
+ focus $w_name
+ return
+ }
+
+ switch -- $opt_action {
+ fetch {
+ set c [console::new \
+ [mc "fetch %s" $name] \
+ [mc "Fetching the %s" $name]]
+ console::exec $c [list git fetch $name]
+ }
+ push {
+ set cmds [list]
+
+ # Parse the location
+ if { [regexp {(?:git\+)?ssh://([^/]+)(/.+)} $location xx host path]
+ || [regexp {([^:][^:]+):(.+)} $location xx host path]} {
+ set ssh ssh
+ if {[info exists env(GIT_SSH)]} {
+ set ssh $env(GIT_SSH)
+ }
+ lappend cmds [list exec $ssh $host mkdir -p $location && git --git-dir=$path init --bare]
+ } elseif { ! [regexp {://} $location xx] } {
+ lappend cmds [list exec mkdir -p $location]
+ lappend cmds [list exec git --git-dir=$location init --bare]
+ } else {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Do not know how to initialize repository at location '%s'." $location]
+ destroy $w
+ return
+ }
+
+ set c [console::new \
+ [mc "push %s" $name] \
+ [mc "Setting up the %s (at %s)" $name $location]]
+
+ lappend cmds [list exec git push -v --all $name]
+ console::chain $c $cmds
+ }
+ none {
+ }
+ }
+
+ destroy $w
+}
+
+method _validate_name {d S} {
+ if {$d == 1} {
+ if {[regexp {[~^:?*\[\0- ]} $S]} {
+ return 0
+ }
+ }
+ return 1
+}
+
+method _visible {} {
+ grab $w
+ $w_name icursor end
+ focus $w_name
+}
+
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Delete Branch Remotely"]]
+# git-gui remote branch deleting support
+# Copyright (C) 2007 Shawn Pearce
+
+class remote_branch_delete {
+
+field w
+field head_m
+
+field urltype {url}
+field remote {}
+field url {}
+
+field checktype {head}
+field check_head {}
+
+field status {}
+field idle_id {}
+field full_list {}
+field head_list {}
+field active_ls {}
+field head_cache
+field full_cache
+field cached
+
+constructor dialog {} {
+ global all_remotes M1B use_ttk NS
+
+ make_dialog top w
++ wm title $top [mc "%s (%s): Delete Branch Remotely" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ }
+
+ ${NS}::label $w.header -text [mc "Delete Branch Remotely"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.delete -text [mc Delete] \
+ -default active \
+ -command [cb _delete]
+ pack $w.buttons.delete -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.dest -text [mc "From Repository"]
+ if {$all_remotes ne {}} {
+ ${NS}::radiobutton $w.dest.remote_r \
+ -text [mc "Remote:"] \
+ -value remote \
+ -variable @urltype
+ if {$use_ttk} {
+ ttk::combobox $w.dest.remote_m -textvariable @remote \
+ -values $all_remotes -state readonly
+ } else {
+ eval tk_optionMenu $w.dest.remote_m @remote $all_remotes
+ }
+ grid $w.dest.remote_r $w.dest.remote_m -sticky w
+ if {[lsearch -sorted -exact $all_remotes origin] != -1} {
+ set remote origin
+ } else {
+ set remote [lindex $all_remotes 0]
+ }
+ set urltype remote
+ trace add variable @remote write [cb _write_remote]
+ } else {
+ set urltype url
+ }
+ ${NS}::radiobutton $w.dest.url_r \
+ -text [mc "Arbitrary Location:"] \
+ -value url \
+ -variable @urltype
+ ${NS}::entry $w.dest.url_t \
+ -width 50 \
+ -textvariable @url \
+ -validate key \
+ -validatecommand {
+ if {%d == 1 && [regexp {\s} %S]} {return 0}
+ return 1
+ }
+ trace add variable @url write [cb _write_url]
+ grid $w.dest.url_r $w.dest.url_t -sticky we -padx {0 5}
+ grid columnconfigure $w.dest 1 -weight 1
+ pack $w.dest -anchor nw -fill x -pady 5 -padx 5
+
+ ${NS}::labelframe $w.heads -text [mc "Branches"]
+ slistbox $w.heads.l \
+ -height 10 \
+ -width 70 \
+ -listvariable @head_list \
+ -selectmode extended
+
+ ${NS}::frame $w.heads.footer
+ ${NS}::label $w.heads.footer.status \
+ -textvariable @status \
+ -anchor w \
+ -justify left
+ ${NS}::button $w.heads.footer.rescan \
+ -text [mc "Rescan"] \
+ -command [cb _rescan]
+ pack $w.heads.footer.status -side left -fill x
+ pack $w.heads.footer.rescan -side right
+
+ pack $w.heads.footer -side bottom -fill x
+ pack $w.heads.l -side left -fill both -expand 1
+ pack $w.heads -fill both -expand 1 -pady 5 -padx 5
+
+ ${NS}::labelframe $w.validate -text [mc "Delete Only If"]
+ ${NS}::radiobutton $w.validate.head_r \
+ -text [mc "Merged Into:"] \
+ -value head \
+ -variable @checktype
+ set head_m [tk_optionMenu $w.validate.head_m @check_head {}]
+ trace add variable @head_list write [cb _write_head_list]
+ trace add variable @check_head write [cb _write_check_head]
+ grid $w.validate.head_r $w.validate.head_m -sticky w
+ ${NS}::radiobutton $w.validate.always_r \
+ -text [mc "Always (Do not perform merge checks)"] \
+ -value always \
+ -variable @checktype
+ grid $w.validate.always_r -columnspan 2 -sticky w
+ grid columnconfigure $w.validate 1 -weight 1
+ pack $w.validate -anchor nw -fill x -pady 5 -padx 5
+
+ trace add variable @urltype write [cb _write_urltype]
+ _rescan $this
+
+ bind $w <Key-F5> [cb _rescan]
+ bind $w <$M1B-Key-r> [cb _rescan]
+ bind $w <$M1B-Key-R> [cb _rescan]
+ bind $w <Key-Return> [cb _delete]
+ bind $w <Key-Escape> [list destroy $w]
+ return $w
+}
+
+method _delete {} {
+ switch $urltype {
+ remote {set uri $remote}
+ url {set uri $url}
+ }
+
+ set cache $urltype:$uri
+ set crev {}
+ if {$checktype eq {head}} {
+ if {$check_head eq {}} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "A branch is required for 'Merged Into'."]
+ return
+ }
+ set crev $full_cache("$cache\nrefs/heads/$check_head")
+ }
+
+ set not_merged [list]
+ set need_fetch 0
+ set have_selection 0
+ set push_cmd [list git push]
+ lappend push_cmd -v
+ lappend push_cmd $uri
+
+ foreach i [$w.heads.l curselection] {
+ set ref [lindex $full_list $i]
+ if {$crev ne {}} {
+ set obj $full_cache("$cache\n$ref")
+ if {[catch {set m [git merge-base $obj $crev]}]} {
+ set need_fetch 1
+ set m {}
+ }
+ if {$obj ne $m} {
+ lappend not_merged [lindex $head_list $i]
+ continue
+ }
+ }
+
+ lappend push_cmd :$ref
+ set have_selection 1
+ }
+
+ if {$not_merged ne {}} {
+ set msg [mc "The following branches are not completely merged into %s:
+
+ - %s" $check_head [join $not_merged "\n - "]]
+
+ if {$need_fetch} {
+ 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 \
+ -icon info \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message $msg
+ if {!$have_selection} return
+ }
+
+ if {!$have_selection} {
+ tk_messageBox \
+ -icon error \
+ -type ok \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Please select one or more branches to delete."]
+ return
+ }
+
+ if {$checktype ne {head}} {
+ if {[tk_messageBox \
+ -icon warning \
+ -type yesno \
+ -title [wm title $w] \
+ -parent $w \
+ -message [mc "Recovering deleted branches is difficult.\n\nDelete the selected branches?"]] ne yes} {
+ return
+ }
+ }
+
+ destroy $w
+
+ set cons [console::new \
+ "push $uri" \
+ [mc "Deleting branches from %s" $uri]]
+ console::exec $cons $push_cmd
+}
+
+method _rescan {{force 1}} {
+ switch $urltype {
+ remote {set uri $remote}
+ url {set uri $url}
+ }
+
+ if {$force} {
+ unset -nocomplain cached($urltype:$uri)
+ }
+
+ if {$idle_id ne {}} {
+ after cancel $idle_id
+ set idle_id {}
+ }
+
+ _load $this $urltype:$uri $uri
+}
+
+method _write_remote {args} { set urltype remote }
+method _write_url {args} { set urltype url }
+method _write_check_head {args} { set checktype head }
+
+method _write_head_list {args} {
+ global current_branch _last_merged_branch
+
+ $head_m delete 0 end
+ foreach abr $head_list {
+ $head_m insert end radiobutton \
+ -label $abr \
+ -value $abr \
+ -variable @check_head
+ }
+ if {[lsearch -exact -sorted $head_list $check_head] < 0} {
+ if {[lsearch -exact -sorted $head_list $current_branch] < 0} {
+ set check_head {}
+ } else {
+ set check_head $current_branch
+ }
+ }
+ set lmb [lsearch -exact -sorted $head_list $_last_merged_branch]
+ if {$lmb >= 0} {
+ $w.heads.l conf -state normal
+ $w.heads.l select set $lmb
+ $w.heads.l yview $lmb
+ $w.heads.l conf -state disabled
+ }
+}
+
+method _write_urltype {args} {
+ if {$urltype eq {url}} {
+ if {$idle_id ne {}} {
+ after cancel $idle_id
+ }
+ _load $this none: {}
+ set idle_id [after 1000 [cb _rescan 0]]
+ } else {
+ _rescan $this 0
+ }
+}
+
+method _load {cache uri} {
+ if {$active_ls ne {}} {
+ catch {close $active_ls}
+ }
+
+ if {$uri eq {}} {
+ $w.heads.l conf -state disabled
+ set head_list [list]
+ set full_list [list]
+ set status [mc "No repository selected."]
+ return
+ }
+
+ if {[catch {set x $cached($cache)}]} {
+ set status [mc "Scanning %s..." $uri]
+ $w.heads.l conf -state disabled
+ set head_list [list]
+ set full_list [list]
+ set head_cache($cache) [list]
+ set full_cache($cache) [list]
+ set active_ls [git_read ls-remote $uri]
+ fconfigure $active_ls \
+ -blocking 0 \
+ -translation lf \
+ -encoding utf-8
+ fileevent $active_ls readable [cb _read $cache $active_ls]
+ } else {
+ set status {}
+ set full_list $full_cache($cache)
+ set head_list $head_cache($cache)
+ $w.heads.l conf -state normal
+ }
+}
+
+method _read {cache fd} {
+ if {$fd ne $active_ls} {
+ catch {close $fd}
+ return
+ }
+
+ while {[gets $fd line] >= 0} {
+ if {[string match {*^{}} $line]} continue
+ if {[regexp {^([0-9a-f]{40}) (.*)$} $line _junk obj ref]} {
+ if {[regsub ^refs/heads/ $ref {} abr]} {
+ lappend head_list $abr
+ lappend head_cache($cache) $abr
+ lappend full_list $ref
+ lappend full_cache($cache) $ref
+ set full_cache("$cache\n$ref") $obj
+ }
+ }
+ }
+
+ if {[eof $fd]} {
+ if {[catch {close $fd} err]} {
+ set status $err
+ set head_list [list]
+ set full_list [list]
+ } else {
+ set status {}
+ set cached($cache) 1
+ $w.heads.l conf -state normal
+ }
+ }
+} ifdeleted {
+ catch {close $fd}
+}
+
+}
--- /dev/null
- -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
+# git-gui desktop icon creators
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc do_windows_shortcut {} {
+ global _gitworktree
+ set fn [tk_getSaveFile \
+ -parent . \
- win32_create_lnk $fn [list \
- [info nameofexecutable] \
- [file normalize $::argv0] \
- ] \
++ -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \
+ -initialfile "Git [reponame].lnk"]
+ if {$fn != {}} {
+ if {[file extension $fn] ne {.lnk}} {
+ set fn ${fn}.lnk
+ }
++ # Use git-gui.exe if available (ie: git-for-windows)
++ set cmdLine [auto_execok git-gui.exe]
++ if {$cmdLine eq {}} {
++ set cmdLine [list [info nameofexecutable] \
++ [file normalize $::argv0]]
++ }
+ if {[catch {
- -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
++ win32_create_lnk $fn $cmdLine \
+ [file normalize $_gitworktree]
+ } err]} {
+ error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
+ }
+ }
+}
+
+proc do_cygwin_shortcut {} {
+ global argv0 _gitworktree
+
+ if {[catch {
+ set desktop [exec cygpath \
+ --windows \
+ --absolute \
+ --long-name \
+ --desktop]
+ }]} {
+ set desktop .
+ }
+ set fn [tk_getSaveFile \
+ -parent . \
- -title [append "[appname] ([reponame]): " [mc "Create Desktop Icon"]] \
++ -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \
+ -initialdir $desktop \
+ -initialfile "Git [reponame].lnk"]
+ if {$fn != {}} {
+ if {[file extension $fn] ne {.lnk}} {
+ set fn ${fn}.lnk
+ }
+ if {[catch {
+ set sh [exec cygpath \
+ --windows \
+ --absolute \
+ /bin/sh.exe]
+ set me [exec cygpath \
+ --unix \
+ --absolute \
+ $argv0]
+ win32_create_lnk $fn [list \
+ $sh -c \
+ "CHERE_INVOKING=1 source /etc/profile;[sq $me] &" \
+ ] \
+ [file normalize $_gitworktree]
+ } err]} {
+ error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"]
+ }
+ }
+}
+
+proc do_macosx_app {} {
+ global argv0 env
+
+ set fn [tk_getSaveFile \
+ -parent . \
++ -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \
+ -initialdir [file join $env(HOME) Desktop] \
+ -initialfile "Git [reponame].app"]
+ if {$fn != {}} {
+ if {[file extension $fn] ne {.app}} {
+ set fn ${fn}.app
+ }
+ if {[catch {
+ set Contents [file join $fn Contents]
+ set MacOS [file join $Contents MacOS]
+ set exe [file join $MacOS git-gui]
+
+ file mkdir $MacOS
+
+ set fd [open [file join $Contents Info.plist] w]
+ puts $fd {<?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>git-gui</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.spearce.git-gui</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+</dict>
+</plist>}
+ close $fd
+
+ set fd [open $exe w]
+ puts $fd "#!/bin/sh"
+ foreach name [lsort [array names env]] {
+ set value $env($name)
+ switch -- $name {
+ GIT_DIR { set value [file normalize [gitdir]] }
+ }
+
+ switch -glob -- $name {
+ SSH_* -
+ GIT_* {
+ puts $fd "if test \"z\$$name\" = z; then"
+ puts $fd " export $name=[sq $value]"
+ puts $fd "fi &&"
+ }
+ }
+ }
+ puts $fd "export PATH=[sq [file dirname $::_git]]:\$PATH &&"
+ puts $fd "cd [sq [file normalize [pwd]]] &&"
+ puts $fd "exec \\"
+ puts $fd " [sq [info nameofexecutable]] \\"
+ puts $fd " [sq [file normalize $argv0]]"
+ close $fd
+
+ file attributes $exe -permissions u+x,g+x,o+x
+ } err]} {
+ error_popup [strcat [mc "Cannot write icon:"] "\n\n$err"]
+ }
+ }
+}
--- /dev/null
- catch {wm attributes $w -type dialog}
+# Functions for supporting the use of themed Tk widgets in git-gui.
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+
+proc InitTheme {} {
+ # Create a color label style (bg can be overridden by widget option)
+ ttk::style layout Color.TLabel {
+ Color.Label.border -sticky news -children {
+ Color.label.fill -sticky news -children {
+ Color.Label.padding -sticky news -children {
+ Color.Label.label -sticky news}}}}
+ eval [linsert [ttk::style configure TLabel] 0 \
+ ttk::style configure Color.TLabel]
+ ttk::style configure Color.TLabel \
+ -borderwidth 0 -relief flat -padding 2
+ ttk::style map Color.TLabel -background {{} gold}
+ # We also need a padded label.
+ ttk::style configure Padded.TLabel \
+ -padding {5 5} -borderwidth 1 -relief solid
+ # We need a gold frame.
+ ttk::style layout Gold.TFrame {
+ Gold.Frame.border -sticky nswe -children {
+ Gold.Frame.fill -sticky nswe}}
+ ttk::style configure Gold.TFrame -background gold -relief flat
+ # listboxes should have a theme border so embed in ttk::frame
+ ttk::style layout SListbox.TFrame {
+ SListbox.Frame.Entry.field -sticky news -border true -children {
+ SListbox.Frame.padding -sticky news
+ }
+ }
+
+ # Handle either current Tk or older versions of 8.5
+ if {[catch {set theme [ttk::style theme use]}]} {
+ set theme $::ttk::currentTheme
+ }
+
+ if {[lsearch -exact {default alt classic clam} $theme] != -1} {
+ # Simple override of standard ttk::entry to change the field
+ # packground according to a state flag. We should use 'user1'
+ # but not all versions of 8.5 support that so make use of 'pressed'
+ # which is not normally in use for entry widgets.
+ ttk::style layout Edged.Entry [ttk::style layout TEntry]
+ ttk::style map Edged.Entry {*}[ttk::style map TEntry]
+ ttk::style configure Edged.Entry {*}[ttk::style configure TEntry] \
+ -fieldbackground lightgreen
+ ttk::style map Edged.Entry -fieldbackground {
+ {pressed !disabled} lightpink
+ }
+ } else {
+ # For fancier themes, in particular the Windows ones, the field
+ # element may not support changing the background color. So instead
+ # override the fill using the default fill element. If we overrode
+ # the vista theme field element we would loose the themed border
+ # of the widget.
+ catch {
+ ttk::style element create color.fill from default
+ }
+
+ ttk::style layout Edged.Entry {
+ Edged.Entry.field -sticky nswe -border 0 -children {
+ Edged.Entry.border -sticky nswe -border 1 -children {
+ Edged.Entry.padding -sticky nswe -children {
+ Edged.Entry.color.fill -sticky nswe -children {
+ Edged.Entry.textarea -sticky nswe
+ }
+ }
+ }
+ }
+ }
+
+ ttk::style configure Edged.Entry {*}[ttk::style configure TEntry] \
+ -background lightgreen -padding 0 -borderwidth 0
+ ttk::style map Edged.Entry {*}[ttk::style map TEntry] \
+ -background {{pressed !disabled} lightpink}
+ }
+
+ if {[lsearch [bind . <<ThemeChanged>>] InitTheme] == -1} {
+ bind . <<ThemeChanged>> +[namespace code [list InitTheme]]
+ }
+}
+
++# Define a style used for the surround of text widgets.
++proc InitEntryFrame {} {
++ ttk::style theme settings default {
++ ttk::style layout EntryFrame {
++ EntryFrame.field -sticky nswe -border 0 -children {
++ EntryFrame.fill -sticky nswe -children {
++ EntryFrame.padding -sticky nswe
++ }
++ }
++ }
++ ttk::style configure EntryFrame -padding 1 -relief sunken
++ ttk::style map EntryFrame -background {}
++ }
++ ttk::style theme settings classic {
++ ttk::style configure EntryFrame -padding 2 -relief sunken
++ ttk::style map EntryFrame -background {}
++ }
++ ttk::style theme settings alt {
++ ttk::style configure EntryFrame -padding 2
++ ttk::style map EntryFrame -background {}
++ }
++ ttk::style theme settings clam {
++ ttk::style configure EntryFrame -padding 2
++ ttk::style map EntryFrame -background {}
++ }
++
++ # Ignore errors for missing native themes
++ catch {
++ ttk::style theme settings winnative {
++ ttk::style configure EntryFrame -padding 2
++ }
++ ttk::style theme settings xpnative {
++ ttk::style configure EntryFrame -padding 1
++ ttk::style element create EntryFrame.field vsapi \
++ EDIT 1 {disabled 4 focus 3 active 2 {} 1} -padding 1
++ }
++ ttk::style theme settings vista {
++ ttk::style configure EntryFrame -padding 2
++ ttk::style element create EntryFrame.field vsapi \
++ EDIT 6 {disabled 4 focus 3 active 2 {} 1} -padding 2
++ }
++ }
++
++ bind EntryFrame <Enter> {%W instate !disabled {%W state active}}
++ bind EntryFrame <Leave> {%W state !active}
++ bind EntryFrame <<ThemeChanged>> {
++ set pad [ttk::style lookup EntryFrame -padding]
++ %W configure -padding [expr {$pad eq {} ? 1 : $pad}]
++ }
++}
++
+proc gold_frame {w args} {
+ global use_ttk
+ if {$use_ttk} {
+ eval [linsert $args 0 ttk::frame $w -style Gold.TFrame]
+ } else {
+ eval [linsert $args 0 frame $w -background gold]
+ }
+}
+
+proc tlabel {w args} {
+ global use_ttk
+ if {$use_ttk} {
+ set cmd [list ttk::label $w -style Color.TLabel]
+ foreach {k v} $args {
+ switch -glob -- $k {
+ -activebackground {}
+ default { lappend cmd $k $v }
+ }
+ }
+ eval $cmd
+ } else {
+ eval [linsert $args 0 label $w]
+ }
+}
+
+# The padded label gets used in the about class.
+proc paddedlabel {w args} {
+ global use_ttk
+ if {$use_ttk} {
+ eval [linsert $args 0 ttk::label $w -style Padded.TLabel]
+ } else {
+ eval [linsert $args 0 label $w \
+ -padx 5 -pady 5 \
+ -justify left \
+ -anchor w \
+ -borderwidth 1 \
+ -relief solid]
+ }
+}
+
+# Create a toplevel for use as a dialog.
+# If available, sets the EWMH dialog hint and if ttk is enabled
+# place a themed frame over the surface.
+proc Dialog {w args} {
+ eval [linsert $args 0 toplevel $w -class Dialog]
++ catch {wm attributes $w -type dialog}
+ pave_toplevel $w
+ return $w
+}
+
+# Tk toplevels are not themed - so pave it over with a themed frame to get
+# the base color correct per theme.
+proc pave_toplevel {w} {
+ global use_ttk
+ if {$use_ttk && ![winfo exists $w.!paving]} {
+ set paving [ttk::frame $w.!paving]
+ place $paving -x 0 -y 0 -relwidth 1 -relheight 1
+ lower $paving
+ }
+}
+
+# Create a scrolled listbox with appropriate border for the current theme.
+# On many themes the border for a scrolled listbox needs to go around the
+# listbox and the scrollbar.
+proc slistbox {w args} {
+ global use_ttk NS
+ if {$use_ttk} {
+ set f [ttk::frame $w -style SListbox.TFrame -padding 2]
+ } else {
+ set f [frame $w -relief flat]
+ }
+ if {[catch {
+ if {$use_ttk} {
+ eval [linsert $args 0 listbox $f.list -relief flat \
+ -highlightthickness 0 -borderwidth 0]
+ } else {
+ eval [linsert $args 0 listbox $f.list]
+ }
+ ${NS}::scrollbar $f.vs -command [list $f.list yview]
+ $f.list configure -yscrollcommand [list $f.vs set]
+ grid $f.list $f.vs -sticky news
+ grid rowconfigure $f 0 -weight 1
+ grid columnconfigure $f 0 -weight 1
+ bind $f.list <<ListboxSelect>> \
+ [list event generate $w <<ListboxSelect>>]
+ interp hide {} $w
+ interp alias {} $w {} $f.list
+ } err]} {
+ destroy $f
+ return -code error $err
+ }
+ return $w
+}
+
+# fetch the background color from a widget.
+proc get_bg_color {w} {
+ global use_ttk
+ if {$use_ttk} {
+ set bg [ttk::style lookup [winfo class $w] -background]
+ } else {
+ set bg [$w cget -background]
+ }
+ return $bg
+}
+
+# ttk::spinbox didn't get added until 8.6
+proc tspinbox {w args} {
+ global use_ttk
+ if {$use_ttk && [llength [info commands ttk::spinbox]] > 0} {
+ eval [linsert $args 0 ttk::spinbox $w]
+ } else {
+ eval [linsert $args 0 spinbox $w]
+ }
+}
+
++# Create a text widget with any theme specific properties.
++proc ttext {w args} {
++ global use_ttk
++ if {$use_ttk} {
++ switch -- [ttk::style theme use] {
++ "vista" - "xpnative" {
++ lappend args -highlightthickness 0 -borderwidth 0
++ }
++ }
++ }
++ set w [eval [linsert $args 0 text $w]]
++ if {$use_ttk} {
++ if {[winfo class [winfo parent $w]] eq "EntryFrame"} {
++ bind $w <FocusIn> {[winfo parent %W] state focus}
++ bind $w <FocusOut> {[winfo parent %W] state !focus}
++ }
++ }
++ return $w
++}
++
++# themed frame suitable for surrounding a text field.
++proc textframe {w args} {
++ global use_ttk
++ if {$use_ttk} {
++ if {[catch {ttk::style layout EntryFrame}]} {
++ InitEntryFrame
++ }
++ eval [linsert $args 0 ttk::frame $w -class EntryFrame -style EntryFrame]
++ } else {
++ eval [linsert $args 0 frame $w]
++ }
++ return $w
++}
++
+proc tentry {w args} {
+ global use_ttk
+ if {$use_ttk} {
+ InitTheme
+ ttk::entry $w -style Edged.Entry
+ } else {
+ entry $w
+ }
+
+ rename $w _$w
+ interp alias {} $w {} tentry_widgetproc $w
+ eval [linsert $args 0 tentry_widgetproc $w configure]
+ return $w
+}
+proc tentry_widgetproc {w cmd args} {
+ global use_ttk
+ switch -- $cmd {
+ state {
+ if {$use_ttk} {
+ return [uplevel 1 [list _$w $cmd] $args]
+ } else {
+ if {[lsearch -exact $args pressed] != -1} {
+ _$w configure -background lightpink
+ } else {
+ _$w configure -background lightgreen
+ }
+ }
+ }
+ configure {
+ if {$use_ttk} {
+ if {[set n [lsearch -exact $args -background]] != -1} {
+ set args [lreplace $args $n [incr n]]
+ if {[llength $args] == 0} {return}
+ }
+ }
+ return [uplevel 1 [list _$w $cmd] $args]
+ }
+ default { return [uplevel 1 [list _$w $cmd] $args] }
+ }
+}
+
+# Tk 8.6 provides a standard font selection dialog. This uses the native
+# dialogs on Windows and MacOSX or a standard Tk dialog on X11.
+proc tchoosefont {w title familyvar sizevar} {
+ if {[package vsatisfies [package provide Tk] 8.6]} {
+ upvar #0 $familyvar family
+ upvar #0 $sizevar size
+ tk fontchooser configure -parent $w -title $title \
+ -font [list $family $size] \
+ -command [list on_choosefont $familyvar $sizevar]
+ tk fontchooser show
+ } else {
+ choose_font::pick $w $title $familyvar $sizevar
+ }
+}
+
+# Called when the Tk 8.6 fontchooser selects a font.
+proc on_choosefont {familyvar sizevar font} {
+ upvar #0 $familyvar family
+ upvar #0 $sizevar size
+ set font [font actual $font]
+ set family [dict get $font -family]
+ set size [dict get $font -size]
+}
+
+# Local variables:
+# mode: tcl
+# indent-tabs-mode: t
+# tab-width: 4
+# End:
--- /dev/null
+# git-gui Tools menu implementation
+
+proc tools_list {} {
+ global repo_config
+
+ set names {}
+ foreach item [array names repo_config guitool.*.cmd] {
+ lappend names [string range $item 8 end-4]
+ }
+ return [lsort $names]
+}
+
+proc tools_populate_all {} {
+ global tools_menubar tools_menutbl
+ global tools_tailcnt
+
+ set mbar_end [$tools_menubar index end]
+ set mbar_base [expr {$mbar_end - $tools_tailcnt}]
+ if {$mbar_base >= 0} {
+ $tools_menubar delete 0 $mbar_base
+ }
+
+ array unset tools_menutbl
+
+ foreach fullname [tools_list] {
+ tools_populate_one $fullname
+ }
+}
+
+proc tools_create_item {parent args} {
+ global tools_menubar tools_tailcnt
+ if {$parent eq $tools_menubar} {
+ set pos [expr {[$parent index end]-$tools_tailcnt+1}]
+ eval [list $parent insert $pos] $args
+ } else {
+ eval [list $parent add] $args
+ }
+}
+
+proc tools_populate_one {fullname} {
+ global tools_menubar tools_menutbl tools_id
+
+ if {![info exists tools_id]} {
+ set tools_id 0
+ }
+
+ set names [split $fullname '/']
+ set parent $tools_menubar
+ for {set i 0} {$i < [llength $names]-1} {incr i} {
+ set subname [join [lrange $names 0 $i] '/']
+ if {[info exists tools_menutbl($subname)]} {
+ set parent $tools_menutbl($subname)
+ } else {
+ set subid $parent.t$tools_id
+ tools_create_item $parent cascade \
+ -label [lindex $names $i] -menu $subid
+ menu $subid
+ set tools_menutbl($subname) $subid
+ set parent $subid
+ incr tools_id
+ }
+ }
+
+ tools_create_item $parent command \
+ -label [lindex $names end] \
+ -command [list tools_exec $fullname]
+}
+
+proc tools_exec {fullname} {
+ global repo_config env current_diff_path
+ global current_branch is_detached
++ global selected_paths
+
+ if {[is_config_true "guitool.$fullname.needsfile"]} {
+ if {$current_diff_path eq {}} {
+ error_popup [mc "Running %s requires a selected file." $fullname]
+ return
+ }
+ }
+
+ catch { unset env(ARGS) }
+ catch { unset env(REVISION) }
+
+ if {[get_config "guitool.$fullname.revprompt"] ne {} ||
+ [get_config "guitool.$fullname.argprompt"] ne {}} {
+ set dlg [tools_askdlg::dialog $fullname]
+ if {![tools_askdlg::execute $dlg]} {
+ return
+ }
+ } elseif {[is_config_true "guitool.$fullname.confirm"]} {
+ if {[is_config_true "guitool.$fullname.needsfile"]} {
+ if {[ask_popup [mc "Are you sure you want to run %1\$s on file \"%2\$s\"?" $fullname $current_diff_path]] ne {yes}} {
+ return
+ }
+ } else {
+ if {[ask_popup [mc "Are you sure you want to run %s?" $fullname]] ne {yes}} {
+ return
+ }
+ }
+ }
+
+ set env(GIT_GUITOOL) $fullname
+ set env(FILENAME) $current_diff_path
++ set env(FILENAMES) [join [array names selected_paths] \n]
+ if {$is_detached} {
+ set env(CUR_BRANCH) ""
+ } else {
+ set env(CUR_BRANCH) $current_branch
+ }
+
+ set cmdline $repo_config(guitool.$fullname.cmd)
+ if {[is_config_true "guitool.$fullname.noconsole"]} {
+ tools_run_silent [list sh -c $cmdline] \
+ [list tools_complete $fullname {}]
+ } else {
+ regsub {/} $fullname { / } title
+ set w [console::new \
+ [mc "Tool: %s" $title] \
+ [mc "Running: %s" $cmdline]]
+ console::exec $w [list sh -c $cmdline] \
+ [list tools_complete $fullname $w]
+ }
+
+ unset env(GIT_GUITOOL)
+ unset env(FILENAME)
++ unset env(FILENAMES)
+ unset env(CUR_BRANCH)
+ catch { unset env(ARGS) }
+ catch { unset env(REVISION) }
+}
+
+proc tools_run_silent {cmd after} {
+ lappend cmd 2>@1
+ set fd [_open_stdout_stderr $cmd]
+
+ fconfigure $fd -blocking 0 -translation binary
+ fileevent $fd readable [list tools_consume_input $fd $after]
+}
+
+proc tools_consume_input {fd after} {
+ read $fd
+ if {[eof $fd]} {
+ fconfigure $fd -blocking 1
+ if {[catch {close $fd}]} {
+ uplevel #0 $after 0
+ } else {
+ uplevel #0 $after 1
+ }
+ }
+}
+
+proc tools_complete {fullname w {ok 1}} {
+ if {$w ne {}} {
+ console::done $w $ok
+ }
+
+ if {$ok} {
+ set msg [mc "Tool completed successfully: %s" $fullname]
+ } else {
+ set msg [mc "Tool failed: %s" $fullname]
+ }
+
+ if {[is_config_true "guitool.$fullname.norescan"]} {
+ ui_status $msg
+ } else {
+ rescan [list ui_status $msg]
+ }
+}
--- /dev/null
- wm title $top [append "[appname] ([reponame]): " [mc "Add Tool"]]
+# git-gui Tools menu dialogs
+
+class tools_add {
+
+field w ; # widget path
+field w_name ; # new remote name widget
+field w_cmd ; # new remote location widget
+
+field name {}; # name of the tool
+field command {}; # command to execute
+field add_global 0; # add to the --global config
+field no_console 0; # disable using the console
+field needs_file 0; # ensure filename is set
+field confirm 0; # ask for confirmation
+field ask_branch 0; # ask for a revision
+field ask_args 0; # ask for additional args
+
+constructor dialog {} {
+ global repo_config use_ttk NS
+
+ make_dialog top w
- wm title $top [append "[appname] ([reponame]): " [mc "Remove Tool"]]
++ wm title $top [mc "%s (%s): Add Tool" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ wm transient $top .
+ }
+
+ ${NS}::label $w.header -text [mc "Add New Tool Command"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::checkbutton $w.buttons.global \
+ -text [mc "Add globally"] \
+ -variable @add_global
+ pack $w.buttons.global -side left -padx 5
+ ${NS}::button $w.buttons.create -text [mc Add] \
+ -default active \
+ -command [cb _add]
+ pack $w.buttons.create -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.desc -text [mc "Tool Details"]
+
+ ${NS}::label $w.desc.name_cmnt -anchor w\
+ -text [mc "Use '/' separators to create a submenu tree:"]
+ grid x $w.desc.name_cmnt -sticky we -padx {0 5} -pady {0 2}
+ ${NS}::label $w.desc.name_l -text [mc "Name:"]
+ set w_name $w.desc.name_t
+ ${NS}::entry $w_name \
+ -width 40 \
+ -textvariable @name \
+ -validate key \
+ -validatecommand [cb _validate_name %d %S]
+ grid $w.desc.name_l $w_name -sticky we -padx {0 5}
+
+ ${NS}::label $w.desc.cmd_l -text [mc "Command:"]
+ set w_cmd $w.desc.cmd_t
+ ${NS}::entry $w_cmd \
+ -width 40 \
+ -textvariable @command
+ grid $w.desc.cmd_l $w_cmd -sticky we -padx {0 5} -pady {0 3}
+
+ grid columnconfigure $w.desc 1 -weight 1
+ pack $w.desc -anchor nw -fill x -pady 5 -padx 5
+
+ ${NS}::checkbutton $w.confirm \
+ -text [mc "Show a dialog before running"] \
+ -variable @confirm -command [cb _check_enable_dlg]
+
+ ${NS}::labelframe $w.dlg -labelwidget $w.confirm
+
+ ${NS}::checkbutton $w.dlg.askbranch \
+ -text [mc "Ask the user to select a revision (sets \$REVISION)"] \
+ -variable @ask_branch -state disabled
+ pack $w.dlg.askbranch -anchor w -padx 15
+
+ ${NS}::checkbutton $w.dlg.askargs \
+ -text [mc "Ask the user for additional arguments (sets \$ARGS)"] \
+ -variable @ask_args -state disabled
+ pack $w.dlg.askargs -anchor w -padx 15
+
+ pack $w.dlg -anchor nw -fill x -pady {0 8} -padx 5
+
+ ${NS}::checkbutton $w.noconsole \
+ -text [mc "Don't show the command output window"] \
+ -variable @no_console
+ pack $w.noconsole -anchor w -padx 5
+
+ ${NS}::checkbutton $w.needsfile \
+ -text [mc "Run only if a diff is selected (\$FILENAME not empty)"] \
+ -variable @needs_file
+ pack $w.needsfile -anchor w -padx 5
+
+ bind $w <Visibility> [cb _visible]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _add]\;break
+ tkwait window $w
+}
+
+method _check_enable_dlg {} {
+ if {$confirm} {
+ $w.dlg.askbranch configure -state normal
+ $w.dlg.askargs configure -state normal
+ } else {
+ $w.dlg.askbranch configure -state disabled
+ $w.dlg.askargs configure -state disabled
+ }
+}
+
+method _add {} {
+ global repo_config
+
+ if {$name eq {}} {
+ error_popup [mc "Please supply a name for the tool."]
+ focus $w_name
+ return
+ }
+
+ set item "guitool.$name.cmd"
+
+ if {[info exists repo_config($item)]} {
+ error_popup [mc "Tool '%s' already exists." $name]
+ focus $w_name
+ return
+ }
+
+ set cmd [list git config]
+ if {$add_global} { lappend cmd --global }
+ set items {}
+ if {$no_console} { lappend items "guitool.$name.noconsole" }
+ if {$needs_file} { lappend items "guitool.$name.needsfile" }
+ if {$confirm} {
+ if {$ask_args} { lappend items "guitool.$name.argprompt" }
+ if {$ask_branch} { lappend items "guitool.$name.revprompt" }
+ if {!$ask_args && !$ask_branch} {
+ lappend items "guitool.$name.confirm"
+ }
+ }
+
+ if {[catch {
+ eval $cmd [list $item $command]
+ foreach citem $items { eval $cmd [list $citem yes] }
+ } err]} {
+ error_popup [mc "Could not add tool:\n%s" $err]
+ } else {
+ set repo_config($item) $command
+ foreach citem $items { set repo_config($citem) yes }
+
+ tools_populate_all
+ }
+
+ destroy $w
+}
+
+method _validate_name {d S} {
+ if {$d == 1} {
+ if {[regexp {[~?*&\[\0\"\\\{]} $S]} {
+ return 0
+ }
+ }
+ return 1
+}
+
+method _visible {} {
+ grab $w
+ $w_name icursor end
+ focus $w_name
+}
+
+}
+
+class tools_remove {
+
+field w ; # widget path
+field w_names ; # name list
+
+constructor dialog {} {
+ global repo_config global_config system_config use_ttk NS
+
+ load_config 1
+
+ make_dialog top w
- wm title $top [append "[appname] ([reponame]): " $title]
++ wm title $top [mc "%s (%s): Remove Tool" [appname] [reponame]]
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ wm transient $top .
+ }
+
+ ${NS}::label $w.header -text [mc "Remove Tool Commands"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.create -text [mc Remove] \
+ -default active \
+ -command [cb _remove]
+ pack $w.buttons.create -side right
+ ${NS}::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
+
+ ${NS}::frame $w.list
+ set w_names $w.list.l
+ slistbox $w_names \
+ -height 10 \
+ -width 30 \
+ -selectmode extended \
+ -exportselection false
+ pack $w.list.l -side left -fill both -expand 1
+ pack $w.list -fill both -expand 1 -pady 5 -padx 5
+
+ set local_cnt 0
+ foreach fullname [tools_list] {
+ # Cannot delete system tools
+ if {[info exists system_config(guitool.$fullname.cmd)]} continue
+
+ $w_names insert end $fullname
+ if {![info exists global_config(guitool.$fullname.cmd)]} {
+ $w_names itemconfigure end -foreground blue
+ incr local_cnt
+ }
+ }
+
+ if {$local_cnt > 0} {
+ ${NS}::label $w.colorlbl -foreground blue \
+ -text [mc "(Blue denotes repository-local tools)"]
+ pack $w.colorlbl -fill x -pady 5 -padx 5
+ }
+
+ bind $w <Visibility> [cb _visible]
+ bind $w <Key-Escape> [list destroy $w]
+ bind $w <Key-Return> [cb _remove]\;break
+ tkwait window $w
+}
+
+method _remove {} {
+ foreach i [$w_names curselection] {
+ set name [$w_names get $i]
+
+ catch { git config --remove-section guitool.$name }
+ catch { git config --global --remove-section guitool.$name }
+ }
+
+ load_config 0
+ tools_populate_all
+
+ destroy $w
+}
+
+method _visible {} {
+ grab $w
+ focus $w_names
+}
+
+}
+
+class tools_askdlg {
+
+field w ; # widget path
+field w_rev {}; # revision browser
+field w_args {}; # arguments
+
+field is_ask_args 0; # has arguments field
+field is_ask_revs 0; # has revision browser
+
+field is_ok 0; # ok to start
+field argstr {}; # arguments
+
+constructor dialog {fullname} {
+ global M1B use_ttk NS
+
+ set title [get_config "guitool.$fullname.title"]
+ if {$title eq {}} {
+ regsub {/} $fullname { / } title
+ }
+
+ make_dialog top w -autodelete 0
++ wm title $top "[mc "%s (%s):" [appname] [reponame]] $title"
+ if {$top ne {.}} {
+ wm geometry $top "+[winfo rootx .]+[winfo rooty .]"
+ wm transient $top .
+ }
+
+ set prompt [get_config "guitool.$fullname.prompt"]
+ if {$prompt eq {}} {
+ set command [get_config "guitool.$fullname.cmd"]
+ set prompt [mc "Run Command: %s" $command]
+ }
+
+ ${NS}::label $w.header -text $prompt -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ set argprompt [get_config "guitool.$fullname.argprompt"]
+ set revprompt [get_config "guitool.$fullname.revprompt"]
+
+ set is_ask_args [expr {$argprompt ne {}}]
+ set is_ask_revs [expr {$revprompt ne {}}]
+
+ if {$is_ask_args} {
+ if {$argprompt eq {yes} || $argprompt eq {true} || $argprompt eq {1}} {
+ set argprompt [mc "Arguments"]
+ }
+
+ ${NS}::labelframe $w.arg -text $argprompt
+
+ set w_args $w.arg.txt
+ ${NS}::entry $w_args \
+ -width 40 \
+ -textvariable @argstr
+ pack $w_args -padx 5 -pady 5 -fill both
+ pack $w.arg -anchor nw -fill both -pady 5 -padx 5
+ }
+
+ if {$is_ask_revs} {
+ if {$revprompt eq {yes} || $revprompt eq {true} || $revprompt eq {1}} {
+ set revprompt [mc "Revision"]
+ }
+
+ if {[is_config_true "guitool.$fullname.revunmerged"]} {
+ set w_rev [::choose_rev::new_unmerged $w.rev $revprompt]
+ } else {
+ set w_rev [::choose_rev::new $w.rev $revprompt]
+ }
+
+ pack $w.rev -anchor nw -fill both -expand 1 -pady 5 -padx 5
+ }
+
+ ${NS}::frame $w.buttons
+ if {$is_ask_revs} {
+ ${NS}::button $w.buttons.visualize \
+ -text [mc Visualize] \
+ -command [cb _visualize]
+ pack $w.buttons.visualize -side left
+ }
+ ${NS}::button $w.buttons.ok \
+ -text [mc OK] \
+ -command [cb _start]
+ pack $w.buttons.ok -side right
+ ${NS}::button $w.buttons.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
+
+ bind $w <$M1B-Key-Return> [cb _start]
+ bind $w <Key-Return> [cb _start]
+ bind $w <Key-Escape> [cb _cancel]
+ wm protocol $w WM_DELETE_WINDOW [cb _cancel]
+
+ bind $w <Visibility> [cb _visible]
+ return $this
+}
+
+method execute {} {
+ tkwait window $w
+ set rv $is_ok
+ delete_this
+ return $rv
+}
+
+method _visible {} {
+ grab $w
+ if {$is_ask_args} {
+ focus $w_args
+ } elseif {$is_ask_revs} {
+ $w_rev focus_filter
+ }
+}
+
+method _cancel {} {
+ wm protocol $w WM_DELETE_WINDOW {}
+ destroy $w
+}
+
+method _rev {} {
+ if {[catch {$w_rev commit_or_die}]} {
+ return {}
+ }
+ return [$w_rev get]
+}
+
+method _visualize {} {
+ global current_branch
+ set rev [_rev $this]
+ if {$rev ne {}} {
+ do_gitk [list --left-right "$current_branch...$rev"]
+ }
+}
+
+method _start {} {
+ global env
+
+ if {$is_ask_revs} {
+ set name [_rev $this]
+ if {$name eq {}} {
+ return
+ }
+ set env(REVISION) $name
+ }
+
+ if {$is_ask_args} {
+ set env(ARGS) $argstr
+ }
+
+ set is_ok 1
+ _cancel $this
+}
+
+}
--- /dev/null
- wm title $w [append "[appname] ([reponame]): " [mc "Push"]]
+# git-gui transport (fetch/push) support
+# Copyright (C) 2006, 2007 Shawn Pearce
+
+proc fetch_from {remote} {
+ set w [console::new \
+ [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]} {
+ lappend cmds [list exec git remote prune $remote]
+ }
+ console::chain $w $cmds
+}
+
+proc prune_from {remote} {
+ set w [console::new \
+ [mc "remote prune %s" $remote] \
+ [mc "Pruning tracking branches deleted from %s" $remote]]
+ console::exec $w [list git remote prune $remote]
+}
+
+proc fetch_from_all {} {
+ set w [console::new \
+ [mc "fetch all remotes"] \
+ [mc "Fetching new changes from all remotes"]]
+
+ set cmd [list git fetch --all]
+ if {[is_config_true gui.pruneduringfetch]} {
+ lappend cmd --prune
+ }
+
+ console::exec $w $cmd
+}
+
+proc prune_from_all {} {
+ global all_remotes
+
+ set w [console::new \
+ [mc "remote prune all remotes"] \
+ [mc "Pruning tracking branches deleted from all remotes"]]
+
+ set cmd [list git remote prune]
+
+ foreach r $all_remotes {
+ lappend cmd $r
+ }
+
+ console::exec $w $cmd
+}
+
+proc push_to {remote} {
+ set w [console::new \
+ [mc "push %s" $remote] \
+ [mc "Pushing changes to %s" $remote]]
+ set cmd [list git push]
+ lappend cmd -v
+ lappend cmd $remote
+ console::exec $w $cmd
+}
+
+proc start_push_anywhere_action {w} {
+ global push_urltype push_remote push_url push_thin push_tags
+ global push_force
+ global repo_config
+
+ set is_mirror 0
+ set r_url {}
+ switch -- $push_urltype {
+ remote {
+ set r_url $push_remote
+ catch {set is_mirror $repo_config(remote.$push_remote.mirror)}
+ }
+ url {set r_url $push_url}
+ }
+ if {$r_url eq {}} return
+
+ set cmd [list git push]
+ lappend cmd -v
+ if {$push_thin} {
+ lappend cmd --thin
+ }
+ if {$push_force} {
+ lappend cmd --force
+ }
+ if {$push_tags} {
+ lappend cmd --tags
+ }
+ lappend cmd $r_url
+ if {$is_mirror} {
+ set cons [console::new \
+ [mc "push %s" $r_url] \
+ [mc "Mirroring to %s" $r_url]]
+ } else {
+ set cnt 0
+ foreach i [$w.source.l curselection] {
+ set b [$w.source.l get $i]
+ lappend cmd "refs/heads/$b:refs/heads/$b"
+ incr cnt
+ }
+ if {$cnt == 0} {
+ return
+ } elseif {$cnt == 1} {
+ set unit branch
+ } else {
+ set unit branches
+ }
+
+ set cons [console::new \
+ [mc "push %s" $r_url] \
+ [mc "Pushing %s %s to %s" $cnt $unit $r_url]]
+ }
+ console::exec $cons $cmd
+ destroy $w
+}
+
+trace add variable push_remote write \
+ [list radio_selector push_urltype remote]
+
+proc do_push_anywhere {} {
+ global all_remotes current_branch
+ global push_urltype push_remote push_url push_thin push_tags
+ global push_force use_ttk NS
+
+ set w .push_setup
+ toplevel $w
+ catch {wm attributes $w -type dialog}
+ wm withdraw $w
+ wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
+ pave_toplevel $w
+
+ ${NS}::label $w.header -text [mc "Push Branches"] \
+ -font font_uibold -anchor center
+ pack $w.header -side top -fill x
+
+ ${NS}::frame $w.buttons
+ ${NS}::button $w.buttons.create -text [mc Push] \
+ -default active \
+ -command [list start_push_anywhere_action $w]
+ pack $w.buttons.create -side right
+ ${NS}::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
+
+ ${NS}::labelframe $w.source -text [mc "Source Branches"]
+ slistbox $w.source.l \
+ -height 10 \
+ -width 70 \
+ -selectmode extended
+ foreach h [load_all_heads] {
+ $w.source.l insert end $h
+ if {$h eq $current_branch} {
+ $w.source.l select set end
+ $w.source.l yview end
+ }
+ }
+ pack $w.source.l -side left -fill both -expand 1
+ pack $w.source -fill both -expand 1 -pady 5 -padx 5
+
+ ${NS}::labelframe $w.dest -text [mc "Destination Repository"]
+ if {$all_remotes ne {}} {
+ ${NS}::radiobutton $w.dest.remote_r \
+ -text [mc "Remote:"] \
+ -value remote \
+ -variable push_urltype
+ if {$use_ttk} {
+ ttk::combobox $w.dest.remote_m -state readonly \
+ -exportselection false \
+ -textvariable push_remote \
+ -values $all_remotes
+ } else {
+ eval tk_optionMenu $w.dest.remote_m push_remote $all_remotes
+ }
+ grid $w.dest.remote_r $w.dest.remote_m -sticky w
+ if {[lsearch -sorted -exact $all_remotes origin] != -1} {
+ set push_remote origin
+ } else {
+ set push_remote [lindex $all_remotes 0]
+ }
+ set push_urltype remote
+ } else {
+ set push_urltype url
+ }
+ ${NS}::radiobutton $w.dest.url_r \
+ -text [mc "Arbitrary Location:"] \
+ -value url \
+ -variable push_urltype
+ ${NS}::entry $w.dest.url_t \
+ -width 50 \
+ -textvariable push_url \
+ -validate key \
+ -validatecommand {
+ if {%d == 1 && [regexp {\s} %S]} {return 0}
+ if {%d == 1 && [string length %S] > 0} {
+ set push_urltype url
+ }
+ return 1
+ }
+ grid $w.dest.url_r $w.dest.url_t -sticky we -padx {0 5}
+ grid columnconfigure $w.dest 1 -weight 1
+ pack $w.dest -anchor nw -fill x -pady 5 -padx 5
+
+ ${NS}::labelframe $w.options -text [mc "Transfer Options"]
+ ${NS}::checkbutton $w.options.force \
+ -text [mc "Force overwrite existing branch (may discard changes)"] \
+ -variable push_force
+ grid $w.options.force -columnspan 2 -sticky w
+ ${NS}::checkbutton $w.options.thin \
+ -text [mc "Use thin pack (for slow network connections)"] \
+ -variable push_thin
+ grid $w.options.thin -columnspan 2 -sticky w
+ ${NS}::checkbutton $w.options.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 [mc "%s (%s): Push" [appname] [reponame]]
+ wm deiconify $w
+ tkwait window $w
+}
--- /dev/null
- # Copyright (C) 2012, 2013, 2014, 2015 Alexander Shopov <ash@kambanaria.org>.
+# Bulgarian translation of git-gui po-file.
- # Alexander Shopov <ash@kambanaria.org>, 2012, 2013, 2014, 2015.
++# Copyright (C) 2012, 2013, 2014, 2015, 2016 Alexander Shopov <ash@kambanaria.org>.
+# This file is distributed under the same license as the git package.
- "POT-Creation-Date: 2015-04-07 07:37+0300\n"
- "PO-Revision-Date: 2015-04-07 07:46+0300\n"
++# Alexander Shopov <ash@kambanaria.org>, 2012, 2013, 2014, 2015, 2016.
+#
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: git-gui master\n"
+"Report-Msgid-Bugs-To: \n"
- #: git-gui.sh:861
++"POT-Creation-Date: 2016-10-13 15:16+0300\n"
++"PO-Revision-Date: 2016-10-13 15:16+0300\n"
+"Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
+"Language-Team: Bulgarian <dict@fsa-bg.org>\n"
+"Language: bg\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
- #: git-gui.sh:915
++#: git-gui.sh:865
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "Указан е неправилен шрифт в „%s“:"
+
- #: git-gui.sh:916
++#: git-gui.sh:919
+msgid "Main Font"
+msgstr "Основен шрифт"
+
- #: git-gui.sh:931 git-gui.sh:945 git-gui.sh:958 git-gui.sh:1048
- #: git-gui.sh:1067 git-gui.sh:3125
++#: git-gui.sh:920
+msgid "Diff/Console Font"
+msgstr "Шрифт за разликите/конзолата"
+
- #: git-gui.sh:932
++#: git-gui.sh:935 git-gui.sh:949 git-gui.sh:962 git-gui.sh:1052 git-gui.sh:1071
++#: git-gui.sh:3147
+msgid "git-gui: fatal error"
+msgstr "git-gui: фатална грешка"
+
- #: git-gui.sh:959
++#: git-gui.sh:936
+msgid "Cannot find git in PATH."
+msgstr "Командата git липсва в пътя (PATH)."
+
- #: git-gui.sh:984
++#: git-gui.sh:963
+msgid "Cannot parse Git version string:"
+msgstr "Низът с версията на Git не може да бъде интерпретиран:"
+
- #: git-gui.sh:1281
++#: git-gui.sh:988
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
+msgstr ""
+"Версията на Git не може да бъде определена.\n"
+"\n"
+"Версията на „%s“ изглежда, че е „%s“.\n"
+"\n"
+"„%s“ изисква Git, версия поне 1.5.0.\n"
+"\n"
+"Да се приеме ли, че „%s“ е версия „1.5.0“?\n"
+
- #: git-gui.sh:1315
++#: git-gui.sh:1285
+msgid "Git directory not found:"
+msgstr "Директорията на Git не е открита:"
+
- #: git-gui.sh:1323
++#: git-gui.sh:1319
+msgid "Cannot move to top of working directory:"
+msgstr "Не може да се премине към родителската директория."
+
- #: git-gui.sh:1331
++#: git-gui.sh:1327
+msgid "Cannot use bare repository:"
+msgstr "Голо хранилище не може да се използва:"
+
- #: git-gui.sh:1503 lib/checkout_op.tcl:306
++#: git-gui.sh:1335
+msgid "No working directory"
+msgstr "Работната директория липсва"
+
- #: git-gui.sh:1563
++#: git-gui.sh:1507 lib/checkout_op.tcl:306
+msgid "Refreshing file status..."
+msgstr "Обновяване на състоянието на файла…"
+
- #: git-gui.sh:1639
++#: git-gui.sh:1567
+msgid "Scanning for modified files ..."
+msgstr "Проверка за променени файлове…"
+
- #: git-gui.sh:1656
++#: git-gui.sh:1645
+msgid "Calling prepare-commit-msg hook..."
+msgstr "Куката „prepare-commit-msg“ се изпълнява в момента…"
+
- #: git-gui.sh:1814 lib/browser.tcl:252
++#: git-gui.sh:1662
+msgid "Commit declined by prepare-commit-msg hook."
+msgstr "Подаването е отхвърлено от куката „prepare-commit-msg“."
+
- #: git-gui.sh:1978
++#: git-gui.sh:1820 lib/browser.tcl:252
+msgid "Ready."
+msgstr "Готово."
+
- "Достигнат е максималният брой файлове за показване (gui.maxfilesdisplayed = "
- "%s). Файловете са общо %s."
++#: git-gui.sh:1984
+#, tcl-format
+msgid ""
+"Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s files."
+msgstr ""
- #: git-gui.sh:2101
++"Достигнат е максималният размер на списъка за извеждане(gui."
++"maxfilesdisplayed = %s), съответно не са показани всички %s файла."
+
- #: git-gui.sh:2103
++#: git-gui.sh:2107
+msgid "Unmodified"
+msgstr "Непроменен"
+
- #: git-gui.sh:2104 git-gui.sh:2116
++#: git-gui.sh:2109
+msgid "Modified, not staged"
+msgstr "Променен, но не е в индекса"
+
- #: git-gui.sh:2105 git-gui.sh:2117
++#: git-gui.sh:2110 git-gui.sh:2122
+msgid "Staged for commit"
+msgstr "В индекса за подаване"
+
- #: git-gui.sh:2106 git-gui.sh:2118
++#: git-gui.sh:2111 git-gui.sh:2123
+msgid "Portions staged for commit"
+msgstr "Части са в индекса за подаване"
+
- #: git-gui.sh:2108
++#: git-gui.sh:2112 git-gui.sh:2124
+msgid "Staged for commit, missing"
+msgstr "В индекса за подаване, но липсва"
+
- #: git-gui.sh:2109 git-gui.sh:2110
++#: git-gui.sh:2114
+msgid "File type changed, not staged"
+msgstr "Видът на файла е сменен, но не е в индекса"
+
- msgstr "Видът на файла е сменен, но в индекса е все още старият"
++#: git-gui.sh:2115 git-gui.sh:2116
+msgid "File type changed, old type staged for commit"
- #: git-gui.sh:2111
++msgstr "Видът на файла е сменен, но новият вид не е в индекса"
+
- #: git-gui.sh:2112
++#: git-gui.sh:2117
+msgid "File type changed, staged"
+msgstr "Видът на файла е сменен и е в индекса"
+
- msgstr "Видът на файла е сменен, но промяната не е в индекса"
++#: git-gui.sh:2118
+msgid "File type change staged, modification not staged"
- #: git-gui.sh:2113
++msgstr "Видът на файла е сменен в индекса, но не и съдържанието"
+
- msgstr "Видът на файла е сменен, файлът липсва"
++#: git-gui.sh:2119
+msgid "File type change staged, file missing"
- #: git-gui.sh:2115
++msgstr "Видът на файла е сменен в индекса, но файлът липсва"
+
- #: git-gui.sh:2120
++#: git-gui.sh:2121
+msgid "Untracked, not staged"
+msgstr "Неследен"
+
- #: git-gui.sh:2121
++#: git-gui.sh:2126
+msgid "Missing"
+msgstr "Липсващ"
+
- #: git-gui.sh:2122
++#: git-gui.sh:2127
+msgid "Staged for removal"
+msgstr "В индекса за изтриване"
+
- #: git-gui.sh:2124 git-gui.sh:2125 git-gui.sh:2126 git-gui.sh:2127
- #: git-gui.sh:2128 git-gui.sh:2129
++#: git-gui.sh:2128
+msgid "Staged for removal, still present"
+msgstr "В индекса за изтриване, но още го има"
+
- #: git-gui.sh:2164
++#: git-gui.sh:2130 git-gui.sh:2131 git-gui.sh:2132 git-gui.sh:2133
++#: git-gui.sh:2134 git-gui.sh:2135
+msgid "Requires merge resolution"
+msgstr "Изисква коригиране при сливане"
+
- #: git-gui.sh:2176
++#: git-gui.sh:2170
+msgid "Starting gitk... please wait..."
+msgstr "Стартиране на „gitk“…, изчакайте…"
+
- #: git-gui.sh:2235
++#: git-gui.sh:2182
+msgid "Couldn't find gitk in PATH"
+msgstr "Командата „gitk“ липсва в пътищата, определени от променливата PATH."
+
- #: git-gui.sh:2654 lib/choose_repository.tcl:41
++#: git-gui.sh:2241
+msgid "Couldn't find git gui in PATH"
+msgstr ""
+"Командата „git gui“ липсва в пътищата, определени от променливата PATH."
+
- #: git-gui.sh:2655
++#: git-gui.sh:2676 lib/choose_repository.tcl:41
+msgid "Repository"
+msgstr "Хранилище"
+
- #: git-gui.sh:2657 lib/choose_rev.tcl:567
++#: git-gui.sh:2677
+msgid "Edit"
+msgstr "Редактиране"
+
- #: git-gui.sh:2660 lib/choose_rev.tcl:554
++#: git-gui.sh:2679 lib/choose_rev.tcl:567
+msgid "Branch"
+msgstr "Клон"
+
- #: git-gui.sh:2663 lib/merge.tcl:123 lib/merge.tcl:152 lib/merge.tcl:170
++#: git-gui.sh:2682 lib/choose_rev.tcl:554
+msgid "Commit@@noun"
+msgstr "Подаване"
+
- #: git-gui.sh:2664 lib/choose_rev.tcl:563
++#: git-gui.sh:2685 lib/merge.tcl:127 lib/merge.tcl:174
+msgid "Merge"
+msgstr "Сливане"
+
- #: git-gui.sh:2667
++#: git-gui.sh:2686 lib/choose_rev.tcl:563
+msgid "Remote"
+msgstr "Отдалечено хранилище"
+
- #: git-gui.sh:2676
++#: git-gui.sh:2689
+msgid "Tools"
+msgstr "Команди"
+
- #: git-gui.sh:2682
++#: git-gui.sh:2698
+msgid "Explore Working Copy"
+msgstr "Разглеждане на работното копие"
+
- #: git-gui.sh:2692
++#: git-gui.sh:2704
+msgid "Git Bash"
+msgstr "Bash за Git"
+
- #: git-gui.sh:2696
++#: git-gui.sh:2714
+msgid "Browse Current Branch's Files"
+msgstr "Разглеждане на файловете в текущия клон"
+
- #: git-gui.sh:2701
++#: git-gui.sh:2718
+msgid "Browse Branch Files..."
+msgstr "Разглеждане на текущия клон…"
+
- #: git-gui.sh:2705
++#: git-gui.sh:2723
+msgid "Visualize Current Branch's History"
+msgstr "Визуализация на историята на текущия клон"
+
- #: git-gui.sh:2712
++#: git-gui.sh:2727
+msgid "Visualize All Branch History"
+msgstr "Визуализация на историята на всички клонове"
+
- msgstr "Разглеждане на файловете в %s"
++#: git-gui.sh:2734
+#, tcl-format
+msgid "Browse %s's Files"
- #: git-gui.sh:2714
++msgstr "Разглеждане на файловете в „%s“"
+
- msgstr "Визуализация на историята на %s"
++#: git-gui.sh:2736
+#, tcl-format
+msgid "Visualize %s's History"
- #: git-gui.sh:2719 lib/database.tcl:40 lib/database.tcl:66
++msgstr "Визуализация на историята на „%s“"
+
- #: git-gui.sh:2722 lib/database.tcl:33
++#: git-gui.sh:2741 lib/database.tcl:40
+msgid "Database Statistics"
+msgstr "Статистика на базата от данни"
+
- #: git-gui.sh:2725
++#: git-gui.sh:2744 lib/database.tcl:33
+msgid "Compress Database"
+msgstr "Компресиране на базата от данни"
+
- #: git-gui.sh:2732 git-gui.sh:2736 git-gui.sh:2740 lib/shortcut.tcl:8
- #: lib/shortcut.tcl:40 lib/shortcut.tcl:72
++#: git-gui.sh:2747
+msgid "Verify Database"
+msgstr "Проверка на базата от данни"
+
- #: git-gui.sh:2748 lib/choose_repository.tcl:193 lib/choose_repository.tcl:201
++#: git-gui.sh:2754 git-gui.sh:2758 git-gui.sh:2762
+msgid "Create Desktop Icon"
+msgstr "Добавяне на икона на работния плот"
+
- #: git-gui.sh:2756
++#: git-gui.sh:2770 lib/choose_repository.tcl:193 lib/choose_repository.tcl:201
+msgid "Quit"
+msgstr "Спиране на програмата"
+
- #: git-gui.sh:2759
++#: git-gui.sh:2778
+msgid "Undo"
+msgstr "Отмяна"
+
- #: git-gui.sh:2763 git-gui.sh:3368
++#: git-gui.sh:2781
+msgid "Redo"
+msgstr "Повторение"
+
- #: git-gui.sh:2766 git-gui.sh:3371 git-gui.sh:3445 git-gui.sh:3530
++#: git-gui.sh:2785 git-gui.sh:3399
+msgid "Cut"
+msgstr "Отрязване"
+
- #: git-gui.sh:2769 git-gui.sh:3374
++#: git-gui.sh:2788 git-gui.sh:3402 git-gui.sh:3476 git-gui.sh:3562
+#: lib/console.tcl:69
+msgid "Copy"
+msgstr "Копиране"
+
- #: git-gui.sh:2772 git-gui.sh:3377 lib/remote_branch_delete.tcl:39
- #: lib/branch_delete.tcl:28
++#: git-gui.sh:2791 git-gui.sh:3405
+msgid "Paste"
+msgstr "Поставяне"
+
- #: git-gui.sh:2776 git-gui.sh:3381 git-gui.sh:3534 lib/console.tcl:71
++#: git-gui.sh:2794 git-gui.sh:3408 lib/branch_delete.tcl:28
++#: lib/remote_branch_delete.tcl:39
+msgid "Delete"
+msgstr "Изтриване"
+
- #: git-gui.sh:2785
++#: git-gui.sh:2798 git-gui.sh:3412 git-gui.sh:3566 lib/console.tcl:71
+msgid "Select All"
+msgstr "Избиране на всичко"
+
- #: git-gui.sh:2791
++#: git-gui.sh:2807
+msgid "Create..."
+msgstr "Създаване…"
+
- #: git-gui.sh:2797
++#: git-gui.sh:2813
+msgid "Checkout..."
+msgstr "Изтегляне…"
+
- #: git-gui.sh:2802
++#: git-gui.sh:2819
+msgid "Rename..."
+msgstr "Преименуване…"
+
- #: git-gui.sh:2807
++#: git-gui.sh:2824
+msgid "Delete..."
+msgstr "Изтриване…"
+
- #: git-gui.sh:2817
++#: git-gui.sh:2829
+msgid "Reset..."
+msgstr "Отмяна на промените…"
+
- #: git-gui.sh:2819
++#: git-gui.sh:2839
+msgid "Done"
+msgstr "Готово"
+
- #: git-gui.sh:2828 git-gui.sh:3309
++#: git-gui.sh:2841
+msgid "Commit@@verb"
+msgstr "Подаване"
+
- #: git-gui.sh:2836 git-gui.sh:3316
++#: git-gui.sh:2850 git-gui.sh:3335
+msgid "New Commit"
+msgstr "Ново подаване"
+
- #: git-gui.sh:2846 git-gui.sh:3270 lib/remote_branch_delete.tcl:101
++#: git-gui.sh:2858 git-gui.sh:3342
+msgid "Amend Last Commit"
+msgstr "Поправяне на последното подаване"
+
- #: git-gui.sh:2852
++#: git-gui.sh:2868 git-gui.sh:3296 lib/remote_branch_delete.tcl:101
+msgid "Rescan"
+msgstr "Обновяване"
+
- #: git-gui.sh:2858
++#: git-gui.sh:2874
+msgid "Stage To Commit"
+msgstr "Към индекса за подаване"
+
- #: git-gui.sh:2864
++#: git-gui.sh:2880
+msgid "Stage Changed Files To Commit"
+msgstr "Всички променени файлове към индекса за подаване"
+
- #: git-gui.sh:2870 lib/index.tcl:442
++#: git-gui.sh:2886
+msgid "Unstage From Commit"
+msgstr "Изваждане от индекса за подаване"
+
- #: git-gui.sh:2878 git-gui.sh:3581 git-gui.sh:3612
++#: git-gui.sh:2892 lib/index.tcl:442
+msgid "Revert Changes"
+msgstr "Връщане на оригинала"
+
- #: git-gui.sh:2882 git-gui.sh:3585 git-gui.sh:3616
++#: git-gui.sh:2900 git-gui.sh:3613 git-gui.sh:3644
+msgid "Show Less Context"
+msgstr "По-малко контекст"
+
- #: git-gui.sh:2889 git-gui.sh:3283 git-gui.sh:3392
++#: git-gui.sh:2904 git-gui.sh:3617 git-gui.sh:3648
+msgid "Show More Context"
+msgstr "Повече контекст"
+
- #: git-gui.sh:2905
++#: git-gui.sh:2911 git-gui.sh:3309 git-gui.sh:3423
+msgid "Sign Off"
+msgstr "Подписване"
+
- #: git-gui.sh:2910
++#: git-gui.sh:2927
+msgid "Local Merge..."
+msgstr "Локално сливане…"
+
- #: git-gui.sh:2922 git-gui.sh:2950
++#: git-gui.sh:2932
+msgid "Abort Merge..."
+msgstr "Преустановяване на сливане…"
+
- #: git-gui.sh:2926
++#: git-gui.sh:2944 git-gui.sh:2972
+msgid "Add..."
+msgstr "Добавяне…"
+
- msgstr "Избутване…"
++#: git-gui.sh:2948
+msgid "Push..."
- #: git-gui.sh:2930
++msgstr "Изтласкване…"
+
- #: git-gui.sh:2940 git-gui.sh:3563
++#: git-gui.sh:2952
+msgid "Delete Branch..."
+msgstr "Изтриване на клон…"
+
- #: git-gui.sh:2951
++#: git-gui.sh:2962 git-gui.sh:3595
+msgid "Options..."
+msgstr "Опции…"
+
- #: git-gui.sh:2960 lib/choose_repository.tcl:55
++#: git-gui.sh:2973
+msgid "Remove..."
+msgstr "Премахване…"
+
- #: git-gui.sh:2964 git-gui.sh:2968 lib/choose_repository.tcl:49
- #: lib/choose_repository.tcl:58 lib/about.tcl:14
++#: git-gui.sh:2982 lib/choose_repository.tcl:55
+msgid "Help"
+msgstr "Помощ"
+
- #: git-gui.sh:2992
++#: git-gui.sh:2986 git-gui.sh:2990 lib/about.tcl:14
++#: lib/choose_repository.tcl:49 lib/choose_repository.tcl:58
+#, tcl-format
+msgid "About %s"
+msgstr "Относно %s"
+
- #: git-gui.sh:2995 lib/choose_repository.tcl:52 lib/choose_repository.tcl:61
++#: git-gui.sh:3014
+msgid "Online Documentation"
+msgstr "Документация в Интернет"
+
- #: git-gui.sh:3014 git-gui.sh:3146
++#: git-gui.sh:3017 lib/choose_repository.tcl:52 lib/choose_repository.tcl:61
+msgid "Show SSH Key"
+msgstr "Показване на ключа за SSH"
+
- #: git-gui.sh:3095 lib/blame.tcl:573
++#: git-gui.sh:3032 git-gui.sh:3164
++msgid "usage:"
++msgstr "употреба:"
++
++#: git-gui.sh:3036 git-gui.sh:3168
+msgid "Usage"
+msgstr "Употреба"
+
- #: git-gui.sh:3126
++#: git-gui.sh:3117 lib/blame.tcl:573
+msgid "Error"
+msgstr "Грешка"
+
- #: git-gui.sh:3159
++#: git-gui.sh:3148
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr ""
+"ФАТАЛНА ГРЕШКА: пътят %s не може да бъде открит: такъв файл или директория "
+"няма"
+
- #: git-gui.sh:3185
- msgid "Staged Changes (Will Commit)"
- msgstr "Промени в индекса (за подаване)"
-
- #: git-gui.sh:3205
++#: git-gui.sh:3181
+msgid "Current Branch:"
+msgstr "Текущ клон:"
+
- #: git-gui.sh:3276
++#: git-gui.sh:3206
+msgid "Unstaged Changes"
+msgstr "Промени извън индекса"
+
- #: git-gui.sh:3295 lib/transport.tcl:137 lib/transport.tcl:229
++#: git-gui.sh:3228
++msgid "Staged Changes (Will Commit)"
++msgstr "Промени в индекса (за подаване)"
++
++#: git-gui.sh:3302
+msgid "Stage Changed"
+msgstr "Индексът е променен"
+
- #: git-gui.sh:3330
++#: git-gui.sh:3321 lib/transport.tcl:137
+msgid "Push"
+msgstr "Изтласкване"
+
- #: git-gui.sh:3331
++#: git-gui.sh:3356
+msgid "Initial Commit Message:"
+msgstr "Първоначално съобщение при подаване:"
+
- #: git-gui.sh:3332
++#: git-gui.sh:3357
+msgid "Amended Commit Message:"
+msgstr "Поправено съобщение при подаване:"
+
- #: git-gui.sh:3333
++#: git-gui.sh:3358
+msgid "Amended Initial Commit Message:"
+msgstr "Поправено първоначално съобщение при подаване:"
+
- #: git-gui.sh:3334
++#: git-gui.sh:3359
+msgid "Amended Merge Commit Message:"
+msgstr "Поправено съобщение при подаване със сливане:"
+
- #: git-gui.sh:3335
++#: git-gui.sh:3360
+msgid "Merge Commit Message:"
+msgstr "Съобщение при подаване със сливане:"
+
- #: git-gui.sh:3384 git-gui.sh:3538 lib/console.tcl:73
++#: git-gui.sh:3361
+msgid "Commit Message:"
+msgstr "Съобщение при подаване:"
+
- #: git-gui.sh:3408 lib/blame.tcl:105
++#: git-gui.sh:3415 git-gui.sh:3570 lib/console.tcl:73
+msgid "Copy All"
+msgstr "Копиране на всичко"
+
- #: git-gui.sh:3526
++#: git-gui.sh:3439 lib/blame.tcl:105
+msgid "File:"
+msgstr "Файл:"
+
- #: git-gui.sh:3547
++#: git-gui.sh:3558
+msgid "Refresh"
+msgstr "Обновяване"
+
- #: git-gui.sh:3551
++#: git-gui.sh:3579
+msgid "Decrease Font Size"
+msgstr "По-едър шрифт"
+
- #: git-gui.sh:3559 lib/blame.tcl:294
++#: git-gui.sh:3583
+msgid "Increase Font Size"
+msgstr "По-дребен шрифт"
+
- #: git-gui.sh:3570
++#: git-gui.sh:3591 lib/blame.tcl:294
+msgid "Encoding"
+msgstr "Кодиране"
+
- #: git-gui.sh:3575
++#: git-gui.sh:3602
+msgid "Apply/Reverse Hunk"
+msgstr "Прилагане/връщане на парче"
+
- #: git-gui.sh:3594
++#: git-gui.sh:3607
+msgid "Apply/Reverse Line"
+msgstr "Прилагане/връщане на ред"
+
- #: git-gui.sh:3599
++#: git-gui.sh:3626
+msgid "Run Merge Tool"
+msgstr "Изпълнение на програмата за сливане"
+
- #: git-gui.sh:3603
++#: git-gui.sh:3631
+msgid "Use Remote Version"
+msgstr "Версия от отдалеченото хранилище"
+
- #: git-gui.sh:3607
++#: git-gui.sh:3635
+msgid "Use Local Version"
+msgstr "Локална версия"
+
- #: git-gui.sh:3625
++#: git-gui.sh:3639
+msgid "Revert To Base"
+msgstr "Връщане към родителската версия"
+
- #: git-gui.sh:3629
++#: git-gui.sh:3657
+msgid "Visualize These Changes In The Submodule"
+msgstr "Визуализиране на промените в подмодула"
+
- #: git-gui.sh:3633
++#: git-gui.sh:3661
+msgid "Visualize Current Branch History In The Submodule"
+msgstr "Визуализация на историята на текущия клон в историята за подмодула"
+
- #: git-gui.sh:3638
++#: git-gui.sh:3665
+msgid "Visualize All Branch History In The Submodule"
+msgstr "Визуализация на историята на всички клони в историята за подмодула"
+
- #: git-gui.sh:3673
++#: git-gui.sh:3670
+msgid "Start git gui In The Submodule"
+msgstr "Стартиране на „git gui“ за подмодула"
+
- #: git-gui.sh:3675
++#: git-gui.sh:3705
+msgid "Unstage Hunk From Commit"
+msgstr "Изваждане на парчето от подаването"
+
- #: git-gui.sh:3677
++#: git-gui.sh:3707
+msgid "Unstage Lines From Commit"
+msgstr "Изваждане на редовете от подаването"
+
- #: git-gui.sh:3680
++#: git-gui.sh:3709
+msgid "Unstage Line From Commit"
+msgstr "Изваждане на реда от подаването"
+
- #: git-gui.sh:3682
++#: git-gui.sh:3712
+msgid "Stage Hunk For Commit"
+msgstr "Добавяне на парчето за подаване"
+
- #: git-gui.sh:3684
++#: git-gui.sh:3714
+msgid "Stage Lines For Commit"
+msgstr "Добавяне на редовете за подаване"
+
- #: git-gui.sh:3709
++#: git-gui.sh:3716
+msgid "Stage Line For Commit"
+msgstr "Добавяне на реда за подаване"
+
- #: git-gui.sh:3852
++#: git-gui.sh:3741
+msgid "Initializing..."
+msgstr "Инициализиране…"
+
- #: git-gui.sh:3881
++#: git-gui.sh:3886
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
+msgstr ""
+"Възможно е да има проблем със средата.\n"
+"\n"
+"Най-вероятно следните променливи няма да бъдат\n"
+"взети под внимание от подпроцесите на Git\n"
+"от %s:\n"
+"\n"
+
- #: git-gui.sh:3886
++#: git-gui.sh:3915
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
+msgstr ""
+"\n"
+"Това е познат проблем и се дължи на\n"
+"версията на Tcl включена в Cygwin."
+
- #: lib/spellcheck.tcl:57
- msgid "Unsupported spell checker"
- msgstr "Тази програма за проверка на правописа не се поддържа"
-
- #: lib/spellcheck.tcl:65
- msgid "Spell checking is unavailable"
- msgstr "Липсва програма за проверка на правописа"
-
- #: lib/spellcheck.tcl:68
- msgid "Invalid spell checking configuration"
- msgstr "Неправилни настройки на проверката на правописа"
++#: git-gui.sh:3920
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
+msgstr ""
+"\n"
+"\n"
+"Добър заместител на „%s“\n"
+"е да поставите настройките „user.name“ и\n"
+"„user.email“ в личния си файл „~/.gitconfig“.\n"
+
- #: lib/spellcheck.tcl:70
++#: lib/about.tcl:26
++msgid "git-gui - a graphical user interface for Git."
++msgstr "git-gui — графичен интерфейс за Git."
+
- msgid "Reverting dictionary to %s."
- msgstr "Ползване на речник за език „%s“."
-
- #: lib/spellcheck.tcl:73
- msgid "Spell checker silently failed on startup"
- msgstr "Програмата за правопис даже не стартира успешно."
-
- #: lib/spellcheck.tcl:80
- msgid "Unrecognized spell checker"
- msgstr "Непозната програма за проверка на правописа"
-
- #: lib/spellcheck.tcl:186
- msgid "No Suggestions"
- msgstr "Няма предложения"
-
- #: lib/spellcheck.tcl:388
- msgid "Unexpected EOF from spell checker"
- msgstr "Неочакван край на файл от програмата за проверка на правописа"
-
- #: lib/spellcheck.tcl:392
- msgid "Spell Checker Failed"
- msgstr "Грешка в програмата за проверка на правописа"
-
- #: lib/remote_add.tcl:20
- msgid "Add Remote"
- msgstr "Добавяне на отдалечено хранилище"
-
- #: lib/remote_add.tcl:25
- msgid "Add New Remote"
- msgstr "Добавяне на отдалечено хранилище"
-
- #: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37
- msgid "Add"
- msgstr "Добавяне"
-
- #: lib/remote_add.tcl:34 lib/browser.tcl:292 lib/branch_checkout.tcl:30
- #: lib/transport.tcl:141 lib/branch_rename.tcl:32 lib/choose_font.tcl:45
- #: lib/option.tcl:127 lib/tools_dlg.tcl:41 lib/tools_dlg.tcl:202
- #: lib/tools_dlg.tcl:345 lib/remote_branch_delete.tcl:43
- #: lib/checkout_op.tcl:579 lib/branch_create.tcl:37 lib/branch_delete.tcl:34
- #: lib/merge.tcl:174
- msgid "Cancel"
- msgstr "Отказване"
-
- #: lib/remote_add.tcl:39
- msgid "Remote Details"
- msgstr "Данни за отдалеченото хранилище"
-
- #: lib/remote_add.tcl:41 lib/tools_dlg.tcl:51 lib/branch_create.tcl:44
- msgid "Name:"
- msgstr "Име:"
++#: lib/blame.tcl:73
+#, tcl-format
- #: lib/remote_add.tcl:50
- msgid "Location:"
- msgstr "Местоположение:"
++msgid "%s (%s): File Viewer"
++msgstr "%s (%s): Преглед на файлове"
+
- #: lib/remote_add.tcl:60
- msgid "Further Action"
- msgstr "Следващо действие"
++#: lib/blame.tcl:79
++msgid "Commit:"
++msgstr "Подаване:"
+
- #: lib/remote_add.tcl:63
- msgid "Fetch Immediately"
- msgstr "Незабавно доставяне"
++#: lib/blame.tcl:280
++msgid "Copy Commit"
++msgstr "Копиране на подаване"
+
- #: lib/remote_add.tcl:69
- msgid "Initialize Remote Repository and Push"
- msgstr "Инициализиране на отдалеченото хранилище и изтласкване на промените"
++#: lib/blame.tcl:284
++msgid "Find Text..."
++msgstr "Търсене на текст…"
+
- #: lib/remote_add.tcl:75
- msgid "Do Nothing Else Now"
- msgstr "Да не се прави нищо"
++#: lib/blame.tcl:288
++msgid "Goto Line..."
++msgstr "Към ред…"
+
- #: lib/remote_add.tcl:100
- msgid "Please supply a remote name."
- msgstr "Задайте име за отдалеченото хранилище."
++#: lib/blame.tcl:297
++msgid "Do Full Copy Detection"
++msgstr "Пълно търсене на копиране"
+
- #: lib/remote_add.tcl:113
- #, tcl-format
- msgid "'%s' is not an acceptable remote name."
- msgstr "Отдалечено хранилище не може да се казва „%s“."
++#: lib/blame.tcl:301
++msgid "Show History Context"
++msgstr "Показване на контекста от историята"
+
- #: lib/remote_add.tcl:124
++#: lib/blame.tcl:304
++msgid "Blame Parent Commit"
++msgstr "Анотиране на родителското подаване"
+
- msgid "Failed to add remote '%s' of location '%s'."
- msgstr "Неуспешно добавяне на отдалеченото хранилище „%s“ от адрес „%s“."
++#: lib/blame.tcl:466
+#, tcl-format
- #: lib/remote_add.tcl:132 lib/transport.tcl:6
- #, tcl-format
- msgid "fetch %s"
- msgstr "доставяне на „%s“"
++msgid "Reading %s..."
++msgstr "Чете се „%s“…"
+
- #: lib/remote_add.tcl:133
- #, tcl-format
- msgid "Fetching the %s"
- msgstr "Доставяне на „%s“"
++#: lib/blame.tcl:594
++msgid "Loading copy/move tracking annotations..."
++msgstr "Зареждане на анотациите за проследяване на копирането/преместването…"
+
- #: lib/remote_add.tcl:156
- #, tcl-format
- msgid "Do not know how to initialize repository at location '%s'."
- msgstr "Хранилището с местоположение „%s“ не може да бъде инициализирано."
++#: lib/blame.tcl:614
++msgid "lines annotated"
++msgstr "реда анотирани"
+
- #: lib/remote_add.tcl:162 lib/transport.tcl:54 lib/transport.tcl:92
- #: lib/transport.tcl:110
- #, tcl-format
- msgid "push %s"
- msgstr "изтласкване на „%s“"
++#: lib/blame.tcl:806
++msgid "Loading original location annotations..."
++msgstr "Зареждане на анотациите за първоначалното местоположение…"
+
- #: lib/remote_add.tcl:163
- #, tcl-format
- msgid "Setting up the %s (at %s)"
- msgstr "Добавяне на хранилище „%s“ (с адрес „%s“)"
++#: lib/blame.tcl:809
++msgid "Annotation complete."
++msgstr "Анотирането завърши."
+
- #: lib/browser.tcl:17
- msgid "Starting..."
- msgstr "Стартиране…"
++#: lib/blame.tcl:839
++msgid "Busy"
++msgstr "Операцията не е завършила"
+
- #: lib/browser.tcl:27
- msgid "File Browser"
- msgstr "Файлов браузър"
++#: lib/blame.tcl:840
++msgid "Annotation process is already running."
++msgstr "В момента тече процес на анотиране."
+
- #: lib/browser.tcl:132 lib/browser.tcl:149
- #, tcl-format
- msgid "Loading %s..."
- msgstr "Зареждане на „%s“…"
++#: lib/blame.tcl:879
++msgid "Running thorough copy detection..."
++msgstr "Изпълнява се цялостен процес на откриване на копиране…"
+
- #: lib/browser.tcl:193
- msgid "[Up To Parent]"
- msgstr "[Към родителя]"
++#: lib/blame.tcl:947
++msgid "Loading annotation..."
++msgstr "Зареждане на анотации…"
+
- #: lib/browser.tcl:275 lib/browser.tcl:282
- msgid "Browse Branch Files"
- msgstr "Разглеждане на файловете в клона"
++#: lib/blame.tcl:1000
++msgid "Author:"
++msgstr "Автор:"
+
- #: lib/browser.tcl:288 lib/choose_repository.tcl:422
- #: lib/choose_repository.tcl:509 lib/choose_repository.tcl:518
- #: lib/choose_repository.tcl:1074
- msgid "Browse"
- msgstr "Разглеждане"
++#: lib/blame.tcl:1004
++msgid "Committer:"
++msgstr "Подал:"
+
- #: lib/browser.tcl:297 lib/branch_checkout.tcl:35 lib/tools_dlg.tcl:321
- msgid "Revision"
- msgstr "Версия"
++#: lib/blame.tcl:1009
++msgid "Original File:"
++msgstr "Първоначален файл:"
+
- #: lib/tools.tcl:75
- #, tcl-format
- msgid "Running %s requires a selected file."
- msgstr "За изпълнението на „%s“ трябва да изберете файл."
++#: lib/blame.tcl:1057
++msgid "Cannot find HEAD commit:"
++msgstr "Подаването за връх „HEAD“ не може да се открие:"
+
- #: lib/tools.tcl:91
- #, tcl-format
- msgid "Are you sure you want to run %1$s on file \"%2$s\"?"
- msgstr "Сигурни ли сте, че искате да изпълните „%1$s“ върху файла „%2$s“?"
++#: lib/blame.tcl:1112
++msgid "Cannot find parent commit:"
++msgstr "Родителското подаване не може да бъде открито"
+
- #: lib/tools.tcl:95
- #, tcl-format
- msgid "Are you sure you want to run %s?"
- msgstr "Сигурни ли сте, че искате да изпълните „%s“?"
++#: lib/blame.tcl:1127
++msgid "Unable to display parent"
++msgstr "Родителят не може да бъде показан"
+
- #: lib/tools.tcl:116
- #, tcl-format
- msgid "Tool: %s"
- msgstr "Команда: %s"
++#: lib/blame.tcl:1128 lib/diff.tcl:358
++msgid "Error loading diff:"
++msgstr "Грешка при зареждане на разлика:"
+
- #: lib/tools.tcl:117
- #, tcl-format
- msgid "Running: %s"
- msgstr "Изпълнение: %s"
++#: lib/blame.tcl:1269
++msgid "Originally By:"
++msgstr "Първоначално от:"
+
- #: lib/tools.tcl:155
- #, tcl-format
- msgid "Tool completed successfully: %s"
- msgstr "Командата завърши успешно: %s"
++#: lib/blame.tcl:1275
++msgid "In File:"
++msgstr "Във файл:"
+
- #: lib/tools.tcl:157
++#: lib/blame.tcl:1280
++msgid "Copied Or Moved Here By:"
++msgstr "Копирано или преместено тук от:"
+
- msgid "Tool failed: %s"
- msgstr "Командата върна грешка: %s"
++#: lib/branch_checkout.tcl:16
+#, tcl-format
- #: lib/branch_checkout.tcl:16 lib/branch_checkout.tcl:21
++msgid "%s (%s): Checkout Branch"
++msgstr "%s (%s): Клон за изтегляне"
+
- #: lib/branch_checkout.tcl:39 lib/option.tcl:310 lib/branch_create.tcl:69
++#: lib/branch_checkout.tcl:21
+msgid "Checkout Branch"
+msgstr "Клон за изтегляне"
+
+#: lib/branch_checkout.tcl:26
+msgid "Checkout"
+msgstr "Изтегляне"
+
- #: lib/transport.tcl:7
++#: lib/branch_checkout.tcl:30 lib/branch_create.tcl:37 lib/branch_delete.tcl:34
++#: lib/branch_rename.tcl:32 lib/browser.tcl:292 lib/checkout_op.tcl:579
++#: lib/choose_font.tcl:45 lib/merge.tcl:178 lib/option.tcl:127
++#: lib/remote_add.tcl:34 lib/remote_branch_delete.tcl:43 lib/tools_dlg.tcl:41
++#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/transport.tcl:141
++msgid "Cancel"
++msgstr "Отказване"
++
++#: lib/branch_checkout.tcl:35 lib/browser.tcl:297 lib/tools_dlg.tcl:321
++msgid "Revision"
++msgstr "Версия"
++
++#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:69 lib/option.tcl:310
+msgid "Options"
+msgstr "Опции"
+
+#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
+msgstr "Изтегляне на промените от следения клон"
+
+#: lib/branch_checkout.tcl:47
+msgid "Detach From Local Branch"
+msgstr "Изтриване от локалния клон"
+
- msgid "Fetching new changes from %s"
- msgstr "Доставяне на промените от „%s“"
++#: lib/branch_create.tcl:23
+#, tcl-format
- #: lib/transport.tcl:18
- #, tcl-format
- msgid "remote prune %s"
- msgstr "окастряне на следящите клони към „%s“"
-
- #: lib/transport.tcl:19
- #, tcl-format
- msgid "Pruning tracking branches deleted from %s"
- msgstr "Окастряне на следящите клони на изтритите клони от „%s“"
-
- #: lib/transport.tcl:25
- msgid "fetch all remotes"
- msgstr "доставяне на всички отдалечени хранилища"
-
- #: lib/transport.tcl:26
- msgid "Fetching new changes from all remotes"
- msgstr "Доставяне на новите промени от всички отдалечени хранилища"
-
- #: lib/transport.tcl:40
- msgid "remote prune all remotes"
- msgstr "окастряне на всички следящи клони"
++msgid "%s (%s): Create Branch"
++msgstr "%s (%s): Създаване на клон"
+
- #: lib/transport.tcl:41
- msgid "Pruning tracking branches deleted from all remotes"
- msgstr ""
- "Окастряне на всички клони, които следят изтрити клони от отдалечени хранилища"
++#: lib/branch_create.tcl:28
++msgid "Create New Branch"
++msgstr "Създаване на нов клон"
+
- #: lib/transport.tcl:55
- #, tcl-format
- msgid "Pushing changes to %s"
- msgstr "Изтласкване на промените към „%s“"
++#: lib/branch_create.tcl:33 lib/choose_repository.tcl:407
++msgid "Create"
++msgstr "Създаване"
+
- #: lib/transport.tcl:93
- #, tcl-format
- msgid "Mirroring to %s"
- msgstr "Изтласкване на всичко към „%s“"
++#: lib/branch_create.tcl:42
++msgid "Branch Name"
++msgstr "Име на клона"
+
- #: lib/transport.tcl:111
- #, tcl-format
- msgid "Pushing %s %s to %s"
- msgstr "Изтласкване на %s „%s“ към „%s“"
++#: lib/branch_create.tcl:44 lib/remote_add.tcl:41 lib/tools_dlg.tcl:51
++msgid "Name:"
++msgstr "Име:"
+
- #: lib/transport.tcl:132
- msgid "Push Branches"
- msgstr "Клони за изтласкване"
++#: lib/branch_create.tcl:57
++msgid "Match Tracking Branch Name"
++msgstr "Съвпадане по името на следения клон"
+
- #: lib/transport.tcl:147
- msgid "Source Branches"
- msgstr "Клони-източници"
++#: lib/branch_create.tcl:66
++msgid "Starting Revision"
++msgstr "Начална версия"
+
- #: lib/transport.tcl:162
- msgid "Destination Repository"
- msgstr "Целево хранилище"
++#: lib/branch_create.tcl:72
++msgid "Update Existing Branch:"
++msgstr "Обновяване на съществуващ клон:"
+
- #: lib/transport.tcl:165 lib/remote_branch_delete.tcl:51
- msgid "Remote:"
- msgstr "Отдалечено хранилище:"
++#: lib/branch_create.tcl:75
++msgid "No"
++msgstr "Не"
+
- #: lib/transport.tcl:187 lib/remote_branch_delete.tcl:72
- msgid "Arbitrary Location:"
- msgstr "Произволно местоположение:"
++#: lib/branch_create.tcl:80
++msgid "Fast Forward Only"
++msgstr "Само тривиално превъртащо сливане"
+
- #: lib/transport.tcl:205
- msgid "Transfer Options"
- msgstr "Настройки при пренасянето"
++#: lib/branch_create.tcl:85 lib/checkout_op.tcl:571
++msgid "Reset"
++msgstr "Отначало"
+
- #: lib/transport.tcl:207
- msgid "Force overwrite existing branch (may discard changes)"
- msgstr ""
- "Изрично презаписване на съществуващ клон (някои промени може да бъдат "
- "загубени)"
++#: lib/branch_create.tcl:97
++msgid "Checkout After Creation"
++msgstr "Преминаване към клона след създаването му"
+
- #: lib/transport.tcl:211
- msgid "Use thin pack (for slow network connections)"
- msgstr "Максимална компресия (за бавни мрежови връзки)"
++#: lib/branch_create.tcl:132
++msgid "Please select a tracking branch."
++msgstr "Изберете клон за следени."
+
- #: lib/transport.tcl:215
- msgid "Include tags"
- msgstr "Включване на етикетите"
++#: lib/branch_create.tcl:141
++#, tcl-format
++msgid "Tracking branch %s is not a branch in the remote repository."
++msgstr "Следящият клон — „%s“, не съществува в отдалеченото хранилище."
+
- #: lib/status_bar.tcl:87
++#: lib/branch_create.tcl:154 lib/branch_rename.tcl:92
++msgid "Please supply a branch name."
++msgstr "Дайте име на клона."
+
- msgid "%s ... %*i of %*i %s (%3i%%)"
- msgstr "%s… %*i от общо %*i %s (%3i%%)"
++#: lib/branch_create.tcl:165 lib/branch_rename.tcl:112
+#, tcl-format
- #: lib/remote.tcl:200
- msgid "Push to"
- msgstr "Изтласкване към"
++msgid "'%s' is not an acceptable branch name."
++msgstr "„%s“ не може да се използва за име на клон."
+
- #: lib/remote.tcl:218
- msgid "Remove Remote"
- msgstr "Премахване на отдалечено хранилище"
++#: lib/branch_delete.tcl:16
++#, tcl-format
++msgid "%s (%s): Delete Branch"
++msgstr "%s (%s): Изтриване на клон"
+
- #: lib/remote.tcl:223
- msgid "Prune from"
- msgstr "Окастряне от"
++#: lib/branch_delete.tcl:21
++msgid "Delete Local Branch"
++msgstr "Изтриване на локален клон"
+
- #: lib/remote.tcl:228
- msgid "Fetch from"
- msgstr "Доставяне от"
++#: lib/branch_delete.tcl:39
++msgid "Local Branches"
++msgstr "Локални клони"
+
- #: lib/sshkey.tcl:31
- msgid "No keys found."
- msgstr "Не са открити ключове."
++#: lib/branch_delete.tcl:51
++msgid "Delete Only If Merged Into"
++msgstr "Изтриване, само ако промените са слети и другаде"
+
- #: lib/sshkey.tcl:34
++#: lib/branch_delete.tcl:53 lib/remote_branch_delete.tcl:120
++msgid "Always (Do not perform merge checks)"
++msgstr "Винаги (без проверка за сливане)"
+
- msgid "Found a public key in: %s"
- msgstr "Открит е публичен ключ в „%s“"
-
- #: lib/sshkey.tcl:40
- msgid "Generate Key"
- msgstr "Генериране на ключ"
-
- #: lib/sshkey.tcl:55 lib/checkout_op.tcl:146 lib/console.tcl:81
- #: lib/database.tcl:30
- msgid "Close"
- msgstr "Затваряне"
-
- #: lib/sshkey.tcl:58
- msgid "Copy To Clipboard"
- msgstr "Копиране към системния буфер"
++#: lib/branch_delete.tcl:103
+#, tcl-format
- #: lib/sshkey.tcl:72
- msgid "Your OpenSSH Public Key"
- msgstr "Публичният ви ключ за OpenSSH"
++msgid "The following branches are not completely merged into %s:"
++msgstr "Не всички промени в клоните са слети в „%s“:"
+
- #: lib/sshkey.tcl:80
- msgid "Generating..."
- msgstr "Генериране…"
++#: lib/branch_delete.tcl:115 lib/remote_branch_delete.tcl:218
++msgid ""
++"Recovering deleted branches is difficult.\n"
++"\n"
++"Delete the selected branches?"
++msgstr ""
++"Възстановяването на изтрити клони може да е трудно.\n"
++"\n"
++"Сигурни ли сте, че искате да триете?"
+
- #: lib/sshkey.tcl:86
++#: lib/branch_delete.tcl:131
++#, tcl-format
++msgid " - %s:"
++msgstr " — „%s:“"
+
- "Could not start ssh-keygen:\n"
- "\n"
++#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
- "Програмата „ssh-keygen“ не може да бъде стартирана:\n"
- "\n"
++"Failed to delete branches:\n"
+"%s"
+msgstr ""
- #: lib/sshkey.tcl:113
- msgid "Generation failed."
- msgstr "Неуспешно генериране."
-
- #: lib/sshkey.tcl:120
- msgid "Generation succeeded, but no keys found."
- msgstr "Генерирането завърши успешно, а не са намерени ключове."
-
- #: lib/sshkey.tcl:123
++"Неуспешно триене на клони:\n"
+"%s"
+
- msgid "Your key is in: %s"
- msgstr "Ключът ви е в „%s“"
++#: lib/branch_rename.tcl:15
+#, tcl-format
- #: lib/branch_rename.tcl:15 lib/branch_rename.tcl:23
++msgid "%s (%s): Rename Branch"
++msgstr "%s (%s): Преименуване на клон"
+
- #: lib/branch_rename.tcl:92 lib/branch_create.tcl:154
- msgid "Please supply a branch name."
- msgstr "Дайте име на клона."
-
++#: lib/branch_rename.tcl:23
+msgid "Rename Branch"
+msgstr "Преименуване на клон"
+
+#: lib/branch_rename.tcl:28
+msgid "Rename"
+msgstr "Преименуване"
+
+#: lib/branch_rename.tcl:38
+msgid "Branch:"
+msgstr "Клон:"
+
+#: lib/branch_rename.tcl:46
+msgid "New Name:"
+msgstr "Ново име:"
+
+#: lib/branch_rename.tcl:81
+msgid "Please select a branch to rename."
+msgstr "Изберете клон за преименуване."
+
- #: lib/branch_rename.tcl:112 lib/branch_create.tcl:165
- #, tcl-format
- msgid "'%s' is not an acceptable branch name."
- msgstr "„%s“ не може да се използва за име на клон."
-
+#: lib/branch_rename.tcl:102 lib/checkout_op.tcl:202
+#, tcl-format
+msgid "Branch '%s' already exists."
+msgstr "Клонът „%s“ вече съществува."
+
- #: lib/choose_font.tcl:41
- msgid "Select"
- msgstr "Избор"
-
- #: lib/choose_font.tcl:55
- msgid "Font Family"
- msgstr "Шрифт"
+#: lib/branch_rename.tcl:123
+#, tcl-format
+msgid "Failed to rename '%s'."
+msgstr "Неуспешно преименуване на „%s“."
+
- #: lib/choose_font.tcl:76
- msgid "Font Size"
- msgstr "Размер"
++#: lib/browser.tcl:17
++msgid "Starting..."
++msgstr "Стартиране…"
+
- #: lib/choose_font.tcl:93
- msgid "Font Example"
- msgstr "Мостра"
++#: lib/browser.tcl:27
++#, tcl-format
++msgid "%s (%s): File Browser"
++msgstr "%s (%s): Файлов браузър"
+
- #: lib/choose_font.tcl:105
- msgid ""
- "This is example text.\n"
- "If you like this text, it can be your font."
- msgstr ""
- "Това е примерен текст.\n"
- "Ако ви харесва как изглежда, изберете шрифта."
++#: lib/browser.tcl:132 lib/browser.tcl:149
++#, tcl-format
++msgid "Loading %s..."
++msgstr "Зареждане на „%s“…"
+
- #: lib/option.tcl:11
++#: lib/browser.tcl:193
++msgid "[Up To Parent]"
++msgstr "[Към родителя]"
+
- msgid "Invalid global encoding '%s'"
- msgstr "Неправилно глобално кодиране „%s“"
++#: lib/browser.tcl:275
+#, tcl-format
- #: lib/option.tcl:19
- #, tcl-format
- msgid "Invalid repo encoding '%s'"
- msgstr "Неправилно кодиране „%s“ на хранилището"
++msgid "%s (%s): Browse Branch Files"
++msgstr "%s (%s): Разглеждане на файловете в клона"
+
- #: lib/option.tcl:119
- msgid "Restore Defaults"
- msgstr "Стандартни настройки"
++#: lib/browser.tcl:282
++msgid "Browse Branch Files"
++msgstr "Разглеждане на файловете в клона"
+
- #: lib/option.tcl:123
- msgid "Save"
- msgstr "Запазване"
++#: lib/browser.tcl:288 lib/choose_repository.tcl:422
++#: lib/choose_repository.tcl:509 lib/choose_repository.tcl:518
++#: lib/choose_repository.tcl:1074
++msgid "Browse"
++msgstr "Разглеждане"
+
- #: lib/option.tcl:133
++#: lib/checkout_op.tcl:85
++#, tcl-format
++msgid "Fetching %s from %s"
++msgstr "Доставяне на „%s“ от „%s“"
+
- msgid "%s Repository"
- msgstr "Хранилище „%s“"
++#: lib/checkout_op.tcl:133
+#, tcl-format
- #: lib/option.tcl:134
- msgid "Global (All Repositories)"
- msgstr "Глобално (за всички хранилища)"
++msgid "fatal: Cannot resolve %s"
++msgstr "фатална грешка: „%s“ не може да се открие"
+
- #: lib/option.tcl:140
- msgid "User Name"
- msgstr "Потребителско име"
++#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:30
++#: lib/sshkey.tcl:55
++msgid "Close"
++msgstr "Затваряне"
+
- #: lib/option.tcl:141
- msgid "Email Address"
- msgstr "Адрес на е-поща"
++#: lib/checkout_op.tcl:175
++#, tcl-format
++msgid "Branch '%s' does not exist."
++msgstr "Клонът „%s“ не съществува."
+
- #: lib/option.tcl:143
- msgid "Summarize Merge Commits"
- msgstr "Обобщаване на подаванията при сливане"
++#: lib/checkout_op.tcl:194
++#, tcl-format
++msgid "Failed to configure simplified git-pull for '%s'."
++msgstr "Неуспешно настройване на опростен git-pull за „%s“."
+
- #: lib/option.tcl:144
- msgid "Merge Verbosity"
- msgstr "Подробности при сливанията"
++#: lib/checkout_op.tcl:229
++#, tcl-format
++msgid ""
++"Branch '%s' already exists.\n"
++"\n"
++"It cannot fast-forward to %s.\n"
++"A merge is required."
++msgstr ""
++"Клонът „%s“ съществува.\n"
++"\n"
++"Той не може да бъде тривиално слят до „%s“.\n"
++"Необходимо е сливане."
+
- #: lib/option.tcl:145
- msgid "Show Diffstat After Merge"
- msgstr "Извеждане на статистика след сливанията"
++#: lib/checkout_op.tcl:243
++#, tcl-format
++msgid "Merge strategy '%s' not supported."
++msgstr "Стратегия за сливане „%s“ не се поддържа."
+
- #: lib/option.tcl:146
- msgid "Use Merge Tool"
- msgstr "Използване на програма за сливане"
++#: lib/checkout_op.tcl:262
++#, tcl-format
++msgid "Failed to update '%s'."
++msgstr "Неуспешно обновяване на „%s“."
+
- #: lib/option.tcl:148
- msgid "Trust File Modification Timestamps"
- msgstr "Доверие във времето на промяна на файловете"
++#: lib/checkout_op.tcl:274
++msgid "Staging area (index) is already locked."
++msgstr "Индексът вече е заключен."
+
- #: lib/option.tcl:149
- msgid "Prune Tracking Branches During Fetch"
- msgstr "Окастряне на следящите клонове при доставяне"
++#: lib/checkout_op.tcl:289
++msgid ""
++"Last scanned state does not match repository state.\n"
++"\n"
++"Another Git program has modified this repository since the last scan. A "
++"rescan must be performed before the current branch can be changed.\n"
++"\n"
++"The rescan will be automatically started now.\n"
++msgstr ""
++"Състоянието при последната проверка не отговаря на състоянието на "
++"хранилището.\n"
++"\n"
++"Някой друг процес за Git е променил хранилището междувременно. Състоянието "
++"трябва да бъде проверено, преди да се премине към нов клон.\n"
++"\n"
++"Автоматично ще започне нова проверка.\n"
+
- #: lib/option.tcl:150
- msgid "Match Tracking Branches"
- msgstr "Напасване на следящите клонове"
++#: lib/checkout_op.tcl:345
++#, tcl-format
++msgid "Updating working directory to '%s'..."
++msgstr "Работната директория се привежда към „%s“…"
+
- #: lib/option.tcl:151
- msgid "Use Textconv For Diffs and Blames"
++#: lib/checkout_op.tcl:346
++msgid "files checked out"
++msgstr "файла са изтеглени"
+
- "Преобразуване на текста с „textconv“ при анотиране и извеждане на разлики"
++#: lib/checkout_op.tcl:376
++#, tcl-format
++msgid "Aborted checkout of '%s' (file level merging is required)."
+msgstr ""
- #: lib/option.tcl:152
- msgid "Blame Copy Only On Changed Files"
- msgstr "Анотиране на копието само по променените файлове"
++"Преустановяване на изтеглянето на „%s“ (необходимо е пофайлово сливане)."
+
- #: lib/option.tcl:153
- msgid "Maximum Length of Recent Repositories List"
- msgstr "Максимална дължина на списъка със скоро ползвани хранилища"
++#: lib/checkout_op.tcl:377
++msgid "File level merge required."
++msgstr "Необходимо е пофайлово сливане."
+
- #: lib/option.tcl:154
- msgid "Minimum Letters To Blame Copy On"
- msgstr "Минимален брой знаци за анотиране на копието"
++#: lib/checkout_op.tcl:381
++#, tcl-format
++msgid "Staying on branch '%s'."
++msgstr "Оставане върху клона „%s“."
+
- #: lib/option.tcl:155
- msgid "Blame History Context Radius (days)"
- msgstr "Исторически обхват за анотиране в дни"
++#: lib/checkout_op.tcl:452
++msgid ""
++"You are no longer on a local branch.\n"
++"\n"
++"If you wanted to be on a branch, create one now starting from 'This Detached "
++"Checkout'."
++msgstr ""
++"Вече не сте на локален клон.\n"
++"\n"
++"Ако искате да сте на клон, създайте базиран на „Това несвързано изтегляне“."
+
- #: lib/option.tcl:156
- msgid "Number of Diff Context Lines"
- msgstr "Брой редове за контекста при извеждане на разликите"
++#: lib/checkout_op.tcl:503 lib/checkout_op.tcl:507
++#, tcl-format
++msgid "Checked out '%s'."
++msgstr "„%s“ е изтеглен."
+
- #: lib/option.tcl:157
- msgid "Additional Diff Parameters"
- msgstr "Допълнителни аргументи към „git diff“"
++#: lib/checkout_op.tcl:535
++#, tcl-format
++msgid "Resetting '%s' to '%s' will lose the following commits:"
++msgstr ""
++"Зануляването на „%s“ към „%s“ ще доведе до загубването на следните подавания:"
+
- #: lib/option.tcl:158
- msgid "Commit Message Text Width"
- msgstr "Широчина на текста на съобщението при подаване"
++#: lib/checkout_op.tcl:557
++msgid "Recovering lost commits may not be easy."
++msgstr "Възстановяването на загубените подавания може да е трудно."
+
- #: lib/option.tcl:159
- msgid "New Branch Name Template"
- msgstr "Шаблон за името на новите клони"
++#: lib/checkout_op.tcl:562
++#, tcl-format
++msgid "Reset '%s'?"
++msgstr "Зануляване на „%s“?"
+
- #: lib/option.tcl:160
- msgid "Default File Contents Encoding"
- msgstr "Стандартно кодиране на файловете"
++#: lib/checkout_op.tcl:567 lib/merge.tcl:170 lib/tools_dlg.tcl:336
++msgid "Visualize"
++msgstr "Визуализация"
+
- #: lib/option.tcl:161
- msgid "Warn before committing to a detached head"
- msgstr "Предупреждаване при подаването при несвързан връх"
++#: lib/checkout_op.tcl:635
++#, tcl-format
++msgid ""
++"Failed to set current branch.\n"
++"\n"
++"This working directory is only partially switched. We successfully updated "
++"your files, but failed to update an internal Git file.\n"
++"\n"
++"This should not have occurred. %s will now close and give up."
++msgstr ""
++"Неуспешно задаване на текущия клон.\n"
++"\n"
++"Работната директория е само частично обновена: файловете са обновени "
++"успешно, но някой от вътрешните, служебни файлове на Git не е бил.\n"
++"\n"
++"Това състояние е аварийно и не трябва да се случва. Програмата „%s“ ще "
++"преустанови работа."
+
- #: lib/option.tcl:162
- msgid "Staging of untracked files"
- msgstr "Вкарване на неследени файлове в индекса"
++#: lib/choose_font.tcl:41
++msgid "Select"
++msgstr "Избор"
+
- #: lib/option.tcl:163
- msgid "Show untracked files"
- msgstr "Показване на неследените файлове"
++#: lib/choose_font.tcl:55
++msgid "Font Family"
++msgstr "Шрифт"
+
- #: lib/option.tcl:164
- msgid "Tab spacing"
- msgstr "Размер на табулацията в интервали"
++#: lib/choose_font.tcl:76
++msgid "Font Size"
++msgstr "Размер"
+
- #: lib/option.tcl:210
- msgid "Change"
- msgstr "Смяна"
++#: lib/choose_font.tcl:93
++msgid "Font Example"
++msgstr "Мостра"
+
- #: lib/option.tcl:254
- msgid "Spelling Dictionary:"
- msgstr "Правописен речник:"
++#: lib/choose_font.tcl:105
++msgid ""
++"This is example text.\n"
++"If you like this text, it can be your font."
++msgstr ""
++"Това е примерен текст.\n"
++"Ако ви харесва как изглежда, изберете шрифта."
++
++#: lib/choose_repository.tcl:33
++msgid "Git Gui"
++msgstr "ГПИ на Git"
++
++#: lib/choose_repository.tcl:92 lib/choose_repository.tcl:412
++msgid "Create New Repository"
++msgstr "Създаване на ново хранилище"
++
++#: lib/choose_repository.tcl:98
++msgid "New..."
++msgstr "Ново…"
++
++#: lib/choose_repository.tcl:105 lib/choose_repository.tcl:496
++msgid "Clone Existing Repository"
++msgstr "Клониране на съществуващо хранилище"
++
++#: lib/choose_repository.tcl:116
++msgid "Clone..."
++msgstr "Клониране…"
++
++#: lib/choose_repository.tcl:123 lib/choose_repository.tcl:1064
++msgid "Open Existing Repository"
++msgstr "Отваряне на съществуващо хранилище"
++
++#: lib/choose_repository.tcl:129
++msgid "Open..."
++msgstr "Отваряне…"
++
++#: lib/choose_repository.tcl:142
++msgid "Recent Repositories"
++msgstr "Скоро ползвани"
++
++#: lib/choose_repository.tcl:148
++msgid "Open Recent Repository:"
++msgstr "Отваряне на хранилище ползвано наскоро:"
++
++#: lib/choose_repository.tcl:316 lib/choose_repository.tcl:323
++#: lib/choose_repository.tcl:330
++#, tcl-format
++msgid "Failed to create repository %s:"
++msgstr "Неуспешно създаване на хранилището „%s“:"
++
++#: lib/choose_repository.tcl:417
++msgid "Directory:"
++msgstr "Директория:"
++
++#: lib/choose_repository.tcl:447 lib/choose_repository.tcl:573
++#: lib/choose_repository.tcl:1098
++msgid "Git Repository"
++msgstr "Хранилище на Git"
++
++#: lib/choose_repository.tcl:472
++#, tcl-format
++msgid "Directory %s already exists."
++msgstr "Вече съществува директория „%s“."
++
++#: lib/choose_repository.tcl:476
++#, tcl-format
++msgid "File %s already exists."
++msgstr "Вече съществува файл „%s“."
++
++#: lib/choose_repository.tcl:491
++msgid "Clone"
++msgstr "Клониране"
++
++#: lib/choose_repository.tcl:504
++msgid "Source Location:"
++msgstr "Адрес на източника:"
++
++#: lib/choose_repository.tcl:513
++msgid "Target Directory:"
++msgstr "Целева директория:"
++
++#: lib/choose_repository.tcl:523
++msgid "Clone Type:"
++msgstr "Вид клониране:"
++
++#: lib/choose_repository.tcl:528
++msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
++msgstr "Стандартно (бързо, частично споделяне на файлове, твърди връзки)"
++
++#: lib/choose_repository.tcl:533
++msgid "Full Copy (Slower, Redundant Backup)"
++msgstr "Пълно (бавно, пълноценно резервно копие)"
++
++#: lib/choose_repository.tcl:538
++msgid "Shared (Fastest, Not Recommended, No Backup)"
++msgstr "Споделено (най-бързо, не се препоръчва, не прави резервно копие)"
++
++#: lib/choose_repository.tcl:545
++msgid "Recursively clone submodules too"
++msgstr "Рекурсивно клониране и на подмодулите"
++
++#: lib/choose_repository.tcl:579 lib/choose_repository.tcl:626
++#: lib/choose_repository.tcl:772 lib/choose_repository.tcl:842
++#: lib/choose_repository.tcl:1104 lib/choose_repository.tcl:1112
++#, tcl-format
++msgid "Not a Git repository: %s"
++msgstr "Това не е хранилище на Git: %s"
++
++#: lib/choose_repository.tcl:615
++msgid "Standard only available for local repository."
++msgstr "Само локални хранилища могат да се клонират стандартно"
++
++#: lib/choose_repository.tcl:619
++msgid "Shared only available for local repository."
++msgstr "Само локални хранилища могат да се клонират споделено"
++
++#: lib/choose_repository.tcl:640
++#, tcl-format
++msgid "Location %s already exists."
++msgstr "Местоположението „%s“ вече съществува."
++
++#: lib/choose_repository.tcl:651
++msgid "Failed to configure origin"
++msgstr "Неуспешно настройване на хранилището-източник"
++
++#: lib/choose_repository.tcl:663
++msgid "Counting objects"
++msgstr "Преброяване на обекти"
++
++#: lib/choose_repository.tcl:664
++msgid "buckets"
++msgstr "клетки"
++
++#: lib/choose_repository.tcl:688
++#, tcl-format
++msgid "Unable to copy objects/info/alternates: %s"
++msgstr "Обектите/информацията/синонимите не могат да бъдат копирани: %s"
++
++#: lib/choose_repository.tcl:724
++#, tcl-format
++msgid "Nothing to clone from %s."
++msgstr "Няма какво да се клонира от „%s“."
++
++#: lib/choose_repository.tcl:726 lib/choose_repository.tcl:940
++#: lib/choose_repository.tcl:952
++msgid "The 'master' branch has not been initialized."
++msgstr "Основният клон — „master“ не е инициализиран."
++
++#: lib/choose_repository.tcl:739
++msgid "Hardlinks are unavailable. Falling back to copying."
++msgstr "Не се поддържат твърди връзки. Преминава се към копиране."
++
++#: lib/choose_repository.tcl:751
++#, tcl-format
++msgid "Cloning from %s"
++msgstr "Клониране на „%s“"
++
++#: lib/choose_repository.tcl:782
++msgid "Copying objects"
++msgstr "Копиране на обекти"
++
++#: lib/choose_repository.tcl:783
++msgid "KiB"
++msgstr "KiB"
++
++#: lib/choose_repository.tcl:807
++#, tcl-format
++msgid "Unable to copy object: %s"
++msgstr "Неуспешно копиране на обект: %s"
++
++#: lib/choose_repository.tcl:817
++msgid "Linking objects"
++msgstr "Създаване на връзки към обектите"
++
++#: lib/choose_repository.tcl:818
++msgid "objects"
++msgstr "обекти"
++
++#: lib/choose_repository.tcl:826
++#, tcl-format
++msgid "Unable to hardlink object: %s"
++msgstr "Неуспешно създаване на твърда връзка към обект: %s"
++
++#: lib/choose_repository.tcl:881
++msgid "Cannot fetch branches and objects. See console output for details."
++msgstr ""
++"Клоните и обектите не могат да бъдат изтеглени. За повече информация "
++"погледнете изхода на конзолата."
++
++#: lib/choose_repository.tcl:892
++msgid "Cannot fetch tags. See console output for details."
++msgstr ""
++"Етикетите не могат да бъдат изтеглени. За повече информация погледнете "
++"изхода на конзолата."
++
++#: lib/choose_repository.tcl:916
++msgid "Cannot determine HEAD. See console output for details."
++msgstr ""
++"Върхът „HEAD“ не може да бъде определен. За повече информация погледнете "
++"изхода на конзолата."
++
++#: lib/choose_repository.tcl:925
++#, tcl-format
++msgid "Unable to cleanup %s"
++msgstr "„%s“ не може да се зачисти"
++
++#: lib/choose_repository.tcl:931
++msgid "Clone failed."
++msgstr "Неуспешно клониране."
++
++#: lib/choose_repository.tcl:938
++msgid "No default branch obtained."
++msgstr "Не е получен клон по подразбиране."
++
++#: lib/choose_repository.tcl:949
++#, tcl-format
++msgid "Cannot resolve %s as a commit."
++msgstr "Няма подаване отговарящо на „%s“."
++
++#: lib/choose_repository.tcl:961
++msgid "Creating working directory"
++msgstr "Създаване на работната директория"
++
++#: lib/choose_repository.tcl:962 lib/index.tcl:70 lib/index.tcl:136
++#: lib/index.tcl:207
++msgid "files"
++msgstr "файлове"
++
++#: lib/choose_repository.tcl:981
++msgid "Cannot clone submodules."
++msgstr "Подмодулите не могат да се клонират."
++
++#: lib/choose_repository.tcl:990
++msgid "Cloning submodules"
++msgstr "Клониране на подмодули"
++
++#: lib/choose_repository.tcl:1015
++msgid "Initial file checkout failed."
++msgstr "Неуспешно първоначално изтегляне."
++
++#: lib/choose_repository.tcl:1059
++msgid "Open"
++msgstr "Отваряне"
++
++#: lib/choose_repository.tcl:1069
++msgid "Repository:"
++msgstr "Хранилище:"
++
++#: lib/choose_repository.tcl:1118
++#, tcl-format
++msgid "Failed to open repository %s:"
++msgstr "Неуспешно отваряне на хранилището „%s“:"
++
++#: lib/choose_rev.tcl:52
++msgid "This Detached Checkout"
++msgstr "Това несвързано изтегляне"
++
++#: lib/choose_rev.tcl:60
++msgid "Revision Expression:"
++msgstr "Израз за версия:"
++
++#: lib/choose_rev.tcl:72
++msgid "Local Branch"
++msgstr "Локален клон"
+
- #: lib/option.tcl:284
- msgid "Change Font"
- msgstr "Смяна на шрифта"
++#: lib/choose_rev.tcl:77
++msgid "Tracking Branch"
++msgstr "Следящ клон"
+
- #: lib/option.tcl:288
++#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544
++msgid "Tag"
++msgstr "Етикет"
+
- msgid "Choose %s"
- msgstr "Избор на „%s“"
++#: lib/choose_rev.tcl:321
+#, tcl-format
- #: lib/option.tcl:294
- msgid "pt."
- msgstr "тчк."
++msgid "Invalid revision: %s"
++msgstr "Неправилна версия: %s"
+
- #: lib/option.tcl:308
- msgid "Preferences"
- msgstr "Настройки"
++#: lib/choose_rev.tcl:342
++msgid "No revision selected."
++msgstr "Не е избрана версия."
+
- #: lib/option.tcl:345
- msgid "Failed to completely save options:"
- msgstr "Неуспешно запазване на настройките:"
++#: lib/choose_rev.tcl:350
++msgid "Revision expression is empty."
++msgstr "Изразът за версия е празен."
+
- #: lib/encoding.tcl:443
- msgid "Default"
- msgstr "Стандартното"
++#: lib/choose_rev.tcl:537
++msgid "Updated"
++msgstr "Обновен"
+
- #: lib/encoding.tcl:448
- #, tcl-format
- msgid "System (%s)"
- msgstr "Системното (%s)"
++#: lib/choose_rev.tcl:565
++msgid "URL"
++msgstr "Адрес"
+
- #: lib/encoding.tcl:459 lib/encoding.tcl:465
- msgid "Other"
- msgstr "Друго"
++#: lib/commit.tcl:9
++msgid ""
++"There is nothing to amend.\n"
++"\n"
++"You are about to create the initial commit. There is no commit before this "
++"to amend.\n"
++msgstr ""
++"Няма какво да се поправи.\n"
++"\n"
++"Ще създадете първоначалното подаване. Преди него няма други подавания, които "
++"да поправите.\n"
+
- #: lib/mergetool.tcl:8
- msgid "Force resolution to the base version?"
- msgstr "Да се използва базовата версия"
++#: lib/commit.tcl:18
++msgid ""
++"Cannot amend while merging.\n"
++"\n"
++"You are currently in the middle of a merge that has not been fully "
++"completed. You cannot amend the prior commit unless you first abort the "
++"current merge activity.\n"
++msgstr ""
++"По време на сливане не може да поправяте.\n"
++"\n"
++"В момента все още не сте завършили операция по сливане. Не може да поправите "
++"предишното подаване, освен ако първо не преустановите текущото сливане.\n"
+
- #: lib/mergetool.tcl:9
- msgid "Force resolution to this branch?"
- msgstr "Да се използва версията от този клон"
++#: lib/commit.tcl:48
++msgid "Error loading commit data for amend:"
++msgstr "Грешка при зареждане на данните от подаване, които да се поправят:"
+
- #: lib/mergetool.tcl:10
- msgid "Force resolution to the other branch?"
- msgstr "Да се използва версията от другия клон"
++#: lib/commit.tcl:75
++msgid "Unable to obtain your identity:"
++msgstr "Идентификацията ви не може да бъде определена:"
+
- #: lib/mergetool.tcl:14
++#: lib/commit.tcl:80
++msgid "Invalid GIT_COMMITTER_IDENT:"
++msgstr "Неправилно поле „GIT_COMMITTER_IDENT“:"
+
- "Note that the diff shows only conflicting changes.\n"
++#: lib/commit.tcl:129
+#, tcl-format
++msgid "warning: Tcl does not support encoding '%s'."
++msgstr "предупреждение: Tcl не поддържа кодирането „%s“."
++
++#: lib/commit.tcl:149
+msgid ""
- "%s will be overwritten.\n"
++"Last scanned state does not match repository state.\n"
+"\n"
- "This operation can be undone only by restarting the merge."
++"Another Git program has modified this repository since the last scan. A "
++"rescan must be performed before another commit can be created.\n"
+"\n"
- "Разликата показва само разликите с конфликт.\n"
++"The rescan will be automatically started now.\n"
+msgstr ""
- "Файлът „%s“ ще бъде презаписан.\n"
++"Състоянието при последната проверка не отговаря на състоянието на "
++"хранилището.\n"
+"\n"
- "Тази операция може да бъде отменена само чрез започване на сливането наново."
++"Някой друг процес за Git е променил хранилището междувременно. Състоянието "
++"трябва да бъде проверено преди ново подаване.\n"
+"\n"
- #: lib/mergetool.tcl:45
++"Автоматично ще започне нова проверка.\n"
+
- msgid "File %s seems to have unresolved conflicts, still stage?"
++#: lib/commit.tcl:173
+#, tcl-format
- "Изглежда, че все още има некоригирани конфликти във файла „%s“. Да се добави "
- "ли файлът към индекса?"
++msgid ""
++"Unmerged files cannot be committed.\n"
++"\n"
++"File %s has merge conflicts. You must resolve them and stage the file "
++"before committing.\n"
+msgstr ""
- #: lib/mergetool.tcl:60
++"Неслетите файлове не могат да бъдат подавани.\n"
++"\n"
++"Във файла „%s“ има конфликти при сливане. За да го подадете, трябва първо да "
++"коригирате конфликтите и да добавите файла към индекса за подаване.\n"
+
- msgid "Adding resolution for %s"
- msgstr "Добавяне на корекция на конфликтите в „%s“"
-
- #: lib/mergetool.tcl:141
- msgid "Cannot resolve deletion or link conflicts using a tool"
++#: lib/commit.tcl:181
+#, tcl-format
- "Конфликтите при символни връзки или изтриване не могат да бъдат коригирани с "
- "външна програма."
-
- #: lib/mergetool.tcl:146
- msgid "Conflict file does not exist"
- msgstr "Файлът, в който е конфликтът, не съществува"
-
- #: lib/mergetool.tcl:246
- #, tcl-format
- msgid "Not a GUI merge tool: '%s'"
- msgstr "Това не е графична програма за сливане: „%s“"
-
- #: lib/mergetool.tcl:275
- #, tcl-format
- msgid "Unsupported merge tool '%s'"
- msgstr "Неподдържана програма за сливане: „%s“"
-
- #: lib/mergetool.tcl:310
- msgid "Merge tool is already running, terminate it?"
- msgstr "Програмата за сливане вече е стартирана. Да бъде ли изключена?"
++msgid ""
++"Unknown file state %s detected.\n"
++"\n"
++"File %s cannot be committed by this program.\n"
+msgstr ""
- #: lib/mergetool.tcl:330
- #, tcl-format
++"Непознато състояние на файл „%s“.\n"
++"\n"
++"Файлът „%s“ не може да бъде подаден чрез текущата програма.\n"
+
- "Error retrieving versions:\n"
- "%s"
++#: lib/commit.tcl:189
+msgid ""
- "Грешка при изтеглянето на версии:\n"
- "%s"
++"No changes to commit.\n"
++"\n"
++"You must stage at least 1 file before you can commit.\n"
+msgstr ""
- #: lib/mergetool.tcl:350
- #, tcl-format
++"Няма промени за подаване.\n"
++"\n"
++"Трябва да добавите поне един файл към индекса, за да подадете.\n"
+
- "Could not start the merge tool:\n"
++#: lib/commit.tcl:204
+msgid ""
- "%s"
++"Please supply a commit message.\n"
+"\n"
- "Програмата за сливане не може да бъде стартирана:\n"
++"A good commit message has the following format:\n"
++"\n"
++"- First line: Describe in one sentence what you did.\n"
++"- Second line: Blank\n"
++"- Remaining lines: Describe why this change is good.\n"
+msgstr ""
- "%s"
-
- #: lib/mergetool.tcl:354
- msgid "Running merge tool..."
- msgstr "Стартиране на програмата за сливане…"
++"Задайте добро съобщение при подаване.\n"
+"\n"
- #: lib/mergetool.tcl:382 lib/mergetool.tcl:390
- msgid "Merge tool failed."
- msgstr "Грешка в програмата за сливане."
++"Използвайте следния формат:\n"
++"\n"
++"● Първи ред: описание в едно изречение на промяната.\n"
++"● Втори ред: празен.\n"
++"● Останалите редове: опишете защо се налага тази промяна.\n"
+
- #: lib/tools_dlg.tcl:22
- msgid "Add Tool"
- msgstr "Добавяне на команда"
++#: lib/commit.tcl:235
++msgid "Calling pre-commit hook..."
++msgstr "Изпълняване на куката преди подаване…"
+
- #: lib/tools_dlg.tcl:28
- msgid "Add New Tool Command"
- msgstr "Добавяне на команда"
++#: lib/commit.tcl:250
++msgid "Commit declined by pre-commit hook."
++msgstr "Подаването е отхвърлено от куката преди подаване."
+
- #: lib/tools_dlg.tcl:34
- msgid "Add globally"
- msgstr "Глобално добавяне"
++#: lib/commit.tcl:269
++msgid ""
++"You are about to commit on a detached head. This is a potentially dangerous "
++"thing to do because if you switch to another branch you will lose your "
++"changes and it can be difficult to retrieve them later from the reflog. You "
++"should probably cancel this commit and create a new branch to continue.\n"
++" \n"
++" Do you really want to proceed with your Commit?"
++msgstr ""
++"Ще подадете към несвързан, отделѐн указател „HEAD“. Това е опасно, защото "
++"при преминаването към клон ще загубите промените си, като единственият начин "
++"да ги върнете ще е чрез журнала на указателите (reflog). Най-вероятно трябва "
++"да не правите това подаване, а да създадете нов клон, преди да продължите.\n"
++" \n"
++"Сигурни ли сте, че искате да извършите текущото подаване?"
+
- #: lib/tools_dlg.tcl:46
- msgid "Tool Details"
- msgstr "Подробности за командата"
++#: lib/commit.tcl:290
++msgid "Calling commit-msg hook..."
++msgstr "Изпълняване на куката за съобщението при подаване…"
+
- #: lib/tools_dlg.tcl:49
- msgid "Use '/' separators to create a submenu tree:"
- msgstr "За създаване на подменюта използвайте знака „/“ за разделител:"
++#: lib/commit.tcl:305
++msgid "Commit declined by commit-msg hook."
++msgstr "Подаването е отхвърлено от куката за съобщението при подаване."
+
- #: lib/tools_dlg.tcl:60
- msgid "Command:"
- msgstr "Команда:"
++#: lib/commit.tcl:318
++msgid "Committing changes..."
++msgstr "Подаване на промените…"
+
- #: lib/tools_dlg.tcl:71
- msgid "Show a dialog before running"
- msgstr "Преди изпълнение да се извежда диалогов прозорец"
++#: lib/commit.tcl:334
++msgid "write-tree failed:"
++msgstr "неуспешно запазване на дървото (write-tree):"
+
- #: lib/tools_dlg.tcl:77
- msgid "Ask the user to select a revision (sets $REVISION)"
- msgstr "Потребителят да укаже версия (задаване на променливата $REVISION)"
++#: lib/commit.tcl:335 lib/commit.tcl:382 lib/commit.tcl:403
++msgid "Commit failed."
++msgstr "Неуспешно подаване."
+
- #: lib/tools_dlg.tcl:82
- msgid "Ask the user for additional arguments (sets $ARGS)"
++#: lib/commit.tcl:352
++#, tcl-format
++msgid "Commit %s appears to be corrupt"
++msgstr "Подаването „%s“ изглежда повредено"
+
- "Потребителят да укаже допълнителни аргументи (задаване на променливата $ARGS)"
++#: lib/commit.tcl:357
++msgid ""
++"No changes to commit.\n"
++"\n"
++"No files were modified by this commit and it was not a merge commit.\n"
++"\n"
++"A rescan will be automatically started now.\n"
+msgstr ""
- #: lib/tools_dlg.tcl:89
- msgid "Don't show the command output window"
- msgstr "Без показване на прозорец с изхода от командата"
++"Няма промени за подаване.\n"
++"\n"
++"В това подаване не са променяни никакви файлове, а и не е подаване със "
++"сливане.\n"
++"\n"
++"Автоматично ще започне нова проверка.\n"
+
- #: lib/tools_dlg.tcl:94
- msgid "Run only if a diff is selected ($FILENAME not empty)"
- msgstr ""
- "Стартиране само след избор на разлика (променливата $FILENAME не е празна)"
++#: lib/commit.tcl:364
++msgid "No changes to commit."
++msgstr "Няма промени за подаване."
+
- #: lib/tools_dlg.tcl:118
- msgid "Please supply a name for the tool."
- msgstr "Задайте име за командата."
++#: lib/commit.tcl:381
++msgid "commit-tree failed:"
++msgstr "неуспешно подаване на дървото (commit-tree):"
+
- #: lib/tools_dlg.tcl:126
++#: lib/commit.tcl:402
++msgid "update-ref failed:"
++msgstr "неуспешно обновяване на указателите (update-ref):"
+
- msgid "Tool '%s' already exists."
- msgstr "Командата „%s“ вече съществува."
++#: lib/commit.tcl:495
+#, tcl-format
- #: lib/tools_dlg.tcl:148
- #, tcl-format
- msgid ""
- "Could not add tool:\n"
- "%s"
- msgstr ""
- "Командата не може да бъде добавена:\n"
- "%s"
++msgid "Created commit %s: %s"
++msgstr "Успешно подаване %s: %s"
+
- #: lib/tools_dlg.tcl:187
- msgid "Remove Tool"
- msgstr "Премахване на команда"
++#: lib/console.tcl:59
++msgid "Working... please wait..."
++msgstr "В момента се извършва действие, изчакайте…"
+
- #: lib/tools_dlg.tcl:193
- msgid "Remove Tool Commands"
- msgstr "Премахване на команди"
++#: lib/console.tcl:186
++msgid "Success"
++msgstr "Успех"
+
- #: lib/tools_dlg.tcl:198
- msgid "Remove"
- msgstr "Премахване"
++#: lib/console.tcl:200
++msgid "Error: Command Failed"
++msgstr "Грешка: неуспешно изпълнение на команда"
+
- #: lib/tools_dlg.tcl:231
- msgid "(Blue denotes repository-local tools)"
- msgstr "(командите към локалното хранилище са обозначени в синьо)"
++#: lib/database.tcl:42
++msgid "Number of loose objects"
++msgstr "Брой непакетирани обекти"
+
- #: lib/tools_dlg.tcl:292
- #, tcl-format
- msgid "Run Command: %s"
- msgstr "Изпълнение на командата „%s“"
++#: lib/database.tcl:43
++msgid "Disk space used by loose objects"
++msgstr "Дисково пространство заето от непакетирани обекти"
+
- #: lib/tools_dlg.tcl:306
- msgid "Arguments"
- msgstr "Аргументи"
++#: lib/database.tcl:44
++msgid "Number of packed objects"
++msgstr "Брой пакетирани обекти"
+
- #: lib/tools_dlg.tcl:336 lib/checkout_op.tcl:567 lib/merge.tcl:166
- msgid "Visualize"
- msgstr "Визуализация"
++#: lib/database.tcl:45
++msgid "Number of packs"
++msgstr "Брой пакети"
+
- #: lib/tools_dlg.tcl:341
- msgid "OK"
- msgstr "Добре"
++#: lib/database.tcl:46
++msgid "Disk space used by packed objects"
++msgstr "Дисково пространство заето от пакетирани обекти"
+
- #: lib/search.tcl:48
- msgid "Find:"
- msgstr "Търсене:"
++#: lib/database.tcl:47
++msgid "Packed objects waiting for pruning"
++msgstr "Пакетирани обекти за окастряне"
+
- #: lib/search.tcl:50
- msgid "Next"
- msgstr "Следваща поява"
++#: lib/database.tcl:48
++msgid "Garbage files"
++msgstr "Файлове за боклука"
+
- #: lib/search.tcl:51
- msgid "Prev"
- msgstr "Предишна поява"
++#: lib/database.tcl:57 lib/option.tcl:182 lib/option.tcl:197 lib/option.tcl:220
++#: lib/option.tcl:282
++#, tcl-format
++msgid "%s:"
++msgstr "%s:"
+
- #: lib/search.tcl:52
- msgid "RegExp"
- msgstr "Рег. израз"
++#: lib/database.tcl:66
++#, tcl-format
++msgid "%s (%s): Database Statistics"
++msgstr "%s (%s): Статистика на базата от данни"
+
- #: lib/search.tcl:54
- msgid "Case"
- msgstr "Регистър"
++#: lib/database.tcl:72
++msgid "Compressing the object database"
++msgstr "Компресиране на базата с данни за обектите"
+
- #: lib/shortcut.tcl:21 lib/shortcut.tcl:62
- msgid "Cannot write shortcut:"
- msgstr "Клавишната комбинация не може да бъде запазена:"
++#: lib/database.tcl:83
++msgid "Verifying the object database with fsck-objects"
++msgstr "Проверка на базата с данни за обектите с програмата „fsck-objects“"
+
- #: lib/shortcut.tcl:137
- msgid "Cannot write icon:"
- msgstr "Иконата не може да бъде запазена:"
++#: lib/database.tcl:107
++#, tcl-format
++msgid ""
++"This repository currently has approximately %i loose objects.\n"
++"\n"
++"To maintain optimal performance it is strongly recommended that you compress "
++"the database.\n"
++"\n"
++"Compress the database now?"
++msgstr ""
++"В това хранилище в момента има към %i непакетирани обекти.\n"
++"\n"
++"За добра производителност се препоръчва да компресирате базата с данни за "
++"обектите.\n"
++"\n"
++"Да се започне ли компресирането?"
+
- #: lib/diff.tcl:140
++#: lib/date.tcl:25
++#, tcl-format
++msgid "Invalid date from Git: %s"
++msgstr "Неправилни данни от Git: %s"
+
+#: lib/diff.tcl:77
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
+"The modification date of this file was updated by another application, but "
+"the content within the file was not changed.\n"
+"\n"
+"A rescan will be automatically started to find other files which may have "
+"the same state."
+msgstr ""
+"Не са открити разлики.\n"
+"\n"
+"Няма промени в „%s“.\n"
+"\n"
+"Времето на промяна на файла е бил зададен от друга програма, но съдържанието "
+"му не е променено.\n"
+"\n"
+"Автоматично ще започне нова проверка дали няма други файлове в това "
+"състояние."
+
+#: lib/diff.tcl:117
+#, tcl-format
+msgid "Loading diff of %s..."
+msgstr "Зареждане на разликите в „%s“…"
+
- #: lib/diff.tcl:145
++#: lib/diff.tcl:143
+msgid ""
+"LOCAL: deleted\n"
+"REMOTE:\n"
+msgstr ""
+"ЛОКАЛНО: изтрит\n"
+"ОТДАЛЕЧЕНО:\n"
+
- #: lib/diff.tcl:152
++#: lib/diff.tcl:148
+msgid ""
+"REMOTE: deleted\n"
+"LOCAL:\n"
+msgstr ""
+"ОТДАЛЕЧЕНО: изтрит\n"
+"ЛОКАЛНО:\n"
+
- #: lib/diff.tcl:155
++#: lib/diff.tcl:155
+msgid "LOCAL:\n"
+msgstr "ЛОКАЛНО:\n"
+
- #: lib/diff.tcl:217 lib/diff.tcl:355
++#: lib/diff.tcl:158
+msgid "REMOTE:\n"
+msgstr "ОТДАЛЕЧЕНО:\n"
+
- #: lib/diff.tcl:218
++#: lib/diff.tcl:220 lib/diff.tcl:357
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Файлът „%s“ не може да бъде показан"
+
- #: lib/diff.tcl:225
++#: lib/diff.tcl:221
+msgid "Error loading file:"
+msgstr "Грешка при зареждане на файл:"
+
- #: lib/diff.tcl:237
++#: lib/diff.tcl:227
+msgid "Git Repository (subproject)"
+msgstr "Хранилище на Git (подмодул)"
+
- #: lib/diff.tcl:242
++#: lib/diff.tcl:239
+msgid "* Binary file (not showing content)."
+msgstr "● Двоичен файл (съдържанието не се показва)."
+
- #: lib/diff.tcl:248
- #, tcl-format
- msgid ""
- "\n"
- "* Untracked file clipped here by %s.\n"
- "* To see the entire file, use an external editor.\n"
- msgstr ""
- "\n"
- "● Неследеният файл е отрязан дотук от програмата „%s“.\n"
- "● Използвайте външен редактор, за да видите целия файл.\n"
-
- #: lib/diff.tcl:356 lib/blame.tcl:1128
- msgid "Error loading diff:"
- msgstr "Грешка при зареждане на разлика:"
-
- #: lib/diff.tcl:578
- msgid "Failed to unstage selected hunk."
- msgstr "Избраното парче не може да бъде извадено от индекса."
-
- #: lib/diff.tcl:585
- msgid "Failed to stage selected hunk."
- msgstr "Избраното парче не може да бъде добавено към индекса."
-
- #: lib/diff.tcl:664
- msgid "Failed to unstage selected line."
- msgstr "Избраният ред не може да бъде изваден от индекса."
-
- #: lib/diff.tcl:672
- msgid "Failed to stage selected line."
- msgstr "Избраният ред не може да бъде добавен към индекса."
-
- #: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
- msgid "Delete Branch Remotely"
- msgstr "Изтриване на отдалечения клон"
-
- #: lib/remote_branch_delete.tcl:48
- msgid "From Repository"
- msgstr "От хранилище"
-
- #: lib/remote_branch_delete.tcl:88
- msgid "Branches"
- msgstr "Клони"
-
- #: lib/remote_branch_delete.tcl:110
- msgid "Delete Only If"
- msgstr "Изтриване, само ако"
-
- #: lib/remote_branch_delete.tcl:112
- msgid "Merged Into:"
- msgstr "Слят в:"
-
- #: lib/remote_branch_delete.tcl:120 lib/branch_delete.tcl:53
- msgid "Always (Do not perform merge checks)"
- msgstr "Винаги (без проверка за сливане)"
-
- #: lib/remote_branch_delete.tcl:153
- msgid "A branch is required for 'Merged Into'."
- msgstr "За данните „Слят в“ е необходимо да зададете клон."
-
- #: lib/remote_branch_delete.tcl:185
- #, tcl-format
- msgid ""
- "The following branches are not completely merged into %s:\n"
- "\n"
- " - %s"
- msgstr ""
- "Следните клони не са слети напълно в „%s“:\n"
- "\n"
- " ● %s"
-
- #: lib/remote_branch_delete.tcl:190
++#: lib/diff.tcl:244
+#, tcl-format
+msgid ""
+"* Untracked file is %d bytes.\n"
+"* Showing only first %d bytes.\n"
+msgstr ""
+"● Неследеният файл е %d байта.\n"
+"● Показват се само първите %d байта.\n"
+
- "One or more of the merge tests failed because you have not fetched the "
- "necessary commits. Try fetching from %s first."
- msgstr ""
- "Поне една от пробите за сливане е неуспешна, защото не сте доставили всички "
- "необходими подавания. Пробвайте първо да доставите подаванията от „%s“."
-
- #: lib/remote_branch_delete.tcl:208
- msgid "Please select one or more branches to delete."
- msgstr "Изберете поне един клон за изтриване."
-
- #: lib/remote_branch_delete.tcl:218 lib/branch_delete.tcl:115
- msgid ""
- "Recovering deleted branches is difficult.\n"
- "\n"
- "Delete the selected branches?"
- msgstr ""
- "Възстановяването на изтрити клони може да е трудно.\n"
++#: lib/diff.tcl:250
+#, tcl-format
+msgid ""
- "Сигурни ли сте, че искате да триете?"
-
- #: lib/remote_branch_delete.tcl:227
- #, tcl-format
- msgid "Deleting branches from %s"
- msgstr "Изтриване на клони от „%s“"
-
- #: lib/remote_branch_delete.tcl:300
- msgid "No repository selected."
- msgstr "Не е избрано хранилище."
-
- #: lib/remote_branch_delete.tcl:305
- #, tcl-format
- msgid "Scanning %s..."
- msgstr "Претърсване на „%s“…"
-
- #: lib/choose_repository.tcl:33
- msgid "Git Gui"
- msgstr "ГПИ на Git"
-
- #: lib/choose_repository.tcl:92 lib/choose_repository.tcl:412
- msgid "Create New Repository"
- msgstr "Създаване на ново хранилище"
-
- #: lib/choose_repository.tcl:98
- msgid "New..."
- msgstr "Ново…"
-
- #: lib/choose_repository.tcl:105 lib/choose_repository.tcl:496
- msgid "Clone Existing Repository"
- msgstr "Клониране на съществуващо хранилище"
+"\n"
- #: lib/choose_repository.tcl:116
- msgid "Clone..."
- msgstr "Клониране…"
++"* Untracked file clipped here by %s.\n"
++"* To see the entire file, use an external editor.\n"
++msgstr ""
++"\n"
++"● Неследеният файл е отрязан дотук от програмата „%s“.\n"
++"● Използвайте външен редактор, за да видите целия файл.\n"
+
- #: lib/choose_repository.tcl:123 lib/choose_repository.tcl:1064
- msgid "Open Existing Repository"
- msgstr "Отваряне на съществуващо хранилище"
++#: lib/diff.tcl:580
++msgid "Failed to unstage selected hunk."
++msgstr "Избраното парче не може да бъде извадено от индекса."
+
- #: lib/choose_repository.tcl:129
- msgid "Open..."
- msgstr "Отваряне…"
++#: lib/diff.tcl:587
++msgid "Failed to stage selected hunk."
++msgstr "Избраното парче не може да бъде добавено към индекса."
+
- #: lib/choose_repository.tcl:142
- msgid "Recent Repositories"
- msgstr "Скоро ползвани"
++#: lib/diff.tcl:666
++msgid "Failed to unstage selected line."
++msgstr "Избраният ред не може да бъде изваден от индекса."
+
- #: lib/choose_repository.tcl:148
- msgid "Open Recent Repository:"
- msgstr "Отваряне на хранилище ползвано наскоро:"
++#: lib/diff.tcl:674
++msgid "Failed to stage selected line."
++msgstr "Избраният ред не може да бъде добавен към индекса."
+
- #: lib/choose_repository.tcl:316 lib/choose_repository.tcl:323
- #: lib/choose_repository.tcl:330
++#: lib/encoding.tcl:443
++msgid "Default"
++msgstr "Стандартното"
+
- msgid "Failed to create repository %s:"
- msgstr "Неуспешно създаване на хранилището „%s“:"
-
- #: lib/choose_repository.tcl:407 lib/branch_create.tcl:33
- msgid "Create"
- msgstr "Създаване"
++#: lib/encoding.tcl:448
+#, tcl-format
- #: lib/choose_repository.tcl:417
- msgid "Directory:"
- msgstr "Директория:"
++msgid "System (%s)"
++msgstr "Системното (%s)"
+
- #: lib/choose_repository.tcl:447 lib/choose_repository.tcl:573
- #: lib/choose_repository.tcl:1098
- msgid "Git Repository"
- msgstr "Хранилище на Git"
++#: lib/encoding.tcl:459 lib/encoding.tcl:465
++msgid "Other"
++msgstr "Друго"
+
- #: lib/choose_repository.tcl:472
++#: lib/error.tcl:20
++#, tcl-format
++msgid "%s: error"
++msgstr "%s: грешка"
+
- msgid "Directory %s already exists."
- msgstr "Вече съществува директория „%s“."
++#: lib/error.tcl:36
+#, tcl-format
- #: lib/choose_repository.tcl:476
++msgid "%s: warning"
++msgstr "%s: предупреждение"
+
- msgid "File %s already exists."
- msgstr "Вече съществува файл „%s“."
++#: lib/error.tcl:80
+#, tcl-format
- #: lib/choose_repository.tcl:491
- msgid "Clone"
- msgstr "Клониране"
++msgid "%s hook failed:"
++msgstr "%s: грешка от куката"
+
- #: lib/choose_repository.tcl:504
- msgid "Source Location:"
- msgstr "Адрес на източника:"
++#: lib/error.tcl:96
++msgid "You must correct the above errors before committing."
++msgstr "Преди да можете да подадете, коригирайте горните грешки."
+
- #: lib/choose_repository.tcl:513
- msgid "Target Directory:"
- msgstr "Целева директория:"
++#: lib/error.tcl:116
++#, tcl-format
++msgid "%s (%s): error"
++msgstr "%s (%s): грешка"
+
- #: lib/choose_repository.tcl:523
- msgid "Clone Type:"
- msgstr "Вид клониране:"
++#: lib/index.tcl:6
++msgid "Unable to unlock the index."
++msgstr "Индексът не може да бъде отключен."
+
- #: lib/choose_repository.tcl:528
- msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
- msgstr "Стандартно (бързо, частично споделяне на файлове, твърди връзки)"
++#: lib/index.tcl:17
++msgid "Index Error"
++msgstr "Грешка в индекса"
+
- #: lib/choose_repository.tcl:533
- msgid "Full Copy (Slower, Redundant Backup)"
- msgstr "Пълно (бавно, пълноценно резервно копие)"
++#: lib/index.tcl:19
++msgid ""
++"Updating the Git index failed. A rescan will be automatically started to "
++"resynchronize git-gui."
++msgstr ""
++"Неуспешно обновяване на индекса на Git. Автоматично ще започне нова проверка "
++"за синхронизирането на git-gui."
+
- #: lib/choose_repository.tcl:538
- msgid "Shared (Fastest, Not Recommended, No Backup)"
- msgstr "Споделено (най-бързо, не се препоръчва, не прави резервно копие)"
++#: lib/index.tcl:30
++msgid "Continue"
++msgstr "Продължаване"
+
- #: lib/choose_repository.tcl:545
- msgid "Recursively clone submodules too"
- msgstr "Рекурсивно клониране и на подмодулите"
++#: lib/index.tcl:33
++msgid "Unlock Index"
++msgstr "Отключване на индекса"
+
- #: lib/choose_repository.tcl:579 lib/choose_repository.tcl:626
- #: lib/choose_repository.tcl:772 lib/choose_repository.tcl:842
- #: lib/choose_repository.tcl:1104 lib/choose_repository.tcl:1112
++#: lib/index.tcl:294
++msgid "Unstaging selected files from commit"
++msgstr "Изваждане на избраните файлове от подаването"
+
- msgid "Not a Git repository: %s"
- msgstr "Това не е хранилище на Git: %s"
++#: lib/index.tcl:298
+#, tcl-format
- #: lib/choose_repository.tcl:615
- msgid "Standard only available for local repository."
- msgstr "Само локални хранилища могат да се клонират стандартно"
++msgid "Unstaging %s from commit"
++msgstr "Изваждане на „%s“ от подаването"
+
- #: lib/choose_repository.tcl:619
- msgid "Shared only available for local repository."
- msgstr "Само локални хранилища могат да се клонират споделено"
++#: lib/index.tcl:337
++msgid "Ready to commit."
++msgstr "Готовност за подаване."
+
- #: lib/choose_repository.tcl:640
++#: lib/index.tcl:346
++msgid "Adding selected files"
++msgstr "Добавяне на избраните файлове"
+
- msgid "Location %s already exists."
- msgstr "Местоположението „%s“ вече съществува."
-
- #: lib/choose_repository.tcl:651
- msgid "Failed to configure origin"
- msgstr "Неуспешно настройване на хранилището-източник"
++#: lib/index.tcl:350
+#, tcl-format
- #: lib/choose_repository.tcl:663
- msgid "Counting objects"
- msgstr "Преброяване на обекти"
++msgid "Adding %s"
++msgstr "Добавяне на „%s“"
+
- #: lib/choose_repository.tcl:664
- msgid "buckets"
- msgstr "клетки"
++#: lib/index.tcl:380
++#, tcl-format
++msgid "Stage %d untracked files?"
++msgstr "Да се добавят ли %d неследени файла към индекса?"
+
- #: lib/choose_repository.tcl:688
++#: lib/index.tcl:388
++msgid "Adding all changed files"
++msgstr "Добавяне на всички променени файлове"
+
- msgid "Unable to copy objects/info/alternates: %s"
- msgstr "Обектите/информацията/синонимите не могат да бъдат копирани: %s"
++#: lib/index.tcl:428
+#, tcl-format
- #: lib/choose_repository.tcl:724
++msgid "Revert changes in file %s?"
++msgstr "Да се махнат ли промените във файла „%s“?"
+
- msgid "Nothing to clone from %s."
- msgstr "Няма какво да се клонира от „%s“."
-
- #: lib/choose_repository.tcl:726 lib/choose_repository.tcl:940
- #: lib/choose_repository.tcl:952
- msgid "The 'master' branch has not been initialized."
- msgstr "Основният клон — „master“ не е инициализиран."
-
- #: lib/choose_repository.tcl:739
- msgid "Hardlinks are unavailable. Falling back to copying."
- msgstr "Не се поддържат твърди връзки. Преминава се към копиране."
++#: lib/index.tcl:430
+#, tcl-format
- #: lib/choose_repository.tcl:751
- #, tcl-format
- msgid "Cloning from %s"
- msgstr "Клониране на „%s“"
++msgid "Revert changes in these %i files?"
++msgstr "Да се махнат ли промените в тези %i файла?"
+
- #: lib/choose_repository.tcl:782
- msgid "Copying objects"
- msgstr "Копиране на обекти"
++#: lib/index.tcl:438
++msgid "Any unstaged changes will be permanently lost by the revert."
++msgstr ""
++"Всички промени, които не са били вкарани в индекса, ще бъдат безвъзвратно "
++"загубени."
+
- #: lib/choose_repository.tcl:783
- msgid "KiB"
- msgstr "KiB"
++#: lib/index.tcl:441
++msgid "Do Nothing"
++msgstr "Нищо да не се прави"
+
- #: lib/choose_repository.tcl:807
++#: lib/index.tcl:459
++msgid "Reverting selected files"
++msgstr "Махане на промените в избраните файлове"
+
- msgid "Unable to copy object: %s"
- msgstr "Неуспешно копиране на обект: %s"
++#: lib/index.tcl:463
+#, tcl-format
- #: lib/choose_repository.tcl:817
- msgid "Linking objects"
- msgstr "Създаване на връзки към обектите"
++msgid "Reverting %s"
++msgstr "Махане на промените в „%s“"
+
- #: lib/choose_repository.tcl:818
- msgid "objects"
- msgstr "обекти"
++#: lib/line.tcl:17
++msgid "Goto Line:"
++msgstr "Към ред:"
+
- #: lib/choose_repository.tcl:826
- #, tcl-format
- msgid "Unable to hardlink object: %s"
- msgstr "Неуспешно създаване на твърда връзка към обект: %s"
++#: lib/line.tcl:23
++msgid "Go"
++msgstr "Придвижване"
+
- #: lib/choose_repository.tcl:881
- msgid "Cannot fetch branches and objects. See console output for details."
++#: lib/merge.tcl:13
++msgid ""
++"Cannot merge while amending.\n"
++"\n"
++"You must finish amending this commit before starting any type of merge.\n"
++msgstr ""
++"По време на поправяне не може да сливане.\n"
++"\n"
++"Трябва да завършите поправянето на текущото подаване, преди да започнете "
++"сливане.\n"
+
- "Клоните и обектите не могат да бъдат изтеглени. За повече информация "
- "погледнете изхода на конзолата."
++#: lib/merge.tcl:27
++msgid ""
++"Last scanned state does not match repository state.\n"
++"\n"
++"Another Git program has modified this repository since the last scan. A "
++"rescan must be performed before a merge can be performed.\n"
++"\n"
++"The rescan will be automatically started now.\n"
+msgstr ""
- #: lib/choose_repository.tcl:892
- msgid "Cannot fetch tags. See console output for details."
++"Последно установеното състояние не отговаря на това в хранилището.\n"
++"\n"
++"Някой друг процес за Git е променил хранилището междувременно. Състоянието "
++"трябва да бъде проверено, преди да се извърши сливане.\n"
++"\n"
++"Автоматично ще започне нова проверка.\n"
++"\n"
+
- "Етикетите не могат да бъдат изтеглени. За повече информация погледнете "
- "изхода на конзолата."
++#: lib/merge.tcl:45
++#, tcl-format
++msgid ""
++"You are in the middle of a conflicted merge.\n"
++"\n"
++"File %s has merge conflicts.\n"
++"\n"
++"You must resolve them, stage the file, and commit to complete the current "
++"merge. Only then can you begin another merge.\n"
+msgstr ""
- #: lib/choose_repository.tcl:916
- msgid "Cannot determine HEAD. See console output for details."
++"В момента тече сливане, но има конфликти.\n"
++"\n"
++"Погледнете файла „%s“.\n"
++"\n"
++"Трябва да коригирате конфликтите в него, да го добавите към индекса и да "
++"завършите текущото сливане чрез подаване. Чак тогава може да започнете ново "
++"сливане.\n"
+
- "Върхът „HEAD“ не може да бъде определен. За повече информация погледнете "
- "изхода на конзолата."
++#: lib/merge.tcl:55
++#, tcl-format
++msgid ""
++"You are in the middle of a change.\n"
++"\n"
++"File %s is modified.\n"
++"\n"
++"You should complete the current commit before starting a merge. Doing so "
++"will help you abort a failed merge, should the need arise.\n"
+msgstr ""
- #: lib/choose_repository.tcl:925
++"В момента тече подаване.\n"
++"\n"
++"Файлът „%s“ е променен.\n"
++"\n"
++"Трябва да завършите текущото подаване, преди да започнете сливане. Така ще "
++"можете лесно да преустановите сливането, ако възникне нужда.\n"
+
- msgid "Unable to cleanup %s"
- msgstr "„%s“ не може да се зачисти"
++#: lib/merge.tcl:108
+#, tcl-format
- #: lib/choose_repository.tcl:931
- msgid "Clone failed."
- msgstr "Неуспешно клониране."
++msgid "%s of %s"
++msgstr "%s от общо %s"
+
- #: lib/choose_repository.tcl:938
- msgid "No default branch obtained."
- msgstr "Не е получен клон по подразбиране."
++#: lib/merge.tcl:126
++#, tcl-format
++msgid "Merging %s and %s..."
++msgstr "Сливане на „%s“ и „%s“…"
+
- #: lib/choose_repository.tcl:949
- #, tcl-format
- msgid "Cannot resolve %s as a commit."
- msgstr "Няма подаване отговарящо на „%s“."
++#: lib/merge.tcl:137
++msgid "Merge completed successfully."
++msgstr "Сливането завърши успешно."
+
- #: lib/choose_repository.tcl:961
- msgid "Creating working directory"
- msgstr "Създаване на работната директория"
++#: lib/merge.tcl:139
++msgid "Merge failed. Conflict resolution is required."
++msgstr "Неуспешно сливане — има конфликти за коригиране."
+
- #: lib/choose_repository.tcl:962 lib/index.tcl:70 lib/index.tcl:136
- #: lib/index.tcl:207
- msgid "files"
- msgstr "файлове"
++#: lib/merge.tcl:156
++#, tcl-format
++msgid "%s (%s): Merge"
++msgstr "%s (%s): Сливане"
+
- #: lib/choose_repository.tcl:981
- msgid "Cannot clone submodules."
- msgstr "Подмодулите не могат да се клонират."
++#: lib/merge.tcl:164
++#, tcl-format
++msgid "Merge Into %s"
++msgstr "Сливане в „%s“"
+
- #: lib/choose_repository.tcl:990
- msgid "Cloning submodules"
- msgstr "Клониране на подмодулите"
++#: lib/merge.tcl:183
++msgid "Revision To Merge"
++msgstr "Версия за сливане"
+
- #: lib/choose_repository.tcl:1015
- msgid "Initial file checkout failed."
- msgstr "Неуспешно първоначално изтегляне."
++#: lib/merge.tcl:218
++msgid ""
++"Cannot abort while amending.\n"
++"\n"
++"You must finish amending this commit.\n"
++msgstr ""
++"Поправянето не може да бъде преустановено.\n"
++"\n"
++"Трябва да завършите поправката на това подаване.\n"
+
- #: lib/choose_repository.tcl:1059
- msgid "Open"
- msgstr "Отваряне"
++#: lib/merge.tcl:228
++msgid ""
++"Abort merge?\n"
++"\n"
++"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
++"\n"
++"Continue with aborting the current merge?"
++msgstr ""
++"Да се преустанови ли сливането?\n"
++"\n"
++"В такъв случай ●ВСИЧКИ● неподадени промени ще бъдат безвъзвратно загубени.\n"
++"\n"
++"Наистина ли да се преустанови сливането?"
+
- #: lib/choose_repository.tcl:1069
- msgid "Repository:"
- msgstr "Хранилище:"
++#: lib/merge.tcl:234
++msgid ""
++"Reset changes?\n"
++"\n"
++"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
++"\n"
++"Continue with resetting the current changes?"
++msgstr ""
++"Да се занулят ли промените?\n"
++"\n"
++"В такъв случай ●ВСИЧКИ● неподадени промени ще бъдат безвъзвратно загубени.\n"
++"\n"
++"Наистина ли да се занулят промените?"
+
- #: lib/choose_repository.tcl:1118
- #, tcl-format
- msgid "Failed to open repository %s:"
- msgstr "Неуспешно отваряне на хранилището „%s“:"
++#: lib/merge.tcl:245
++msgid "Aborting"
++msgstr "Преустановяване"
+
- #: lib/about.tcl:26
- msgid "git-gui - a graphical user interface for Git."
- msgstr "git-gui — графичен интерфейс за Git."
++#: lib/merge.tcl:245
++msgid "files reset"
++msgstr "файла със занулени промени"
+
- #: lib/checkout_op.tcl:85
- #, tcl-format
- msgid "Fetching %s from %s"
- msgstr "Доставяне на „%s“ от „%s“"
++#: lib/merge.tcl:273
++msgid "Abort failed."
++msgstr "Неуспешно преустановяване."
+
- #: lib/checkout_op.tcl:133
- #, tcl-format
- msgid "fatal: Cannot resolve %s"
- msgstr "фатална грешка: „%s“ не може да се открие"
++#: lib/merge.tcl:275
++msgid "Abort completed. Ready."
++msgstr "Успешно преустановяване. Готовност за следващо действие."
+
- #: lib/checkout_op.tcl:175
- #, tcl-format
- msgid "Branch '%s' does not exist."
- msgstr "Клонът „%s“ не съществува."
++#: lib/mergetool.tcl:8
++msgid "Force resolution to the base version?"
++msgstr "Да се използва базовата версия"
+
- #: lib/checkout_op.tcl:194
- #, tcl-format
- msgid "Failed to configure simplified git-pull for '%s'."
- msgstr "Неуспешно настройване на опростен git-pull за „%s“."
++#: lib/mergetool.tcl:9
++msgid "Force resolution to this branch?"
++msgstr "Да се използва версията от този клон"
+
- #: lib/checkout_op.tcl:229
++#: lib/mergetool.tcl:10
++msgid "Force resolution to the other branch?"
++msgstr "Да се използва версията от другия клон"
+
- "Branch '%s' already exists.\n"
++#: lib/mergetool.tcl:14
+#, tcl-format
+msgid ""
- "It cannot fast-forward to %s.\n"
- "A merge is required."
++"Note that the diff shows only conflicting changes.\n"
+"\n"
- "Клонът „%s“ съществува.\n"
++"%s will be overwritten.\n"
++"\n"
++"This operation can be undone only by restarting the merge."
+msgstr ""
- "Той не може да бъде тривиално слят до „%s“.\n"
- "Необходимо е сливане."
++"Разликата показва само разликите с конфликт.\n"
+"\n"
- #: lib/checkout_op.tcl:243
++"Файлът „%s“ ще бъде презаписан.\n"
++"\n"
++"Тази операция може да бъде отменена само чрез започване на сливането наново."
+
- msgid "Merge strategy '%s' not supported."
- msgstr "Стратегия за сливане „%s“ не се поддържа."
++#: lib/mergetool.tcl:45
+#, tcl-format
- #: lib/checkout_op.tcl:262
++msgid "File %s seems to have unresolved conflicts, still stage?"
++msgstr ""
++"Изглежда, че все още има некоригирани конфликти във файла „%s“. Да се добави "
++"ли файлът към индекса?"
+
- msgid "Failed to update '%s'."
- msgstr "Неуспешно обновяване на „%s“."
-
- #: lib/checkout_op.tcl:274
- msgid "Staging area (index) is already locked."
- msgstr "Индексът вече е заключен."
++#: lib/mergetool.tcl:60
+#, tcl-format
- #: lib/checkout_op.tcl:289
- msgid ""
- "Last scanned state does not match repository state.\n"
- "\n"
- "Another Git program has modified this repository since the last scan. A "
- "rescan must be performed before the current branch can be changed.\n"
- "\n"
- "The rescan will be automatically started now.\n"
++msgid "Adding resolution for %s"
++msgstr "Добавяне на корекция на конфликтите в „%s“"
+
- "Състоянието при последната проверка не отговаря на състоянието на "
- "хранилището.\n"
- "\n"
- "Някой друг процес за Git е променил хранилището междувременно. Състоянието "
- "трябва да бъде проверено, преди да се премине към нов клон.\n"
- "\n"
- "Автоматично ще започне нова проверка.\n"
++#: lib/mergetool.tcl:141
++msgid "Cannot resolve deletion or link conflicts using a tool"
+msgstr ""
- #: lib/checkout_op.tcl:345
- #, tcl-format
- msgid "Updating working directory to '%s'..."
- msgstr "Работната директория се привежда към „%s“…"
++"Конфликтите при символни връзки или изтриване не могат да бъдат коригирани с "
++"външна програма."
+
- #: lib/checkout_op.tcl:346
- msgid "files checked out"
- msgstr "файла са изтеглени"
++#: lib/mergetool.tcl:146
++msgid "Conflict file does not exist"
++msgstr "Файлът, в който е конфликтът, не съществува"
+
- #: lib/checkout_op.tcl:376
++#: lib/mergetool.tcl:246
++#, tcl-format
++msgid "Not a GUI merge tool: '%s'"
++msgstr "Това не е графична програма за сливане: „%s“"
+
- msgid "Aborted checkout of '%s' (file level merging is required)."
- msgstr ""
- "Преустановяване на изтеглянето на „%s“ (необходимо е пофайлово сливане)."
++#: lib/mergetool.tcl:275
+#, tcl-format
- #: lib/checkout_op.tcl:377
- msgid "File level merge required."
- msgstr "Необходимо е пофайлово сливане."
++msgid "Unsupported merge tool '%s'"
++msgstr "Неподдържана програма за сливане: „%s“"
+
- #: lib/checkout_op.tcl:381
++#: lib/mergetool.tcl:310
++msgid "Merge tool is already running, terminate it?"
++msgstr "Програмата за сливане вече е стартирана. Да бъде ли изключена?"
+
- msgid "Staying on branch '%s'."
- msgstr "Оставане върху клона „%s“."
++#: lib/mergetool.tcl:330
+#, tcl-format
- #: lib/checkout_op.tcl:452
++msgid ""
++"Error retrieving versions:\n"
++"%s"
++msgstr ""
++"Грешка при изтеглянето на версии:\n"
++"%s"
+
- "You are no longer on a local branch.\n"
++#: lib/mergetool.tcl:350
++#, tcl-format
+msgid ""
- "If you wanted to be on a branch, create one now starting from 'This Detached "
- "Checkout'."
++"Could not start the merge tool:\n"
+"\n"
- "Вече не сте на локален клон.\n"
++"%s"
+msgstr ""
- "Ако искате да сте на клон, създайте базиран на „Това несвързано изтегляне“."
++"Програмата за сливане не може да бъде стартирана:\n"
+"\n"
- #: lib/checkout_op.tcl:503 lib/checkout_op.tcl:507
++"%s"
+
- msgid "Checked out '%s'."
- msgstr "„%s“ е изтеглен."
++#: lib/mergetool.tcl:354
++msgid "Running merge tool..."
++msgstr "Стартиране на програмата за сливане…"
++
++#: lib/mergetool.tcl:382 lib/mergetool.tcl:390
++msgid "Merge tool failed."
++msgstr "Грешка в програмата за сливане."
++
++#: lib/option.tcl:11
+#, tcl-format
- #: lib/checkout_op.tcl:535
++msgid "Invalid global encoding '%s'"
++msgstr "Неправилно глобално кодиране „%s“"
+
- msgid "Resetting '%s' to '%s' will lose the following commits:"
- msgstr ""
- "Зануляването на „%s“ към „%s“ ще доведе до загубването на следните подавания:"
++#: lib/option.tcl:19
+#, tcl-format
- #: lib/checkout_op.tcl:557
- msgid "Recovering lost commits may not be easy."
- msgstr "Възстановяването на загубените подавания може да е трудно."
++msgid "Invalid repo encoding '%s'"
++msgstr "Неправилно кодиране „%s“ на хранилището"
+
- #: lib/checkout_op.tcl:562
++#: lib/option.tcl:119
++msgid "Restore Defaults"
++msgstr "Стандартни настройки"
+
- msgid "Reset '%s'?"
- msgstr "Зануляване на „%s“?"
++#: lib/option.tcl:123
++msgid "Save"
++msgstr "Запазване"
++
++#: lib/option.tcl:133
+#, tcl-format
- #: lib/checkout_op.tcl:571 lib/branch_create.tcl:85
- msgid "Reset"
- msgstr "Отначало"
++msgid "%s Repository"
++msgstr "Хранилище „%s“"
+
- #: lib/checkout_op.tcl:635
- #, tcl-format
- msgid ""
- "Failed to set current branch.\n"
- "\n"
- "This working directory is only partially switched. We successfully updated "
- "your files, but failed to update an internal Git file.\n"
- "\n"
- "This should not have occurred. %s will now close and give up."
- msgstr ""
- "Неуспешно задаване на текущия клон.\n"
- "\n"
- "Работната директория е само частично обновена: файловете са обновени "
- "успешно, но някой от вътрешните, служебни файлове на Git не е бил.\n"
- "\n"
- "Това състояние е аварийно и не трябва да се случва. Програмата „%s“ ще "
- "преустанови работа."
++#: lib/option.tcl:134
++msgid "Global (All Repositories)"
++msgstr "Глобално (за всички хранилища)"
+
- #: lib/branch_create.tcl:23
- msgid "Create Branch"
- msgstr "Създаване на клон"
++#: lib/option.tcl:140
++msgid "User Name"
++msgstr "Потребителско име"
+
- #: lib/branch_create.tcl:28
- msgid "Create New Branch"
- msgstr "Създаване на нов клон"
++#: lib/option.tcl:141
++msgid "Email Address"
++msgstr "Адрес на е-поща"
+
- #: lib/branch_create.tcl:42
- msgid "Branch Name"
- msgstr "Име на клона"
++#: lib/option.tcl:143
++msgid "Summarize Merge Commits"
++msgstr "Обобщаване на подаванията при сливане"
+
- #: lib/branch_create.tcl:57
- msgid "Match Tracking Branch Name"
- msgstr "Съвпадане по името на следения клон"
++#: lib/option.tcl:144
++msgid "Merge Verbosity"
++msgstr "Подробности при сливанията"
+
- #: lib/branch_create.tcl:66
- msgid "Starting Revision"
- msgstr "Начална версия"
++#: lib/option.tcl:145
++msgid "Show Diffstat After Merge"
++msgstr "Извеждане на статистика след сливанията"
+
- #: lib/branch_create.tcl:72
- msgid "Update Existing Branch:"
- msgstr "Обновяване на съществуващ клон:"
++#: lib/option.tcl:146
++msgid "Use Merge Tool"
++msgstr "Използване на програма за сливане"
+
- #: lib/branch_create.tcl:75
- msgid "No"
- msgstr "Не"
++#: lib/option.tcl:148
++msgid "Trust File Modification Timestamps"
++msgstr "Доверие във времето на промяна на файловете"
+
- #: lib/branch_create.tcl:80
- msgid "Fast Forward Only"
- msgstr "Само тривиално превъртащо сливане"
++#: lib/option.tcl:149
++msgid "Prune Tracking Branches During Fetch"
++msgstr "Окастряне на следящите клонове при доставяне"
+
- #: lib/branch_create.tcl:97
- msgid "Checkout After Creation"
- msgstr "Преминаване към клона след създаването му"
++#: lib/option.tcl:150
++msgid "Match Tracking Branches"
++msgstr "Напасване на следящите клонове"
+
- #: lib/branch_create.tcl:132
- msgid "Please select a tracking branch."
- msgstr "Изберете клон за следени."
++#: lib/option.tcl:151
++msgid "Use Textconv For Diffs and Blames"
++msgstr "Използване на „textconv“ за разликите и анотирането"
+
- #: lib/branch_create.tcl:141
- #, tcl-format
- msgid "Tracking branch %s is not a branch in the remote repository."
- msgstr "Следящият клон — „%s“, не съществува в отдалеченото хранилище."
++#: lib/option.tcl:152
++msgid "Blame Copy Only On Changed Files"
++msgstr "Анотиране на копието само по променените файлове"
+
- #: lib/console.tcl:59
- msgid "Working... please wait..."
- msgstr "В момента се извършва действие, изчакайте…"
++#: lib/option.tcl:153
++msgid "Maximum Length of Recent Repositories List"
++msgstr "Максимален брой на списъка „Скоро ползвани“ хранилища"
+
- #: lib/console.tcl:186
- msgid "Success"
- msgstr "Успех"
++#: lib/option.tcl:154
++msgid "Minimum Letters To Blame Copy On"
++msgstr "Минимален брой знаци за анотиране на копието"
+
- #: lib/console.tcl:200
- msgid "Error: Command Failed"
- msgstr "Грешка: неуспешно изпълнение на команда"
++#: lib/option.tcl:155
++msgid "Blame History Context Radius (days)"
++msgstr "Исторически обхват за анотиране в дни"
+
- #: lib/choose_rev.tcl:52
- msgid "This Detached Checkout"
- msgstr "Това несвързано изтегляне"
++#: lib/option.tcl:156
++msgid "Number of Diff Context Lines"
++msgstr "Брой редове за контекста на разликите"
+
- #: lib/choose_rev.tcl:60
- msgid "Revision Expression:"
- msgstr "Израз за версия:"
++#: lib/option.tcl:157
++msgid "Additional Diff Parameters"
++msgstr "Аргументи към командата за разликите"
+
- #: lib/choose_rev.tcl:72
- msgid "Local Branch"
- msgstr "Локален клон"
++#: lib/option.tcl:158
++msgid "Commit Message Text Width"
++msgstr "Широчина на текста на съобщението при подаване"
+
- #: lib/choose_rev.tcl:77
- msgid "Tracking Branch"
- msgstr "Следящ клон"
++#: lib/option.tcl:159
++msgid "New Branch Name Template"
++msgstr "Шаблон за името на новите клони"
+
- #: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544
- msgid "Tag"
- msgstr "Етикет"
++#: lib/option.tcl:160
++msgid "Default File Contents Encoding"
++msgstr "Кодиране на файловете"
+
- #: lib/choose_rev.tcl:321
- #, tcl-format
- msgid "Invalid revision: %s"
- msgstr "Неправилна версия: %s"
++#: lib/option.tcl:161
++msgid "Warn before committing to a detached head"
++msgstr "Предупреждаване при подаване към несвързан указател"
+
- #: lib/choose_rev.tcl:342
- msgid "No revision selected."
- msgstr "Не е избрана версия."
++#: lib/option.tcl:162
++msgid "Staging of untracked files"
++msgstr "Добавяне на неследените файлове към индекса"
+
- #: lib/choose_rev.tcl:350
- msgid "Revision expression is empty."
- msgstr "Изразът за версия е празен."
++#: lib/option.tcl:163
++msgid "Show untracked files"
++msgstr "Показване на неследените файлове"
+
- #: lib/choose_rev.tcl:537
- msgid "Updated"
- msgstr "Обновен"
++#: lib/option.tcl:164
++msgid "Tab spacing"
++msgstr "Ширина на табулацията"
+
- #: lib/choose_rev.tcl:565
- msgid "URL"
- msgstr "Адрес"
++#: lib/option.tcl:210
++msgid "Change"
++msgstr "Смяна"
+
- #: lib/line.tcl:17
- msgid "Goto Line:"
- msgstr "Към ред:"
++#: lib/option.tcl:254
++msgid "Spelling Dictionary:"
++msgstr "Правописен речник:"
+
- #: lib/line.tcl:23
- msgid "Go"
- msgstr "Придвижване"
++#: lib/option.tcl:284
++msgid "Change Font"
++msgstr "Смяна на шрифта"
+
- #: lib/commit.tcl:9
- msgid ""
- "There is nothing to amend.\n"
- "\n"
- "You are about to create the initial commit. There is no commit before this "
- "to amend.\n"
- msgstr ""
- "Няма какво да се поправи.\n"
- "\n"
- "Ще създадете първоначалното подаване. Преди него няма други подавания, които "
- "да поправите.\n"
++#: lib/option.tcl:288
++#, tcl-format
++msgid "Choose %s"
++msgstr "Избор на „%s“"
+
- #: lib/commit.tcl:18
- msgid ""
- "Cannot amend while merging.\n"
- "\n"
- "You are currently in the middle of a merge that has not been fully "
- "completed. You cannot amend the prior commit unless you first abort the "
- "current merge activity.\n"
- msgstr ""
- "По време на сливане не може да поправяте.\n"
- "\n"
- "В момента все още не сте завършили операция по сливане. Не може да поправите "
- "предишното подаване, освен ако първо не преустановите текущото сливане.\n"
++#: lib/option.tcl:294
++msgid "pt."
++msgstr "тчк."
+
- #: lib/commit.tcl:48
- msgid "Error loading commit data for amend:"
- msgstr "Грешка при зареждане на данните от подаване, които да се поправят:"
++#: lib/option.tcl:308
++msgid "Preferences"
++msgstr "Настройки"
+
- #: lib/commit.tcl:75
- msgid "Unable to obtain your identity:"
- msgstr "Идентификацията ви не може да бъде определена:"
++#: lib/option.tcl:345
++msgid "Failed to completely save options:"
++msgstr "Неуспешно запазване на настройките:"
+
- #: lib/commit.tcl:80
- msgid "Invalid GIT_COMMITTER_IDENT:"
- msgstr "Неправилно поле „GIT_COMMITTER_IDENT“:"
++#: lib/remote.tcl:200
++msgid "Push to"
++msgstr "Изтласкване към"
+
- #: lib/commit.tcl:129
- #, tcl-format
- msgid "warning: Tcl does not support encoding '%s'."
- msgstr "предупреждение: Tcl не поддържа кодирането „%s“."
++#: lib/remote.tcl:218
++msgid "Remove Remote"
++msgstr "Премахване на отдалечено хранилище"
+
- #: lib/commit.tcl:149
- msgid ""
- "Last scanned state does not match repository state.\n"
- "\n"
- "Another Git program has modified this repository since the last scan. A "
- "rescan must be performed before another commit can be created.\n"
- "\n"
- "The rescan will be automatically started now.\n"
- msgstr ""
- "Състоянието при последната проверка не отговаря на състоянието на "
- "хранилището.\n"
- "\n"
- "Някой друг процес за Git е променил хранилището междувременно. Състоянието "
- "трябва да бъде проверено преди ново подаване.\n"
- "\n"
- "Автоматично ще започне нова проверка.\n"
++#: lib/remote.tcl:223
++msgid "Prune from"
++msgstr "Окастряне от"
++
++#: lib/remote.tcl:228
++msgid "Fetch from"
++msgstr "Доставяне от"
+
- #: lib/commit.tcl:173
++#: lib/remote.tcl:253 lib/remote.tcl:258
++msgid "All"
++msgstr "Всички"
+
- msgid ""
- "Unmerged files cannot be committed.\n"
- "\n"
- "File %s has merge conflicts. You must resolve them and stage the file "
- "before committing.\n"
- msgstr ""
- "Неслетите файлове не могат да бъдат подавани.\n"
- "\n"
- "Във файла „%s“ има конфликти при сливане. За да го подадете, трябва първо да "
- "коригирате конфликтите и да добавите файла към индекса за подаване.\n"
++#: lib/remote_add.tcl:20
+#, tcl-format
- #: lib/commit.tcl:181
- #, tcl-format
- msgid ""
- "Unknown file state %s detected.\n"
- "\n"
- "File %s cannot be committed by this program.\n"
- msgstr ""
- "Непознато състояние на файл „%s“.\n"
- "\n"
- "Файлът „%s“ не може да бъде подаден чрез текущата програма.\n"
++msgid "%s (%s): Add Remote"
++msgstr "%s (%s): Добавяне на отдалечено хранилище"
+
- #: lib/commit.tcl:189
- msgid ""
- "No changes to commit.\n"
- "\n"
- "You must stage at least 1 file before you can commit.\n"
- msgstr ""
- "Няма промени за подаване.\n"
- "\n"
- "Трябва да добавите поне един файл към индекса, за да подадете.\n"
++#: lib/remote_add.tcl:25
++msgid "Add New Remote"
++msgstr "Добавяне на отдалечено хранилище"
+
- #: lib/commit.tcl:204
- msgid ""
- "Please supply a commit message.\n"
- "\n"
- "A good commit message has the following format:\n"
- "\n"
- "- First line: Describe in one sentence what you did.\n"
- "- Second line: Blank\n"
- "- Remaining lines: Describe why this change is good.\n"
- msgstr ""
- "Задайте добро съобщение при подаване.\n"
- "\n"
- "Използвайте следния формат:\n"
- "\n"
- "● Първи ред: описание в едно изречение на промяната.\n"
- "● Втори ред: празен.\n"
- "● Останалите редове: опишете защо се налага тази промяна.\n"
++#: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37
++msgid "Add"
++msgstr "Добавяне"
+
- #: lib/commit.tcl:235
- msgid "Calling pre-commit hook..."
- msgstr "Изпълняване на куката преди подаване…"
++#: lib/remote_add.tcl:39
++msgid "Remote Details"
++msgstr "Данни за отдалеченото хранилище"
+
- #: lib/commit.tcl:250
- msgid "Commit declined by pre-commit hook."
- msgstr "Подаването е отхвърлено от куката преди подаване."
++#: lib/remote_add.tcl:50
++msgid "Location:"
++msgstr "Местоположение:"
+
- #: lib/commit.tcl:269
- msgid ""
- "You are about to commit on a detached head. This is a potentially dangerous "
- "thing to do because if you switch to another branch you will lose your "
- "changes and it can be difficult to retrieve them later from the reflog. You "
- "should probably cancel this commit and create a new branch to continue.\n"
- " \n"
- " Do you really want to proceed with your Commit?"
- msgstr ""
- "Ще подавате към несвързан връх. Това е опасно — при изтеглянето на друг клон "
- "ще изгубите промените си. След това може да е невъзможно да ги възстановите "
- "от журнала на указателите „reflog“. Най-вероятно трябва да отмените това "
- "подаване и да създадете клон, в който да подадете.\n"
- " \n"
- "Сигурни ли сте, че искате да подадете към несвързан връх?"
++#: lib/remote_add.tcl:60
++msgid "Further Action"
++msgstr "Следващо действие"
+
- #: lib/commit.tcl:290
- msgid "Calling commit-msg hook..."
- msgstr "Изпълняване на куката за съобщението при подаване…"
++#: lib/remote_add.tcl:63
++msgid "Fetch Immediately"
++msgstr "Незабавно доставяне"
+
- #: lib/commit.tcl:305
- msgid "Commit declined by commit-msg hook."
- msgstr "Подаването е отхвърлено от куката за съобщението при подаване."
++#: lib/remote_add.tcl:69
++msgid "Initialize Remote Repository and Push"
++msgstr "Инициализиране на отдалеченото хранилище и изтласкване на промените"
+
- #: lib/commit.tcl:318
- msgid "Committing changes..."
- msgstr "Подаване на промените…"
++#: lib/remote_add.tcl:75
++msgid "Do Nothing Else Now"
++msgstr "Да не се прави нищо"
+
- #: lib/commit.tcl:334
- msgid "write-tree failed:"
- msgstr "неуспешно запазване на дървото (write-tree):"
++#: lib/remote_add.tcl:100
++msgid "Please supply a remote name."
++msgstr "Задайте име за отдалеченото хранилище."
+
- #: lib/commit.tcl:335 lib/commit.tcl:379 lib/commit.tcl:400
- msgid "Commit failed."
- msgstr "Неуспешно подаване."
++#: lib/remote_add.tcl:113
++#, tcl-format
++msgid "'%s' is not an acceptable remote name."
++msgstr "Отдалечено хранилище не може да се казва „%s“."
+
- #: lib/commit.tcl:352
++#: lib/remote_add.tcl:124
++#, tcl-format
++msgid "Failed to add remote '%s' of location '%s'."
++msgstr "Неуспешно добавяне на отдалеченото хранилище „%s“ от адрес „%s“."
+
- msgid "Commit %s appears to be corrupt"
- msgstr "Подаването „%s“ изглежда повредено"
++#: lib/remote_add.tcl:132 lib/transport.tcl:6
+#, tcl-format
- #: lib/commit.tcl:357
- msgid ""
- "No changes to commit.\n"
- "\n"
- "No files were modified by this commit and it was not a merge commit.\n"
- "\n"
- "A rescan will be automatically started now.\n"
- msgstr ""
- "Няма промени за подаване.\n"
- "\n"
- "В това подаване не са променяни никакви файлове, а и не е подаване със "
- "сливане.\n"
- "\n"
- "Автоматично ще започне нова проверка.\n"
++msgid "fetch %s"
++msgstr "доставяне на „%s“"
+
- #: lib/commit.tcl:364
- msgid "No changes to commit."
- msgstr "Няма промени за подаване."
++#: lib/remote_add.tcl:133
++#, tcl-format
++msgid "Fetching the %s"
++msgstr "Доставяне на „%s“"
+
- #: lib/commit.tcl:378
- msgid "commit-tree failed:"
- msgstr "неуспешно подаване на дървото (commit-tree):"
++#: lib/remote_add.tcl:156
++#, tcl-format
++msgid "Do not know how to initialize repository at location '%s'."
++msgstr "Хранилището с местоположение „%s“ не може да бъде инициализирано."
+
- #: lib/commit.tcl:399
- msgid "update-ref failed:"
- msgstr "неуспешно обновяване на указателите (update-ref):"
++#: lib/remote_add.tcl:162 lib/transport.tcl:54 lib/transport.tcl:92
++#: lib/transport.tcl:110
++#, tcl-format
++msgid "push %s"
++msgstr "изтласкване на „%s“"
+
- #: lib/commit.tcl:492
++#: lib/remote_add.tcl:163
++#, tcl-format
++msgid "Setting up the %s (at %s)"
++msgstr "Добавяне на хранилище „%s“ (с адрес „%s“)"
+
- msgid "Created commit %s: %s"
- msgstr "Успешно подаване %s: %s"
++#: lib/remote_branch_delete.tcl:29
+#, tcl-format
- #: lib/branch_delete.tcl:16
- msgid "Delete Branch"
- msgstr "Изтриване на клон"
++msgid "%s (%s): Delete Branch Remotely"
++msgstr "%s (%s): Изтриване на отдалечения клон"
+
- #: lib/branch_delete.tcl:21
- msgid "Delete Local Branch"
- msgstr "Изтриване на локален клон"
++#: lib/remote_branch_delete.tcl:34
++msgid "Delete Branch Remotely"
++msgstr "Изтриване на отдалечения клон"
+
- #: lib/branch_delete.tcl:39
- msgid "Local Branches"
- msgstr "Локални клони"
++#: lib/remote_branch_delete.tcl:48
++msgid "From Repository"
++msgstr "От хранилище"
+
- #: lib/branch_delete.tcl:51
- msgid "Delete Only If Merged Into"
- msgstr "Изтриване, само ако промените са слети и другаде"
++#: lib/remote_branch_delete.tcl:51 lib/transport.tcl:165
++msgid "Remote:"
++msgstr "Отдалечено хранилище:"
+
- #: lib/branch_delete.tcl:103
- #, tcl-format
- msgid "The following branches are not completely merged into %s:"
- msgstr "Не всички промени в клоните са слети в „%s“:"
++#: lib/remote_branch_delete.tcl:72 lib/transport.tcl:187
++msgid "Arbitrary Location:"
++msgstr "Произволно местоположение:"
+
- #: lib/branch_delete.tcl:141
++#: lib/remote_branch_delete.tcl:88
++msgid "Branches"
++msgstr "Клони"
+
- "Failed to delete branches:\n"
- "%s"
++#: lib/remote_branch_delete.tcl:110
++msgid "Delete Only If"
++msgstr "Изтриване, само ако"
++
++#: lib/remote_branch_delete.tcl:112
++msgid "Merged Into:"
++msgstr "Слят в:"
++
++#: lib/remote_branch_delete.tcl:153
++msgid "A branch is required for 'Merged Into'."
++msgstr "За данните „Слят в“ е необходимо да зададете клон."
++
++#: lib/remote_branch_delete.tcl:185
+#, tcl-format
+msgid ""
- "Неуспешно триене на клони:\n"
- "%s"
++"The following branches are not completely merged into %s:\n"
++"\n"
++" - %s"
+msgstr ""
- #: lib/blame.tcl:73
- msgid "File Viewer"
- msgstr "Преглед на файлове"
++"Следните клони не са слети напълно в „%s“:\n"
++"\n"
++" ● %s"
+
- #: lib/blame.tcl:79
- msgid "Commit:"
- msgstr "Подаване:"
++#: lib/remote_branch_delete.tcl:190
++#, tcl-format
++msgid ""
++"One or more of the merge tests failed because you have not fetched the "
++"necessary commits. Try fetching from %s first."
++msgstr ""
++"Поне една от пробите за сливане е неуспешна, защото не сте доставили всички "
++"необходими подавания. Пробвайте първо да доставите подаванията от „%s“."
+
- #: lib/blame.tcl:280
- msgid "Copy Commit"
- msgstr "Копиране на подаване"
++#: lib/remote_branch_delete.tcl:208
++msgid "Please select one or more branches to delete."
++msgstr "Изберете поне един клон за изтриване."
+
- #: lib/blame.tcl:284
- msgid "Find Text..."
- msgstr "Търсене на текст…"
++#: lib/remote_branch_delete.tcl:227
++#, tcl-format
++msgid "Deleting branches from %s"
++msgstr "Изтриване на клони от „%s“"
+
- #: lib/blame.tcl:288
- msgid "Goto Line..."
- msgstr "Към ред…"
++#: lib/remote_branch_delete.tcl:300
++msgid "No repository selected."
++msgstr "Не е избрано хранилище."
+
- #: lib/blame.tcl:297
- msgid "Do Full Copy Detection"
- msgstr "Пълно търсене на копиране"
++#: lib/remote_branch_delete.tcl:305
++#, tcl-format
++msgid "Scanning %s..."
++msgstr "Претърсване на „%s“…"
+
- #: lib/blame.tcl:301
- msgid "Show History Context"
- msgstr "Показване на контекста от историята"
++#: lib/search.tcl:48
++msgid "Find:"
++msgstr "Търсене:"
+
- #: lib/blame.tcl:304
- msgid "Blame Parent Commit"
- msgstr "Анотиране на родителското подаване"
++#: lib/search.tcl:50
++msgid "Next"
++msgstr "Следваща поява"
+
- #: lib/blame.tcl:466
- #, tcl-format
- msgid "Reading %s..."
- msgstr "Чете се „%s“…"
++#: lib/search.tcl:51
++msgid "Prev"
++msgstr "Предишна поява"
+
- #: lib/blame.tcl:594
- msgid "Loading copy/move tracking annotations..."
- msgstr "Зареждане на анотациите за проследяване на копирането/преместването…"
++#: lib/search.tcl:52
++msgid "RegExp"
++msgstr "РегИзр"
+
- #: lib/blame.tcl:614
- msgid "lines annotated"
- msgstr "реда анотирани"
++#: lib/search.tcl:54
++msgid "Case"
++msgstr "Главни/малки"
+
- #: lib/blame.tcl:806
- msgid "Loading original location annotations..."
- msgstr "Зареждане на анотациите за първоначалното местоположение…"
++#: lib/shortcut.tcl:8 lib/shortcut.tcl:43 lib/shortcut.tcl:75
++#, tcl-format
++msgid "%s (%s): Create Desktop Icon"
++msgstr "%s (%s): Добавяне на икона на работния плот"
+
- #: lib/blame.tcl:809
- msgid "Annotation complete."
- msgstr "Анотирането завърши."
++#: lib/shortcut.tcl:24 lib/shortcut.tcl:65
++msgid "Cannot write shortcut:"
++msgstr "Клавишната комбинация не може да бъде запазена:"
+
- #: lib/blame.tcl:839
- msgid "Busy"
- msgstr "Операцията не е завършила"
++#: lib/shortcut.tcl:140
++msgid "Cannot write icon:"
++msgstr "Иконата не може да бъде запазена:"
+
- #: lib/blame.tcl:840
- msgid "Annotation process is already running."
- msgstr "В момента тече процес на анотиране."
++#: lib/spellcheck.tcl:57
++msgid "Unsupported spell checker"
++msgstr "Тази програма за проверка на правописа не се поддържа"
+
- #: lib/blame.tcl:879
- msgid "Running thorough copy detection..."
- msgstr "Изпълнява се цялостен процес на откриване на копиране…"
++#: lib/spellcheck.tcl:65
++msgid "Spell checking is unavailable"
++msgstr "Липсва програма за проверка на правописа"
+
- #: lib/blame.tcl:947
- msgid "Loading annotation..."
- msgstr "Зареждане на анотации…"
++#: lib/spellcheck.tcl:68
++msgid "Invalid spell checking configuration"
++msgstr "Неправилни настройки на проверката на правописа"
+
- #: lib/blame.tcl:1000
- msgid "Author:"
- msgstr "Автор:"
++#: lib/spellcheck.tcl:70
++#, tcl-format
++msgid "Reverting dictionary to %s."
++msgstr "Ползване на речник за език „%s“."
+
- #: lib/blame.tcl:1004
- msgid "Committer:"
- msgstr "Подал:"
++#: lib/spellcheck.tcl:73
++msgid "Spell checker silently failed on startup"
++msgstr "Програмата за правопис даже не стартира успешно."
+
- #: lib/blame.tcl:1009
- msgid "Original File:"
- msgstr "Първоначален файл:"
++#: lib/spellcheck.tcl:80
++msgid "Unrecognized spell checker"
++msgstr "Непозната програма за проверка на правописа"
+
- #: lib/blame.tcl:1057
- msgid "Cannot find HEAD commit:"
- msgstr "Подаването за връх „HEAD“ не може да се открие:"
++#: lib/spellcheck.tcl:186
++msgid "No Suggestions"
++msgstr "Няма предложения"
+
- #: lib/blame.tcl:1112
- msgid "Cannot find parent commit:"
- msgstr "Родителското подаване не може да бъде открито"
++#: lib/spellcheck.tcl:388
++msgid "Unexpected EOF from spell checker"
++msgstr "Неочакван край на файл от програмата за проверка на правописа"
+
- #: lib/blame.tcl:1127
- msgid "Unable to display parent"
- msgstr "Родителят не може да бъде показан"
++#: lib/spellcheck.tcl:392
++msgid "Spell Checker Failed"
++msgstr "Грешка в програмата за проверка на правописа"
+
- #: lib/blame.tcl:1269
- msgid "Originally By:"
- msgstr "Първоначално от:"
++#: lib/sshkey.tcl:31
++msgid "No keys found."
++msgstr "Не са открити ключове."
+
- #: lib/blame.tcl:1275
- msgid "In File:"
- msgstr "Във файл:"
++#: lib/sshkey.tcl:34
++#, tcl-format
++msgid "Found a public key in: %s"
++msgstr "Открит е публичен ключ в „%s“"
+
- #: lib/blame.tcl:1280
- msgid "Copied Or Moved Here By:"
- msgstr "Копирано или преместено тук от:"
++#: lib/sshkey.tcl:40
++msgid "Generate Key"
++msgstr "Генериране на ключ"
+
- #: lib/index.tcl:6
- msgid "Unable to unlock the index."
- msgstr "Индексът не може да бъде отключен."
++#: lib/sshkey.tcl:58
++msgid "Copy To Clipboard"
++msgstr "Копиране към системния буфер"
+
- #: lib/index.tcl:17
- msgid "Index Error"
- msgstr "Грешка в индекса"
++#: lib/sshkey.tcl:72
++msgid "Your OpenSSH Public Key"
++msgstr "Публичният ви ключ за OpenSSH"
+
- #: lib/index.tcl:19
++#: lib/sshkey.tcl:80
++msgid "Generating..."
++msgstr "Генериране…"
+
- "Updating the Git index failed. A rescan will be automatically started to "
- "resynchronize git-gui."
++#: lib/sshkey.tcl:86
++#, tcl-format
+msgid ""
- "Неуспешно обновяване на индекса на Git. Автоматично ще започне нова проверка "
- "за синхронизирането на git-gui."
++"Could not start ssh-keygen:\n"
++"\n"
++"%s"
+msgstr ""
- #: lib/index.tcl:30
- msgid "Continue"
- msgstr "Продължаване"
++"Програмата „ssh-keygen“ не може да бъде стартирана:\n"
++"\n"
++"%s"
+
- #: lib/index.tcl:33
- msgid "Unlock Index"
- msgstr "Отключване на индекса"
++#: lib/sshkey.tcl:113
++msgid "Generation failed."
++msgstr "Неуспешно генериране."
+
- #: lib/index.tcl:298
++#: lib/sshkey.tcl:120
++msgid "Generation succeeded, but no keys found."
++msgstr "Генерирането завърши успешно, а не са намерени ключове."
+
- msgid "Unstaging %s from commit"
- msgstr "Изваждане на „%s“ от подаването"
++#: lib/sshkey.tcl:123
+#, tcl-format
- #: lib/index.tcl:337
- msgid "Ready to commit."
- msgstr "Готовност за подаване."
++msgid "Your key is in: %s"
++msgstr "Ключът ви е в „%s“"
+
- #: lib/index.tcl:350
++#: lib/status_bar.tcl:87
++#, tcl-format
++msgid "%s ... %*i of %*i %s (%3i%%)"
++msgstr "%s… %*i от общо %*i %s (%3i%%)"
+
- msgid "Adding %s"
- msgstr "Добавяне на „%s“"
++#: lib/tools.tcl:76
+#, tcl-format
- #: lib/index.tcl:380
++msgid "Running %s requires a selected file."
++msgstr "За изпълнението на „%s“ трябва да изберете файл."
+
- msgid "Stage %d untracked files?"
- msgstr "Да се вкарат ли %d неследени файла в индекса?"
++#: lib/tools.tcl:92
+#, tcl-format
- #: lib/index.tcl:428
++msgid "Are you sure you want to run %1$s on file \"%2$s\"?"
++msgstr "Сигурни ли сте, че искате да изпълните „%1$s“ върху файла „%2$s“?"
+
- msgid "Revert changes in file %s?"
- msgstr "Да се махнат ли промените във файла „%s“?"
++#: lib/tools.tcl:96
+#, tcl-format
- #: lib/index.tcl:430
++msgid "Are you sure you want to run %s?"
++msgstr "Сигурни ли сте, че искате да изпълните „%s“?"
+
- msgid "Revert changes in these %i files?"
- msgstr "Да се махнат ли промените в тези %i файла?"
++#: lib/tools.tcl:118
+#, tcl-format
- #: lib/index.tcl:438
- msgid "Any unstaged changes will be permanently lost by the revert."
++msgid "Tool: %s"
++msgstr "Команда: %s"
+
- "Всички промени, които не са били вкарани в индекса, ще бъдат безвъзвратно "
- "загубени."
++#: lib/tools.tcl:119
++#, tcl-format
++msgid "Running: %s"
++msgstr "Изпълнение: %s"
++
++#: lib/tools.tcl:158
++#, tcl-format
++msgid "Tool completed successfully: %s"
++msgstr "Командата завърши успешно: %s"
++
++#: lib/tools.tcl:160
++#, tcl-format
++msgid "Tool failed: %s"
++msgstr "Командата върна грешка: %s"
++
++#: lib/tools_dlg.tcl:22
++#, tcl-format
++msgid "%s (%s): Add Tool"
++msgstr "%s (%s): Добавяне на команда"
++
++#: lib/tools_dlg.tcl:28
++msgid "Add New Tool Command"
++msgstr "Добавяне на команда"
++
++#: lib/tools_dlg.tcl:34
++msgid "Add globally"
++msgstr "Глобално добавяне"
++
++#: lib/tools_dlg.tcl:46
++msgid "Tool Details"
++msgstr "Подробности за командата"
++
++#: lib/tools_dlg.tcl:49
++msgid "Use '/' separators to create a submenu tree:"
++msgstr "За създаване на подменюта използвайте знака „/“ за разделител:"
++
++#: lib/tools_dlg.tcl:60
++msgid "Command:"
++msgstr "Команда:"
++
++#: lib/tools_dlg.tcl:71
++msgid "Show a dialog before running"
++msgstr "Преди изпълнение да се извежда диалогов прозорец"
++
++#: lib/tools_dlg.tcl:77
++msgid "Ask the user to select a revision (sets $REVISION)"
++msgstr "Потребителят да укаже версия (задаване на променливата $REVISION)"
++
++#: lib/tools_dlg.tcl:82
++msgid "Ask the user for additional arguments (sets $ARGS)"
+msgstr ""
- #: lib/index.tcl:441
- msgid "Do Nothing"
- msgstr "Нищо да не се прави"
++"Потребителят да укаже допълнителни аргументи (задаване на променливата $ARGS)"
+
- #: lib/index.tcl:459
- msgid "Reverting selected files"
- msgstr "Махане на промените в избраните файлове"
++#: lib/tools_dlg.tcl:89
++msgid "Don't show the command output window"
++msgstr "Без показване на прозорец с изхода от командата"
++
++#: lib/tools_dlg.tcl:94
++msgid "Run only if a diff is selected ($FILENAME not empty)"
++msgstr ""
++"Стартиране само след избор на разлика (променливата $FILENAME не е празна)"
+
- #: lib/index.tcl:463
++#: lib/tools_dlg.tcl:118
++msgid "Please supply a name for the tool."
++msgstr "Задайте име за командата."
+
- msgid "Reverting %s"
- msgstr "Махане на промените в „%s“"
++#: lib/tools_dlg.tcl:126
+#, tcl-format
- #: lib/date.tcl:25
++msgid "Tool '%s' already exists."
++msgstr "Командата „%s“ вече съществува."
+
- msgid "Invalid date from Git: %s"
- msgstr "Неправилни данни от Git: %s"
-
- #: lib/database.tcl:42
- msgid "Number of loose objects"
- msgstr "Брой непакетирани обекти"
++#: lib/tools_dlg.tcl:148
+#, tcl-format
- #: lib/database.tcl:43
- msgid "Disk space used by loose objects"
- msgstr "Дисково пространство заето от непакетирани обекти"
++msgid ""
++"Could not add tool:\n"
++"%s"
++msgstr ""
++"Командата не може да бъде добавена:\n"
++"%s"
+
- #: lib/database.tcl:44
- msgid "Number of packed objects"
- msgstr "Брой пакетирани обекти"
++#: lib/tools_dlg.tcl:187
++#, tcl-format
++msgid "%s (%s): Remove Tool"
++msgstr "%s (%s): Премахване на команда"
+
- #: lib/database.tcl:45
- msgid "Number of packs"
- msgstr "Брой пакети"
++#: lib/tools_dlg.tcl:193
++msgid "Remove Tool Commands"
++msgstr "Премахване на команди"
+
- #: lib/database.tcl:46
- msgid "Disk space used by packed objects"
- msgstr "Дисково пространство заето от пакетирани обекти"
++#: lib/tools_dlg.tcl:198
++msgid "Remove"
++msgstr "Премахване"
+
- #: lib/database.tcl:47
- msgid "Packed objects waiting for pruning"
- msgstr "Пакетирани обекти за окастряне"
++#: lib/tools_dlg.tcl:231
++msgid "(Blue denotes repository-local tools)"
++msgstr "(командите към локалното хранилище са обозначени в синьо)"
+
- #: lib/database.tcl:48
- msgid "Garbage files"
- msgstr "Файлове за боклука"
++#: lib/tools_dlg.tcl:283
++#, tcl-format
++msgid "%s (%s):"
++msgstr "%s (%s):"
+
- #: lib/database.tcl:72
- msgid "Compressing the object database"
- msgstr "Компресиране на базата с данни за обектите"
++#: lib/tools_dlg.tcl:292
++#, tcl-format
++msgid "Run Command: %s"
++msgstr "Изпълнение на командата „%s“"
+
- #: lib/database.tcl:83
- msgid "Verifying the object database with fsck-objects"
- msgstr "Проверка на базата с данни за обектите с програмата „fsck-objects“"
++#: lib/tools_dlg.tcl:306
++msgid "Arguments"
++msgstr "Аргументи"
+
- #: lib/database.tcl:107
++#: lib/tools_dlg.tcl:341
++msgid "OK"
++msgstr "Добре"
+
- msgid ""
- "This repository currently has approximately %i loose objects.\n"
- "\n"
- "To maintain optimal performance it is strongly recommended that you compress "
- "the database.\n"
- "\n"
- "Compress the database now?"
- msgstr ""
- "В това хранилище в момента има към %i непакетирани обекти.\n"
- "\n"
- "За добра производителност се препоръчва да компресирате базата с данни за "
- "обектите.\n"
- "\n"
- "Да се започне ли компресирането?"
++#: lib/transport.tcl:7
+#, tcl-format
- #: lib/error.tcl:20 lib/error.tcl:116
- msgid "error"
- msgstr "грешка"
++msgid "Fetching new changes from %s"
++msgstr "Доставяне на промените от „%s“"
+
- #: lib/error.tcl:36
- msgid "warning"
- msgstr "предупреждение"
++#: lib/transport.tcl:18
++#, tcl-format
++msgid "remote prune %s"
++msgstr "окастряне на следящите клони към „%s“"
+
- #: lib/error.tcl:96
- msgid "You must correct the above errors before committing."
- msgstr "Преди да можете да подадете, коригирайте горните грешки."
++#: lib/transport.tcl:19
++#, tcl-format
++msgid "Pruning tracking branches deleted from %s"
++msgstr "Окастряне на следящите клони на изтритите клони от „%s“"
+
- #: lib/merge.tcl:13
- msgid ""
- "Cannot merge while amending.\n"
- "\n"
- "You must finish amending this commit before starting any type of merge.\n"
- msgstr ""
- "По време на поправяне не може да сливане.\n"
- "\n"
- "Трябва да завършите поправянето на текущото подаване, преди да започнете "
- "сливане.\n"
++#: lib/transport.tcl:25
++msgid "fetch all remotes"
++msgstr "доставяне от всички отдалечени"
+
- #: lib/merge.tcl:27
- msgid ""
- "Last scanned state does not match repository state.\n"
- "\n"
- "Another Git program has modified this repository since the last scan. A "
- "rescan must be performed before a merge can be performed.\n"
- "\n"
- "The rescan will be automatically started now.\n"
- msgstr ""
- "Последно установеното състояние не отговаря на това в хранилището.\n"
- "\n"
- "Някой друг процес за Git е променил хранилището междувременно. Състоянието "
- "трябва да бъде проверено, преди да се извърши сливане.\n"
- "\n"
- "Автоматично ще започне нова проверка.\n"
- "\n"
++#: lib/transport.tcl:26
++msgid "Fetching new changes from all remotes"
++msgstr "Доставяне на промените от всички отдалечени хранилища"
+
- #: lib/merge.tcl:45
- #, tcl-format
- msgid ""
- "You are in the middle of a conflicted merge.\n"
- "\n"
- "File %s has merge conflicts.\n"
- "\n"
- "You must resolve them, stage the file, and commit to complete the current "
- "merge. Only then can you begin another merge.\n"
++#: lib/transport.tcl:40
++msgid "remote prune all remotes"
++msgstr "окастряне на следящите изтрити"
+
- "В момента тече сливане, но има конфликти.\n"
- "\n"
- "Погледнете файла „%s“.\n"
- "\n"
- "Трябва да коригирате конфликтите в него, да го добавите към индекса и да "
- "завършите текущото сливане чрез подаване. Чак тогава може да започнете ново "
- "сливане.\n"
++#: lib/transport.tcl:41
++msgid "Pruning tracking branches deleted from all remotes"
+msgstr ""
- #: lib/merge.tcl:55
++"Окастряне на следящите клони на изтритите клони от всички отдалечени "
++"хранилища"
+
- msgid ""
- "You are in the middle of a change.\n"
- "\n"
- "File %s is modified.\n"
- "\n"
- "You should complete the current commit before starting a merge. Doing so "
- "will help you abort a failed merge, should the need arise.\n"
- msgstr ""
- "В момента тече подаване.\n"
- "\n"
- "Файлът „%s“ е променен.\n"
- "\n"
- "Трябва да завършите текущото подаване, преди да започнете сливане. Така ще "
- "можете лесно да преустановите сливането, ако възникне нужда.\n"
++#: lib/transport.tcl:55
+#, tcl-format
- #: lib/merge.tcl:108
++msgid "Pushing changes to %s"
++msgstr "Изтласкване на промените към „%s“"
+
- msgid "%s of %s"
- msgstr "%s от общо %s"
++#: lib/transport.tcl:93
+#, tcl-format
- #: lib/merge.tcl:122
++msgid "Mirroring to %s"
++msgstr "Изтласкване на всичко към „%s“"
+
- msgid "Merging %s and %s..."
- msgstr "Сливане на „%s“ и „%s“…"
-
- #: lib/merge.tcl:133
- msgid "Merge completed successfully."
- msgstr "Сливането завърши успешно."
-
- #: lib/merge.tcl:135
- msgid "Merge failed. Conflict resolution is required."
- msgstr "Неуспешно сливане — има конфликти за коригиране."
++#: lib/transport.tcl:111
+#, tcl-format
- #: lib/merge.tcl:160
- #, tcl-format
- msgid "Merge Into %s"
- msgstr "Сливане в „%s“"
++msgid "Pushing %s %s to %s"
++msgstr "Изтласкване на %s „%s“ към „%s“"
+
- #: lib/merge.tcl:179
- msgid "Revision To Merge"
- msgstr "Версия за сливане"
++#: lib/transport.tcl:132
++msgid "Push Branches"
++msgstr "Клони за изтласкване"
+
- #: lib/merge.tcl:214
- msgid ""
- "Cannot abort while amending.\n"
- "\n"
- "You must finish amending this commit.\n"
- msgstr ""
- "Поправянето не може да бъде преустановено.\n"
- "\n"
- "Трябва да завършите поправката на това подаване.\n"
++#: lib/transport.tcl:147
++msgid "Source Branches"
++msgstr "Клони-източници"
+
- #: lib/merge.tcl:224
- msgid ""
- "Abort merge?\n"
- "\n"
- "Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
- "\n"
- "Continue with aborting the current merge?"
- msgstr ""
- "Да се преустанови ли сливането?\n"
- "\n"
- "В такъв случай ●ВСИЧКИ● неподадени промени ще бъдат безвъзвратно загубени.\n"
- "\n"
- "Наистина ли да се преустанови сливането?"
++#: lib/transport.tcl:162
++msgid "Destination Repository"
++msgstr "Целево хранилище"
+
- #: lib/merge.tcl:230
- msgid ""
- "Reset changes?\n"
- "\n"
- "Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
- "\n"
- "Continue with resetting the current changes?"
++#: lib/transport.tcl:205
++msgid "Transfer Options"
++msgstr "Настройки при пренасянето"
+
- "Да се занулят ли промените?\n"
- "\n"
- "В такъв случай ●ВСИЧКИ● неподадени промени ще бъдат безвъзвратно загубени.\n"
- "\n"
- "Наистина ли да се занулят промените?"
-
- #: lib/merge.tcl:241
- msgid "Aborting"
- msgstr "Преустановяване"
++#: lib/transport.tcl:207
++msgid "Force overwrite existing branch (may discard changes)"
+msgstr ""
- #: lib/merge.tcl:241
- msgid "files reset"
- msgstr "файла със занулени промени"
++"Изрично презаписване на съществуващ клон (някои промени може да бъдат "
++"загубени)"
+
- #: lib/merge.tcl:269
- msgid "Abort failed."
- msgstr "Неуспешно преустановяване."
++#: lib/transport.tcl:211
++msgid "Use thin pack (for slow network connections)"
++msgstr "Максимална компресия (за бавни мрежови връзки)"
+
- #: lib/merge.tcl:271
- msgid "Abort completed. Ready."
- msgstr "Успешно преустановяване. Готовност за следващо действие."
++#: lib/transport.tcl:215
++msgid "Include tags"
++msgstr "Включване на етикетите"
+
++#: lib/transport.tcl:229
++#, tcl-format
++msgid "%s (%s): Push"
++msgstr "%s (%s): Изтласкване"
--- /dev/null
- # Irina Riesen <irina.riesen@gmail.com>, 2007.
- #
+# Translation of git-gui to russian
+# Copyright (C) 2007 Shawn Pearce
+# This file is distributed under the same license as the git-gui package.
- "Project-Id-Version: git-gui\n"
++# Translators:
++# Dimitriy Ryazantcev <DJm00n@mail.ru>, 2015-2016
++# Irina Riesen <irina.riesen@gmail.com>, 2007
+msgid ""
+msgstr ""
- "PO-Revision-Date: 2007-10-22 22:30-0200\n"
- "Last-Translator: Alex Riesen <raa.lkml@gmail.com>\n"
- "Language-Team: Russian Translation <git@vger.kernel.org>\n"
++"Project-Id-Version: Git Russian Localization Project\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2010-01-26 15:47-0800\n"
- msgstr ""
- "Невозможно определить версию Git\n"
- "\n"
- "%s указывает на версию '%s'.\n"
- "\n"
- "для %s требуется версия Git, начиная с 1.5.0\n"
- "\n"
- "Принять '%s' как версию 1.5.0?\n"
++"PO-Revision-Date: 2016-06-30 12:39+0000\n"
++"Last-Translator: Dimitriy Ryazantcev <DJm00n@mail.ru>\n"
++"Language-Team: Russian (http://www.transifex.com/djm00n/git-po-ru/language/ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
++"Language: ru\n"
++"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);\n"
+
+#: git-gui.sh:41 git-gui.sh:793 git-gui.sh:807 git-gui.sh:820 git-gui.sh:903
+#: git-gui.sh:922
+msgid "git-gui: fatal error"
+msgstr "git-gui: критическая ошибка"
+
+#: git-gui.sh:743
+#, tcl-format
+msgid "Invalid font specified in %s:"
+msgstr "В %s установлен неверный шрифт:"
+
+#: git-gui.sh:779
+msgid "Main Font"
+msgstr "Шрифт интерфейса"
+
+#: git-gui.sh:780
+msgid "Diff/Console Font"
+msgstr "Шрифт консоли и изменений (diff)"
+
+#: git-gui.sh:794
+msgid "Cannot find git in PATH."
+msgstr "git не найден в PATH."
+
+#: git-gui.sh:821
+msgid "Cannot parse Git version string:"
+msgstr "Невозможно распознать строку версии Git: "
+
+#: git-gui.sh:839
+#, tcl-format
+msgid ""
+"Git version cannot be determined.\n"
+"\n"
+"%s claims it is version '%s'.\n"
+"\n"
+"%s requires at least Git 1.5.0 or later.\n"
+"\n"
+"Assume '%s' is version 1.5.0?\n"
- msgstr "Обновление информации о состоянии файлов..."
++msgstr "Невозможно определить версию Git\n\n%s указывает на версию «%s».\n\nдля %s требуется версия Git, начиная с 1.5.0\n\nПредположить, что «%s» и есть версия 1.5.0?\n"
+
+#: git-gui.sh:1128
+msgid "Git directory not found:"
+msgstr "Каталог Git не найден:"
+
+#: git-gui.sh:1146
+msgid "Cannot move to top of working directory:"
+msgstr "Невозможно перейти к корню рабочего каталога репозитория: "
+
+#: git-gui.sh:1154
+msgid "Cannot use bare repository:"
+msgstr "Невозможно использование репозитория без рабочего каталога:"
+
+#: git-gui.sh:1162
+msgid "No working directory"
+msgstr "Отсутствует рабочий каталог"
+
+#: git-gui.sh:1334 lib/checkout_op.tcl:306
+msgid "Refreshing file status..."
- msgstr "Поиск измененных файлов..."
++msgstr "Обновление информации о состоянии файлов…"
+
+#: git-gui.sh:1390
+msgid "Scanning for modified files ..."
- msgstr "Вызов программы поддержки репозитория prepare-commit-msg..."
++msgstr "Поиск измененных файлов…"
+
+#: git-gui.sh:1454
+msgid "Calling prepare-commit-msg hook..."
- msgstr ""
- "Сохранение прервано программой поддержки репозитория prepare-commit-msg"
++msgstr "Вызов перехватчика prepare-commit-msg…"
+
+#: git-gui.sh:1471
+msgid "Commit declined by prepare-commit-msg hook."
- msgstr "Изменено, не подготовлено"
++msgstr "Коммит прерван перехватчиком prepare-commit-msg."
+
+#: git-gui.sh:1629 lib/browser.tcl:246
+msgid "Ready."
+msgstr "Готово."
+
+#: git-gui.sh:1787
+#, tcl-format
+msgid "Displaying only %s of %s files."
+msgstr "Показано %s из %s файлов."
+
+#: git-gui.sh:1913
+msgid "Unmodified"
+msgstr "Не изменено"
+
+#: git-gui.sh:1915
+msgid "Modified, not staged"
- msgstr "Подготовлено для сохранения"
++msgstr "Изменено, не в индексе"
+
+#: git-gui.sh:1916 git-gui.sh:1924
+msgid "Staged for commit"
- msgstr "Части, подготовленные для сохранения"
++msgstr "В индексе для коммита"
+
+#: git-gui.sh:1917 git-gui.sh:1925
+msgid "Portions staged for commit"
- msgstr "Подготовлено для сохранения, отсутствует"
++msgstr "Части, в индексе для коммита"
+
+#: git-gui.sh:1918 git-gui.sh:1926
+msgid "Staged for commit, missing"
- msgstr "Тип файла изменён, не подготовлено"
++msgstr "В индексе для коммита, отсутствует"
+
+#: git-gui.sh:1920
+msgid "File type changed, not staged"
- msgstr "Тип файла изменён, подготовлено"
++msgstr "Тип файла изменён, не в индексе"
+
+#: git-gui.sh:1921
+msgid "File type changed, staged"
- msgstr "Не отслеживается, не подготовлено"
++msgstr "Тип файла изменён, в индексе"
+
+#: git-gui.sh:1923
+msgid "Untracked, not staged"
- msgstr "Подготовлено для удаления"
++msgstr "Не отслеживается, не в индексе"
+
+#: git-gui.sh:1928
+msgid "Missing"
+msgstr "Отсутствует"
+
+#: git-gui.sh:1929
+msgid "Staged for removal"
- msgstr "Подготовлено для удаления, еще не удалено"
++msgstr "В индексе для удаления"
+
+#: git-gui.sh:1930
+msgid "Staged for removal, still present"
- msgstr "Запускается gitk... Подождите, пожалуйста..."
++msgstr "В индексе для удаления, еще не удалено"
+
+#: git-gui.sh:1932 git-gui.sh:1933 git-gui.sh:1934 git-gui.sh:1935
+#: git-gui.sh:1936 git-gui.sh:1937
+msgid "Requires merge resolution"
+msgstr "Требуется разрешение конфликта при слиянии"
+
+#: git-gui.sh:1972
+msgid "Starting gitk... please wait..."
- msgstr "Ветвь"
++msgstr "Запускается gitk… Подождите, пожалуйста…"
+
+#: git-gui.sh:1984
+msgid "Couldn't find gitk in PATH"
+msgstr "gitk не найден в PATH."
+
+#: git-gui.sh:2043
+msgid "Couldn't find git gui in PATH"
+msgstr "git gui не найден в PATH."
+
+#: git-gui.sh:2455 lib/choose_repository.tcl:36
+msgid "Repository"
+msgstr "Репозиторий"
+
+#: git-gui.sh:2456
+msgid "Edit"
+msgstr "Редактировать"
+
+#: git-gui.sh:2458 lib/choose_rev.tcl:561
+msgid "Branch"
- msgstr "Состояние"
++msgstr "Ветка"
+
+#: git-gui.sh:2461 lib/choose_rev.tcl:548
+msgid "Commit@@noun"
- msgstr "Просмотреть файлы текущей ветви"
++msgstr "Коммит"
+
+#: git-gui.sh:2464 lib/merge.tcl:121 lib/merge.tcl:150 lib/merge.tcl:168
+msgid "Merge"
+msgstr "Слияние"
+
+#: git-gui.sh:2465 lib/choose_rev.tcl:557
+msgid "Remote"
+msgstr "Внешние репозитории"
+
+#: git-gui.sh:2468
+msgid "Tools"
+msgstr "Вспомогательные операции"
+
+#: git-gui.sh:2477
+msgid "Explore Working Copy"
+msgstr "Просмотр рабочего каталога"
+
+#: git-gui.sh:2483
+msgid "Browse Current Branch's Files"
- msgstr "Показать файлы ветви..."
++msgstr "Просмотреть файлы текущей ветки"
+
+#: git-gui.sh:2487
+msgid "Browse Branch Files..."
- msgstr "Показать историю текущей ветви"
++msgstr "Показать файлы ветки…"
+
+#: git-gui.sh:2492
+msgid "Visualize Current Branch's History"
- msgstr "Показать историю всех ветвей"
++msgstr "Показать историю текущей ветки"
+
+#: git-gui.sh:2496
+msgid "Visualize All Branch History"
- msgstr "Показать файлы ветви %s"
++msgstr "Показать историю всех веток"
+
+#: git-gui.sh:2503
+#, tcl-format
+msgid "Browse %s's Files"
- msgstr "Показать историю ветви %s"
++msgstr "Показать файлы ветки %s"
+
+#: git-gui.sh:2505
+#, tcl-format
+msgid "Visualize %s's History"
- msgstr "Создать..."
++msgstr "Показать историю ветки %s"
+
+#: git-gui.sh:2510 lib/database.tcl:27 lib/database.tcl:67
+msgid "Database Statistics"
+msgstr "Статистика базы данных"
+
+#: git-gui.sh:2513 lib/database.tcl:34
+msgid "Compress Database"
+msgstr "Сжать базу данных"
+
+#: git-gui.sh:2516
+msgid "Verify Database"
+msgstr "Проверить базу данных"
+
+#: git-gui.sh:2523 git-gui.sh:2527 git-gui.sh:2531 lib/shortcut.tcl:8
+#: lib/shortcut.tcl:40 lib/shortcut.tcl:72
+msgid "Create Desktop Icon"
+msgstr "Создать ярлык на рабочем столе"
+
+#: git-gui.sh:2539 lib/choose_repository.tcl:183 lib/choose_repository.tcl:191
+msgid "Quit"
+msgstr "Выход"
+
+#: git-gui.sh:2547
+msgid "Undo"
+msgstr "Отменить"
+
+#: git-gui.sh:2550
+msgid "Redo"
+msgstr "Повторить"
+
+#: git-gui.sh:2554 git-gui.sh:3109
+msgid "Cut"
+msgstr "Вырезать"
+
+#: git-gui.sh:2557 git-gui.sh:3112 git-gui.sh:3186 git-gui.sh:3259
+#: lib/console.tcl:69
+msgid "Copy"
+msgstr "Копировать"
+
+#: git-gui.sh:2560 git-gui.sh:3115
+msgid "Paste"
+msgstr "Вставить"
+
+#: git-gui.sh:2563 git-gui.sh:3118 lib/branch_delete.tcl:26
+#: lib/remote_branch_delete.tcl:38
+msgid "Delete"
+msgstr "Удалить"
+
+#: git-gui.sh:2567 git-gui.sh:3122 git-gui.sh:3263 lib/console.tcl:71
+msgid "Select All"
+msgstr "Выделить все"
+
+#: git-gui.sh:2576
+msgid "Create..."
- msgstr "Перейти..."
++msgstr "Создать…"
+
+#: git-gui.sh:2582
+msgid "Checkout..."
- msgstr "Переименовать..."
++msgstr "Перейти…"
+
+#: git-gui.sh:2588
+msgid "Rename..."
- msgstr "Удалить..."
++msgstr "Переименовать…"
+
+#: git-gui.sh:2593
+msgid "Delete..."
- msgstr "Сбросить..."
++msgstr "Удалить…"
+
+#: git-gui.sh:2598
+msgid "Reset..."
- msgstr "Сохранить"
++msgstr "Сбросить…"
+
+#: git-gui.sh:2608
+msgid "Done"
+msgstr "Завершено"
+
+#: git-gui.sh:2610
+msgid "Commit@@verb"
- msgstr "Новое состояние"
++msgstr "Закоммитить"
+
+#: git-gui.sh:2619 git-gui.sh:3050
+msgid "New Commit"
- msgstr "Исправить последнее состояние"
++msgstr "Новый коммит"
+
+#: git-gui.sh:2627 git-gui.sh:3057
+msgid "Amend Last Commit"
- msgstr "Подготовить для сохранения"
++msgstr "Исправить последний коммит"
+
+#: git-gui.sh:2637 git-gui.sh:3011 lib/remote_branch_delete.tcl:99
+msgid "Rescan"
+msgstr "Перечитать"
+
+#: git-gui.sh:2643
+msgid "Stage To Commit"
- msgstr "Подготовить измененные файлы для сохранения"
++msgstr "Добавить в индекс"
+
+#: git-gui.sh:2649
+msgid "Stage Changed Files To Commit"
- msgstr "Убрать из подготовленного"
++msgstr "Добавить изменённые файлы в индекс"
+
+#: git-gui.sh:2655
+msgid "Unstage From Commit"
- msgstr "Отменить изменения"
++msgstr "Убрать из издекса"
+
+#: git-gui.sh:2661 lib/index.tcl:412
+msgid "Revert Changes"
- msgstr "Локальное слияние..."
++msgstr "Обратить изменения"
+
+#: git-gui.sh:2669 git-gui.sh:3310 git-gui.sh:3341
+msgid "Show Less Context"
+msgstr "Меньше контекста"
+
+#: git-gui.sh:2673 git-gui.sh:3314 git-gui.sh:3345
+msgid "Show More Context"
+msgstr "Больше контекста"
+
+#: git-gui.sh:2680 git-gui.sh:3024 git-gui.sh:3133
+msgid "Sign Off"
+msgstr "Вставить Signed-off-by"
+
+#: git-gui.sh:2696
+msgid "Local Merge..."
- msgstr "Прервать слияние..."
++msgstr "Локальное слияние…"
+
+#: git-gui.sh:2701
+msgid "Abort Merge..."
- msgstr "Добавить..."
++msgstr "Прервать слияние…"
+
+#: git-gui.sh:2713 git-gui.sh:2741
+msgid "Add..."
- msgstr "Отправить..."
++msgstr "Добавить…"
+
+#: git-gui.sh:2717
+msgid "Push..."
- msgstr "Удалить ветвь..."
++msgstr "Отправить…"
+
+#: git-gui.sh:2721
+msgid "Delete Branch..."
- msgstr "Настройки..."
++msgstr "Удалить ветку…"
+
+#: git-gui.sh:2731 git-gui.sh:3292
+msgid "Options..."
- msgstr "Удалить..."
++msgstr "Настройки…"
+
+#: git-gui.sh:2742
+msgid "Remove..."
- msgstr "Текущая ветвь:"
++msgstr "Удалить…"
+
+#: git-gui.sh:2751 lib/choose_repository.tcl:50
+msgid "Help"
+msgstr "Помощь"
+
+#: git-gui.sh:2755 git-gui.sh:2759 lib/about.tcl:14
+#: lib/choose_repository.tcl:44 lib/choose_repository.tcl:53
+#, tcl-format
+msgid "About %s"
+msgstr "О %s"
+
+#: git-gui.sh:2783
+msgid "Online Documentation"
+msgstr "Документация в интернете"
+
+#: git-gui.sh:2786 lib/choose_repository.tcl:47 lib/choose_repository.tcl:56
+msgid "Show SSH Key"
+msgstr "Показать ключ SSH"
+
+#: git-gui.sh:2893
+#, tcl-format
+msgid "fatal: cannot stat path %s: No such file or directory"
+msgstr "критическая ошибка: %s: нет такого файла или каталога"
+
+#: git-gui.sh:2926
+msgid "Current Branch:"
- msgstr "Подготовлено (будет сохранено)"
++msgstr "Текущая ветка:"
+
+#: git-gui.sh:2947
+msgid "Staged Changes (Will Commit)"
- msgstr "Подготовить все"
++msgstr "Изменения в индексе (будут закоммичены)"
+
+#: git-gui.sh:2967
+msgid "Unstaged Changes"
+msgstr "Изменено (не будет сохранено)"
+
+#: git-gui.sh:3017
+msgid "Stage Changed"
- msgstr "Комментарий к первому состоянию:"
++msgstr "Индексировать всё"
+
+#: git-gui.sh:3036 lib/transport.tcl:104 lib/transport.tcl:193
+msgid "Push"
+msgstr "Отправить"
+
+#: git-gui.sh:3071
+msgid "Initial Commit Message:"
- msgstr "Комментарий к исправленному состоянию:"
++msgstr "Сообщение первого коммита:"
+
+#: git-gui.sh:3072
+msgid "Amended Commit Message:"
- msgstr "Комментарий к исправленному первоначальному состоянию:"
++msgstr "Сообщение исправленного коммита:"
+
+#: git-gui.sh:3073
+msgid "Amended Initial Commit Message:"
- msgstr "Комментарий к исправленному слиянию:"
++msgstr "Сообщение исправленного первого коммита:"
+
+#: git-gui.sh:3074
+msgid "Amended Merge Commit Message:"
- msgstr "Комментарий к слиянию:"
++msgstr "Сообщение исправленного слияния:"
+
+#: git-gui.sh:3075
+msgid "Merge Commit Message:"
- msgstr "Комментарий к состоянию:"
++msgstr "Сообщение слияния:"
+
+#: git-gui.sh:3076
+msgid "Commit Message:"
- msgstr "Отменить изменения"
++msgstr "Сообщение коммита:"
+
+#: git-gui.sh:3125 git-gui.sh:3267 lib/console.tcl:73
+msgid "Copy All"
+msgstr "Копировать все"
+
+#: git-gui.sh:3149 lib/blame.tcl:104
+msgid "File:"
+msgstr "Файл:"
+
+#: git-gui.sh:3255
+msgid "Refresh"
+msgstr "Обновить"
+
+#: git-gui.sh:3276
+msgid "Decrease Font Size"
+msgstr "Уменьшить размер шрифта"
+
+#: git-gui.sh:3280
+msgid "Increase Font Size"
+msgstr "Увеличить размер шрифта"
+
+#: git-gui.sh:3288 lib/blame.tcl:281
+msgid "Encoding"
+msgstr "Кодировка"
+
+#: git-gui.sh:3299
+msgid "Apply/Reverse Hunk"
+msgstr "Применить/Убрать изменение"
+
+#: git-gui.sh:3304
+msgid "Apply/Reverse Line"
+msgstr "Применить/Убрать строку"
+
+#: git-gui.sh:3323
+msgid "Run Merge Tool"
+msgstr "Запустить программу слияния"
+
+#: git-gui.sh:3328
+msgid "Use Remote Version"
+msgstr "Взять внешнюю версию"
+
+#: git-gui.sh:3332
+msgid "Use Local Version"
+msgstr "Взять локальную версию"
+
+#: git-gui.sh:3336
+msgid "Revert To Base"
- msgstr ""
++msgstr "Обратить изменения"
+
+#: git-gui.sh:3354
+msgid "Visualize These Changes In The Submodule"
- msgstr "Показать историю текущей ветви подмодуля"
++msgstr "Показать эти изменения подмодуля"
+
+#: git-gui.sh:3358
+msgid "Visualize Current Branch History In The Submodule"
- msgstr "Показать историю всех ветвей подмодуля"
++msgstr "Показать историю текущей ветки подмодуля"
+
+#: git-gui.sh:3362
+msgid "Visualize All Branch History In The Submodule"
- msgstr ""
++msgstr "Показать историю всех веток подмодуля"
+
+#: git-gui.sh:3367
+msgid "Start git gui In The Submodule"
- msgstr "Не сохранять часть"
++msgstr "Запустить git gui в подмодуле"
+
+#: git-gui.sh:3389
+msgid "Unstage Hunk From Commit"
- msgstr "Убрать строки из подготовленного"
++msgstr "Убрать блок из индекса"
+
+#: git-gui.sh:3391
+msgid "Unstage Lines From Commit"
- msgstr "Убрать строку из подготовленного"
++msgstr "Убрать строки из индекса"
+
+#: git-gui.sh:3393
+msgid "Unstage Line From Commit"
- msgstr "Подготовить часть для сохранения"
++msgstr "Убрать строку из индекса"
+
+#: git-gui.sh:3396
+msgid "Stage Hunk For Commit"
- msgstr "Подготовить строки для сохранения"
++msgstr "Добавить блок в индекс"
+
+#: git-gui.sh:3398
+msgid "Stage Lines For Commit"
- msgstr "Подготовить строку для сохранения"
++msgstr "Добавить строки в индекс"
+
+#: git-gui.sh:3400
+msgid "Stage Line For Commit"
- msgstr "Инициализация..."
++msgstr "Добавить строку в индекс"
+
+#: git-gui.sh:3424
+msgid "Initializing..."
- msgstr ""
- "Возможны ошибки в переменных окружения.\n"
- "\n"
- "Переменные окружения, которые возможно\n"
- "будут проигнорированы командами Git,\n"
- "запущенными из %s\n"
- "\n"
++msgstr "Инициализация…"
+
+#: git-gui.sh:3541
+#, tcl-format
+msgid ""
+"Possible environment issues exist.\n"
+"\n"
+"The following environment variables are probably\n"
+"going to be ignored by any Git subprocess run\n"
+"by %s:\n"
+"\n"
- msgstr ""
- "\n"
- "Это известная проблема с Tcl,\n"
- "распространяемым Cygwin."
++msgstr "Возможны ошибки в переменных окружения.\n\nПеременные окружения, которые возможно\nбудут проигнорированы командами Git,\nзапущенными из %s\n\n"
+
+#: git-gui.sh:3570
+msgid ""
+"\n"
+"This is due to a known issue with the\n"
+"Tcl binary distributed by Cygwin."
- msgstr ""
- "\n"
- "\n"
- "Вместо использования %s можно\n"
- "сохранить значения user.name и\n"
- "user.email в Вашем персональном\n"
- "файле ~/.gitconfig.\n"
++msgstr "\nЭто известная проблема с Tcl,\nраспространяемым Cygwin."
+
+#: git-gui.sh:3575
+#, tcl-format
+msgid ""
+"\n"
+"\n"
+"A good replacement for %s\n"
+"is placing values for the user.name and\n"
+"user.email settings into your personal\n"
+"~/.gitconfig file.\n"
- msgstr "Сохраненное состояние:"
++msgstr "\n\nВместо использования %s можно\nсохранить значения user.name и\nuser.email в Вашем персональном\nфайле ~/.gitconfig.\n"
+
+#: lib/about.tcl:26
+msgid "git-gui - a graphical user interface for Git."
+msgstr "git-gui - графический пользовательский интерфейс к Git."
+
+#: lib/blame.tcl:72
+msgid "File Viewer"
+msgstr "Просмотр файла"
+
+#: lib/blame.tcl:78
+msgid "Commit:"
- msgstr "Скопировать SHA-1"
++msgstr "Коммит:"
+
+#: lib/blame.tcl:271
+msgid "Copy Commit"
- msgstr "Найти текст..."
++msgstr "Копировать SHA-1"
+
+#: lib/blame.tcl:275
+msgid "Find Text..."
- msgstr "Рассмотреть состояние предка"
++msgstr "Найти текст…"
+
+#: lib/blame.tcl:284
+msgid "Do Full Copy Detection"
+msgstr "Провести полный поиск копий"
+
+#: lib/blame.tcl:288
+msgid "Show History Context"
+msgstr "Показать исторический контекст"
+
+#: lib/blame.tcl:291
+msgid "Blame Parent Commit"
- msgstr "Чтение %s..."
++msgstr "Авторы родительского коммита"
+
+#: lib/blame.tcl:450
+#, tcl-format
+msgid "Reading %s..."
- msgstr "Загрузка аннотации копирований/переименований..."
++msgstr "Чтение %s…"
+
+#: lib/blame.tcl:557
+msgid "Loading copy/move tracking annotations..."
- msgstr "Загрузка аннотаций первоначального положения объекта..."
++msgstr "Загрузка аннотации копирований/переименований…"
+
+#: lib/blame.tcl:577
+msgid "lines annotated"
+msgstr "строк прокомментировано"
+
+#: lib/blame.tcl:769
+msgid "Loading original location annotations..."
- msgstr "Выполнение полного поиска копий..."
++msgstr "Загрузка аннотаций первоначального положения объекта…"
+
+#: lib/blame.tcl:772
+msgid "Annotation complete."
+msgstr "Аннотация завершена."
+
+#: lib/blame.tcl:802
+msgid "Busy"
+msgstr "Занят"
+
+#: lib/blame.tcl:803
+msgid "Annotation process is already running."
+msgstr "Аннотация уже запущена"
+
+#: lib/blame.tcl:842
+msgid "Running thorough copy detection..."
- msgstr "Загрузка аннотации..."
++msgstr "Выполнение полного поиска копий…"
+
+#: lib/blame.tcl:910
+msgid "Loading annotation..."
- msgstr "Сохранил:"
++msgstr "Загрузка аннотации…"
+
+#: lib/blame.tcl:963
+msgid "Author:"
+msgstr "Автор:"
+
+#: lib/blame.tcl:967
+msgid "Committer:"
- msgstr "Невозможно найти текущее состояние:"
++msgstr "Коммитер:"
+
+#: lib/blame.tcl:972
+msgid "Original File:"
+msgstr "Исходный файл:"
+
+#: lib/blame.tcl:1020
+msgid "Cannot find HEAD commit:"
- msgstr "Невозможно найти состояние предка:"
++msgstr "Не удалось найти текущее состояние:"
+
+#: lib/blame.tcl:1075
+msgid "Cannot find parent commit:"
- msgstr "Перейти на ветвь"
++msgstr "Не удалось найти родительское состояние:"
+
+#: lib/blame.tcl:1090
+msgid "Unable to display parent"
+msgstr "Не могу показать предка"
+
+#: lib/blame.tcl:1091 lib/diff.tcl:320
+msgid "Error loading diff:"
+msgstr "Ошибка загрузки изменений:"
+
+#: lib/blame.tcl:1231
+msgid "Originally By:"
+msgstr "Источник:"
+
+#: lib/blame.tcl:1237
+msgid "In File:"
+msgstr "Файл:"
+
+#: lib/blame.tcl:1242
+msgid "Copied Or Moved Here By:"
+msgstr "Скопировано/перемещено в:"
+
+#: lib/branch_checkout.tcl:14 lib/branch_checkout.tcl:19
+msgid "Checkout Branch"
- msgstr "Получить изменения из внешней ветви"
++msgstr "Перейти на ветку"
+
+#: lib/branch_checkout.tcl:23
+msgid "Checkout"
+msgstr "Перейти"
+
+#: lib/branch_checkout.tcl:27 lib/branch_create.tcl:35
+#: lib/branch_delete.tcl:32 lib/branch_rename.tcl:30 lib/browser.tcl:282
+#: lib/checkout_op.tcl:579 lib/choose_font.tcl:43 lib/merge.tcl:172
+#: lib/option.tcl:125 lib/remote_add.tcl:32 lib/remote_branch_delete.tcl:42
+#: lib/tools_dlg.tcl:40 lib/tools_dlg.tcl:204 lib/tools_dlg.tcl:352
+#: lib/transport.tcl:108
+msgid "Cancel"
+msgstr "Отмена"
+
+#: lib/branch_checkout.tcl:32 lib/browser.tcl:287 lib/tools_dlg.tcl:328
+msgid "Revision"
+msgstr "Версия"
+
+#: lib/branch_checkout.tcl:36 lib/branch_create.tcl:69 lib/option.tcl:280
+msgid "Options"
+msgstr "Настройки"
+
+#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:92
+msgid "Fetch Tracking Branch"
- msgstr "Отсоединить от локальной ветви"
++msgstr "Извлечь изменения из внешней ветки"
+
+#: lib/branch_checkout.tcl:44
+msgid "Detach From Local Branch"
- msgstr "Создание ветви"
++msgstr "Отсоединить от локальной ветки"
+
+#: lib/branch_create.tcl:22
+msgid "Create Branch"
- msgstr "Создать новую ветвь"
++msgstr "Создать ветку"
+
+#: lib/branch_create.tcl:27
+msgid "Create New Branch"
- msgstr "Название ветви"
++msgstr "Создать новую ветку"
+
+#: lib/branch_create.tcl:31 lib/choose_repository.tcl:381
+msgid "Create"
+msgstr "Создать"
+
+#: lib/branch_create.tcl:40
+msgid "Branch Name"
- msgstr "Взять из имен ветвей слежения"
++msgstr "Имя ветки"
+
+#: lib/branch_create.tcl:43 lib/remote_add.tcl:39 lib/tools_dlg.tcl:50
+msgid "Name:"
+msgstr "Название:"
+
+#: lib/branch_create.tcl:58
+msgid "Match Tracking Branch Name"
- msgstr "Обновить имеющуюся ветвь:"
++msgstr "Соответствовать имени отслеживаемой ветки"
+
+#: lib/branch_create.tcl:66
+msgid "Starting Revision"
+msgstr "Начальная версия"
+
+#: lib/branch_create.tcl:72
+msgid "Update Existing Branch:"
- msgstr "Укажите ветвь слежения."
++msgstr "Обновить имеющуюся ветку:"
+
+#: lib/branch_create.tcl:75
+msgid "No"
+msgstr "Нет"
+
+#: lib/branch_create.tcl:80
+msgid "Fast Forward Only"
+msgstr "Только Fast Forward"
+
+#: lib/branch_create.tcl:85 lib/checkout_op.tcl:571
+msgid "Reset"
+msgstr "Сброс"
+
+#: lib/branch_create.tcl:97
+msgid "Checkout After Creation"
+msgstr "После создания сделать текущей"
+
+#: lib/branch_create.tcl:131
+msgid "Please select a tracking branch."
- msgstr "Ветвь слежения %s не является ветвью во внешнем репозитории."
++msgstr "Укажите отлеживаемую ветку."
+
+#: lib/branch_create.tcl:140
+#, tcl-format
+msgid "Tracking branch %s is not a branch in the remote repository."
- msgstr "Укажите название ветви."
++msgstr "Отслеживаемая ветка %s не является веткой на внешнем репозитории."
+
+#: lib/branch_create.tcl:153 lib/branch_rename.tcl:86
+msgid "Please supply a branch name."
- msgstr "Недопустимое название ветви '%s'."
++msgstr "Укажите имя ветки."
+
+#: lib/branch_create.tcl:164 lib/branch_rename.tcl:106
+#, tcl-format
+msgid "'%s' is not an acceptable branch name."
- msgstr "Удаление ветви"
++msgstr "Недопустимое имя ветки «%s»."
+
+#: lib/branch_delete.tcl:15
+msgid "Delete Branch"
- msgstr "Удалить локальную ветвь"
++msgstr "Удаление ветки"
+
+#: lib/branch_delete.tcl:20
+msgid "Delete Local Branch"
- msgstr "Локальные ветви"
++msgstr "Удалить локальную ветку"
+
+#: lib/branch_delete.tcl:37
+msgid "Local Branches"
- msgstr "Ветви, которые не полностью сливаются с %s:"
++msgstr "Локальные ветки"
+
+#: lib/branch_delete.tcl:52
+msgid "Delete Only If Merged Into"
+msgstr "Удалить только в случае, если было слияние с"
+
+#: lib/branch_delete.tcl:54 lib/remote_branch_delete.tcl:119
+msgid "Always (Do not perform merge checks)"
+msgstr "Всегда (не выполнять проверку на слияние)"
+
+#: lib/branch_delete.tcl:103
+#, tcl-format
+msgid "The following branches are not completely merged into %s:"
- msgstr ""
- "Восстановить удаленные ветви сложно.\n"
- "\n"
- "Продолжить?"
++msgstr "Ветки, которые не полностью сливаются с %s:"
+
+#: lib/branch_delete.tcl:115 lib/remote_branch_delete.tcl:217
+msgid ""
+"Recovering deleted branches is difficult.\n"
+"\n"
+"Delete the selected branches?"
- msgstr ""
- "Не удалось удалить ветви:\n"
- "%s"
++msgstr "Восстановить удаленные ветки сложно.\n\nПродолжить?"
+
+#: lib/branch_delete.tcl:141
+#, tcl-format
+msgid ""
+"Failed to delete branches:\n"
+"%s"
- msgstr "Переименование ветви"
++msgstr "Не удалось удалить ветки:\n%s"
+
+#: lib/branch_rename.tcl:14 lib/branch_rename.tcl:22
+msgid "Rename Branch"
- msgstr "Ветвь:"
++msgstr "Переименование ветки"
+
+#: lib/branch_rename.tcl:26
+msgid "Rename"
+msgstr "Переименовать"
+
+#: lib/branch_rename.tcl:36
+msgid "Branch:"
- msgstr "Укажите ветвь для переименования."
++msgstr "Ветка:"
+
+#: lib/branch_rename.tcl:39
+msgid "New Name:"
+msgstr "Новое название:"
+
+#: lib/branch_rename.tcl:75
+msgid "Please select a branch to rename."
- msgstr "Ветвь '%s' уже существует."
++msgstr "Укажите ветку для переименования."
+
+#: lib/branch_rename.tcl:96 lib/checkout_op.tcl:202
+#, tcl-format
+msgid "Branch '%s' already exists."
- msgstr "Не удалось переименовать '%s'. "
++msgstr "Ветка «%s» уже существует."
+
+#: lib/branch_rename.tcl:117
+#, tcl-format
+msgid "Failed to rename '%s'."
- msgstr "Запуск..."
++msgstr "Не удалось переименовать «%s». "
+
+#: lib/browser.tcl:17
+msgid "Starting..."
- msgstr "Загрузка %s..."
++msgstr "Запуск…"
+
+#: lib/browser.tcl:26
+msgid "File Browser"
+msgstr "Просмотр списка файлов"
+
+#: lib/browser.tcl:126 lib/browser.tcl:143
+#, tcl-format
+msgid "Loading %s..."
- msgstr "Показать файлы ветви"
++msgstr "Загрузка %s…"
+
+#: lib/browser.tcl:187
+msgid "[Up To Parent]"
+msgstr "[На уровень выше]"
+
+#: lib/browser.tcl:267 lib/browser.tcl:273
+msgid "Browse Branch Files"
- msgstr "Получение %s из %s "
++msgstr "Показать файлы ветки"
+
+#: lib/browser.tcl:278 lib/choose_repository.tcl:398
+#: lib/choose_repository.tcl:486 lib/choose_repository.tcl:497
+#: lib/choose_repository.tcl:1028
+msgid "Browse"
+msgstr "Показать"
+
+#: lib/checkout_op.tcl:85
+#, tcl-format
+msgid "Fetching %s from %s"
- msgstr "Ветвь '%s' не существует "
++msgstr "Извлечение %s из %s "
+
+#: lib/checkout_op.tcl:133
+#, tcl-format
+msgid "fatal: Cannot resolve %s"
+msgstr "критическая ошибка: невозможно разрешить %s"
+
+#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:31
+#: lib/sshkey.tcl:53
+msgid "Close"
+msgstr "Закрыть"
+
+#: lib/checkout_op.tcl:175
+#, tcl-format
+msgid "Branch '%s' does not exist."
- msgstr "Ошибка создания упрощённой конфигурации git pull для '%s'."
++msgstr "Ветка «%s» не существует."
+
+#: lib/checkout_op.tcl:194
+#, tcl-format
+msgid "Failed to configure simplified git-pull for '%s'."
- msgstr ""
- "Ветвь '%s' уже существует.\n"
- "\n"
- "Она не может быть прокручена(fast-forward) к %s.\n"
- "Требуется слияние."
++msgstr "Ошибка создания упрощённой конфигурации git pull для «%s»."
+
+#: lib/checkout_op.tcl:229
+#, tcl-format
+msgid ""
+"Branch '%s' already exists.\n"
+"\n"
+"It cannot fast-forward to %s.\n"
+"A merge is required."
- msgstr "Неизвестная стратегия слияния: '%s'."
++msgstr "Ветка «%s» уже существует.\n\nОна не может быть перемотана вперед к %s.\nТребуется слияние."
+
+#: lib/checkout_op.tcl:243
+#, tcl-format
+msgid "Merge strategy '%s' not supported."
- msgstr "Не удалось обновить '%s'."
++msgstr "Неизвестная стратегия слияния «%s»."
+
+#: lib/checkout_op.tcl:262
+#, tcl-format
+msgid "Failed to update '%s'."
- "Another Git program has modified this repository since the last scan. A "
- "rescan must be performed before the current branch can be changed.\n"
++msgstr "Не удалось обновить «%s»."
+
+#: lib/checkout_op.tcl:274
+msgid "Staging area (index) is already locked."
+msgstr "Рабочая область заблокирована другим процессом."
+
+#: lib/checkout_op.tcl:289
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
- msgstr ""
- "Последнее прочитанное состояние репозитория не соответствует текущему.\n"
- "\n"
- "С момента последней проверки репозиторий был изменен другой программой Git. "
- "Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь.\n"
- "\n"
- "Это будет сделано сейчас автоматически.\n"
++"Another Git program has modified this repository since the last scan. A rescan must be performed before the current branch can be changed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
- msgstr "Обновление рабочего каталога из '%s'..."
++msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем текущая ветка может быть изменена.\n\nЭто будет сделано сейчас автоматически.\n"
+
+#: lib/checkout_op.tcl:345
+#, tcl-format
+msgid "Updating working directory to '%s'..."
- msgstr "Прерван переход на '%s' (требуется слияние содержания файлов)"
++msgstr "Обновление рабочего каталога из «%s»…"
+
+#: lib/checkout_op.tcl:346
+msgid "files checked out"
+msgstr "файлы извлечены"
+
+#: lib/checkout_op.tcl:376
+#, tcl-format
+msgid "Aborted checkout of '%s' (file level merging is required)."
- msgstr "Ветвь '%s' остается текущей."
++msgstr "Прерван переход на «%s» (требуется слияние содержимого файлов)"
+
+#: lib/checkout_op.tcl:377
+msgid "File level merge required."
+msgstr "Требуется слияние содержания файлов."
+
+#: lib/checkout_op.tcl:381
+#, tcl-format
+msgid "Staying on branch '%s'."
- "If you wanted to be on a branch, create one now starting from 'This Detached "
- "Checkout'."
- msgstr ""
- "Вы находитесь не в локальной ветви.\n"
- "\n"
- "Если вы хотите снова вернуться к какой-нибудь ветви, создайте ее сейчас, "
- "начиная с 'Текущего отсоединенного состояния'."
++msgstr "Ветка «%s» остаётся текущей."
+
+#: lib/checkout_op.tcl:452
+msgid ""
+"You are no longer on a local branch.\n"
+"\n"
- msgstr "Ветвь '%s' сделана текущей."
++"If you wanted to be on a branch, create one now starting from 'This Detached Checkout'."
++msgstr "Вы более не находитесь на локальной ветке.\n\nЕсли вы хотите снова вернуться к какой-нибудь ветке, создайте её сейчас, начиная с «Текущего отсоединенного состояния»."
+
+#: lib/checkout_op.tcl:503 lib/checkout_op.tcl:507
+#, tcl-format
+msgid "Checked out '%s'."
- msgstr "Сброс '%s' в '%s' приведет к потере следующих сохраненных состояний: "
++msgstr "Выполнен переход на «%s»."
+
+#: lib/checkout_op.tcl:535
+#, tcl-format
+msgid "Resetting '%s' to '%s' will lose the following commits:"
- msgstr "Восстановить потерянные сохраненные состояния будет сложно."
++msgstr "Сброс «%s» на «%s» приведет к потере следующих коммитов:"
+
+#: lib/checkout_op.tcl:557
+msgid "Recovering lost commits may not be easy."
- msgstr "Сбросить '%s'?"
++msgstr "Восстановить потерянные коммиты будет сложно."
+
+#: lib/checkout_op.tcl:562
+#, tcl-format
+msgid "Reset '%s'?"
- "This working directory is only partially switched. We successfully updated "
- "your files, but failed to update an internal Git file.\n"
++msgstr "Сбросить «%s»?"
+
+#: lib/checkout_op.tcl:567 lib/merge.tcl:164 lib/tools_dlg.tcl:343
+msgid "Visualize"
+msgstr "Наглядно"
+
+#: lib/checkout_op.tcl:635
+#, tcl-format
+msgid ""
+"Failed to set current branch.\n"
+"\n"
- msgstr ""
- "Не удалось установить текущую ветвь.\n"
- "\n"
- "Ваш рабочий каталог обновлен только частично. Были обновлены все файлы кроме "
- "служебных файлов Git. \n"
- "\n"
- "Этого не должно было произойти. %s завершается."
++"This working directory is only partially switched. We successfully updated your files, but failed to update an internal Git file.\n"
+"\n"
+"This should not have occurred. %s will now close and give up."
- msgstr ""
- "Это пример текста.\n"
- "Если Вам нравится этот текст, это может быть Ваш шрифт."
++msgstr "Не удалось установить текущую ветку.\n\nВаш рабочий каталог обновлён только частично. Были обновлены все файлы кроме служебных файлов Git. \n\nЭтого не должно было произойти. %s завершается."
+
+#: lib/choose_font.tcl:39
+msgid "Select"
+msgstr "Выбрать"
+
+#: lib/choose_font.tcl:53
+msgid "Font Family"
+msgstr "Шрифт"
+
+#: lib/choose_font.tcl:74
+msgid "Font Size"
+msgstr "Размер шрифта"
+
+#: lib/choose_font.tcl:91
+msgid "Font Example"
+msgstr "Пример текста"
+
+#: lib/choose_font.tcl:103
+msgid ""
+"This is example text.\n"
+"If you like this text, it can be your font."
- msgstr "Новый..."
++msgstr "Это пример текста.\nЕсли Вам нравится этот текст, это может быть Ваш шрифт."
+
+#: lib/choose_repository.tcl:28
+msgid "Git Gui"
+msgstr "Git Gui"
+
+#: lib/choose_repository.tcl:87 lib/choose_repository.tcl:386
+msgid "Create New Repository"
+msgstr "Создать новый репозиторий"
+
+#: lib/choose_repository.tcl:93
+msgid "New..."
- msgstr "Склонировать..."
++msgstr "Новый…"
+
+#: lib/choose_repository.tcl:100 lib/choose_repository.tcl:471
+msgid "Clone Existing Repository"
+msgstr "Склонировать существующий репозиторий"
+
+#: lib/choose_repository.tcl:106
+msgid "Clone..."
- msgstr "Открыть..."
++msgstr "Клонировать…"
+
+#: lib/choose_repository.tcl:113 lib/choose_repository.tcl:1016
+msgid "Open Existing Repository"
+msgstr "Выбрать существующий репозиторий"
+
+#: lib/choose_repository.tcl:119
+msgid "Open..."
- msgstr "Стандартный (Быстрый, полуизбыточный, \"жесткие\" ссылки)"
++msgstr "Открыть…"
+
+#: lib/choose_repository.tcl:132
+msgid "Recent Repositories"
+msgstr "Недавние репозитории"
+
+#: lib/choose_repository.tcl:138
+msgid "Open Recent Repository:"
+msgstr "Открыть последний репозиторий"
+
+#: lib/choose_repository.tcl:306 lib/choose_repository.tcl:313
+#: lib/choose_repository.tcl:320
+#, tcl-format
+msgid "Failed to create repository %s:"
+msgstr "Не удалось создать репозиторий %s:"
+
+#: lib/choose_repository.tcl:391
+msgid "Directory:"
+msgstr "Каталог:"
+
+#: lib/choose_repository.tcl:423 lib/choose_repository.tcl:550
+#: lib/choose_repository.tcl:1052
+msgid "Git Repository"
+msgstr "Репозиторий"
+
+#: lib/choose_repository.tcl:448
+#, tcl-format
+msgid "Directory %s already exists."
+msgstr "Каталог '%s' уже существует."
+
+#: lib/choose_repository.tcl:452
+#, tcl-format
+msgid "File %s already exists."
+msgstr "Файл '%s' уже существует."
+
+#: lib/choose_repository.tcl:466
+msgid "Clone"
+msgstr "Склонировать"
+
+#: lib/choose_repository.tcl:479
+msgid "Source Location:"
+msgstr "Исходное положение:"
+
+#: lib/choose_repository.tcl:490
+msgid "Target Directory:"
+msgstr "Каталог назначения:"
+
+#: lib/choose_repository.tcl:502
+msgid "Clone Type:"
+msgstr "Тип клона:"
+
+#: lib/choose_repository.tcl:508
+msgid "Standard (Fast, Semi-Redundant, Hardlinks)"
- msgstr ""
++msgstr "Стандартный (Быстрый, полуизбыточный, «жесткие» ссылки)"
+
+#: lib/choose_repository.tcl:514
+msgid "Full Copy (Slower, Redundant Backup)"
+msgstr "Полная копия (Медленный, создает резервную копию)"
+
+#: lib/choose_repository.tcl:520
+msgid "Shared (Fastest, Not Recommended, No Backup)"
+msgstr "Общий (Самый быстрый, не рекомендуется, без резервной копии)"
+
+#: lib/choose_repository.tcl:556 lib/choose_repository.tcl:603
+#: lib/choose_repository.tcl:749 lib/choose_repository.tcl:819
+#: lib/choose_repository.tcl:1058 lib/choose_repository.tcl:1066
+#, tcl-format
+msgid "Not a Git repository: %s"
+msgstr "Каталог не является репозиторием: %s"
+
+#: lib/choose_repository.tcl:592
+msgid "Standard only available for local repository."
+msgstr "Стандартный клон возможен только для локального репозитория."
+
+#: lib/choose_repository.tcl:596
+msgid "Shared only available for local repository."
+msgstr "Общий клон возможен только для локального репозитория."
+
+#: lib/choose_repository.tcl:617
+#, tcl-format
+msgid "Location %s already exists."
+msgstr "Путь '%s' уже существует."
+
+#: lib/choose_repository.tcl:628
+msgid "Failed to configure origin"
+msgstr "Не могу сконфигурировать исходный репозиторий."
+
+#: lib/choose_repository.tcl:640
+msgid "Counting objects"
+msgstr "Считаю объекты"
+
+#: lib/choose_repository.tcl:641
+msgid "buckets"
- msgstr "Не инициализирована ветвь 'master'."
++msgstr "блоки"
+
+#: lib/choose_repository.tcl:665
+#, tcl-format
+msgid "Unable to copy objects/info/alternates: %s"
+msgstr "Не могу скопировать objects/info/alternates: %s"
+
+#: lib/choose_repository.tcl:701
+#, tcl-format
+msgid "Nothing to clone from %s."
+msgstr "Нечего клонировать с %s."
+
+#: lib/choose_repository.tcl:703 lib/choose_repository.tcl:917
+#: lib/choose_repository.tcl:929
+msgid "The 'master' branch has not been initialized."
- msgstr "\"Жесткие ссылки\" недоступны. Будет использовано копирование."
++msgstr "Не инициализирована ветвь «master»."
+
+#: lib/choose_repository.tcl:716
+msgid "Hardlinks are unavailable. Falling back to copying."
- msgstr "Не могу \"жестко связать\" объект: %s"
++msgstr "«Жесткие ссылки» недоступны. Будет использовано копирование."
+
+#: lib/choose_repository.tcl:728
+#, tcl-format
+msgid "Cloning from %s"
+msgstr "Клонирование %s"
+
+#: lib/choose_repository.tcl:759
+msgid "Copying objects"
+msgstr "Копирование objects"
+
+#: lib/choose_repository.tcl:760
+msgid "KiB"
+msgstr "КБ"
+
+#: lib/choose_repository.tcl:784
+#, tcl-format
+msgid "Unable to copy object: %s"
+msgstr "Не могу скопировать объект: %s"
+
+#: lib/choose_repository.tcl:794
+msgid "Linking objects"
+msgstr "Создание ссылок на objects"
+
+#: lib/choose_repository.tcl:795
+msgid "objects"
+msgstr "объекты"
+
+#: lib/choose_repository.tcl:803
+#, tcl-format
+msgid "Unable to hardlink object: %s"
- msgstr ""
- "Не могу получить ветви и объекты. Дополнительная информация на консоли."
++msgstr "Не могу создать «жесткую ссылку» на объект: %s"
+
+#: lib/choose_repository.tcl:858
+msgid "Cannot fetch branches and objects. See console output for details."
- msgstr "Не могу получить метки. Дополнительная информация на консоли."
++msgstr "Не удалось извлечь ветки и объекты. Дополнительная информация на консоли."
+
+#: lib/choose_repository.tcl:869
+msgid "Cannot fetch tags. See console output for details."
- msgstr "Не было получено ветви по умолчанию."
++msgstr "Не удалось извлечь метки. Дополнительная информация на консоли."
+
+#: lib/choose_repository.tcl:893
+msgid "Cannot determine HEAD. See console output for details."
+msgstr "Не могу определить HEAD. Дополнительная информация на консоли."
+
+#: lib/choose_repository.tcl:902
+#, tcl-format
+msgid "Unable to cleanup %s"
+msgstr "Не могу очистить %s"
+
+#: lib/choose_repository.tcl:908
+msgid "Clone failed."
+msgstr "Клонирование не удалось."
+
+#: lib/choose_repository.tcl:915
+msgid "No default branch obtained."
- msgstr "Не могу распознать %s как состояние."
++msgstr "Ветка по умолчанию не была получена."
+
+#: lib/choose_repository.tcl:926
+#, tcl-format
+msgid "Cannot resolve %s as a commit."
- msgstr "Локальная ветвь:"
++msgstr "Не могу распознать %s как коммит."
+
+#: lib/choose_repository.tcl:938
+msgid "Creating working directory"
+msgstr "Создаю рабочий каталог"
+
+#: lib/choose_repository.tcl:939 lib/index.tcl:67 lib/index.tcl:130
+#: lib/index.tcl:198
+msgid "files"
+msgstr "файлов"
+
+#: lib/choose_repository.tcl:968
+msgid "Initial file checkout failed."
+msgstr "Не удалось получить начальное состояние файлов репозитория."
+
+#: lib/choose_repository.tcl:1011
+msgid "Open"
+msgstr "Открыть"
+
+#: lib/choose_repository.tcl:1021
+msgid "Repository:"
+msgstr "Репозиторий:"
+
+#: lib/choose_repository.tcl:1072
+#, tcl-format
+msgid "Failed to open repository %s:"
+msgstr "Не удалось открыть репозиторий %s:"
+
+#: lib/choose_rev.tcl:53
+msgid "This Detached Checkout"
+msgstr "Текущее отсоединенное состояние"
+
+#: lib/choose_rev.tcl:60
+msgid "Revision Expression:"
+msgstr "Выражение для определения версии:"
+
+#: lib/choose_rev.tcl:74
+msgid "Local Branch"
- msgstr "Ветвь слежения"
++msgstr "Локальная ветка:"
+
+#: lib/choose_rev.tcl:79
+msgid "Tracking Branch"
- "You are about to create the initial commit. There is no commit before this "
- "to amend.\n"
- msgstr ""
- "Отсутствует состояние для исправления.\n"
- "\n"
- "Вы создаете первое состояние в репозитории, здесь еще нечего исправлять.\n"
++msgstr "Отслеживаемая ветка"
+
+#: lib/choose_rev.tcl:84 lib/choose_rev.tcl:538
+msgid "Tag"
+msgstr "Метка"
+
+#: lib/choose_rev.tcl:317
+#, tcl-format
+msgid "Invalid revision: %s"
+msgstr "Неверная версия: %s"
+
+#: lib/choose_rev.tcl:338
+msgid "No revision selected."
+msgstr "Версия не указана."
+
+#: lib/choose_rev.tcl:346
+msgid "Revision expression is empty."
+msgstr "Пустое выражение для определения версии."
+
+#: lib/choose_rev.tcl:531
+msgid "Updated"
+msgstr "Обновлено"
+
+#: lib/choose_rev.tcl:559
+msgid "URL"
+msgstr "Ссылка"
+
+#: lib/commit.tcl:9
+msgid ""
+"There is nothing to amend.\n"
+"\n"
- "You are currently in the middle of a merge that has not been fully "
- "completed. You cannot amend the prior commit unless you first abort the "
- "current merge activity.\n"
- msgstr ""
- "Невозможно исправить состояние во время операции слияния.\n"
- "\n"
- "Текущее слияние не завершено. Невозможно исправить предыдущее сохраненное "
- "состояние, не прерывая эту операцию.\n"
++"You are about to create the initial commit. There is no commit before this to amend.\n"
++msgstr "Отсутствует коммиты для исправления.\n\nВы создаете начальный коммит, здесь еще нечего исправлять.\n"
+
+#: lib/commit.tcl:18
+msgid ""
+"Cannot amend while merging.\n"
+"\n"
- msgstr "Ошибка при загрузке данных для исправления сохраненного состояния:"
++"You are currently in the middle of a merge that has not been fully completed. You cannot amend the prior commit unless you first abort the current merge activity.\n"
++msgstr "Невозможно исправить коммит во время слияния.\n\nТекущее слияние не завершено. Невозможно исправить предыдуий коммит, не прерывая эту операцию.\n"
+
+#: lib/commit.tcl:48
+msgid "Error loading commit data for amend:"
- msgstr "Неверный GIT_COMMITTER_IDENT:"
++msgstr "Ошибка при загрузке данных для исправления коммита:"
+
+#: lib/commit.tcl:75
+msgid "Unable to obtain your identity:"
+msgstr "Невозможно получить информацию об авторстве:"
+
+#: lib/commit.tcl:80
+msgid "Invalid GIT_COMMITTER_IDENT:"
- msgstr "предупреждение: Tcl не поддерживает кодировку '%s'."
++msgstr "Недопустимый GIT_COMMITTER_IDENT:"
+
+#: lib/commit.tcl:129
+#, tcl-format
+msgid "warning: Tcl does not support encoding '%s'."
- "Another Git program has modified this repository since the last scan. A "
- "rescan must be performed before another commit can be created.\n"
++msgstr "предупреждение: Tcl не поддерживает кодировку «%s»."
+
+#: lib/commit.tcl:149
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
- msgstr ""
- "Последнее прочитанное состояние репозитория не соответствует текущему.\n"
- "\n"
- "С момента последней проверки репозиторий был изменен другой программой Git. "
- "Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь. \n"
- "\n"
- "Это будет сделано сейчас автоматически.\n"
++"Another Git program has modified this repository since the last scan. A rescan must be performed before another commit can be created.\n"
+"\n"
+"The rescan will be automatically started now.\n"
- "File %s has merge conflicts. You must resolve them and stage the file "
- "before committing.\n"
- msgstr ""
- "Нельзя сохранить файлы с незавершённой операцией слияния.\n"
- "\n"
- "Для файла %s возник конфликт слияния. Разрешите конфликт и добавьте к "
- "подготовленным файлам перед сохранением.\n"
++msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь. \n\nЭто будет сделано сейчас автоматически.\n"
+
+#: lib/commit.tcl:172
+#, tcl-format
+msgid ""
+"Unmerged files cannot be committed.\n"
+"\n"
- msgstr ""
- "Обнаружено неизвестное состояние файла %s.\n"
- "\n"
- "Файл %s не может быть сохранен данной программой.\n"
++"File %s has merge conflicts. You must resolve them and stage the file before committing.\n"
++msgstr "Нельзя выполнить коммит с незавершённой операцией слияния.\n\nДля файла %s возник конфликт слияния. Разрешите конфликт и добавьте их в индекс перед выполнением коммита.\n"
+
+#: lib/commit.tcl:180
+#, tcl-format
+msgid ""
+"Unknown file state %s detected.\n"
+"\n"
+"File %s cannot be committed by this program.\n"
- msgstr ""
- "Отсутствуют изменения для сохранения.\n"
- "\n"
- "Подготовьте хотя бы один файл до создания сохраненного состояния.\n"
++msgstr "Обнаружено неизвестное состояние файла %s.\n\nФайл %s не может быть закоммичен этой программой.\n"
+
+#: lib/commit.tcl:188
+msgid ""
+"No changes to commit.\n"
+"\n"
+"You must stage at least 1 file before you can commit.\n"
- msgstr ""
- "Напишите комментарий к сохраненному состоянию.\n"
- "\n"
- "Рекомендуется следующий формат комментария:\n"
- "\n"
- "- первая строка: краткое описание сделанных изменений.\n"
- "- вторая строка пустая\n"
- "- оставшиеся строки: опишите, что дают ваши изменения.\n"
++msgstr "Отсутствуют изменения для сохранения.\n\nДобавьте в индекс хотя бы один файл перед выполнением коммита.\n"
+
+#: lib/commit.tcl:203
+msgid ""
+"Please supply a commit message.\n"
+"\n"
+"A good commit message has the following format:\n"
+"\n"
+"- First line: Describe in one sentence what you did.\n"
+"- Second line: Blank\n"
+"- Remaining lines: Describe why this change is good.\n"
- msgstr "Вызов программы поддержки репозитория pre-commit..."
++msgstr "Укажите сообщение коммита.\n\nРекомендуется следующий формат сообщения:\n\n- в первой строке краткое описание сделанных изменений\n- вторая строка пустая\n- в оставшихся строках опишите, что дают ваши изменения\n"
+
+#: lib/commit.tcl:234
+msgid "Calling pre-commit hook..."
- msgstr "Сохранение прервано программой поддержки репозитория pre-commit"
++msgstr "Вызов перехватчика pre-commit…"
+
+#: lib/commit.tcl:249
+msgid "Commit declined by pre-commit hook."
- msgstr "Вызов программы поддержки репозитория commit-msg..."
++msgstr "Коммит прерван переватчиком pre-commit."
+
+#: lib/commit.tcl:272
+msgid "Calling commit-msg hook..."
- msgstr "Сохранение прервано программой поддержки репозитория commit-msg"
++msgstr "Вызов перехватчика commit-msg…"
+
+#: lib/commit.tcl:287
+msgid "Commit declined by commit-msg hook."
- msgstr "Сохранение изменений..."
++msgstr "Коммит прерван переватчиком commit-msg"
+
+#: lib/commit.tcl:300
+msgid "Committing changes..."
- msgstr "Сохранить состояние не удалось."
++msgstr "Коммит изменений…"
+
+#: lib/commit.tcl:316
+msgid "write-tree failed:"
+msgstr "Программа write-tree завершилась с ошибкой:"
+
+#: lib/commit.tcl:317 lib/commit.tcl:361 lib/commit.tcl:382
+msgid "Commit failed."
- msgstr "Состояние %s выглядит поврежденным"
++msgstr "Не удалось закоммитить изменения."
+
+#: lib/commit.tcl:334
+#, tcl-format
+msgid "Commit %s appears to be corrupt"
- msgstr ""
- "Отсутствуют изменения для сохранения.\n"
- "\n"
- "Ни один файл не был изменен и не было слияния.\n"
- "\n"
- "Сейчас автоматически запустится перечитывание репозитория.\n"
++msgstr "Коммит %s похоже поврежден"
+
+#: lib/commit.tcl:339
+msgid ""
+"No changes to commit.\n"
+"\n"
+"No files were modified by this commit and it was not a merge commit.\n"
+"\n"
+"A rescan will be automatically started now.\n"
- msgstr "Отсутствуют изменения для сохранения."
++msgstr "Нет изменения для коммита.\n\nНи один файл не был изменен и не было слияния.\n\nСейчас автоматически запустится перечитывание репозитория.\n"
+
+#: lib/commit.tcl:346
+msgid "No changes to commit."
- msgstr "Создано состояние %s: %s "
++msgstr "Нет изменения для коммита."
+
+#: lib/commit.tcl:360
+msgid "commit-tree failed:"
+msgstr "Программа commit-tree завершилась с ошибкой:"
+
+#: lib/commit.tcl:381
+msgid "update-ref failed:"
+msgstr "Программа update-ref завершилась с ошибкой:"
+
+#: lib/commit.tcl:469
+#, tcl-format
+msgid "Created commit %s: %s"
- msgstr "В процессе... пожалуйста, ждите..."
++msgstr "Создан коммит %s: %s "
+
+#: lib/console.tcl:59
+msgid "Working... please wait..."
- "To maintain optimal performance it is strongly recommended that you compress "
- "the database.\n"
++msgstr "В процессе… пожалуйста, ждите…"
+
+#: lib/console.tcl:186
+msgid "Success"
+msgstr "Процесс успешно завершен"
+
+#: lib/console.tcl:200
+msgid "Error: Command Failed"
+msgstr "Ошибка: не удалось выполнить команду"
+
+#: lib/database.tcl:43
+msgid "Number of loose objects"
+msgstr "Количество несвязанных объектов"
+
+#: lib/database.tcl:44
+msgid "Disk space used by loose objects"
+msgstr "Объем дискового пространства, занятый несвязанными объектами"
+
+#: lib/database.tcl:45
+msgid "Number of packed objects"
+msgstr "Количество упакованных объектов"
+
+#: lib/database.tcl:46
+msgid "Number of packs"
+msgstr "Количество pack-файлов"
+
+#: lib/database.tcl:47
+msgid "Disk space used by packed objects"
+msgstr "Объем дискового пространства, занятый упакованными объектами"
+
+#: lib/database.tcl:48
+msgid "Packed objects waiting for pruning"
+msgstr "Несвязанные объекты, которые можно удалить"
+
+#: lib/database.tcl:49
+msgid "Garbage files"
+msgstr "Мусор"
+
+#: lib/database.tcl:72
+msgid "Compressing the object database"
+msgstr "Сжатие базы объектов"
+
+#: lib/database.tcl:83
+msgid "Verifying the object database with fsck-objects"
+msgstr "Проверка базы объектов при помощи fsck"
+
+#: lib/database.tcl:107
+#, tcl-format
+msgid ""
+"This repository currently has approximately %i loose objects.\n"
+"\n"
- msgstr ""
- "Этот репозиторий сейчас содержит примерно %i свободных объектов\n"
- "\n"
- "Для лучшей производительности рекомендуется сжать базу данных.\n"
- "\n"
- "Сжать базу данных сейчас?"
++"To maintain optimal performance it is strongly recommended that you compress the database.\n"
+"\n"
+"Compress the database now?"
- "The modification date of this file was updated by another application, but "
- "the content within the file was not changed.\n"
- "\n"
- "A rescan will be automatically started to find other files which may have "
- "the same state."
- msgstr ""
- "Изменений не обнаружено.\n"
++msgstr "Этот репозиторий сейчас содержит примерно %i свободных объектов\n\nДля лучшей производительности рекомендуется сжать базу данных.\n\nСжать базу данных сейчас?"
+
+#: lib/date.tcl:25
+#, tcl-format
+msgid "Invalid date from Git: %s"
+msgstr "Неправильная дата в репозитории: %s"
+
+#: lib/diff.tcl:64
+#, tcl-format
+msgid ""
+"No differences detected.\n"
+"\n"
+"%s has no changes.\n"
+"\n"
- "в %s отсутствуют изменения.\n"
- "\n"
- "Дата изменения файла была обновлена другой программой, но содержимое файла "
- "осталось прежним.\n"
- "\n"
- "Сейчас будет запущено перечитывание репозитория, чтобы найти подобные файлы."
++"The modification date of this file was updated by another application, but the content within the file was not changed.\n"
+"\n"
- msgstr "Загрузка изменений в %s..."
++"A rescan will be automatically started to find other files which may have the same state."
++msgstr "Изменений не обнаружено.\n\nв %s отсутствуют изменения.\n\nДата изменения файла была обновлена другой программой, но содержимое файла осталось прежним.\n\nСейчас будет запущено перечитывание репозитория, чтобы найти подобные файлы."
+
+#: lib/diff.tcl:104
+#, tcl-format
+msgid "Loading diff of %s..."
- msgstr ""
- "ЛОКАЛЬНО: удалён\n"
- "ВНЕШНИЙ:\n"
++msgstr "Загрузка изменений %s…"
+
+#: lib/diff.tcl:125
+msgid ""
+"LOCAL: deleted\n"
+"REMOTE:\n"
- msgstr ""
- "ВНЕШНИЙ: удалён\n"
- "ЛОКАЛЬНО:\n"
++msgstr "ЛОКАЛЬНО: удалён\nВНЕШНИЙ:\n"
+
+#: lib/diff.tcl:130
+msgid ""
+"REMOTE: deleted\n"
+"LOCAL:\n"
- msgstr ""
- "* Размер неподготовленного файла %d байт.\n"
- "* Показано первых %d байт.\n"
++msgstr "ВНЕШНИЙ: удалён\nЛОКАЛЬНО:\n"
+
+#: lib/diff.tcl:137
+msgid "LOCAL:\n"
+msgstr "ЛОКАЛЬНО:\n"
+
+#: lib/diff.tcl:140
+msgid "REMOTE:\n"
+msgstr "ВНЕШНИЙ:\n"
+
+#: lib/diff.tcl:202 lib/diff.tcl:319
+#, tcl-format
+msgid "Unable to display %s"
+msgstr "Не могу показать %s"
+
+#: lib/diff.tcl:203
+msgid "Error loading file:"
+msgstr "Ошибка загрузки файла:"
+
+#: lib/diff.tcl:210
+msgid "Git Repository (subproject)"
+msgstr "Репозиторий Git (подпроект)"
+
+#: lib/diff.tcl:222
+msgid "* Binary file (not showing content)."
+msgstr "* Двоичный файл (содержимое не показано)"
+
+#: lib/diff.tcl:227
+#, tcl-format
+msgid ""
+"* Untracked file is %d bytes.\n"
+"* Showing only first %d bytes.\n"
- msgstr ""
- "\n"
- "* Неподготовленный файл обрезан: %s.\n"
- "* Чтобы увидеть весь файл, используйте программу-редактор.\n"
++msgstr "* Размер неотслеживаемого файла %d байт.\n* Показано первых %d байт.\n"
+
+#: lib/diff.tcl:233
+#, tcl-format
+msgid ""
+"\n"
+"* Untracked file clipped here by %s.\n"
+"* To see the entire file, use an external editor.\n"
- msgstr "Не удалось подготовить к сохранению выбранную часть."
++msgstr "\n* Неотслеживаемый файл обрезан: %s.\n* Чтобы увидеть весь файл, используйте внешний редактор.\n"
+
+#: lib/diff.tcl:482
+msgid "Failed to unstage selected hunk."
+msgstr "Не удалось исключить выбранную часть."
+
+#: lib/diff.tcl:489
+msgid "Failed to stage selected hunk."
- msgstr "Не удалось подготовить к сохранению выбранную строку."
++msgstr "Не удалось проиндексировать выбранный блок изменений."
+
+#: lib/diff.tcl:568
+msgid "Failed to unstage selected line."
+msgstr "Не удалось исключить выбранную строку."
+
+#: lib/diff.tcl:576
+msgid "Failed to stage selected line."
- msgstr "Прежде чем сохранить, исправьте вышеуказанные ошибки."
++msgstr "Не удалось проиндексировать выбранную строку."
+
+#: lib/encoding.tcl:443
+msgid "Default"
+msgstr "По умолчанию"
+
+#: lib/encoding.tcl:448
+#, tcl-format
+msgid "System (%s)"
+msgstr "Системная (%s)"
+
+#: lib/encoding.tcl:459 lib/encoding.tcl:465
+msgid "Other"
+msgstr "Другая"
+
+#: lib/error.tcl:20 lib/error.tcl:114
+msgid "error"
+msgstr "ошибка"
+
+#: lib/error.tcl:36
+msgid "warning"
+msgstr "предупреждение"
+
+#: lib/error.tcl:94
+msgid "You must correct the above errors before committing."
- msgstr ""
- "Не удалось обновить индекс Git. Состояние репозитория будет перечитано "
- "автоматически."
++msgstr "Перед коммитом, исправьте вышеуказанные ошибки."
+
+#: lib/index.tcl:6
+msgid "Unable to unlock the index."
+msgstr "Не удалось разблокировать индекс"
+
+#: lib/index.tcl:15
+msgid "Index Error"
+msgstr "Ошибка в индексе"
+
+#: lib/index.tcl:17
+msgid ""
+"Updating the Git index failed. A rescan will be automatically started to "
+"resynchronize git-gui."
- msgstr "Удаление %s из подготовленного"
++msgstr "Не удалось обновить индекс Git. Состояние репозитория будет перечитано автоматически."
+
+#: lib/index.tcl:28
+msgid "Continue"
+msgstr "Продолжить"
+
+#: lib/index.tcl:31
+msgid "Unlock Index"
+msgstr "Разблокировать индекс"
+
+#: lib/index.tcl:289
+#, tcl-format
+msgid "Unstaging %s from commit"
- msgstr "Подготовлено для сохранения"
++msgstr "Удаление %s из индекса"
+
+#: lib/index.tcl:328
+msgid "Ready to commit."
- msgstr "Добавление %s..."
++msgstr "Готов для коммита."
+
+#: lib/index.tcl:341
+#, tcl-format
+msgid "Adding %s"
- msgstr "Отменить изменения в файле %s?"
++msgstr "Добавление %s…"
+
+#: lib/index.tcl:398
+#, tcl-format
+msgid "Revert changes in file %s?"
- msgstr "Отменить изменения в %i файле(-ах)?"
++msgstr "Обратить изменения в файле %s?"
+
+#: lib/index.tcl:400
+#, tcl-format
+msgid "Revert changes in these %i files?"
- msgstr ""
- "Любые изменения, не подготовленные к сохранению, будут потеряны при данной "
- "операции."
++msgstr "Обратить изменения в %i файле(-ах)?"
+
+#: lib/index.tcl:408
+msgid "Any unstaged changes will be permanently lost by the revert."
- msgstr "Удаление изменений в выбранных файлах"
++msgstr "Любые непроиндексированные изменения, будут потеряны при обращении изменений."
+
+#: lib/index.tcl:411
+msgid "Do Nothing"
+msgstr "Ничего не делать"
+
+#: lib/index.tcl:429
+msgid "Reverting selected files"
- msgstr "Отмена изменений в %s"
++msgstr "Обращение изменений в выбранных файлах"
+
+#: lib/index.tcl:433
+#, tcl-format
+msgid "Reverting %s"
- msgstr ""
- "Невозможно выполнить слияние во время исправления.\n"
- "\n"
- "Завершите исправление данного состояния перед выполнением операции слияния.\n"
++msgstr "Обращение изменений в %s"
+
+#: lib/merge.tcl:13
+msgid ""
+"Cannot merge while amending.\n"
+"\n"
+"You must finish amending this commit before starting any type of merge.\n"
- "Another Git program has modified this repository since the last scan. A "
- "rescan must be performed before a merge can be performed.\n"
++msgstr "Невозможно выполнить слияние во время исправления.\n\nЗавершите исправление данного коммита перед выполнением операции слияния.\n"
+
+#: lib/merge.tcl:27
+msgid ""
+"Last scanned state does not match repository state.\n"
+"\n"
- msgstr ""
- "Последнее прочитанное состояние репозитория не соответствует текущему.\n"
- "\n"
- "С момента последней проверки репозиторий был изменен другой программой Git. "
- "Необходимо перечитать репозиторий, прежде чем изменять текущую ветвь.\n"
- "\n"
- "Это будет сделано сейчас автоматически.\n"
++"Another Git program has modified this repository since the last scan. A rescan must be performed before a merge can be performed.\n"
+"\n"
+"The rescan will be automatically started now.\n"
- "You must resolve them, stage the file, and commit to complete the current "
- "merge. Only then can you begin another merge.\n"
- msgstr ""
- "Предыдущее слияние не завершено из-за конфликта.\n"
- "\n"
- "Для файла %s возник конфликт слияния.\n"
- "\n"
- "Разрешите конфликт, подготовьте файл и сохраните. Только после этого можно "
- "начать следующее слияние.\n"
++msgstr "Последнее прочитанное состояние репозитория не соответствует текущему.\n\nС момента последней проверки репозиторий был изменен другой программой Git. Необходимо перечитать репозиторий, прежде чем слияние может быть сделано.\n\nЭто будет сделано сейчас автоматически.\n"
+
+#: lib/merge.tcl:45
+#, tcl-format
+msgid ""
+"You are in the middle of a conflicted merge.\n"
+"\n"
+"File %s has merge conflicts.\n"
+"\n"
- "You should complete the current commit before starting a merge. Doing so "
- "will help you abort a failed merge, should the need arise.\n"
- msgstr ""
- "Изменения не сохранены.\n"
- "\n"
- "Файл %s изменен.\n"
- "\n"
- "Подготовьте и сохраните изменения перед началом слияния. В случае "
- "необходимости это позволит прервать операцию слияния.\n"
++"You must resolve them, stage the file, and commit to complete the current merge. Only then can you begin another merge.\n"
++msgstr "Предыдущее слияние не завершено из-за конфликта.\n\nДля файла %s возник конфликт слияния.\n\nРазрешите конфликт, добавьте файл в индекс и закоммитьте. Только после этого можно начать следующее слияние.\n"
+
+#: lib/merge.tcl:55
+#, tcl-format
+msgid ""
+"You are in the middle of a change.\n"
+"\n"
+"File %s is modified.\n"
+"\n"
- msgstr "Слияние %s и %s..."
++"You should complete the current commit before starting a merge. Doing so will help you abort a failed merge, should the need arise.\n"
++msgstr "Вы находитесь в процессе изменений.\n\nФайл %s изменён.\n\nВы должны завершить текущий коммит перед началом слияния. В случае необходимости, это позволит прервать операцию слияния.\n"
+
+#: lib/merge.tcl:107
+#, tcl-format
+msgid "%s of %s"
+msgstr "%s из %s"
+
+#: lib/merge.tcl:120
+#, tcl-format
+msgid "Merging %s and %s..."
- msgstr ""
- "Невозможно прервать исправление.\n"
- "\n"
- "Завершите текущее исправление сохраненного состояния.\n"
++msgstr "Слияние %s и %s…"
+
+#: lib/merge.tcl:131
+msgid "Merge completed successfully."
+msgstr "Слияние успешно завершено."
+
+#: lib/merge.tcl:133
+msgid "Merge failed. Conflict resolution is required."
+msgstr "Не удалось завершить слияние. Требуется разрешение конфликта."
+
+#: lib/merge.tcl:158
+#, tcl-format
+msgid "Merge Into %s"
+msgstr "Слияние с %s"
+
+#: lib/merge.tcl:177
+msgid "Revision To Merge"
+msgstr "Версия, с которой провести слияние"
+
+#: lib/merge.tcl:212
+msgid ""
+"Cannot abort while amending.\n"
+"\n"
+"You must finish amending this commit.\n"
- msgstr ""
- "Прервать операцию слияния?\n"
- "\n"
- "Прерывание этой операции приведет к потере *ВСЕХ* несохраненных изменений.\n"
- "\n"
- "Продолжить?"
++msgstr "Невозможно прервать исправление.\n\nЗавершите текущее исправление коммита.\n"
+
+#: lib/merge.tcl:222
+msgid ""
+"Abort merge?\n"
+"\n"
+"Aborting the current merge will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with aborting the current merge?"
- msgstr ""
- "Прервать операцию слияния?\n"
- "\n"
- "Прерывание этой операции приведет к потере *ВСЕХ* несохраненных изменений.\n"
- "\n"
- "Продолжить?"
++msgstr "Прервать операцию слияния?\n\nПрерывание текущего слияния приведет к потере *ВСЕХ* несохраненных изменений.\n\nПродолжить?"
+
+#: lib/merge.tcl:228
+msgid ""
+"Reset changes?\n"
+"\n"
+"Resetting the changes will cause *ALL* uncommitted changes to be lost.\n"
+"\n"
+"Continue with resetting the current changes?"
- msgstr "Использовать версию этой ветви для разрешения конфликта?"
++msgstr "Сбросить изменения?\n\nСброс изменений приведет к потере *ВСЕХ* несохраненных изменений.\n\nПродолжить?"
+
+#: lib/merge.tcl:239
+msgid "Aborting"
+msgstr "Прерываю"
+
+#: lib/merge.tcl:239
+msgid "files reset"
+msgstr "изменения в файлах отменены"
+
+#: lib/merge.tcl:267
+msgid "Abort failed."
+msgstr "Прервать не удалось."
+
+#: lib/merge.tcl:269
+msgid "Abort completed. Ready."
+msgstr "Прервано."
+
+#: lib/mergetool.tcl:8
+msgid "Force resolution to the base version?"
+msgstr "Использовать базовую версию для разрешения конфликта?"
+
+#: lib/mergetool.tcl:9
+msgid "Force resolution to this branch?"
- msgstr "Использовать версию другой ветви для разрешения конфликта?"
++msgstr "Использовать версию из этой ветки для разрешения конфликта?"
+
+#: lib/mergetool.tcl:10
+msgid "Force resolution to the other branch?"
- msgstr ""
- "Внимание! Список изменений показывает только конфликтующие отличия.\n"
- "\n"
- "%s будет переписан.\n"
- "\n"
- "Это действие можно отменить только перезапуском операции слияния."
++msgstr "Использовать версию из другой ветки для разрешения конфликта?"
+
+#: lib/mergetool.tcl:14
+#, tcl-format
+msgid ""
+"Note that the diff shows only conflicting changes.\n"
+"\n"
+"%s will be overwritten.\n"
+"\n"
+"This operation can be undone only by restarting the merge."
- msgstr ""
- "Файл %s, похоже, содержит необработанные конфликты. Продолжить подготовку к "
- "сохранению?"
++msgstr "Внимание! Список изменений показывает только конфликтующие отличия.\n\n%s будет переписан.\n\nЭто действие можно отменить только перезапуском операции слияния."
+
+#: lib/mergetool.tcl:45
+#, tcl-format
+msgid "File %s seems to have unresolved conflicts, still stage?"
- msgstr ""
- "Программа слияния не обрабатывает конфликты с удалением или участием ссылок"
++msgstr "Похоже, что файл %s содержит неразрешенные конфликты. Продолжить индексацию?"
+
+#: lib/mergetool.tcl:60
+#, tcl-format
+msgid "Adding resolution for %s"
+msgstr "Добавляю результат разрешения для %s"
+
+#: lib/mergetool.tcl:141
+msgid "Cannot resolve deletion or link conflicts using a tool"
- msgstr "'%s' не является программой слияния"
++msgstr "Программа слияния не обрабатывает конфликты с удалением или участием ссылок"
+
+#: lib/mergetool.tcl:146
+msgid "Conflict file does not exist"
+msgstr "Конфликтующий файл не существует"
+
+#: lib/mergetool.tcl:264
+#, tcl-format
+msgid "Not a GUI merge tool: '%s'"
- msgstr "Неизвестная программа слияния '%s'"
++msgstr "«%s» не является программой слияния"
+
+#: lib/mergetool.tcl:268
+#, tcl-format
+msgid "Unsupported merge tool '%s'"
- msgstr ""
- "Ошибка получения версий:\n"
- "%s"
++msgstr "Неподдерживаемая программа слияния «%s»"
+
+#: lib/mergetool.tcl:303
+msgid "Merge tool is already running, terminate it?"
+msgstr "Программа слияния уже работает. Прервать?"
+
+#: lib/mergetool.tcl:323
+#, tcl-format
+msgid ""
+"Error retrieving versions:\n"
+"%s"
- msgstr ""
- "Ошибка запуска программы слияния:\n"
- "\n"
- "%s"
++msgstr "Ошибка получения версий:\n%s"
+
+#: lib/mergetool.tcl:343
+#, tcl-format
+msgid ""
+"Could not start the merge tool:\n"
+"\n"
+"%s"
- msgstr "Запуск программы слияния..."
++msgstr "Ошибка запуска программы слияния:\n\n%s"
+
+#: lib/mergetool.tcl:347
+msgid "Running merge tool..."
- msgstr "Ошибка в глобальной установке кодировки '%s'"
++msgstr "Запуск программы слияния…"
+
+#: lib/mergetool.tcl:375 lib/mergetool.tcl:383
+msgid "Merge tool failed."
+msgstr "Ошибка выполнения программы слияния."
+
+#: lib/option.tcl:11
+#, tcl-format
+msgid "Invalid global encoding '%s'"
- msgstr "Неверная кодировка репозитория: '%s'"
++msgstr "Неверная глобальная кодировка «%s»"
+
+#: lib/option.tcl:19
+#, tcl-format
+msgid "Invalid repo encoding '%s'"
- msgstr "Суммарный комментарий при слиянии"
++msgstr "Неверная кодировка репозитория «%s»"
+
+#: lib/option.tcl:117
+msgid "Restore Defaults"
+msgstr "Восстановить настройки по умолчанию"
+
+#: lib/option.tcl:121
+msgid "Save"
+msgstr "Сохранить"
+
+#: lib/option.tcl:131
+#, tcl-format
+msgid "%s Repository"
+msgstr "Для репозитория %s"
+
+#: lib/option.tcl:132
+msgid "Global (All Repositories)"
+msgstr "Общие (для всех репозиториев)"
+
+#: lib/option.tcl:138
+msgid "User Name"
+msgstr "Имя пользователя"
+
+#: lib/option.tcl:139
+msgid "Email Address"
+msgstr "Адрес электронной почты"
+
+#: lib/option.tcl:141
+msgid "Summarize Merge Commits"
- msgstr "Чистка ветвей слежения при получении изменений"
++msgstr "Суммарное сообщение при слиянии"
+
+#: lib/option.tcl:142
+msgid "Merge Verbosity"
+msgstr "Уровень детальности сообщений при слиянии"
+
+#: lib/option.tcl:143
+msgid "Show Diffstat After Merge"
+msgstr "Показать отчет об изменениях после слияния"
+
+#: lib/option.tcl:144
+msgid "Use Merge Tool"
+msgstr "Использовать для слияния программу"
+
+#: lib/option.tcl:146
+msgid "Trust File Modification Timestamps"
+msgstr "Доверять времени модификации файла"
+
+#: lib/option.tcl:147
+msgid "Prune Tracking Branches During Fetch"
- msgstr "Имя новой ветви взять из имен ветвей слежения"
++msgstr "Чистка отслеживаемых веток при извлечении изменений"
+
+#: lib/option.tcl:148
+msgid "Match Tracking Branches"
- msgstr "Ширина текста комментария"
++msgstr "Такое же имя, как и у отслеживаемой ветки"
+
+#: lib/option.tcl:149
+msgid "Blame Copy Only On Changed Files"
+msgstr "Поиск копий только в изменённых файлах"
+
+#: lib/option.tcl:150
+msgid "Minimum Letters To Blame Copy On"
+msgstr "Минимальное количество символов для поиска копий"
+
+#: lib/option.tcl:151
+msgid "Blame History Context Radius (days)"
+msgstr "Радиус исторического контекста (в днях)"
+
+#: lib/option.tcl:152
+msgid "Number of Diff Context Lines"
+msgstr "Число строк в контексте diff"
+
+#: lib/option.tcl:153
+msgid "Commit Message Text Width"
- msgstr "Шаблон для имени новой ветви"
++msgstr "Ширина текста сообщения коммита"
+
+#: lib/option.tcl:154
+msgid "New Branch Name Template"
- # carbon copy
++msgstr "Шаблон для имени новой ветки"
+
+#: lib/option.tcl:155
+msgid "Default File Contents Encoding"
+msgstr "Кодировка содержания файла по умолчанию"
+
+#: lib/option.tcl:203
+msgid "Change"
+msgstr "Изменить"
+
+#: lib/option.tcl:230
+msgid "Spelling Dictionary:"
+msgstr "Словарь для проверки правописания:"
+
+#: lib/option.tcl:254
+msgid "Change Font"
+msgstr "Изменить"
+
+#: lib/option.tcl:258
+#, tcl-format
+msgid "Choose %s"
+msgstr "Выберите %s"
+
- msgstr "Получение из"
+#: lib/option.tcl:264
+msgid "pt."
+msgstr "pt."
+
+#: lib/option.tcl:278
+msgid "Preferences"
+msgstr "Настройки"
+
+#: lib/option.tcl:314
+msgid "Failed to completely save options:"
+msgstr "Не удалось полностью сохранить настройки:"
+
+#: lib/remote.tcl:163
+msgid "Remove Remote"
+msgstr "Удалить ссылку на внешний репозиторий"
+
+#: lib/remote.tcl:168
+msgid "Prune from"
+msgstr "Чистка"
+
+#: lib/remote.tcl:173
+msgid "Fetch from"
- msgstr ""
++msgstr "Извлечение из"
+
+#: lib/remote.tcl:215
+msgid "Push to"
+msgstr "Отправить"
+
+#: lib/remote_add.tcl:19
+msgid "Add Remote"
+msgstr "Зарегистрировать внешний репозиторий"
+
+#: lib/remote_add.tcl:24
+msgid "Add New Remote"
+msgstr "Добавить внешний репозиторий"
+
+#: lib/remote_add.tcl:28 lib/tools_dlg.tcl:36
+msgid "Add"
- msgstr "Скачать сразу"
++msgstr "Добавить"
+
+#: lib/remote_add.tcl:37
+msgid "Remote Details"
+msgstr "Информация о внешнем репозитории"
+
+#: lib/remote_add.tcl:50
+msgid "Location:"
+msgstr "Положение:"
+
+#: lib/remote_add.tcl:62
+msgid "Further Action"
+msgstr "Следующая операция"
+
+#: lib/remote_add.tcl:65
+msgid "Fetch Immediately"
- msgstr "Недопустимое название внешнего репозитория '%s'."
++msgstr "Сразу извлечь изменения"
+
+#: lib/remote_add.tcl:71
+msgid "Initialize Remote Repository and Push"
+msgstr "Инициализировать внешний репозиторий и отправить"
+
+#: lib/remote_add.tcl:77
+msgid "Do Nothing Else Now"
+msgstr "Больше ничего не делать"
+
+#: lib/remote_add.tcl:101
+msgid "Please supply a remote name."
+msgstr "Укажите название внешнего репозитория."
+
+#: lib/remote_add.tcl:114
+#, tcl-format
+msgid "'%s' is not an acceptable remote name."
- msgstr "Не удалось добавить '%s' из '%s'. "
++msgstr "«%s» не является допустимым именем внешнего репозитория."
+
+#: lib/remote_add.tcl:125
+#, tcl-format
+msgid "Failed to add remote '%s' of location '%s'."
- msgstr "получение %s"
++msgstr "Не удалось добавить «%s» из «%s». "
+
+#: lib/remote_add.tcl:133 lib/transport.tcl:6
+#, tcl-format
+msgid "fetch %s"
- msgstr "Получение %s"
++msgstr "извлечение %s"
+
+#: lib/remote_add.tcl:134
+#, tcl-format
+msgid "Fetching the %s"
- msgstr "Невозможно инициализировать репозиторий в '%s'."
++msgstr "Извлечение %s"
+
+#: lib/remote_add.tcl:157
+#, tcl-format
+msgid "Do not know how to initialize repository at location '%s'."
- msgstr "Удаление ветви во внешнем репозитории"
++msgstr "Невозможно инициализировать репозиторий в «%s»."
+
+#: lib/remote_add.tcl:163 lib/transport.tcl:25 lib/transport.tcl:63
+#: lib/transport.tcl:81
+#, tcl-format
+msgid "push %s"
+msgstr "отправить %s"
+
+#: lib/remote_add.tcl:164
+#, tcl-format
+msgid "Setting up the %s (at %s)"
+msgstr "Настройка %s (в %s)"
+
+#: lib/remote_branch_delete.tcl:29 lib/remote_branch_delete.tcl:34
+msgid "Delete Branch Remotely"
- msgstr "Ветви"
++msgstr "Удаление ветки во внешнем репозитории"
+
+#: lib/remote_branch_delete.tcl:47
+msgid "From Repository"
+msgstr "Из репозитория"
+
+#: lib/remote_branch_delete.tcl:50 lib/transport.tcl:134
+msgid "Remote:"
+msgstr "внешний:"
+
+#: lib/remote_branch_delete.tcl:66 lib/transport.tcl:149
+msgid "Arbitrary Location:"
+msgstr "Указанное положение:"
+
+#: lib/remote_branch_delete.tcl:84
+msgid "Branches"
- msgstr "Для опции 'Слияние с' требуется указать ветвь."
++msgstr "Ветки"
+
+#: lib/remote_branch_delete.tcl:109
+msgid "Delete Only If"
+msgstr "Удалить только в случае, если"
+
+#: lib/remote_branch_delete.tcl:111
+msgid "Merged Into:"
+msgstr "Слияние с:"
+
+#: lib/remote_branch_delete.tcl:152
+msgid "A branch is required for 'Merged Into'."
- msgstr ""
- "Следующие ветви могут быть объединены с %s при помощи операции слияния:\n"
- "\n"
- " - %s"
++msgstr "Для операции «Слияние с» требуется указать ветку."
+
+#: lib/remote_branch_delete.tcl:184
+#, tcl-format
+msgid ""
+"The following branches are not completely merged into %s:\n"
+"\n"
+" - %s"
- msgstr ""
- "Некоторые тесты на слияние не прошли, потому что Вы не получили необходимые "
- "состояния. Попытайтесь получить их из %s."
++msgstr "Следующие ветки могут быть объединены с %s при помощи операции слияния:\n\n - %s"
+
+#: lib/remote_branch_delete.tcl:189
+#, tcl-format
+msgid ""
+"One or more of the merge tests failed because you have not fetched the "
+"necessary commits. Try fetching from %s first."
- msgstr "Укажите одну или несколько ветвей для удаления."
++msgstr "Некоторые тесты на слияние не прошли, потому что вы не извлекли необходимые коммиты. Попытайтесь извлечь их из %s."
+
+#: lib/remote_branch_delete.tcl:207
+msgid "Please select one or more branches to delete."
- msgstr "Удаление ветвей из %s"
++msgstr "Укажите одну или несколько веток для удаления."
+
+#: lib/remote_branch_delete.tcl:226
+#, tcl-format
+msgid "Deleting branches from %s"
- msgstr "Перечитывание %s... "
++msgstr "Удаление веток из %s"
+
+#: lib/remote_branch_delete.tcl:292
+msgid "No repository selected."
+msgstr "Не указан репозиторий."
+
+#: lib/remote_branch_delete.tcl:297
+#, tcl-format
+msgid "Scanning %s..."
- msgstr "Создание..."
++msgstr "Перечитывание %s…"
+
+#: lib/search.tcl:21
+msgid "Find:"
+msgstr "Поиск:"
+
+#: lib/search.tcl:23
+msgid "Next"
+msgstr "Дальше"
+
+#: lib/search.tcl:24
+msgid "Prev"
+msgstr "Обратно"
+
+#: lib/search.tcl:25
+msgid "Case-Sensitive"
+msgstr "Игн. большие/маленькие"
+
+#: lib/shortcut.tcl:21 lib/shortcut.tcl:62
+msgid "Cannot write shortcut:"
+msgstr "Невозможно записать ссылку:"
+
+#: lib/shortcut.tcl:137
+msgid "Cannot write icon:"
+msgstr "Невозможно записать значок:"
+
+#: lib/spellcheck.tcl:57
+msgid "Unsupported spell checker"
+msgstr "Неподдерживаемая программа проверки правописания"
+
+#: lib/spellcheck.tcl:65
+msgid "Spell checking is unavailable"
+msgstr "Проверка правописания не доступна"
+
+#: lib/spellcheck.tcl:68
+msgid "Invalid spell checking configuration"
+msgstr "Неправильная конфигурация программы проверки правописания"
+
+#: lib/spellcheck.tcl:70
+#, tcl-format
+msgid "Reverting dictionary to %s."
+msgstr "Словарь вернут к %s."
+
+#: lib/spellcheck.tcl:73
+msgid "Spell checker silently failed on startup"
+msgstr "Программа проверки правописания не смогла запуститься"
+
+#: lib/spellcheck.tcl:80
+msgid "Unrecognized spell checker"
+msgstr "Нераспознанная программа проверки правописания"
+
+#: lib/spellcheck.tcl:186
+msgid "No Suggestions"
+msgstr "Исправлений не найдено"
+
+#: lib/spellcheck.tcl:388
+msgid "Unexpected EOF from spell checker"
+msgstr "Программа проверки правописания прервала передачу данных"
+
+#: lib/spellcheck.tcl:392
+msgid "Spell Checker Failed"
+msgstr "Ошибка проверки правописания"
+
+#: lib/sshkey.tcl:31
+msgid "No keys found."
+msgstr "Ключ не найден"
+
+#: lib/sshkey.tcl:34
+#, tcl-format
+msgid "Found a public key in: %s"
+msgstr "Публичный ключ из %s"
+
+#: lib/sshkey.tcl:40
+msgid "Generate Key"
+msgstr "Создать ключ"
+
+#: lib/sshkey.tcl:56
+msgid "Copy To Clipboard"
+msgstr "Скопировать в буфер обмена"
+
+#: lib/sshkey.tcl:70
+msgid "Your OpenSSH Public Key"
+msgstr "Ваш публичный ключ OpenSSH"
+
+#: lib/sshkey.tcl:78
+msgid "Generating..."
- msgstr ""
- "Ошибка запуска ssh-keygen:\n"
- "\n"
- "%s"
++msgstr "Создание…"
+
+#: lib/sshkey.tcl:84
+#, tcl-format
+msgid ""
+"Could not start ssh-keygen:\n"
+"\n"
+"%s"
- msgstr "%s ... %*i из %*i %s (%3i%%)"
++msgstr "Ошибка запуска ssh-keygen:\n\n%s"
+
+#: lib/sshkey.tcl:111
+msgid "Generation failed."
+msgstr "Ключ не создан."
+
+#: lib/sshkey.tcl:118
+msgid "Generation succeeded, but no keys found."
+msgstr "Создание ключа завершилось, но результат не был найден"
+
+#: lib/sshkey.tcl:121
+#, tcl-format
+msgid "Your key is in: %s"
+msgstr "Ваш ключ находится в: %s"
+
+#: lib/status_bar.tcl:83
+#, tcl-format
+msgid "%s ... %*i of %*i %s (%3i%%)"
- msgstr "Используйте '/' для создания подменю"
++msgstr "%s … %*i из %*i %s (%3i%%)"
+
+#: lib/tools.tcl:75
+#, tcl-format
+msgid "Running %s requires a selected file."
+msgstr "Запуск %s требует выбранного файла."
+
+#: lib/tools.tcl:90
+#, tcl-format
+msgid "Are you sure you want to run %s?"
+msgstr "Действительно запустить %s?"
+
+#: lib/tools.tcl:110
+#, tcl-format
+msgid "Tool: %s"
+msgstr "Вспомогательная операция: %s"
+
+#: lib/tools.tcl:111
+#, tcl-format
+msgid "Running: %s"
+msgstr "Выполнение: %s"
+
+#: lib/tools.tcl:149
+#, tcl-format
+msgid "Tool completed successfully: %s"
+msgstr "Программа %s завершилась успешно."
+
+#: lib/tools.tcl:151
+#, tcl-format
+msgid "Tool failed: %s"
+msgstr "Ошибка выполнения программы: %s"
+
+#: lib/tools_dlg.tcl:22
+msgid "Add Tool"
+msgstr "Добавить вспомогательную операцию"
+
+#: lib/tools_dlg.tcl:28
+msgid "Add New Tool Command"
+msgstr "Новая вспомогательная операция"
+
+#: lib/tools_dlg.tcl:33
+msgid "Add globally"
+msgstr "Добавить для всех репозиториев"
+
+#: lib/tools_dlg.tcl:45
+msgid "Tool Details"
+msgstr "Описание вспомогательной операции"
+
+#: lib/tools_dlg.tcl:48
+msgid "Use '/' separators to create a submenu tree:"
- msgstr "Вспомогательная операция '%s' уже существует."
++msgstr "Используйте «/» для создания подменю"
+
+#: lib/tools_dlg.tcl:61
+msgid "Command:"
+msgstr "Команда:"
+
+#: lib/tools_dlg.tcl:74
+msgid "Show a dialog before running"
+msgstr "Показать диалог перед запуском"
+
+#: lib/tools_dlg.tcl:80
+msgid "Ask the user to select a revision (sets $REVISION)"
+msgstr "Запрос на выбор версии (устанавливает $REVISION)"
+
+#: lib/tools_dlg.tcl:85
+msgid "Ask the user for additional arguments (sets $ARGS)"
+msgstr "Запрос дополнительных аргументов (устанавливает $ARGS)"
+
+#: lib/tools_dlg.tcl:92
+msgid "Don't show the command output window"
+msgstr "Не показывать окно вывода команды"
+
+#: lib/tools_dlg.tcl:97
+msgid "Run only if a diff is selected ($FILENAME not empty)"
+msgstr "Запуск только если показан список изменений ($FILENAME не пусто)"
+
+#: lib/tools_dlg.tcl:121
+msgid "Please supply a name for the tool."
+msgstr "Укажите название вспомогательной операции."
+
+#: lib/tools_dlg.tcl:129
+#, tcl-format
+msgid "Tool '%s' already exists."
- msgstr ""
- "Ошибка добавления программы:\n"
- "%s"
++msgstr "Вспомогательная операция «%s» уже существует."
+
+#: lib/tools_dlg.tcl:151
+#, tcl-format
+msgid ""
+"Could not add tool:\n"
+"%s"
- msgstr "Получение изменений из %s "
++msgstr "Ошибка добавления программы:\n%s"
+
+#: lib/tools_dlg.tcl:190
+msgid "Remove Tool"
+msgstr "Удалить программу"
+
+#: lib/tools_dlg.tcl:196
+msgid "Remove Tool Commands"
+msgstr "Удалить команды программы"
+
+#: lib/tools_dlg.tcl:200
+msgid "Remove"
+msgstr "Удалить"
+
+#: lib/tools_dlg.tcl:236
+msgid "(Blue denotes repository-local tools)"
+msgstr "(Синим выделены программы локальные репозиторию)"
+
+#: lib/tools_dlg.tcl:297
+#, tcl-format
+msgid "Run Command: %s"
+msgstr "Запуск команды: %s"
+
+#: lib/tools_dlg.tcl:311
+msgid "Arguments"
+msgstr "Аргументы"
+
+#: lib/tools_dlg.tcl:348
+msgid "OK"
+msgstr "OK"
+
+#: lib/transport.tcl:7
+#, tcl-format
+msgid "Fetching new changes from %s"
- # carbon copy
++msgstr "Извлечение изменений из %s "
+
- msgstr "Чистка ветвей слежения, удаленных из %s"
+#: lib/transport.tcl:18
+#, tcl-format
+msgid "remote prune %s"
+msgstr "чистка внешнего %s"
+
+#: lib/transport.tcl:19
+#, tcl-format
+msgid "Pruning tracking branches deleted from %s"
- msgstr "Отправить изменения в ветвях"
++msgstr "Чистка отслеживаемых веток, удалённых из %s"
+
+#: lib/transport.tcl:26
+#, tcl-format
+msgid "Pushing changes to %s"
+msgstr "Отправка изменений в %s "
+
+#: lib/transport.tcl:64
+#, tcl-format
+msgid "Mirroring to %s"
+msgstr "Точное копирование в %s"
+
+#: lib/transport.tcl:82
+#, tcl-format
+msgid "Pushing %s %s to %s"
+msgstr "Отправка %s %s в %s"
+
+#: lib/transport.tcl:100
+msgid "Push Branches"
- msgstr "Исходные ветви"
++msgstr "Отправить ветки"
+
+#: lib/transport.tcl:114
+msgid "Source Branches"
- msgstr "Намеренно переписать существующую ветвь (возможна потеря изменений)"
++msgstr "Исходные ветки"
+
+#: lib/transport.tcl:131
+msgid "Destination Repository"
+msgstr "Репозиторий назначения"
+
+#: lib/transport.tcl:169
+msgid "Transfer Options"
+msgstr "Настройки отправки"
+
+#: lib/transport.tcl:171
+msgid "Force overwrite existing branch (may discard changes)"
++msgstr "Принудительно перезаписать существующую ветку (возможна потеря изменений)"
+
+#: lib/transport.tcl:175
+msgid "Use thin pack (for slow network connections)"
+msgstr "Использовать thin pack (для медленных сетевых подключений)"
+
+#: lib/transport.tcl:179
+msgid "Include tags"
+msgstr "Передать метки"