103 lines
2.9 KiB
Python
Executable File
103 lines
2.9 KiB
Python
Executable File
#!/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 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 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",
|
|
)
|
|
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='{args.name}'
|
|
export GIT_AUTHOR_EMAIL='{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)
|
|
|
|
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() |