From: Elijah Newren <newren@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, "Ævar Arnfjörð" <avarab@gmail.com>,
andreastacchiotti@gmail.com,
"Eckhard Maaß" <eckhard.s.maass@googlemail.com>,
"Eric Sunshine" <sunshine@sunshineco.com>,
"Duy Nguyen" <pclouds@gmail.com>,
"Elijah Newren" <newren@gmail.com>
Subject: [PATCHv2] commit: fix erroneous BUG, 'multiple renames on the same target? how?'
Date: Thu, 27 Sep 2018 10:36:57 -0700 [thread overview]
Message-ID: <20180927173657.4723-1-newren@gmail.com> (raw)
In-Reply-To: <20180927072043.19130-1-newren@gmail.com>
builtin/commit.c:prepare_to_commit() can call run_status() twice if
using the editor, including status, and the user attempts to record a
non-merge empty commit without explicit --allow-empty. If there is also
a rename involved as well (due to using 'git add -N'), then a BUG in
wt-status.c is triggered:
BUG: wt-status.c:476: multiple renames on the same target? how?
The reason we hit this bug is that both run_status() calls use the same
struct wt_status * (named s), and s->change is not freed between runs.
Changes are inserted into s with string_list_insert, which usually means
that the second run just recomputes all the same results and overwrites
what was computed the first time. However, ever since commit
176ea7479309 ("wt-status.c: handle worktree renames", 2017-12-27),
wt-status started checking for renames and copies but also added a
preventative check that d->rename_status wasn't already set and output a
BUG message if it was. The problem isn't that there are multiple rename
targets to a single path as the error implies, the problem is that 's'
is not freed/cleared between the two run_status() calls.
Ever since commit dc6b1d92ca9c ("wt-status: use settings from
git_diff_ui_config", 2018-05-04), which stopped hardcoding
DIFF_DETECT_RENAME and allowed users to ask for copy detection, this bug
has also been triggerable with a copy instead of a rename.
Fix the bug by clearing s->change. A better change might be to clean up
all of s between the two run_status() calls. A good first step towards
such a goal might be writing a function to free the necessary fields in
the wt_status * struct; a cursory glance at the code suggests all of its
allocated data is probably leaked. However, doing all that cleanup is a
bigger task for someone else interested to tackle; just fix the bug for
now.
Reported-by: Andrea Stacchiotti <andreastacchiotti@gmail.com>
Signed-off-by: Elijah Newren <newren@gmail.com>
---
Changes since v1:
- Remove non-portable and unneccessary -a flag to cp (Flagged by Eric)
- Move the string_list_clear() from just before the second run_status()
call to just after the first one (As suggested by Duy)
builtin/commit.c | 1 +
t/t7500-commit.sh | 23 +++++++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/builtin/commit.c b/builtin/commit.c
index b57d8e4b82..342cc9cff0 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -874,6 +874,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
s->use_color = 0;
commitable = run_status(s->fp, index_file, prefix, 1, s);
s->use_color = saved_color_setting;
+ string_list_clear(&s->change, 1);
} else {
struct object_id oid;
const char *parent = "HEAD";
diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh
index 170b4810e0..31ab608b67 100755
--- a/t/t7500-commit.sh
+++ b/t/t7500-commit.sh
@@ -359,4 +359,27 @@ test_expect_success 'new line found before status message in commit template' '
test_i18ncmp expected-template editor-input
'
+test_expect_success 'setup empty commit with unstaged rename and copy' '
+ test_create_repo unstaged_rename_and_copy &&
+ (
+ cd unstaged_rename_and_copy &&
+
+ echo content >orig &&
+ git add orig &&
+ test_commit orig &&
+
+ cp orig new_copy &&
+ mv orig new_rename &&
+ git add -N new_copy new_rename
+ )
+'
+
+test_expect_success 'check commit with unstaged rename and copy' '
+ (
+ cd unstaged_rename_and_copy &&
+
+ test_must_fail git -c diff.renames=copy commit
+ )
+'
+
test_done
--
2.19.0.222.gfbc440e6cd.dirty
prev parent reply other threads:[~2018-09-27 17:37 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-09-27 7:20 Triggering "BUG: wt-status.c:476: multiple renames on the same target? how?" Elijah Newren
2018-09-27 10:15 ` Eric Sunshine
2018-09-27 16:48 ` Duy Nguyen
2018-09-27 17:36 ` Elijah Newren [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180927173657.4723-1-newren@gmail.com \
--to=newren@gmail.com \
--cc=andreastacchiotti@gmail.com \
--cc=avarab@gmail.com \
--cc=eckhard.s.maass@googlemail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=pclouds@gmail.com \
--cc=sunshine@sunshineco.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).