From: "Phillip Wood via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Phillip Wood <phillip.wood123@gmail.com>,
Phillip Wood <phillip.wood@dunelm.org.uk>
Subject: [PATCH v2 0/4] rebase -i: fix ORIG_HEAD handling
Date: Wed, 04 Nov 2020 15:29:36 +0000 [thread overview]
Message-ID: <pull.773.v2.git.1604503780.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.773.git.1603807337.gitgitgadget@gmail.com>
The buffer containing the oid for ORIG_HEAD is overwritten before ORIG_HEAD
is created. This series fixes that bug and then converts the code to use
struct object_id rather than passing around strings.
Thanks to Caspar for reporting the bug and providing a reproducible example
Changes since v1:
* Updated the commit message to patch 1 as suggested by Junio
* Moved the conversion from find_unique_abbrev() to oid_to_hex() from patch
1 to patch 4
* Fixed a compilation error in patch 3 (the required change was in patch 4
by a mistake)
Cc: Johannes Schindelin Johannes.Schindelin@gmx.de
[Johannes.Schindelin@gmx.de], Caspar Duregger herr.kaste@gmail.com
[herr.kaste@gmail.com]
Phillip Wood (4):
rebase -i: stop overwriting ORIG_HEAD buffer
rebase -i: use struct object_id rather than looking up commit
rebase -i: use struct object_id when writing state
rebase -i: simplify get_revision_ranges()
builtin/rebase.c | 20 ++++++++++----------
sequencer.c | 15 ++++++---------
sequencer.h | 7 ++++---
t/t3404-rebase-interactive.sh | 11 +++++++++++
4 files changed, 31 insertions(+), 22 deletions(-)
base-commit: 2e673356aefa8ed19be3c878f966ad6189ecb510
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-773%2Fphillipwood%2Fwip%2Frebase-fix-orig_head-handling-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-773/phillipwood/wip/rebase-fix-orig_head-handling-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/773
Range-diff vs v1:
1: 24f2c4a623 ! 1: da05958c58 rebase -i: stop overwriting ORIG_HEAD buffer
@@ Metadata
## Commit message ##
rebase -i: stop overwriting ORIG_HEAD buffer
- After rebasing ORIG_HEAD is supposed to point to the old HEAD of the
- rebased branch. Unfortunately the buffer storing the oid was
- overwritten with a new oid before ORIG_HEAD was created. The buffer is
- also used when writing .git/rebase-merge/orig-head which is used by
- `rebase --abort` to restore the previous head. Luckily that file is
- written before the buffer is overwritten. As we want the full oid
- find_unique_abbrev() is replaced with oid_to_hex_r() rather than
- find_unique_abbrev_r().
+ After rebasing, ORIG_HEAD is supposed to point to the old HEAD of the
+ rebased branch. The code used find_unique_abbrev() to obtain the
+ object name of the old HEAD and wrote to both
+ .git/rebase-merge/orig-head (used by `rebase --abort` to go back to
+ the previous state) and to ORIG_HEAD. The buffer find_unique_abbrev()
+ gives back is volatile, unfortunately, and was overwritten after the
+ former file is written but before ORIG_FILE is written, leaving an
+ incorrect object name in it.
+
+ Avoid relying on the volatile buffer of find_unique_abbrev(), and
+ instead supply our own buffer to keep the object name.
I think that all of the users of head_hash should actually be using
opts->orig_head instead as passing a string rather than a struct
object_id around is a hang over from the scripted implementation. This
patch just fixes the immediate bug and adds a regression test based on
- Caspar's reproduction example. The users will be converted to use
+ Caspar's reproduction example[1]. The users will be converted to use
struct object_id and head_hash removed in the next few commits.
+ [1] https://lore.kernel.org/git/CAFzd1+7PDg2PZgKw7U0kdepdYuoML9wSN4kofmB_-8NHrbbrHg@mail.gmail.com
+
Reported-by: Caspar Duregger <herr.kaste@gmail.com>
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
@@ builtin/rebase.c: static int edit_todo_file(unsigned flags)
const char *shorthead;
- *head_hash = find_unique_abbrev(orig_head, GIT_MAX_HEXSZ);
-+ oid_to_hex_r(head_hash, orig_head);
++ find_unique_abbrev_r(head_hash, orig_head, GIT_MAX_HEXSZ);
*revisions = xstrfmt("%s...%s", oid_to_hex(&base_rev->object.oid),
- *head_hash);
+ head_hash);
2: 589aed08f1 = 2: da499f1e4c rebase -i: use struct object_id rather than looking up commit
3: 11494a7b79 ! 3: 076d212915 rebase -i: use struct object_id when writing state
@@ builtin/rebase.c: static int get_revision_ranges(struct commit *upstream, struct
{
FILE *interactive;
+@@ builtin/rebase.c: static int do_interactive_rebase(struct rebase_options *opts, unsigned flags)
+
+ if (init_basic_state(&replay,
+ opts->head_name ? opts->head_name : "detached HEAD",
+- opts->onto, head_hash)) {
++ opts->onto, &opts->orig_head)) {
+ free(revisions);
+ free(shortrevisions);
+
## sequencer.c ##
@@ sequencer.c: static void write_strategy_opts(struct replay_opts *opts)
4: ed78f8628a ! 4: faae3ccff5 rebase -i: simplify get_revision_ranges()
@@ Commit message
use a opts->orig_head instead we can stop returning head_hash from
get_revision_ranges().
+ Because we want to pass the full object names back to the caller in
+ `revisions` the find_unique_abbrev_r() call that was used to initialize
+ `head_hash` is replaced with oid_to_hex().
+
Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
## builtin/rebase.c ##
@@ builtin/rebase.c: static int edit_todo_file(unsigned flags)
struct commit *base_rev = upstream ? upstream : onto;
const char *shorthead;
-- oid_to_hex_r(head_hash, orig_head);
+- find_unique_abbrev_r(head_hash, orig_head, GIT_MAX_HEXSZ);
*revisions = xstrfmt("%s...%s", oid_to_hex(&base_rev->object.oid),
- head_hash);
+ oid_to_hex(orig_head));
@@ builtin/rebase.c: static int do_interactive_rebase(struct rebase_options *opts,
return -1;
if (init_basic_state(&replay,
- opts->head_name ? opts->head_name : "detached HEAD",
-- opts->onto, head_hash)) {
-+ opts->onto, &opts->orig_head)) {
- free(revisions);
- free(shortrevisions);
-
--
gitgitgadget
next prev parent reply other threads:[~2020-11-04 15:29 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-27 14:02 [PATCH 0/4] rebase -i: fix ORIG_HEAD handling Phillip Wood via GitGitGadget
2020-10-27 14:02 ` [PATCH 1/4] rebase -i: stop overwriting ORIG_HEAD buffer Phillip Wood via GitGitGadget
2020-10-27 21:10 ` Junio C Hamano
2020-10-31 10:55 ` Phillip Wood
2020-11-02 19:40 ` herr.kaste
2020-11-03 0:21 ` Junio C Hamano
2020-11-03 11:02 ` herr.kaste
2020-10-27 14:02 ` [PATCH 2/4] rebase -i: use struct object_id rather than looking up commit Phillip Wood via GitGitGadget
2020-10-27 14:02 ` [PATCH 3/4] rebase -i: use struct object_id when writing state Phillip Wood via GitGitGadget
2020-10-27 14:02 ` [PATCH 4/4] rebase -i: simplify get_revision_ranges() Phillip Wood via GitGitGadget
2020-11-04 15:29 ` Phillip Wood via GitGitGadget [this message]
2020-11-04 15:29 ` [PATCH v2 1/4] rebase -i: stop overwriting ORIG_HEAD buffer Phillip Wood via GitGitGadget
2020-11-04 15:29 ` [PATCH v2 2/4] rebase -i: use struct object_id rather than looking up commit Phillip Wood via GitGitGadget
2020-11-04 15:29 ` [PATCH v2 3/4] rebase -i: use struct object_id when writing state Phillip Wood via GitGitGadget
2020-11-04 15:29 ` [PATCH v2 4/4] rebase -i: simplify get_revision_ranges() Phillip Wood via GitGitGadget
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=pull.773.v2.git.1604503780.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=phillip.wood123@gmail.com \
--cc=phillip.wood@dunelm.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.