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>
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>
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>
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>
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>
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>
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>
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>
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>
Alex Riesen wanted a quieter installation process for git and its
contained git-gui. His earlier patch to do this failed to work
properly when V=1, and didn't really give a great indication of
what the installation was doing.
These rules are a little bit on the messy side, as each of our
install actions is composed of at least two variables, but in the
V=1 case the text is identical to what we had before, while in the
non-V=1 case we use some more complex rules to show the interesting
details, and hide the less interesting bits.
We now can also set QUIET= (nothing) to see the rules that are used
when V= (nothing), so we can debug those too if we have to. This is
actually a side-effect of how we insert the @ into the rules we use
for the "lists of things", like our builtins or our library files.
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>
Mark Levedahl <mlevedahl@gmail.com> noted that installation on Cygwin
to /usr/bin can cause problems with the automatic guessing of our
library location. The problem is that installation to /usr/bin
means we actually have:
/usr/bin = c:\cygwin\bin
/usr/share = c:\cygwin\usr\share
So git-gui guesses that its library should be found within the
c:\cygwin\share directory, as that is where it should be relative
to the script itself in c:\cygwin\bin.
In my first version of this patch I tried to use `cygpath` to resolve
/usr/bin and /usr/share to test that they were in the same relative
locations, but that didn't work out correctly as we were actually
testing /usr/share against itself, so it always was equal, and we
always used relative paths. So my original solution was quite wrong.
Mark suggested we just always disable relative behavior on Cygwin,
because of the complexity of the mount mapping problem, so that's
all I'm doing.
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>
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>
Earlier git.git applied a large "war on whitespace" patch that was
created using 'apply --whitespace=strip'. Unfortunately a few of
git-gui's own files got caught in the mix and were also cleaned up.
That was a6080a0a44d5ead84db3dabbbc80e82df838533d.
This patch is needed in git-gui.git to reapply those exact same
changes here, otherwise our version generator script is unable to
obtain our version number from git-describe when we are hosted in
the git.git repository.
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
...
The main window's diff header bar background switched from orange
to gold recently, and I liked the effect it had on readability of
the text. Since I wanted the blame viewer to match, here it is.
Though this probably should be a user defined color, or at least
a constant somewhere that everyone can reference.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Usually when you are looking at blame annotations for a region of
a file you are more interested in why something was originally
done then why it is here now. This is because most of the time
when we get original annotation data we are looking at a simple
refactoring performed to better organize code, not to change its
semantic meaning or function. Reorganizations are sometimes of
interest, but not usually.
We now show the original commit data first in the tooltip. This
actually looks quite nice as the original commit will usually have an
author date prior to the current (aka move/copy) annotation's commit,
so the two commits will now tend to appear in chronological order.
I also found myself to always be clicking on the line of interest
in the file column but I always wanted the original tracking data
and not the move/copy data. So I changed our default commit from
$asim_data (the simple move/copy annotation) to the more complex
$amov_data (the -M -C -C original annotation).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
It feels wrong to call the -M -C -C annotations "move/copy tracking"
as they are actually the original locations. So I'm relabeling
the status bar to show "copy/move tracking annotations" for the
current file (no -M -C -C) as that set of annotations tells us who
put the hunk here (who moved/copied it). I'm now calling the -M
-C -C pass "original location annotations" as that's what we're
really digging for.
I also tried to clarify some of the text in the hover tooltip.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To prevent neighboring lines that are different commits from using
the same background color we now use 3 colors and assign them
by selecting the color that is not used before or after the line
in question. We still color "on the fly" as we receive hunks from
git-blame, but we delay our color decisions until we are getting
the original location data (the slower -M -C -C pass) as that is
usually more fine-grained than the current location data.
Credit goes to Martin Waitz for the tri-coloring concept.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When the user clicks on a commit link within one of the columns
in the blame viewer we now jump them not just to that commit/file
pair but also to the line of the original file. This saves the
user a lot of time, as they don't need to search through the new
file data for the chunk they were previously looking at.
We also restore the prior view when the user clicks the back button
to return to a pior commit/file pair that they were looking at.
Turned out this was quite tricky to get working in Tk. Every time
I tried to jump the text widgets to the correct locations by way
of the "yview moveto" or "see" subcommands Tk performed the change
until the current event finished dispatching, and then reset the
views back to 0, making the change never take place. Forcing Tk
to run the pending events before we jump the UI resolves the issue.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>