Like our blame subcommand the browser subcommand now accepts both
a revision and a path, just a revision or just a path. This way
the user can start the subcommand on any branch, or on any subtree.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A long time ago Linus Torvalds tried to run git-gui on a bare
repository to look at the blame viewer, but it failed to start
because we required that the user run us only from within a
working directory that had a normal git repository associated
with it.
This change relaxes that requirement so that you can start the
tree browser or the blame viewer against a bare repository. In
the latter case we do require that you provide a revision and a
pathname if we cannot find the pathname in the current working
directory.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
By moving our feature option determination up before we look for GIT_DIR
we can make a decision about whether or not we need a working tree up
front, before we look for GIT_DIR. A future change could then allow
us to start in a bare Git repository if we only need access to the ODB.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I'm moving the code related to looking to see if we should GC now
into a procedure closer to where it belongs, the database module.
This reduces our script by a few lines for the single commit case
(aka citool). But really it just is to help organize the code.
We now perform the check after we have been running for at least
1 second. This way the main window has time to open up and our
dialog (if we open it) will attach to the main window, instead of
floating out in no-mans-land like it did before on Mac OS X.
I had to use a wait of a full second here as a wait of 1 millisecond
made our console install itself into the main window. Apparently we
had a race condition with the console code where both the console and
the main window thought they were the main window.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Some users may do odd things, like tag their own private version of
Git with an annotated tag such as 'testver', then compile that git
and try to use it with git-gui. In such a case `git --version` will
give us 'git version testver', which is not a numeric argument that
we can pass off to our version comparsion routine.
We now check that the cleaned up git version is a going to pass the
version comparsion routine without failure. If it has a non-numeric
component, or lacks at least a minor revision then we ask the user to
confirm they really want to use this version of git within git-gui.
If they do we shall assume it is git 1.5.0 and run with only the code
that will support.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Instead of running a full git-count-objects to count all of the loose
objects we can get a reasonably close approximation by counting the
number of files in the .git/objects/42 subdirectory. This works out
reasonably well because the SHA-1 hash has a fairly even distribution,
so every .git/objects/?? subdirectory should get a relatively equal
number of files. If we have at least 8 files in .git/objects/42 than it
is very likely there is about 8 files in every other directory, leaving
us with around 2048 loose objects.
This check is much faster, as we need to only perform a readdir of
a single directory, and we can do it directly from Tcl and avoid the
costly fork+exec.
All of the credit on how clever this is goes to Linus Torvalds; he
suggested using this trick in a post commit hook to repack every so
often.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Not every caller of 'git' or 'git_pipe' wants to use nice to lower the
priority of the process its executing. In many cases we may never use
the nice process to launch git. So we can avoid searching our $PATH
to locate a suitable nice if we'll never actually use it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The git-gui version check doesn't handle versions of the form
n.n.n.GIT which you can get by installing from an tarball produced by
git-archive.
Without this change you get an error of the form:
'Error in startup script: expected version number but got "1.5.3.GIT"'
Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
On Windows (which includes Cygwin) Tcl defaults to leaving the EOF
character of input file streams set to the ASCII EOF character, but
if that character were to appear in the data stream then Tcl will
close the channel early. So we have to disable eofchar on Windows.
Since the default is disabled on all platforms except Windows, we
can just disable it everywhere to prevent any sort of read problem.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
My prior change to allow git-gui to run with a version of Git
that was built from a working directory that had uncommitted
changes didn't account for the pattern starting with -, and
that confused Tcl.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user is running a 'dirty' version of git (one compiled in a
working directory with modified files) we want to just assume it
was a committed version, as we really only look at the part that
came from a real annotated tag anyway.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We now embed any GIT_* and SSH_* environment variables as well as
the path to the git wrapper executable into the Mac OS X .app file.
This should allow us to restore the environment properly when
we restart.
We also try to use proper Bourne shell single quoting when we can,
as this avoids any sort of problems that might occur due to a path
containing shell metacharacters.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that we are pretty strict about setting up own absolute paths to
any git helper (saving a marginal runtime cost to resolve the tool)
we can do the same in our console widget by making sure all console
execs go through git_read if they are a git subcommand, and if not
make sure they at least try to use the Tcl 2>@1 IO redirection if
possible, as it should be faster than |& cat.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we cannot locate a .exe for a git tool that we want to run than
it may just be a Bourne shell script as these are popular in Git.
In such a case the first line of the file will say "#!/bin/sh" so
a UNIX kernel knows what program to start to parse and run that.
But Windows doesn't support shbang lines, and neither does the Tcl
that comes with Cygwin.
We can pass control off to the git wrapper as that is a real Cygwin
program and can therefore start the Bourne shell script, but that is
at least two fork+exec calls to get the program running. One to do
the fork+exec of the git wrapper and another to start the Bourne shell
script. If the program is run multiple times it is rather expensive
as the magic shbang detection won't be cached across executions.
On MinGW/MSYS we don't have the luxury of such magic detection. The
MSYS team has taught some of this magic to the git wrapper, but again
its slower than it needs to be as the git wrapper must still go and
run the Bourne shell after it is called.
We now attempt to guess the shbang line on Windows by reading the
first line of the file and building our own command line path from
it. Currently we support Bourne shell (sh), Perl and Python. That
is the entire set of shbang lines that appear in git.git today.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We know that the version subcommand of git is special. It does not
currently have an executable link installed into $gitexecdir and we
therefore would never match it with one of our file exists tests.
So we forward any invocations to it directly to the git wrapper, as
it is a builtin within that executable.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we cannot locate a command in $gitexecdir on our own then it may
just be because we are supposed to run it by `git $name` rather than
by `git-$name`. Many commands are now builtins, more are likely to
go in that direction, and we may see the hardlinks in $gitexecdir go
away in future versions of git.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The master Makefile in git.git installs gitk into bindir, not
gitexecdir, which means gitk is located as a sibling of the git
wrapper and not as though it were a git helper tool.
We can also avoid some Tcl concat operations by letting eval do
all of the heavy lifting; we have two proper Tcl lists ($cmd and
$revs) that we are joining together and $revs is currently never
an empty list.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Rather than making the C library search for git every time we want
to execute it we now search for the main git wrapper at startup, do
symlink resolution, and then always use the absolute path that we
found to execute the binary later on. This should save us some
cycles, especially on stat challenged systems like Cygwin/Win32.
While I was working on this change I also converted all of our
existing pipes ([open "| git ..."]) to use two new pipe wrapper
functions. These functions take additional options like --nice
and --stderr which instructs Tcl to take special action, like
running the underlying git program through `nice` (if available)
or redirect stderr to stdout for capture in Tcl.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that we have a fancy status bar mega-widget we can reuse that
within our main window. This opens the door for implementating
future improvements like a progress bar.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the end-user feeds us an abbreviated SHA-1 on the command line for
`git gui browser` or `git gui blame` we now unabbreviate the value
through `git rev-parse` so that the title section of the blame or
browser window shows the user the complete SHA-1 as Git determined
it to be.
If the abbreviated value was ambiguous we now complain with the
standard error message(s) as reported by git-rev-parse --verify,
so that the user can understand what might be wrong and correct
their command line.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This is a major rewrite of the way we perform switching between
branches and the subsequent update of the working directory. Like
core Git we now use a single code path to perform all changes: our
new checkout_op class. We also use it for branch creation/update
as it integrates the tracking branch fetch process along with a
very basic merge (fast-forward and reset only currently).
Because some users have literally hundreds of local branches we
use the standard revision picker (with its branch filtering tool)
to select the local branch, rather than keeping all of the local
branches in the Branch menu. The branch menu listing out all of
the available branches is simply not sane for those types of huge
repositories.
Users can now checkout a detached head by ticking off the option
in the checkout dialog. This option is off by default for the
obvious reason, but it can be easily enabled for any local branch
by simply checking it. We also detach the head if any non local
branch was selected, or if a revision expression was entered.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I'm really starting to dislike global variables. The ui_status_value
global varible is just one of those that seems to appear in a lot of
code and in many cases we didn't even declare it "global" within the
proc that updates it so we haven't always been getting all of the
updates we expected to see.
This change introduces two new global procs:
ui_status $msg; # Sets the status bar to show $msg.
ui_ready; # Changes the status bar to show "Ready."
The second (special) form is used because we often update the area
with this message once we are done processing a block of work and
want the user to know we have completed it.
I'm not fixing the cases that appear in lib/branch.tcl right now
as I'm actually in the middle of a huge refactoring of that code
to support making a detached HEAD checkout.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the current branch is not a symbolic-ref that points to a
name in the refs/heads/ namespace we now just assume that the
head is a detached head. In this case we return the special
branch name of HEAD rather than empty string, as HEAD is a
valid revision specification and the empty string is not.
I have also slightly improved the current-branch function by
using string functions to parse the symbolic-ref data. This
should be slightly faster than using a regsub. I think the
code is clearer too.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
In some workflows users will want to almost always just create a new
local branch that matches a remote branch. In this type of workflow
it is handy to have the new branch dialog default to "Match Tracking
Branch" and "Starting Revision"-Tracking Branch", with the focus in
the branch filter field. This can save users working on this type
of workflow at least two mouse clicks every time they create a new
local branch or switch to one with a fast-forward.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A simple refactoring of the delete branch dialog to allow use of
the class construct to better organize the code and to reuse the
revision selection code of our new choose_rev mega-widget.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This rather large change pulls the "Starting Revision" part of the
new branch dialog into a mega widget that we can use anytime we
need to select a commit SHA-1. To make use of the mega widget I
have also refactored the branch dialog to use the class system,
much like the delete remote branch dialog already does.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Some newer features of git-gui want to rely on features that are
new to Git 1.5.3. Since they were added as part of the 1.5.3
development series we cannot use those features with versions of
Git that are older than 1.5.3, such as from the stable 1.5.2 series.
We introduce [git-version >= 1.5.3] to allow the caller to get a
response of 0 if the current version of git is < 1.5.3 and 1 if
the current version of git is >= 1.5.3. This makes it easy to
setup conditional code based upon the version of Git available to
us at runtime.
Instead of parsing the version text by hand we now use the Tcl
[package vcompare] subcommand to compare the two version strings.
This works nicely, as Tcl as already done all of the hard work
of doing version comparsions. But we do have to remove the Git
specific components such as the Git commit SHA-1, commit count and
release candidate suffix (rc) as we want only the final release
version number.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint:
git-gui: Ensure windows shortcuts always have .bat extension
git-gui: Include a Push action on the left toolbar
git-gui: Bind M1-P to push action
git-gui: Don't bind F5/M1-R in all windows
Conflicts:
git-gui.sh
Pushing changes to a remote system is a very common action for
many users of git-gui, so much so that in some workflows a user
is supposed to push immediately after they make a local commit
so that their change(s) are immediately available for their
teammates to view and build on top of.
Including the push button right below the commit button on the
left toolbar indicates that users should probably perform this
action after they have performed the commit action.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users often need to be able to push the current branch so that they
can publish their recent changes to anyone they are collaborating
with on the project. Associating a keyboard action with this will
make it easier for keyboard-oriented users to quickly activate the
push features.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We actually only want our F5/M1-R keystroke bound in the main window.
Within a browser/blame/console window pressing these keys should not
execute the rescan action.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
On 'Visualize ...', a gitk process is started. Since it is run in the
background, catching a possible startup error doesn't work, and the error
output goes to the console git-gui is started from. The most probable
startup error is that gitk is not installed; so before trying to start,
check for the existence of the gitk program, and popup an error message
unless it's found.
This was noticed and reported by Paul Wise through
http://bugs.debian.org/429810
Signed-off-by: Gerrit Pape <pape@smarden.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint:
git-gui: Don't require a .pvcsrc to create Tools/Migrate menu hack
git-gui: Don't nice git blame on MSYS as nice is not supported
git-gui: Don't require $DISPLAY just to get --version
The Tools/Migrate menu option is a hack just for me. Yes, that's
right, git-gui has a hidden feature that really only works for me,
and the users that I support within my day-job's great firewall.
The menu option is not supported outside of that environment.
In the past we only enabled Tools/Migrate if our special local
script 'gui-miga' existed in the proper location, and if there
was a special '.pvcsrc' in the top level of the working directory.
This latter test for the '.pvcsrc' file is now failing, as the file
was removed from all Git repositories due to changes made to other
tooling within the great firewall's realm.
I have changed the test to only work on Cygwin, and only if the
special 'gui-miga' is present. This works around the configuration
changes made recently within the great firewall's realm, but really
this entire Tools/Migrate thing should be abstracted out into some
sort of plugin system so other users can extend git-gui as they need.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Junio asked that we don't force the user to have a valid X11 server
configured in $DISPLAY just to obtain the output of `git gui version`.
This makes sense, the user may be an automated tool that is running
without an X server available to it, such as a build script or other
sort of package management system. Or it might just be a user working
in a non-GUI environment and wondering "what version of git-gui do I
have installed?".
Tcl has a lot of warts, but one of its better ones is that a comment
can be continued to the next line by escaping the LF that would have
ended the comment using a backslash-LF sequence. In the past we have
used this trick to escape away the 'exec wish' that is actually a Bourne
shell script and keep Tcl from executing it.
I'm using that feature here to comment out the Bourne shell script and
hide it from the Tcl engine. Except now our Bourne shell script is a
few lines long and checks to see if it should print the version, or not.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because Tk does not assure us the order that it will process
children in before it destroys the main toplevel we cannot safely
save our geometry data during a "bind . <Destroy>" event binding.
The geometry may have already changed as a result of a one or
more children being removed from the layout. This was pointed
out in gitk by Mark Levedahl, and patched over there by commit
b6047c5a81.
So we now also use "wm protocol . WM_DELETE_WINDOW" to detect when
the window is closed by the user, and forward that close event to
our main do_quit routine.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Apparently git-commit.sh (the command line commit user interface in
core Git) always gives precedence to the prior commit's message if
`commit --amend` is used and a $GIT_DIR/MERGE_MSG file also exists.
We actually were doing the same here in git-gui, but the amended
message got lost if $GIT_DIR/MERGE_MSG already existed because
we started a rescan immediately after loading the prior commit's
body into the edit buffer. When that happened the rescan found
MERGE_MSG existed and replaced the commit message buffer with the
contents of that file. This meant the user never saw us pick up
the commit message of the prior commit we are about to replace.
Johannes Sixt <J.Sixt@eudaptics.com> found this bug in git-gui by
running `git cherry-pick -n $someid` and then trying to amend the
prior commit in git-gui, thus combining the contents of $someid
with the contents of HEAD, and reusing the commit message of HEAD,
not $someid. With the recent changes to make cherry-pick use the
$GIT_DIR/MERGE_MSG file Johannes saw git-gui pick up the message
of $someid, not HEAD. Now we always use HEAD if we are amending.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint: (38 commits)
git-gui: Changed blame header bar background to match main window
git-gui: Favor the original annotations over the recent ones
git-gui: Improve our labeling of blame annotation types
git-gui: Use three colors for the blame viewer background
git-gui: Jump to original line in blame viewer
git-gui: Display both commits in our tooltips
git-gui: Run blame twice on the same file and display both outputs
git-gui: Display the "Loading annotation..." message in italic
git-gui: Rename fields in blame viewer to better descriptions
git-gui: Label the uncommitted blame history entry
git-gui: Switch internal blame structure to Tcl lists
git-gui: Cleanup redundant column management in blame viewer
git-gui: Better document our blame variables
git-gui: Remove unused commit_list from blame viewer
git-gui: Automatically expand the line number column as needed
git-gui: Make the line number column slightly wider in blame
git-gui: Use lighter colors in blame view
git-gui: Remove unnecessary space between columns in blame viewer
git-gui: Remove the loaded column from the blame viewer
git-gui: Clip the commit summaries in the blame history menu
...
If the user clicks on a line region that we haven't yet received
an annotation for from git-blame we show them "Loading annotation".
But I don't want the user to confuse this loading message with a
commit whose first line is "Loading annotation" and think we messed
up our display somehow. Since we never use italics for anything
else, I'm going with the idea that italic slant can be used to show
data is missing/elided out at the time being.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The default font was already bold, so marking the selected file with bold
font did not work. Change that to lightgray background.
Also, the header colors are now softer, giving better readability.
Signed-off-by: Matthijs Melchior <mmelchior@xs4all.nl>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint:
Revert "Make the installation target of git-gui a little less chatty"
git-gui: Verify Tcl/Tk is new enough for our needs
git-gui: Attach font_ui to all spinbox widgets
For quite a while we have been assuming the user is running on
a Tcl/Tk 8.4 or later platform. This may not be the case on
some very old systems. Unfortunately I am pretty far down the
path of using the Tcl/Tk 8.4 commands and options and cannot
easily work around them to support earlier versions of Tcl/Tk.
So we'll check that we are using the correct version up front,
and if not we'll stop with a related error message.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Earlier I missed making sure our spinbox widgets used the same font
as the other widgets around them. This meant that using a main font
with a size of 20 would make every widget in the options dialog huge,
but the spinboxes would be left with whatever the OS native font is.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Its wrong to exit the application if we destroy a random widget
contained withing something else; especially if its some small
trivial thing that has no impact on the overall operation.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To improve performance on fork+exec impoverished systems (such as
Windows) we want to avoid running git-symbolic-ref on every rescan
if we can do so. A quick way to implement such an avoidance is to
just read the HEAD ref ourselves; we'll either see it as a symref
(starts with "ref: ") or we'll see it as a detached head (40 hex
digits). In either case we can treat that as our current branch.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>