Compare commits

...

22 Commits

Author SHA1 Message Date
0b5ea163d2 git-gui: Make 'make' quieter by default
To fit nicely into the output of the git.git project's own quieter
Makefile, we want to make the git-gui Makefile nice and quiet too.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-03-06 02:13:23 -05:00
c3e8a0a4dd git-gui: Remove unnecessary /dev/null redirection.
Git 1.5.0 and later no longer output useless messages to standard
error when making the initial (or what looks to be) commit of a
repository.  Since /dev/null does not exist on Windows in the
MinGW environment we can't redirect there anyway.  Since Git
does not output anymore, I'm removing the redirection.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-03-01 14:37:34 -05:00
51bd9d7b8c git-gui: Don't create empty (same tree as parent) commits.
Mark Levedahl noticed that git-gui will let you create an empty
normal (non-merge) commit if the file state in the index is out
of whack.  The case Mark was looking at was with the new autoCRLF
feature in git enabled and is actually somewhat difficult to create.

I found a different way to create an empty commit:  turn on the
Trust File Modifications flag, touch a file, rescan, then move
the file into the "Changes To Be Committed" list without looking
at the file's diff.  This makes git-gui think there are files
staged for commit, yet the update-index call did nothing other
than refresh the stat information for the affected file.  In
this case git-gui allowed the user to make a commit that did
not actually change anything in the repository.

Creating empty commits is usually a pointless operation; rarely
does it record useful information.  More often than not an empty
commit is actually an indication that the user did not properly
update their index prior to commit.  We should help the user out
by detecting this possible mistake and guiding them through it,
rather than blindly recording it.

After we get the new tree name back from write-tree we compare
it to the parent commit's tree; if they are the same string and
this is a normal (non-merge, non-amend) commit then something
fishy is going on.  The user is making an empty commit, but they
most likely don't want to do that.  We now pop an informational
dialog and start a rescan, aborting the commit.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-26 11:47:14 -05:00
fd234dfdb7 git-gui: Add Reset to the Branch menu.
cehteh on #git noticed that there was no way to perform a reset --hard
from within git-gui.  When I pointed out this was Merge->Abort Merge
cehteh said this is not very understandable, and that most users would
never guess to try that option unless they were actually in a merge.

So Branch->Reset is now also a way to cause a reset --hard from within
the UI.  Right now the confirmation dialog is the same as the one used
in Merge->Abort Merge.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-26 11:22:10 -05:00
9b28a8b9c2 git-gui: Relocate the menu/transport menu code.
This code doesn't belong down in the main window UI creation,
its really part of the menu system and probably should be
located with it.  I'm moving it because I could not find
the code when I was looking for it earlier today, as it was
not where I expected it to be found.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-26 11:17:11 -05:00
92446aba47 Don't modify CREDITS-FILE if it hasn't changed.
We should always avoid rewriting a built file during `make install`
if nothing has changed since `make all`.  This is to help support
the typical installation process of compiling a package as yourself,
then installing it as root.

Forcing CREDITS-FILE to be always be rebuilt in the Makefile means
that CREDITS-GEN needs to check for a change and only update
CREDITS-FILE if the file content actually differs.  After all,
content is king in Git.

Signed-off-by: Junio C Hamano <junkio@cox.net>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-25 02:18:26 -05:00
981193786f git-gui: Don't crash in citool mode on initial commit.
Attempting to use `git citool` to create an initial commit caused
git-gui to crash with a Tcl error as it tried to add the newly
born branch to the non-existant branch menu.  Moving this code
to after the normal commit cleanup logic resolves the issue, as
we only have a branch menu if we are not in singlecommit mode.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-21 01:33:59 -05:00
7391b2e999 git-gui: Remove TODO list.
I'm apparently not very good at keeping my own TODO file current.
I its also somewhat strange to keep the TODO list as part of the
software branch, as its meta-information that is not directly
related to the code.  I'm pulling the TODO list from git-gui and
moving it into a seperate branch.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-21 01:29:05 -05:00
c0f7a6c33d git-gui: Include browser in our usage message.
Now that the 'browser' subcommand can be used to startup the tree
browser, it should be listed as a possible subcommand option in
our usage message.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-21 01:24:57 -05:00
019f42a4ff git-gui: Change summary of git-gui.
Since git-gui does more than create commits, it is unfair to call
it "a commit creation tool".  Instead lets just call it a graphical
user interface.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-21 00:11:02 -05:00
871f4c97ad git-gui: Display all authors of git-gui.
Now that git-gui has been released to the public as part of Git 1.5.0
I am starting to see some work from other people beyond myself and
Paul.  Consequently the copyright for git-gui is not strictly the
two of us anymore, and these others deserve to have some credit
given to them.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-21 00:11:01 -05:00
ee40599330 git-gui: Use mixed path for docs on Cygwin.
The Firefox browser requires that a URL use / to delimit directories.
This is instead of \, as \ gets escaped by the browser into its hex
escape code and then relative URLs are incorrectly resolved, Firefox
no longer sees the directories for what they are.  Since we are
handing the browser a true URL, we better use the standard / for
directories.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-21 00:11:01 -05:00
372ef954a1 git-gui: Correct crash when saving options in blame mode.
Martin Waitz noticed that git-gui crashed while saving the user's
options out if the application was started in blame mode.  This
was caused by the do_save_config procedure invoking reshow_diff
incase the number of context lines was modified by the user.
Because we bypassed main window UI setup to enter blame mode we
did not set many of the globals which were accessed by reshow_diff,
and reading unset variables is an error in Tcl.

Aside from moving the globals to be set earlier, I also modified
reshow_diff to not invoke clear_diff if there is no path currently
in the diff viewer.  This way reshow_diff does not crash when in
blame mode due to the $ui_diff command not being defined.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-18 02:12:32 -05:00
b90d479255 git-gui: Expose the browser as a subcommand.
Some users may find being able to browse around an arbitrary
branch to be handy, so we now expose our graphical browser
through `git gui browse <committish>`.

Yes, I'm being somewhat lazy and making the user give us
the name of the branch to browse.  They can always enter
HEAD.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-16 00:24:03 -05:00
101e3ae7a6 git-gui: Create new branches from a tag.
I'm missing the possibility to base a new branch on a tag.
The following adds a tag drop down to the new branch dialog.

Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-15 01:34:40 -05:00
26370f73c0 git-gui: Prefer version file over git-describe.
Some distributions are using Git for part of their package
management system, but unpack Git's own source code for
delivery from the .tar.gz.  This means that when we walk
up the directory tree with git-describe to locate a Git
repository, the repository we find is for the distribution
and *not* for git-gui.  Consequently any tag we might find
there is bogus and does not apply to us.

In this case the version file should always exist and be
readable, as the packager is working from the released
.tar.gz sources.  So we should always favor the version
file over anything git-describe guess for us.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-14 01:55:16 -05:00
ed3adde081 git-gui: Print version on the console.
Like `git version`, `git gui version` (or `git gui --version`) shows
the version of git-gui, in case the user needs to know this, without
looking at it in the GUI about dialog.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-14 00:28:00 -05:00
5ac58f5ba1 git-gui: More consistently display the application name.
I started to find it confusing that git-gui would refer to itself
as git-citool when it was started through the citool hardlink, or
with the citool subcommand.  What was especially confusing was the
options dialog and the about dialog, as both seemed to imply they
were somehow different from the git-gui versions.  In actuality
there is no difference at all.

Now we just call our options menu item 'Options...' (skipping the
application name) and our About dialog now always shows git-gui
within the short description (above the copyleft notice) and in
the version field.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-14 00:10:20 -05:00
cdf6e08880 git-gui: Permit merging tags into the current branch.
It was pointed out on the git mailing list by Martin Koegler that
we did not show tags as possible things to merge into the current
branch.  They actually are, and core Git's Grand Unified Merge
Driver will accept them just like any other commit.

So our merge dialog now requests all refs/heads, refs/remotes and
refs/tags named refs and attempts to match them against the commits
not in HEAD.  One complicating factor here is that we must use the
%(*objectname) field when talking about an annotated tag, as they
will not appear in the output of rev-list.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-13 23:43:48 -05:00
54acdd95b8 git-gui: Basic version check to ensure git 1.5.0 or later is used.
This is a very crude (but hopefully effective) check against the
`git` executable found in our PATH.  Some of the subcommands and
options that git-gui requires to be present to operate were created
during the 1.5.0 development cycle, so 1.5 is the minimum version
of git that we can expect to support.

There actually are early releases of 1.5 (e.g. 1.5.0-rc0) that
don't have everything we expect (like `blame --incremental`) but
these are purely academic at this point.  1.5.0 final was tagged
and released just a few hours ago.  The release candidates will
(hopefully) fade into the dark quickly.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-13 23:15:25 -05:00
8134722306 git-gui: Refactor 'exec git subcmd' idiom.
As we frequently need to execute a Git subcommand and obtain
its returned output we are making heavy use of [exec git foo]
to run foo.  As I'm concerned about possibly needing to carry
environment data through a shell on Cygwin for at least some
subcommands, I'm migrating all current calls to a new git
proc.  This actually makes the code look cleaner too, as
we aren't saying 'exec git' everywhere.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-13 21:32:52 -05:00
022fef30fa git-gui: fix typo in GIT-VERSION-GEN, "/dev/null" not "/devnull"
Signed-off-by: Andy Parkins <andyparkins@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
2007-02-13 10:35:58 -05:00
6 changed files with 388 additions and 155 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
CREDITS-FILE
GIT-VERSION-FILE GIT-VERSION-FILE
git-citool git-citool
git-gui git-gui

71
CREDITS-GEN Executable file
View File

@ -0,0 +1,71 @@
#!/bin/sh
CF=CREDITS-FILE
tip=
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 $p; break;;
esac
done
}
generate_credits ()
{
tip=$1 &&
rm -f "$2" &&
git shortlog -n -s $tip | sed 's/: .*$//' >"$2" || exit
}
# Always use the tarball credits 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.
#
credits_tmp=/var/tmp/gitgui-credits-$$
trap 'rm -f "$credits_tmp"' 0
orig="$credits_tmp"
if test -f credits
then
orig=credits
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) &&
tip=$(tree_search $head $tree) &&
test -n "$tip"
then
generate_credits $tip "$orig" || exit
elif tip="$(git rev-parse --verify HEAD 2>/dev/null)" &&
test -n "$tip"
then
generate_credits $tip "$orig" || exit
else
echo "error: Cannot locate authorship information." >&2
exit 1
fi
if test -f "$orig" && cmp -s "$orig" "$CF"
then
: noop
else
rm -f "$CF" &&
cat "$orig" >"$CF"
fi

View File

@ -10,7 +10,7 @@ tree_search ()
{ {
head=$1 head=$1
tree=$2 tree=$2
for p in $(git rev-list --parents --max-count=1 $head 2>/devnull) for p in $(git rev-list --parents --max-count=1 $head 2>/dev/null)
do do
test $tree = $(git rev-parse $p^{tree} 2>/dev/null) && test $tree = $(git rev-parse $p^{tree} 2>/dev/null) &&
vn=$(git describe --abbrev=4 $p 2>/dev/null) && vn=$(git describe --abbrev=4 $p 2>/dev/null) &&
@ -20,6 +20,11 @@ tree_search ()
done 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 # We may be a subproject, so try looking for the merge
# commit that supplied this directory content if we are # commit that supplied this directory content if we are
# not at the toplevel. We probably will always be the # not at the toplevel. We probably will always be the
@ -27,10 +32,13 @@ tree_search ()
# that fact. # that fact.
# #
# If we are at the toplevel or the merge assumption fails # If we are at the toplevel or the merge assumption fails
# try looking for a gitgui-* tag, or fallback onto the # try looking for a gitgui-* tag.
# distributed version file.
if prefix="$(git rev-parse --show-prefix 2>/dev/null)" if test -f version &&
VN=$(cat version)
then
: happy
elif prefix="$(git rev-parse --show-prefix 2>/dev/null)"
test -n "$prefix" && test -n "$prefix" &&
head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) && head=$(git rev-list --max-count=1 HEAD -- . 2>/dev/null) &&
tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) && tree=$(git rev-parse --verify "HEAD:$prefix" 2>/dev/null) &&
@ -48,9 +56,6 @@ elif VN=$(git describe --abbrev=4 HEAD 2>/dev/null) &&
esac esac
then then
VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g'); VN=$(echo "$VN" | sed -e 's/^gitgui-//;s/-/./g');
elif test -f version
then
VN=$(cat version) || VN="$DEF_VER"
else else
VN="$DEF_VER" VN="$DEF_VER"
fi fi

View File

@ -1,12 +1,14 @@
all:: all::
# Define V=1 to have a more verbose compile.
#
GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
@$(SHELL_PATH) ./GIT-VERSION-GEN @$(SHELL_PATH) ./GIT-VERSION-GEN
-include GIT-VERSION-FILE -include GIT-VERSION-FILE
SCRIPT_SH = git-gui.sh
GITGUI_BUILT_INS = git-citool GITGUI_BUILT_INS = git-citool
ALL_PROGRAMS = $(GITGUI_BUILT_INS) $(patsubst %.sh,%,$(SCRIPT_SH)) ALL_PROGRAMS = git-gui $(GITGUI_BUILT_INS)
ifndef SHELL_PATH ifndef SHELL_PATH
SHELL_PATH = /bin/sh SHELL_PATH = /bin/sh
@ -20,23 +22,32 @@ ifndef INSTALL
INSTALL = install INSTALL = install
endif endif
ifndef V
QUIET_GEN = @echo ' ' GEN $@;
QUIET_BUILT_IN = @echo ' ' BUILTIN $@;
endif
DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) gitexecdir_SQ = $(subst ','\'',$(gitexecdir))
SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
$(patsubst %.sh,%,$(SCRIPT_SH)) : % : %.sh git-gui: git-gui.sh GIT-VERSION-FILE CREDITS-FILE
rm -f $@ $@+ $(QUIET_GEN)rm -f $@ $@+ && \
sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ sed -n \
-e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \
-e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \ -e 's/@@GITGUI_VERSION@@/$(GITGUI_VERSION)/g' \
$@.sh >$@+ -e '1,/^set gitgui_credits /p' \
chmod +x $@+ $@.sh >$@+ && \
cat CREDITS-FILE >>$@+ && \
sed -e '1,/^set gitgui_credits /d' $@.sh >>$@+ && \
chmod +x $@+ && \
mv $@+ $@ mv $@+ $@
$(GITGUI_BUILT_INS): git-gui CREDITS-FILE: CREDITS-GEN .FORCE-CREDITS-FILE
rm -f $@ && ln git-gui $@ $(QUIET_GEN)$(SHELL_PATH) ./CREDITS-GEN
# These can record GITGUI_VERSION $(GITGUI_BUILT_INS): git-gui
$(patsubst %.sh,%,$(SCRIPT_SH)): GIT-VERSION-FILE $(QUIET_BUILT_IN)rm -f $@ && ln git-gui $@
all:: $(ALL_PROGRAMS) all:: $(ALL_PROGRAMS)
@ -45,12 +56,14 @@ install: all
$(INSTALL) git-gui '$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL) git-gui '$(DESTDIR_SQ)$(gitexecdir_SQ)'
$(foreach p,$(GITGUI_BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;) $(foreach p,$(GITGUI_BUILT_INS), rm -f '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' && ln '$(DESTDIR_SQ)$(gitexecdir_SQ)/git-gui' '$(DESTDIR_SQ)$(gitexecdir_SQ)/$p' ;)
dist-version: dist-version: CREDITS-FILE
@mkdir -p $(TARDIR) @mkdir -p $(TARDIR)
@echo $(GITGUI_VERSION) > $(TARDIR)/version @echo $(GITGUI_VERSION) > $(TARDIR)/version
@cat CREDITS-FILE > $(TARDIR)/credits
clean:: clean::
rm -f $(ALL_PROGRAMS) GIT-VERSION-FILE rm -f $(ALL_PROGRAMS) GIT-VERSION-FILE CREDITS-FILE
.PHONY: all install dist-version clean .PHONY: all install dist-version clean
.PHONY: .FORCE-GIT-VERSION-FILE .PHONY: .FORCE-GIT-VERSION-FILE
.PHONY: .FORCE-CREDITS-FILE

44
TODO
View File

@ -1,44 +0,0 @@
Items outstanding:
* Add file to .gitignore or info/excludes.
* Populate the pull menu with local branches.
* Make use of the new default merge data stored in repo-config.
* Checkout a different local branch.
* Push any local branch to a remote branch.
* Merge any local branches through a real merge UI.
* Allow user to define keyboard shortcuts for frequently used fetch
or merge operations. Or maybe just define a keyboard shortcut
for default fetch/default merge of current branch is enough;
but I do know a few users who merge a couple of common branches
also into the same branch so one default isn't quite enough.
* Better organize fetch/push/pull console windows.
* Clone UI (to download a new repository).
* Remotes editor (for .git/config format only).
* Show a shortlog of the last couple of commits in the main window,
to give the user warm fuzzy feelings that we have their data
saved. Actually this may be the set of commits not yet in
the upstream (aka default merge branch remote repository).
* GUI configuration editor for options listed in
git.git/Documentation/config.txt. Ideally this would
parse that file and generate the options dialog from
the documentation itself, and include the help text
from the documentation as part of the UI somehow.
Known bugs:
* git-gui sometimes just closes on Windows with no error message.
I'm not sure what the problem is here. I suspect the wish
process is just terminating due to a segfault or something,
as the do_quit proc in git-gui doesn't run. It often seems to
occur while writing a commit message in the buffer. Odd.

View File

@ -4,7 +4,7 @@ exec wish "$0" -- "$@"
set appvers {@@GITGUI_VERSION@@} set appvers {@@GITGUI_VERSION@@}
set copyright { set copyright {
Copyright <20> 2006, 2007 Shawn Pearce, Paul Mackerras. Copyright <20> 2006, 2007 Shawn Pearce, et. al.
This program is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -19,6 +19,9 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA} Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA}
set gitgui_credits {
Paul Mackerras
}
###################################################################### ######################################################################
## ##
@ -46,7 +49,7 @@ proc gitdir {args} {
proc gitexec {args} { proc gitexec {args} {
global _gitexec global _gitexec
if {$_gitexec eq {}} { if {$_gitexec eq {}} {
if {[catch {set _gitexec [exec git --exec-path]} err]} { if {[catch {set _gitexec [git --exec-path]} err]} {
error "Git not installed?\n\n$err" error "Git not installed?\n\n$err"
} }
} }
@ -202,14 +205,14 @@ proc save_config {} {
set value $global_config_new($name) set value $global_config_new($name)
if {$value ne $global_config($name)} { if {$value ne $global_config($name)} {
if {$value eq $default_config($name)} { if {$value eq $default_config($name)} {
catch {exec git config --global --unset $name} catch {git config --global --unset $name}
} else { } else {
regsub -all "\[{}\]" $value {"} value regsub -all "\[{}\]" $value {"} value
exec git config --global $name $value git config --global $name $value
} }
set global_config($name) $value set global_config($name) $value
if {$value eq $repo_config($name)} { if {$value eq $repo_config($name)} {
catch {exec git config --unset $name} catch {git config --unset $name}
set repo_config($name) $value set repo_config($name) $value
} }
} }
@ -219,16 +222,24 @@ proc save_config {} {
set value $repo_config_new($name) set value $repo_config_new($name)
if {$value ne $repo_config($name)} { if {$value ne $repo_config($name)} {
if {$value eq $global_config($name)} { if {$value eq $global_config($name)} {
catch {exec git config --unset $name} catch {git config --unset $name}
} else { } else {
regsub -all "\[{}\]" $value {"} value regsub -all "\[{}\]" $value {"} value
exec git config $name $value git config $name $value
} }
set repo_config($name) $value set repo_config($name) $value
} }
} }
} }
######################################################################
##
## handy utils
proc git {args} {
return [eval exec git $args]
}
proc error_popup {msg} { proc error_popup {msg} {
set title [appname] set title [appname]
if {[reponame] ne {}} { if {[reponame] ne {}} {
@ -287,12 +298,44 @@ proc ask_popup {msg} {
-message $msg] -message $msg]
} }
######################################################################
##
## version check
set req_maj 1
set req_min 5
if {[catch {set v [git --version]} err]} {
catch {wm withdraw .}
error_popup "Cannot determine Git version:
$err
[appname] requires Git $req_maj.$req_min or later."
exit 1
}
if {[regexp {^git version (\d+)\.(\d+)} $v _junk act_maj act_min]} {
if {$act_maj < $req_maj
|| ($act_maj == $req_maj && $act_min < $req_min)} {
catch {wm withdraw .}
error_popup "[appname] requires Git $req_maj.$req_min or later.
You are using $v."
exit 1
}
} else {
catch {wm withdraw .}
error_popup "Cannot parse Git version string:\n\n$v"
exit 1
}
unset -nocomplain v _junk act_maj act_min req_maj req_min
###################################################################### ######################################################################
## ##
## repository setup ## repository setup
if { [catch {set _gitdir $env(GIT_DIR)}] if { [catch {set _gitdir $env(GIT_DIR)}]
&& [catch {set _gitdir [exec git rev-parse --git-dir]} err]} { && [catch {set _gitdir [git rev-parse --git-dir]} err]} {
catch {wm withdraw .} catch {wm withdraw .}
error_popup "Cannot find the git directory:\n\n$err" error_popup "Cannot find the git directory:\n\n$err"
exit 1 exit 1
@ -319,6 +362,24 @@ set _reponame [lindex [file split \
[file normalize [file dirname $_gitdir]]] \ [file normalize [file dirname $_gitdir]]] \
end] end]
######################################################################
##
## global init
set current_diff_path {}
set current_diff_side {}
set diff_actions [list]
set ui_status_value {Initializing...}
set HEAD {}
set PARENT {}
set MERGE_HEAD [list]
set commit_type {}
set empty_tree {}
set current_branch {}
set current_diff_path {}
set selected_commit_type new
###################################################################### ######################################################################
## ##
## task management ## task management
@ -365,7 +426,7 @@ proc repository_state {ctvar hdvar mhvar} {
set mh [list] set mh [list]
if {[catch {set current_branch [exec git symbolic-ref HEAD]}]} { if {[catch {set current_branch [git symbolic-ref HEAD]}]} {
set current_branch {} set current_branch {}
} else { } else {
regsub ^refs/((heads|tags|remotes)/)? \ regsub ^refs/((heads|tags|remotes)/)? \
@ -374,7 +435,7 @@ proc repository_state {ctvar hdvar mhvar} {
current_branch current_branch
} }
if {[catch {set hd [exec git rev-parse --verify HEAD]}]} { if {[catch {set hd [git rev-parse --verify HEAD]}]} {
set hd {} set hd {}
set ct initial set ct initial
return return
@ -402,7 +463,7 @@ proc PARENT {} {
return $p return $p
} }
if {$empty_tree eq {}} { if {$empty_tree eq {}} {
set empty_tree [exec git mktree << {}] set empty_tree [git mktree << {}]
} }
return $empty_tree return $empty_tree
} }
@ -642,8 +703,9 @@ proc reshow_diff {} {
global current_diff_path current_diff_side global current_diff_path current_diff_side
set p $current_diff_path set p $current_diff_path
if {$p eq {} if {$p eq {}} {
|| $current_diff_side eq {} # No diff is being shown.
} elseif {$current_diff_side eq {}
|| [catch {set s $file_states($p)}] || [catch {set s $file_states($p)}]
|| [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} { || [lsearch -sorted -exact $file_lists($current_diff_side) $p] == -1} {
clear_diff clear_diff
@ -1042,7 +1104,7 @@ proc committer_ident {} {
global GIT_COMMITTER_IDENT global GIT_COMMITTER_IDENT
if {$GIT_COMMITTER_IDENT eq {}} { if {$GIT_COMMITTER_IDENT eq {}} {
if {[catch {set me [exec git var GIT_COMMITTER_IDENT]} err]} { if {[catch {set me [git var GIT_COMMITTER_IDENT]} err]} {
error_popup "Unable to obtain your identity:\n\n$err" error_popup "Unable to obtain your identity:\n\n$err"
return {} return {}
} }
@ -1205,6 +1267,24 @@ proc commit_committree {fd_wt curHEAD msg} {
return return
} }
# -- Verify this wasn't an empty change.
#
if {$commit_type eq {normal}} {
set old_tree [git rev-parse "$PARENT^{tree}"]
if {$tree_id eq $old_tree} {
info_popup {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 {set ui_status_value {No changes to commit.}}
return
}
}
# -- Build the message. # -- Build the message.
# #
set msg_p [gitdir COMMIT_EDITMSG] set msg_p [gitdir COMMIT_EDITMSG]
@ -1219,15 +1299,9 @@ proc commit_committree {fd_wt curHEAD msg} {
# -- Create the commit. # -- Create the commit.
# #
set cmd [list git commit-tree $tree_id] set cmd [list git commit-tree $tree_id]
set parents [concat $PARENT $MERGE_HEAD] foreach p [concat $PARENT $MERGE_HEAD] {
if {[llength $parents] > 0} {
foreach p $parents {
lappend cmd -p $p lappend cmd -p $p
} }
} else {
# git commit-tree writes to stderr during initial commit.
lappend cmd 2>/dev/null
}
lappend cmd <$msg_p lappend cmd <$msg_p
if {[catch {set cmt_id [eval exec $cmd]} err]} { if {[catch {set cmt_id [eval exec $cmd]} err]} {
error_popup "commit-tree failed:\n\n$err" error_popup "commit-tree failed:\n\n$err"
@ -1256,14 +1330,6 @@ proc commit_committree {fd_wt curHEAD msg} {
return return
} }
# -- Make sure our current branch exists.
#
if {$commit_type eq {initial}} {
lappend all_heads $current_branch
set all_heads [lsort -unique $all_heads]
populate_branch_menu
}
# -- Cleanup after ourselves. # -- Cleanup after ourselves.
# #
catch {file delete $msg_p} catch {file delete $msg_p}
@ -1275,7 +1341,7 @@ proc commit_committree {fd_wt curHEAD msg} {
# -- Let rerere do its thing. # -- Let rerere do its thing.
# #
if {[file isdirectory [gitdir rr-cache]]} { if {[file isdirectory [gitdir rr-cache]]} {
catch {exec git rerere} catch {git rerere}
} }
# -- Run the post-commit hook. # -- Run the post-commit hook.
@ -1299,6 +1365,14 @@ proc commit_committree {fd_wt curHEAD msg} {
if {[is_enabled singlecommit]} do_quit if {[is_enabled singlecommit]} do_quit
# -- Make sure our current branch exists.
#
if {$commit_type eq {initial}} {
lappend all_heads $current_branch
set all_heads [lsort -unique $all_heads]
populate_branch_menu
}
# -- Update in memory status # -- Update in memory status
# #
set selected_commit_type new set selected_commit_type new
@ -1876,11 +1950,24 @@ proc all_tracking_branches {} {
return [lsort -unique $all_trackings] return [lsort -unique $all_trackings]
} }
proc load_all_tags {} {
set all_tags [list]
set fd [open "| git for-each-ref --format=%(refname) refs/tags" r]
while {[gets $fd line] > 0} {
if {![regsub ^refs/tags/ $line {} name]} continue
lappend all_tags $name
}
close $fd
return [lsort $all_tags]
}
proc do_create_branch_action {w} { proc do_create_branch_action {w} {
global all_heads null_sha1 repo_config global all_heads null_sha1 repo_config
global create_branch_checkout create_branch_revtype global create_branch_checkout create_branch_revtype
global create_branch_head create_branch_trackinghead global create_branch_head create_branch_trackinghead
global create_branch_name create_branch_revexp global create_branch_name create_branch_revexp
global create_branch_tag
set newbranch $create_branch_name set newbranch $create_branch_name
if {$newbranch eq {} if {$newbranch eq {}
@ -1894,7 +1981,7 @@ proc do_create_branch_action {w} {
focus $w.desc.name_t focus $w.desc.name_t
return return
} }
if {![catch {exec git show-ref --verify -- "refs/heads/$newbranch"}]} { if {![catch {git show-ref --verify -- "refs/heads/$newbranch"}]} {
tk_messageBox \ tk_messageBox \
-icon error \ -icon error \
-type ok \ -type ok \
@ -1904,7 +1991,7 @@ proc do_create_branch_action {w} {
focus $w.desc.name_t focus $w.desc.name_t
return return
} }
if {[catch {exec git check-ref-format "heads/$newbranch"}]} { if {[catch {git check-ref-format "heads/$newbranch"}]} {
tk_messageBox \ tk_messageBox \
-icon error \ -icon error \
-type ok \ -type ok \
@ -1919,9 +2006,10 @@ proc do_create_branch_action {w} {
switch -- $create_branch_revtype { switch -- $create_branch_revtype {
head {set rev $create_branch_head} head {set rev $create_branch_head}
tracking {set rev $create_branch_trackinghead} tracking {set rev $create_branch_trackinghead}
tag {set rev $create_branch_tag}
expression {set rev $create_branch_revexp} expression {set rev $create_branch_revexp}
} }
if {[catch {set cmt [exec git rev-parse --verify "${rev}^0"]}]} { if {[catch {set cmt [git rev-parse --verify "${rev}^0"]}]} {
tk_messageBox \ tk_messageBox \
-icon error \ -icon error \
-type ok \ -type ok \
@ -1964,6 +2052,8 @@ trace add variable create_branch_head write \
[list radio_selector create_branch_revtype head] [list radio_selector create_branch_revtype head]
trace add variable create_branch_trackinghead write \ trace add variable create_branch_trackinghead write \
[list radio_selector create_branch_revtype tracking] [list radio_selector create_branch_revtype tracking]
trace add variable create_branch_tag write \
[list radio_selector create_branch_revtype tag]
trace add variable delete_branch_head write \ trace add variable delete_branch_head write \
[list radio_selector delete_branch_checktype head] [list radio_selector delete_branch_checktype head]
@ -1975,6 +2065,7 @@ proc do_create_branch {} {
global create_branch_checkout create_branch_revtype global create_branch_checkout create_branch_revtype
global create_branch_head create_branch_trackinghead global create_branch_head create_branch_trackinghead
global create_branch_name create_branch_revexp global create_branch_name create_branch_revexp
global create_branch_tag
set w .branch_editor set w .branch_editor
toplevel $w toplevel $w
@ -2038,6 +2129,19 @@ proc do_create_branch {} {
$all_trackings $all_trackings
grid $w.from.tracking_r $w.from.tracking_m -sticky w grid $w.from.tracking_r $w.from.tracking_m -sticky w
} }
set all_tags [load_all_tags]
if {$all_tags ne {}} {
set create_branch_tag [lindex $all_tags 0]
radiobutton $w.from.tag_r \
-text {Tag:} \
-value tag \
-variable create_branch_revtype \
-font font_ui
eval tk_optionMenu $w.from.tag_m \
create_branch_tag \
$all_tags
grid $w.from.tag_r $w.from.tag_m -sticky w
}
radiobutton $w.from.exp_r \ radiobutton $w.from.exp_r \
-text {Revision Expression:} \ -text {Revision Expression:} \
-value expression \ -value expression \
@ -2100,7 +2204,7 @@ proc do_delete_branch_action {w} {
} }
if {$check_rev eq {:none}} { if {$check_rev eq {:none}} {
set check_cmt {} set check_cmt {}
} elseif {[catch {set check_cmt [exec git rev-parse --verify "${check_rev}^0"]}]} { } elseif {[catch {set check_cmt [git rev-parse --verify "${check_rev}^0"]}]} {
tk_messageBox \ tk_messageBox \
-icon error \ -icon error \
-type ok \ -type ok \
@ -2114,10 +2218,10 @@ proc do_delete_branch_action {w} {
set not_merged [list] set not_merged [list]
foreach i [$w.list.l curselection] { foreach i [$w.list.l curselection] {
set b [$w.list.l get $i] set b [$w.list.l get $i]
if {[catch {set o [exec git rev-parse --verify $b]}]} continue if {[catch {set o [git rev-parse --verify $b]}]} continue
if {$check_cmt ne {}} { if {$check_cmt ne {}} {
if {$b eq $check_rev} continue if {$b eq $check_rev} continue
if {[catch {set m [exec git merge-base $o $check_cmt]}]} continue if {[catch {set m [git merge-base $o $check_cmt]}]} continue
if {$o ne $m} { if {$o ne $m} {
lappend not_merged $b lappend not_merged $b
continue continue
@ -2155,7 +2259,7 @@ Delete the selected branches?}
foreach i $to_delete { foreach i $to_delete {
set b [lindex $i 0] set b [lindex $i 0]
set o [lindex $i 1] set o [lindex $i 1]
if {[catch {exec git update-ref -d "refs/heads/$b" $o} err]} { if {[catch {git update-ref -d "refs/heads/$b" $o} err]} {
append failed " - $b: $err\n" append failed " - $b: $err\n"
} else { } else {
set x [lsearch -sorted -exact $all_heads $b] set x [lsearch -sorted -exact $all_heads $b]
@ -2366,7 +2470,7 @@ Staying on branch '$current_branch'."
# here, it Just Works(tm). If it doesn't we are in some really ugly # here, it Just Works(tm). If it doesn't we are in some really ugly
# state that is difficult to recover from within git-gui. # state that is difficult to recover from within git-gui.
# #
if {[catch {exec git symbolic-ref HEAD "refs/heads/$new_branch"} err]} { if {[catch {git symbolic-ref HEAD "refs/heads/$new_branch"} err]} {
error_popup "Failed to set current branch. error_popup "Failed to set current branch.
This working directory is only partially switched. This working directory is only partially switched.
@ -2876,14 +2980,16 @@ proc do_local_merge {} {
pack $w.source -fill both -expand 1 -pady 5 -padx 5 pack $w.source -fill both -expand 1 -pady 5 -padx 5
set cmd [list git for-each-ref] set cmd [list git for-each-ref]
lappend cmd {--format=%(objectname) %(refname)} lappend cmd {--format=%(objectname) %(*objectname) %(refname)}
lappend cmd refs/heads lappend cmd refs/heads
lappend cmd refs/remotes lappend cmd refs/remotes
lappend cmd refs/tags
set fr_fd [open "| $cmd" r] set fr_fd [open "| $cmd" r]
fconfigure $fr_fd -translation binary fconfigure $fr_fd -translation binary
while {[gets $fr_fd line] > 0} { while {[gets $fr_fd line] > 0} {
set line [split $line { }] set line [split $line { }]
set sha1([lindex $line 0]) [lindex $line 1] set sha1([lindex $line 0]) [lindex $line 2]
set sha1([lindex $line 1]) [lindex $line 2]
} }
close $fr_fd close $fr_fd
@ -2891,7 +2997,7 @@ proc do_local_merge {} {
set fr_fd [open "| git rev-list --all --not HEAD"] set fr_fd [open "| git rev-list --all --not HEAD"]
while {[gets $fr_fd line] > 0} { while {[gets $fr_fd line] > 0} {
if {[catch {set ref $sha1($line)}]} continue if {[catch {set ref $sha1($line)}]} continue
regsub ^refs/(heads|remotes)/ $ref {} ref regsub ^refs/(heads|remotes|tags)/ $ref {} ref
lappend to_show $ref lappend to_show $ref
} }
close $fr_fd close $fr_fd
@ -2972,7 +3078,14 @@ proc new_browser {commit} {
global next_browser_id cursor_ptr M1B global next_browser_id cursor_ptr M1B
global browser_commit browser_status browser_stack browser_path browser_busy global browser_commit browser_status browser_stack browser_path browser_busy
if {[winfo ismapped .]} {
set w .browser[incr next_browser_id] set w .browser[incr next_browser_id]
set tl $w
toplevel $w
} else {
set w {}
set tl .
}
set w_list $w.list.l set w_list $w.list.l
set browser_commit($w_list) $commit set browser_commit($w_list) $commit
set browser_status($w_list) {Starting...} set browser_status($w_list) {Starting...}
@ -2980,7 +3093,6 @@ proc new_browser {commit} {
set browser_path($w_list) $browser_commit($w_list): set browser_path($w_list) $browser_commit($w_list):
set browser_busy($w_list) 1 set browser_busy($w_list) 1
toplevel $w
label $w.path -textvariable browser_path($w_list) \ label $w.path -textvariable browser_path($w_list) \
-anchor w \ -anchor w \
-justify left \ -justify left \
@ -3030,8 +3142,8 @@ proc new_browser {commit} {
bind $w_list <Left> break bind $w_list <Left> break
bind $w_list <Right> break bind $w_list <Right> break
bind $w <Visibility> "focus $w" bind $tl <Visibility> "focus $w"
bind $w <Destroy> " bind $tl <Destroy> "
array unset browser_buffer $w_list array unset browser_buffer $w_list
array unset browser_files $w_list array unset browser_files $w_list
array unset browser_status $w_list array unset browser_status $w_list
@ -3040,7 +3152,7 @@ proc new_browser {commit} {
array unset browser_commit $w_list array unset browser_commit $w_list
array unset browser_busy $w_list array unset browser_busy $w_list
" "
wm title $w "[appname] ([reponame]): File Browser" wm title $tl "[appname] ([reponame]): File Browser"
ls_tree $w_list $browser_commit($w_list) {} ls_tree $w_list $browser_commit($w_list) {}
} }
@ -4161,7 +4273,7 @@ proc do_quit {} {
set rc_geometry {} set rc_geometry {}
} }
if {$cfg_geometry ne $rc_geometry} { if {$cfg_geometry ne $rc_geometry} {
catch {exec git config gui.geometry $cfg_geometry} catch {git config gui.geometry $cfg_geometry}
} }
} }
@ -4380,6 +4492,61 @@ proc do_commit {} {
commit_tree commit_tree
} }
proc do_credits {} {
global gitgui_credits
set w .credits_dialog
toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
label $w.header -text {git-gui Contributors} -font font_uibold
pack $w.header -side top -fill x
frame $w.buttons
button $w.buttons.close -text {Close} \
-font font_ui \
-command [list destroy $w]
pack $w.buttons.close -side right
pack $w.buttons -side bottom -fill x -pady 10 -padx 10
frame $w.credits
text $w.credits.t \
-background [$w.header cget -background] \
-yscrollcommand [list $w.credits.sby set] \
-width 20 \
-height 10 \
-wrap none \
-borderwidth 1 \
-relief solid \
-padx 5 -pady 5 \
-font font_ui
scrollbar $w.credits.sby -command [list $w.credits.t yview]
pack $w.credits.sby -side right -fill y
pack $w.credits.t -fill both -expand 1
pack $w.credits -side top -fill both -expand 1 -padx 5 -pady 5
label $w.desc \
-text "All portions are copyrighted by their respective authors
and are distributed under the GNU General Public License." \
-padx 5 -pady 5 \
-justify left \
-anchor w \
-borderwidth 1 \
-relief solid \
-font font_ui
pack $w.desc -side top -fill x -padx 5 -pady 5
$w.credits.t insert end "[string trim $gitgui_credits]\n"
$w.credits.t conf -state disabled
$w.credits.t see 1.0
bind $w <Visibility> "grab $w; focus $w"
bind $w <Key-Escape> [list destroy $w]
wm title $w [$w.header cget -text]
tkwait window $w
}
proc do_about {} { proc do_about {} {
global appvers copyright global appvers copyright
global tcl_patchLevel tk_patchLevel global tcl_patchLevel tk_patchLevel
@ -4396,11 +4563,15 @@ proc do_about {} {
button $w.buttons.close -text {Close} \ button $w.buttons.close -text {Close} \
-font font_ui \ -font font_ui \
-command [list destroy $w] -command [list destroy $w]
button $w.buttons.credits -text {Contributors} \
-font font_ui \
-command do_credits
pack $w.buttons.credits -side left
pack $w.buttons.close -side right pack $w.buttons.close -side right
pack $w.buttons -side bottom -fill x -pady 10 -padx 10 pack $w.buttons -side bottom -fill x -pady 10 -padx 10
label $w.desc \ label $w.desc \
-text "[appname] - a commit creation tool for Git. -text "git-gui - a graphical user interface for Git.
$copyright" \ $copyright" \
-padx 5 -pady 5 \ -padx 5 -pady 5 \
-justify left \ -justify left \
@ -4411,8 +4582,8 @@ $copyright" \
pack $w.desc -side top -fill x -padx 5 -pady 5 pack $w.desc -side top -fill x -padx 5 -pady 5
set v {} set v {}
append v "[appname] version $appvers\n" append v "git-gui version $appvers\n"
append v "[exec git version]\n" append v "[git version]\n"
append v "\n" append v "\n"
if {$tcl_patchLevel eq $tk_patchLevel} { if {$tcl_patchLevel eq $tk_patchLevel} {
append v "Tcl/Tk version $tcl_patchLevel" append v "Tcl/Tk version $tcl_patchLevel"
@ -4471,7 +4642,7 @@ proc do_options {} {
toplevel $w toplevel $w
wm geometry $w "+[winfo rootx .]+[winfo rooty .]" wm geometry $w "+[winfo rootx .]+[winfo rooty .]"
label $w.header -text "[appname] Options" \ label $w.header -text "Options" \
-font font_uibold -font font_uibold
pack $w.header -side top -fill x pack $w.header -side top -fill x
@ -4945,6 +5116,9 @@ enable_option branch
enable_option transport enable_option transport
switch -- $subcommand { switch -- $subcommand {
--version -
version -
browser -
blame { blame {
disable_option multicommit disable_option multicommit
disable_option branch disable_option branch
@ -5094,6 +5268,12 @@ if {[is_enabled branch]} {
-font font_ui -font font_ui
lappend disable_on_lock [list .mbar.branch entryconf \ lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state] [.mbar.branch index last] -state]
.mbar.branch add command -label {Reset...} \
-command do_reset_hard \
-font font_ui
lappend disable_on_lock [list .mbar.branch entryconf \
[.mbar.branch index last] -state]
} }
# -- Commit Menu # -- Commit Menu
@ -5168,6 +5348,34 @@ if {[is_enabled multicommit] || [is_enabled singlecommit]} {
[list .mbar.commit entryconf [.mbar.commit index last] -state] [list .mbar.commit entryconf [.mbar.commit index last] -state]
} }
# -- Merge Menu
#
if {[is_enabled branch]} {
menu .mbar.merge
.mbar.merge add command -label {Local Merge...} \
-command do_local_merge \
-font font_ui
lappend disable_on_lock \
[list .mbar.merge entryconf [.mbar.merge index last] -state]
.mbar.merge add command -label {Abort Merge...} \
-command do_reset_hard \
-font font_ui
lappend disable_on_lock \
[list .mbar.merge entryconf [.mbar.merge index last] -state]
}
# -- Transport Menu
#
if {[is_enabled transport]} {
menu .mbar.fetch
menu .mbar.push
.mbar.push add command -label {Push...} \
-command do_push_anywhere \
-font font_ui
}
if {[is_MacOSX]} { if {[is_MacOSX]} {
# -- Apple Menu (Mac OS X only) # -- Apple Menu (Mac OS X only)
# #
@ -5177,7 +5385,7 @@ if {[is_MacOSX]} {
.mbar.apple add command -label "About [appname]" \ .mbar.apple add command -label "About [appname]" \
-command do_about \ -command do_about \
-font font_ui -font font_ui
.mbar.apple add command -label "[appname] Options..." \ .mbar.apple add command -label "Options..." \
-command do_options \ -command do_options \
-font font_ui -font font_ui
} else { } else {
@ -5236,7 +5444,7 @@ set doc_path [file dirname [gitexec]]
set doc_path [file join $doc_path Documentation index.html] set doc_path [file join $doc_path Documentation index.html]
if {[is_Cygwin]} { if {[is_Cygwin]} {
set doc_path [exec cygpath --windows $doc_path] set doc_path [exec cygpath --mixed $doc_path]
} }
if {$browser eq {}} { if {$browser eq {}} {
@ -5280,6 +5488,20 @@ bind all <$M1B-Key-W> {destroy [winfo toplevel %W]}
# -- Not a normal commit type invocation? Do that instead! # -- Not a normal commit type invocation? Do that instead!
# #
switch -- $subcommand { switch -- $subcommand {
--version -
version {
puts "git-gui version $appvers"
exit
}
browser {
if {[llength $argv] != 1} {
puts stderr "usage: $argv0 browser commit"
exit 1
}
set current_branch [lindex $argv 0]
new_browser $current_branch
return
}
blame { blame {
if {[llength $argv] != 2} { if {[llength $argv] != 2} {
puts stderr "usage: $argv0 blame commit path" puts stderr "usage: $argv0 blame commit path"
@ -5302,7 +5524,7 @@ gui {
# fall through to setup UI for commits # fall through to setup UI for commits
} }
default { default {
puts stderr "usage: $argv0 \[{blame|citool}\]" puts stderr "usage: $argv0 \[{blame|browser|citool}\]"
exit 1 exit 1
} }
} }
@ -5326,28 +5548,6 @@ pack .branch.l1 -side left
pack .branch.cb -side left -fill x pack .branch.cb -side left -fill x
pack .branch -side top -fill x pack .branch -side top -fill x
if {[is_enabled branch]} {
menu .mbar.merge
.mbar.merge add command -label {Local Merge...} \
-command do_local_merge \
-font font_ui
lappend disable_on_lock \
[list .mbar.merge entryconf [.mbar.merge index last] -state]
.mbar.merge add command -label {Abort Merge...} \
-command do_reset_hard \
-font font_ui
lappend disable_on_lock \
[list .mbar.merge entryconf [.mbar.merge index last] -state]
menu .mbar.fetch
menu .mbar.push
.mbar.push add command -label {Push...} \
-command do_push_anywhere \
-font font_ui
}
# -- Main Window Layout # -- Main Window Layout
# #
panedwindow .vpane -orient vertical panedwindow .vpane -orient vertical
@ -5552,9 +5752,6 @@ bind_button3 $ui_comm "tk_popup $ctxm %X %Y"
# -- Diff Header # -- Diff Header
# #
set current_diff_path {}
set current_diff_side {}
set diff_actions [list]
proc trace_current_diff_path {varname args} { proc trace_current_diff_path {varname args} {
global current_diff_path diff_actions file_states global current_diff_path diff_actions file_states
if {$current_diff_path eq {}} { if {$current_diff_path eq {}} {
@ -5747,7 +5944,6 @@ unset ui_diff_applyhunk
# -- Status Bar # -- Status Bar
# #
set ui_status_value {Initializing...}
label .status -textvariable ui_status_value \ label .status -textvariable ui_status_value \
-anchor w \ -anchor w \
-justify left \ -justify left \
@ -5821,15 +6017,6 @@ unset i
set file_lists($ui_index) [list] set file_lists($ui_index) [list]
set file_lists($ui_workdir) [list] set file_lists($ui_workdir) [list]
set HEAD {}
set PARENT {}
set MERGE_HEAD [list]
set commit_type {}
set empty_tree {}
set current_branch {}
set current_diff_path {}
set selected_commit_type new
wm title . "[appname] ([file normalize [file dirname [gitdir]]])" wm title . "[appname] ([file normalize [file dirname [gitdir]]])"
focus -force $ui_comm focus -force $ui_comm
@ -5904,7 +6091,7 @@ if {[is_enabled transport]} {
if {[is_enabled multicommit]} { if {[is_enabled multicommit]} {
set object_limit 2000 set object_limit 2000
if {[is_Windows]} {set object_limit 200} if {[is_Windows]} {set object_limit 200}
regexp {^([0-9]+) objects,} [exec git count-objects] _junk objects_current regexp {^([0-9]+) objects,} [git count-objects] _junk objects_current
if {$objects_current >= $object_limit} { if {$objects_current >= $object_limit} {
if {[ask_popup \ if {[ask_popup \
"This repository currently has $objects_current loose objects. "This repository currently has $objects_current loose objects.