538 Commits

Author SHA1 Message Date
Johannes Sixt
c461528cd4 git-gui: fix error handling of Revert Changes command
The command Revert Changes has two different erroneous behaviors
depending on the Tcl version used.

The command uses a "chord" facility where different "notes" are
evaluated asynchronously and any error is reported after all of them
have finished. The intent is that a private namespace is used where
the notes can store the error state. Tcl 9 changed namespace handling
in a subtle way, as https://www.tcl-lang.org/software/tcltk/9.0.html
summarizes under "Notable incompatibilities":

    Unqualified varnames resolved in current namespace, not global.
    Note that in almost all cases where this causes a change, the
    change is actually the removal of a latent bug.

And that's exactly what happens here.

- Under Tcl 9:

  - When the command operates without any errors, the variable `err`
    is never set. When the error handler wants to inspect `err` (in
    the correct private namespace), it does not find it and a Tcl
    error about an unset variable occurs. Incidentally, this is also
    the case when the user cancels the operation with the option
    "Do Nothing"!

    On the other hand, when an error occurs during the operation, `err`
    is set and found as intended.

  Check for the existence of the variable `err` before the attempt to
  read it.

- Under Tcl 8.6:

  The error handler looks up `err` in the global namespace, which is
  bogus and unintended. The variable is set due to the many
  `catch ... err` that occur during startup in the global namespace.

  - When the command operates without any errors, the error handler
    finds the global `err`, which happens to be the empty string at
    this point, and no error is reported.

    On the other hand, when an error occurs during the operation, the
    global `err` is set and found, so that an error is reported as
    desired.

    However, the value of `err` persists in the global namespace. When
    the command is repeated, an error is reported again, even if there
    was actually no error, and even "Do Nothing" was used to cancel
    the operation.

  Clear the global `err` before the operation begins.

The lingering error message is not a problem under Tcl 9, because a
prestine namespace is established every time the command is used.

This fixes https://github.com/j6t/git-gui/issues/21.

Helped-by: Igor Stepushchik
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-09-01 21:07:57 +02:00
Johannes Sixt
14ff7c8956 Merge branch 'strip-post-hooks' of github.com:orgads/git-gui
* 'strip-post-hooks' of github.com:orgads/git-gui:
  git-gui: strip the commit message after running commit-msg hook

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-08-02 14:45:19 +02:00
Johannes Sixt
83fd8a0545 Merge branch 'ml/tcl90'
* ml/tcl90:
  git-gui: Allow Tcl 9.0
  git-gui: use -profile tcl8 on encoding conversions
  git-gui: use -profile tcl8 for file input with Tcl 9
  git-gui: themed.tcl: use full namespace for color
  git-gui: remove EOL translation for gets
  git-gui: do not mix -translation binary and -encoding
  git-gui: replace encoding binary with iso8859-1
  git-gui: translation binary defines iso8859-1
  git-gui: assure -eofchar {} on all channels

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-08-02 14:43:25 +02:00
Mark Levedahl
cc41d374fa git-gui: use -profile tcl8 on encoding conversions
git-gui in the prior commit learned to apply -profile tcl8 when reading
files, avoiding errors on non-binary data streams whose encoding is not
utf-8. But, git-gui also consumes binary data streams (generally blobs
from commits) as the output of commands, and internally decodes this to
support various displays.

With Tcl9, errors occur in this decoding for the same reasons described
in the previous commit: basically, the underlying data may contain
extended ascii characters violating the assumption of utf-8 encoding.

This problem has a similar fix to the prior issue: we must use the tlc8
profile when converting this data to the internal unicode format. Do so,
again only on Tcl9 as Tcl8.6 does not recognize -profile, and only Tcl
9.0 makes strict the default.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-31 13:51:03 -04:00
Mark Levedahl
0832752392 git-gui: themed.tcl: use full namespace for color
Tcl 9 imposes strict requirements on namespaces for variables, while Tcl
8 does not. lib/themed.tcl does not use the fully qualified name for the
"color" namespace, with result that variables are not found with Tcl
9.0. Fix this.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-31 13:51:03 -04:00
Mark Levedahl
beab415e42 git-gui: remove EOL translation for gets
git-gui configures '-translation lf' on a number of channels. The
default configuration is 'auto', which on input changes any occurrence
of \n, \r, or \r\n to \n, and on output changes any such EOL sequence to
a platform dependent value (\n on Unix, \r\n on Windows). Such
translation can be necessary, but much of what is configured now is
redundant.

In particular, many of the channels configured this way are then
consumed by gets, which already recognizes any of \n, \r, or \r\n as
terminators.  Configuring a channel to first change these line endings,
then give the result to gets, is redundant.

The valid uses of -translation lf are for output where we do not want
\r\n on Windows, and for consuming entire files without going through
gets, assuring that \n will be used internally. Let's remove all the
others that only serve to confuse.

lib/diff.tcl must have -translation lf because \r\n might be stored in
the repository (e.g., on Windows, with no crlf translation enabled), and
git will treat \n as the line ending, while the preceding \r is just
whitespace, and these may be split by ANSI color coding. git-gui's
read_diff handles this correctly as-is.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-31 13:50:59 -04:00
Johannes Sixt
f91175ea64 Merge branch 'ml/windows-tie-loose-ends'
* ml/windows-tie-loose-ends:
  git-gui: use /cmd/git-gui.exe for shortcut
  git-gui: Windows tk_getSaveFile is not useful for shortcuts
  git-gui: let nice work on Windows
  git-gui: do not add directories to PATH on Windows

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-31 19:20:22 +02:00
Mark Levedahl
07714e220b git-gui: do not mix -translation binary and -encoding
git-gui has many instances of '-translation binary' and '-encoding
$SOMETHING' on the same channel.  As eofchar is always null given a
prior commit, the net effect of having '-translation binary' in such
configuration is only to change how text line endings are handled.

For cases where the channel is opened to be consumed via gets, the eol
translation is irrelevant because Tcl's gets is documented to recognize
any of \n, \r, and \r\n as a line ending.  So, keep only the '-encoding
$SOMETHING' configuration in these cases, making the configuration more
clear.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-22 12:32:58 -04:00
Mark Levedahl
40f54f670a git-gui: replace encoding binary with iso8859-1
git-gui currently configures some channels as '-encoding binary' when
the channel is not really binary (e.g, the channel is consumed as lines
of text).  In 8.6, '-encoding binary' is an alias for '-encoding
iso8859), but TIP 699 removes this alias for Tcl 9.0. Let's switch to
'-encoding iso8859-1' to be compatible across Tcl versions.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-22 12:32:58 -04:00
Mark Levedahl
f6d3ee2014 git-gui: translation binary defines iso8859-1
git-gui has many cases where -translation binary and -encoding binary
are configured on the same channel. But, -translation binary defines a
binary channel, which sets up -encoding iso8859-1 as part of its work.
Tcl 8.x defines -encoding binary as an alias of -encoding iso8859-1, and
this alias is deleted in Tcl 9.0.  Let's delete the redundant encoding
definition now.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-22 12:32:58 -04:00
Mark Levedahl
847c8a2ec4 git-gui: assure -eofchar {} on all channels
Per 6eb420ef61 ("git-gui: Always disable the Tcl EOF character when
reading", 2007-07-17), git-gui should disable Tcl's EOF character
detection on all files when on Windows: the default is disabled on all
other platforms (and with Tcl 9.0, is disabled on Windows too).  This
EOF character is for compatibility with files / applications written for
file systems that know only the disc sectors allocated, and not the
number of bytes used.  This has nothing to do with git.

But, git-gui does not set -eofchar {} on all channels.  To avoid any
further leakage, let's just add this to the Windows specific override of
open.  This override is needed only as long as Tcl 8.x is in use (Tcl
9.0 makes -eofchar {} default on all platforms).

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-22 12:32:58 -04:00
Johannes Sixt
436dad00c5 Merge branch 'ml/abandon-old-versions'
* ml/abandon-old-versions:
  git-gui: eliminate _search_exe
  git-gui: remove procs gitexec and _git_cmd
  git-gui: use dashless 'git cmd' form for read/write
  git-gui: default to full copy for linked worktrees
  git-gui: use git-clone
  git-gui: remove unused git-version
  git-gui: use git_init to create new repository dir
  git-gui: git-remote is always available
  git-gui: git merge understands --strategy=recursive
  git-gui: git-diff knows submodules and textconv
  git-gui: git-blame understands -w and textconv
  git-gui: git rev-parse knows show_toplevel
  git-gui: use git-branch --show-current
  git-gui: git-diff-index always knows submodules
  git-gui: git ls-files knows --exclude-standard
  git-gui: require git >= 2.36

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-22 17:37:33 +02:00
Johannes Sixt
594810d2a9 Merge branch 'ml/tcl86'
* ml/tcl86:
  git-gui: remove non-ttk code
  git-gui: remove ${NS} indirection for ttk
  git-gui: always use themed widgets from ttk
  git-gui: remove redundant check for Tk >= 8.5
  git-gui: remove unreachable Tk 8.4 code
  git-gui: Make TclTk 8.6 the minimum, allow 8.7

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-22 17:34:31 +02:00
Mark Levedahl
158800ac9c git-gui: use /cmd/git-gui.exe for shortcut
git-gui on Windows creates a shortcut that presumes the git-gui script
will run on the basic Windows environment as configured. But, Git for
Windows uses wrapper scripts to launch executables, assuring the
environment is correct (see [1] for details). The launcher for git-gui
is /cmd/git-gui.exe, is not on PATH, and is not detected or used by the
current shortcut code. Let's look for this before trying the existing
approaches.

[1] https://gitforwindows.org/git-wrapper.html

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-22 10:21:44 -04:00
Mark Levedahl
eaca720ecd git-gui: remove procs gitexec and _git_cmd
gitexec looks up and caches the method to execute git subcommands using
the long deprecated dashed form if found in $(git--exec-path). But,
git_read and git_write now use the dashless form, by-passing gitexec.
This leaves two remaining uses of gitexec: one during startup to define
use of an ssh_key helper, and one in the about dialog box. These are
neither performance critical nor likely to be called more than once, so
do not justify an otherwise unused cacheing system.

Let's change those two uses, making gitexec unused. This allows removing
gitexec and _git_cmd.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-21 18:22:33 -04:00
Mark Levedahl
3ce650f4c9 git-gui: default to full copy for linked worktrees
git-gui's default clone method is git-clone's default, and this uses
hardlinks rather than copying the objects directory for local
repositories. However, this method explicitly fails if a symlink (or
.gitfile) exists in the path to the objects directory. Thus, the default
clone option fails for worktrees created by git-new-workdir or
git-worktree.  git-gui's original do_clone trapped this error for a
symlinked git-new-workdir tree, directly falling back to a full clone,
while the updated git-gui using git-clone does not. (The old do_clone
could not handle gitfile linked worktrees, however).

Let's apply the more friendly fallback to a full clone in both these
cases where git-clone behavior throws an error on the default method.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-21 18:22:33 -04:00
Mark Levedahl
6ff8d68ec1 git-gui: use git-clone
git-gui clones a repository by invoking git-plumbing commands, in proc
do_clone, rather than using git-clone.  The justification was that the
low-level commands are guaranteed to provide a stable interface, while
the higher level commands such as git-clone may not be stable. This
approach requires git-gui to continually evolve by mirroring new
features in git itself, which has not happened, while the user interface
in git-clone has proven very stable. Also, git-gui does directly call
many other non-plumbing commands in git's repertoire.

do_clone's last significant functionality change was in 2015, and
updates are required for shallow clones, the reftable backend, cloning
from linked worktrees, and perhaps other features and bugs. For
instance, I had reports of git-gui failing to correctly clone
repositories prior to 2015, resulting in essentially the patch given
here. The only significant work was supporting .gitfile linked worktrees
unknown to do_clone, but supported by git-clone, and none regarding the
interface to git-clone itself. That interface is clearly stable enough
to not be a problem.

Supporting new use-cases with this requires exposing new options in the
clone dialog, then passing flags to git-clone. This avoids updating
do_clone to understand those options, reducing the maintenance burdens.

So, teach git-gui to use git-clone.  This change is in one patch as
there is no obvious incremental path to migration. The existing dialog /
options / status screen are unchanged, the known user-visible changes
are that cloning from a working directory linked by a gitfile now works,
there is no auto-fallback to a full copy when cloning linked workdirs
and worktrees (meaning git-clone fails unless a full or shared copy is
selected), and messages displayed are from git-clone.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-21 18:22:33 -04:00
Mark Levedahl
9b1c537fdb git-gui: remove non-ttk code
git-gui has code paths to support older non-ttk widgets, but this code
is no longer reachable as ttk is always used. Remove that code.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-21 11:59:21 -04:00
Mark Levedahl
3c8e1fe0ea git-gui: Windows tk_getSaveFile is not useful for shortcuts
git-gui invokes the tk_getSaveFile dialog to determine the full
path-name of the shortcut file to create. But, on Windows, this dialog
always dereferences a shortcut (.lnk) file, as this is essentially a
soft-link to its target. If the shortcut file already exists, the dialog
returns the path-name of the target (i.e., GIT/cmd/git-gui.exe), and not
the desired shortcut file selected by the user.

There is no Windows file chooser available in Tcl/Tk that does not
dereference .lnk files, so this patch avoids using a dialog: the
shortcut to be created is on the desktop and named as "Git + Repository
Name". If this .lnk file already exists, the user must give permission
to overwrite it or the process terminates.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-19 09:12:11 -04:00
Mark Levedahl
fdc0e3a290 git-gui: remove ${NS} indirection for ttk
git-gui uses ${NS} to switch between non-themed and themed widgets, with
${NS} == 'ttk' selecting the latter. As git-gui now always uses ttk,
this indirection is not needed. Remove it.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:34 -04:00
Mark Levedahl
4e3369f0f6 git-gui: remove unreachable Tk 8.4 code
git-gui has remnant code to allow some drawing with Tk 8.4 predating the
addition of themed widgets. As git-gui requires Tk >= 8.6, this code can
never trigger. Remove it.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:34 -04:00
Mark Levedahl
c85557098f git-gui: use git_init to create new repository dir
When creating a new repository, git-gui creates a directory, cds to it,
then runs git-init, but git-init learned to create and initialize the
directory in 1.6.5. git-gui requires git version >= 2.36, so teach
git-gui to use git-init's full capability.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:06 -04:00
Mark Levedahl
8b48034f78 git-gui: git-remote is always available
git-gui checks for git version >= 1.6.6 before enabling the remotes
menu. But git-gui requires git v2.36 or later, so git-remote is always
available.  Delete this check and always enable the menu.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:06 -04:00
Mark Levedahl
e42ba88178 git-gui: git merge understands --strategy=recursive
git-gui's merge driver includes code to invoke the recursive strategy
for merging prior to git v2.5 that added a simpler syntax. As git-gui
requires git v2.36 or later, let's delete the code targeting earlier
git.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:06 -04:00
Mark Levedahl
940640de8b git-gui: git-diff knows submodules and textconv
git-gui's diff functions avoid using textconv filters on git < 1.6.1, or
asking about submodules on version before 1.7.2, but git-gui requires
git >= v2.36.  So, remove this now obsolete code.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:06 -04:00
Mark Levedahl
e48c822012 git-gui: git-blame understands -w and textconv
git-gui uses alternate code paths for git versions < 1.7.2, avoiding use
of --ignore-all-space and textconv. git-gui requires git v2.36 or later,
so this alternate code is obsolete. Remove it.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
2025-07-18 23:48:06 -04:00
Takashi Iwai
dab92fe42f git-gui: Add support of SHA256 repo
This patch adds the basic support of SHA256 Git repositories.
Most of changes are idiomatic replacement of the hard-coded hash ID
length, but there are subtle things:

* The hash length is determined on startup, and stored in $hashlength
  global variable (either 40 or 64).
* The hard-coded "40" are replaced with $hashlength;
  for regexp patterns, the ugly string map is used.
* Some code have the fixed numbers like 39 and 45, and those are
  replaced with the $hashlength and the offset correction.
* $nullid and $nullid2 are generated for the hash length.

A caveat is that repository picker dialog is performed before
evaluating the repo type, hence $hashlength isn't set there yet.
So the code dealing with the hard-coded "40" are handled differently;
namely, the regexp range is expanded, and the null id is generated
from the HEAD id length locally.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-16 18:52:38 +02:00
Takashi Iwai
532a054451 git-gui: Replace null_sha1 with nullid
Both $nullid and $null_sha1 point to the same content.
Use only $nullid consistently.

This is a preliminary cleanup for adding the support of SHA256 repo.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-16 18:21:37 +02:00
Orgad Shaneh
bfacf832b0 git-gui: strip the commit message after running commit-msg hook
When commit-msg writes the file using CRLF, the lines in the final
message include trailing spaces.

Postpone stripping until after hooks execute.

This aligns with Git's behavior, which passes the original message
to commit-msg, then strips comments and whitespace.

Signed-off-by: Orgad Shaneh <orgads@gmail.com>
2025-07-14 16:11:22 +03:00
Johannes Sixt
3f07230844 Merge branch 'js/fix-open-exec-git'
This addresses CVE-2025-46835, Git GUI can create and overwrite a
user's files:

When a user clones an untrusted repository and is tricked into editing
a file located in a maliciously named directory in the repository, then
Git GUI can create and overwrite files for which the user has write
permission.

* js/fix-open-exec-git:
  git-gui: sanitize 'exec' arguments: convert new 'cygpath' calls
  git-gui: do not mistake command arguments as redirection operators
  git-gui: introduce function git_redir for git calls with redirections
  git-gui: pass redirections as separate argument to git_read
  git-gui: pass redirections as separate argument to _open_stdout_stderr
  git-gui: convert git_read*, git_write to be non-variadic
  git-gui: use git_read in githook_read
  git-gui: break out a separate function git_read_nice
  git-gui: remove option --stderr from git_read
  git-gui: sanitize 'exec' arguments: background
  git-gui: sanitize 'exec' arguments: simple cases
  git-gui: treat file names beginning with "|" as relative paths
  git-gui: remove git config --list handling for git < 1.5.3
  git-gui: remove HEAD detachment implementation for git < 1.5.3
  git-gui: remove Tcl 8.4 workaround on 2>@1 redirection

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-08 21:22:48 +02:00
Johannes Sixt
88125ffe70 Merge branch 'ml/replace-auto-execok'
This addresses CVE-2025-46334, Git GUI malicious command injection on
Windows.

A malicious repository can ship versions of sh.exe or typical textconv
filter programs such as astextplain.  Due to the unfortunate design of
Tcl on Windows, the search path when looking for an executable always
includes the current directory.  The mentioned programs are invoked when
the user selects "Git Bash" or "Browse Files" from the menu.

* ml/replace-auto-execok:
  git-gui: override exec and open only on Windows
  git-gui: sanitize $PATH on all platforms
  git-gui: assure PATH has only absolute elements.
  git-gui: cleanup git-bash menu item
  git-gui: avoid auto_execok in do_windows_shortcut
  git-gui: avoid auto_execok for git-bash menu item
  git-gui: remove unused proc is_shellscript
  git-gui: remove special treatment of Windows from open_cmd_pipe
  git-gui: use only the configured shell
  git-gui: make _shellpath usable on startup
  git-gui: use [is_Windows], not bad _shellpath
  git-gui: _which, only add .exe suffix if not present

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-07-08 21:20:21 +02:00
Johannes Sixt
e8dd723956 Merge branch 'ob/strip-comments-on-commit'
* ob/strip-comments-on-commit:
  git-gui: do not end the commit message with an empty line
2025-06-21 16:39:14 +02:00
Taylor Blau
afca9a4fb4 Merge branch 'ml/replace-auto-execok' into js/fix-open-exec
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:27 -04:00
Johannes Sixt
99f7bc1af6 git-gui: introduce function git_redir for git calls with redirections
Proc git invokes git and collects all output, which is it returns.
We are going to treat command arguments and redirections differently to
avoid passing arguments that look like redirections to the command
accidentally. A few invocations also pass redirection operators as
command arguments deliberately. Rewrite these cases to use a new
function git_redir that takes two lists, one for the regular command
arguments and one for the redirection operations.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:24 -04:00
Johannes Sixt
60b0ba0a04 git-gui: pass redirections as separate argument to git_read
We are going to treat command arguments and redirections differently to
avoid passing arguments that look like redirections to the command
accidentally. To do so, it will be necessary to know which arguments
are intentional redirections. Rewrite direct call sites of git_read
to pass intentional redirections as a second (optional) argument.

git_read defers to safe_open_command, but we cannot make it safe, yet,
because one of the callers of git_read is proc git, which does not yet
know which of its arguments are redirections. This is the topic of the
next commit.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:24 -04:00
Johannes Sixt
1e0a93c3d3 git-gui: pass redirections as separate argument to _open_stdout_stderr
We are going to treat command arguments and redirections differently to
avoid passing arguments that look like redirections to the command
accidentally. To do so, it will be necessary to know which arguments
are intentional redirections. Rewrite direct callers of
_open_stdout_stderr to pass intentional redirections as a second
(optional) argument.

Passing arbitrary arguments is not safe right now, but we rename it
to safe_open_command anyway to avoid having to touch the call sites
again later when we make it actually safe.

We cannot make the function safe right away because one caller is
git_read, which does not yet know which of its arguments are
redirections. This is the topic of the next commit.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:24 -04:00
Johannes Sixt
dc9ecb1aab git-gui: convert git_read*, git_write to be non-variadic
We are going to treat command arguments and redirections differently to
avoid passing arguments that look like redirections to the command
accidentally. To do so, it will be necessary to know which arguments
are intentional redirections. As a preparation, convert git_read,
git_read_nice, and git_write to take just a single argument that is
the command in a list. Adjust all call sites accordingly.

In the future, this argument will be the regular command arguments and
a second argument will be the redirection operations.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:24 -04:00
Johannes Sixt
aa42e87ef4 git-gui: break out a separate function git_read_nice
There are two callers of git_read that request special treatment using
option --nice. Rewrite them to call a new function git_read_nice that
does the special treatment. Now we can remove all option treatment from
git_read.

git_write has the same capability, but there are no callers that
request --nice. Remove the feature without substitution.

This is a preparation for a later change where we want to make git_read
and friends non-variadic. Then it cannot have optional arguments.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Johannes Sixt
23ba43256b git-gui: remove option --stderr from git_read
Some callers of git_read want to redirect stderr of the invoked command
to stdout.  The function offers option --stderr for this purpose.
However, the option only appends 2>@1 to the commands.  The callers can
do that themselves. In lib/console.tcl we even have a caller that
already knew implictly what --stderr does behind the scenes.

This is a preparation for a later change where we want to make git_read
non-variadic. Then it cannot have optional leading arguments.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Mark Levedahl
00c7aa86e9 git-gui: avoid auto_execok in do_windows_shortcut
git-gui on Windows uses auto_execok to locate git-gui.exe,
which performs the same flawed search as does the builtin exec.
Use _which instead, performing a safe PATH lookup.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Johannes Sixt
4f3e0a4bce git-gui: sanitize 'exec' arguments: simple cases
Tcl 'exec' assigns special meaning to its argument when they begin with
redirection, pipe or background operator. There are a number of
invocations of 'exec' which construct arguments that are taken from the
Git repository or a user input. However, when file names or ref names
are taken from the repository, it is possible to find names that have
these special forms. They must not be interpreted by 'exec' lest it
redirects input or output, or attempts to build a pipeline using a
command name controlled by the repository.

Introduce a helper function that identifies such arguments and prepends
"./" to force such a name to be regarded as a relative file name.

Convert those 'exec' calls where the arguments can simply be packed
into a list.

Note that most commands containing the word 'exec' route through
console::exec or console::chain, which we will treat in another commit.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Johannes Sixt
c2e8904258 git-gui: treat file names beginning with "|" as relative paths
The Tcl 'open' function has a very wide interface. It can open files as
well as pipes to external processes. The difference is made only by the
first character of the file name: if it is "|", a process is spawned.

We have a number of calls of Tcl 'open' that take a file name from the
environment in which Git GUI is running. Be prepared that insane values
are injected. In particular, when we intend to open a file, do not take
a file name that happens to begin with "|" as a request to run a process.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Mark Levedahl
f9a2e8a38f git-gui: remove HEAD detachment implementation for git < 1.5.3
git-gui provides an implementation to detach HEAD on Git versions prior
to 1.5.3.  Nobody should be using such an old version anymore.
(Moreover, since 0730a5a3a, git-gui requires git v2.36 or later).
Keep only the code for modern Git.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
[j6t: message tweaked]
Signed-off-by: Johannes Sixt <j6t@kdbg.org>

Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Mark Levedahl
02dd866ba9 git-gui: use only the configured shell
git-gui has a few places where a bare "sh" is passed to exec, meaning
that the first instance of "sh" on $PATH will be used rather than the
shell configured. This violates expectations that the configured shell
is being used. Let's use [shellpath] everywhere.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
2025-05-23 17:04:23 -04:00
Johannes Sixt
80983c4131 git-gui: do not end the commit message with an empty line
The commit message is processed to remove unnecessary empty lines.
In particular, it is ensured that the text ends with at most one LF
character. This one is always present, because the Tk text widget
ensures that is present.

However, did not consider that the processed text is written to the
commit message file using `puts`, which also appends a LF character,
so that the final commit message ends with two LF. Trim all trailing
LF characters, and while we are here, use `string trim`, which lets
us remove the leading LF in the same command.

Reported-by: Gareth Fenn <garethfenn@gmail.com>
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-05-15 19:44:45 +02:00
Patrick Steinhardt
8bf062dd14 git-gui: wire up support for the Meson build system
The Git project has started to wire up Meson as a build system in Git
v2.48.0. Wire up support for Meson in "git-gui" so that we can trivially
include it as a subproject in Git.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
2025-05-13 08:48:09 +02:00
Johannes Sixt
2a7d4f2f07 Merge branch 'ob/strip-comments-on-commit'
* ob/strip-comments-on-commit:
  git-gui: heed core.commentChar/commentString
2025-04-20 09:27:22 +02:00
Oswald Buddenhagen
6b43a57dfc git-gui: heed core.commentChar/commentString
This amends 1ae85ff6d (git-gui: strip comments and consecutive empty
lines from commit messages, 2024-08-13) to deal with custom comment
characters/strings.

The magic commentString value "auto" is not handled, because the option
makes no sense to me - it does not support comments in templates and
hook output, and it seems far-fetched that someone would introduce
comments during editing the message.

Signed-off-by: Oswald Buddenhagen <oswald.buddenhagen@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2025-03-16 13:51:55 +01:00
Johannes Sixt
5c95773eac Merge branch 'js/no-rescan-on-empty-diff'
* js/no-rescan-on-empty-diff:
  git-gui: Remove forced rescan of stat-dirty files.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2024-12-21 14:06:33 +01:00
Yuri Konotopov
e5b5eca3f2
git-gui: use system encoding to show console output
This change makes non-ascii console output (eg server messages in the
`git push` command output) properly render in the git gui windows.

Fixes: https://github.com/prati0100/git-gui/issues/68

Signed-off-by: Yuri Konotopov <ykonotopov@gnome.org>
2024-12-08 22:14:45 +04:00