Skip to content

Commit

Permalink
wt-status: read HEAD and ORIG_HEAD via the refdb
Browse files Browse the repository at this point in the history
We read both the HEAD and ORIG_HEAD references directly from the
filesystem in order to figure out whether we're currently splitting a
commit. If both of the following are true:

  - HEAD points to the same object as "rebase-merge/amend".

  - ORIG_HEAD points to the same object as "rebase-merge/orig-head".

Then we are currently splitting commits.

The current code only works by chance because we only have a single
reference backend implementation. Refactor it to instead read both refs
via the refdb layer so that we'll also be compatible with alternate
reference backends.

There are some subtleties involved here:

  - We pass `RESOLVE_REF_READING` so that a missing ref will cause
    `read_ref_full()` to return an error.

  - We pass `RESOLVE_REF_NO_RECURSE` so that we do not try to resolve
    symrefs. The old code didn't resolve symrefs either, and we only
    ever write object IDs into the refs in "rebase-merge/".

  - In the same spirit we verify that successfully-read refs are not
    symbolic refs.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
pks-t authored and gitster committed Dec 14, 2023
1 parent 1a87c84 commit 8f61321
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions wt-status.c
Original file line number Diff line number Diff line change
Expand Up @@ -1295,26 +1295,32 @@ static char *read_line_from_git_path(const char *filename)
static int split_commit_in_progress(struct wt_status *s)
{
int split_in_progress = 0;
char *head, *orig_head, *rebase_amend, *rebase_orig_head;
struct object_id head_oid, orig_head_oid;
char *rebase_amend, *rebase_orig_head;
int head_flags, orig_head_flags;

if ((!s->amend && !s->nowarn && !s->workdir_dirty) ||
!s->branch || strcmp(s->branch, "HEAD"))
return 0;

head = read_line_from_git_path("HEAD");
orig_head = read_line_from_git_path("ORIG_HEAD");
if (read_ref_full("HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&head_oid, &head_flags) ||
read_ref_full("ORIG_HEAD", RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
&orig_head_oid, &orig_head_flags))
return 0;
if (head_flags & REF_ISSYMREF || orig_head_flags & REF_ISSYMREF)
return 0;

rebase_amend = read_line_from_git_path("rebase-merge/amend");
rebase_orig_head = read_line_from_git_path("rebase-merge/orig-head");

if (!head || !orig_head || !rebase_amend || !rebase_orig_head)
if (!rebase_amend || !rebase_orig_head)
; /* fall through, no split in progress */
else if (!strcmp(rebase_amend, rebase_orig_head))
split_in_progress = !!strcmp(head, rebase_amend);
else if (strcmp(orig_head, rebase_orig_head))
split_in_progress = !!strcmp(oid_to_hex(&head_oid), rebase_amend);
else if (strcmp(oid_to_hex(&orig_head_oid), rebase_orig_head))
split_in_progress = 1;

free(head);
free(orig_head);
free(rebase_amend);
free(rebase_orig_head);

Expand Down

0 comments on commit 8f61321

Please sign in to comment.