Recent git versions have a git-status that honors the core.excludesfile
configuration option when it reports on untracked files. Unfortunately
I missed the introduction of this configuration option in the core
porcelain implementation, so it was not reflected here in git-gui.
Found and reported by Lars Noschinski <lars@public.noschinski.de>.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Also, the warning message when clicking "Reset" is adapted to
the wording "Reset" rather than a confusion "Cancel commit?".
Signed-off-by: Christian Stimming <stimming@tuhh.de>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user is in the middle of a merge and has already started to
modify their commit message we were losing the user's changes when
they pressed 'Rescan' after resolving issues or making changes in
the working directory.
The problem here was our background timer that saves the commit
message buffer. It marks the commit message buffer as not being
modified when it writes it out to disk, so during the rescan we
assumed the buffer should be replaced with what we read from the
MERGE_MSG file. So we now only read these files from .git if we
have a valid backup file. Since we clear it on commit this will
only have an impact while the user is actively editing the current
commit.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The i18n team has also identified a rather ugly block of code in
git-gui that is used to make a pair of Repository menu items show
the current branch name. This code is difficult to convert to use
[mc ...] to lookup the translation, so I'm refactoring it into a
procedure.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The folks working on the i18n version of git-gui have had some
trouble trying to convert these English strings into [mc] calls
due to the double evaluation. Moving this block into a standard
procedure eliminates the double evaluation, making their work
easier.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Junio recently pointed out on the mailing list that our "Add Existing"
feature is a lot like `git add -u`, which is generally described as
"(Re)Add Tracked Files". This came up during discussion of how to
translate "Add Existing" into Japanese, as the individual working on
the translation was not quite sure what the option meant and therefore
had some trouble selecting the best translation.
I'm changing the menu option to "Add Tracked Files To Commit" and the
button to "Add Tracked". This should help new users to better understand
the actions behind those GUI widgets.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This menu option of Tools/Migrate has been living inside of git-gui
as a local hack to support some coworkers of mine. It has no value
to anyone outside of my day-job team and never really should have
been in a release version of git-gui. So I'm pulling it out, so
that nobody else has to deal with this garbage.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A few users have been seeing crashes in Tk when using the undo key
binding to undo the last few keystroke events in the commit buffer.
Unfortunately that means the user loses their commit message and
must start over from scratch when the user restarts the process.
git-gui now saves the user's commit message buffer every couple of
seconds to a temporary file under .git (specifically .git/GITGUI_BCK).
At exit time we rename this file to .git/GITGUI_MSG if there is a
message, the file exists, and it is currently synchronized with the
Tk buffer. Otherwise we do our usual routine of saving the Tk buffer
to .git/GITGUI_MSG and delete .git/GITGUI_BCK, if it exists.
During startup we favor .git/GITGUI_BCK over .git/GITGUI_MSG. This
way a crash doesn't take out the user's message buffer but instead
will cause the user to lose only a few keystrokes. Most people do
not type more than 200 WPM, and with 30 possible saves per minute
we are unlikely to lose more than 7 words.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Running global takes slightly longer than just accessing the variable
via its package name, especially if the variable is just only once in
the procedure, or isn't even used at all in the procedure. So this is
a minor cleanup for some of our commonly invoked procedures.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users who merge often may want to access the merge action quickly,
so we now bind M to the merge action.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users shouldn't see this menu option if they startup a browser or
blame from the command line, especially if they are doing so on a
bare repository.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users who are new to Git may not realize that visualizing things in
a repository involves looking at history. Adding in a small amount
of text to the menu items really helps to understand what the action
might do, before you invoke it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We now allow users to pick which commit they want to browse through
our revision picking mega-widget. This opens up in a dialog first,
and then opens a tree browser for that selected commit. It is a very
simple approach and requires minimal code changes.
I also clarified the language a bit in the Repository menu, to show
that these actions will access files. Just in case a user is not
quite sure what specific action they are looking for, but they know
they want some sort of file thing.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Like our blame subcommand the browser subcommand now accepts both
a revision and a path, just a revision or just a path. This way
the user can start the subcommand on any branch, or on any subtree.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A long time ago Linus Torvalds tried to run git-gui on a bare
repository to look at the blame viewer, but it failed to start
because we required that the user run us only from within a
working directory that had a normal git repository associated
with it.
This change relaxes that requirement so that you can start the
tree browser or the blame viewer against a bare repository. In
the latter case we do require that you provide a revision and a
pathname if we cannot find the pathname in the current working
directory.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
By moving our feature option determination up before we look for GIT_DIR
we can make a decision about whether or not we need a working tree up
front, before we look for GIT_DIR. A future change could then allow
us to start in a bare Git repository if we only need access to the ODB.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I'm moving the code related to looking to see if we should GC now
into a procedure closer to where it belongs, the database module.
This reduces our script by a few lines for the single commit case
(aka citool). But really it just is to help organize the code.
We now perform the check after we have been running for at least
1 second. This way the main window has time to open up and our
dialog (if we open it) will attach to the main window, instead of
floating out in no-mans-land like it did before on Mac OS X.
I had to use a wait of a full second here as a wait of 1 millisecond
made our console install itself into the main window. Apparently we
had a race condition with the console code where both the console and
the main window thought they were the main window.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Some users may do odd things, like tag their own private version of
Git with an annotated tag such as 'testver', then compile that git
and try to use it with git-gui. In such a case `git --version` will
give us 'git version testver', which is not a numeric argument that
we can pass off to our version comparsion routine.
We now check that the cleaned up git version is a going to pass the
version comparsion routine without failure. If it has a non-numeric
component, or lacks at least a minor revision then we ask the user to
confirm they really want to use this version of git within git-gui.
If they do we shall assume it is git 1.5.0 and run with only the code
that will support.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Instead of running a full git-count-objects to count all of the loose
objects we can get a reasonably close approximation by counting the
number of files in the .git/objects/42 subdirectory. This works out
reasonably well because the SHA-1 hash has a fairly even distribution,
so every .git/objects/?? subdirectory should get a relatively equal
number of files. If we have at least 8 files in .git/objects/42 than it
is very likely there is about 8 files in every other directory, leaving
us with around 2048 loose objects.
This check is much faster, as we need to only perform a readdir of
a single directory, and we can do it directly from Tcl and avoid the
costly fork+exec.
All of the credit on how clever this is goes to Linus Torvalds; he
suggested using this trick in a post commit hook to repack every so
often.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Not every caller of 'git' or 'git_pipe' wants to use nice to lower the
priority of the process its executing. In many cases we may never use
the nice process to launch git. So we can avoid searching our $PATH
to locate a suitable nice if we'll never actually use it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The git-gui version check doesn't handle versions of the form
n.n.n.GIT which you can get by installing from an tarball produced by
git-archive.
Without this change you get an error of the form:
'Error in startup script: expected version number but got "1.5.3.GIT"'
Signed-off-by: Julian Phillips <julian@quantumfyre.co.uk>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
On Windows (which includes Cygwin) Tcl defaults to leaving the EOF
character of input file streams set to the ASCII EOF character, but
if that character were to appear in the data stream then Tcl will
close the channel early. So we have to disable eofchar on Windows.
Since the default is disabled on all platforms except Windows, we
can just disable it everywhere to prevent any sort of read problem.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
My prior change to allow git-gui to run with a version of Git
that was built from a working directory that had uncommitted
changes didn't account for the pattern starting with -, and
that confused Tcl.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user is running a 'dirty' version of git (one compiled in a
working directory with modified files) we want to just assume it
was a committed version, as we really only look at the part that
came from a real annotated tag anyway.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We now embed any GIT_* and SSH_* environment variables as well as
the path to the git wrapper executable into the Mac OS X .app file.
This should allow us to restore the environment properly when
we restart.
We also try to use proper Bourne shell single quoting when we can,
as this avoids any sort of problems that might occur due to a path
containing shell metacharacters.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that we are pretty strict about setting up own absolute paths to
any git helper (saving a marginal runtime cost to resolve the tool)
we can do the same in our console widget by making sure all console
execs go through git_read if they are a git subcommand, and if not
make sure they at least try to use the Tcl 2>@1 IO redirection if
possible, as it should be faster than |& cat.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we cannot locate a .exe for a git tool that we want to run than
it may just be a Bourne shell script as these are popular in Git.
In such a case the first line of the file will say "#!/bin/sh" so
a UNIX kernel knows what program to start to parse and run that.
But Windows doesn't support shbang lines, and neither does the Tcl
that comes with Cygwin.
We can pass control off to the git wrapper as that is a real Cygwin
program and can therefore start the Bourne shell script, but that is
at least two fork+exec calls to get the program running. One to do
the fork+exec of the git wrapper and another to start the Bourne shell
script. If the program is run multiple times it is rather expensive
as the magic shbang detection won't be cached across executions.
On MinGW/MSYS we don't have the luxury of such magic detection. The
MSYS team has taught some of this magic to the git wrapper, but again
its slower than it needs to be as the git wrapper must still go and
run the Bourne shell after it is called.
We now attempt to guess the shbang line on Windows by reading the
first line of the file and building our own command line path from
it. Currently we support Bourne shell (sh), Perl and Python. That
is the entire set of shbang lines that appear in git.git today.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We know that the version subcommand of git is special. It does not
currently have an executable link installed into $gitexecdir and we
therefore would never match it with one of our file exists tests.
So we forward any invocations to it directly to the git wrapper, as
it is a builtin within that executable.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we cannot locate a command in $gitexecdir on our own then it may
just be because we are supposed to run it by `git $name` rather than
by `git-$name`. Many commands are now builtins, more are likely to
go in that direction, and we may see the hardlinks in $gitexecdir go
away in future versions of git.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The master Makefile in git.git installs gitk into bindir, not
gitexecdir, which means gitk is located as a sibling of the git
wrapper and not as though it were a git helper tool.
We can also avoid some Tcl concat operations by letting eval do
all of the heavy lifting; we have two proper Tcl lists ($cmd and
$revs) that we are joining together and $revs is currently never
an empty list.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Rather than making the C library search for git every time we want
to execute it we now search for the main git wrapper at startup, do
symlink resolution, and then always use the absolute path that we
found to execute the binary later on. This should save us some
cycles, especially on stat challenged systems like Cygwin/Win32.
While I was working on this change I also converted all of our
existing pipes ([open "| git ..."]) to use two new pipe wrapper
functions. These functions take additional options like --nice
and --stderr which instructs Tcl to take special action, like
running the underlying git program through `nice` (if available)
or redirect stderr to stdout for capture in Tcl.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that we have a fancy status bar mega-widget we can reuse that
within our main window. This opens the door for implementating
future improvements like a progress bar.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the end-user feeds us an abbreviated SHA-1 on the command line for
`git gui browser` or `git gui blame` we now unabbreviate the value
through `git rev-parse` so that the title section of the blame or
browser window shows the user the complete SHA-1 as Git determined
it to be.
If the abbreviated value was ambiguous we now complain with the
standard error message(s) as reported by git-rev-parse --verify,
so that the user can understand what might be wrong and correct
their command line.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This is a major rewrite of the way we perform switching between
branches and the subsequent update of the working directory. Like
core Git we now use a single code path to perform all changes: our
new checkout_op class. We also use it for branch creation/update
as it integrates the tracking branch fetch process along with a
very basic merge (fast-forward and reset only currently).
Because some users have literally hundreds of local branches we
use the standard revision picker (with its branch filtering tool)
to select the local branch, rather than keeping all of the local
branches in the Branch menu. The branch menu listing out all of
the available branches is simply not sane for those types of huge
repositories.
Users can now checkout a detached head by ticking off the option
in the checkout dialog. This option is off by default for the
obvious reason, but it can be easily enabled for any local branch
by simply checking it. We also detach the head if any non local
branch was selected, or if a revision expression was entered.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I'm really starting to dislike global variables. The ui_status_value
global varible is just one of those that seems to appear in a lot of
code and in many cases we didn't even declare it "global" within the
proc that updates it so we haven't always been getting all of the
updates we expected to see.
This change introduces two new global procs:
ui_status $msg; # Sets the status bar to show $msg.
ui_ready; # Changes the status bar to show "Ready."
The second (special) form is used because we often update the area
with this message once we are done processing a block of work and
want the user to know we have completed it.
I'm not fixing the cases that appear in lib/branch.tcl right now
as I'm actually in the middle of a huge refactoring of that code
to support making a detached HEAD checkout.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the current branch is not a symbolic-ref that points to a
name in the refs/heads/ namespace we now just assume that the
head is a detached head. In this case we return the special
branch name of HEAD rather than empty string, as HEAD is a
valid revision specification and the empty string is not.
I have also slightly improved the current-branch function by
using string functions to parse the symbolic-ref data. This
should be slightly faster than using a regsub. I think the
code is clearer too.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
In some workflows users will want to almost always just create a new
local branch that matches a remote branch. In this type of workflow
it is handy to have the new branch dialog default to "Match Tracking
Branch" and "Starting Revision"-Tracking Branch", with the focus in
the branch filter field. This can save users working on this type
of workflow at least two mouse clicks every time they create a new
local branch or switch to one with a fast-forward.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A simple refactoring of the delete branch dialog to allow use of
the class construct to better organize the code and to reuse the
revision selection code of our new choose_rev mega-widget.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This rather large change pulls the "Starting Revision" part of the
new branch dialog into a mega widget that we can use anytime we
need to select a commit SHA-1. To make use of the mega widget I
have also refactored the branch dialog to use the class system,
much like the delete remote branch dialog already does.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Some newer features of git-gui want to rely on features that are
new to Git 1.5.3. Since they were added as part of the 1.5.3
development series we cannot use those features with versions of
Git that are older than 1.5.3, such as from the stable 1.5.2 series.
We introduce [git-version >= 1.5.3] to allow the caller to get a
response of 0 if the current version of git is < 1.5.3 and 1 if
the current version of git is >= 1.5.3. This makes it easy to
setup conditional code based upon the version of Git available to
us at runtime.
Instead of parsing the version text by hand we now use the Tcl
[package vcompare] subcommand to compare the two version strings.
This works nicely, as Tcl as already done all of the hard work
of doing version comparsions. But we do have to remove the Git
specific components such as the Git commit SHA-1, commit count and
release candidate suffix (rc) as we want only the final release
version number.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint:
git-gui: Ensure windows shortcuts always have .bat extension
git-gui: Include a Push action on the left toolbar
git-gui: Bind M1-P to push action
git-gui: Don't bind F5/M1-R in all windows
Conflicts:
git-gui.sh
Pushing changes to a remote system is a very common action for
many users of git-gui, so much so that in some workflows a user
is supposed to push immediately after they make a local commit
so that their change(s) are immediately available for their
teammates to view and build on top of.
Including the push button right below the commit button on the
left toolbar indicates that users should probably perform this
action after they have performed the commit action.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users often need to be able to push the current branch so that they
can publish their recent changes to anyone they are collaborating
with on the project. Associating a keyboard action with this will
make it easier for keyboard-oriented users to quickly activate the
push features.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We actually only want our F5/M1-R keystroke bound in the main window.
Within a browser/blame/console window pressing these keys should not
execute the rescan action.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
On 'Visualize ...', a gitk process is started. Since it is run in the
background, catching a possible startup error doesn't work, and the error
output goes to the console git-gui is started from. The most probable
startup error is that gitk is not installed; so before trying to start,
check for the existence of the gitk program, and popup an error message
unless it's found.
This was noticed and reported by Paul Wise through
http://bugs.debian.org/429810
Signed-off-by: Gerrit Pape <pape@smarden.org>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint:
git-gui: Don't require a .pvcsrc to create Tools/Migrate menu hack
git-gui: Don't nice git blame on MSYS as nice is not supported
git-gui: Don't require $DISPLAY just to get --version
The Tools/Migrate menu option is a hack just for me. Yes, that's
right, git-gui has a hidden feature that really only works for me,
and the users that I support within my day-job's great firewall.
The menu option is not supported outside of that environment.
In the past we only enabled Tools/Migrate if our special local
script 'gui-miga' existed in the proper location, and if there
was a special '.pvcsrc' in the top level of the working directory.
This latter test for the '.pvcsrc' file is now failing, as the file
was removed from all Git repositories due to changes made to other
tooling within the great firewall's realm.
I have changed the test to only work on Cygwin, and only if the
special 'gui-miga' is present. This works around the configuration
changes made recently within the great firewall's realm, but really
this entire Tools/Migrate thing should be abstracted out into some
sort of plugin system so other users can extend git-gui as they need.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Junio asked that we don't force the user to have a valid X11 server
configured in $DISPLAY just to obtain the output of `git gui version`.
This makes sense, the user may be an automated tool that is running
without an X server available to it, such as a build script or other
sort of package management system. Or it might just be a user working
in a non-GUI environment and wondering "what version of git-gui do I
have installed?".
Tcl has a lot of warts, but one of its better ones is that a comment
can be continued to the next line by escaping the LF that would have
ended the comment using a backslash-LF sequence. In the past we have
used this trick to escape away the 'exec wish' that is actually a Bourne
shell script and keep Tcl from executing it.
I'm using that feature here to comment out the Bourne shell script and
hide it from the Tcl engine. Except now our Bourne shell script is a
few lines long and checks to see if it should print the version, or not.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because Tk does not assure us the order that it will process
children in before it destroys the main toplevel we cannot safely
save our geometry data during a "bind . <Destroy>" event binding.
The geometry may have already changed as a result of a one or
more children being removed from the layout. This was pointed
out in gitk by Mark Levedahl, and patched over there by commit
b6047c5a81.
So we now also use "wm protocol . WM_DELETE_WINDOW" to detect when
the window is closed by the user, and forward that close event to
our main do_quit routine.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Apparently git-commit.sh (the command line commit user interface in
core Git) always gives precedence to the prior commit's message if
`commit --amend` is used and a $GIT_DIR/MERGE_MSG file also exists.
We actually were doing the same here in git-gui, but the amended
message got lost if $GIT_DIR/MERGE_MSG already existed because
we started a rescan immediately after loading the prior commit's
body into the edit buffer. When that happened the rescan found
MERGE_MSG existed and replaced the commit message buffer with the
contents of that file. This meant the user never saw us pick up
the commit message of the prior commit we are about to replace.
Johannes Sixt <J.Sixt@eudaptics.com> found this bug in git-gui by
running `git cherry-pick -n $someid` and then trying to amend the
prior commit in git-gui, thus combining the contents of $someid
with the contents of HEAD, and reusing the commit message of HEAD,
not $someid. With the recent changes to make cherry-pick use the
$GIT_DIR/MERGE_MSG file Johannes saw git-gui pick up the message
of $someid, not HEAD. Now we always use HEAD if we are amending.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint: (38 commits)
git-gui: Changed blame header bar background to match main window
git-gui: Favor the original annotations over the recent ones
git-gui: Improve our labeling of blame annotation types
git-gui: Use three colors for the blame viewer background
git-gui: Jump to original line in blame viewer
git-gui: Display both commits in our tooltips
git-gui: Run blame twice on the same file and display both outputs
git-gui: Display the "Loading annotation..." message in italic
git-gui: Rename fields in blame viewer to better descriptions
git-gui: Label the uncommitted blame history entry
git-gui: Switch internal blame structure to Tcl lists
git-gui: Cleanup redundant column management in blame viewer
git-gui: Better document our blame variables
git-gui: Remove unused commit_list from blame viewer
git-gui: Automatically expand the line number column as needed
git-gui: Make the line number column slightly wider in blame
git-gui: Use lighter colors in blame view
git-gui: Remove unnecessary space between columns in blame viewer
git-gui: Remove the loaded column from the blame viewer
git-gui: Clip the commit summaries in the blame history menu
...
If the user clicks on a line region that we haven't yet received
an annotation for from git-blame we show them "Loading annotation".
But I don't want the user to confuse this loading message with a
commit whose first line is "Loading annotation" and think we messed
up our display somehow. Since we never use italics for anything
else, I'm going with the idea that italic slant can be used to show
data is missing/elided out at the time being.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The default font was already bold, so marking the selected file with bold
font did not work. Change that to lightgray background.
Also, the header colors are now softer, giving better readability.
Signed-off-by: Matthijs Melchior <mmelchior@xs4all.nl>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
* maint:
Revert "Make the installation target of git-gui a little less chatty"
git-gui: Verify Tcl/Tk is new enough for our needs
git-gui: Attach font_ui to all spinbox widgets
For quite a while we have been assuming the user is running on
a Tcl/Tk 8.4 or later platform. This may not be the case on
some very old systems. Unfortunately I am pretty far down the
path of using the Tcl/Tk 8.4 commands and options and cannot
easily work around them to support earlier versions of Tcl/Tk.
So we'll check that we are using the correct version up front,
and if not we'll stop with a related error message.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Earlier I missed making sure our spinbox widgets used the same font
as the other widgets around them. This meant that using a main font
with a size of 20 would make every widget in the options dialog huge,
but the spinboxes would be left with whatever the OS native font is.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Its wrong to exit the application if we destroy a random widget
contained withing something else; especially if its some small
trivial thing that has no impact on the overall operation.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To improve performance on fork+exec impoverished systems (such as
Windows) we want to avoid running git-symbolic-ref on every rescan
if we can do so. A quick way to implement such an avoidance is to
just read the HEAD ref ourselves; we'll either see it as a symref
(starts with "ref: ") or we'll see it as a detached head (40 hex
digits). In either case we can treat that as our current branch.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
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>
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>
If we cannot locate our git-gui library directory, or we find it
but the tclIndex file is not present there (or it is present but
is not something we are allowed to read) the user cannot use the
application. Rather than silently ignoring the errors related to
the tclIndex file being unavailable we report them up front and
display to the user why we cannot start.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When we are using our "non-optimized" tclIndex format (which is
just a list of filenames, in the order necessary for source'ing)
we are doing all of our loading before we even tested to see if
GITGUI_VERBOSE was set in the environment. This meant we never
showed the files as we sourced them into the environment.
Now we setup our overloaded auto_load and source scripts before
we attempt to define our library path, or source the scripts that
it mentions. This way GITGUI_VERBOSE is always honored if set.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because we now try to automatically guess the library directory
in certain installations users may wonder where git-gui is getting
its supporting files from. We now display this location in our
About dialog, and we also include the location we are getting our
Git executables from.
Unfortunately users cannot use this 'About git-gui' dialog to
troubleshoot library loading problems; the dialog is defined by
code that exists in the library directory, creating a catch-22.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
In some workflows it is common for a large number of temporary
branches to be created in a remote repository, get fetched to
clients that typically only use git-gui, and then later have
those branches deleted from the remote repository once they have
been fully merged into all destination branches. Users of git-gui
would obviously like to have their local tracking branches cleaned
up for them, otherwise their local tracking branch namespace would
grow out of control.
The best known way to remove these tracking branches is to run
"git remote prune <remotename>". Even though it is more of a
Porcelain command than plumbing I'm invoking it through the UI,
because frankly I don't see a reason to reimplement its ls-remote
output filtering and config file parsing.
A new configuration option (gui.pruneduringfetch) can be used to
automatically enable running "git remote prune <remotename>" after
the fetch of that remote also completes successfully. This is off
by default as it require an additional network connection and is
not very fast on Cygwin if a large number of tracking branches have
been removed (due to the 2 fork+exec calls per branch).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
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>
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>
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>
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>
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>
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>
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>
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>
All menu entries talk about "staging" and "unstaging" changes, but the
titles of the file lists use different wording, which may confuse
newcomers.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Like the console procs I have moved the code related to merge
support into their own namespace, so that they are isolated
from the rest of the world.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
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>
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>
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>
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>
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>
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>
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>
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
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>
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>
Some parts of git-gui were not respecting the default GUI font.
Most of them were catched and fixed.
Signed-off-by: Eygene Ryabinkin <rea-git@codelabs.ru>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
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>
This reverts commit 871f4c97ad.
Too many users have complained about the credits generator in
git-gui, so I'm backing the entire thing out. This revert will
finish that series.
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>
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>
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>
Now that the 'browser' subcommand can be used to startup the tree
browser, it should be listed as a possible subcommand option in
our usage message.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Since git-gui does more than create commits, it is unfair to call
it "a commit creation tool". Instead lets just call it a graphical
user interface.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that git-gui has been released to the public as part of Git 1.5.0
I am starting to see some work from other people beyond myself and
Paul. Consequently the copyright for git-gui is not strictly the
two of us anymore, and these others deserve to have some credit
given to them.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The Firefox browser requires that a URL use / to delimit directories.
This is instead of \, as \ gets escaped by the browser into its hex
escape code and then relative URLs are incorrectly resolved, Firefox
no longer sees the directories for what they are. Since we are
handing the browser a true URL, we better use the standard / for
directories.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Martin Waitz noticed that git-gui crashed while saving the user's
options out if the application was started in blame mode. This
was caused by the do_save_config procedure invoking reshow_diff
incase the number of context lines was modified by the user.
Because we bypassed main window UI setup to enter blame mode we
did not set many of the globals which were accessed by reshow_diff,
and reading unset variables is an error in Tcl.
Aside from moving the globals to be set earlier, I also modified
reshow_diff to not invoke clear_diff if there is no path currently
in the diff viewer. This way reshow_diff does not crash when in
blame mode due to the $ui_diff command not being defined.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Some users may find being able to browse around an arbitrary
branch to be handy, so we now expose our graphical browser
through `git gui browse <committish>`.
Yes, I'm being somewhat lazy and making the user give us
the name of the branch to browse. They can always enter
HEAD.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I'm missing the possibility to base a new branch on a tag.
The following adds a tag drop down to the new branch dialog.
Signed-off-by: Martin Koegler <mkoegler@auto.tuwien.ac.at>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Like `git version`, `git gui version` (or `git gui --version`) shows
the version of git-gui, in case the user needs to know this, without
looking at it in the GUI about dialog.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I started to find it confusing that git-gui would refer to itself
as git-citool when it was started through the citool hardlink, or
with the citool subcommand. What was especially confusing was the
options dialog and the about dialog, as both seemed to imply they
were somehow different from the git-gui versions. In actuality
there is no difference at all.
Now we just call our options menu item 'Options...' (skipping the
application name) and our About dialog now always shows git-gui
within the short description (above the copyleft notice) and in
the version field.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
It was pointed out on the git mailing list by Martin Koegler that
we did not show tags as possible things to merge into the current
branch. They actually are, and core Git's Grand Unified Merge
Driver will accept them just like any other commit.
So our merge dialog now requests all refs/heads, refs/remotes and
refs/tags named refs and attempts to match them against the commits
not in HEAD. One complicating factor here is that we must use the
%(*objectname) field when talking about an annotated tag, as they
will not appear in the output of rev-list.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This is a very crude (but hopefully effective) check against the
`git` executable found in our PATH. Some of the subcommands and
options that git-gui requires to be present to operate were created
during the 1.5.0 development cycle, so 1.5 is the minimum version
of git that we can expect to support.
There actually are early releases of 1.5 (e.g. 1.5.0-rc0) that
don't have everything we expect (like `blame --incremental`) but
these are purely academic at this point. 1.5.0 final was tagged
and released just a few hours ago. The release candidates will
(hopefully) fade into the dark quickly.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
As we frequently need to execute a Git subcommand and obtain
its returned output we are making heavy use of [exec git foo]
to run foo. As I'm concerned about possibly needing to carry
environment data through a shell on Cygwin for at least some
subcommands, I'm migrating all current calls to a new git
proc. This actually makes the code look cleaner too, as
we aren't saying 'exec git' everywhere.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that the decision has been made to treat git-gui as a
subproject, rather than merging it directly into git, we
should use a different substitution for our version value
to avoid any possible confusion.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that git 1.5.0 and later contains a version of gitk that uses
correct geometry on Windows platforms, even if ~/.gitk exists, we
should not delete the user's ~/.gitk to work around the bug. It
is downright mean to remove a user's preferences for another app.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Rather than trying to mark the background color of the line numbers
to show which lines have annotated data loaded, we now show a ruler
between the line numbers and the file data. This ruler is just 1
character wide and its background color is set to grey to denote
which lines have annotation ready. I had to make this change as I
kept loosing the annotation marker when a line was no longer colored
as part of the current selection.
We now color the lines blamed on the current commit in yellow, the
lines in the commit which came after (descendant) in red (hotter,
less tested) and the lines in the commit before (ancestor) in blue
(cooler, better tested).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To help clue users into the fact that annotation data arrives
incrementally, and that they should try to locate the region
they want while the tool is running, we jump to the first line
of the first annotation if the user has not already clicked on
a line they are interested in and if the window is still looking
at the very top of the file.
Since it takes a second (at least on my PowerBook) to even generate
the first annotation for git-gui.sh, the user should have plenty of
time to adjust the scrollbar or click on a line even before we get
that first annotation record in, which allows the user to bypass
our automatic jumping.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Using 180 columns worth of screen space to display just 20 columns of
file data and 160 columns worth of annotation information is not
practically useful. Users need/want to see the file data, and have
the anotation associated with it displayed in a detail pane only when
they have focused on a particular region of the file.
Now our file viewer has a small 10-line high pane below the file
which shows the commit message for the commit this line was blamed
on. The columns have all been removed, except the current line
number column as that has some real value when trying to locate an
interesting block.
To keep the user entertained we have a progress meter in the status
bar of the viewer which lets them know how many lines have been
annotated, and how much has been completed. We use a grey background
on the line numbers for lines which we have obtained annotation from,
and we color all lines in the current commit with a yellow background,
so they stand out when scanning through the file. All other lines
are kept with a white background, making the yellow really pop.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that core Git has "renamed" git-repo-config to git-config,
we should do the same. I don't know how long core Git will
keep the repo-config command, and since git-gui's userbase
is so small and almost entirely on some flavor of 1.5.0-rc2
or later, where the rename has already taken place, it should
be OK to rename now.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
One user that I spoke with recently was confused why the 'Add All'
button did not add all of his 'Changed But Not Updated' files.
The particular files in question were new, and thus not known to
Git. Since the 'Add All' routine only updates files which are
already tracked, they were not added automatically.
I suspect that calling this action 'Add Existing' would be less
confusing, so I'm renaming it.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we are invoked as `git-foo`, then we should run the `foo` subcommand,
as the user has made some sort of link from `git-foo` to our actual
program code. So we should honor their request.
If we are invoked as `git-gui foo`, the user has not made a link (or
did, but is not using it right now) so we should execute the `foo`
subcommand.
We now can start the single commit UI mode via `git-citool` and also
through `git gui citool`.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Viewing annotated files is one of those tasks that is relatively
difficult to do in a simple vt100 terminal emulator. The user
really wants to be able to browse through a lot of information,
and to interact with it by navigating through revisions.
Now users can start our file viewer with annotations by running
'git gui blame commit path', thereby seeing the contents of the
given file at the given commit. Right now I am being lazy by
not allowing the user to omit the commit name (and have us thus
assume HEAD).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the commit area does not exist, don't save the commit message to
a file, or the window geometry. The reason I'm doing this is I want
to make the main window entirely optional, such as if the user has
asked us to show a blame from the command line. In such cases the
commit area won't exist and trying to get its text would cause an
error.
If we are running without the commit message area, we cannot save
our window geometry either, as the root window '.' won't be a normal
commit window.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This is a minor code cleanup to make working with what used to be the
$single_commit flag easier. Its also to better handle various UI
configurations, depending on command line parameters given by the
user, or perhaps user preferences.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We already replace \n with \\n so that Tk widgets don't start a new
display line with part of a file path which is just unlucky enough
to contain an LF. But then its confusing to read a path whose name
actually contains \n as literal characters. Escaping \ to \\ would
make that case display as \\n, clarifying the output.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users want to navigate the file list shown in our branch browser
windows using the keyboard. So we now support basic traversal
with the arrow keys:
Up/Down: Move the "selection bar" to focus on a different name.
Return: Move into the subtree, or open the annotated file.
M1-Right: Ditto.
M1-Up: Move to the parent tree.
M1-Left: Ditto.
Probably the only feature missing from this is to key a leading part
of the file name and jump directly to that file (or subtree).
This change did require a bit of refactoring, to pull the navigation
logic out of the mouse click procedure and into more generic routines
which can also be used in bindings.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user has created (or deleted) a branch through an external tool,
and uses Rescan, they probably are trying to make git-gui update to show
their newly created branch.
So now we load all known heads and update the branch menu during any
rescan operation, just in-case the set of known branches was modified.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To help the user visually see which lines are associated with each other
in the file we attempt to sign a unique background color to each commit
and then render all text associated with that commit using that color.
This works out OK for a file which has very few commits in it; but
most files don't have that property.
What we really need to do is look at what colors are used by our
neighboring commits (if known yet) and pick a color which does not
conflict with our neighbor. If we have run out of colors then we
should force our neighbor to recolor too. Yes, its the graph coloring
problem.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Using a panedwindow to display the blame viewer's individual columns
just doesn't make sense. Most of the important data fits within the
columns we have allocated, and those that don't the leading part fits
and that's good enough. There are just too many columns within this
viewer to let the user sanely control individual column widths. This
change shouldn't really be an issue for most git-gui users as their
displays should be large enough to accept this massive dump of data.
We now also have a properly working horizontal scrollbar for the
current file data area. This makes it easier to get away with a
narrow window when screen space is limited, as you can still scroll
around within the file content.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I started to get confused about what each column meant in the blame
viewer, and I'm the guy who wrote the code! So now git-gui hints to
the user about what each column is by drawing headers at the top.
Unfortunately this meant I had to use those dreaded frame objects
which seem to cause so much pain on Windows.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When we annotate a file and show its line data, we're already asking
for copy and movement detection (-M -C). This costs extra time, but
gives extra data. Since we are asking for the extra data we really
should show it to the user.
Now the blame UI has two additional columns, one for the original
filename (in the case of a move/copy between files) and one for the
original line number of the current line of code.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Anytime are about to open a pipe on what may be user data we need to
make sure the value is escaped correctly into a Tcl list, so that the
executed subprocess will receive the right arguments. For the most
part we were already doing this correctly, but a handful of locations
did not.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Since we run blame incrementally in the background we might as well get
as much data as we can from the file. Adding -M and -C definately makes
it take longer to compute the revision annotations, but since they are
streamed in and updated as they are discovered we'll get recent data
almost immediately anyway.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users may need to be able to alter their user.name or user.email
configuration settings. If they are mostly a git-gui user they
should be able to view/set these important values from within
the git-gui environment, rather than needing to edit a raw text
file on their local filesystem.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Rather than using HEAD for the current branch, use the actual name of
the current branch in the browser. This way the user knows what a
browser is browsing if they open up different browsers while on different
branches.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Real icons which seem to indicate going up to the parent (an up arrow)
and a subdirectory (an open folder). Files are now drawn with the
file_mod icon, like a modified file is. This just looks better as it
is more consistent with the rest of our UI.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This rather huge change provides a browser for the current branch. The
browser simply shows the contents of tree HEAD, and lets the user drill
down through the tree. The icons used really stink, as I just copied in
icon which we already had. I really need to replace the file_dir and
file_uplevel icons with something more useful.
If the user double clicks on a file within the browser we open it in
a blame viewer. This makes use of the new incremental blame feature
that Linus just added yesterday to core Git. Fortunately the feature
will be in 1.5.0 final so we can rely on having it available here.
Since the blame engine is incremental the user will get blame data
for groups which can be determined early. Git will slowly fill in
the remaining lines as it goes.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Running on Cygwin is different than if we were running through MinGW.
In the Cygwin case we have cygpath available to us, we need to perform
UNIX<->Windows path translation sometimes, and we need to perform odd
things like spawning our own login shells to perform network operations.
But in the MinGW case these don't occur. Git knows native Windows file
paths, and login shells may not even exist.
Now git-gui will avoid running cygpath unless it knows its on Cygwin.
It also uses a different shortcut type when Cygwin is not present, and
it avoids invoking /bin/sh to execute hooks if Cygwin is not present.
This latter part probably needs more testing in the MinGW case.
This change also improves how we start gitk. If the user is on any type
of Windows system its known that gitk won't start right if ~/.gitk exists.
So we delete it before starting if we are running on any type of Windows
operating system. We always use the same wish executable which launched
git-gui to start gitk; this way on Windows we don't have to jump back to
/bin/sh just to go into the first wish found in the user's PATH. This
should help on MinGW when we probably don't want to spawn a shell just
to start gitk.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users may want to be able to read Git documentation, even if they
are not command line users. There are many important concepts and
terms covered within the standard Git documentation which would be
useful to even non command line using people.
We now try to offer an 'Online Documentation' menu option within the
Help menu. First we try to guess to see what browser the user has
setup. We default to instaweb.browser, if set, as this is probably
accurate for the user's configuration. If not then we try to guess
based on the operating system and the available browsers for each.
We prefer documentation which is installed parallel to Git's own
executables, e.g. `git --exec-path`/../Documentation/index.html, as
that is how I typically install the HTML docs. If those are not found
then we open the documentation published on kernel.org.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
OK, its official, I'm not reading documentation as well as I should be.
Core Git's merge.summary configuration option is used to control the
generation of the text appearing within the merge commit itself. It
is not (and never has been) used to default the --no-summary command
line option, which disables the diffstat at the end of the merge.
I completely blame Git for naming two unrelated options almost the
exact same thing. But its my own fault for allowing git-gui to
confuse the two.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Changed our private merge summary config option to be the same as the
merge.summary option supported by core Git. This means setting the
"Show Merge Summary" flag in git-gui will have the same effect on
the command line.
In the same vein I've also added merge.verbosity to the gui options,
allowing the user to adjust the verbosity level of the recursive
merge strategy. I happen to like level 1 and suggest that other users
use that, but level 2 is the core Git default right now so we'll use
the same default in git-gui.
Unfortunately it appears as though core Git has broken support for
the merge.summary option, even though its still in the documentation
For the time being we should pass along --no-summary to git-merge if
merge.summary is false.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Anytime we use a listbox to show branch names its possible for the
listbox to exceed 10 entries (actually its probably very common).
So we should always offer a scrollbar for the Y axis on these
listboxes. I just forgot to add it when I defined them.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user is in the middle of a commit they have files which are
modified. These may conflict with any merge that they may want
to perform, which would cause problems if the user wants to abort
a bad merge as we wouldn't have a checkpoint to roll back onto.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If an octopus merge goes horribly wrong git-merge will leave the
working directory and index dirty, but will not leave behind a
MERGE_HEAD file for a later commit. Consequently we won't know
its a merge commit and instead would let the user resolve the
conflicts and commit a single-parent commit, which is wrong.
So now if an octopus merge fails we notify the user that the
merge did not work, tell them we will reset the working directory,
and suggest that they merge one branch at a time. This prevents
the user from committing a bad octopus merge.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I got slightly confused when I did two merges in a row, as the status
bar said "merge completed successfully" while the second merge was
still running. Now we show what branches are actively being merged.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If you get into the middle of a merge that turns out to be horrible
and just not something you want to do right now, odds are you need
to run `git reset --hard` to recover your working directory to a
pre-merge state.
We now offer Merge->Abort Merge for exactly this purpose, however
its also useful to thow away a non-merge, as its basically the same
logic as `git reset --hard`.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
To allow users to merge local heads and tracking branches we now offer
a dialog which lets the user select 1-15 branches and merge them using
the stock `git merge` Grand Unified Merge Driver.
Originally I had wanted to implement this merge internally within git-gui
as I consider GUMD to be mostly Porcelain-ish, but the truth is it does
its job exceedingly well and its a relatively complex chunk of code.
I'll probably circle back later and try to remove the invocation of GUMD
from git-gui, but right now it lets me get the job done faster.
Users cannot start a merge if they are currently in the middle of one,
or if they are amending a commit. Trying to do either is just stupid
and should be stopped as early as possible.
I've also made it simple for users to startup a gitk session prior to
a merge by offering a Visualize button which runs `gitk $revs --not HEAD`,
where $revs is the list of branches currently selected in the merge
dialog. This makes it quite simple to find out what the damage will
be to the current branch if you were to carry out the currently proposed
merge.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Technically the new git-gc command is strictly Porcelain; its invoking
multiple plumbing commands to do its work. Since git-gui tries to not
rely on Porclain we shouldn't be invoking git-gc directly, instead we
should perform its tasks on our own.
To make this easy I've created console_chain, which takes a list of
tasks to perform and runs them all in the same console window. If
any individual task fails then the chain stops running and the window
shows a failure bar. Only once all tasks have been completed will it
invoke console_done with a successful status.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because I want to be able to run multiple output-producing commands
in a single 'console' window within git-gui I'm refactoring the
console handling routines to require the "after" argument of console_exec.
This should specify a procedure to execute which will receive two args,
the first is the console window handle and the second is the status of
the last command (0 on failure, 1 on success).
A new procedure console_done can be passed to the last console_exec
command to forward perform all cleanup and enable the Close button.
Its status argument is used to update the final status bar on the
bottom of the console window.
This isn't any real logic changing, and no new functionality is in
this patch.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Right now `git-push -v` is actually not that verbose; it merely adds
the URL it is pushing to. This can be informative if you are pushing
to a configured remote, as you may not actually remember what URL that
remote is connected to. That detail can be important if the push
fails and you attempt to communicate the errors to a 3rd party to help
you resolve the issue.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because we aren't going to support single click pulling of changes from
an existing remote anytime in the near future, I'm moving the code which
used to perform that action. Hopefully we'll be able to do something
like it in the near-future, but also support local branches just as
easily.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Because its common for some users to push topic branches to a remote
repository for review and merging by other parties, users need an
easy way to push one or more branches to a remote repository without
needing to edit their .git/config file anytime their set of active
branches changes.
We now provide a basic 'Push...' menu action in the Push menu which
opens a dialog allowing the user to select from their set of local
branches (refs/heads, minus tracking branches). The user can designate
which repository to send the changes to by selecting from an already
configured remote or by entering any valid Git URL.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Anytime we are using lsearch we are doing [lsearch -sorted] and we
are applying it to file paths (or file path like things). Its valid
for these to contain special glob characters, but when that happens
we do not want globbing to occur. Instead we really need exact
match semantics. Always supplying -exact to lsearch will ensure that
is the case.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I just noticed that a file was always jumping to compare against HEAD
and the index during a refresh, even if the diff viewer was comparing
the index against the working directory prior to the refresh. The
bug turned out to be caused by a foreach loop going through all file
list names searching for the path. Since $ui_index was the first one
searched and the file was contained in that file list the loop broke
out, leaving $w set to $ui_index when it had been set by the caller
to $ui_workdir. Silly bug caused by using a parameter as a loop
index.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Its pointless to switch to the current branch, so don't do it. We
are already on it and the current index and working directory should
just be left alone.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The Pull menu as it stands right now is a really horrible idea. Most
users will have too many branches show up in this menu, and what with
the new globbing syntax for fetch entries we were offering up possible
merging that just isn't really valid. So this menu is dead and will
be rewritten to support better merge capabilities.
The Branch menu shouldn't include a separator entry if there are no
branches, it just looks too damn weird. This can happen in an initial
repository before any branches have been created and before the first
commit.
The Fetch and Push menus should just be organized around their own
menus rather than being given the menu to populate.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I'm a fool and previously used a text widget configured with a height
of 1 and special bindings to handle focus traversal rather than the
already built (and properly behaved) entry widget.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The stat frame was right on the edge of the window on Mac OS X,
making the frame's border blend in with the window border. Not
exactly the effect I had in mind.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Now that recent versions of gitk (shipping with at least git 1.5.0-rc1
and later) actually accept command line revision specifiers without
crashing on internal Tk errors we can offer the 'Visualize All Branches'
menu item in the Repository menu on Mac OS X.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Apparently a "feature" of Tcl/Tk on Mac OS X is that a disabled text
widget cannot receive focus or receive a selection within it. This
makes the diff viewer almost useless on that platform as you cannot
select individual parts of the buffer.
Now we force focus into the diff viewer when its clicked on with
button 1. This works around the feature and allows selection to
work within the viewer just like it does on other less sane systems,
like Microsoft Windows.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When committing changes its useless to have trailing whitespace on the
end of a line within the commit message itself; this serves no purpose
beyond wasting space in the repository. But it happens a lot on my
Mac OS X system if I copy text out of a Terminal.app window and paste
it into git-gui.
We now clip any trailing whitespace from the commit buffer when loading
it from a file, when saving it out to our backup file, or when making
the actual commit object.
I also fixed a bug where we lost the commit message buffer if you quit
without editing the text region. This can happen if you quit and restart
git-gui frequently in the middle of an editing session.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we are displaying a diff for a DOS-style (CRLF) formatted file then
the Tk text widget would normally show the CR at the end of every line;
in most fonts this will come out as a square box. Rather than showing
this character we'll tag it with a tag which forces the character to
be elided away, so its not displayed. However since the character is
still within the text buffer we can still obtain it and supply it over
to `git apply` when staging or unstaging an individual hunk, ensuring
that the file contents is always fully preserved as-is.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Just like `git-add --interactive` we can now stage and unstage individual
hunks within a file, rather than the entire file at once. This works
on the basic idea of scanning backwards from the mouse position to
find the hunk header, then going forwards to find the end of the hunk.
Everything in that is sent to `git apply --cached`, prefixed by the
diff header lines.
We ignore whitespace errors while applying a hunk, as we expect the
user's pre-commit hook to catch any possible problems. This matches
our existing behavior with regards to adding an entire file with
no whitespace error checking.
Applying hunks means that we now have to capture and save the diff header
lines, rather than chucking them. Not really a big deal, we just needed
a new global to hang onto that current header information. We probably
could have recreated it on demand during apply_hunk but that would mean
we need to implement all of the funny rules about how to encode weird
path names (e.g. ones containing LF) into a diff header so that the
`git apply` process would understand what we are asking it to do. Much
simpler to just store this small amount of data in a global and replay
it when needed.
I'm making absolutely no attempt to correct the line numbers on the
remaining hunk headers after one hunk has been applied. This may
cause some hunks to fail, as the position information would not be
correct. Users can always refresh the current diff before applying a
failing hunk to work around the issue. Perhaps if we ever implement
hunk splitting we could also fix the remaining hunk headers.
Applying hunks directly means that we need to process the diff data in
binary, rather than using the system encoding and an automatic linefeed
translation. This ensures that CRLF formatted files will be able to be
fed directly to `git apply` without failures. Unfortunately it also means
we will see CRs show up in the GUI as ugly little boxes at the end of
each line in a CRLF file.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
There is no reason to attempt refreshing an empty diff viewer, so
the Refresh option of our diff context menu should be disabled when
there is no diff currently shown.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Just as we show the amount of disk space taken by the loose objects,
its interesting to know how much space is taken by the packs directory.
So show that in our Database Statistics dialog.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
In the new branch dialog and delete branch dialog we are using the
system default labelframe border settings (whatever those are) and
they look reasonable on both Windows and Mac OS X. But for some
unknown reason to me I used a raised border for the options dialog.
It doesn't look consistent anymore, so I'm switching it to the
defaults.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user selects a different branch from the Branch menu, or asks
us to create a new branch and immediately checkout that branch we
now perform the update of the working directory by way of a 2 way
read-tree invocation.
This emulates the behavior of `git checkout branch` or the behavior
of `git checkout -b branch initrev`. We don't however support the
-m style behavior, where a switch can occur with file level merging
performed by merge-recursive. Support for this is planned for a
future update.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Its nice to know how many loose objects and roughly how much disk space
they are taking up, so that you can guestimate about when might be a
good time to run 'Compress Database'. The same is true of packfiles,
especially once the automatic keep-pack code in git-fetch starts to
be more widely used.
We now offer the output of count-objects -v in a nice little dialog
hung off the Repository menu. Our labels are slightly more verbose
than those of `count-objects -v`, so users will hopefully be able
to make better sense of what we are showing them here.
We probably should also offer pack file size information, and data
about *.idx files which exist which lack corresponding *.pack files
(a situation caused by the HTTP fetch client). But in the latter
case we should only offer the data once we have way to let the user
clean up old and inactive index files.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Git prefers that all log messages are encoding in UTF-8. So now when
git-gui generates the commit message it converts the commit message
text from the internal Tcl Unicode representation into a UTF-8 file.
The file is then fed as stdin to git-commit-tree. I had to start
using a file here rather than feeding the message in with << as
<< uses the system encoding, which we may not want.
When we reload a commit message via git-cat-file we are getting the
raw byte stream, with no encoding performed by Git itself. So unless
the new 'encoding' header appears in the message we should probably
assume it is utf-8 encoded; but if the header is present we need to
use whatever it claims.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Since git operates on filenames using the operating system encoding
any data we are receiving from it by way of a pipe, or sending to it
by way of a pipe must be formatted in that encoding. This should
be the same as the Tcl system encoding, as its the encoding that
applications should be using to converse with the operating system.
Sadly this does not fix the gitweb/test file in git.git on Macs;
that's due to something really broken happening in the filesystem.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This newline is stupid; it doesn't get put here unless the file
is very large, and then its just sort of out of place.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Users may want to know what a file is before they add it to the
repository, especially if its a binary file. So when possible
invoke 'file' on the path and try to get its output. Since
this is strictly advice to the user we won't bother to report
any failures from our attempt to run `file`.
Since some file commands also output the path name they were
given we look for that case and strip it off the front of the
returned output before placing it into the diff viewer.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Our internal diff viewer displays untracked files to help users see if
they should become tracked, or not. It is not meant as a full file
viewer that handles any sort of input. Consequently it is rather
unreasonable for users to expect us to show them very large files.
Some users may click on a very big file (and not know its very big)
then get surprised when Tk takes a long time to load the content and
render it, especially if their memory is tight and their OS starts to
swap processes out.
Instead we now limit the amount of data we load to the first 128 KiB
of any untracked file. If the file is larger than 128 KiB we display
a warning message at the top of our diff viewer to notify the user
that we are not going to load the entire thing. Users should be able
to recognize a file just by its first 128 KiB and determine if it
should be added to the repository or not.
Since we are loading 128 KiB we may as well scan it to see if the
file is binary. So I've removed the "first 8000 bytes" rule and
just allowed git-gui to scan the entire data chunk that it read in.
This is probably faster anyway if Tcl's [string range] command winds
up making a copy of the data.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
A binary file can be very large, and showing the complete content of
one is horribly ugly and confusing. So we now use the same rule that
core Git uses; if there is a NUL byte (\0) within the first 8000 bytes
of the file we assume it is binary and refuse to show the content.
Given that we have loaded the entire content of the file into memory
we probably could just afford to search the whole thing, but we also
probably should not load multi-megabyte binary files either.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we got an empty diff its probably because the modification time of
the file was changed but the file content hasn't been changed. Typically
this happens because an outside program modified the file and git-gui
was told to not run 'update-index --refresh', as the user generally
trusts file modification timestamps. But we can also get an empty diff
when a program undos a file change and still updates the modification
timestamp upon saving, but has undone the file back to the same as what
is in the index or in PARENT.
So even if gui.trustmtime is false we should still run a rescan on
an empty diff. This change also lets us cleanup the dialog message
that we show when this case occurs, as its no longer got anything to
do with Trust File Modification Timestamps.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If one or both versions of the file don't have a newline at the end
of the file we get a line telling us so in the diff output. This
shouldn't be tagged, nor should it generate a warning about not
being tagged.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Sometimes the Select All action from our context menus doesn't work
unless the text field its supposed to act on has focus. I'm not
really sure why adding the sel tag requires having focus. It
technically should not be required to update the sel tag membership,
but perhaps there is a bug in Tcl/Tk 8.4.1 on Windows which is
causing this odd behavior.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We don't want to tag these new file/delete file lines, as they aren't
actually that interesting. Its quite clear from the diff itself that
the file is a new file or is a deleted file (as the entire thing will
appear in the diff).
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Its possible for external programs to update file modification dates of
many files within a repository. I've seen this on Windows with a popular
virus scanner, sadly enough. If the user has Trust File Modification
Timestamp enabled and the virus scanner touches a large number of files
it can be annoying trying to clear them out of the 'Changed But Not
Updated' file list by clicking on them one at a time to load the diff.
So now we force a rescan as soon as one such file is found, and for
just that rescan we disable the Trust File Modification Timestamp option
thereby allowing Git to update the modification dates in the index.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
We sometimes see a mode line show up in a diff if the file mode was
changed. But its not something we format specially.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If we are making an initial commit our branch head did not exist when
we scanned for all heads during startup. Consequently we won't have
it in our branch menu. So force it to be put there after the ref was
created.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
I didn't really like the way a new git-gui launched in a new repository
as the window geometry wasn't quite the best layou. So this is a minor
tweak to try and get space distributed around the window better.
By decreasing the widths we're also able to shrink the gui smaller
without Tk clipping content at the edge of the window. A nice feature.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Up until now git-gui did not support the new wildcard syntax used to
fetch any remote branch into a tracking branch during 'git fetch'. Now
if we identify a tracking branch as ending with the string '/*' then
we use for-each-ref to print out the reference names which may have
been fetched by that pattern. We also now correctly filter any
tracking branches out of refs/heads, if they user has placed any there.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When the user selects a starting revision from one of our offered popup
lists (local branches or tracking branches) or enters in an expression
in the expression input field we should automatically activate the
corresponding radio button for them.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
If the user is tabbing through fields in the options dialog they are
likely to want to just enter a new value for the field, rather than
edit the value in-place. This is easier if we select the entire value
upon focusing into the field.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
When we are in a dialog such as the new branch dialog or our options
dialog we should permit the user to traverse around through the available
widgets with their Tab/Shift-Tab key combinations. So in any single
line text field where we don't want tab characters to actually be
inserted into the value rebind Tab and Shift-Tab to honor what the
tk_focusPrev and tk_focusNext scripts recommend.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>