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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
* maint:
Revert "Make the installation target of git-gui a little less chatty"
git-gui: Verify Tcl/Tk is new enough for our needs
git-gui: Attach font_ui to all spinbox widgets
This reverts commit c289f6fa1f.
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>
For quite a while we have been assuming the user is running on
a Tcl/Tk 8.4 or later platform. This may not be the case on
some very old systems. Unfortunately I am pretty far down the
path of using the Tcl/Tk 8.4 commands and options and cannot
easily work around them to support earlier versions of Tcl/Tk.
So we'll check that we are using the correct version up front,
and if not we'll stop with a related error message.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Earlier I missed making sure our spinbox widgets used the same font
as the other widgets around them. This meant that using a main font
with a size of 20 would make every widget in the options dialog huge,
but the spinboxes would be left with whatever the OS native font is.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Its wrong to exit the application if we destroy a random widget
contained withing something else; especially if its some small
trivial thing that has no impact on the overall operation.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To improve performance on fork+exec impoverished systems (such as
Windows) we want to avoid running git-symbolic-ref on every rescan
if we can do so. A quick way to implement such an avoidance is to
just read the HEAD ref ourselves; we'll either see it as a symref
(starts with "ref: ") or we'll see it as a detached head (40 hex
digits). In either case we can treat that as our current branch.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
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>
Recently git-merge learned to avoid generating the diffstat after
a merge by reading the merge.diffstat configuration option. By
default this option is assumed to be true, as that is the old
behavior. However we can force it to false by setting it as a
standard boolean option.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Git has supported remote branch deletion for quite some time, but
I've just never gotten around to supporting it in git-gui. Some
workflows have users push short-term branches to some remote Git
repository, then delete them a few days/weeks later when that topic
has been fully merged into the main trunk. Typically in that style
of workflow the user will want to remove the branches they created.
We now offer a "Delete..." option in the Push menu, right below the
generic "Push..." option. When the user opens our generic delete
dialog they can select a preconfigured remote, or enter a random
URL. We run `git ls-remote $url` to obtain the list of branches and
tags known there, and offer this list in a listbox for the user to
select one or more from.
Like our local branch delete dialog we offer the user a way to filter
their selected branch list down to only those branches that have been
merged into another branch. This is a very common operation as the
user will likely want to select a range of topic branches, but only
delete them if they have been merged into some sort of common trunk.
Unfortunately our remote merge base detection is not nearly as strict
as the local branch version. We only offer remote heads as the test
commit (not any local ones) and we require that all necessary commits
to successfully run git-merge-base are available locally. If one or
more is missing we suggest that the user run a fetch first.
Since the Git remote protocol doesn't let us specify what the tested
commit was when we evaluated our decision to execute the remote delete
there is a race condition here. The user could do a merge test against
the trunk, determine a topic branch was fully merged, but before they
can start pushing the delete request another user could fast-forward
the remote topic branch to a new commit that is not merged into the
trunk. The delete will arrive after, and remove the topic, even though
it was not fully merged.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Git's native command line interface has had branch renaming
support for quite a while, through the -m/-M options to the
git-branch command line tool. This is an extremely useful
feature as users may decide that the name of their current
branch is not an adequate description, or was just entered
incorrectly when it was created.
Even though most people would consider git-branch to be a
Porcelain tool I'm using it here in git-gui as it is the
only code that implements the rather complex set of logic
needed to successfully rename a branch in Git. Currently
that is along the lines of:
*) Backup the ref
*) Backup the reflog
*) Delete the old ref
*) Create the new ref
*) Move the backed up reflog to the new ref
*) Record the rename event in the reflog
*) If the current branch was renamed, update HEAD
*) If HEAD changed, record the rename event in the HEAD reflog
*) Rename the [branch "$name"] section in the config file
Since that is some rather ugly set of functionality to implement
and get right, and some of it isn't easily accessible through the
raw plumbing layer I'm just cheating by relying on the Porcelain.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The Windows and Mac OS X platforms do not generally use the tearoff
menu feature found on traditional X11 based systems. On Windows the
Tk engine does support the feature, but it really is out of place and
just confuses people who aren't used to working on a UNIX system. On
Mac OS X its not supported for the root menu bar and its submenus, as
it doesn't fit into the overall platform UI model.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>