* Re: [PATCH] i18n: factorize even more 'incompatible options' messages
From: Eric Sunshine @ 2023-11-27 17:48 UTC (permalink / raw)
To: René Scharfe
Cc: Jean-Noël Avila, Patrick Steinhardt, Junio C Hamano,
Git List
In-Reply-To: <d1f28272-635d-4638-b0f4-76d64013b0d5@web.de>
On Mon, Nov 27, 2023 at 12:39 PM René Scharfe <l.s.r@web.de> wrote:
> Am 26.11.23 um 18:49 schrieb Eric Sunshine:
> > A couple additional instances recently slipped into `show-ref.c` which
> > were caught during review[1,2] but nevertheless made it to
> > "master"[3,4]. This patch, of course, doesn't need to address those,
> > but if rerolling for some other reason, perhaps they can be included,
> > as well(?).
> >
> > [1]: https://lore.kernel.org/git/CAPig+cSrp7vZuy7D_ENHKZKZzF4OSmCtfYNHPGMtS1Hj6gArDw@mail.gmail.com/
> > [2]: https://lore.kernel.org/git/CAPig+cRTOMie0rUf=Mhbo9e2EXf-_2kQyMeqpB9OCRB1MZZ1rw@mail.gmail.com/
> > [3]: 199970e72f (builtin/show-ref: ensure mutual exclusiveness of
> > subcommands, 2023-10-31)
> > [4]: 9080a7f178 (builtin/show-ref: add new mode to check for reference
> > existence, 2023-10-31)
>
> [4] changes the message added by [3], so that's one instance, right?
Yes, correct. Sorry for misleadingly saying there were two new
messages; it's been a month since I looked at the patches closely, and
forgot that it was just the single message which had been modified by
the subsequent patch.
Thanks for taking care of this so quickly!
> --- >8 ---
> Subject: [PATCH] show-ref: use die_for_incompatible_opt3()
>
> Use the standard message for reporting the use of multiple mutually
> exclusive options by calling die_for_incompatible_opt3() instead of
> rolling our own. This has the benefits of showing only the actually
> given options, reducing the number of strings to translate and making
> the UI slightly more consistent.
>
> Adjust the test to no longer insist on a specific order of the
> reported options, as this implementation detail does not affect the
> usefulness of the error message.
>
> Signed-off-by: René Scharfe <l.s.r@web.de>
Apparently, I haven't been following along closely enough, thus wasn't
aware that we had the die_for_incompatible_opt*() family of functions.
Neat.
^ permalink raw reply
* Re: [PATCH v2 0/5] Avoid hang if curl needs eof twice + minor related improvements
From: Jonathan Tan @ 2023-11-27 18:26 UTC (permalink / raw)
To: Jiří Hruška; +Cc: Jonathan Tan, git, Jeff King, Junio C Hamano
In-Reply-To: <CAGE_+C4B=zjPqNV+fGt9gaA0O8qmqmK3CDh-eLBPmXx+ChzXAQ@mail.gmail.com>
Jiří Hruška <jirka@fud.cz> writes:
> > I've already reviewed 1/5 so I'll summarize what I think of the rest.
> Thank you for your time looking at everything, Jonathan.
>
> I'm sorry for the delay in my reply, I was away for a while and also trying
> to get clarity from the cURL side, summarized in [1].
>
> [1] https://lore.kernel.org/git/CAGE_+C5u9H8m5faK1vXKk6QTyjcHgKHqxOZy5ptzsYbF_0yrCQ@mail.gmail.com/
>
> Most importantly, the bug has been apparently in libcurl only for ~1 year and
> it can no longer manifest for a few months. Therefore, the main point of my
> changes is a bit moot and we might reconsider what is useful and what is not.
Thanks for following up with the Curl side. Even if the Curl bug is
fixed now, for what it's worth, I still think that it's worth including
this mitigation in Git.
^ permalink raw reply
* Re: [PATCH] setup: recognize bare repositories with packed-refs
From: Josh Steadmon @ 2023-11-27 19:42 UTC (permalink / raw)
To: Glen Choo; +Cc: Junio C Hamano, git, Adam Majer
In-Reply-To: <CA+we5Gqp2nhoXyqJKJiXQMDx-ZXcnNGHu3wnwERWREng2XHHuQ@mail.gmail.com>
On 2023.11.20 17:31, Glen Choo wrote:
> On Mon, Nov 20, 2023 at 7:24 AM Junio C Hamano <gitster@pobox.com> wrote:
> >
> > Adam Majer <adamm@zombino.com> writes:
> >
> > > In a garbage collected bare git repository, the refs/ subdirectory is
> > > empty. In use-cases when such a repository is directly added into
> > > another repository, it no longer is detected as valid.
> >
> > Josh & Glen [*], isn't this a layout that we explicitly discourage and
> > eventually plan to forbid anyway?
>
> If my recollection of [1] serves me correctly, we didn't come to a
> strong conclusion on whether or not to forbid bare repositories in the
> working tree, particularly because it would leave existing repos (like
> Git LFS) high and dry. Though personally, I'd be happy to see a
> version of Git that forbade bare repositories in the working tree.
>
> I don't really recall the bare repo tracing bits, so I'll leave that to Josh.
>
> [1] https://lore.kernel.org/git/kl6lsfqpygsj.fsf@chooglen-macbookpro.roam.corp.google.com/
Yeah, my understanding was that we don't want to forbid bare
repositories outright, which is why we have the config option to let
end-users choose what to do with them.
^ permalink raw reply
* Re: [PATCH] setup: recognize bare repositories with packed-refs
From: Josh Steadmon @ 2023-11-27 19:44 UTC (permalink / raw)
To: Adam Majer; +Cc: git
In-Reply-To: <20231117203253.21143-1-adamm@zombino.com>
On 2023.11.17 21:32, Adam Majer wrote:
> In a garbage collected bare git repository, the refs/ subdirectory is
> empty. In use-cases when such a repository is directly added into
> another repository, it no longer is detected as valid. Git doesn't
> preserve empty paths so refs/ subdirectory is not present. Simply
> creating an empty refs/ subdirectory fixes this problem.
>
> Looking more carefully, there are two backends to handle various refs in
> git -- the files backend that uses refs/ subdirectory and the
> packed-refs backend that uses packed-refs file. If references are not
> found in refs/ subdirectory (or directory doesn't exist), the
> packed-refs directory will be consulted. Garbage collected repository
> will have all its references in packed-refs file.
>
> To allow the use-case when packed-refs is the only source of refs and
> refs/ subdirectory is simply not present, augment 'is_git_directory()'
> setup function to look for packed-refs file as an alternative to refs/
> subdirectory.
>
> Signed-off-by: Adam Majer <adamm@zombino.com>
> ---
> setup.c | 10 +++++++---
> t/t6500-gc.sh | 8 ++++++++
> 2 files changed, 15 insertions(+), 3 deletions(-)
>
> diff --git a/setup.c b/setup.c
> index fc592dc6dd..2a6dda6ae9 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -348,7 +348,7 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
> *
> * - either an objects/ directory _or_ the proper
> * GIT_OBJECT_DIRECTORY environment variable
> - * - a refs/ directory
> + * - a refs/ directory or packed-refs file
> * - either a HEAD symlink or a HEAD file that is formatted as
> * a proper "ref:", or a regular file HEAD that has a properly
> * formatted sha1 object name.
> @@ -384,8 +384,12 @@ int is_git_directory(const char *suspect)
>
> strbuf_setlen(&path, len);
> strbuf_addstr(&path, "/refs");
> - if (access(path.buf, X_OK))
> - goto done;
> + if (access(path.buf, X_OK)) {
> + strbuf_setlen(&path, len);
> + strbuf_addstr(&path, "/packed-refs");
> + if (access(path.buf, R_OK))
> + goto done;
> + }
>
> ret = 1;
> done:
> diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
> index 18fe1c25e6..e81eb7d2ab 100755
> --- a/t/t6500-gc.sh
> +++ b/t/t6500-gc.sh
> @@ -214,6 +214,14 @@ test_expect_success 'gc.repackFilter launches repack with a filter' '
> grep -E "^trace: (built-in|exec|run_command): git repack .* --filter=blob:none ?.*" trace.out
> '
>
> +test_expect_success 'remove empty refs/ subdirectory' '
> + git -C bare.git cat-file -e 60dd8ad7d8ed49005c18b7ce9f5b7a45c28df814 &&
> + test_dir_is_empty bare.git/refs/heads &&
> + test_dir_is_empty bare.git/refs/tags &&
> + rm -r bare.git/refs &&
> + GIT_DIR="$PWD"/bare.git git -C bare.git cat-file -e 60dd8ad7d8ed49005c18b7ce9f5b7a45c28df814
> +'
> +
Two suggestions for the test here:
1) Can you give the test a more descriptive name, such as "GCed bare
repos still recognized"?
2) Can you add a check that bare.git/packed-refs exists?
Other than that, looks good to me.
Reviewed-by: Josh Steadmon <steadmon@google.com>
^ permalink raw reply
* Re: --end-of-options inconsistently available?!
From: Jeff King @ 2023-11-27 21:22 UTC (permalink / raw)
To: Sven Strickroth; +Cc: git
In-Reply-To: <4d944fe3-d31d-4859-8ed2-6c1da64410fe@cs-ware.de>
On Mon, Nov 27, 2023 at 12:22:44PM +0100, Sven Strickroth wrote:
> Hi,
>
> gitcli(7) states:
> > Because -- disambiguates revisions and paths in some commands, it cannot be used for those commands to separate options and revisions. You can use --end-of-options for this (it also works for commands that do not distinguish between revisions in paths, in which case it is simply an alias for --).
>
> However, when I use this for certain commands it fails:
>
> $ git reset --end-of-options HEAD --
> fatal: option '--end-of-options' must come before non-option arguments
This one seems like a bug. Handling of --end-of-options usually happens
via the parse_options() API. But in this case, cmd_reset() calls it with
PARSE_OPT_KEEP_DASHDASH, which retains the --end-of-options marker. But
then the caller is not ready to deal with that string being left in
argv[0] (it is OK with "--", but not anything else).
So at first glance, it feels like parse-options should avoid leaving it
in place, like:
diff --git a/parse-options.c b/parse-options.c
index e0c94b0546..5c07ad47ec 100644
--- a/parse-options.c
+++ b/parse-options.c
@@ -931,7 +931,7 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
if (!arg[2] /* "--" */ ||
!strcmp(arg + 2, "end-of-options")) {
- if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
+ if (arg[2] || !(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
ctx->argc--;
ctx->argv++;
}
But I think that confuses other callers. For example, t4202 fails
because we try (with a ref called refs/heads/--source) to run:
git log --end-of-options --source
expecting it it to be resolved as a ref. With the patch above, it gets
confused. So I think we may need to teach KEEP_DASHDASH callers to
handle end-of-options themselves. In the case of git-log, it is done by
the revision machinery, but reset doesn't use that.
So something like this works:
diff --git a/builtin/reset.c b/builtin/reset.c
index 4b018d20e3..a0d801179a 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -259,6 +259,9 @@ static void parse_args(struct pathspec *pathspec,
* At this point, argv points immediately after [-opts].
*/
+ if (argv[0] && !strcmp(argv[0], "--end-of-options"))
+ argv++;
+
if (argv[0]) {
if (!strcmp(argv[0], "--")) {
argv++; /* reset to HEAD, possibly with paths */
but it feels like a maintenance problem that we'd have to audit every
caller that uses KEEP_DASHDASH.
On the other hand, I do think the callers need to be a bit aware of the
issue to make things work seamlessly. In particular, this now does what
you'd expect:
git reset --end-of-options foo -- bar
But if we do this:
git reset --end-of-options --foo
it works if "--foo" can be resolved, but otherwise complains "option
'--foo' must come before non-option arguments", even if it exists as a
file! IOW, the do-what-I-mean handling of "--" is too picky; in
verify_filename() it complains about things that look like options, not
realizing we already made sure to avoid those.
OTOH that is also true of "git log --end-of-options --foo". And maybe
not that big a deal in practice. If you are truly being careful you'd
always do:
git log --end-of-options --foo -- --bar
anyway, which is unambiguous.
So I dunno. I'm not sure there's a central fix, and we may have to just
fix this spot and look for others.
> $ git rev-parse --symbolic-full-name --end-of-options master
> --end-of-options
> refs/heads/master
>
> Here, the output also contains "--end-of-options" as if it is a reference
> (same for "--")
This one is intentional. rev-parse in its default mode is not just
spitting out revisions, but also options that are meant to be passed
along to the revision machinery via other commands (like rev-list). So
for example:
$ git rev-parse --foo HEAD
--foo
564d0252ca632e0264ed670534a51d18a689ef5d
And it does understand end-of-options explicitly, so:
$ git rev-parse --end-of-options --foo --
--end-of-options
fatal: bad revision '--foo'
If you just want to parse a name robustly, use --verify.
> $ git checkout -f --end-of-options HEAD~1 -- afile.txt
> fatal: only one reference expected, 2 given.
I think this is the same KEEP_DASHDASH problem as with git-reset.
-Peff
^ permalink raw reply related
* Re: [PATCH 2/2] checkout: forbid "-B <branch>" from touching a branch used elsewhere
From: Jeff King @ 2023-11-27 21:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Phillip Wood, Willem Verstraeten, git
In-Reply-To: <xmqqwmu42ccb.fsf@gitster.g>
On Mon, Nov 27, 2023 at 10:51:00AM +0900, Junio C Hamano wrote:
> >> + if (opts->new_branch_force) {
> >> + char *full_ref = xstrfmt("refs/heads/%s", opts->new_branch);
> >> + die_if_switching_to_a_branch_in_use(opts, full_ref);
> >> + free(full_ref);
> >
> > At the moment this is academic as neither of the test scripts changed
> > by this patch are leak free and so I don't think we need to worry
> > about it but it raises an interesting question about how we should
> > handle memory leaks when dying. Leaving the leak when dying means that
> > a test script that tests an expected failure will never be leak free
> > but using UNLEAK() would mean we miss a leak being introduced in the
> > successful case should the call to "free()" ever be removed.
>
> Is there a leak here? The piece of memory is pointed at by an on-stack
> variable full_ref when leak sanitizer starts scanning the heap and
> the stack just before the process exits due to die, so I do not see
> a reason to worry about this particular variable over all the other
> on stack variables we accumulated before the control reached this
> point of the code.
Right, I think the only reasonable approach here is to not consider this
a leak. We've discussed this in the past. Here's a link into a relevant
thread for reference, but I don't think it's really worth anybody's
time to re-visit:
https://lore.kernel.org/git/Y0+i1G5ybdhUGph2@coredump.intra.peff.net/
> Are you worried about optimizing compilers that behave more cleverly
> than their own good to somehow lose the on-stack reference to
> full_ref while calling die_if_switching_to_a_branch_in_use()? We
> might need to squelch them with UNLEAK() but that does not mean we
> have to remove the free() we see above, and I suspect a more
> productive use of our time to solve that issue is ensure that our
> leak-sanitizing build will not triger such an unwanted optimization
> anyway.
We did have that problem, but it should no longer be the case after
d3775de074 (Makefile: force -O0 when compiling with SANITIZE=leak,
2022-10-18). If that is not sufficient for some compiler/code combo, I'd
be interested to hear about it.
-Peff
^ permalink raw reply
* Re: Fix git-send-email.perl w.r.t. recent Getopt::Long update
From: Jeff King @ 2023-11-27 21:38 UTC (permalink / raw)
To: H.Merijn Brand; +Cc: Bagas Sanjaya, Git Mailing List
In-Reply-To: <20231125104211.5b7fe0be@pc09>
On Sat, Nov 25, 2023 at 10:45:22AM +0100, H.Merijn Brand wrote:
> As I am used to PR's by now on all OSS projects I am involved in, or
> use git commits or merges directly on the repo, I *never* use
> format-patch and/or send-email.
>
> These docs - yes I read them - do not offer a concise cut-n-paste
> example for people like me. In order to have my relative simple patch
> submitted (I already had the PR ready, but that came with a huge
> warning that PR's are not accepted) I did it the way I did it. Now I
> need to read and learn two new commands> I don't think that is very
> user-friendly, but that might be just me.
These days you can use GitGitGadget to submit a PR to the mailing list:
https://gitgitgadget.github.io/
The PR template mentions this, as well as the "about" text for git/git,
but I won't be surprised if there are other spots that should be updated
to mention it. If you found a message that would benefit from mentioning
it, let us know so we can update it.
Thanks.
-Peff
^ permalink raw reply
* Re: [PATCH 2/4] trace2: redact passwords from https:// URLs by default
From: Jeff King @ 2023-11-27 21:50 UTC (permalink / raw)
To: Elijah Newren
Cc: Johannes Schindelin via GitGitGadget, git, Johannes Schindelin
In-Reply-To: <CABPp-BELjVqVEB3oVx3fMzmvNfE1f7muLR_2k912_C+SaQtZtg@mail.gmail.com>
On Thu, Nov 23, 2023 at 10:59:20AM -0800, Elijah Newren wrote:
> > Let's at least avoid logging such secrets via Trace2, much like we avoid
> > logging secrets in `http.c`. Much like the code in `http.c` is guarded
> > via `GIT_TRACE_REDACT` (defaulting to `true`), we guard the new code via
> > `GIT_TRACE2_REDACT` (also defaulting to `true`).
>
> Training users is hard. I appreciate the changes here to make trace2
> not be a leak vector, but is it time to perhaps consider bigger safety
> measures: At the clone/fetch level, automatically warn loudly whenever
> such a URL is provided, accompanied with a note that in the future it
> will be turned into a hard error?
Yes, the password in such a case ends up in the plaintext .git/config
file, which is not great.
There's some discussion and patches here:
https://lore.kernel.org/git/nycvar.QRO.7.76.6.1905172121130.46@tvgsbejvaqbjf.bet/
I meant to follow up on them, but never did.
-Peff
^ permalink raw reply
* Re: [BUG?] Semantics of HEAD when bare cloning non-bare repositories
From: Jeff King @ 2023-11-27 21:56 UTC (permalink / raw)
To: guillaume.yziquel; +Cc: git
In-Reply-To: <179a3f7b2605b295.375e54053ab898bd.31bd44aeb0344c08@hilbert>
On Thu, Nov 23, 2023 at 12:13:27PM +0000, guillaume.yziquel@mailfence.com wrote:
> Observation: When git clone --bare is used on a non-bare repo, the
> HEAD is put in ./refs/HEAD, and conflicts with ./HEAD in the sense
> that they may end up decorelated over time.
That sounds like a bug, but I can't reproduce it here:
$ git init not-bare
$ git -C not-bare commit --allow-empty -m foo
$ git clone --bare not-bare bare.git
$ find bare.git/refs
bare.git/refs
bare.git/refs/tags
bare.git/refs/heads
$ cat bare.git/packed-refs
# pack-refs with: peeled fully-peeled sorted
db58e786007ca405e34df314479e27ddd337957a refs/heads/main
Are you sure that your non-bare repository does not accidentally have a
"refs/HEAD" that should not be there?
> Suggestion: When bare cloning on a non-bare repo, do not put the HEAD
> of the non-bare repo in refs/HEAD like every branch, but treat it
> separately: put it in ./HEAD, not ./refs/HEAD.
That should be what happens already.
-Peff
^ permalink raw reply
* Re: [PATCH] doc: make the gitfile syntax easier to discover
From: Marcel Krause @ 2023-11-28 1:51 UTC (permalink / raw)
To: git mailing list; +Cc: Junio C Hamano, Marcel Krause
In-Reply-To: <xmqqr0kd5i66.fsf@gitster.g>
Thanks for your advice! I'll prepare a new patch.
> The title itself is sufficient, i.e. it had poor visibility, and you
> fix it by giving it better visibility.
Yeah I see now, I should have sent the explanation as cover letter,
not as commit message.
> more relevant is why you needed to find out what the former should
> be in the first place.
My gitfile links worktrees on limited-capability filesystems to a
git repo on a nicer filesystem.
^-- Should I write this in the commit message?
(For the more curious: That way I sync GRUB configs accross lots of
FAT FS thumb drives while having the main repo and main worktree on
an ext3 FS with symlinks and proper owner/group/mode for non-config
files of the project.)
> Do not unnecessary rewrap existing text, only to insert a few
> words, to force reviewers read a lot more than needed.
The shortest diff I can come up with would be:
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -25,3 +25,4 @@ A Git repository comes in two different flavours:
your working tree, containing `gitdir: <path>` to point at the real
-directory that has the repository. This mechanism is often used for
+directory that has the repository.
+This mechanism is called a 'gitfile' and is often used for
a working tree of a submodule checkout, to allow you in the
It loses the double space and thus the sentence boundary information,
but a similar case exists in line 156 (old) so I guess it'll be ok.
> Running "git grep linkgit:gitrepository-layout" would help you find
> the right way to spell this one, I think.
Found and fixed the missing "[5]".
Maybe I'll try and teach our tests to catch that.
^ permalink raw reply
* Re: Migration of git-scm.com to a static web site: ready for review/testing
From: Todd Zullinger @ 2023-11-28 1:54 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Matt Burke, Victoria Dye, Matthias Aßhauer
In-Reply-To: <1d83b8f8-b739-6277-ac4f-e7fe6ff2d2fe@gmx.de>
[-- Attachment #1: Type: text/plain, Size: 1842 bytes --]
Hi Johannes,
Johannes Schindelin wrote:
> I found https://lychee.cli.rs/#/ in the meantime and figured out how to
> use it in a local setup:
Nice. That's much faster.
> My most recent lychee run results in 0 broken links.
>
> As a bonus, some of the links that are currently broken on
> https://git-scm.com/ are fixed in https://git.github.io/git-scm.com/.
> For example, following the `Pull Request Referləri` link at the top of
> https://git-scm.com/book/az/v2/Appendix-C:-Git-%C6%8Fmrl%C9%99ri-Plumbing-%C6%8Fmrl%C9%99ri/
> leads to a 404. But following it in
> https://git.github.io/git-scm.com/book/az/v2/Appendix-C:-Git-%C6%8Fmrl%C9%99ri-Plumbing-%C6%8Fmrl%C9%99ri/
> directs the browser to the correct URL:
> https://git.github.io/git-scm.com/book/az/v2/GitHub-Bir-Layih%C9%99nin-Saxlan%C4%B1lmas%C4%B1/#_pr_refs
>
> Another thing that is broken on https://git-scm.com/ are the footnotes in
> the Czech translation of the ProGit book. These were broken in the Hugo
> version, too, but now they are fixed. See e.g.
> https://dscho.github.io/git-scm.com/book/cs/v2/Z%C3%A1klady-pr%C3%A1ce-se-syst%C3%A9mem-Git-Zobrazen%C3%AD-historie-reviz%C3%AD/#_footnotedef_7
> and note that the Rails App redirects to
> https://git-scm.com/book/cs/v2/Z%C3%A1klady-pr%C3%A1ce-se-syst%C3%A9mem-Git-Zobrazen%C3%AD-historie-reviz%C3%AD/ch00/_footnotedef_7
> when clicking on the `[7]`, which 404s.
>
> Could you double-check that the links in the current version?
Since I had it already, I ran linkchecker again. It found
25 errors. I'll attach the output, though I'm not sure if
the list will pass it along or not.
It looks like a number of errors are due to '?' characters
in the generated links, e.g.:
https://git.github.io/git-scm.com/book/en/v2/Getting-Started-What-is-Git?/
Cheers,
--
Todd
[-- Attachment #2: git.github.io_git-scm.com.txt --]
[-- Type: text/plain, Size: 13508 bytes --]
LinkChecker 10.2.1
Copyright (C) 2000-2016 Bastian Kleineidam, 2010-2022 LinkChecker Authors
LinkChecker comes with ABSOLUTELY NO WARRANTY!
This is free software, and you are welcome to redistribute it under
certain conditions. Look at the file `LICENSE' within this distribution.
Read the documentation at https://linkchecker.github.io/linkchecker/
Write comments and bugs to https://github.com/linkchecker/linkchecker/issues
Start checking at 2023-11-25 18:49:01+000
URL `/git-scm.com/book/en/v2/Getting-Started-What-is-Git%3F'
Name `What is Git?'
Parent URL https://git.github.io/git-scm.com/book/en/v2, line 9, col 1
Real URL https://git.github.io/git-scm.com/book/en/v2/Getting-Started-What-is-Git?/
Check time 2.388 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/en/v2/Getting-Started-What-is-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/az/v2/Ba%c5%9flan%c4%9f%c4%b1c-Git-N%c9%99dir%3F'
Name `Git Nədir?'
Parent URL https://git.github.io/git-scm.com/book/az/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/az/v2/Ba%C5%9Flan%C4%9F%C4%B1c-Git-N%C9%99dir?/
Check time 0.074 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/az/v2/Ba%C5%9Flan%C4%9F%C4%B1c-Git-N%C9%99dir?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/de/v2/Erste-Schritte-Was-ist-Versionsverwaltung%3F'
Name `Erste Schritte'
Parent URL https://git.github.io/git-scm.com/book/de/v2, line 5, col 3159
Real URL https://git.github.io/git-scm.com/book/de/v2/Erste-Schritte-Was-ist-Versionsverwaltung?/
Check time 0.121 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/de/v2/Erste-Schritte-Was-ist-Versionsverwaltung?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/de/v2/Erste-Schritte-Was-ist-Git%3F'
Name `Was ist Git?'
Parent URL https://git.github.io/git-scm.com/book/de/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/de/v2/Erste-Schritte-Was-ist-Git?/
Check time 0.068 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/de/v2/Erste-Schritte-Was-ist-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/es/v2/Inicio---Sobre-el-Control-de-Versiones-%c2%bfC%c3%b3mo-obtener-ayuda%3F'
Name `¿Cómo obtener ayuda?'
Parent URL https://git.github.io/git-scm.com/book/es/v2, line 12, col 1
Real URL https://git.github.io/git-scm.com/book/es/v2/Inicio---Sobre-el-Control-de-Versiones-%C2%BFC%C3%B3mo-obtener-ayuda?/
Check time 0.093 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/es/v2/Inicio---Sobre-el-Control-de-Versiones-%C2%BFC%C3%B3mo-obtener-ayuda?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/es/v2/Ramificaciones-en-Git-%c2%bfQu%c3%a9-es-una-rama%3F'
Name `Ramificaciones en Git'
Parent URL https://git.github.io/git-scm.com/book/es/v2, line 21, col 111
Real URL https://git.github.io/git-scm.com/book/es/v2/Ramificaciones-en-Git-%C2%BFQu%C3%A9-es-una-rama?/
Check time 0.094 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/es/v2/Ramificaciones-en-Git-%C2%BFQu%C3%A9-es-una-rama?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/ko/v2/%ec%8b%9c%ec%9e%91%ed%95%98%ea%b8%b0-%eb%b2%84%ec%a0%84-%ea%b4%80%eb%a6%ac%eb%9e%80%3F'
Name `시작하기'
Parent URL https://git.github.io/git-scm.com/book/ko/v2, line 5, col 3159
Real URL https://git.github.io/git-scm.com/book/ko/v2/%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%AC%EB%9E%80?/
Check time 0.094 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/ko/v2/%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-%EB%B2%84%EC%A0%84-%EA%B4%80%EB%A6%AC%EB%9E%80?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/nl/v2/Aan-de-slag-Wat-is-Git%3F'
Name `Wat is Git?'
Parent URL https://git.github.io/git-scm.com/book/nl/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/nl/v2/Aan-de-slag-Wat-is-Git?/
Check time 0.070 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/nl/v2/Aan-de-slag-Wat-is-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/ru/v2/%d0%92%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%a7%d1%82%d0%be-%d1%82%d0%b0%d0%ba%d0%be%d0%b5-Git%3F'
Name `Что такое Git?'
Parent URL https://git.github.io/git-scm.com/book/ru/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-Git?/
Check time 0.075 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%A7%D1%82%D0%BE-%D1%82%D0%B0%D0%BA%D0%BE%D0%B5-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/sl/v2/Za%c4%8detek-Kaj-je-Git%3F'
Name `Kaj je Git?'
Parent URL https://git.github.io/git-scm.com/book/sl/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/sl/v2/Za%C4%8Detek-Kaj-je-Git?/
Check time 0.071 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/sl/v2/Za%C4%8Detek-Kaj-je-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/ru/v2/%d0%92%d0%b2%d0%b5%d0%b4%d0%b5%d0%bd%d0%b8%d0%b5-%d0%9a%d0%b0%d0%ba-%d0%bf%d0%be%d0%bb%d1%83%d1%87%d0%b8%d1%82%d1%8c-%d0%bf%d0%be%d0%bc%d0%be%d1%89%d1%8c%3F'
Name `Как получить помощь?'
Parent URL https://git.github.io/git-scm.com/book/ru/v2, line 12, col 1
Real URL https://git.github.io/git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9A%D0%B0%D0%BA-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C?/
Check time 0.077 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/ru/v2/%D0%92%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5-%D0%9A%D0%B0%D0%BA-%D0%BF%D0%BE%D0%BB%D1%83%D1%87%D0%B8%D1%82%D1%8C-%D0%BF%D0%BE%D0%BC%D0%BE%D1%89%D1%8C?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/sr/v2/%d0%9f%d0%be%d1%87%d0%b5%d1%82%d0%b0%d0%ba-%d0%a8%d1%82%d0%b0-%d1%98%d0%b5-%d0%93%d0%b8%d1%82%3F'
Name `Шта је Гит?'
Parent URL https://git.github.io/git-scm.com/book/sr/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/sr/v2/%D0%9F%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BA-%D0%A8%D1%82%D0%B0-%D1%98%D0%B5-%D0%93%D0%B8%D1%82?/
Check time 0.084 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/sr/v2/%D0%9F%D0%BE%D1%87%D0%B5%D1%82%D0%B0%D0%BA-%D0%A8%D1%82%D0%B0-%D1%98%D0%B5-%D0%93%D0%B8%D1%82?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/uz/v2/%d0%98%d1%88-%d0%b1%d0%be%d1%88%d0%bb%d0%b0%d0%bd%d0%b8%d1%88%d0%b8-%d2%9a%d0%b0%d0%bd%d0%b4%d0%b0%d0%b9-%d1%91%d1%80%d0%b4%d0%b0%d0%bc-%d0%be%d0%bb%d0%b8%d1%88-%d0%bc%d1%83%d0%bc%d0%ba%d0%b8%d0%bd%3F'
Name `Қандай ёрдам олиш мумкин?'
Parent URL https://git.github.io/git-scm.com/book/uz/v2, line 12, col 1
Real URL https://git.github.io/git-scm.com/book/uz/v2/%D0%98%D1%88-%D0%B1%D0%BE%D1%88%D0%BB%D0%B0%D0%BD%D0%B8%D1%88%D0%B8-%D2%9A%D0%B0%D0%BD%D0%B4%D0%B0%D0%B9-%D1%91%D1%80%D0%B4%D0%B0%D0%BC-%D0%BE%D0%BB%D0%B8%D1%88-%D0%BC%D1%83%D0%BC%D0%BA%D0%B8%D0%BD?/
Check time 0.074 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/uz/v2/%D0%98%D1%88-%D0%B1%D0%BE%D1%88%D0%BB%D0%B0%D0%BD%D0%B8%D1%88%D0%B8-%D2%9A%D0%B0%D0%BD%D0%B4%D0%B0%D0%B9-%D1%91%D1%80%D0%B4%D0%B0%D0%BC-%D0%BE%D0%BB%D0%B8%D1%88-%D0%BC%D1%83%D0%BC%D0%BA%D0%B8%D0%BD?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/be/v2/%d0%9f%d0%b5%d1%80%d1%88%d1%8b%d1%8f-%d0%ba%d1%80%d0%be%d0%ba%d1%96-What-is-Git%3F'
Name `What is Git?'
Parent URL https://git.github.io/git-scm.com/book/be/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/be/v2/%D0%9F%D0%B5%D1%80%D1%88%D1%8B%D1%8F-%D0%BA%D1%80%D0%BE%D0%BA%D1%96-What-is-Git?/
Check time 0.105 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/be/v2/%D0%9F%D0%B5%D1%80%D1%88%D1%8B%D1%8F-%D0%BA%D1%80%D0%BE%D0%BA%D1%96-What-is-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/it/v2/Per-Iniziare-Cos%e2%80%99%c3%a9-Git%3F'
Name `Cos’é Git?'
Parent URL https://git.github.io/git-scm.com/book/it/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/it/v2/Per-Iniziare-Cos%E2%80%99%C3%A9-Git?/
Check time 0.068 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/it/v2/Per-Iniziare-Cos%E2%80%99%C3%A9-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/ms/v2/Getting-Started-What-is-Git%3F'
Name `What is Git?'
Parent URL https://git.github.io/git-scm.com/book/ms/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/ms/v2/Getting-Started-What-is-Git?/
Check time 0.078 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/ms/v2/Getting-Started-What-is-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/sv/v2/Kom-ig%c3%a5ng-Vad-%c3%a4r-Git%3F'
Name `Vad är Git?'
Parent URL https://git.github.io/git-scm.com/book/sv/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/sv/v2/Kom-ig%C3%A5ng-Vad-%C3%A4r-Git?/
Check time 0.086 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/sv/v2/Kom-ig%C3%A5ng-Vad-%C3%A4r-Git?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/tr/v2/Ba%c5%9flang%c4%b1%c3%a7-Git-Nedir%3F'
Name `Git Nedir?'
Parent URL https://git.github.io/git-scm.com/book/tr/v2, line 8, col 1
Real URL https://git.github.io/git-scm.com/book/tr/v2/Ba%C5%9Flang%C4%B1%C3%A7-Git-Nedir?/
Check time 0.076 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/book/tr/v2/Ba%C5%9Flang%C4%B1%C3%A7-Git-Nedir?/'.
Result Error: 404 Not Found
URL `/git-scm.com/book/fr/v2/Les-branches-avec-Git-Branches-et-fusions'
Name `next'
Parent URL https://git.github.io/git-scm.com/book/fr/v2/Les-branches-avec-Git-Les-branches-en-bref, line 160, col 1436
Real URL https://git.github.io/git-scm.com/book/fr/v2/Les-branches-avec-Git-Branches-et-fusions
Check time 1.887 seconds
Size 1KB
Result Error: 404 Not Found
URL `/git-scm.com/docs/git-submodules'
Parent URL https://git.github.io/git-scm.com/docs/git-submodules/fr, line 2, col 1
Real URL https://git.github.io/git-scm.com/docs/git-submodules/
Check time 5.581 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/docs/git-submodules/'.
Result Error: 404 Not Found
URL `/git-scm.com/docs/git-maintainance'
Parent URL https://git.github.io/git-scm.com/docs/git-maintainance/is, line 2, col 1
Real URL https://git.github.io/git-scm.com/docs/git-maintainance/
Check time 5.867 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/docs/git-maintainance/'.
Result Error: 404 Not Found
URL `/git-scm.com/docs/gitignorar'
Parent URL https://git.github.io/git-scm.com/docs/gitignorar/pt_BR, line 2, col 1
Real URL https://git.github.io/git-scm.com/docs/gitignorar/
Check time 5.546 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/docs/gitignorar/'.
Result Error: 404 Not Found
URL `/git-scm.com/docs/git-fsmonitor----daemon'
Parent URL https://git.github.io/git-scm.com/docs/git-fsmonitor----daemon/pt_BR, line 2, col 1
Real URL https://git.github.io/git-scm.com/docs/git-fsmonitor----daemon/
Check time 5.616 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/docs/git-fsmonitor----daemon/'.
Result Error: 404 Not Found
URL `/git-scm.com/docs/git-pack'
Parent URL https://git.github.io/git-scm.com/docs/git-pack/pt_BR, line 2, col 1
Real URL https://git.github.io/git-scm.com/docs/git-pack/
Check time 4.311 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/docs/git-pack/'.
Result Error: 404 Not Found
URL `/git-scm.com/docs/git-hash'
Parent URL https://git.github.io/git-scm.com/docs/git-hash/fr, line 2, col 1
Real URL https://git.github.io/git-scm.com/docs/git-hash/
Check time 1.156 seconds
Size 1KB
Info Redirected to
`https://git.github.io/git-scm.com/docs/git-hash/'.
Result Error: 404 Not Found
Statistics:
Downloaded: 302.2MB.
Content types: 5656 image, 11838 text, 0 video, 0 audio, 15 application, 29 mail and 620 other.
URL lengths: min=15, max=841, avg=72.
That's it. 18158 links in 19951 URLs checked. 0 warnings found. 25 errors found.
Stopped checking at 2023-11-25 19:34:52+000 (45 minutes, 51 seconds)
^ permalink raw reply
* Re: Fix git-send-email.perl w.r.t. recent Getopt::Long update
From: Todd Zullinger @ 2023-11-28 2:07 UTC (permalink / raw)
To: H.Merijn Brand; +Cc: Junio C Hamano, git
In-Reply-To: <20231127093810.2092fe1d@pc09>
Hi,
H.Merijn Brand wrote:
> On Mon, 27 Nov 2023 09:58:52 +0900, Junio C Hamano <gitster@pobox.com> wrote:
>> One downside of unconditional upgrade of the call is, of course,
>> that it would no longer work for those with older Getopt::Long that
>> did not support the "!" suffix. Fortunately, Getopt::Long 2.33
>> started shipping with Perl 5.8.1 that is more than 20 years old, so
>> with the series we accepted, we also have a change to bump the
>> required version of Perl from 5.8.0 to 5.8.1 to make it clear that
>> it is deliberate that we drop the support for anything older at the
>> same time.
>
> The is a no-issue ...
>
> Just the 'use Getopt::Long' is enough to guarantee a working version:
>
> The '!' was already implemented in version 2.10 (April 1997):
> --8<---
> =item !
>
> Option does not take an argument and may be negated, i.e. prefixed by
> "no". E.g. "foo!" will allow B<--foo> (with value 1) and B<-nofoo>
> (with value 0).
> The option variable will be set to 1, or 0 if negated.
> -->8---
The real issue is the lack of support for the '--no-' prefix
when used with the '!' parameter. The '--no-' form is what
has always been documented by git-send-email(1). It was not
supported until Getopt::Long 2.33, included in perl 5.8.1.
Prior, 'foo!' provided --foo and --nofoo but not --no-foo.
But as Junio said, we can accept requiring a perl which was
released sometime in the past 2 decades in order to run the
most recent git release. ;)
Thanks for noticing this and sending a patch!
--
Todd
^ permalink raw reply
* Re: [PATCH] doc: make the gitfile syntax easier to discover
From: Marcel Krause @ 2023-11-28 5:55 UTC (permalink / raw)
To: git mailing list; +Cc: Junio C Hamano, Marcel Krause
In-Reply-To: <70125a8e-57ed-2ac6-1260-2aaa10cbc851@pimpmybyte.de>
Sorry for being slow on understanding your "git worktree add" hint.
I agree that discoverability of that command is at least as important
as discoverability of the syntax. I'll add a line about that, too.
^ permalink raw reply
* [PATCH] doc: make the gitfile syntax easier to discover
From: Marcel Krause @ 2023-11-28 6:48 UTC (permalink / raw)
To: git mailing list; +Cc: Junio C Hamano, Marcel Krause
In-Reply-To: <182d290a-86e5-b361-87a1-6860641fc726@pimpmybyte.de>
---
Documentation/gitrepository-layout.txt | 4 +++-
Documentation/glossary-content.txt | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index 1a2ef4c150..949cd8a31e 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -23,7 +23,9 @@ A Git repository comes in two different flavours:
*Note*: Also you can have a plain text file `.git` at the root of
your working tree, containing `gitdir: <path>` to point at the real
-directory that has the repository. This mechanism is often used for
+directory that has the repository.
+This mechanism is called a 'gitfile' and is usually managed via the
+`git submodule` and `git worktree` commands. It is often used for
a working tree of a submodule checkout, to allow you in the
containing superproject to `git checkout` a branch that does not
have the submodule. The `checkout` has to remove the entire
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 5a537268e2..3f912e7bb2 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -184,6 +184,8 @@ current branch integrates with) obviously do not work, as there is no
[[def_gitfile]]gitfile::
A plain file `.git` at the root of a working tree that
points at the directory that is the real repository.
+ For proper use see linkgit:git-worktree[1] or linkgit:git-submodule[1].
+ For syntax see linkgit:gitrepository-layout[5].
[[def_grafts]]grafts::
Grafts enables two otherwise different lines of development to be joined
--
2.25.1
^ permalink raw reply related
* [PATCH] doc: make the gitfile syntax easier to discover
From: Marcel Krause @ 2023-11-28 6:55 UTC (permalink / raw)
To: git mailing list; +Cc: Junio C Hamano, Marcel Krause
In-Reply-To: <182d290a-86e5-b361-87a1-6860641fc726@pimpmybyte.de>
Signed-off-by: Marcel Krause <mk+copyleft@pimpmybyte.de>
---
Documentation/gitrepository-layout.txt | 4 +++-
Documentation/glossary-content.txt | 2 ++
2 files changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt
index 1a2ef4c150..949cd8a31e 100644
--- a/Documentation/gitrepository-layout.txt
+++ b/Documentation/gitrepository-layout.txt
@@ -23,7 +23,9 @@ A Git repository comes in two different flavours:
*Note*: Also you can have a plain text file `.git` at the root of
your working tree, containing `gitdir: <path>` to point at the real
-directory that has the repository. This mechanism is often used for
+directory that has the repository.
+This mechanism is called a 'gitfile' and is usually managed via the
+`git submodule` and `git worktree` commands. It is often used for
a working tree of a submodule checkout, to allow you in the
containing superproject to `git checkout` a branch that does not
have the submodule. The `checkout` has to remove the entire
diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt
index 5a537268e2..3f912e7bb2 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -184,6 +184,8 @@ current branch integrates with) obviously do not work, as there is no
[[def_gitfile]]gitfile::
A plain file `.git` at the root of a working tree that
points at the directory that is the real repository.
+ For proper use see linkgit:git-worktree[1] or linkgit:git-submodule[1].
+ For syntax see linkgit:gitrepository-layout[5].
[[def_grafts]]grafts::
Grafts enables two otherwise different lines of development to be joined
--
2.25.1
^ permalink raw reply related
* Re: --end-of-options inconsistently available?!
From: Sven Strickroth @ 2023-11-28 8:40 UTC (permalink / raw)
To: Jeff King; +Cc: git
In-Reply-To: <20231127212254.GA87495@coredump.intra.peff.net>
Am 27.11.2023 um 22:22 schrieb Jeff King:
>> $ git rev-parse --symbolic-full-name --end-of-options master
>> --end-of-options
>> refs/heads/master
>>
>> Here, the output also contains "--end-of-options" as if it is a reference
>> (same for "--")
>
> This one is intentional. rev-parse in its default mode is not just
> spitting out revisions, but also options that are meant to be passed
> along to the revision machinery via other commands (like rev-list). So
> for example:
>
> $ git rev-parse --foo HEAD
> --foo
> 564d0252ca632e0264ed670534a51d18a689ef5d
>
> And it does understand end-of-options explicitly, so:
>
> $ git rev-parse --end-of-options --foo --
> --end-of-options
> fatal: bad revision '--foo'
>
> If you just want to parse a name robustly, use --verify.
I would expect that -- and --end-of-options are handled in a special way
here so that rev-parse can also be used in scripts. I need to check
whether --verify works for me (from the manual I thought I need to
specify full reference names).
>> $ git checkout -f --end-of-options HEAD~1 -- afile.txt
>> fatal: only one reference expected, 2 given.
>
> I think this is the same KEEP_DASHDASH problem as with git-reset.
I also found another problem:
$ git format-patch --end-of-options -1
fatal: option '-1' must come before non-option arguments
Where -1 is the number of commits here...
Best,
Sven
^ permalink raw reply
* Re: [PATCH] i18n: factorize even more 'incompatible options' messages
From: Patrick Steinhardt @ 2023-11-28 12:33 UTC (permalink / raw)
To: René Scharfe
Cc: Eric Sunshine, Jean-Noël Avila, Junio C Hamano, Git List
In-Reply-To: <d1f28272-635d-4638-b0f4-76d64013b0d5@web.de>
[-- Attachment #1: Type: text/plain, Size: 4338 bytes --]
On Mon, Nov 27, 2023 at 06:39:41PM +0100, René Scharfe wrote:
> Am 26.11.23 um 18:49 schrieb Eric Sunshine:
> > On Sun, Nov 26, 2023 at 6:57 AM René Scharfe <l.s.r@web.de> wrote:
> >> Continue the work of 12909b6b8a (i18n: turn "options are incompatible"
> >> into "cannot be used together", 2022-01-05) and a699367bb8 (i18n:
> >> factorize more 'incompatible options' messages, 2022-01-31) to use the
> >> same parameterized error message for reporting incompatible command line
> >> options. This reduces the number of strings to translate and makes the
> >> UI slightly more consistent.
> >
> > Thanks for tackling this.
> >
> > A couple additional instances recently slipped into `show-ref.c` which
> > were caught during review[1,2] but nevertheless made it to
> > "master"[3,4]. This patch, of course, doesn't need to address those,
> > but if rerolling for some other reason, perhaps they can be included,
> > as well(?).
Ah, I wasn't aware of these new wrappers, either. The below patch looks
good to me, thanks for the fixup.
Patrick
> > [1]: https://lore.kernel.org/git/CAPig+cSrp7vZuy7D_ENHKZKZzF4OSmCtfYNHPGMtS1Hj6gArDw@mail.gmail.com/
> > [2]: https://lore.kernel.org/git/CAPig+cRTOMie0rUf=Mhbo9e2EXf-_2kQyMeqpB9OCRB1MZZ1rw@mail.gmail.com/
> > [3]: 199970e72f (builtin/show-ref: ensure mutual exclusiveness of
> > subcommands, 2023-10-31)
> > [4]: 9080a7f178 (builtin/show-ref: add new mode to check for reference
> > existence, 2023-10-31)
>
> [4] changes the message added by [3], so that's one instance, right?
>
> --- >8 ---
> Subject: [PATCH] show-ref: use die_for_incompatible_opt3()
>
> Use the standard message for reporting the use of multiple mutually
> exclusive options by calling die_for_incompatible_opt3() instead of
> rolling our own. This has the benefits of showing only the actually
> given options, reducing the number of strings to translate and making
> the UI slightly more consistent.
>
> Adjust the test to no longer insist on a specific order of the
> reported options, as this implementation detail does not affect the
> usefulness of the error message.
>
> Reported-by: Eric Sunshine <sunshine@sunshineco.com>
> Signed-off-by: René Scharfe <l.s.r@web.de>
> ---
> builtin/show-ref.c | 6 +++---
> t/t1403-show-ref.sh | 16 +++++++++-------
> 2 files changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/builtin/show-ref.c b/builtin/show-ref.c
> index 7aac525a87..59d2291cbf 100644
> --- a/builtin/show-ref.c
> +++ b/builtin/show-ref.c
> @@ -315,9 +315,9 @@ int cmd_show_ref(int argc, const char **argv, const char *prefix)
> argc = parse_options(argc, argv, prefix, show_ref_options,
> show_ref_usage, 0);
>
> - if ((!!exclude_existing_opts.enabled + !!verify + !!exists) > 1)
> - die(_("only one of '%s', '%s' or '%s' can be given"),
> - "--exclude-existing", "--verify", "--exists");
> + die_for_incompatible_opt3(exclude_existing_opts.enabled, "--exclude-existing",
> + verify, "--verify",
> + exists, "--exists");
>
> if (exclude_existing_opts.enabled)
> return cmd_show_ref__exclude_existing(&exclude_existing_opts);
> diff --git a/t/t1403-show-ref.sh b/t/t1403-show-ref.sh
> index b50ae6fcf1..d477689e33 100755
> --- a/t/t1403-show-ref.sh
> +++ b/t/t1403-show-ref.sh
> @@ -197,18 +197,20 @@ test_expect_success 'show-ref --verify with dangling ref' '
> '
>
> test_expect_success 'show-ref sub-modes are mutually exclusive' '
> - cat >expect <<-EOF &&
> - fatal: only one of ${SQ}--exclude-existing${SQ}, ${SQ}--verify${SQ} or ${SQ}--exists${SQ} can be given
> - EOF
> -
> test_must_fail git show-ref --verify --exclude-existing 2>err &&
> - test_cmp expect err &&
> + grep "verify" err &&
> + grep "exclude-existing" err &&
> + grep "cannot be used together" err &&
>
> test_must_fail git show-ref --verify --exists 2>err &&
> - test_cmp expect err &&
> + grep "verify" err &&
> + grep "exists" err &&
> + grep "cannot be used together" err &&
>
> test_must_fail git show-ref --exclude-existing --exists 2>err &&
> - test_cmp expect err
> + grep "exclude-existing" err &&
> + grep "exists" err &&
> + grep "cannot be used together" err
> '
>
> test_expect_success '--exists with existing reference' '
> --
> 2.43.0
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply
* Re: [PATCH] completion: add and use the __git_get_config_subsection helper function
From: SZEDER Gábor @ 2023-11-28 12:40 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Philippe Blain
In-Reply-To: <xmqqzfzh16qp.fsf@gitster.g>
On Tue, Nov 14, 2023 at 10:08:46AM +0900, Junio C Hamano wrote:
> SZEDER Gábor <szeder.dev@gmail.com> writes:
>
> > +# Lists all subsections in the given section which contain the given
> > +# config variable, with the section and variable names removed.
> > +__git_get_config_subsections ()
> > +{
> > + local section="$1" var="$2" i IFS=$'\n'
> > + for i in $(__git config --name-only --get-regexp "^$section\..*\.$var$"); do
> > + i=${i#$section.}
> > + i=${i%.$var}
>
> As this script is allowed bash-isms, I wondered if we can use
> a single pattern substitution instead of two remove pre/suffix
> pattern substitution, but I guess it would not work, and the above
> is perfectly readable.
Yeah, I don't think it's possible to remove the prefix and suffix with
Bash builtins in a single operation.
> > + echo "$i"
>
> As the subsection is designed to contain unbounded set of end-user
> controlled names, we probably should do
>
> printf "%s\n" "$i"
>
> instead to protect us from interesting names (e.g. ones that begin
> with a dash).
Indeed, will do.
> > + done
> > +}
>
> Interesting to see that we do not need to bother deduplicating the
> output from here.
Bash will sort and deduplicate the completion words anyway, so we
don't have to. Sometimes we do deduplicate them, though, but either
to make testing easier or for performance reasons; in this case
neither of them applies.
> > diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
> > index a7c3b4eb63..11ed83d0ed 100755
> > --- a/t/t9902-completion.sh
> > +++ b/t/t9902-completion.sh
> > @@ -2130,6 +2130,19 @@ test_expect_success '__git_get_config_variables' '
> > test_cmp expect actual
> > '
> >
> > +test_expect_success '__git_get_config_subsections' '
> > + cat >expect <<-\EOF &&
> > + subsection-1
> > + SubSection-2
> > + sub.section.3
> > + EOF
> > + test_config interesting.subsection-1.name good &&
> > + test_config Interesting.SubSection-2.Name good &&
> > + test_config interesting.sub.section.3.name good &&
> > + __git_get_config_subsections interesting name >actual &&
> > + test_cmp expect actual
> > +'
>
> Good to see an uppercase character is used here ;-).
That's just for good measure, but not really necessasry here, as that
primarily tests that 'git config' lists the section and variable names
(but not the subsection!) normalized to lowercase, no matter what
CaMeLCase the user might have written them.
^ permalink raw reply
* Re: [PATCH] setup: recognize bare repositories with packed-refs
From: Adam Majer @ 2023-11-28 14:14 UTC (permalink / raw)
To: Josh Steadmon, git
In-Reply-To: <ZWTxuBV1DGieo6n2@google.com>
On 11/27/23 20:44, Josh Steadmon wrote:> Two suggestions for the test here:
> 1) Can you give the test a more descriptive name, such as "GCed bare
> repos still recognized"?
Thanks, adjusted. I've also added that empty refs/ directory is not there.
> 2) Can you add a check that bare.git/packed-refs exists?
Done.
I've also removed the -C parameter since we actually need GIT_DIR= in
all cases to prevent git from going up directory tree. -C is then
superflous. In addition, I've changed the hardcoded object id to master
branch to make it less magical looking.
- Adam
^ permalink raw reply
* [PATCH] setup: recognize bare repositories with packed-refs
From: Adam Majer @ 2023-11-28 14:28 UTC (permalink / raw)
To: git; +Cc: Adam Majer
In-Reply-To: <20231117203253.21143-1-adamm@zombino.com>
In a garbage collected bare git repository, the refs/ subdirectory is
empty. In use-cases when such a repository is directly added into
another repository, it no longer is detected as valid. Git doesn't
preserve empty paths so refs/ subdirectory is not present. Simply
creating an empty refs/ subdirectory fixes this problem.
Looking more carefully, there are two backends to handle various refs in
git -- the files backend that uses refs/ subdirectory and the
packed-refs backend that uses packed-refs file. If references are not
found in refs/ subdirectory (or directory doesn't exist), the
packed-refs directory will be consulted. Garbage collected repository
will have all its references in packed-refs file.
To allow the use-case when packed-refs is the only source of refs and
refs/ subdirectory is simply not present, augment 'is_git_directory()'
setup function to look for packed-refs file as an alternative to refs/
subdirectory.
Signed-off-by: Adam Majer <adamm@zombino.com>
---
setup.c | 10 +++++++---
t/t6500-gc.sh | 9 +++++++++
2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/setup.c b/setup.c
index fc592dc6dd..2a6dda6ae9 100644
--- a/setup.c
+++ b/setup.c
@@ -348,7 +348,7 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
*
* - either an objects/ directory _or_ the proper
* GIT_OBJECT_DIRECTORY environment variable
- * - a refs/ directory
+ * - a refs/ directory or packed-refs file
* - either a HEAD symlink or a HEAD file that is formatted as
* a proper "ref:", or a regular file HEAD that has a properly
* formatted sha1 object name.
@@ -384,8 +384,12 @@ int is_git_directory(const char *suspect)
strbuf_setlen(&path, len);
strbuf_addstr(&path, "/refs");
- if (access(path.buf, X_OK))
- goto done;
+ if (access(path.buf, X_OK)) {
+ strbuf_setlen(&path, len);
+ strbuf_addstr(&path, "/packed-refs");
+ if (access(path.buf, R_OK))
+ goto done;
+ }
ret = 1;
done:
diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
index 18fe1c25e6..4ad1690817 100755
--- a/t/t6500-gc.sh
+++ b/t/t6500-gc.sh
@@ -214,6 +214,15 @@ test_expect_success 'gc.repackFilter launches repack with a filter' '
grep -E "^trace: (built-in|exec|run_command): git repack .* --filter=blob:none ?.*" trace.out
'
+test_expect_success 'GCed bare repos without empty refs/ still recognized' '
+ GIT_DIR="$PWD"/bare.git git cat-file -e master &&
+ test_dir_is_empty bare.git/refs/heads &&
+ test_dir_is_empty bare.git/refs/tags &&
+ test_file_not_empty bare.git/packed-refs &&
+ rm -r bare.git/refs &&
+ GIT_DIR="$PWD"/bare.git git cat-file -e master
+'
+
test_expect_success 'gc.repackFilterTo store filtered out objects' '
test_when_finished "rm -rf bare.git filtered.git" &&
--
2.43.0.1.g67290e5b65
^ permalink raw reply related
* Re: Submodule update fetching with outer repo's default branch
From: Ricardo Abreu @ 2023-11-28 18:32 UTC (permalink / raw)
To: scott; +Cc: git
In-Reply-To: <111c2777-6fd4-45ab-8418-9d064999661c@app.fastmail.com>
I have the same problem. Here is a generic recipe to reproduce, assuming a repository X with a submodule Y (set with an `https` URL):
1. `git clone ... X`
2. `cd X`
3. `git submodule sync`
4. `git submodule update --init --recursive`
5. `git remote rename origin remotex` # rename the remote in X, not Y
6. Elsewhere, add a new commit to Y and create a branch "update-y" in X, pointing the submodule to that commit. Suppose the hash of the new commit in Y is `abc1abc`.
7. `git fetch remotex`
8. `git checkout update-y`
9. `git submodule sync`
10. `GIT_TRACE=1 git submodule update --init --recursive`
- observe:
* the command in the last trace message to be `git fetch remotex abc1abc` (should be `git fetch origin abc1abc`, because that is still the name of the submodule's remote)
* the wrong error message complaining about 'file' protocol (which isn't involved anywhere)
^ permalink raw reply
* Re: [PATCH] setup: recognize bare repositories with packed-refs
From: Josh Steadmon @ 2023-11-28 18:45 UTC (permalink / raw)
To: Adam Majer; +Cc: git
In-Reply-To: <20231128142845.11523-1-adamm@zombino.com>
On 2023.11.28 15:28, Adam Majer wrote:
> In a garbage collected bare git repository, the refs/ subdirectory is
> empty. In use-cases when such a repository is directly added into
> another repository, it no longer is detected as valid. Git doesn't
> preserve empty paths so refs/ subdirectory is not present. Simply
> creating an empty refs/ subdirectory fixes this problem.
>
> Looking more carefully, there are two backends to handle various refs in
> git -- the files backend that uses refs/ subdirectory and the
> packed-refs backend that uses packed-refs file. If references are not
> found in refs/ subdirectory (or directory doesn't exist), the
> packed-refs directory will be consulted. Garbage collected repository
> will have all its references in packed-refs file.
>
> To allow the use-case when packed-refs is the only source of refs and
> refs/ subdirectory is simply not present, augment 'is_git_directory()'
> setup function to look for packed-refs file as an alternative to refs/
> subdirectory.
>
> Signed-off-by: Adam Majer <adamm@zombino.com>
> ---
> setup.c | 10 +++++++---
> t/t6500-gc.sh | 9 +++++++++
> 2 files changed, 16 insertions(+), 3 deletions(-)
>
> diff --git a/setup.c b/setup.c
> index fc592dc6dd..2a6dda6ae9 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -348,7 +348,7 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
> *
> * - either an objects/ directory _or_ the proper
> * GIT_OBJECT_DIRECTORY environment variable
> - * - a refs/ directory
> + * - a refs/ directory or packed-refs file
> * - either a HEAD symlink or a HEAD file that is formatted as
> * a proper "ref:", or a regular file HEAD that has a properly
> * formatted sha1 object name.
> @@ -384,8 +384,12 @@ int is_git_directory(const char *suspect)
>
> strbuf_setlen(&path, len);
> strbuf_addstr(&path, "/refs");
> - if (access(path.buf, X_OK))
> - goto done;
> + if (access(path.buf, X_OK)) {
> + strbuf_setlen(&path, len);
> + strbuf_addstr(&path, "/packed-refs");
> + if (access(path.buf, R_OK))
> + goto done;
> + }
>
> ret = 1;
> done:
> diff --git a/t/t6500-gc.sh b/t/t6500-gc.sh
> index 18fe1c25e6..4ad1690817 100755
> --- a/t/t6500-gc.sh
> +++ b/t/t6500-gc.sh
> @@ -214,6 +214,15 @@ test_expect_success 'gc.repackFilter launches repack with a filter' '
> grep -E "^trace: (built-in|exec|run_command): git repack .* --filter=blob:none ?.*" trace.out
> '
>
> +test_expect_success 'GCed bare repos without empty refs/ still recognized' '
> + GIT_DIR="$PWD"/bare.git git cat-file -e master &&
> + test_dir_is_empty bare.git/refs/heads &&
> + test_dir_is_empty bare.git/refs/tags &&
> + test_file_not_empty bare.git/packed-refs &&
> + rm -r bare.git/refs &&
> + GIT_DIR="$PWD"/bare.git git cat-file -e master
> +'
> +
> test_expect_success 'gc.repackFilterTo store filtered out objects' '
> test_when_finished "rm -rf bare.git filtered.git" &&
>
> --
> 2.43.0.1.g67290e5b65
Thanks for the fixes. This looks good to me. BTW, in the future please
add a version number when you send updated patches (e.g. add "-v 2" to
your command-line if you're using git-format-patch).
Reviewed-by: Josh Steadmon <steadmon@google.com>
^ permalink raw reply
* Re: [PATCH] setup: recognize bare repositories with packed-refs
From: Jeff King @ 2023-11-28 19:04 UTC (permalink / raw)
To: Adam Majer; +Cc: git
In-Reply-To: <20231128142845.11523-1-adamm@zombino.com>
On Tue, Nov 28, 2023 at 03:28:45PM +0100, Adam Majer wrote:
> In a garbage collected bare git repository, the refs/ subdirectory is
> empty. In use-cases when such a repository is directly added into
> another repository, it no longer is detected as valid. Git doesn't
> preserve empty paths so refs/ subdirectory is not present. Simply
> creating an empty refs/ subdirectory fixes this problem.
I understand your use case, but I still have a vague feeling that this
is bending some assumptions in a way that may create problems or
confusion later. In particular:
> Looking more carefully, there are two backends to handle various refs in
> git -- the files backend that uses refs/ subdirectory and the
> packed-refs backend that uses packed-refs file. If references are not
> found in refs/ subdirectory (or directory doesn't exist), the
> packed-refs directory will be consulted. Garbage collected repository
> will have all its references in packed-refs file.
This second paragraph doesn't seem totally accurate to me. There are not
really two backends that Git can use. For production use, there is just
one, the "files" backend, which happens to also use packed-refs under
the hood (and a convenient way for the code to structure this was a
subordinate backend). But it has never been possible to have a repo that
just uses packed-refs.
There is also the experimental reftable, of course. And there we have
not yet loosened is_git_directory(), and it has to create an unused
"refs/" directory (there has been some discussion about allowing it to
be an empty file, though no patches have been merged).
So with regards to the loosening in your patch, my questions would be:
- if we are going to change the rules for repository detection, is
this where we want to end up? We haven't changed them (yet) for
reftables. If we are going to do so, should we have a scheme that
will work for that transition, too? The "refs is an empty file"
scheme would fix your use case, too (though see below).
- is the rest of Git ready to handle a missing "refs/" directory? It
looks like making a ref will auto-create it (since we may have to
make refs/foo/bar/... anyway).
- what about other implementations? Your embedded repos will
presumably not work with libgit2, jgit, etc, until they also get
similar patches.
- what about empty repositories? In that case there will be no "refs/"
file and no "packed-refs" file (such a repository is less likely, of
course, but it may contain objects but no refs, or the point may be
to have an empty repo as a test vector). Likewise, it is possible
for a repository to have an empty "objects" directory (even with a
non-empty refs directory, if there are only symrefs), and your patch
doesn't address that.
> To allow the use-case when packed-refs is the only source of refs and
> refs/ subdirectory is simply not present, augment 'is_git_directory()'
> setup function to look for packed-refs file as an alternative to refs/
> subdirectory.
Getting back to your use case, I'd suggest one of:
- do the usual "touch refs/.gitignore" trick to explicitly track the
empty directory. It looks like the ref code will ignore this (we
don't allow ref names to start with "." in a path component)
- whatever is consuming the embedded repos could "mkdir -p refs
objects" as needed. This is a minor pain, but I think in the long
term we are moving to a world where you have to explicitly do
"GIT_DIR=$PWD/embedded.git" to access an embedded bare repo. So
they're already special and require some setup; adding an extra step
may not be so bad.
Now it may be that neither of those solutions is acceptable for various
reasons. But it is probably worth detailing those reasons in your commit
message.
-Peff
^ permalink raw reply
* [PATCH 00/24] pack-objects: multi-pack verbatim reuse
From: Taylor Blau @ 2023-11-28 19:07 UTC (permalink / raw)
To: git; +Cc: Jeff King, Patrick Steinhardt, Junio C Hamano
Back in fff42755ef (pack-bitmap: add support for bitmap indexes,
2013-12-21), we added support for reachability bitmaps, and taught
pack-objects how to reuse verbatim chunks from the bitmapped pack. When
multi-pack bitmaps were introduced, this pack-reuse mechanism evolved to
use the MIDX's "preferred" pack as the source for verbatim reuse.
This allows repositories to incrementally repack themselves (e.g., using
a `--geometric` repack), storing the result in a MIDX, and generating a
corresponding bitmap. This keeps our bitmap coverage up-to-date, while
maintaining a relatively small number of packs.
However, it is recommended (and matches what we do in production at
GitHub) that repositories repack themselves all-into-one, and
generate a corresponding single-pack reachability bitmap. This is done
for a couple of reasons, but the most relevant one to this series is
that it enables us to perform verbatim pack-reuse over a complete copy
of the repository, since the entire repository resides in a single pack
(and thus is eligible for verbatim pack-reuse).
As repositories grow larger, packing their contents into a single pack
becomes less feasible. This series extends the pack-reuse mechanism to
operate over multiple packs which are known ahead of time to be disjoint
with respect to one another's set of objects.
The implementation has a few components:
- A new MIDX chunk called "Disjoint packfiles" or DISP is introduced
to keep track of the bitmap position, number of objects, and
disjointed-ness for each pack contained in the MIDX.
- A new mode for `git multi-pack-index write --stdin-packs` that
allows specifying disjoint packs, as well as a new option
`--retain-disjoint` which preserves the set of existing disjoint
packs in the new MIDX.
- A new pack-objects mode `--ignore-disjoint`, which produces packs
which are disjoint with respect to the current set of disjoint packs
(i.e. it discards any objects from the packing list which appear in
any of the known-disjoint packs).
- A new repack mode, `--extend-disjoint` which causes any new pack(s)
which are generated to be disjoint with respect to the set of packs
currently marked as disjoint, minus any pack(s) which are about to
be deleted.
With all of that in place, the patch series then rewrites all of the
pack-reuse functions in terms of the new `bitmapped_pack` structure.
Once we have dropped all of the assumptions stemming from only
performing pack-reuse over a single candidate pack, we can then enable
reuse over all of the disjoint packs.
In addition to the many new tests in t5332 added by that series, I tried
to simulate a "real world" test on git.git by breaking the repository
into chunks of 1,000 commits (plus their set of reachable objects not
reachable from earlier chunk(s)) and packing those chunks. This produces
a large number of packs with the objects from git.git which are known to
be disjoint with respect to one another.
$ git clone git@github.com:git/git.git base
$ cd base
$ mv .git/objects/pack/pack-*.idx{,.bak}
$ git unpack-objects <.git/objects/pack/pack-*.pack
# pack the objects from each successive block of 1k commits
$ for rev in $(git rev-list --all | awk '(NR) % 1000 == 0' | tac)
do
echo $rev |
git.compile pack-objects --revs --unpacked .git/objects/pack/pack || return 1
done
# and grab any stragglers, pruning the unpacked objects
$ git repack -d
I then constructed a MIDX and corresponding bitmap
$ find_pack () {
for idx in .git/objects/pack/pack-*.idx
do
git show-index <$idx | grep -q "$1" && basename $idx
done
}
$ preferred="$(find_pack $(git rev-parse HEAD))"
$ ( cd .git/objects/pack && ls -1 *.idx ) | sed -e 's/^/+/g' |
git.compile multi-pack-index write --bitmap --stdin-packs \
--preferred-pack=$preferred
$ git for-each-ref --format='%(objectname)' refs/heads refs/tags >in
With all of that in place, I was able to produce a significant speed-up
by reusing objects from multiple packs:
$ hyperfine -L v single,multi -n '{v}-pack reuse' 'git.compile -c pack.allowPackReuse={v} pack-objects --revs --stdout --use-bitmap-index --delta-base-offset <in >/dev/null'
Benchmark 1: single-pack reuse
Time (mean ± σ): 6.094 s ± 0.023 s [User: 43.723 s, System: 0.358 s]
Range (min … max): 6.063 s … 6.126 s 10 runs
Benchmark 2: multi-pack reuse
Time (mean ± σ): 906.5 ms ± 3.2 ms [User: 1081.5 ms, System: 30.9 ms]
Range (min … max): 903.5 ms … 912.7 ms 10 runs
Summary
multi-pack reuse ran
6.72 ± 0.03 times faster than single-pack reuse
(There are corresponding tests in p5332 that test different sized chunks
and measure the runtime performance as well as resulting pack size).
Performing verbatim pack reuse naturally trades off between CPU time and
the resulting pack size. In the above example, the single-pack reuse
case produces a clone size of ~194 MB on my machine, while the
multi-pack reuse case produces a clone size closer to ~266 MB, which is
a ~37% increase in clone size.
I think there is still some opportunity to close this gap, since the
"packing" strategy here is extremely naive. In a production setting, I'm
sure that there are more well thought out repacking strategies that
would produce more similar clone sizes.
I considered breaking this series up into smaller chunks, but was
unsatisfied with the result. Since this series is rather large, if you
have alternate suggestions on better ways to structure this, please let
me know.
Thanks in advance for your review!
Taylor Blau (24):
pack-objects: free packing_data in more places
pack-bitmap-write: deep-clear the `bb_commit` slab
pack-bitmap: plug leak in find_objects()
midx: factor out `fill_pack_info()`
midx: implement `DISP` chunk
midx: implement `midx_locate_pack()`
midx: implement `--retain-disjoint` mode
pack-objects: implement `--ignore-disjoint` mode
repack: implement `--extend-disjoint` mode
pack-bitmap: pass `bitmapped_pack` struct to pack-reuse functions
pack-bitmap: simplify `reuse_partial_packfile_from_bitmap()` signature
pack-bitmap: return multiple packs via
`reuse_partial_packfile_from_bitmap()`
pack-objects: parameterize pack-reuse routines over a single pack
pack-objects: keep track of `pack_start` for each reuse pack
pack-objects: pass `bitmapped_pack`'s to pack-reuse functions
pack-objects: prepare `write_reused_pack()` for multi-pack reuse
pack-objects: prepare `write_reused_pack_verbatim()` for multi-pack
reuse
pack-objects: include number of packs reused in output
pack-bitmap: prepare to mark objects from multiple packs for reuse
pack-objects: add tracing for various packfile metrics
t/test-lib-functions.sh: implement `test_trace2_data` helper
pack-objects: allow setting `pack.allowPackReuse` to "single"
pack-bitmap: reuse objects from all disjoint packs
t/perf: add performance tests for multi-pack reuse
Documentation/config/pack.txt | 8 +-
Documentation/git-multi-pack-index.txt | 12 ++
Documentation/git-pack-objects.txt | 8 +
Documentation/git-repack.txt | 12 ++
Documentation/gitformat-pack.txt | 109 ++++++++++
builtin/multi-pack-index.c | 13 +-
builtin/pack-objects.c | 200 +++++++++++++++----
builtin/repack.c | 57 +++++-
midx.c | 218 +++++++++++++++++---
midx.h | 11 +-
pack-bitmap-write.c | 9 +-
pack-bitmap.c | 265 ++++++++++++++++++++-----
pack-bitmap.h | 18 +-
pack-objects.c | 15 ++
pack-objects.h | 1 +
t/helper/test-read-midx.c | 31 ++-
t/lib-disjoint.sh | 49 +++++
t/perf/p5332-multi-pack-reuse.sh | 81 ++++++++
t/t5319-multi-pack-index.sh | 140 +++++++++++++
t/t5331-pack-objects-stdin.sh | 156 +++++++++++++++
t/t5332-multi-pack-reuse.sh | 219 ++++++++++++++++++++
t/t6113-rev-list-bitmap-filters.sh | 2 +
t/t7700-repack.sh | 4 +-
t/t7705-repack-extend-disjoint.sh | 142 +++++++++++++
t/test-lib-functions.sh | 14 ++
25 files changed, 1650 insertions(+), 144 deletions(-)
create mode 100644 t/lib-disjoint.sh
create mode 100755 t/perf/p5332-multi-pack-reuse.sh
create mode 100755 t/t5332-multi-pack-reuse.sh
create mode 100755 t/t7705-repack-extend-disjoint.sh
base-commit: 564d0252ca632e0264ed670534a51d18a689ef5d
--
2.43.0.24.g980b318f98
^ permalink raw reply
* [PATCH 01/24] pack-objects: free packing_data in more places
From: Taylor Blau @ 2023-11-28 19:07 UTC (permalink / raw)
To: git; +Cc: Jeff King, Patrick Steinhardt, Junio C Hamano
In-Reply-To: <cover.1701198172.git.me@ttaylorr.com>
The pack-objects internals use a packing_data struct to track what
objects are part of the pack(s) being formed.
Since these structures contain allocated fields, failing to
appropriately free() them results in a leak. Plug that leak by
introducing a free_packing_data() function, and call it in the
appropriate spots.
This is a fairly straightforward leak to plug, since none of the callers
expect to read any values or have any references to parts of the address
space being freed.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
---
builtin/pack-objects.c | 1 +
midx.c | 5 +++++
pack-objects.c | 15 +++++++++++++++
pack-objects.h | 1 +
4 files changed, 22 insertions(+)
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c
index 89a8b5a976..bfa60359d4 100644
--- a/builtin/pack-objects.c
+++ b/builtin/pack-objects.c
@@ -4522,6 +4522,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
reuse_packfile_objects);
cleanup:
+ free_packing_data(&to_pack);
list_objects_filter_release(&filter_options);
strvec_clear(&rp);
diff --git a/midx.c b/midx.c
index 2f3863c936..3b727dc633 100644
--- a/midx.c
+++ b/midx.c
@@ -1592,8 +1592,13 @@ static int write_midx_internal(const char *object_dir,
flags) < 0) {
error(_("could not write multi-pack bitmap"));
result = 1;
+ free_packing_data(&pdata);
+ free(commits);
goto cleanup;
}
+
+ free_packing_data(&pdata);
+ free(commits);
}
/*
* NOTE: Do not use ctx.entries beyond this point, since it might
diff --git a/pack-objects.c b/pack-objects.c
index f403ca6986..1c7bedcc94 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -151,6 +151,21 @@ void prepare_packing_data(struct repository *r, struct packing_data *pdata)
init_recursive_mutex(&pdata->odb_lock);
}
+void free_packing_data(struct packing_data *pdata)
+{
+ if (!pdata)
+ return;
+
+ free(pdata->cruft_mtime);
+ free(pdata->in_pack);
+ free(pdata->in_pack_by_idx);
+ free(pdata->in_pack_pos);
+ free(pdata->index);
+ free(pdata->layer);
+ free(pdata->objects);
+ free(pdata->tree_depth);
+}
+
struct object_entry *packlist_alloc(struct packing_data *pdata,
const struct object_id *oid)
{
diff --git a/pack-objects.h b/pack-objects.h
index 0d78db40cb..336217e8cd 100644
--- a/pack-objects.h
+++ b/pack-objects.h
@@ -169,6 +169,7 @@ struct packing_data {
};
void prepare_packing_data(struct repository *r, struct packing_data *pdata);
+void free_packing_data(struct packing_data *pdata);
/* Protect access to object database */
static inline void packing_data_lock(struct packing_data *pdata)
--
2.43.0.24.g980b318f98
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox