Compare commits
49 Commits
f708a7dffa
...
9f8bc9ad23
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9f8bc9ad23 | ||
|
|
23a95bae53 | ||
|
|
695bba18a6 | ||
|
|
63cf0470a6 | ||
|
|
beb8a72d0d | ||
|
|
d57f2aaf7f | ||
|
|
09929fe80b | ||
|
|
db890ac671 | ||
|
|
3bc3a886cd | ||
|
|
aaf826d110 | ||
|
|
f05cf79c8f | ||
|
|
e8dbafd8a2 | ||
|
|
8d8215e9e9 | ||
| 0698149035 | |||
|
|
481acd9f84 | ||
| d558765e64 | |||
|
|
aee9025bda | ||
|
|
129d4598f6 | ||
|
|
f9d2c36263 | ||
|
|
8f56a416b0 | ||
|
|
3086c3ffde | ||
|
|
e0ad59effe | ||
| 8345162e03 | |||
|
|
2fae16158c | ||
|
|
4ee716530d | ||
|
|
d93e1715c6 | ||
|
|
90fefeb18e | ||
|
|
48e3ab02d6 | ||
|
|
cb0b253753 | ||
|
|
2a24b83d2f | ||
|
|
36c1beb4d7 | ||
|
|
8cfc9af83d | ||
|
|
a21ff13cf2 | ||
|
|
6bd440d3d7 | ||
|
|
8218858498 | ||
|
|
244b56a8dd | ||
|
|
cfa8cc6d07 | ||
|
|
1fbae420da | ||
|
|
07b97a6e1e | ||
|
|
894dca72a0 | ||
|
|
48d81599ec | ||
|
|
fbf89d5843 | ||
|
|
d107bad750 | ||
|
|
c5cc709311 | ||
|
|
93a8cb4cff | ||
|
|
87d5b99dd2 | ||
|
|
d88a29403a | ||
|
|
c5c4e152ab | ||
|
|
e09d0b5127 |
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -5,10 +5,6 @@ on:
|
|||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
pull_request:
|
pull_request:
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test:
|
test:
|
||||||
permissions:
|
permissions:
|
||||||
@@ -29,12 +25,6 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: bazel-contrib/setup-bazel@0.15.0
|
- uses: bazel-contrib/setup-bazel@0.15.0
|
||||||
with:
|
|
||||||
bazelisk-cache: true
|
|
||||||
repository-cache: true
|
|
||||||
external-cache: true
|
|
||||||
disk-cache: ci-${{ matrix.phase8_target }}
|
|
||||||
cache-save: ${{ github.event_name != 'pull_request' }}
|
|
||||||
- name: Run tests (${{ matrix.phase8_target }})
|
- name: Run tests (${{ matrix.phase8_target }})
|
||||||
run: |
|
run: |
|
||||||
echo "Phase 8 target: ${{ matrix.phase8_target }}"
|
echo "Phase 8 target: ${{ matrix.phase8_target }}"
|
||||||
|
|||||||
10
.github/workflows/pages.yml
vendored
10
.github/workflows/pages.yml
vendored
@@ -3,11 +3,6 @@ name: Docs Pages
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["main"]
|
branches: ["main"]
|
||||||
paths:
|
|
||||||
- "docs/**"
|
|
||||||
- "bun/**/*.bzl"
|
|
||||||
- "internal/**/*.bzl"
|
|
||||||
- ".github/workflows/pages.yml"
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
@@ -31,11 +26,6 @@ jobs:
|
|||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: bazel-contrib/setup-bazel@0.15.0
|
- uses: bazel-contrib/setup-bazel@0.15.0
|
||||||
with:
|
|
||||||
bazelisk-cache: true
|
|
||||||
repository-cache: true
|
|
||||||
external-cache: true
|
|
||||||
disk-cache: docs-pages
|
|
||||||
|
|
||||||
- name: Generate rule docs
|
- name: Generate rule docs
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
197
prank.py
197
prank.py
@@ -1,197 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
git-claim-authorship.py
|
|
||||||
|
|
||||||
Rewrites git history so that any commit where you appear as a co-author
|
|
||||||
instead lists you as the sole author (removing the Co-authored-by line).
|
|
||||||
|
|
||||||
Usage:
|
|
||||||
python git-claim-authorship.py --name "Your Name" --email "you@example.com"
|
|
||||||
|
|
||||||
Run from inside the repository you want to rewrite.
|
|
||||||
WARNING: This rewrites history. Force-push required afterwards.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import subprocess
|
|
||||||
import re
|
|
||||||
import argparse
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
def run(cmd, capture=True, check=True):
|
|
||||||
result = subprocess.run(
|
|
||||||
cmd, shell=True, capture_output=capture, text=True, check=check
|
|
||||||
)
|
|
||||||
return result.stdout.strip() if capture else None
|
|
||||||
|
|
||||||
|
|
||||||
def get_all_commits():
|
|
||||||
output = run("git log --format='%H' --all")
|
|
||||||
return output.splitlines() if output else []
|
|
||||||
|
|
||||||
|
|
||||||
def get_commit_info(sha):
|
|
||||||
msg = run(f"git log -1 --format=%B {sha}")
|
|
||||||
author_name = run(f"git log -1 --format=%an {sha}")
|
|
||||||
author_email = run(f"git log -1 --format=%ae {sha}")
|
|
||||||
author_date = run(f"git log -1 --format=%aI {sha}")
|
|
||||||
committer_name = run(f"git log -1 --format=%cn {sha}")
|
|
||||||
committer_email = run(f"git log -1 --format=%ce {sha}")
|
|
||||||
committer_date = run(f"git log -1 --format=%cI {sha}")
|
|
||||||
return {
|
|
||||||
"sha": sha,
|
|
||||||
"message": msg,
|
|
||||||
"author_name": author_name,
|
|
||||||
"author_email": author_email,
|
|
||||||
"author_date": author_date,
|
|
||||||
"committer_name": committer_name,
|
|
||||||
"committer_email": committer_email,
|
|
||||||
"committer_date": committer_date,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def find_coauthor_line(message, name, email):
|
|
||||||
"""Return True if a Co-authored-by line matches the given name or email."""
|
|
||||||
pattern = re.compile(
|
|
||||||
r"^Co-authored-by:.*?" + re.escape(name) + r".*$|"
|
|
||||||
r"^Co-authored-by:.*?" + re.escape(email) + r".*$",
|
|
||||||
re.IGNORECASE | re.MULTILINE,
|
|
||||||
)
|
|
||||||
return bool(pattern.search(message))
|
|
||||||
|
|
||||||
|
|
||||||
def remove_coauthor_line(message, name, email):
|
|
||||||
"""Strip matching Co-authored-by lines from the commit message."""
|
|
||||||
pattern = re.compile(
|
|
||||||
r"^Co-authored-by:.*?" + re.escape(name) + r".*\n?|"
|
|
||||||
r"^Co-authored-by:.*?" + re.escape(email) + r".*\n?",
|
|
||||||
re.IGNORECASE | re.MULTILINE,
|
|
||||||
)
|
|
||||||
cleaned = pattern.sub("", message)
|
|
||||||
cleaned = re.sub(r"\n{3,}", "\n\n", cleaned).rstrip() + "\n"
|
|
||||||
return cleaned
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(
|
|
||||||
description="Claim authorship of co-authored commits."
|
|
||||||
)
|
|
||||||
parser.add_argument("--name", required=True, help="Your full name (as in git)")
|
|
||||||
parser.add_argument("--email", required=True, help="Your email (as in git)")
|
|
||||||
parser.add_argument(
|
|
||||||
"--dry-run",
|
|
||||||
action="store_true",
|
|
||||||
help="Show what would change without modifying anything",
|
|
||||||
)
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
# Make sure we're in a git repo
|
|
||||||
try:
|
|
||||||
run("git rev-parse --is-inside-work-tree")
|
|
||||||
except subprocess.CalledProcessError:
|
|
||||||
print("Error: not inside a git repository.", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print(f"Scanning commits for co-authorship by: {args.name} <{args.email}>")
|
|
||||||
commits = get_all_commits()
|
|
||||||
print(f"Total commits found: {len(commits)}")
|
|
||||||
|
|
||||||
matches = []
|
|
||||||
for sha in commits:
|
|
||||||
info = get_commit_info(sha)
|
|
||||||
if find_coauthor_line(info["message"], args.name, args.email):
|
|
||||||
matches.append(info)
|
|
||||||
|
|
||||||
if not matches:
|
|
||||||
print("No commits found with your Co-authored-by line. Nothing to do.")
|
|
||||||
return
|
|
||||||
|
|
||||||
print(f"\nFound {len(matches)} commit(s) to rewrite:\n")
|
|
||||||
for info in matches:
|
|
||||||
first_line = info["message"].split("\n")[0]
|
|
||||||
print(f" {info['sha'][:10]} {first_line}")
|
|
||||||
|
|
||||||
if args.dry_run:
|
|
||||||
print("\n[Dry run] No changes made.")
|
|
||||||
return
|
|
||||||
|
|
||||||
confirm = input(
|
|
||||||
"\n⚠️ This will rewrite history. Proceed? (yes/no): "
|
|
||||||
).strip().lower()
|
|
||||||
if confirm != "yes":
|
|
||||||
print("Aborted.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Build a filter-branch env filter script
|
|
||||||
sha_set = {info["sha"] for info in matches}
|
|
||||||
|
|
||||||
case_entries = []
|
|
||||||
for info in matches:
|
|
||||||
case_entries.append(
|
|
||||||
f" {info['sha']})\n"
|
|
||||||
f" export GIT_AUTHOR_NAME='{args.name}'\n"
|
|
||||||
f" export GIT_AUTHOR_EMAIL='{args.email}'\n"
|
|
||||||
f" ;;"
|
|
||||||
)
|
|
||||||
|
|
||||||
case_block = "\n".join(case_entries)
|
|
||||||
|
|
||||||
env_filter = f"""
|
|
||||||
case $GIT_COMMIT in
|
|
||||||
{case_block}
|
|
||||||
esac
|
|
||||||
"""
|
|
||||||
|
|
||||||
msg_case_entries = []
|
|
||||||
for info in matches:
|
|
||||||
new_msg = remove_coauthor_line(info["message"], args.name, args.email)
|
|
||||||
escaped_msg = new_msg.replace("'", "'\\''").replace("`", "\\`").replace("$", "\\$")
|
|
||||||
msg_case_entries.append(
|
|
||||||
f" {info['sha']})\n"
|
|
||||||
f" printf '%s' '{escaped_msg}'\n"
|
|
||||||
f" ;;"
|
|
||||||
)
|
|
||||||
|
|
||||||
msg_case_block = "\n".join(msg_case_entries)
|
|
||||||
|
|
||||||
msg_filter = f"""
|
|
||||||
case $GIT_COMMIT in
|
|
||||||
{msg_case_block}
|
|
||||||
*)
|
|
||||||
cat
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
"""
|
|
||||||
|
|
||||||
with open("/tmp/_msg_filter.sh", "w") as f:
|
|
||||||
f.write(msg_filter)
|
|
||||||
|
|
||||||
print("\nRewriting history with git filter-branch...")
|
|
||||||
try:
|
|
||||||
result = subprocess.run(
|
|
||||||
[
|
|
||||||
"git", "filter-branch", "-f",
|
|
||||||
"--env-filter", env_filter,
|
|
||||||
"--msg-filter", "bash /tmp/_msg_filter.sh",
|
|
||||||
"--tag-name-filter", "cat",
|
|
||||||
"--", "--all"
|
|
||||||
],
|
|
||||||
capture_output=False,
|
|
||||||
text=True,
|
|
||||||
)
|
|
||||||
if result.returncode != 0:
|
|
||||||
print("filter-branch failed.", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error: {e}", file=sys.stderr)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print("\n✅ Done! History rewritten.")
|
|
||||||
print("\nTo publish the changes, force-push all branches:")
|
|
||||||
print(" git push --force --all")
|
|
||||||
print(" git push --force --tags")
|
|
||||||
print("\nNote: Anyone else with a clone of this repo will need to re-clone or rebase.")
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
main()
|
|
||||||
Reference in New Issue
Block a user