* Bug: diff --no-index with cachetextconv crashes
@ 2024-02-26 7:03 Paweł Dominiak
2024-02-26 7:22 ` Jeff King
0 siblings, 1 reply; 5+ messages in thread
From: Paweł Dominiak @ 2024-02-26 7:03 UTC (permalink / raw)
To: git
Hey!
That's my first bug report for git and my first email to a mailing
list in general, I hope for understanding :)
[Steps to reproduce your issue]
Global .gitattributes:
*.txt diff=test
Global .gitconfig:
[diff "test"]
textconv = cat
cachetextconv = true
Called command:
git --no-pager diff --no-index foo.txt bar.txt
[Expected behavior]
diff --git a/foo.txt b/bar.txt
index f6a4b70..2b24d27 100644
--- a/foo.txt
+++ b/bar.txt
@@ -1 +1 @@
-Foo bar baz
+Foo bar qux
[Actual behavior]
BUG: refs.c:2095: attempting to get main_ref_store outside of repository
The command works as expected if cachetextconv is disabled:
git --no-pager -c diff.test.cachetextconv=false diff --no-index foo.txt bar.txt
[System Info]
git version 2.44.0.windows.1
cpu: x86_64
built from commit: ad0bbfffa543db6979717be96df630d3e5741331
sizeof-long: 4
sizeof-size_t: 8
shell-path: /bin/sh
feature: fsmonitor--daemon
uname: Windows 10.0 19045
compiler info: gnuc: 13.2
libc info: no libc information available
$SHELL (typically, interactive shell): C:\Program Files\Git\usr\bin\bash.exe
[Enabled Hooks]
not run from a git repository - no hooks to show
Pawel
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: Bug: diff --no-index with cachetextconv crashes
2024-02-26 7:03 Bug: diff --no-index with cachetextconv crashes Paweł Dominiak
@ 2024-02-26 7:22 ` Jeff King
2024-02-26 7:56 ` Paweł Dominiak
0 siblings, 1 reply; 5+ messages in thread
From: Jeff King @ 2024-02-26 7:22 UTC (permalink / raw)
To: Paweł Dominiak; +Cc: git
On Mon, Feb 26, 2024 at 08:03:04AM +0100, Paweł Dominiak wrote:
> That's my first bug report for git and my first email to a mailing
> list in general, I hope for understanding :)
Hi, welcome, and thanks for a clear bug report. :)
> [Steps to reproduce your issue]
>
> Global .gitattributes:
>
> *.txt diff=test
>
> Global .gitconfig:
>
> [diff "test"]
> textconv = cat
> cachetextconv = true
>
> Called command:
>
> git --no-pager diff --no-index foo.txt bar.txt
OK, I would say that this failing is semi-expected. :) The caching
system works using "git notes", which are stored in refs in the
repository. And since you are running "diff --no-index" outside of a
repository, there is nowhere to put them.
And so this BUG call makes sense:
> BUG: refs.c:2095: attempting to get main_ref_store outside of repository
We tried to load notes but there's no ref store at all, and the
low-level ref code caught this.
Of course any time we see a BUG something has gone wrong. What I think
_should_ happen is that we should quietly disable the caching (which,
after all, is just an optimization) and otherwise complete the command.
So we'd probably want something like this:
diff --git a/userdiff.c b/userdiff.c
index e399543823..fce3a31efa 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -3,6 +3,7 @@
#include "userdiff.h"
#include "attr.h"
#include "strbuf.h"
+#include "environment.h"
static struct userdiff_driver *drivers;
static int ndrivers;
@@ -460,7 +461,8 @@ struct userdiff_driver *userdiff_get_textconv(struct repository *r,
if (!driver->textconv)
return NULL;
- if (driver->textconv_want_cache && !driver->textconv_cache) {
+ if (driver->textconv_want_cache && !driver->textconv_cache &&
+ have_git_dir()) {
struct notes_cache *c = xmalloc(sizeof(*c));
struct strbuf name = STRBUF_INIT;
-Peff
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: Bug: diff --no-index with cachetextconv crashes
2024-02-26 7:22 ` Jeff King
@ 2024-02-26 7:56 ` Paweł Dominiak
2024-02-26 10:27 ` [PATCH] userdiff: skip textconv caching when not in a repository Jeff King
0 siblings, 1 reply; 5+ messages in thread
From: Paweł Dominiak @ 2024-02-26 7:56 UTC (permalink / raw)
To: Jeff King; +Cc: git
> OK, I would say that this failing is semi-expected. :) The caching
> system works using "git notes", which are stored in refs in the
> repository. And since you are running "diff --no-index" outside of a
> repository, there is nowhere to put them.
I have not mentioned this specifically, but my goal is a general diff
command, which internally uses text conversions, pager etc. as
configured for git.
It makes sense to cache the textconv results when used in a
repository, but I don't think it should fail when not in one.
I think the default behavior should be to silently skip caching in
such situations but produce a diff otherwise.
> Of course any time we see a BUG something has gone wrong. What I think
> _should_ happen is that we should quietly disable the caching (which,
> after all, is just an optimization) and otherwise complete the command.
In my script I currently disable caching explicitly for all drivers:
keys=$(git config --name-only --get-regexp '^diff\.\w+\.cachetextconv$')
config=(); for key in $keys; do config+=(-c "$key=false"); done
git "${config[@]}" diff --no-index --no-prefix "$@"
But it seems like something git should handle on its own, so that diff
would accommodate use in different circumstances with the same config.
-Pawel
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] userdiff: skip textconv caching when not in a repository
2024-02-26 7:56 ` Paweł Dominiak
@ 2024-02-26 10:27 ` Jeff King
2024-02-26 16:35 ` Junio C Hamano
0 siblings, 1 reply; 5+ messages in thread
From: Jeff King @ 2024-02-26 10:27 UTC (permalink / raw)
To: Paweł Dominiak; +Cc: git
On Mon, Feb 26, 2024 at 08:56:09AM +0100, Paweł Dominiak wrote:
> But it seems like something git should handle on its own, so that diff
> would accommodate use in different circumstances with the same config.
Yes, definitely. Here's my patch with a commit message and a test.
-- >8 --
Subject: userdiff: skip textconv caching when not in a repository
The textconv caching system uses git-notes to store its cache entries.
But if you're using "diff --no-index" outside of a repository, then
obviously that isn't going to work.
Since caching is just an optimization, it's OK for us to skip it.
However, the current behavior is much worse: we call notes_cache_init()
which tries to look up the ref, and the low-level ref code hits a BUG(),
killing the program. Instead, we should notice before setting up the
cache that it there's no repository, and just silently skip it.
Reported-by: Paweł Dominiak <dominiak.pawel@gmail.com>
Signed-off-by: Jeff King <peff@peff.net>
---
t/t4042-diff-textconv-caching.sh | 22 ++++++++++++++++++++++
userdiff.c | 4 +++-
2 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/t/t4042-diff-textconv-caching.sh b/t/t4042-diff-textconv-caching.sh
index bf33aedf4b..8ebfa3c1be 100755
--- a/t/t4042-diff-textconv-caching.sh
+++ b/t/t4042-diff-textconv-caching.sh
@@ -118,4 +118,26 @@ test_expect_success 'log notes cache and still use cache for -p' '
git log --no-walk -p refs/notes/textconv/magic HEAD
'
+test_expect_success 'caching is silently ignored outside repo' '
+ mkdir -p non-repo &&
+ echo one >non-repo/one &&
+ echo two >non-repo/two &&
+ echo "* diff=test" >attr &&
+ test_expect_code 1 \
+ nongit git -c core.attributesFile="$PWD/attr" \
+ -c diff.test.textconv="tr a-z A-Z <" \
+ -c diff.test.cachetextconv=true \
+ diff --no-index one two >actual &&
+ cat >expect <<-\EOF &&
+ diff --git a/one b/two
+ index 5626abf..f719efd 100644
+ --- a/one
+ +++ b/two
+ @@ -1 +1 @@
+ -ONE
+ +TWO
+ EOF
+ test_cmp expect actual
+'
+
test_done
diff --git a/userdiff.c b/userdiff.c
index e399543823..fce3a31efa 100644
--- a/userdiff.c
+++ b/userdiff.c
@@ -3,6 +3,7 @@
#include "userdiff.h"
#include "attr.h"
#include "strbuf.h"
+#include "environment.h"
static struct userdiff_driver *drivers;
static int ndrivers;
@@ -460,7 +461,8 @@ struct userdiff_driver *userdiff_get_textconv(struct repository *r,
if (!driver->textconv)
return NULL;
- if (driver->textconv_want_cache && !driver->textconv_cache) {
+ if (driver->textconv_want_cache && !driver->textconv_cache &&
+ have_git_dir()) {
struct notes_cache *c = xmalloc(sizeof(*c));
struct strbuf name = STRBUF_INIT;
--
2.44.0.rc2.424.gbdbf4d014b
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] userdiff: skip textconv caching when not in a repository
2024-02-26 10:27 ` [PATCH] userdiff: skip textconv caching when not in a repository Jeff King
@ 2024-02-26 16:35 ` Junio C Hamano
0 siblings, 0 replies; 5+ messages in thread
From: Junio C Hamano @ 2024-02-26 16:35 UTC (permalink / raw)
To: Jeff King; +Cc: Paweł Dominiak, git
Jeff King <peff@peff.net> writes:
> Subject: userdiff: skip textconv caching when not in a repository
>
> The textconv caching system uses git-notes to store its cache entries.
> But if you're using "diff --no-index" outside of a repository, then
> obviously that isn't going to work.
>
> Since caching is just an optimization, it's OK for us to skip it.
> However, the current behavior is much worse: we call notes_cache_init()
> which tries to look up the ref, and the low-level ref code hits a BUG(),
> killing the program. Instead, we should notice before setting up the
> cache that it there's no repository, and just silently skip it.
Makes sense.
Will queue. Thanks.
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2024-02-26 16:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-02-26 7:03 Bug: diff --no-index with cachetextconv crashes Paweł Dominiak
2024-02-26 7:22 ` Jeff King
2024-02-26 7:56 ` Paweł Dominiak
2024-02-26 10:27 ` [PATCH] userdiff: skip textconv caching when not in a repository Jeff King
2024-02-26 16:35 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).