summaryrefslogtreecommitdiffstats
path: root/builtin/merge-recursive.c (unfollow)
Commit message (Collapse)AuthorFilesLines
2024-12-22reftable/stack: fix zero-sized allocation when there are no readersPatrick Steinhardt1-10/+14
Similar as the preceding commit, we may try to do a zero-sized allocation when reloading a reftable stack that ain't got any tables. It is implementation-defined whether malloc(3p) returns a NULL pointer in that case or a zero-sized object. In case it does return a NULL pointer though it causes us to think we have run into an out-of-memory situation, and thus we return an error. Fix this by only allocating arrays when they have at least one entry. Reported-by: Randall S. Becker <rsbecker@nexbridge.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-22reftable/merged: fix zero-sized allocation when there are no readersPatrick Steinhardt1-5/+7
It was reported [1] that Git started to fail with an out-of-memory error when initializing repositories with the reftable backend on NonStop platforms. A bisect led to 802c0646ac (reftable/merged: handle allocation failures in `merged_table_init_iter()`, 2024-10-02), which changed how we allocate memory when initializing a merged table. The root cause of this seems to be that NonStop returns a `NULL` pointer when doing a zero-sized allocation. This would've already happened before the above change, but we never noticed because we did not check the result. Now we do notice and thus return an out-of-memory error to the caller. Fix the issue by skipping the allocation altogether in case there are no readers. [1]: <00ad01db5017$aa9ce340$ffd6a9c0$@nexbridge.com> Reported-by: Randall S. Becker <rsbecker@nexbridge.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-22reftable/stack: don't perform auto-compaction with less than two tablesPatrick Steinhardt1-0/+3
In order to compact tables we need at least two tables. Bail out early from `reftable_stack_auto_compact()` in case we have less than two tables. In the original, `stack_table_sizes_for_compaction()` yields an array that has the same length as the number of tables. This array is then passed on to `suggest_compaction_segment()`, which returns an empty segment in case we have less than two tables. The segment is then passed to `segment_size()`, which will return `0` because both start and end of the segment are `0`. And because we only call `stack_compact_range()` in case we have a positive segment size we don't perform auto-compaction at all. Consequently, this change does not result in a user-visible change in behaviour when called with a single table. But when called with no tables this protects us against a potential out-of-memory error: `stack_table_sizes_for_compaction()` would try to allocate a zero-byte object when there aren't any tables, and that may lead to a `NULL` pointer on some platforms like NonStop which causes us to bail out with an out-of-memory error. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-19Finishing touches before 2.48-rc1Junio C Hamano1-0/+16
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-16Git 2.48-rc0v2.48.0-rc0Junio C Hamano2-1/+23
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-14gitk: offer "Copy commit ID to X11 selection" only on X11Johannes Sixt1-4/+10
This option is only useful where a selection clipboard is available, which is only the case on X11. Do not clutter the UI in other environments. Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2024-12-13The sixteenth batchJunio C Hamano1-0/+22
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-13log: --remerge-diff needs to keep around commit parentsJohannes Schindelin2-2/+13
To show a remerge diff, the merge needs to be recreated. For that to work, the merge base(s) need to be found, which means that the commits' parents have to be traversed until common ancestors are found (if any). However, one optimization that hails all the way back to cb115748ec0d (Some more memory leak avoidance, 2006-06-17) is to release the commit's list of parents immediately after showing it _and to set that parent list to `NULL`_. This can break the merge base computation. This problem is most obvious when traversing the commits in reverse: In that instance, if a parent of a merge commit has been shown as part of the `git log` command, by the time the merge commit's diff needs to be computed, that parent commit's list of parent commits will have been set to `NULL` and as a result no merge base will be found (even if one should be found). Traversing commits in reverse is far from the only circumstance in which this problem occurs, though. There are many avenues to traversing at least one commit in the revision walk that will later be part of a merge base computation, for example when not even walking any revisions in `git show <merge1> <merge2>` where `<merge1>` is part of the commit graph between the parents of `<merge2>`. Another way to force a scenario where a commit is traversed before it has to be traversed again as part of a merge base computation is to start with two revisions (where the first one is reachable from the second but not in a first-parent ancestry) and show the commit log with `--topo-order` and `--first-parent`. Let's fix this by special-casing the `remerge_diff` mode, similar to what we did with reflogs in f35650dff6a4 (log: do not free parents when walking reflog, 2017-07-07). Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-13gitk: support auto-copy comit ID to primary clipboardAvi Halachmi (:avih)1-3/+11
Auto-select ("Copy commit ID to X11 selection") is useful when a selection cliboard exists, but otherwise generally meaningless, for instance on Windows. Add a similar pref and behavior which copies the commit ID to the primary clipboard - for platforms without a selection clipboard, but which can also be useful additionally on platforms with selection. Note that while autoselect is enabled by default, autocopy isn't. That's because the selection clipboard is typically dispensable, while the primary clipboard can be considered a more precious resource, which we don't want to (clear and) overwrite by default. Signed-off-by: Avi Halachmi (:avih) <avihpit@yahoo.com>
2024-12-13gitk: prefs dialog: refine Auto-select UIAvi Halachmi (:avih)1-4/+7
Tl;DR: change Auto-select text, move the length input to a new line. The Auto-select preference auto-selects [part of] the commit ID text at the respective widget on startup, and when the current commit at the graph changes. Its real premise, however, is to populate the selection clipboard with the commit ID. Consider, for instance, how meaningless it is on platforms without a selection clipboard - like Windows or macOS (on Windows the selection is not even visible with the default Tk theme, because it's only visible in focused widgets - which the commit ID widget is not during normal application of this selection). So rename the Auto-select label to "Copy commit ID to X11 selection", to reflect better the ultimate outcome of its application Note that there exists other, non-X11 platforms with a selection clipboard, like Wayland, and if a native Tk client exists on such platforms, then the description will not be accurate, but hopefully it's not too misleading either. Additionally, move the length input widget to a new line, because: - This length applies to both Auto-select and "Copy commit reference" context menu item, so it's not exclusive to the selection length. - The next commit will add support for primary clipboard as well, where this length will also be used. Also, move the "Hide remotes" item above these selection prefs, to keep the selection prefs semi-grouped before the spacing of the following title "Diff display options". Signed-off-by: Avi Halachmi (:avih) <avihpit@yahoo.com>
2024-12-13gitk: UI text: change "SHA1 ID" to "Commit ID"Avi Halachmi (:avih)1-5/+5
SHA1 might not stay forever, and plans to use SHA256 already exist, so use the official name for it - "Commit ID". Only visible UI texts are modified to reduce the noise when using git-blame, while comments and variable names still contain SHA1/sha1. Signed-off-by: Avi Halachmi (:avih) <avihpit@yahoo.com>
2024-12-12bundle: remove unneeded codeToon Claes2-30/+44
The changes in commit c06793a4ed (allow git-bundle to create bottomless bundle, 2007-08-08) ensure annotated tags are properly preserved when creating a bundle using a revision range operation. At the time the range notation would peel the ends to their corresponding commit, meaning ref v2.0 would point to the v2.0^0 commit. So the above workaround was introduced. This code looks up the ref before it's written to the bundle, and if the ref doesn't point to the object we expect (for tags this would be a tag object), we skip the ref from the bundle. Instead, when the ref is a tag that's the positive end of the range (e.g. v2.0 from the range "v1.0..v2.0"), then that ref is written to the bundle instead. Later, in 895c5ba3c1 (revision: do not peel tags used in range notation, 2013-09-19), the behavior of parsing ranges was changed and the problem was fixed at the cause. But the workaround in bundle.c was not reverted. Now it seems this workaround can cause a race condition. git-bundle(1) uses setup_revisions() to parse the input into `struct rev_info`. Later, in write_bundle_refs(), it uses this info to write refs to the bundle. As mentioned at this point each ref is looked up again and checked whether it points to the object we expect. If not, the ref is not written to the bundle. But, when creating a bundle in a heavy traffic repository (a repo with many references, and frequent ref updates) it's possible a branch ref was updated between setup_revisions() and write_bundle_refs() and thus the extra check causes the ref to be skipped. The workaround was originally added to deal with tags, but the code path also gets hit by non-tag refs, causing this race condition. Because it's no longer needed, remove it and fix the possible race condition. Signed-off-by: Toon Claes <toon@iotcl.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-12ci/lib: fix "CI setup" sections with GitLab CIPatrick Steinhardt1-2/+2
Whenever we source "ci/lib.sh" we wrap the directives in a separate group so that they can easily be collapsed in the web UI. And as we source the script multiple times during a single CI run we thus end up with the same section name reused multiple times, as well. This is broken on GitLab CI though, where reusing the same group name is not supported. The consequence is that only the last of these sections can be collapsed. Fix this issue by including the name of the sourcing script in the group's name. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-12ci/lib: do not interpret escape sequences in `group ()` argumentsPatrick Steinhardt1-2/+4
We use printf to set up sections with GitLab CI, which requires us to print a bunch of escape sequences via printf. The group name is controlled by the user and is expanded directly into the formatting string, which may cause problems in case the argument contains escape sequences or formatting directives. Fix this potential issue by using formatting directives to pass variable data. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-12ci/lib: remove duplicate trap to end "CI setup" groupPatrick Steinhardt1-1/+0
We exlicitly trap on EXIT in order to end the "CI setup" group. This isn't necessary though given that `begin_group ()` already sets up the trap for us. Remove the duplicate trap. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-12gitlab-ci: update macOS images to SonomaPatrick Steinhardt1-2/+2
The macOS Ventura images we use for GitLab CI runners have been deprecated. Update them to macOS 14, aka Sonoma. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-10The fifteenth batchJunio C Hamano1-0/+20
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-10strvec: `strvec_splice()` to a statically initialized vectorRubén Justo2-4/+17
We use a singleton empty array to initialize a `struct strvec`; similar to the empty string singleton we use to initialize a `struct strbuf`. Note that an empty strvec instance (with zero elements) does not necessarily need to be an instance initialized with the singleton. Let's refer to strvec instances initialized with the singleton as "empty-singleton" instances. As a side note, this is the current `strvec_pop()`: void strvec_pop(struct strvec *array) { if (!array->nr) return; free((char *)array->v[array->nr - 1]); array->v[array->nr - 1] = NULL; array->nr--; } So, with `strvec_pop()` an instance can become empty but it does not going to be the an "empty-singleton". This "empty-singleton" circumstance requires us to be careful when adding elements to instances. Specifically, when adding the first element: when we detach the strvec instance from the singleton and set the internal pointer in the instance to NULL. After this point we apply `realloc()` on the pointer. We do this in `strvec_push_nodup()`, for example. The recently introduced `strvec_splice()` API is expected to be normally used with non-empty strvec's. However, it can also end up being used with "empty-singleton" strvec's: struct strvec arr = STRVEC_INIT; int a = 0, b = 0; ... no modification to arr, a or b ... const char *rep[] = { "foo" }; strvec_splice(&arr, a, b, rep, ARRAY_SIZE(rep)); So, we'll try to add elements to an "empty-singleton" strvec instance. Avoid misapplying `realloc()` to the singleton in `strvec_splice()` by adding a special case for strvec's initialized with the singleton. Signed-off-by: Rubén Justo <rjusto@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-10index-pack --promisor: also check commits' treesJonathan Tan1-0/+1
Commit c08589efdc (index-pack: repack local links into promisor packs, 2024-11-01) seems to contain an oversight in that the tree of a commit is not checked. Teach git to check these trees. The fix slows down a fetch from a certain repo at $DAYJOB from 2m2.127s to 2m45.052s, but in order to make the fetch correct, it seems worth it. In order to test this, we could create server and client repos as follows... C S \ / O (O and C are commits both on the client and server. S is a commit only on the server. C and S have the same tree but different commit messages. The diff between O and C is non-zero.) ...and then, from the client, fetch S from the server. In theory, the client declares "have C" and the server can use this information to exclude S's tree (since it knows that the client has C's tree, which is the same as S's tree). However, it is also possible for the server to compute that it needs to send S and not O, and proceed from there; therefore the objects of C are not considered at all when determining what to send in the packfile. In order to prevent a test of client functionality from having such a dependence on server behavior, I have not included such a test. Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-10index-pack --promisor: don't check blobsJonathan Tan1-1/+30
As a follow-up to the parent of this commit, it was found that not checking for the existence of blobs linked from trees sped up the fetch from 24m47.815s to 2m2.127s. Teach Git to do that. The tradeoff of not checking blobs is documented in a code comment. (Blobs may also be linked from tag objects, but it is impossible to know the type of an object linked from a tag object without looking it up in the object database, so the code for that is untouched.) Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-10index-pack --promisor: dedup before checking linksJonathan Tan1-33/+42
Commit c08589efdc (index-pack: repack local links into promisor packs, 2024-11-01) fixed a bug with what was believed to be a negligible decrease in performance [1] [2]. But at $DAYJOB, with at least one repo, it was found that the decrease in performance was very significant. Looking at the patch, whenever we parse an object in the packfile to be indexed, we check the targets of all its outgoing links for its existence. However, this could be optimized by first collecting all such targets into an oidset (thus deduplicating them) before checking. Teach Git to do that. On a certain fetch from the aforementioned repo, this improved performance from approximately 7 hours to 24m47.815s. This number will be further reduced in a subsequent patch. [1] https://lore.kernel.org/git/CAG1j3zGiNMbri8rZNaF0w+yP+6OdMz0T8+8_Wgd1R_p1HzVasg@mail.gmail.com/ [2] https://lore.kernel.org/git/20241105212849.3759572-1-jonathantanmy@google.com/ Signed-off-by: Jonathan Tan <jonathantanmy@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-10Document HOME environment variableAlejandro Barreto1-0/+8
Git documentation refers to $HOME and $XDG_CONFIG_HOME often, but does not specify how or where these values come from on Windows where neither is set by default. The new documentation reflects the behavior of setup_windows_environment() in compat/mingw.c. Signed-off-by: Alejandro Barreto <alejandro.barreto@ni.com> Signed-off-by: M Hickford <mirth.hickford@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-09gitk: add text wrapping preferencesChristoph Sommer1-8/+27
Add a new preference "wrapdefault" which allows enabling char/word wrap. Impacts all text in the ctext widget for which no other preference exists. Also make the (existing) preference "wrapcomment" configurable graphically. Its setting impacts only the "comment" part of the ctext widget. Signed-off-by: Christoph Sommer <sommer@cms-labs.org> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2024-12-09gitk: make headings of preferences boldChristoph Sommer1-5/+5
Make preference groups like "Diff display options" stand out more. Signed-off-by: Christoph Sommer <sommer@cms-labs.org> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
2024-12-08object-name: fix reversed ordering with ":/<text>" revisionsPatrick Steinhardt2-2/+17
Recently it was reported [1] that "look for the youngest commit reachable from any ref with log message that match the given pattern" syntax (i.e. ':/<text>') started to return results in reverse recency order. This regression was introduced in Git v2.47.0 and is caused by a memory leak fix done in 57fb139b5e (object-name: fix leaking commit list items, 2024-08-01). The intent of the identified commit is to stop modifying the commit list provided by the caller such that the caller can properly free all commit list items, including those that the called function might potentially remove from the list. This was done by creating a copy of the passed-in commit list and modifying this copy instead of the caller-provided list. We already knew to create such a copy beforehand with the `backup` list, which was used to clear the `ONELINE_SEEN` commit mark after we were done. So the refactoring simply renamed that list to `copy` and started to operate on that list instead. There is a gotcha though: the backup list, and thus now also the copied list, is always being prepended to, so the resulting list is in reverse order! The end result is that we pop commits from the wrong end of the commit list, returning commits in reverse recency order. Fix the bug by appending to the list instead. [1]: <CAKOEJdcPYn3O01p29rVa+xv=Qr504FQyKJeSB-Moze04ViCGGg@mail.gmail.com> Reported-by: Aarni Koskela <aarni@valohai.com> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-07fetch: do not ask for HEAD unnecessarilyJunio C Hamano2-1/+36
In 3f763ddf28 (fetch: set remote/HEAD if it does not exist, 2024-11-22), git-fetch learned to opportunistically set $REMOTE/HEAD when fetching by always asking for remote HEAD, in the hope that it will help setting refs/remotes/<name>/HEAD if missing. But it is not needed to always ask for remote HEAD. When we are fetching from a remote, for which we have remote-tracking branches, we do need to know about HEAD. But if we are doing one-shot fetch, e.g., $ git fetch --tags https://github.com/git/git we do not even know what sub-hierarchy of refs/remotes/<remote>/ we need to adjust the remote HEAD for. There is no need to ask for HEAD in such a case. Incidentally, because the unconditional request to list "HEAD" affected the number of ref-prefixes requested in the ls-remote request, this affected how the requests for tags are added to the same ls-remote request, breaking "git fetch --tags $URL" performed against a URL that is not configured as a remote. Reported-by: Josh Steadmon <steadmon@google.com> [jc: tests are also borrowed from Josh's patch] Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-07reftable/writer: ensure valid range for log's update_indexKarthik Nayak3-4/+63
Each reftable addition has an associated update_index. While writing refs, the update_index is verified to be within the range of the reftable writer, i.e. `writer.min_update_index <= ref.update_index` and `writer.max_update_index => ref.update_index`. The corresponding check for reflogs in `reftable_writer_add_log` is however missing. Add a similar check, but only check for the upper limit. This is because reflogs are treated a bit differently than refs. Each reflog entry in reftable has an associated update_index and we also allow expiring entries in the middle, which is done by simply writing a new reflog entry with the same update_index. This means, writing reflog entries with update_index lesser than the writer's update_index is an expected scenario. Add a new unit test to check for the limits and fix some of the existing tests, which were setting arbitrary values for the update_index by ensuring they stay within the now checked limits. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Introduce support for the Meson build systemPatrick Steinhardt27-0/+3880
Introduce support for the Meson build system, a "modern" meta build system that supports many different platforms, including Linux, macOS, Windows and BSDs. Meson supports different backends, including Ninja, Xcode and Microsoft Visual Studio. Several common IDEs provide an integration with it. The biggest contender compared to Meson is probably CMake as outlined in our "Documentation/technical/build-systems.txt" file. Based on my own personal experience from working with both build systems extensively I strongly favor Meson over CMake. In my opinion, it feels significantly easier to use with a syntax that feels more like a "real" programming language. The second big reason is that Meson supports Rust natively, which may prove to be important given that the project may pick up Rust as another language eventually. Using Meson is rather straight-forward. An example: ``` # Meson uses out-of-tree builds. You can set up multiple build # directories, how you name them is completely up to you. $ mkdir build $ cd build $ meson setup .. -Dprefix=/tmp/git-installation # Build the project. This also provides several other targets like e.g. `install` or `test`. $ ninja # Meson has been wired up to support execution of our test suites. # Both our unit tests and our integration tests are supported. # Running `meson test` without any arguments will execute all tests, # but the syntax supports globbing to select only some tests. $ meson test 't-*' # Execute single test interactively to allow for debugging. $ meson test 't0000-*' --interactive --test-args=-ix ``` The build instructions have been successfully tested on the following systems, tests are passing: - Apple macOS 10.15. - FreeBSD 14.1. - NixOS 24.11. - OpenBSD 7.6. - Ubuntu 24.04. - Windows 10 with Cygwin. - Windows 10 with MinGW64, except for t9700, which is also broken with our Makefile. - Windows 10 with Visual Studio 2022 toolchain, using the Native Tools Command Prompt with `meson setup --vsenv`. Tests pass, except for t9700. - Windows 10 with Visual Studio 2022 solution, using the Native Tools Command Prompt with `meson setup --backend vs2022`. Tests pass, except for t9700. - Windows 10 with VS Code, using the Meson plug-in. It is expected that there will still be rough edges in the current version. If this patch lands the expectation is that it will coexist with our other build systems for a while. Like this, distributions can slowly migrate over to Meson and report any findings they have to us such that we can continue to iterate. A potential cutoff date for other build systems may be Git 3.0. Some notes: - The installed distribution is structured somewhat differently than how it used to be the case. All of our binaries are installed into `$libexec/git-core`, while all binaries part of `$bindir` are now symbolic links pointing to the former. This rule is consistent in itself and thus easier to reason about. - We do not install dashed binaries into `$libexec/git-core` anymore, so there won't e.g. be a symlink for git-add(1). These are not required by modern Git and there isn't really much of a use case for those anymore. By not installing those symlinks we thus start the deprecation of this layout. - We're targeting Meson 1.3.0, which has been released relatively recently November 2023. The only feature we use from that version is `fs.relative_to()`, which we could replace if necessary. If so, we could start to target Meson 1.0.0 and newer, released in December 2022. - The whole build instructions count around 3300 lines, half of which is listing all of our code and test files. Our Makefiles are around 5000 lines, autoconf adds another 1300 lines. CMake in comparison has only 1200 linescode, but it avoids listing individual files and does not wire up auto-configuration as extensively as the Meson instructions do. - We bundle a set of subproject wrappers for curl, expat, openssl, pcre2 and zlib. This allows developers to build Git without these dependencies preinstalled, and Meson will fetch and build them automatically. This is especially helpful on Windows. Helped-by: Eli Schwartz <eschwartz@gentoo.org> Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Documentation: add comparison of build systemsPatrick Steinhardt2-0/+225
We're contemplating whether to eventually replace our build systems with a build system that is easier to use. Add a comparison of build systems to our technical documentation as a baseline for discussion. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06t: allow overriding build dirPatrick Steinhardt1-1/+2
Our "test-lib.sh" assumes that our build directory is the parent directory of "t/". While true when using our Makefile, it's not when using build systems that support out-of-tree builds. In commit ee9e66e4e7 (cmake: avoid editing t/test-lib.sh, 2022-10-18), we have introduce support for overriding the GIT_BUILD_DIR by creating the file "$GIT_BUILD_DIR/GIT-BUILD-DIR" with its contents pointing to the location of the build directory. The intent was to stop modifying "t/test-lib.sh" with the CMake build systems while allowing out-of-tree builds. But "$GIT_BUILD_DIR" is somewhat misleadingly named, as it in fact points to the _source_ directory. So while that commit solved part of the problem for out-of-tree builds, CMake still has to write files into the source tree. Solve the second part of the problem, namely not having to write any data into the source directory at all, by also supporting an environment variable that allows us to point to a different build directory. This allows us to perform properly self-contained out-of-tree builds. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06t: better support for out-of-tree buildsPatrick Steinhardt7-11/+34
Our in-tree builds used by the Makefile use various different build directories scattered around different locations. The paths to those build directories have to be propagated to our tests such that they can find the contained files. This is done via a mixture of hardcoded paths in our test library and injected variables in our bin-wrappers or "GIT-BUILD-OPTIONS". The latter two mechanisms are preferable over using hardcoded paths. For one, we have all paths which are subject to change stored in a small set of central files instead of having the knowledge of build paths in many files. And second, it allows build systems which build files elsewhere to adapt those paths based on their own needs. This is especially nice in the context of build systems that use out-of-tree builds like CMake or Meson. Remove hardcoded knowledge of build paths from our test library and move it into our bin-wrappers and "GIT-BUILD-OPTIONS". Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Documentation: extract script to generate a list of mergetoolsPatrick Steinhardt2-14/+25
We include the list of available mergetools into our manpages. Extract the script that performs this logic such that we can reuse it in other build systems. While at it, refactor the Makefile targets such that we don't create "mergetools-list.made" anymore. It shouldn't be necessary, as we can instead have other targets depend on "mergetools-{diff,merge}.txt" directly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Documentation: teach "cmd-list.perl" about out-of-tree buildsPatrick Steinhardt2-12/+13
The "cmd-list.perl" script generates a list of commands that can be included into our manpages. The script doesn't know about out-of-tree builds and instead writes resulting files into the source directory. Adapt it such that we can read data from the source directory and write data into the build directory. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Documentation: allow sourcing generated includes from separate dirPatrick Steinhardt5-15/+18
Our documentation uses "include::" directives to include parts that are either reused across multiple documents or parts that we generate at build time. Unfortunately, top-level includes are only ever resolved relative to the base directory, which is typically the directory of the including document. Most importantly, it is not possible to have either asciidoc or asciidoctor search multiple directories. It follows that both kinds of includes must live in the same directory. This is of course a bummer for out-of-tree builds, because here the dynamically-built includes live in the build directory whereas the static includes live in the source directory. Introduce a `build_dir` attribute and prepend it to all of our includes for dynamically-built files. This attribute gets set to the build directory and thus converts the include path to an absolute path, which asciidoc and asciidoctor know how to resolve. Note that this change also requires us to update "build-docdep.perl", which tries to figure out included files such our Makefile can set up proper build-time dependencies. This script simply scans through the source files for any lines that match "^include::" and treats the remainder of the line as included file path. But given that those may now contain the "{build_dir}" variable we have to teach the script to replace that attribute with the actual build directory. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: simplify building of templatesPatrick Steinhardt19-37/+37
When we install Git we also install a set of default templates that both git-init(1) and git-clone(1) populate into our build directories. The way the pristine templates are laid out in our source directory is somewhat weird though: instead of reconstructing the actual directory hierarchy in "templates/", we represent directory separators with "--". The only reason I could come up with for why we have this is the "branches/" directory, which is supposed to be empty when installing it. And as Git famously doesn't store empty directories at all we have to work around this limitation. Now the thing is that the "branches/" directory is a leftover to how branches used to be stored in the dark ages. gitrepository-layout(5) lists this directory as "slightly deprecated", which I would claim is a strong understatement. I have never encountered anybody using it today and would be surprised if it even works as expected. So having the "--" hack in place for an item that is basically unused, unmaintained and deprecated doesn't only feel unreasonable, but installing that entry by default may also cause confusion for users that do not know what this is supposed to be in the first place. Remove this directory from our templates and, now that we do not require the workaround anymore, restructure the templates to form a proper hierarchy. This makes it way easier for build systems to install these templates into place. We should likely think about removing support for "branch/" altogether, but that is outside of the scope of this patch series. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: write absolute program path into bin-wrappersPatrick Steinhardt3-7/+7
Write the absolute program path into our bin-wrappers. This allows us to simplify the Meson build instructions we are about to introduce a bit. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: allow "bin-wrappers/" directory to existPatrick Steinhardt6-8/+16
The "bin-wrappers/" directory gets created by our build system and is populated with one script for each of our binaries. There isn't anything inherently wrong with the current layout, but it is somewhat hard to adapt for out-of-tree build systems. Adapt the layout such that our "bin-wrappers/" directory always exists and contains our "wrap-for-bin.sh" script to make things a little bit easier for subsequent steps. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: refactor generators to be PWD-independentPatrick Steinhardt5-34/+68
We have multiple scripts that generate headers from other data. All of these scripts have the assumption built-in that they are executed in the current source directory, which makes them a bit unwieldy to use during out-of-tree builds. Refactor them to instead take the source directory as well as the output file as arguments. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: extract script to generate gitweb.jsPatrick Steinhardt2-1/+14
Similar to the preceding commit, also extract the script to generate the "gitweb.js" file. While the logic itself is trivial, it helps us avoid duplication of logic across build systems and ensures that the build systems will remain in sync with each other in case the logic ever needs to change. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: extract script to generate gitweb.cgiPatrick Steinhardt4-31/+101
In order to generate "gitweb.cgi" we have to replace various different placeholders. This is done ad-hoc and is thus not easily reusable across different build systems. Introduce a new GITWEB-BUILD-OPTIONS.in template that we populate at configuration time with the expected options. This script is then used as input for a new "generate-gitweb.sh" script that generates the final "gitweb.cgi" file. While this requires us to repeat the options multiple times, it is in line to how we generate other build options like our GIT-BUILD-OPTIONS file. While at it, refactor how we replace the GITWEB_PROJECT_MAXDEPTH. Even though this variable is supposed to be an integer, the source file has the value quoted. The quotes are eventually stripped via sed(1), which replaces `"@GITWEB_PROJECT_MAXDEPTH@"` with the actual value, which is rather nonsensical. This is made clearer by just dropping the quotes in the source file. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: extract script to massage Python scriptsPatrick Steinhardt3-10/+33
Extract a script that massages Python scripts. This provides a couple of benefits: - The build logic is deduplicated across Make, CMake and Meson. - CMake learns to rewrite scripts as-needed at build time instead of only writing them at configure time. Furthermore, we will use this script when introducing Meson to deduplicate the logic across build systems. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: extract script to massage Shell scriptsPatrick Steinhardt4-35/+68
Same as in the preceding commits, extract a script that allows us to unify how we massage shell scripts. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: use "generate-perl.sh" to massage Perl libraryPatrick Steinhardt4-22/+27
Extend "generate-perl.sh" such that it knows to also massage the Perl library files. There are two major differences: - We do not read in the Perl header. This is handled by matching on whether or not we have a Perl shebang. - We substitute some more variables, which we read in via our GIT-BUILD-OPTIONS. Adapt both our Makefile and the CMake build instructions to use this. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: extract script to massage Perl scriptsPatrick Steinhardt3-15/+56
Extract the script to inject various build-time parameters into our Perl scripts into a standalone script. This is done such that we can reuse it in other build systems. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: consistently use PERL_PATHPatrick Steinhardt4-5/+5
When injecting the Perl path into our scripts we sometimes use '@PERL@' while we othertimes use '@PERL_PATH@'. Refactor the code use the latter consistently, which makes it easier to reuse the same logic for multiple scripts. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: generate doc versions via GIT-VERSION-GENPatrick Steinhardt5-15/+25
The documentation we generate embeds information for the exact Git version used as well as the date of the commit. This information is injected by injecting attributes into the build process via command line argument. Refactor the logic so that we write the information into "asciidoc.conf" and "asciidoctor-extensions.rb" via `GIT-VERSION-GEN` for AsciiDoc and AsciiDoctor, respectively. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: generate "git.rc" via GIT-VERSION-GENPatrick Steinhardt5-17/+30
The "git.rc" is used on Windows to embed information like the project name and version into the resulting executables. As such we need to inject the version information, which we do by using preprocessor defines. The logic to do so is non-trivial and needs to be kept in sync with the different build systems. Refactor the logic so that we generate "git.rc" via `GIT-VERSION-GEN`. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: propagate Git version via generated headerPatrick Steinhardt6-11/+35
We set up a couple of preprocessor macros when compiling Git that propagate the version that Git was built from to `git version` et al. The way this is set up makes it harder than necessary to reuse the infrastructure across the different build systems. Refactor this such that we generate a "version-def.h" header via `GIT-VERSION-GEN` instead. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: refactor GIT-VERSION-GEN to be reusablePatrick Steinhardt6-34/+59
Our "GIT-VERSION-GEN" script always writes the "GIT-VERSION-FILE" into the current directory, where the expectation is that it should exist in the source directory. But other build systems that support out-of-tree builds may not want to do that to keep the source directory pristine, even though CMake currently doesn't care. Refactor the script such that it won't write the "GIT-VERSION-FILE" directly anymore, but instead knows to replace @PLACEHOLDERS@ in an arbitrary input file. This allows us to simplify the logic in CMake to determine the project version, but can also be reused later on in order to generate other files that need to contain version information like our "git.rc" file. While at it, change the format of the version file by removing the spaces around the equals sign. Like this we can continue to include the file in our Makefiles, but can also start to source it in shell scripts in subsequent steps. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
2024-12-06Makefile: consistently use @PLACEHOLDER@ to substitutePatrick Steinhardt18-119/+119
We have a bunch of placeholders in our scripts that we replace at build time, for example by using sed(1). These placeholders come in three different formats: @PLACEHOLDER@, @@PLACEHOLDER@@ and ++PLACEHOLDER++. Next to being inconsistent it also creates a bit of a problem with CMake, which only supports the first syntax in its `configure_file()` function. To work around that we instead manually replace placeholders via string operations, which is a hassle and removes safeguards that CMake has to verify that we didn't forget to replace any placeholders. Besides that, other build systems like Meson also support the CMake syntax. Unify our codebase to consistently use the syntax supported by such build systems. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>