config: drop `git_config_get_multivar_gently()` wrapper
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove
`git_config_get_multivar_gently()`. All callsites are adjusted so that
they use `repo_config_get_multivar_gently(the_repository, ...)` instead.
While some callsites might already have a repository available, this
mechanical conversion is the exact same as the current situation and
thus cannot cause any regression. Those sites should eventually be
cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
config: drop `git_config_set_multivar_in_file_gently()` wrapper
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove
`git_config_set_multivar_in_file_gently()`. All callsites are adjusted
so that they use
`repo_config_set_multivar_in_file_gently(the_repository, ...)` instead.
While some callsites might already have a repository available, this
mechanical conversion is the exact same as the current situation and
thus cannot cause any regression. Those sites should eventually be
cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
config: drop `git_config_set_in_file_gently()` wrapper
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove
`git_config_set_in_file_gently()`. All callsites are adjusted so that
they use `repo_config_set_in_file_gently(the_repository, ...)` instead.
While some callsites might already have a repository available, this
mechanical conversion is the exact same as the current situation and
thus cannot cause any regression. Those sites should eventually be
cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_set()`. All
callsites are adjusted so that they use `repo_config_set(the_repository,
...)` instead. While some callsites might already have a repository
available, this mechanical conversion is the exact same as the current
situation and thus cannot cause any regression. Those sites should
eventually be cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_set_gently()`.
All callsites are adjusted so that they use
`repo_config_set_gently(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_set_in_file()`.
All callsites are adjusted so that they use
`repo_config_set_in_file(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_bool()`. All
callsites are adjusted so that they use
`repo_config_get_bool(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_ulong()`. All
callsites are adjusted so that they use
`repo_config_get_ulong(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_int()`. All
callsites are adjusted so that they use
`repo_config_get_int(the_repository, ...)` instead. While some callsites
might already have a repository available, this mechanical conversion is
the exact same as the current situation and thus cannot cause any
regression. Those sites should eventually be cleaned up in a later patch
series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_string()`.
All callsites are adjusted so that they use
`repo_config_get_string(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_string()`.
All callsites are adjusted so that they use
`repo_config_get_string(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
config: drop `git_config_get_string_multi()` wrapper
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove
`git_config_get_string_multi()`. All callsites are adjusted so that they
use `repo_config_get_string_multi(the_repository, ...)` instead. While
some callsites might already have a repository available, this
mechanical conversion is the exact same as the current situation and
thus cannot cause any regression. Those sites should eventually be
cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_value()`. All
callsites are adjusted so that they use
`repo_config_get_value(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get_value()`. All
callsites are adjusted so that they use
`repo_config_get_value(the_repository, ...)` instead. While some
callsites might already have a repository available, this mechanical
conversion is the exact same as the current situation and thus cannot
cause any regression. Those sites should eventually be cleaned up in a
later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_get()`. All
callsites are adjusted so that they use `repo_config_get(the_repository,
...)` instead. While some callsites might already have a repository
available, this mechanical conversion is the exact same as the current
situation and thus cannot cause any regression. Those sites should
eventually be cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config_clear()`. All
callsites are adjusted so that they use
`repo_config_clear(the_repository, ...)` instead. While some callsites
might already have a repository available, this mechanical conversion is
the exact same as the current situation and thus cannot cause any
regression. Those sites should eventually be cleaned up in a later patch
series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
In 036876a1067 (config: hide functions using `the_repository` by
default, 2024-08-13) we have moved around a bunch of functions in the
config subsystem that depend on `the_repository`. Those function have
been converted into mere wrappers around their equivalent function that
takes in a repository as parameter, and the intent was that we'll
eventually remove those wrappers to make the dependency on the global
repository variable explicit at the callsite.
Follow through with that intent and remove `git_config()`. All callsites
are adjusted so that they use `repo_config(the_repository, ...)`
instead. While some callsites might already have a repository available,
this mechanical conversion is the exact same as the current situation
and thus cannot cause any regression. Those sites should eventually be
cleaned up in a later patch series.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jacob Keller [Tue, 22 Jul 2025 23:18:26 +0000 (16:18 -0700)]
reflog: close leak of reflog expire entry
find_cfg_ent() allocates a struct reflog_expire_entry_option via
FLEX_ALLOC_MEM and inserts it into a linked list in the
reflog_expire_options structure. The entries in this list are never
freed, resulting in a leak in cmd_reflog_expire and the gc reflog expire
maintenance task:
Direct leak of 39 byte(s) in 1 object(s) allocated from:
#0 0x7ff975ee6883 in calloc (/lib64/libasan.so.8+0xe6883)
#1 0x0000010edada in xcalloc ../wrapper.c:154
#2 0x000000df0898 in find_cfg_ent ../reflog.c:28
#3 0x000000df0898 in reflog_expire_config ../reflog.c:70
#4 0x00000095c451 in configset_iter ../config.c:2116
#5 0x0000006d29e7 in git_config ../config.h:724
#6 0x0000006d29e7 in cmd_reflog_expire ../builtin/reflog.c:205
#7 0x0000006d504c in cmd_reflog ../builtin/reflog.c:419
#8 0x0000007e4054 in run_builtin ../git.c:480
#9 0x0000007e4054 in handle_builtin ../git.c:746
#10 0x0000007e8a35 in run_argv ../git.c:813
#11 0x0000007e8a35 in cmd_main ../git.c:953
#12 0x000000441e8f in main ../common-main.c:9
#13 0x7ff9754115f4 in __libc_start_call_main (/lib64/libc.so.6+0x35f4)
#14 0x7ff9754116a7 in __libc_start_main@@GLIBC_2.34 (/lib64/libc.so.6+0x36a7)
#15 0x000000444184 in _start (/home/jekeller/libexec/git-core/git+0x444184)
Close this leak by adding a reflog_clear_expire_config() function which
iterates the linked list and frees its elements. Call it upon exit of
cmd_reflog_expire() and reflog_expire_condition().
Add a basic test which covers this leak. While at it, cover the
functionality from commit commit 3cb22b8efe (Per-ref reflog expiry
configuration, 2008-06-15). We've had this support for years, but lacked
any tests.
Co-developed-by: Jeff King <peff@peff.net> Signed-off-by: Jacob Keller <jacob.keller@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Tue, 22 Jul 2025 20:30:21 +0000 (13:30 -0700)]
Merge branch 'master' of https://github.com/j6t/gitk
* 'master' of https://github.com/j6t/gitk: (21 commits)
gitk: remove header of now empty section "General options"
gitk: separate upstream refs when using the sort-by-type option
gitk: make 'sort-refs-by-type' optional and persistent
gitk: sort by ref type on the 'tags and heads' view
gitk: choosefont - remove a stray debugging line
gitk: allow horizontal commit-graph scrolling
gitk: update aqua scrolling for TclTk 8.6 / TIP171
gitk: update x11 scrolling for TclTk 8.6 / TIP 171
gitk: update win32 scrolling for Tk 8.6 / TIP 171
gitk: mousewheel scrolling functions for Tk 8.6
gitk: wheel scrolling multiplier preference
gitk: separate x11 / win32 / aqua Mouse bindings
gitk: remove non-ttk support code
gitk: replace ${NS} with ttk
gitk: always use themed Tk (ttk)
gitk: use $config_variables as list for save/restore
gitk: remove implementations for Tcl/Tk < 8.6
gitk: Make TclTk 8.6 the minimum, allow 8.7
gitk: remove code targeting git <= 1.7.2
gitk: require git >= 2.20
...
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>
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>
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>
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>
Johannes Sixt [Tue, 22 Jul 2025 16:13:31 +0000 (18:13 +0200)]
Merge branch 'mr/sort-refs-by-type'
* mr/sort-refs-by-type:
gitk: separate upstream refs when using the sort-by-type option
gitk: make 'sort-refs-by-type' optional and persistent
gitk: sort by ref type on the 'tags and heads' view
docs: explain how to use `git imap-send --list` command to get a list of available folders
The output `git imap-send --list` command can be a bit confusing for new
users since the IMAP LIST command output is very verbose. Help such users
to analyse the same by using an example output.
Signed-off-by: Aditya Garg <gargaditya08@live.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe [Fri, 18 Jul 2025 09:39:11 +0000 (11:39 +0200)]
commit: use prio_queue_replace() in pop_most_recent_commit()
Optimize pop_most_recent_commit() by adding the first parent using the
more efficient prio_queue_peek() and prio_queue_replace() instead of
prio_queue_get() and prio_queue_put().
On my machine this neutralizes the performance hit it took in Git's own
repository when we converted it to prio_queue two patches ago (git_pq):
$ hyperfine -w3 -L git ./git_2.50.1,./git_pq,./git '{git} rev-parse :/^Initial.revision'
Benchmark 1: ./git_2.50.1 rev-parse :/^Initial.revision
Time (mean ± σ): 1.073 s ± 0.003 s [User: 1.053 s, System: 0.019 s]
Range (min … max): 1.069 s … 1.078 s 10 runs
Benchmark 2: ./git_pq rev-parse :/^Initial.revision
Time (mean ± σ): 1.077 s ± 0.002 s [User: 1.057 s, System: 0.018 s]
Range (min … max): 1.072 s … 1.079 s 10 runs
Benchmark 3: ./git rev-parse :/^Initial.revision
Time (mean ± σ): 1.069 s ± 0.003 s [User: 1.049 s, System: 0.018 s]
Range (min … max): 1.065 s … 1.074 s 10 runs
Summary
./git rev-parse :/^Initial.revision ran
1.00 ± 0.00 times faster than ./git_2.50.1 rev-parse :/^Initial.revision
1.01 ± 0.00 times faster than ./git_pq rev-parse :/^Initial.revision
Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe [Fri, 18 Jul 2025 09:39:14 +0000 (11:39 +0200)]
prio-queue: add prio_queue_replace()
Add a function to replace the top element of the queue that basically
does the same as prio_queue_get() followed by prio_queue_put(), but
without the work by prio_queue_get() to rebalance the heap. It can be
used to optimize loops that get one element and then immediately add
another one. That's common e.g., with commit history traversal, where
we get out a commit and then put in its parents.
Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
René Scharfe [Fri, 18 Jul 2025 09:39:06 +0000 (11:39 +0200)]
commit: convert pop_most_recent_commit() to prio_queue
pop_most_recent_commit() calls commit_list_insert_by_date() for parent
commits, which is itself called in a loop. This can lead to quadratic
complexity if there are many merges. Replace the commit_list with a
prio_queue to ensure logarithmic worst case complexity and convert all
three users.
Add a performance test that exercises one of them using a pathological
history that consists of 50% merges and 50% root commits to demonstrate
the speedup:
Test v2.50.1 HEAD
----------------------------------------------------------------------
1501.2: rev-parse ':/65535' 2.48(2.47+0.00) 0.20(0.19+0.00) -91.9%
Alas, sane histories don't benefit from the conversion much, and
traversing Git's own history takes a 1% performance hit on my machine:
$ hyperfine -w3 -L git ./git_2.50.1,./git '{git} rev-parse :/^Initial.revision'
Benchmark 1: ./git_2.50.1 rev-parse :/^Initial.revision
Time (mean ± σ): 1.071 s ± 0.004 s [User: 1.052 s, System: 0.017 s]
Range (min … max): 1.067 s … 1.078 s 10 runs
Benchmark 2: ./git rev-parse :/^Initial.revision
Time (mean ± σ): 1.079 s ± 0.003 s [User: 1.060 s, System: 0.017 s]
Range (min … max): 1.074 s … 1.083 s 10 runs
Summary
./git_2.50.1 rev-parse :/^Initial.revision ran
1.01 ± 0.00 times faster than ./git rev-parse :/^Initial.revision
Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
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>
Junio C Hamano [Mon, 21 Jul 2025 22:46:42 +0000 (15:46 -0700)]
rev-list: update a NEEDSWORK comment
The comment is poorly phrased and it in't clear what it wanted to
say. Strongly discourage this broken pattern to be copied and
pasted to other code paths.
Junio C Hamano [Fri, 18 Jul 2025 23:58:03 +0000 (16:58 -0700)]
rev-list: make "struct rev_list_info" static to the only user
The structure has nothing to do with what "git bisect" does; as
nobody other than "git rev-list" implementation uses it, move it
as a private data type to builtin/rev-list.c
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>
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>
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>
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>
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>
Lidong Yan [Sun, 20 Jul 2025 12:43:34 +0000 (20:43 +0800)]
pull: add pull.autoStash config option
Git uses `rebase.autostash` or `merge.autostash` to determine whether a
dirty worktree is allowed during pull. However, this behavior is not
clearly documented, making it difficult for users to discover how to
enable autostash, or causing them to unknowingly enable it. Add new
config option `pull.autostash` along with its documentation and test
cases.
`pull.autostash` provides the same functionality as `rebase.autostash`
and `merge.autostash`, but overrides them when set. If `pull.autostash`
is not set, it falls back to `rebase.autostash` or `merge.autostash`,
depending on the value of `pull.rebase`.
Signed-off-by: Lidong Yan <yldhome2d2@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King [Sat, 19 Jul 2025 07:08:13 +0000 (03:08 -0400)]
revision: drop early output option
We added the --early-output feature long ago in cdcefbc971 (Add
"--early-output" log flag for interactive GUI use, 2007-11-03). The idea
was that GUIs could use it to progressively render a history view,
showing something quick-and-inaccurate at first and then enhancing it
later.
But we never documented it, and it appears never to have been used, even
by the projects which initially expressed interest. There was an RFC
patch for gitk to use it:
but it was never fully merged (to this day, QGit has a commented-out line to
add "--early-output" to the "log" invocation). Searching for other
mentions on the web or forges like github.com turns up nothing.
Meanwhile, the feature has been broken off and on over the years without
anybody noticing (and naturally, there are no tests, either). From 2011
to 2017 the option didn't even turn on via "--early-output"; this was
fixed in e35b6ac56f (revision.h: turn rev_info.early_output back into an
unsigned int, 2017-06-10).
It worked for a while then, but it does not interact well at all with
commit-graphs (which are turned on by default these days). The main
logic to count early commits is triggered by limit_list(), which we
traditionally invoked when showing output in topo-order (and
--early-output always enables --topo-order). But that changed in f0d9cc4196 (revision.c: begin refactoring --topo-order logic,
2018-11-01). Now when we have generation numbers, we skip limit_list()
entirely, and the early-output code shows no commits, and just the final
header "Final output: 1 done". Which is syntactically OK, but
semantically wrong: that message should give the total number of commits
we're about to show.
So let's drop the feature. It is extra code that is untested and
undocumented, and makes working on the revision machinery more brittle.
Given the history above, it seems unlikely that anybody is using it (or
has used it), and we can drop it without the usual deprecation period.
A gentler option might be to "soft" drop it: keep accepting the option,
have it imply --topo-order as it does now, print "Final output: 1 done",
and then do our regular traversal. That would keep any hypothetical
caller working. But it doesn't seem worth the hassle to me.
Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Junio C Hamano [Mon, 21 Jul 2025 16:14:27 +0000 (09:14 -0700)]
Merge branch 'ja/doc-git-log-markup'
Doc mark-up updates.
* ja/doc-git-log-markup:
doc: git-log: convert log config to new doc format
doc: git-log: convert diff options to new doc format
doc: git-log: convert pretty formats to new doc format
doc: git-log: convert pretty options to new doc format
doc: git-log: convert rev list options to new doc format
doc: git-log: convert line range format to new doc format
doc: git-log: convert line range options to new doc format
doc: git-log convert rev-list-description to new doc format
doc: convert git-log to new documentation format
Junio C Hamano [Mon, 21 Jul 2025 16:14:26 +0000 (09:14 -0700)]
Merge branch 'ps/meson-cleanups'
Meson-based build update.
* ps/meson-cleanups:
ci: use Meson's new `--slice` option
meson: update subproject wrappers
meson: fix lookup of shell on MINGW64
meson: clean up unnecessary variables
meson: improve summary of auto-detected features
meson: stop printing 'https' option twice in our summaries
meson: stop discovering native version of Python
Junio C Hamano [Mon, 21 Jul 2025 16:14:26 +0000 (09:14 -0700)]
Merge branch 'jk/remote-avoid-overlapping-names'
"git remote" now detects remote names that overlap with each other
(e.g., remote nickname "outer" and "outer/inner" are used at the
same time), as it will lead to overlapping remote-tracking
branches.
* jk/remote-avoid-overlapping-names:
remote: detect collisions in remote names
Junio C Hamano [Mon, 21 Jul 2025 16:14:26 +0000 (09:14 -0700)]
Merge branch 'tb/midx-avoid-cruft-packs'
"pack-objects" has been taught to avoid pointing into objects in
cruft packs from midx.
* tb/midx-avoid-cruft-packs:
repack: exclude cruft pack(s) from the MIDX where possible
pack-objects: introduce '--stdin-packs=follow'
pack-objects: swap 'show_{object,commit}_pack_hint'
pack-objects: fix typo in 'show_object_pack_hint()'
pack-objects: perform name-hash traversal for unpacked objects
pack-objects: declare 'rev_info' for '--stdin-packs' earlier
pack-objects: factor out handling '--stdin-packs'
pack-objects: limit scope in 'add_object_entry_from_pack()'
pack-objects: use standard option incompatibility functions
Junio C Hamano [Mon, 21 Jul 2025 16:14:25 +0000 (09:14 -0700)]
Merge branch 'bc/use-sha256-by-default-in-3.0'
Prepare to flip the default hash function to SHA-256.
* bc/use-sha256-by-default-in-3.0:
Enable SHA-256 by default in breaking changes mode
help: add a build option for default hash
t5300: choose the built-in hash outside of a repo
t4042: choose the built-in hash outside of a repo
t1007: choose the built-in hash outside of a repo
t: default to compile-time default hash if not set
setup: use the default algorithm to initialize repo format
Use legacy hash for legacy formats
builtin: use default hash when outside a repository
hash: add a constant for the legacy hash algorithm
hash: add a constant for the default hash algorithm
Michael Rappazzo [Sat, 19 Jul 2025 19:24:39 +0000 (15:24 -0400)]
gitk: separate upstream refs when using the sort-by-type option
Since the upstream refs of local refs may be of more significance in the
context of the local refs, they are sorted after local refs and before the
remainder of the remote refs.
Signed-off-by: Michael Rappazzo <michael.rappazzo@infor.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Michael Rappazzo [Fri, 18 Jul 2025 20:33:08 +0000 (16:33 -0400)]
gitk: make 'sort-refs-by-type' optional and persistent
On the 'tags and heads' view, add an option to enable or disable
'Sort refs by type'. This option is read from and written to the
config file. Clicking on the option will update the refs in the
view.
Signed-off-by: Michael Rappazzo <michael.rappazzo@infor.com> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
meson: work around broken system PCRE2 dependency in macOS
macOS provides a PCRE2 library in base that is not usable and not
configured properly, as it installs a pkgconf module that
points to a non-existent pcre2.h header in /usr/local/include.
Detect that case and if the feature is enabled, try to fallback
to a wrapped subproject through an anonymous dependency, aborting
with an error if that is not possible.
Change the feature to "auto" and print a warning and disable it
if a broken dependency was detected, but to keep consistency
with the cmake build system used on Windows, add a special rule
to re-enable the pcre2 feature by default there.
Helped-by: Eric Sunshine <sunshine@sunshineco.com> Suggested-by: Eli Schwartz <eschwartz@gentoo.org> Signed-off-by: Carlo Marcelo Arenas Belón <carenas@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
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>
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>
Junio C Hamano [Thu, 17 Jul 2025 16:30:56 +0000 (09:30 -0700)]
Merge branch 'bc/use-sha256-by-default-in-3.0' into ps/config-wo-the-repository
* bc/use-sha256-by-default-in-3.0:
Enable SHA-256 by default in breaking changes mode
help: add a build option for default hash
t5300: choose the built-in hash outside of a repo
t4042: choose the built-in hash outside of a repo
t1007: choose the built-in hash outside of a repo
t: default to compile-time default hash if not set
setup: use the default algorithm to initialize repo format
Use legacy hash for legacy formats
builtin: use default hash when outside a repository
hash: add a constant for the legacy hash algorithm
hash: add a constant for the default hash algorithm
object-file: get rid of `the_repository` in index-related functions
Both `index_fd()` and `index_path()` still use `the_repository` even
though they have a repository available via `struct index_state`. Adapt
them so that they use the index' repository instead to get rid of this
global dependency.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` in `force_object_loose()`
The function `force_object_loose()` forces an object to become a loose
object in case it only exists in its packed form. To do so it implicitly
relies on `the_repository`.
Refactor the function by passing a `struct odb_source` as parameter.
While the check whether any such loose object exists already acts on the
whole object database, writing the loose object happens in one specific
source.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` in `read_loose_object()`
The function `read_loose_object()` takes a path to an object file and
tries to parse it. As such, the function does not depend on any specific
object database but instead acts as an ODB-independent way to read a
specific file. As such, all it needs as input is a repository so that we
can derive repo settings and the hash algorithm.
That repository isn't passed in as a parameter though, as we implicitly
depend on the global `the_repository`. Refactor the function so that we
pass in the repository as a parameter.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` in loose object iterators
The iterators for loose objects still rely on `the_repository`. Refactor
them:
- `for_each_loose_file_in_objdir()` is refactored so that the caller
is now expected to pass an `odb_source` as parameter instead of the
path to that source. Furthermore, it is renamed accordingly to
`for_each_loose_file_in_source()`.
- `for_each_loose_object()` is refactored to take in an object
database now and calls the above function in a loop.
This allows us to get rid of the global dependency.
Adjust callers accordingly.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: remove declaration for `for_each_file_in_obj_subdir()`
The function `for_each_file_in_obj_subdir()` is declared in our headers,
but it is not used anywhere else than in the corresponding code file
itself. Drop the declaration and mark the function as file-local.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
The function `for_each_loose_file_in_objdir_buf()` is declared in our
headers, but it is not used anywhere else than in the corresponding code
file itself. Drop the declaration and inline the function into its only
caller.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` when writing objects
The logic that writes loose objects still relies on `the_repository` to
decide where exactly the object shall be written to. Refactor it so that
the logic instead operates on a `struct odb_source` so that we can get
rid of this global dependency.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
We do not have a backend-agnostic way to write objects into an object
database. While there is `write_object_file()`, this function is rather
specific to the loose object format.
Introduce `odb_write_object()` to plug this gap. For now, this function
is a simple wrapper around `write_object_file()` and doesn't even use
the passed-in object database yet. This will change in subsequent
commits, where `write_object_file()` is converted so that it works on
top of an `odb_source`. `odb_write_object()` will then become
responsible for deciding which source an object shall be written to.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
When a repository is configured to have a compatibility hash algorithm
we keep track of object ID mappings for loose objects via the loose
object map. This map simply maps an object ID of the actual hash to the
object ID of the compatibility hash. This loose object map is an
inherent property of the loose files backend and thus of one specific
object source.
Refactor the interfaces to reflect this by requiring a `struct
odb_source` as input instead of a repository. This prepares for
subsequent commits where we will refactor writing of loose objects to
work on a `struct odb_source`, as well.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` in `finalize_object_file()`
We implicitly depend on `the_repository` when moving an object file into
place in `finalize_object_file()`. Get rid of this global dependency by
passing in a repository.
Note that one might be pressed to inject an object database instead of a
repository. But the function doesn't really care about the ODB at all.
All it does is to move a file into place while checking whether there is
any collision. As such, the functionality it provides is independent of
the object database and only needs the repository as parameter so that
it can adjust permissions of the file we are about to finalize.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` in `loose_object_info()`
While `loose_object_info()` already accepts a repository as parameter we
still have one callsite in there where we use `the_repository` to figure
out the hash algorithm. Use the passed-in repository instead.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` when freshening objects
We implicitly depend on `the_repository` when freshening either loose or
packed objects. Refactor these functions to instead accept an object
database as input so that we can get rid of the global dependency.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
object-file: get rid of `the_repository` in `has_loose_object()`
We implicitly depend on `the_repository` in `has_loose_object()`.
Refactor the function to accept an `odb_source` as input that should be
checked for such a loose object.
This refactoring changes semantics of the function to not check the
whole object database for such a loose object anymore, but instead we
now only check that single source. Existing callers thus need to loop
through all sources manually now.
While this change may seem illogical at first, whether or not an object
exists in a specific format should be answered by the source using that
format. As such, we can eventually convert this into a generic function
`odb_source_has_object()` that simply checks whether a given object
exists in an object source. And as we will know about the format that
any given source uses it allows us to derive whether the object exists
in a given format.
This change also makes `has_loose_object_nonlocal()` obsolete. The only
caller of this function is adapted so that it skips the primary object
source.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
There are a couple of users of the `the_hash_algo` macro, which
implicitly depends on `the_repository`. Adapt these callers to not do so
anymore, either by deriving it from already-available context or by
using `the_repository->hash_algo`. The latter variant doesn't yet help
to remove the global dependency, but such users will be adapted in the
following commits to not use `the_repository` anymore.
Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Mark Levedahl [Thu, 20 Mar 2025 18:16:07 +0000 (14:16 -0400)]
gitk: allow Tcl/Tk 9.0+
Tcl/Tk 9.0 has been released, and has shipped in Fedora 42. Prior
patches in this sequence have addressed known incompatibilities, so gitk
is now operating with Tcl9. So, let's allow Tcl9.
Signed-off-by: Mark Levedahl <mlevedahl@gmail.com>
Mark Levedahl [Sun, 18 May 2025 14:41:30 +0000 (10:41 -0400)]
gitk: use -profile tcl8 on encoding conversions
gitk in the prior commit learned to apply -profile tcl8 to all input
data streams, avoiding errors on non-binary data streams whose encoding
is not utf-8. But, gitk also consumes binary data streams (generally blobs
from commits), 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 was not validated
to conform to the given encoding, and this source encoding may not be
utf-8. gitk performs this decoding using Tcl's '[encoding convert from'
operator.
For example, the 7th commit in gitk's history has the extended ascii
value 0xA9, so
in gitk's repository raises an exception. The error log has:
unexpected byte sequence starting at index 11: '\xA9'
while executing
"encoding convertfrom $diffencoding $line"
(procedure "parseblobdiffline" line 135)
invoked from within
"parseblobdiffline $ids $line"
(procedure "getblobdiffline" line 16)
invoked from within
"getblobdiffline file6 9a40c50c1e05c0658b7a7c68b56d615eb6f170dd"
("eval" body line 1)
invoked from within
"eval $script"
(procedure "dorunq" line 11)
invoked from within
"dorunq"
("after" script)
This problem has a similar fix to the prior issue: we must use the tlc8
profile when converting this data. 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>
Mark Levedahl [Fri, 14 Mar 2025 15:45:35 +0000 (11:45 -0400)]
gitk: use -profile tcl8 for file input with Tcl 9
gitk 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, of which there are many, has long
been acceptable 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.
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 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
gitk 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. As a result, gitk +
Tcl 9 cannot view the git repository at any point beyond that commit.
Note: Tcl 9.0 has a bug, to be fixed in 9.1, where this particular
condition results in a memory error causing Tcl to crash [1].
The tcl8 profile used so far has acceptable behavior given gitk's
acceptance: this allows gitk 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.