Compare commits
19 Commits
a9e2be6f63
...
cd6e85cac0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd6e85cac0 | ||
|
|
ff90522c3c | ||
|
|
a1a6568227 | ||
|
|
6cf1e57409 | ||
|
|
e40127378d | ||
|
|
af377eac9d | ||
|
|
d10365e9fe | ||
|
|
ab8e5e0061 | ||
|
|
44a28bc262 | ||
|
|
ff029adbc9 | ||
|
|
4144633204 | ||
|
|
29c39822d5 | ||
|
|
87882c9d9f | ||
|
|
a38cae0265 | ||
|
|
b614afd435 | ||
|
|
255958b3dd | ||
|
|
01fe0a790d | ||
|
|
70aa7c4655 | ||
|
|
722d503edb |
138
prank.py
Executable file
138
prank.py
Executable file
@@ -0,0 +1,138 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
git-claim-authorship.py
|
||||
|
||||
Rewrites git history so that all commits list you as the author.
|
||||
|
||||
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 argparse
|
||||
import shlex
|
||||
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_original_refs():
|
||||
output = run("git for-each-ref --format='%(refname)' refs/original", check=False)
|
||||
return output.splitlines() if output else []
|
||||
|
||||
|
||||
def shell_quote(value):
|
||||
return shlex.quote(value)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Rewrite history so all commits use the provided author."
|
||||
)
|
||||
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",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--keep-original-refs",
|
||||
action="store_true",
|
||||
help="Keep git filter-branch backup refs instead of deleting them after rewrite",
|
||||
)
|
||||
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 to rewrite author to: {args.name} <{args.email}>")
|
||||
commits = get_all_commits()
|
||||
print(f"Total commits found: {len(commits)}")
|
||||
|
||||
if not commits:
|
||||
print("No commits found. Nothing to do.")
|
||||
return
|
||||
|
||||
print(f"\nFound {len(commits)} commit(s) to rewrite.\n")
|
||||
|
||||
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
|
||||
env_filter = f"""
|
||||
export GIT_AUTHOR_NAME={shell_quote(args.name)}
|
||||
export GIT_AUTHOR_EMAIL={shell_quote(args.email)}
|
||||
export GIT_COMMITTER_NAME={shell_quote(args.name)}
|
||||
export GIT_COMMITTER_EMAIL={shell_quote(args.email)}
|
||||
"""
|
||||
|
||||
print("\nRewriting history with git filter-branch...")
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[
|
||||
"git", "filter-branch", "-f",
|
||||
"--env-filter", env_filter,
|
||||
"--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)
|
||||
|
||||
if args.keep_original_refs:
|
||||
print("\nKept git filter-branch backup refs under refs/original.")
|
||||
else:
|
||||
original_refs = get_original_refs()
|
||||
if original_refs:
|
||||
print("\nRemoving git filter-branch backup refs...")
|
||||
for ref in original_refs:
|
||||
subprocess.run(["git", "update-ref", "-d", ref], check=True)
|
||||
|
||||
print("Expiring reflogs and pruning unreachable objects...")
|
||||
subprocess.run(
|
||||
["git", "reflog", "expire", "--expire=now", "--all"],
|
||||
check=True,
|
||||
)
|
||||
subprocess.run(["git", "gc", "--prune=now"], check=True)
|
||||
|
||||
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