If we have commit data from both the simple blame and the
rename/move tracking blame and they differ than there is a
bigger story to tell. We now include data from both commits
so that the user can see that this link as moved, who moved
it, and where it originated from.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Run blame twice on the same file and display both outputs
We now perform two passes over any input file given to the blame
viewer. Our first pass is a quick "git-blame" with no options,
getting the details of how each line arrived into this file. We
are specifically ignoring/omitting the rename detection logic as
this first pass is to determine why things got into the state they
are in.
Once the first pass is complete and is displayed in the UI we run
a second pass, using the much more CPU intensive "-M -C -C" options
to perform extensive rename/movement detection. The output of this
second pass is shown in a different column, allowing the user to see
for any given line how it got to be, and if it came from somewhere
else, where that is.
This is actually very instructive when run on our own lib/branch.tcl
script. That file grew recently out of a very large block of code
in git-gui.sh. The first pass shows when I created that file, while
the second pass shows the original commit information.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Display the "Loading annotation..." message in italic
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>
git-gui: Rename fields in blame viewer to better descriptions
Calling the commit message pane $w_cmit is a tad confusing when
we also have the $w_cgrp column that shows the abbreviated SHA-1s.
So w_cmit -> w_cviewer, as it is the "commit viewer"; and
w_cgrp -> w_amov as it is the "annotated commit + move tracking"
column. Also changed line_data -> amov_data, as that list is
exactly the results shown in w_amov.
Why call the column "move tracking"? Because this column holds
data from "git blame -M -C". I'm considering adding an additional
column that holds the data from "git blame" without -M/-C, showing
who did the copy/move, and when they did it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Label the uncommitted blame history entry
If the user runs the blame viewer on a working directory file
instead of a specific commit-ish then we have no value for the
commit SHA1 or the summary line; this causes the history menu
to get an empty entry at the very bottom. We now look for this
odd case and call the meny entry "Working Directory".
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Switch internal blame structure to Tcl lists
The Tcl list datatype is significantly faster to work with than
the array type, especially if our indexes are a consecutive set
of numbers, like say line numbers in a file.
This rather large change reorganizes the internal data structure
of the blame viewer to use a proper Tcl list for the annotation
information about a line. Each line is given its own list within
the larger line_data list, where the indexes correspond to various
facts about that particular line.
The interface does seem to be more responsive this way, with less
time required by Tcl to process blame, and to switch to another
version of the same file. It could just be a placebo effect, but
either way most Tcl experts perfer lists for this type of work over
arrays.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Cleanup redundant column management in blame viewer
The code to handle our three different text widgets is a bit
on the messy side as we issue the same command on all three
widgets one at a time. Adding (or removing) columns from the
viewer is messy, as a lot of locations need to have the new
column added into the sequence, or removed from it.
We also now delete the tags we create for each commit when
we switch to display another "commit:path" pair. This way the
text viewer doesn't get bogged down with a massive number of tags
as we traverse through history.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The array variable "order" used to be used to tell us in what
order each commit was received in. Recent changes have removed
that need for an ordering and the "order" array is now just a
boolean 'do we have that commit yet' flag.
The colors were moved to fields, so they appear inside of the
blame viewer instance. This keeps two different concurrently
running blame viewers from stepping on each other's ordering
of the colors in group_colors.
Most of the other fields were moved around a little bit so
that they are organized by major category and value lifespan.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Remove unused commit_list from blame viewer
This list used to store the commits in the order we received
them in. I originally was using it to update the colors of
the commit before and the commit after the current commit,
but since that interface concept turned out to be horribly
ugly and has been removed we no longer need this list.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Automatically expand the line number column as needed
After we finish reading a chunk of data from the file stream
we know how many digits we need in the line number column to
show the current maximum line number. If our line number column
isn't wide enough, we should expand it out to the correct width.
Any file over our default allowance of 5 digits (99,999 lines)
is so large that the slight UI "glitch" when we widen the column
out is trivial compared to the time it will take Git to fully do
the annotations.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Make the line number column slightly wider in blame
Most source code files are under 9,999 lines of text, so using a
field width of 5 characters meant that we should have had one char
padding on the left edge (because we right-justify the line number).
Unfortunately when I added the right margin earlier (when I removed
the padding) I ate into the extra character's space, losing the left
margin. This put the line numbers too close to the commit column in
any file with more than 999 lines in it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The colors I originally picked out on a Mac OS X system look a
tad too dark on a Windows 2000 system; the greys are dark enough
to make it difficult to read some lines of text and the green used
to highlight the current commit was also difficult to read text on.
I also added a third grey to the mix, to try and help some files
that wind up with a number of neighboring chunks getting the same
colors.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Remove unnecessary space between columns in blame viewer
On Mac OS X the OS has "features" that like to draw thick black
borders around the text field that has focus. This is nice if
you want to know where your text is going and are blind as a bat,
but it isn't the best thing to have in a table that is being
faked through the abuse of Tk text widgets.
By setting our takefocus, highlightthickness and padx/y we can
get rid of this border and get our text widgets packed right next
to each other, with no padding between them. This makes the blame
background color smoothly run across the entire line of commit data,
line number and file content.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Remove the loaded column from the blame viewer
Originally I had placed this loaded column between the line number
and the file line data to help users know if a particular line has
received annotation data or not yet. This way users would know if
the line(s) they were interested in were ready for viewing, or if
they still had to wait. It also was an entertaining way for the
user to spend their time waiting for git-blame --incremental to
compute the complete set of annotations.
However it is completely useless now that we show the abbreviated
commit SHA-1 and author initials in the leftmost column. That area
is empty until we get the annotation data, and as soon as we get it
in we display something there, indicating to the user that there is
now blame data ready. Further with the tooltips the user is likely
to see the data as soon as it comes in, as they are probably not
keeping their mouse perfectly still. So I'm removing the field to
save screen space for more useful things, like file content.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Clip the commit summaries in the blame history menu
Some commit lines can get really long when users enter a lot of
text without linewrapping (for example). Rather than letting the
menu get out of control in terms of width we clip the summary to
the first 50+ characters.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Use a label instead of a button for the back button
Apparently Tk on Mac OS X won't draw a button with an image using a
transparent background. Instead it draws the button using some sort
of 3D effect, even though I asked for no relief and no border. The
background is also not our orange that we expected it to be.
Earlier I had tried this same trick on Windows and it draws the same
way as the button did, so I'm going to switch to the label as that
seems to be more portable.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we have two commits right next to each other in the final
file and they were kept as different blocks in the leftmost
column then its probably because the original filename was
different. To help the user know where they are digging into
when they click on that link we now show the original file in
the tooltip, but to save space we do so only if the original
file is not the same as the file we are currently viewing.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Combine blame groups only if commit and filename match
Consecutive chunks of a file could come from the same commit, but
have different original file names. Previously we would have put
them into a single group, but then the hyperlink would jump to only
one of the files, and the other would not be accessible. Now we can
get to the other file too.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Allow digging through history in blame viewer
gitweb has long had a feature where the user can click on any
commit the blame display and go visit that commit's information
page. From the user could go get the blame display for the file
they are tracking, and try to digg through the history of any
part of the code they are interested in seeing.
We now offer somewhat similiar functionality in git-gui. The 4
digit commit abreviation in the first column of our blame view is
now offered as a hyperlink if the commit isn't the one we are now
viewing the blame output for (as there is no point in linking back
to yourself). Clicking on that link will stop the current blame
engine (if still running), push the new target commit onto the
history stack, and restart the blame viewer at that commit, using
the "original file name" as supplied by git-blame for that chunk
of the output.
Users can navigate back to a version they had been viewing before
by way of a back button, which offers the prior commits in a popup
menu displayed right below the back button. I'm always showing the
menu here as the cost of switching between views is very high; you
don't want to jump to a commit you are not interested in looking at
again.
During switches we throw away all data except the cached commit data,
as that is relatively small compared to most source files and their
annotation marks. Unfortunately throwing this per-file data away in
Tcl seems to take some time; I probably should move the line indexed
arrays to proper lists and use [lindex] rather than the array lookup
(usually lists are faster).
We now start the git-blame process using "nice", so that its priority
will drop hopefully below our own. If I don't do this the blame engine
gets a lot of CPU under Windows 2000 and the git-gui user interface is
almost non-responsive, even though Tcl is just sitting there waiting
for events.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Display a progress bar during blame annotation gathering
Computing the blame records for a large file with a long project
history can take git a while to run; traditionally we have shown
a little meter in the status area of our blame viewer that lets
the user know how many lines have been finished, and how far we
are through the process.
Usually such progress indicators are drawn with a little progress
bar in the window, where the bar shows how much has been completed
and hides itself when the process is complete. I'm using a very
simple hack to do that: draw a canvas with a filled rectangle.
Of course the time remaining has absolutely no relationship to the
progress meter. It could take very little time for git-blame to get
the first 90% of the file, and then it could take many times that to
get the remaining 10%. So the progress meter doesn't really have any
sort of assurances that it relates to the true progress of the work.
But in practice on some ugly history it does seem to hold a reasonable
indicator to the completion status. Besides, its amusing to watch and
that keeps the user from realizing git is being somewhat slow.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Allow the user to control the blame/commit split point
At one point I tried to present the blame viewer to an audience of
people on a 640 by 480 pixel LCD projector. This did not work at
all as the top area (the file data) was taking up all of the screen
realestate and the split point was not adjustable by the user. In
general locking the user into a specific ratio of display is just
not user friendly.
So we now place a split pane control into the middle of our blame
window, so the user can adjust it to their current needs. If the
window increases (or decreases) in height we assign the difference
to the file data area, as that is generally the area of the window
that users are trying to see more of when they grow the window.
Unfortunately there appears to be a bug in the "pack" layout manager
in Tcl/Tk 8.4.1. The status bar and the lower commit pane was being
squashed if the window decreased in height. I think the pack manager
was just not decreasing the size of the panedwindow slave properly if
the main window shrank. Switching to the "grid" layout manager fixes
the problem, but is slightly uglier setup code.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Frequently when I'm looking at blocks of code in the blame
viewer I want to know who is the culprit, or who I should
be praising for a job well done. The tooltips nicely show
this if I mouse over a block, but it doesn't work to get
this detail at a glance.
Since we don't use the leftmost commit column for anything
after the first line within a commit group I'm now tossing
the author's initials into that field, right justified. It
is quite clearly not a SHA-1 number as we always show the
SHA-1 in lowercase, while we explicitly select only the
uppercase characters from an author's name field, and only
those that are following whitespace.
I'm using initials here over anything else as they are quite
commonly unique within small development teams. The leading
part of the email address field was out for some of the teams
I work with, as there the email addresses are all of the form
"Givenname.Surname@initech.com". That will never fit into the
4 characters available.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Space the commit group continuation out in blame view
The | in the continued lines of the same commit group as not
easily seen on the left edge; putting a single space in front
of the pipe makes it slightly more visually appealing to me as
I can follow the line down through the group to the next commit
marker.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Remove unnecessary reshow of blamed commit
Because we no longer redraw colors every time we select a particular
commit there is no need to redraw the screen after we get a new commit
in from blame --incremental.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Highlight the blame commit header from everything else
The selected commit's blame header is now drawn in green, using
the same background color that is shown in the main file content
viewer. The result is a much better looking commit pane, as we
use bold for header "keys" and proportional width fonts for the
stuff that doesn't need to be fixed width to maintain its formatting.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When the mouse is over a particular line and we have blame data
for that line, but its not the active commit, we should show the
user information about that commit like who the author was and
what the subject (first line) was.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Use arror cursor in blame viewer file data
Since we don't allow the user to select text from the file
viewer right now I'm disabling the normal text cursor and
putting in a plain arror instead. This way users don't
think they can select and copy text, because they can't.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Simplify consecutive lines that come from the same commit
If two consecutive lines in the final file came from the same commit
then we store a "|" in the first column rather than the commit id,
for the second and subsequent lines in that block. This cleans up
the interface so runs associated with the same commit can be more
easily seen visually.
We also now use the abbreviation "work" for the uncommitted stuff in
your working directory, rather than "0000". This looks nicer to the
eyes and explains pretty quickly what is going on.
There was also a minor bug in the commit abbreviation column for the
last line of the file. This is now also fixed.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The git-gui blame viewer has always been ugly as s**t. Linus Torvalds
suggested the coloring scheme I'm using here, which is two different
shades of grey for the background colors, and black text on a pale green
background for the currently selected/focused commit.
The difference is a massive improvement. The interface no longer will
cause seizures in people who are prone to that sort of thing. It no
longer uses a very offensive hot pink. The green being current actually
makes sense. And not having the background of the other non-current
lines change when you change the current commit is really a big deal.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The blame viewer has this silly blank line at the bottom of it;
we really don't want to see it displayed as we will never get
any blame data for that line (it doesn't exist in the source).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A lot of this code was pre-class, which meant that I just sort of
copied and pasted my way through it, rather than being really smart
and using a variable for each widget's path name. Since we have a
field for each path, we can use those throughout the constructor
and make things a lot neater.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Add a 4 digit commit abbreviation to the blame viewer
We now show the first 4 digits of each commit in the left most
column of our blame viewer, before the line numbers. These are
drawn as the data becomes available from git-blame --incremental,
and helps the user to visually group lines together.
I'm using only the first 4 digits because within a given cluster
of lines its unlikely that two neighboring commits will have the
same 4 digit prefix.
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>
Junio pointed out that Alex's change breaks in some cases, like
when V=1, and is more verbose than it should be even if that worked.
I'm backing it out and redoing it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Verify Tcl/Tk is new enough for our needs
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>
git-gui: Don't quit when we destroy a child widget
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>
Johannes Sixt pointed out that dropping to 0 lines of context
does allow the user to get more fine-grained hunk selection,
especially since we don't currently support "highlight and
apply (or revert)".
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user has no branches at all (their refs/heads/ is empty)
and they are on a detached HEAD we have a valid repository but
there are no branches to populate into the branch pulldown in
the create branch dialog. Instead of erroring out we can skip
that part of the dialog, much like we do with tracking branches
or tags when the user doesn't have any.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Guess our share/git-gui/lib path at runtime if possible
Johannes Sixt asked me to try to avoid embedding the runtime location
of git-gui's library directory in the executable script. Not embedding
it helps the MinGW to be relocatable to another directory should a user
wish to install the programs in a directory other than the location the
packager wanted them to be installed into.
Most of this is a hack. We try to determine if the path of our master
git-gui script will be able to locate the lib by ../share/git-gui/lib.
This should be true if $(gitexecdir) and $(libdir) have the same prefix.
If they do then we defer the assignment of $(libdir) until runtime, and
we get it from $argv0 rather than embedding it into the script itself.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Alberto Bertogli reported on #git that git-gui was exiting with
alt-q, while gitk on the same system was exiting with ctrl-q.
That was not what I wanted. I really wanted M1B to be bound to
the Control key on most non-Mac OS X platforms, but according to
Sam Vilain M1 on most systems means alt. Since gitk always does
control, I'm doing the same thing for all non-Mac OS X systems.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Tighten internal pattern match for lib/ directory
Our GITGUI_LIBDIR macro was testing only for @@ at the start of
the path, assuming nobody would ever find that to be a reasonable
prefix for a directory to install our library into. That is most
likely a valid assumption, but its even more unlikely they would
have the start be @@GITGUI_ and the end be @@. Note that we
cannot use the full string here because that would get expanded
by the sed replacement in our Makefile.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Gracefully handle bad TCL_PATH at compile time
Petr Baudis pointed out the main git.git repository's Makefile dies
now if git-gui 0.7.0-rc1 or later is being used and TCL_PATH was not
set to a working tclsh program path. This breaks people who may have
a working build configuration today and suddenly upgrade to the latest
git release.
The tclIndex is required for git-gui to load its associated lib files,
but using the Tcl auto_load procedure to source only the files we need
is a performance optimization. We can emulate the auto_load by just
source'ing every file in that directory, assuming we source class.tcl
first to initialize our crude class system.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We can use [list ...] rather than "", especially when we are talking
about values as then they are properly escaped if necessary. Small
nit, but probably not a huge deal as the only data being inlined here
is Tk paths.
Some of the lines in the parser code were longer than 80 characters
wide, and they actually were all the same value on the end part of
the line. Rather than keeping the mess copied-and-pasted around we
can set the last argument into a local variable and reuse it many
times.
The commit display code was also rather difficult to read on an 80
character wide terminal, so I'm moving it all into a double quoted
string that is easier to read.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Generate blame on uncommitted working tree file
If the user doesn't give us a revision parameter to our blame
subcommand then we can generate blame against the working tree
file by passing the file path off to blame with the --contents
argument. In this case we cannot obtain the contents of the
file from the ODB; instead we must obtain the contents by
reading the working directory file as-is.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Smarter command line parsing for browser, blame
The browser subcommand now optionally accepts a single revision
argument; if no revision argument is supplied then we use the
current branch as the tree to browse. This is very common, so
its a nice option.
Our blame subcommand now tries to perform the same assumptions
as the command line git-blame; both the revision and the file
are optional. We assume the argument is a filename if the file
exists in the working directory, otherwise we assume the argument
is a revision name. A -- can be supplied between the two to force
parsing, or before the filename to force it to be a filename.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Use prefix if blame is run in a subdirectory
I think it was Andy Parkins who pointed out that git gui blame HEAD f
does not work if f is in a subdirectory and we are currently running
git-gui within that subdirectory. This is happening because we did
not take the user's prefix into account when we computed the file
path in the repository.
We now assume the prefix as returned by rev-parse --show-prefix is
valid and we use that during the command line blame subcommand when
we apply the parameters.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Convert blame to the "class" way of doing things
Our blame viewer code has historically been a mess simply
because the data for multiple viewers was all crammed into
a single pair of Tcl arrays. This made the code hard to
read and even harder to maintain.
Now that we have a slightly better way of tracking the data
for our "meta-widgets" we can make use of it here in the
blame viewer to cleanup the code and make it easier to work
with long term.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Don't attempt to inline array reads in methods
If a variable reference to a field is to an array, and it is
the only reference to that field in that method we cannot make
it an inlined [set foo] call as the regexp was converting the
Tcl code wrong. We were producing "[set foo](x)" for "$foo(x)",
and that isn't valid Tcl when foo is an array. So we just punt
if the only occurance has a ( after it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Convert browser, console to "class" format
Now that we have a slightly easier method of working with per-widget
data we should make use of that technique in our browser and console
meta-widgets, as both have a decent amount of information that they
store on a per-widget basis and our current approach of handling
it is difficult to follow.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
As most of the git-gui interface is based upon "meta-widgets"
that need to carry around a good deal of state (e.g. console
windows, browser windows, blame viewer) we have a good deal
of messy code that tries to store this meta-widget state in
global arrays, where keys into the array are formed from a
union of a unique "object instance id" and the field name.
This is a simple class system for Tcl that allows us to
hide much of that mess by making Tcl do what it does best;
process strings to manipulate its own code during startup.
Each object instance is placed into its own namespace. The
namespace is created when the object instance is created and
the namespace is destroyed when the object instance is removed
from the system. Within that namespace we place variables for
each field within the class; these variables can themselves be
scalar values or full-blown Tcl arrays.
All fields must be declared before any constructors or methods. This
allows our class to generate a list of the fields so it can properly
alter the definition of the constructor and method bodies prior to
passing them off to Tcl for definition with proc. A field may optionally
be given a default/initial value. This can only be done for non-array
type fields.
Constructors are given full access to all fields of the class, so they
can initialize the data values. The default values of fields (if any)
are set before the constructor runs, and the implicit local variable
$this is initialized to the instance identifier.
Methods are given access to fields they actually use in their body.
Every method has an implicit "this" argument inserted as its first
parameter; callers of methods must be sure they supply this value.
Some basic optimization tricks are performed (but not much). We
try to only upvar (locally bind) fields that are accessed within a
method, but we err on the side of caution and may upvar more than
we need to. If a variable is accessed only once within a method
and that access is by $foo (read) we avoid the upvar and instead
use [set foo] to obtain the value. This is slightly faster as Tcl
does not need to lookup the variable twice.
We also offer some small syntatic sugar for interacting with Tk and
the fileevent callback system in Tcl. If a field (say "foo") is used
as "@foo" we insert instead the true global variable name of that
variable into the body of the constructor or method. This allows easy
binding to Tk textvariable options, e.g.:
label $w.title -textvariable @title
Proper namespace callbacks can also be setup with the special cb proc
that is defined in each namespace. [cb _foo a] will invoke the method
_foo in the current namespace, passing it $this as the first (implied)
parameter and a as the second parameter. This makes it very simple to
connect an object instance to a -command option for a Tk widget or to
a fileevent readable or writable for a file channel.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Allow shift-{k,j} to select a range of branches to merge
I found it useful to be able to use j/k (vi-like keys) to move
up and down the list of branches to merge and shift-j/k to do
the selection, much as shift-up/down (arrow keys) would alter
the selection.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Since we support vi-like keys for scrolling in other UI contexts
we can easily do so here too. Tk's handy little `event generate'
makes this a lot easier than I thought it would be. We may want
to go back and fix some of the other vi-like bindings to redirect
to the arrow and pageup/pagedown keys, rather than running the
view changes directly.
I've bound 'v' to visualize, as this is a somewhat common thing
to want to do in the merge dialog. Control (or Command) Return
is also bound to start the merge, much as it is bound in the
main window to activate the commit.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Include commit id/subject in merge choices
When merging branches using our local merge feature it can be
handy to know the first few digits of the commit the ref points
at as well as the short description of the branch name.
Unfortunately I'm unable to use three listboxes in a row, as Tcl
freaks out and refuses to let me have a selection in more than
one of them at any given point in time. So instead we use a
fixed width font in the existing listbox and organize the data
into three columns. Not nearly as nice looking, but users can
continue to use the listbox's features.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Johannes Sixt pointed out that git-gui was randomly selecting
which branch (or tag!) it will show in the merge dialog when
more than one ref points at the same commit. This can be a
problem for the user if they want to merge a branch, but the
ref that git-gui selected to display was actually a tag that
points at the commit at the tip of that branch. Since the
user is looking for the branch, and not the tag, its confusing
to not find it, and worse, merging the tag causes git-merge to
generate a different message than if the branch was selected.
While I am in here and am messing around I have changed the
for-each-ref usage to take advantage of its --tcl formatting,
and to fetch the subject line of the commit (or tag) we are
looking at. This way we could present the subject line in the
UI to the user, given them an even better chance to select
the correct branch.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Allow vi keys to scroll the diff/blame regions
Users who are used to vi and recent versions of gitk may want
to scroll the diff region using vi style keybindings. Since
these aren't bound to anything else and that widget does not
accept focus for data input, we can easily support that too.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Move console procs into their own namespace
To help modularize git-gui better I'm isolating the code and
variables required to handle our little console windows into
their own namespace. This way we can say console::new rather
than new_console, and the hidden internal procs to create the
window and read data from our filehandle are off in their own
private little land, where most users don't see them.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Refactor into multiple files to save my sanity
I'm finding it difficult to work with a 6,000+ line Tcl script
and not go insane while looking for a particular block of code.
Since most of the program is organized into different units of
functionality and not all users will need all units immediately
on startup we can improve things by splitting procs out into
multiple files and let auto_load handle things for us.
This should help not only to better organize the source, but
it may also improve startup times for some users as the Tcl
parser does not need to read as much script before it can show
the UI. In many cases the user can avoid reading at least half
of git-gui now.
Unfortunately we now need a library directory in our runtime
location. This is currently assumed to be $(sharedir)/git-gui/lib
and its expected that the Makefile invoker will setup some sort of
reasonable sharedir value for us, or let us assume its going to be
$(gitexecdir)/../share.
We now also require a tclsh (in TCL_PATH) to just run the Makefile,
as we use tclsh to generate the tclIndex for our lib directory. I'm
hoping this is not an unncessary burden on end-users who are building
from source.
I haven't really made any functionality changes here, this is just a
huge migration of code from one file to many smaller files. All of
the new changes are to setup the library path and install the library
files.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Track our own embedded values and rebuild when they change
Like core-Git we now track the values that we embed into our shell
script wrapper, and we "recompile" that wrapper if they are changed.
This concept was lifted from git.git's Makefile, where a similar
thing was done by Eygene Ryabinkin. Too bad it wasn't just done
here in git-gui from the beginning, as the git.git Makefile support
for GIT-GUI-VARS was really just because git-gui doesn't do it on
its own.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Whenever we want to execute a git subcommand from the plumbing
layer (and on rare occasion, the more porcelain-ish layer) we
tend to use our proc wrapper, just to make the code slightly
cleaner at the call sites. I wasn't doing that in a couple of
places, so this is a simple cleanup to correct that.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Use option database defaults to set the font
Rather than passing "-font font_ui" to every widget that we
create we can instead reconfigure the option database for
all widget classes to use our font_ui as the default widget
font. This way Tk will automatically setup their defaults
for us, and we can reduce the size of the application.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
An earlier change tossed these optionMenu font configurations
all over the code, when really we can just rename the proc to
a hidden internal name and provide our own wrapper to install
the font configuration we really want.
We also don't need to set these option database entries in all
of the procedures that open dialogs; instead we should just set
one time, them after we have the font configuration ready for use.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Correct line wrapping for too many branch message
Since Tk automatically wraps lines for us in tk_messageBox
widgets we don't need to try to wrap them ourselves. Its
actually worse that we linewrapped this here in the script,
as not all fonts will render this dialog nicely.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Warn users before making an octopus merge
A coworker who was new to git-gui recently tried to make an octopus
merge when he did not quite mean to. Unfortunately in his case the
branches had file level conflicts and failed to merge with the octopus
strategy, and he didn't quite know why this happened. Since most users
really don't want to perform an octopus merge this additional safety
valve in front of the merge process is a good thing.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Include the subject in the status bar after commit
Now that the command line git-commit has made displaying
the subject (first line) of the newly created commit popular
we can easily do the same thing here in git-gui, without the
ugly part of forking off a child process to obtain that first
line.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the path of our wish executable that are running under
contains spaces we need to make sure they are escaped in
a proper Tcl list, otherwise we are unable to start gitk.
Reported by Randal L. Schwartz on #git.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Uwe Kleine-König discovered git-gui mangled his surname and did
not send the proper UTF-8 byte sequence to git-commit-tree when
his name appeared in the commit message (e.g. Signed-Off-By line).
Turns out this was related to other trouble that I had in the past
with trying to use "fconfigure $fd -encoding $enc" to select the
stream encoding and let Tcl's IO engine do all of the encoding work
for us. Other parts of git-gui were just always setting the file
channels to "-encoding binary" and then performing the encoding
work themselves using "encoding convertfrom" and "convertto", as
that was the only way I could make UTF-8 filenames work properly.
I found this same bug in the amend code path, and in the blame
display. So its fixed in all three locations (commit creation,
reloading message for amend, viewing message in blame).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Mimick what we do for gitk. Since you do have a source file,
git-gui.sh, which is separate from the target, it should be much
easier in git-gui's Makefile.
Signed-off-by: Junio C Hamano <junkio@cox.net> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Junio rightly pointed out this patch doesn't handle the
`make install` target very well:
Junio C Hamano <junkio@cox.net> writes:
> You should never generate new files in the source tree from
> 'install' target. Otherwise, the usual pattern of "make" as
> yourself and then "make install" as root would not work from a
> "root-to-nobody-squashing" NFS mounted source tree to local
> filesystem. You should know better than accepting such a patch.
git-gui: Display the directory basename in the title
By showing the basename of the directory very early in the
title bar I can more easily locate a particular git-gui
session when I have 8 open at once and my Windows taskbar
is overflowing with items.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* er/ui:
Always bind the return key to the default button
Do not break git-gui messages into multiple lines.
Improve look-and-feel of the git-gui tool.
Teach git-gui to use the user-defined UI font everywhere.
Allow wish interpreter to be defined with TCLTK_PATH
git-gui: Brown paper bag fix division by 0 in blame
If we generate a blame status string before we have obtained
any annotation data at all from the input file, or if the input
file is empty, our total_lines will be 0. This causes a division
by 0 error when we blindly divide by the 0 to compute the total
percentage of lines loaded. Instead we should report 0% done.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If a dialog/window has a default button registered not every
platform associates the return key with that button, but all
users do. We have to register the binding of the return key
ourselves to make sure the user's expectations of pressing
return will activate the default button are met.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Do not break git-gui messages into multiple lines.
Many git-gui messages were broken into a multiple lines to make
good paragraph width. Unfortunately in reality it breaks the paragraph
width completely, because the dialog window width does not coincide
with the paragraph width created by the current font.
Tcl/Tk's standard dialog boxes are breaking the long lines
automatically, so it is better to make long lines and let the
interpreter do the job.
Signed-off-by: Eygene Ryabinkin <rea-git@codelabs.ru> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Made the default buttons on the dialog active and focused upon the
dialog appearence.
Bound 'Escape' and 'Return' keys to the dialog dismissal where it
was appropriate: mainly for dialogs with only one button and no
editable fields, but on console output dialogs as well.
Signed-off-by: Eygene Ryabinkin <rea-git@codelabs.ru> Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
git-gui: Allow 'git gui version' outside of a repository
I got a little surprise one day when I tried to run 'git gui version'
outside of a Git repository to determine what version of git-gui was
installed on that system. Turns out we were doing the repository
check long before we got around to command line argument handling.
We now look to see if the only argument we have been given is
'version' or '--version', and if so, print out the version and
exit immediately; long before we consider looking at the Git
version or working directory. This way users can still get to
the git-gui version number even if Git's version cannot be read.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Johannes Sixt noticed that git-gui would not let the user commit
a merge created by `git merge -s ours` as the ours strategy does
not alter the tree (that is HEAD^1^{tree} = HEAD^{tree} after the
merge). The same issue arises from amending such a merge commit.
We now permit an empty commit (no changed files) if we are doing
a merge commit. Core Git does this with its command line based
git-commit tool, so it makes sense for the GUI to do the same.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
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>
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>
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>
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>
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>
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>
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>