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>
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>
If we have more than our desired number of objects and we try to
open the "Do you want to repack now?" dialog we cannot include a
-parent . argument if the main window has not been mapped yet.
On Mac OS X it appears this window isn't mapped right away, so we
had better hang avoid including it.
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>
This cat-file was done on maint, where we did not have git_read
available to us. But here on master we do, so we should make
use of it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
From Johannes Sixt <J.Sixt@eudaptics.com>:
> It seems that MSYS's wish does some quoting for Bourne shells,
> in particular, escape the first '{' of the "^{tree}" suffix, but
> then it uses cmd.exe to run "git rev-parse". However, cmd.exe does
> not remove the backslash, so that the resulting rev expression
> ends up in git's guts as unrecognizable garbage: rev-parse fails,
> and git-gui hickups in a way that it must be restarted.
Johannes originally submitted a patch to this section of commit.tcl
to use `git rev-parse $PARENT:`, but not all versions of Git will
accept that format. So I'm just taking the really simple approach
here of scanning the first line of the commit to grab its tree.
About the same cost, but works everywhere.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because we are trying to execute /bin/sh we know it must be a real
Windows executable and thus ends with the standard .exe suffix.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We cannot execute the git directory, it is not a valid Tcl command
name. Instead we just want to pass it as an argument to our sq
proc.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we get more than 80 characters of text in a single line odds
are it is output from git-fetch or git-push and its showing a
lot of detail off to the right edge that is not so important to
the average user. We still want to make sure we show everything
we need, but we can get away with that information being off to
the side with a horizontal scrollbar.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Our file browser was showing bad output as it did not properly buffer
a partial record when read from `ls-tree -z`. This did not show up on
my Mac OS X system as most trees are small, the pipe buffers generally
big and `ls-tree -z` was generally fast enough that all data was ready
before Tcl started to read. However on my Cygwin system one of my
production repositories had a large enough tree and packfile that it
took a couple of pipe buffers for `ls-tree -z` to complete its dump.
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>
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>
Sometimes switching between branches can take more than a second or
two, in which case `git checkout` would normally have shown a small
progress meter to the user on the terminal to let them know that we
are in fact working, and give them a reasonable idea of when we may
finish.
We now do obtain that progress meter from read-tree -v and include
it in our main window's status bar. This allows users to see how
many files we have checked out, how many remain, and what percentage
of the operation is completed. It should help to keep users from
getting bored during a large checkout operation.
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>
Our blame viewer has had a very fancy progress bar at the bottom of
the window that shows the current status of the blame engine, which
includes the number of lines completed as both a text and a graphical
meter. I want to reuse this meter system in other places, such as
during a branch switch where read-tree -v can give us a progress
meter for any long-running operation.
This change extracts the code and refactors it as a widget that we
can take advantage of in locations other than in the blame viewer.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user double clicks a branch in the checkout dialog then they
probably want to start the checkout process on that branch. I found
myself doing this without realizing it, and of course it did nothing
as there was no action bound to the listbox's Double-Button-1 event
handler. Since I did it without thinking, others will probably also
try, and expect the same behavior.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we have specifications listed in our revision picker mega-widget
then we should default the selection within that widget to the first
ref available. This way the user does not need to use the spacebar
to activate the selection of a ref within the box; instead they can
navigate up/down with the arrow keys and be done with it.
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 user is creating a new local branch and has selected to use
a tracking branch as the starting revision they probably want to
make sure they are using the absolute latest version available of
that branch.
We now offer a checkbox "Fetch Tracking Branch" (on by default)
that instructs git-gui to run git-fetch on just that one branch
before resolving the branch name into a commit SHA-1 and making
(or updating) the local branch.
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>
When trying to create a branch from a tag most people are looking
for a recent tag, not one that is ancient history. Rather than
sorting tags by their string we now sort them by taggerdate, as
this places the recent tags at the top of the list and the very
old ones at the end. Tag date works nicely as an approximation
of the actual history order of commits.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
One of my production repositories has hundreds of remote tracking
branches. Trying to navigate these through a popup menu is just
not possible. The list is far larger than the screen and it does
not scroll fast enough to efficiently select a branch name when
trying to create a branch or delete a branch.
This is major rewrite of the revision chooser mega-widget. We
now use a single listbox for all three major types of named refs
(heads, tracking branches, tags) and a radio button group to pick
which of those namespaces should be shown in the listbox. A filter
field is shown to the right allowing the end-user to key in a glob
specification to filter the list they are viewing. The filter is
always taken as substring, so we assume * both starts and ends the
pattern the user wanted but otherwise treat it as a glob pattern.
This new picker works out really nicely. What used to take me at
least a minute to find and select a branch now takes mere seconds.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user elects to create a local branch that has the same name
as an existing branch and we can fast-forward the local branch to
the selected revision we might as well do the fast-forward for the
user, rather than making them first switch to the branch then merge
the selected revision into it. After all, its really just a fast
forward. No history is lost. The resulting branch checkout may
also be faster if the branch we are switching from is closer to
the new revision.
Likewise we also now allow the user to reset the local branch if
it already exists but would not fast-forward. However before we
do the actual reset we tell the user what commits they are going to
lose by showing the oneline subject and abbreviated sha1, and we also
let them inspect the range of commits in gitk.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Some workflows have users create a local branch that matches a remote
branch they have fetched from another repository. If the user wants
to push their changes back to that remote repository then they probably
want to use the same branch name locally so that git-gui's push dialog
can setup the push refspec automatically.
To prevent typos with the local branch name we now offer an option to
use the remote tracking branch name as the new local branch name.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
In the next change I want to let the user create their local branch
name to match the remote branch name, so that the existing push
dialog can push the branch back up to the remote repository without
needing to do any sort of remapping. To do that we need to know
exactly what branch name the remote system is using.
So all_tracking_branches returns a list of specifications, where
each specification is itself a list of:
- local ref name (destination we fetch into)
- remote name (repository we fetch from)
- remote ref name (source ref we fetch from)
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Most people using Git 1.5.x and later are using the newer style
of remotes layout where all of their tracking branches are in
refs/remotes and refs/heads contains only the user's own local
branches.
In such a situation we can avoid calling is_tracking_branch
for each head we are considering because we know that all of
the heads must be local branches if no fetch option or Pull:
line maps a branch into that namespace.
If however any remote maps a remote branch into a local
tracking branch that resides in refs/heads we do exactly
what we did before, which requires scanning through all
fetch lines in case any patterns are matched.
I also switched some regexp/regsub calls to string match
as this can be a faster operation for prefix matching.
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>
Its handy to be able to ask an object to do something for you by
handing it a subcommand. For example if we want to get the value
of an object's private field the object could expose a method that
would return that value. Application level code can then invoke
"$inst get" to perform the method call.
Tk uses this pattern for all of its widgets, so we'd certainly
like to use it for our own mega-widgets that we might develop.
Up until now we haven't needed such functionality, but I'm working
on a new revision picker mega-widget that would benefit from it.
To make this work we have to change the definition of $this to
actually be a procedure within the namespace. By making $this a
procedure any caller that has $this can call subcommands by passing
them as the first argument to $this. That subcommand then needs
to call the proper subroutine.
Placing the dispatch procedure into the object's variable namespace
ensures that it will always be deleted when the object is deleted.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Our blame viewer only grabbed the first initial of the git.git
author string "Simon 'corecode' Schubert". Here the problem was we
looked at Simon, pulled the S into the author initials, then saw
the single quote as the start of the next name and did not like
this character as it was not an uppercase letter.
We now skip over single quoted nicknames placed within the author
name field and grab the initials following it. So the above name
will get the initials SS, rather than just S.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The blame window shows "who wrote the piece originally" and "who
moved it there" in two columns. In order to identify the former
more correctly, it helps to use the new -w option.
[sp: Minor change to only enable -w if underlying git >= 1.5.3]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Recently in git.git change b4372ef136 Johannes Schindelin taught
git-commit.sh to invoke (or skip) calling git-rerere based upon
the rerere.enabled configuration setting:
So, check the config variable "rerere.enabled". If it is set
to "false" explicitely, do not activate rerere, even if
.git/rr-cache exists. This should help when you want to disable
rerere temporarily.
If "rerere.enabled" is not set at all, fall back to detection
of the directory .git/rr-cache.
We now do the same logic in git-gui's own commit implementation.
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
Apparently under some setups on Windows Tk is hiding our file
extension recommendation of ".bat" from the user and that is
allowing the user to create a shortcut file which has no file
extension. Double clicking on such a file in Windows Explorer
brings up the associate file dialog, as Windows does not know
what application to launch.
We now append the file extension ".bat" to the filename of the
shortcut file if it has no extension or if it has one but it is
not ".bat".
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The status field of the remote branch delete dialog was marked to
expand, which meant that if the user grew the window vertically
most of the new vertical height was given to the status field and
not to the branch list. Since the status field is just a single
line of text there is no reason for it to gain additional height,
instead we should make sure all additional height goes to the
branch list.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Most users these days are using a windowing system attached to a
monitor that has more than 600 pixels worth of vertical space
available for application use. As most files stored by Git are
longer than they are wide (have more lines than columns) we want
to dedicate as much vertical space as we can to the viewer.
Instead of always starting the window at ~600 pixels high we now
start the window 100 pixels shorter than the screen claims it has
available to it. This -100 rule is used because some popular OSen
add menu bars at the top of the monitor, and docks on the bottom
(e.g. Mac OS X, CDE, KDE). We want to avoid making our window too
big and causing the window's resize control from being out of reach
of the user.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Pressing the escape key while in the merge dialog cancels the merge
and correctly unlocks the index. Unfortunately this is not true of
the Cancel button, using it closes the dialog but does not release
the index lock, rendering git-gui frozen until you restart it. We
now properly release the index lock when the Cancel button is used.
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
Johannes Sixt reported that MinGW/MSYS does not have a nice.exe to
drop the priority of a child process when it gets spawned. So we
have to avoid trying to start `git blame` through nice when we are
on Windows and do not have Cygwin available to us.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The blame viewer is composed of two different areas, the file
area on top and the commit area on the bottom. If users are
trying to shift the focus it is probably because they want to
shift from one area to the other, so we just setup Tab and
Shift-Tab to jump from the one half to the other in a cycle.
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
b6047c5a8166a71e01c6b63ebbb67c6894d95114.
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>