Skip to content

describe the base and series length in the summary - #10

Merged
yuval-block merged 2 commits into
mainfrom
base-info
Oct 19, 2026
Merged

yuval-block merged 2 commits into
mainfrom
base-info

Conversation

@bc1cindy

@bc1cindy bc1cindy commented Oct 8, 2026

Copy link
Copy Markdown
Member

closes #6: the summary now says whether the base is the same, a descendant or diverged, and the series length before and after.

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
range-diff for force push cc74687bdb → 1cfe7d26d0 October 8, 2026 17:07 UTC: 2 unchanged; 2 commits; same base df32adc225

reproduce: git range-diff df32adc..cc74687 df32adc..1cfe7d2

1:  d6502cd215 = 1:  d6502cd215 Find where a series forked from a rewritten base
2:  cc74687bdb = 2:  1cfe7d26d0 Describe the base and series length in the summary

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
range-diff for force push 1cfe7d26d0 → 3d03b915a7 October 8, 2026 17:32 UTC: 2 unchanged; 2 commits; same base df32adc225

reproduce: git range-diff df32adc..1cfe7d2 df32adc..3d03b91

1:  d6502cd215 = 1:  d6502cd215 Find where a series forked from a rewritten base
2:  1cfe7d26d0 = 2:  3d03b915a7 Describe the base and series length in the summary

@github-actions

github-actions Bot commented Oct 8, 2026

Copy link
Copy Markdown
range-diff for force push 3d03b915a7 → 4fda8c5a5e October 8, 2026 23:23 UTC: 2 modified; 2 commits; same base df32adc225

reproduce: git range-diff df32adc..3d03b91 df32adc..4fda8c5

1:  d6502cd215 ! 1:  04f0bfeccd Find where a series forked from a rewritten base
2:  3d03b915a7 ! 2:  4fda8c5a5e Describe the base and series length in the summary
1: d6502cd215 ! 1: 04f0bfeccd Find where a series forked from a rewritten base
@@ post-range-diff-comment.sh: if git merge-base --is-ancestor "$BEFORE" "$AFTER";
 +# from further back.  GitHub's activity log stands in for the reflog that
 +# `git merge-base --fork-point` reads.
 +base_tips=("origin/$BASE_REF")
-+if rewound="$(gh api --paginate --jq '.[].before' \
-+  "repos/$REPO/activity?ref=refs/heads/$BASE_REF&activity_type=force_push&per_page=100")"; then
++if rewound="$(gh api --paginate --method GET --jq '.[].before' "repos/$REPO/activity" \
++  -f ref="refs/heads/$BASE_REF" -f activity_type=force_push -F per_page=100)"; then
 +  for tip in $rewound; do
 +    if git fetch --quiet --no-tags origin "$tip" 2>/dev/null; then
 +      base_tips+=("$tip")
@@ post-range-diff-comment.sh: if git merge-base --is-ancestor "$BEFORE" "$AFTER";
 +
  # Diff each side against where it forked from the base branch, so a rebase
  # onto a newer base does not drag the base's new commits into the comparison.
- # Fall back to the symmetric difference if either side is unrelated to base.
+-# Fall back to the symmetric difference if either side is unrelated to base.
 -if old_base="$(git merge-base "origin/$BASE_REF" "$BEFORE")" &&
 -  new_base="$(git merge-base "origin/$BASE_REF" "$AFTER")"; then
++# Fall back to the symmetric difference if either side is unrelated to base,
++# or if a tip of the base contains it: its range would be empty, which
++# range-diff rejects.
 +if old_base="$(git merge-base "$BEFORE" "${base_tips[@]}")" &&
-+  new_base="$(git merge-base "$AFTER" "${base_tips[@]}")"; then
++  new_base="$(git merge-base "$AFTER" "${base_tips[@]}")" &&
++  [[ $old_base != "$(git rev-parse "$BEFORE^{commit}")" ]] &&
++  [[ $new_base != "$(git rev-parse "$AFTER^{commit}")" ]]; then
    old_range="$old_base..$BEFORE"
    new_range="$new_base..$AFTER"
  else
+-  echo "::warning::no merge base with $BASE_REF; using $BEFORE...$AFTER"
++  echo "::warning::no fork point from $BASE_REF; using $BEFORE...$AFTER"
+   old_range="$AFTER..$BEFORE"
+   new_range="$BEFORE..$AFTER"
+ fi
 
  ## tests/test_action.py ##
 @@ tests/test_action.py: class ActionTest(unittest.TestCase):
@@ tests/test_action.py: class ActionTest(unittest.TestCase):
 +        self.assertIn(f"git range-diff {old_parent[:7]}", out)
 +        self.assertIn(f"{new_parent[:7]}..{self.after[:7]}</code>", out)
 +        self.assertIn(": 1 unchanged</summary>", out)
++
++    def test_series_an_old_base_tip_contained(self):
++        self.git("checkout", "-q", "-b", "child")
++        self.before = self.commit("child\n", "child", path="child")
++        self.git("branch", "merged", self.before)
++        self.after = self.commit("child again\n", "child", amend=True, path="child")
++        self.run_action(base_ref="topic", rewound=[self.before])
 +
      def test_force_push_shallow_checkout(self):
          self.run_action(shallow=True)
2: 3d03b915a7 ! 2: 4fda8c5a5e Describe the base and series length in the summary
@@ README.md: jobs:
 
  ## post-range-diff-comment.sh ##
 @@ post-range-diff-comment.sh: if old_base="$(git merge-base "$BEFORE" "${base_tips[@]}")" &&
-   new_base="$(git merge-base "$AFTER" "${base_tips[@]}")"; then
+   [[ $new_base != "$(git rev-parse "$AFTER^{commit}")" ]]; then
    old_range="$old_base..$BEFORE"
    new_range="$new_base..$AFTER"
 +  read -r base_behind base_ahead < <(git rev-list --left-right --count "$old_base...$new_base")
  else
-   echo "::warning::no merge base with $BASE_REF; using $BEFORE...$AFTER"
+   echo "::warning::no fork point from $BASE_REF; using $BEFORE...$AFTER"
    old_range="$AFTER..$BEFORE"
    new_range="$BEFORE..$AFTER"
 +  old_base="" new_base="" base_behind=0 base_ahead=0
@@ tests/test_action.py: class ActionTest(unittest.TestCase):
 +        self.after = self.git("rev-parse", "HEAD")
 +        self.assertNotIn("base <a", self.run_action())
  
-     def test_force_push_shallow_checkout(self):
-         self.run_action(shallow=True)
+     def test_series_an_old_base_tip_contained(self):
+         self.git("checkout", "-q", "-b", "child")
 
  ## tests/test_render.py ##
 @@ tests/test_render.py: FIXTURES = pathlib.Path(__file__).parent / "fixtures"

Comment thread README.md Resolved
@github-actions

github-actions Bot commented Oct 9, 2026

Copy link
Copy Markdown
range-diff for force push 4fda8c5a5e → 2b03757377 October 9, 2026 11:59 UTC: 1 modified, 1 unchanged; 2 commits; same base df32adc225

reproduce: git range-diff df32adc..4fda8c5 df32adc..2b03757

1:  04f0bfeccd = 1:  04f0bfeccd Find where a series forked from a rewritten base
2:  4fda8c5a5e ! 2:  2b03757377 Describe the base and series length in the summary
2: 4fda8c5a5e ! 2: 2b03757377 Describe the base and series length in the summary
@@ Metadata
  ## Commit message ##
     Describe the base and series length in the summary
 
-    Says whether a force push kept the base, moved to a descendant or to a
-    diverged one, and how many commits the series had before and after.
+    Says whether a force push kept the base or moved it to a descendant, an
+    ancestor or a diverged one, and how many commits the series had before
+    and after.
 
  ## README.md ##
 @@ README.md: jobs:
@@ README.md: jobs:
 -recognized from its force pushes in the repository's activity log. Inputs and
 -outputs are described in [action.yml](action.yml).
 +changes. The summary line says how many commits the series had before and
-+after, and whether its base is the same, a descendant of the old one, or
-+diverged from it. A base branch that was itself rewritten, as a parent in a
-+stack, is recognized from its force pushes in the repository's activity log.
-+Inputs and outputs are described in [action.yml](action.yml).
++after, and whether its base is the same, a descendant or an ancestor of the
++old one, or diverged from it. A base branch that was itself rewritten, as a
++parent in a stack, is recognized from its force pushes in the repository's
++activity log. Inputs and outputs are described in [action.yml](action.yml).
  
  `pull_request_target` gives fork PRs a token that can comment. It is safe here
  because nothing from the PR runs: the checkout is the base branch, the action

@oakagent

Copy link
Copy Markdown

ACK 2b03757 (automated): reviewed 2 commits 04f0bfe..2b03757; no findings.

@yuval-block yuval-block left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

concept ACK, the code seems good but i only skimmed it and haven't thought through various edge cases. i'm inclined to merge anyway since this is an incremental improvement and consequences if this has a bug are very minor

A parent rewritten in a stack leaves its old tips unreachable, so they
are read from the repository activity log in place of a reflog.
Says whether a force push kept the base or moved it to a descendant, an
ancestor or a diverged one, and how many commits the series had before
and after.
@github-actions

Copy link
Copy Markdown
range-diff for force push 2b03757377 → 582337537e October 19, 2026 22:23 UTC: 2 unchanged; 2 commits; base df32adc225 → 0bf2c28224 (descendant, 2 commits ahead)

reproduce: git range-diff df32adc..2b03757 0bf2c28..5823375

1:  04f0bfeccd = 1:  e3d23d89e0 Find where a series forked from a rewritten base
2:  2b03757377 = 2:  582337537e Describe the base and series length in the summary

@yuval-block
yuval-block merged commit a8eb1cb into main Oct 19, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

also post information about the base

3 participants