]> Kevux Git Server - rit/log
rit
6 weeks agogit-gui: check browser/blame arguments carefully
Mark Levedahl [Sun, 31 May 2026 23:02:24 +0000 (19:02 -0400)]
git-gui: check browser/blame arguments carefully

git gui offers two related commands, browser and blame, that provide
graphical interfaces driven by git ls-tree and git blame. As such, the
arguments to git-gui need to satisfy those two git commands. But,
git-gui does not assure this leading to confusing or incorrect results.
For instance 'git browser <non-existent path>' shows a blank browser
window rather than error message.

Also, commit 3e45ee1ef2 ("git-gui: Smarter command line parsing for
browser, blame", 2007-05-08) implemented code to allow giving path
before rev on the command line, and unconditionally uses the worktree to
disambiguate. As a result, the following command run in a current
git-gui checkout of the master branch shows the master branch version of
blame.tcl, when none should be shown as that file does not exist in
gitgui-0.6.0.

  git gui blame lib/blame.tcl gitgui-0.6.0

This 'file before rev' feature in git-gui mirrors ideas considered when
git's user interface was very young, but no such feature is documented
for any git command.  Rather than try to fix an idea git itself
rejected, let's just remove this broken and hopefully unused feature.

git-gui browser|blame both accept 'rev' and 'path' as command line
arguments.  rev defaults to 'HEAD' if not given, while path must be
given. path names a directory tree to ls-tree or a file to blame. path
must exist in rev for ls-tree and for blame.  In addition git blame will
include uncommitted changes from the worktree file at 'path' if rev is
not given (thus defaulting to HEAD), but still requires that the file
exists in HEAD.

So, let's clean up the parser to check that the arguments are usable.
- give a full synopsis, including '--' that may be used to separate rev and
  path. (as path is the required final arg, -- gives no extra info)
- explicitly check the number of arguments
- use rev-parse to assure a user supplied rev is valid
- use ls-tree to assure that path exists in rev
- for blame only, with no rev given and a worktree existing, also assure
  that path points to a file in the worktree

With these changes, error messages are thrown by the parser if the path
or rev are not known: no blank or erroneous displays are created. Also,
this avoids accessing the worktree except in the specific use case
supported by blame / git-blame, meaning browser|blame now also work
without a worktree.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: allow specifying path '.' to the browser
Mark Levedahl [Sun, 31 May 2026 23:02:23 +0000 (19:02 -0400)]
git-gui: allow specifying path '.' to the browser

Invoking "git-gui browser rev ." should show the file browser for the
commitish rev, starting at the current directory. When the current
directory is the working tree root, this errors out in normalize_relpath
because the '.' is removed, yielding an empty list as argument to [file
join ...]. git ls-tree (underlying the browser) accepts '.', so use that
as the value when in the root.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: try harder to find worktree from gitdir
Mark Levedahl [Sun, 31 May 2026 23:02:22 +0000 (19:02 -0400)]
git-gui: try harder to find worktree from gitdir

git-gui, since 87cd09f43e ("git-gui: work from the .git dir",
2010-01-23), has had the intent to allow starting from inside a
repository, then switching to the parent directory if that is a valid
worktree.

This certainly hasn't worked since 2d92ab32fd ("rev-parse: make
--show-toplevel without a worktree an error", 2019-11-19) in git, but
breaking this git-gui feature was unintentional.

There are (at least) 3 cases where the gitdir can tell us where the
worktree is, and we would like all to work:

- core.worktree is set, and points to a valid worktree. This is already
  handled  by git rev-parse --show-toplevel, even when not in the worktree.
  There is nothing more to do in this case.

- the gitdir is embedded in a worktree as subdirectory .git. The parent
  is (or at least should be) a valid worktree. This worked long ago.

- the gitdir is a worktree specific directory (under
  <mainrepo>/worktrees/worktree_name), within which there is a file
  "gitdir" pointing to .git in the worktree. git gui never learned to
  handle this case.

Let's handle the latter two cases. Always check that the discovered
worktree is valid and points to the already discovered gitdir according
to git rev-parse. This avoids issues that may arise because we are
discovering from the gitdir up, rather than the worktree down, and file
system non-posix behavior or misconfiguration of git might cause
confusion.  For instance, a manually moved worktree might not be where
the gitdir points, or the gitdir might be configured with
core.bare=true.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: simplify [is_bare] to report if a worktree is known
Mark Levedahl [Sun, 31 May 2026 23:02:21 +0000 (19:02 -0400)]
git-gui: simplify [is_bare] to report if a worktree is known

git-gui includes proc is_bare, used in several places to make decisions
on whether a worktree exists, but also in discovery to tell if a
worktree can be supported.

But, is_bare is out of date with regard to multiple worktrees, safe
repository guards, and possibly other relevant features known to git
rev-parse. Also, is_bare caches its result on the first call, so is not
useful if a later step in the discovery process finds a worktree.

So, simplify is_bare to report whether git-gui has a worktree or is
working only from a repository.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: use git rev-parse for worktree discovery
Mark Levedahl [Sun, 31 May 2026 23:02:20 +0000 (19:02 -0400)]
git-gui: use git rev-parse for worktree discovery

git gui uses a combination of tcl code and git invocations to determine
the worktree and the location with respect to the worktree root
(_prefix). But, git rev-parse provides all of this information directly,
and assures full error and configuration checking are done by git
itself. The entirety of discovery in normal configurations involves

git rev-parse --show-toplevel (gets worktree root)
git rev-parse --show-prefix (shows location wrt the root)

An error thrown on either of these lines means the worktree discovered
by git is unusable, or git did not discover a worktree because the
current directory is inside the repository. If the user has defined
GIT_DIR or GIT_WORK_TREE, this is a user configuration error and git-gui
should stop.

Otherwise, the blame or browser subcommands can be used without a
worktree.

A separate error might occur when changing to the root of the discovered
worktree. The cause would be file system related and completely outside
of git's control, so trap that independently.

Discovery of the repository and the worktree must be guarded to trap
errors: the intent is that any configuration problems are caught during
discovery, and later processing need not include error trapping and
recovery. So, move all worktree discovery code to be immediately after
repository discovery.

This does move configuration loading to occur after worktree discovery
rather than before. None of the code executed in worktree discovery has
any option controlled by a git-gui configuration variable, so no impact
is expected. git itself will always read the repository configuration,
including worktree specific configuration data if that exists, so this
is unaffected by when git-gui loads its own config data. Also, we cannot
be sure the worktree dependent configuration can be loaded before
full discovery is complete.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: use rev-parse exclusively to find a repository
Mark Levedahl [Sun, 31 May 2026 23:02:19 +0000 (19:02 -0400)]
git-gui: use rev-parse exclusively to find a repository

git-gui attempts to use env(GIT_DIR) directly as the git repository,
accepting GIT_DIR if it is a directory. Only if that fails is git
rev-parse used to discover the repository.  But, this avoids all of
git-core's validity checking on a repository, thus possibly deferring an
error to a later step, possibly unexpected. Repository validation should
be part of initial setup so that later processing does not need error
trapping for configuration errors.

Let's just invoke rev-parse so all error checking is done.

While here, let's cleanup the error handling.

Stop if an error occurs and the user set GIT_DIR or GIT_WORK_TREE.
Use of either or both of those variables is supported by git, but their
use also means the user has taken responsibility that they are correct,
so a failure is something the user must address.

Otherwise on error, continue the existing behavior and show the
repository picker. But, let's move the possible invocation of
repository_chooser::pick to a separate code block. This permits adding
separate conditions on using pick independent of repository discovery, and
will be exploited later in the series.  Note that the picker always
returns with the current directory in the root of a worktree with the
git repository is in the .git subdirectory.  The variable "picked" is
used by git-gui to automatically execute the "Explore Working Copy" menu
item after the repository picker is run.  This is controlled by config
variable gui.autoexplore, and happens after all discovery is complete.

Remove a later check on whether _gitdir is a directory: that code
cannot be reached without rev-parse already validating the repository.

_prefix is set as part of worktree discovery, but must be {} if not
running with a worktree. Initialze this as {} along with other global
variables, this is the correct value is no worktree is found.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: use --absolute-git-dir
Mark Levedahl [Sun, 31 May 2026 23:02:18 +0000 (19:02 -0400)]
git-gui: use --absolute-git-dir

git-gui uses git rev-parse --git-dir to get the pathname of the
discovered git repository. The returned value can be relative, and is
'.' if the current directory is the top of the repository directory
itself.  git-gui has code to change '.' to [pwd] in this case so that
subsequent logic runs.

But, git rev-parse supports --absolute-git-dir from fac60b8925
("rev-parse: add option for absolute or relative path formatting",
2020-12-13), and included in git 2.31. git-gui requires git >= 2.36, so
this more useful form is always available. Use --absolute-git-dir to
always get an absolute path, avoiding the need for other checks, and
delete the now unneeded code to fix a relative _gitdir.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: do not change global vars in choose_repository::pick
Mark Levedahl [Sun, 31 May 2026 23:02:17 +0000 (19:02 -0400)]
git-gui: do not change global vars in choose_repository::pick

The repository picker (choose_repository::pick, AKA pick) on success
always returns with the current directory at the root of the selected
worktree, with the global variable _gitdir holding the name of the
git repository, possibly as a relative path, and _prefix {}. The
worktree root (_gitworktree) is not filled out, and if the selection was
from the "recent" list, no validation has occurred beyond testing that
the worktree root exists. So, repository and worktree validation are
still needed to be sure the new repo + worktree is usable.

pick only supports worktrees with a .git entry in the worktree root, so
git repository and worktree discovery will work starting in the current
directory on return. In cases of error, or user abort, pick exits the
process rather than returning.

So, let's change pick to not alter any global values, with success
indicated by the process returning to the caller. In this case, the
current directory is the worktree root, with a .git entry. The caller
then proceeds with normal discovery to find and validate both repository
and worktree.

With this, pick now returns 1 in the success case, but additional work
would be necessary to return from conditions where 0 should be returned.
Checking this return value would be superfluous.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE
Mark Levedahl [Sun, 31 May 2026 23:02:16 +0000 (19:02 -0400)]
git-gui: guard set/unset of GIT_DIR and GIT_WORK_TREE

git-gui unconditionally exports _gitdir as GIT_DIR, and _gitworktree as
GIT_WORK_TREE, to the environment, and unconditionally
unsets these environment variables before invoking gitk or git-gui when
a submodule is involved. This export happens even if _gitworktree is
empty, which happens when running from a bare repository. However,
exporting GIT_WORK_TREE as empty is never valid, and causes errors in
git.

GIT_DIR must be exported if the repository is not discoverable from the
worktree (or current directory if there is no worktree). The user might
have configured this.

If there is a worktree, git-gui makes this the current directory.
However, if the repository sets core.worktree, this value can only be
overridden by GIT_WORK_TREE so the latter must be exported.

As we cannot eliminate conditions where either variable is needed, let's
implement a pair of functions to set / unset these variables without
error, and without ever exporting an empty GIT_WORK_TREE.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: remove unnecessary 'cd $_gitworktree' from do_gitk
Johannes Sixt [Sun, 31 May 2026 23:02:15 +0000 (19:02 -0400)]
git-gui: remove unnecessary 'cd $_gitworktree' from do_gitk

In the procedure that invokes Gitk, we have a 'cd $_gitworktree'. Such
a change of the current directory is not necessary, because

- if we have a working tree, then the startup routine has already
  changed the current directory to the root of the working tree, which
  *is* $_gitworktree; or

- if we are in a bare repository, then there is no point in changing
  the current directory anywhere. (And $_gitworktree is empty.)

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
6 weeks agogit-gui: use HEAD as current branch when detached
Mark Levedahl [Sun, 31 May 2026 23:02:14 +0000 (19:02 -0400)]
git-gui: use HEAD as current branch when detached

commit f87a36b697 ("git-gui: use git-branch --show-current", 2024-02-12)
changed git-gui to use git-branch to access refs, rather than directly
reading files as doing the latter is not compatible with the reftable
backend. git branch --show-current reports an empty branch name when the
head is detached, and in this case load_current_branch needs to report
HEAD using special case logic as it did prior to the above commit. Make
it do so.

This addresses an issue with git-gui browser failing with a detached
head.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
4 months agogit-gui: grey out comment lines in commit message
Wolfgang Faust [Wed, 4 Mar 2026 01:30:52 +0000 (17:30 -0800)]
git-gui: grey out comment lines in commit message

Comment lines are stripped by wash_commit_message, but there is no
indication in the UI that they are special and will be removed.
Grey these lines out to indicate that they will be removed.

Signed-off-by: Wolfgang Faust <contrib-git@wolfgangfaust.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
4 months agoMerge branch 'pks-meson-fixes' of github.com:pks-gitlab/git-gui
Johannes Sixt [Wed, 18 Feb 2026 12:02:20 +0000 (13:02 +0100)]
Merge branch 'pks-meson-fixes' of github.com:pks-gitlab/git-gui

* 'pks-meson-fixes' of github.com:pks-gitlab/git-gui:
  git-gui: wire up "git-gui--askyesno" with Meson
  git-gui: massage "git-gui--askyesno" with "generate-script.sh"
  git-gui: prefer shell at "/bin/sh" with Meson
  git-gui: fix use of GIT_CEILING_DIRECTORIES

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
4 months agogit-gui: wire up "git-gui--askyesno" with Meson
Patrick Steinhardt [Tue, 10 Feb 2026 13:19:28 +0000 (14:19 +0100)]
git-gui: wire up "git-gui--askyesno" with Meson

The new "git-gui--askyesno" helper script has only been wired up for our
Makefile, not for Meson. Wire it up properly to bring both build systems
on par with each other again.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
4 months agogit-gui: massage "git-gui--askyesno" with "generate-script.sh"
Patrick Steinhardt [Tue, 10 Feb 2026 13:18:04 +0000 (14:18 +0100)]
git-gui: massage "git-gui--askyesno" with "generate-script.sh"

In e749c87 (git-gui: provide question helper for retry fallback on
Windows, 2025-08-28) we have introudced a new "git-gui--askyesno" helper
script. While the script is conceptually similar to our existing helper
script "git-gui--askpass", we don't massage it via "generate-script.sh".
This means that build options like the path to the wish shell are not
propagated correctly.

Fix this issue.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
4 months agogit-gui: prefer shell at "/bin/sh" with Meson
Patrick Steinhardt [Tue, 10 Feb 2026 12:45:33 +0000 (13:45 +0100)]
git-gui: prefer shell at "/bin/sh" with Meson

Meson detects the path of the target shell via `find_program("sh")`,
which essentially does a lookup via `PATH`. We know that almost all
systems have "/bin/sh" available though, which makes it the superior
choice as a default value.

Adapt `find_program()` to prefer "/bin/sh" over any other "sh"
executable.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
4 months agogit-gui: fix use of GIT_CEILING_DIRECTORIES
Patrick Steinhardt [Tue, 10 Feb 2026 12:45:17 +0000 (13:45 +0100)]
git-gui: fix use of GIT_CEILING_DIRECTORIES

The GIT-VERSION-GEN script sets up GIT_CEILING_DIRECTORIES so that we
won't accidentally parse version information from an unrelated parent
repository. The ceiling is derived from the source directory by simply
appendign "/.." to it, which mean that we'll only consider the current
directory for repository discovery.

This works alright in the case where git-gui is built as a standalone
project, but it breaks when git-gui is embedded into a _related_ parent
project. This is for example how git-gui is distributed via Git.

Interestingly enough, the version information is still derived properly
when building git-gui via Git's Makefile. In that case we eventually end
up specifying the ceiling directory as "./.." as we use relative paths
there, and that seems to not restrict the repository discovery.

But when building via Meson we specify the source directory as an
absolute path, and if so the repository discovery _is_ stopped. The
consequence is that we won't be able to derive the version in that case.

Fix the issue by adding a new optional parameter to GIT-VERSION-GEN that
allows the caller to override the parent project directory and wire up
new build options for Meson and Make that allows users to specify it.

Note that by default we won't set the parent project directory. This
isn't required for Meson anyway as we already use absolute paths there,
but for our Makefile it means that we still end up with "./.." as
ceiling directory, which is ineffective. But using e.g. pwd(1) as the
default value would break downstream's version generation, unless we
updated git-gui and the Makefile at the same point in time.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
5 months agogit-gui: shift tabstops to account for the first column of patch text
Chris Idema [Thu, 29 Jan 2026 11:09:04 +0000 (11:09 +0000)]
git-gui: shift tabstops to account for the first column of patch text

When reviewing a change before staging, it is desirable to see text after
tabstops aligned the same way as in the text editor. However, since there
is always an additional character in column one in patch text ('+', '-',
or space), the alignment is broken if text before the first tab character
is just long enough to push the stop to the next tab position.

Commit a43c5f51a4b1 (git-gui: add configurable tab size to the diff view,
2012-02-12) added infrastructure that manipulates the tabstop positions
of the Tk text widget. However, it does so only when a 3-way diff is
shown and only so that it takes into account the one additional markup at
the beginning of lines. This only achieved that alignment does not get
worse for 3-way diffs compared to regular patch text, but left misaligned
text in regular patch text unmodified.

Use and modify this infrastructure to shift tabstops by one position for
regular patch text and two positions for 3-way diffs. Existing code
already resets the tabstops to an unshifted position when contents of
untracked files are displayed.

Signed-off-by: Chris Idema <github_chris_idema@proton.me>
[j6t: extend commit message]
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
5 months agogit-gui: mark *.po files at any directory level as UTF-8
Johannes Sixt [Sun, 25 Jan 2026 09:46:23 +0000 (10:46 +0100)]
git-gui: mark *.po files at any directory level as UTF-8

When a commit is viewed in Gitk that changes a file in po/glossary, the
patch text shows mojibake instead of correctly decoded UTF-8 text.
Gitk retrieves the encoding attribute to decide how to treat the bytes
that make up the patch text. There is an attribute definition that all
files are US-ASCII, and a later attribute definition overrides this.
But the override, which specifies UTF-8, applies only to *.po files in
directory po/ and does not apply to subdirectories.

Widen the pattern to apply to all directory levels.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
5 months agoMerge branch 'master' of github.com:alshopov/git-gui
Johannes Sixt [Sun, 25 Jan 2026 09:32:21 +0000 (10:32 +0100)]
Merge branch 'master' of github.com:alshopov/git-gui

* 'master' of github.com:alshopov/git-gui:
  git-gui i18n: Update Bulgarian translation (558t)

5 months agogit-gui i18n: Update Bulgarian translation (558t)
Alexander Shopov [Mon, 19 Jan 2026 09:13:14 +0000 (10:13 +0100)]
git-gui i18n: Update Bulgarian translation (558t)

- Translate new string (558t)
- Add graves for disambiguation
- Improve glossary translation (96t) and synchonize with git

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
5 months agoMerge branch 'master' of github.com:alshopov/git-gui
Johannes Sixt [Sat, 24 Jan 2026 08:25:29 +0000 (09:25 +0100)]
Merge branch 'master' of github.com:alshopov/git-gui

* 'master' of github.com:alshopov/git-gui:
  git-gui i18n: Update Bulgarian translation (557t)

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
5 months agogit-gui i18n: Update Bulgarian translation (557t)
Alexander Shopov [Mon, 19 Jan 2026 09:13:14 +0000 (10:13 +0100)]
git-gui i18n: Update Bulgarian translation (557t)

Fix the meaning of a string

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
10 months agogit-gui: sync Makefiles with git.git
Adam Dinwoodie [Sat, 15 Feb 2025 21:19:03 +0000 (21:19 +0000)]
git-gui: sync Makefiles with git.git

In git.git, commit 5309c1e9fb39 (Makefile: set default goals in
makefiles, 2025-02-15) touched two Makefiles in the git-git/ directory.
Import these changes, so that the trees can converge again with the
next merge of this repository into git.git.

Reported-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agoMerge branch 'ml/misc-simplifications'
Johannes Sixt [Sat, 6 Sep 2025 09:59:19 +0000 (11:59 +0200)]
Merge branch 'ml/misc-simplifications'

* ml/misc-simplifications:
  git-gui: simplify using nice(1)
  git-gui: simplify PATH de-duplication

10 months agoMerge branch 'js/ask-yesno'
Johannes Sixt [Sat, 6 Sep 2025 09:59:09 +0000 (11:59 +0200)]
Merge branch 'js/ask-yesno'

* js/ask-yesno:
  git-gui--askyesno (mingw): use Git for Windows' icon, if available
  git-gui--askyesno: allow overriding the window title
  git gui: set GIT_ASKPASS=git-gui--askpass if not set yet
  git-gui: provide question helper for retry fallback on Windows

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agogit-gui: fix error handling of Revert Changes command
Johannes Sixt [Mon, 1 Sep 2025 18:20:08 +0000 (20:20 +0200)]
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>
10 months agogit-gui--askyesno (mingw): use Git for Windows' icon, if available
Johannes Schindelin [Thu, 28 Aug 2025 08:58:50 +0000 (08:58 +0000)]
git-gui--askyesno (mingw): use Git for Windows' icon, if available

This provides a unified look-and-feel in Git for Windows.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agogit-gui--askyesno: allow overriding the window title
Johannes Schindelin [Thu, 28 Aug 2025 08:58:49 +0000 (08:58 +0000)]
git-gui--askyesno: allow overriding the window title

"Question?" is maybe not the most informative thing to ask. In the
absence of better information, it is the best we can do, of course.

However, Git for Windows' auto updater just learned the trick to use
git-gui--askyesno to ask the user whether to update now or not. And in
this scripted scenario, we can easily pass a command-line option to
change the window title.

So let's support that with the new `--title <title>` option.

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agogit gui: set GIT_ASKPASS=git-gui--askpass if not set yet
Johannes Schindelin [Thu, 28 Aug 2025 08:58:48 +0000 (08:58 +0000)]
git gui: set GIT_ASKPASS=git-gui--askpass if not set yet

Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agogit-gui: provide question helper for retry fallback on Windows
Heiko Voigt [Thu, 28 Aug 2025 08:58:47 +0000 (08:58 +0000)]
git-gui: provide question helper for retry fallback on Windows

Make use of the new environment variable GIT_ASK_YESNO to support the
recently implemented fallback in case unlink, rename or rmdir fail for
files in use on Windows. The added dialog will present a yes/no question
to the the user which will currently be used by the windows compat layer
to let the user retry a failed file operation.

Signed-off-by: Heiko Voigt <hvoigt@hvoigt.net>
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agogit-gui: simplify using nice(1)
Mark Levedahl [Wed, 20 Aug 2025 16:50:21 +0000 (12:50 -0400)]
git-gui: simplify using nice(1)

git-gui invokes some long running commands using "nice git $cmd" if nice
is found and works, otherwise just "git $cmd".  The current code is more
complex than needed; let's simplify it.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
10 months agogit-gui: simplify PATH de-duplication
Mark Levedahl [Wed, 20 Aug 2025 15:31:43 +0000 (11:31 -0400)]
git-gui: simplify PATH de-duplication

git-gui since 8fe7861c51 ("git-gui: assure PATH has only absolute
elements.", 2025-04-11) uses a list to maintain order and a dict to
detect duplicated elements without quadratic complexity.  But, Tcl's
dict explicitly maintains keys in the order first added, thus the list
is not needed.  Simplify the code.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agoMerge branch 'cb/no-tcl86-on-macos'
Johannes Sixt [Mon, 4 Aug 2025 16:27:03 +0000 (18:27 +0200)]
Merge branch 'cb/no-tcl86-on-macos'

* cb/no-tcl86-on-macos:
  git-gui: ensure own version of git-gui--askpass is used
  git-gui: honor TCLTK_PATH in git-gui--askpass
  git-gui: retire Git Gui.app
  git-gui: fix dependency of GITGUI_MAIN on generator
  git-gui: remove uname_O in Makefile

11 months agogit-gui: ensure own version of git-gui--askpass is used
Carlo Marcelo Arenas Belón [Thu, 31 Jul 2025 08:06:28 +0000 (01:06 -0700)]
git-gui: ensure own version of git-gui--askpass is used

When finding a location for the askpass helper, git will be asked
for its exec path, but if that git is not the same that called
git-gui then we might mistakenly point to its helper instead.

Assume that git-gui and the helper are colocated to derive its
path instead.

This is specially useful in macOS where a broken version of that
helper is provided by the system git.

[j6t: move directory to variable to help in-flight topics]

Suggested-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agoMerge branch 'strip-post-hooks' of github.com:orgads/git-gui
Johannes Sixt [Sat, 2 Aug 2025 12:45:19 +0000 (14:45 +0200)]
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>
11 months agoMerge branch 'ml/tcl90'
Johannes Sixt [Sat, 2 Aug 2025 12:43:25 +0000 (14:43 +0200)]
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>
11 months agoMerge branch 'master' of https://github.com/alshopov/git-gui
Johannes Sixt [Sat, 2 Aug 2025 12:41:48 +0000 (14:41 +0200)]
Merge branch 'master' of https://github.com/alshopov/git-gui

* 'master' of https://github.com/alshopov/git-gui:
  git-gui i18n: Remove the locations within the Bulgarian translation
  git-gui i18n: Update Bulgarian translation (557t)

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agogit-gui: Allow Tcl 9.0
Mark Levedahl [Sat, 17 May 2025 02:30:37 +0000 (22:30 -0400)]
git-gui: Allow Tcl 9.0

TclTk 9.0 is now shipping, and git-gui is now patched to support use of
this newer version. Adjust required versions to allow Tcl/Tk >= 8.6,
including 9.x.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: use -profile tcl8 on encoding conversions
Mark Levedahl [Sat, 31 May 2025 19:18:31 +0000 (15:18 -0400)]
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>
11 months agogit-gui: use -profile tcl8 for file input with Tcl 9
Mark Levedahl [Sat, 31 May 2025 18:52:35 +0000 (14:52 -0400)]
git-gui: use -profile tcl8 for file input with Tcl 9

git-gui invokes many git commands expecting output in utf-8 encoding,
but git accepts extended ascii (code page unknown) as utf-8 without
validating, so cannot guarantee valid utf-8 on output.  In particular,
using any extended ascii code page has long been acceptable on git given
that everyone on a project is aware of and uses that same code page to
view all data. utf-8 accepts only 7-bit ascii characters in single
bytes, and any characters outside of that base set require at least two
bytes for representation in unicode.

Tcl is a string based language, and transcodes all input data to an
internal unicode format, and to whatever format is requested on output:
"pure" binary is recoded byte by byte using iso8859-1.  Tcl8.x silently
recodes invalid utf-8 as binary data, so extended ascii characters
maintain their binary value on output but may not display correctly.

Tcl 8.7 added three profiles to control this behaviour: strict (raises
exceptions), replace (replaces each invalid byte with ?), and the
default tcl8 maintaining the old behavior.  Tcl 9 changes the default
profile to strict, meaning any invalid utf-8 raises an exception that
git-gui does not handle.

An example of this in the git repository is commit 7eb93c8965 ("[PATCH]
Simplify git script", 2005-09-07). This includes extended ascii
characters in the author name and commit message.

The tcl8 profile used so far has acceptable behavior given git-gui's
acceptance: this allows git-gui to accept extended ascii though it may
display incorrectly.  Let's continue that behavior by overriding open to
use the tcl8 profile on Tcl9 and later: Tcl 8.6 does not understand
fconfigure -profile, and Tcl 8.7 maintains the tcl8 profile.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: themed.tcl: use full namespace for color
Mark Levedahl [Sat, 10 May 2025 01:39:56 +0000 (21:39 -0400)]
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>
11 months agogit-gui: remove EOL translation for gets
Mark Levedahl [Thu, 22 May 2025 01:13:27 +0000 (21:13 -0400)]
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>
11 months agoMerge branch 'ml/windows-tie-loose-ends'
Johannes Sixt [Thu, 31 Jul 2025 17:20:22 +0000 (19:20 +0200)]
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>
11 months agogit-gui: honor TCLTK_PATH in git-gui--askpass
Carlo Marcelo Arenas Belón [Thu, 31 Jul 2025 08:06:27 +0000 (01:06 -0700)]
git-gui: honor TCLTK_PATH in git-gui--askpass

Since its introduction in 8c76212 (git-gui: Add a simple implementation
of SSH_ASKPASS., 2008-10-15), git-gui--askpass has been calling whatever
wish interpreter is in the path, unlike git-gui.

Correct that by turning it into a script that would be processed at build
time.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agogit-gui: retire Git Gui.app
Carlo Marcelo Arenas Belón [Thu, 31 Jul 2025 08:06:26 +0000 (01:06 -0700)]
git-gui: retire Git Gui.app

In a recent commit, the minimum version of Tcl/Tk was raised to
8.6, but the "app" relies on the system provided Framework that
is based on 8.5.

Remove it, and let git-gui use a third party version of Wish if
available.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agogit-gui: fix dependency of GITGUI_MAIN on generator
Carlo Marcelo Arenas Belón [Thu, 31 Jul 2025 08:06:25 +0000 (01:06 -0700)]
git-gui: fix dependency of GITGUI_MAIN on generator

Since 854e883 (git-gui: extract script to generate "git-gui",
2025-03-11), the logic to generate the main script was pulled
out of the Makefile, but adding the resulting generator as a
dependency was missed.

If the logic changes, the main script should be regenerated, so
add it as a dependency.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agogit-gui: remove uname_O in Makefile
Carlo Marcelo Arenas Belón [Thu, 31 Jul 2025 08:06:24 +0000 (01:06 -0700)]
git-gui: remove uname_O in Makefile

Last used in ae49066 (git gui Makefile - remove Cygwin modifications,
2023-06-26), and unused since.

Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
11 months agogit-gui i18n: Remove the locations within the Bulgarian translation
Alexander Shopov [Tue, 29 Jul 2025 18:09:45 +0000 (20:09 +0200)]
git-gui i18n: Remove the locations within the Bulgarian translation

This makes sending diffs via mail list easier and
brings the po-file in line with git po-file.

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
11 months agogit-gui i18n: Update Bulgarian translation (557t)
Alexander Shopov [Mon, 28 Jul 2025 11:20:01 +0000 (13:20 +0200)]
git-gui i18n: Update Bulgarian translation (557t)

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
11 months agogit-gui: do not mix -translation binary and -encoding
Mark Levedahl [Wed, 21 May 2025 23:18:46 +0000 (19:18 -0400)]
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>
11 months agogit-gui: replace encoding binary with iso8859-1
Mark Levedahl [Thu, 22 May 2025 17:33:00 +0000 (13:33 -0400)]
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>
11 months agogit-gui: translation binary defines iso8859-1
Mark Levedahl [Thu, 22 May 2025 17:17:08 +0000 (13:17 -0400)]
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>
11 months agogit-gui: assure -eofchar {} on all channels
Mark Levedahl [Wed, 21 May 2025 21:38:10 +0000 (17:38 -0400)]
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>
11 months agoMerge branch 'ml/abandon-old-versions'
Johannes Sixt [Tue, 22 Jul 2025 15:37:33 +0000 (17:37 +0200)]
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>
11 months agoMerge branch 'ml/tcl86'
Johannes Sixt [Tue, 22 Jul 2025 15:34:08 +0000 (17:34 +0200)]
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>
11 months agogit-gui: use /cmd/git-gui.exe for shortcut
Mark Levedahl [Sun, 13 Apr 2025 18:45:04 +0000 (14:45 -0400)]
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>
11 months agogit-gui: eliminate _search_exe
Mark Levedahl [Sat, 5 Apr 2025 12:00:00 +0000 (08:00 -0400)]
git-gui: eliminate _search_exe

git-gui has _search_exe as needed to give the executable suffix
(.exe) on Windows. But, the prior commit eliminated the only user of
this variable. Delete it.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: remove procs gitexec and _git_cmd
Mark Levedahl [Sun, 6 Apr 2025 15:14:35 +0000 (11:14 -0400)]
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>
11 months agogit-gui: use dashless 'git cmd' form for read/write
Mark Levedahl [Sat, 5 Apr 2025 03:08:35 +0000 (23:08 -0400)]
git-gui: use dashless 'git cmd' form for read/write

git-gui implements its own approach to locating and running various git
subcommands, bypassing git's capabilities for running git-*.  This was
written in 2007: at that time, many git commands were shell-scripts
stored in $(git --exec-path), git's run-command api was not well adapted
to Windows and had serious performance issues when it worked at all, and
running subcommand 'git foo' as 'git-foo' was common and fully supported.

On Windows, git-gui searches $(git --exec-path) for builtin commands,
then attempts to find an interpreter on PATH to run those, invoking
these differently than on other platforms. For instance, the explicit
shebang #!/usr/bin/perl found in a script will be run by the first Perl
interpreter found on $PATH, which might not be at that specific location
so could be different than what git would run.

The various issues leading to the current implemention no longer exist.
Most git commands are now builtins, links to run those are not installed
in $(git --exec-path) by default (the "dashless" form is recommended
instead), and git's run-command api works well everywhere.

So, let's use git to launch its subcommands on all platforms.  Do so by
modifying procs git_read and git_write to use the "dashless" form for
invoking git commands, avoiding the search for git-<foo>. This leaves
_git_cmd unused with cleanup in a later patch.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: default to full copy for linked worktrees
Mark Levedahl [Mon, 21 Jul 2025 15:12:18 +0000 (11:12 -0400)]
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>
11 months agogit-gui: use git-clone
Mark Levedahl [Fri, 9 Feb 2024 23:07:45 +0000 (18:07 -0500)]
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>
11 months agogit-gui: remove non-ttk code
Mark Levedahl [Tue, 20 May 2025 17:53:52 +0000 (13:53 -0400)]
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>
11 months agogit-gui: Windows tk_getSaveFile is not useful for shortcuts
Mark Levedahl [Sun, 13 Apr 2025 18:31:52 +0000 (14:31 -0400)]
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>
11 months agogit-gui: let nice work on Windows
Mark Levedahl [Tue, 20 May 2025 14:08:44 +0000 (10:08 -0400)]
git-gui: let nice work on Windows

git-gui runs blame and diff commands with nice by default. On Unix, nice
is accepted if found and it will run git. Commit ff9db6c79d ("On
Windows, avoid git-gui to call Cygwin's nice utility", 2010-10-05)
rejects nice if not collocated with git. In Git for Windows' (g4w) POSIX
path name space, nice and git are found in different directories:

$ which git
/mingw64/bin/git
$ which nice
/usr/bin/nice

Thus, git-gui will not use nice in the supported Windows configuration.
Commit ff9db6c79d justifies the collocation requirement as avoiding
problems in a mixed MSYS and Cygwin configuration: such configurations
are not supported by either project as they are known to cause many
problems.

So, let's revert ff9db6c79d and let git-gui work correctly in the
supported configuration.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: do not add directories to PATH on Windows
Mark Levedahl [Sun, 13 Apr 2025 18:15:08 +0000 (14:15 -0400)]
git-gui: do not add directories to PATH on Windows

git-gui on Windows prepends three directories to PATH so does not honor
PATH as configured. This can have undesirable consequences, for instance
by preventing use of a different git for testing.  This also provides at
best a subset of the configuration included with Git for Windows (g4w),
so is neither necessary nor sufficient there.

Since commit be700fe3, git-gui.sh adds its directory to the front of
PATH: this is essentially adding $(git --execdir) to the path, this is
long deprecated as git moved to using "dashless" subcommands.

The windows/git-gui.sh wrapper file, since commit 99fe594d, adds two
directories relative to its installed location to PATH, and does so
without checking that either exists or is needed.

The above modifications were made before the Git For Windows project
took responsibility for distributing a working solution on Windows. g4w
assures a correct configuration on Windows without these, and doing so
requires more than the above modifications.  See [1] for a more thorough
treatment.

git-gui does not modify PATH on any platform except on Windows, and
doing so is not needed by g4w.  Let's stop modifying PATH on Windows as
well.

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

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: remove ${NS} indirection for ttk
Mark Levedahl [Mon, 14 Jul 2025 16:15:49 +0000 (12:15 -0400)]
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>
11 months agogit-gui: always use themed widgets from ttk
Mark Levedahl [Wed, 21 May 2025 20:31:14 +0000 (16:31 -0400)]
git-gui: always use themed widgets from ttk

git-gui optionally uses themed ui elements from ttk, but the full set of
ttk ui elements is always available with Tk 8.6.  Keeping code making
ttk use optional increases maintenance burden for no benefit.  Let's use
ttk always, allowing removal of alternate code paths in subsequent
patches.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: remove redundant check for Tk >= 8.5
Mark Levedahl [Sun, 18 Feb 2024 18:06:05 +0000 (13:06 -0500)]
git-gui: remove redundant check for Tk >= 8.5

Since commit c80d7be5e1e0d, git-gui checks for the availability of ttk
before enabling its use, but this check is redundant as Tk >= 8.6 is
required.  Remove the redundant check.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: remove unreachable Tk 8.4 code
Mark Levedahl [Fri, 16 Feb 2024 23:24:06 +0000 (18:24 -0500)]
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>
11 months agogit-gui: remove unused git-version
Mark Levedahl [Tue, 13 Feb 2024 05:19:56 +0000 (00:19 -0500)]
git-gui: remove unused git-version

git-version supports choosing different bodies of code passed into it,
rather than using the more traditional if/else construct typically used.
The only use of git-version in this mode was by its author in 2007, and
that code has been deleted.  So, delete this now unused function that
was mostly ignored.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: use git_init to create new repository dir
Mark Levedahl [Fri, 9 Feb 2024 22:58:04 +0000 (17:58 -0500)]
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>
11 months agogit-gui: git-remote is always available
Mark Levedahl [Tue, 13 Feb 2024 05:13:45 +0000 (00:13 -0500)]
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>
11 months agogit-gui: git merge understands --strategy=recursive
Mark Levedahl [Tue, 13 Feb 2024 05:13:10 +0000 (00:13 -0500)]
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>
11 months agogit-gui: git-diff knows submodules and textconv
Mark Levedahl [Tue, 13 Feb 2024 05:11:32 +0000 (00:11 -0500)]
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>
11 months agogit-gui: git-blame understands -w and textconv
Mark Levedahl [Tue, 13 Feb 2024 05:09:02 +0000 (00:09 -0500)]
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>
11 months agogit-gui: git rev-parse knows show_toplevel
Mark Levedahl [Tue, 13 Feb 2024 03:03:30 +0000 (22:03 -0500)]
git-gui: git rev-parse knows show_toplevel

git-gui has its own code to determine the worktree root for git-versions
earlier than 1.7.0, where git rev-parse learned this function.  git-gui
requires git v2.36 or later, so delete the now obsolete alternate code.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: use git-branch --show-current
Mark Levedahl [Mon, 12 Feb 2024 19:42:05 +0000 (14:42 -0500)]
git-gui: use git-branch --show-current

git-gui relies upon the files back-end to determine the current branch.
This does not support the newer reftables backend.  But, git-branch has
long supported --show-current to get this same information regardless of
backend cahnged.  So teach git-gui to use git-branch --show-current.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: git-diff-index always knows submodules
Mark Levedahl [Sat, 5 Apr 2025 14:19:48 +0000 (10:19 -0400)]
git-gui: git-diff-index always knows submodules

git-gui asks for submodule info only on git-versions >=1.72, which
introduced such capability. But, git-gui requires git version >= 2.36,
so this alternate code path is obsolete. Remove it.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: git ls-files knows --exclude-standard
Mark Levedahl [Sat, 5 Apr 2025 14:18:06 +0000 (10:18 -0400)]
git-gui: git ls-files knows --exclude-standard

git-gui includes code to implement ls-files for git versions prior to
1.63 that did not know --exclude-standard. But, git-gui now requires git
version >= 2.36, so remove the obsolete code.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: Make TclTk 8.6 the minimum, allow 8.7
Mark Levedahl [Sat, 17 May 2025 02:25:17 +0000 (22:25 -0400)]
git-gui: Make TclTk 8.6 the minimum, allow 8.7

git-gui requires that Tcl and Tk are 8.5, though the check using
'package require' allows 8.6. As git-gui runs under wish, both Tcl and
Tk are always available and of the same version, so only one need be
checked.

The 8.5 requirement is very outdated as the earliest Tcl currently
shipping on any supported OS is 8.6. 8.7 is in alpha test and is
generally compatible with 8.6, so should also be allowed.  Tcl 9.0 has
planned compatibility breaking changes so cannot be allowed.

Let's update the requirements to be 8.6 or 8.7, and check only on Tcl as
Tk will be the same version.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: require git >= 2.36
Mark Levedahl [Tue, 13 Feb 2024 04:32:44 +0000 (23:32 -0500)]
git-gui: require git >= 2.36

git-gui since commit d6967022 explicitly requires version >= 1.5.0, and
this coded requirement has never been changed. But, since 0730a5a3a
git-gui actually requires git 2.36, providing 'git hook run.' git-gui
throws an error if that command is not supported.

So, let's update the requirement checking code to 2.36, and throw a more
useful error if this is not met.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
11 months agogit-gui: Add support of SHA256 repo
Takashi Iwai [Wed, 16 Jul 2025 07:32:25 +0000 (09:32 +0200)]
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>
11 months agogit-gui: Replace null_sha1 with nullid
Takashi Iwai [Wed, 16 Jul 2025 07:32:24 +0000 (09:32 +0200)]
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>
12 months agogit-gui: strip the commit message after running commit-msg hook
Orgad Shaneh [Sun, 13 Jul 2025 20:59:38 +0000 (23:59 +0300)]
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>
12 months agoMerge branch 'js/fix-open-exec-git'
Johannes Sixt [Tue, 8 Jul 2025 19:22:00 +0000 (21:22 +0200)]
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>
12 months agoMerge branch 'ml/replace-auto-execok'
Johannes Sixt [Tue, 8 Jul 2025 19:19:28 +0000 (21:19 +0200)]
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>
12 months agoMerge branch 'ob/strip-comments-on-commit'
Johannes Sixt [Sat, 21 Jun 2025 14:39:14 +0000 (16:39 +0200)]
Merge branch 'ob/strip-comments-on-commit'

* ob/strip-comments-on-commit:
  git-gui: do not end the commit message with an empty line

12 months agogit-gui i18n: Updated Bulgarian translation (578t)
Alexander Shopov [Sun, 15 Jun 2025 12:26:33 +0000 (14:26 +0200)]
git-gui i18n: Updated Bulgarian translation (578t)

Signed-off-by: Alexander Shopov <ash@kambanaria.org>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
13 months agogit-gui: don't delete source files when auto_mkindex fails
Johannes Sixt [Fri, 6 Jun 2025 05:41:42 +0000 (07:41 +0200)]
git-gui: don't delete source files when auto_mkindex fails

Commit 2cc5b0facfa4 (git-gui: extract script to generate "tclIndex",
2025-03-11) converted commands in a Makefile rule to a shell script.
In this process, the Makefile variable $@ had to be replaced by the
file name that it represents, 'lib/tclIndex'. However, the occurrence
in `rm -f $@` was missed. In a shell script, $@ expands to all
command line arguments, which happen to be the source files lib/*.tcl
in this case. Needless to say that we do not want to remove source
files during a build. Replace $@ by the intended 'lib/tclIndex'.

Reported-by: Randall S. Becker <rsbecker@nexbridge.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
13 months agoMerge branch 'pks-meson-support' of github.com:pks-t/git-gui
Johannes Sixt [Thu, 29 May 2025 08:01:14 +0000 (10:01 +0200)]
Merge branch 'pks-meson-support' of github.com:pks-t/git-gui

* 'pks-meson-support' of github.com:pks-t/git-gui:
  git-gui: wire up support for the Meson build system
  git-gui: stop including GIT-VERSION-FILE file
  git-gui: extract script to generate macOS app
  git-gui: extract script to generate macOS wrapper
  git-gui: extract script to generate "tclIndex"
  git-gui: extract script to generate "git-gui"
  git-gui: drop no-op GITGUI_SCRIPT replacement
  git-gui: make output of GIT-VERSION-GEN source'able
  git-gui: prepare GIT-VERSION-GEN for out-of-tree builds
  git-gui: replace GIT-GUI-VARS with GIT-GUI-BUILD-OPTIONS

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
13 months agogit-gui: sanitize 'exec' arguments: convert new 'cygpath' calls
Johannes Sixt [Wed, 14 May 2025 19:06:37 +0000 (21:06 +0200)]
git-gui: sanitize 'exec' arguments: convert new 'cygpath' calls

The side branch merged in the previous commit introduces new 'exec'
calls. Convert these in the same way we did earlier for existing
'exec' calls.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
13 months agoMerge branch 'ml/replace-auto-execok' into js/fix-open-exec
Taylor Blau [Fri, 23 May 2025 21:04:27 +0000 (17:04 -0400)]
Merge branch 'ml/replace-auto-execok' into js/fix-open-exec

Signed-off-by: Taylor Blau <me@ttaylorr.com>
13 months agogit-gui: do not mistake command arguments as redirection operators
Johannes Sixt [Sun, 4 May 2025 19:59:19 +0000 (21:59 +0200)]
git-gui: do not mistake command arguments as redirection operators

Tcl 'open' assigns special meaning to its argument when they begin with
redirection, pipe or background operator. There are many calls of the
'open' variant that runs a process which construct arguments that are
taken from the Git repository or are 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 'open' lest it redirects input or output, or attempts to build a
pipeline using a command name controlled by the repository.

Use the helper function make_arglist_safe, which identifies such
arguments and prepends "./" to force such a name to be regarded as a
relative file name.

After this change the following 'open' calls that start a process do not
apply the argument processing:

git-gui.sh:4095:         || [catch {set spell_fd [open $spell_cmd r+]} spell_err]} {
lib/spellcheck.tcl:47:                                          set pipe_fd [open [list | $s_prog -v] r]
lib/spellcheck.tcl:133:         _connect $this [open $spell_cmd r+]
lib/spellcheck.tcl:405:         set fd [open [list | aspell dump dicts] r]

In all cases, the command arguments are constant strings (or begin with
a constant string) that are of a form that would not be affected by the
processing anyway.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
13 months agogit-gui: introduce function git_redir for git calls with redirections
Johannes Sixt [Sun, 4 May 2025 18:26:11 +0000 (20:26 +0200)]
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>
13 months agogit-gui: pass redirections as separate argument to git_read
Johannes Sixt [Sun, 4 May 2025 13:39:03 +0000 (15:39 +0200)]
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>
13 months agogit-gui: pass redirections as separate argument to _open_stdout_stderr
Johannes Sixt [Sun, 4 May 2025 13:06:11 +0000 (15:06 +0200)]
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>
13 months agogit-gui: convert git_read*, git_write to be non-variadic
Johannes Sixt [Sat, 3 May 2025 11:24:48 +0000 (13:24 +0200)]
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>
13 months agogit-gui: override exec and open only on Windows
Mark Levedahl [Fri, 11 Apr 2025 14:58:20 +0000 (10:58 -0400)]
git-gui: override exec and open only on Windows

Since aae9560a355d (Work around Tcl's default `PATH` lookup,
2022-11-23), git-gui overrides exec and open on all platforms. But,
this was done in response to Tcl adding elements to $PATH on Windows,
while exec, open, and auto_execok honor $PATH as given on all other
platforms.

Let's do the override only on Windows, restoring others to using their
native exec and open. These honor the sanitized $PATH as that is written
out to env(PATH) in a previous commit. auto_execok is also safe on these
platforms, so can be used for _which.

Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>
13 months agogit-gui: use git_read in githook_read
Johannes Sixt [Sat, 3 May 2025 17:21:53 +0000 (19:21 +0200)]
git-gui: use git_read in githook_read

0730a5a3a5e6 ("git-gui - use git-hook, honor core.hooksPath", 2023-09-17)
rewrote githook_read to use `git hook` to run a hook script. The code
that was replaced discovered the hook script file manually and invoked
it using function _open_stdout_stderr. After the rewrite, this function
is still invoked, but it calls into `git` instead of the hook scripts.

Notice though, that we have function git_read that invokes git and
prepares a pipe for the caller to read from. Replace the implementation
of githook_read to be just a wrapper around git_read. This unifies the
way in which the git executable is invoked. git_read ultimately also
calls into _open_stdout_stderr, but it modifies the path to the git
executable before doing so.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Taylor Blau <me@ttaylorr.com>