import argparse
import subprocess
import os
import shutil
import tempfile
import random
from datetime import datetime, timedelta
TARGET_EMAIL = "user@gmail.com"
DUMP_REPO_URL = "https://github.com/user/dump-commit.git"
START_DATE = datetime(2024, 8, 1)
END_DATE = datetime(2025, 12, 16)
def run_command(command, cwd=None, env=None):
"""명령어를 실행하고 출력을 반환합니다."""
try:
result = subprocess.run(
command,
cwd=cwd,
env=env,
check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
print(f"Error running command: {' '.join(command)}\nSTDERR: {e.stderr}")
raise
def generate_dates():
"""시작일부터 종료일까지의 모든 날짜와 각 날짜별 커밋 횟수를 생성합니다 (인간미 추가)."""
current_date = START_DATE
commit_plan = []
total_commits = 0
days = 0
print("[*] Generating human-like commit plan...")
while current_date <= END_DATE:
days += 1
is_weekend = current_date.weekday() >= 5
if is_weekend:
if random.random() < 0.2:
current_date += timedelta(days=1)
continue
count = random.randint(1, 5)
else:
if random.random() < 0.1:
current_date += timedelta(days=1)
continue
count = random.randint(10, 30)
total_commits += count
for _ in range(count):
hour = random.randint(9, 23)
minute = random.randint(0, 59)
second = random.randint(0, 59)
commit_dt = current_date.replace(hour=hour, minute=minute, second=second)
commit_plan.append(commit_dt)
current_date += timedelta(days=1)
commit_plan.sort()
print(f"[*] Human-like Plan generated: {total_commits} commits over {days} days duration.")
return commit_plan
def plant_grass(commit_datetimes):
"""생성된 계획에 따라 빈 커밋을 생성합니다."""
if not commit_datetimes:
print("[!] No commits to generate.")
return
work_dir = tempfile.mkdtemp(prefix="grass_generation_")
print(f"[*] Created temporary working directory: {work_dir}")
try:
print(f"[*] Cloning dump repository: {DUMP_REPO_URL}")
run_command(["git", "clone", DUMP_REPO_URL, "."], cwd=work_dir)
run_command(["git", "config", "user.email", TARGET_EMAIL], cwd=work_dir)
run_command(["git", "config", "user.name", "Grass Generator"], cwd=work_dir)
print("[*] Starting to generate commits...")
count = 0
total = len(commit_datetimes)
for dt in commit_datetimes:
count += 1
date_iso = dt.isoformat()
env = os.environ.copy()
env["GIT_AUTHOR_DATE"] = date_iso
env["GIT_COMMITTER_DATE"] = date_iso
run_command(
["git", "commit", "--allow-empty", "-m", f"Keep growing: {date_iso}"],
cwd=work_dir,
env=env
)
if count % 100 == 0:
print(f" Generated {count}/{total} commits...")
print(f"[*] Successfully created {count} commits.")
print("[*] Pushing to remote repository...")
run_command(["git", "push", "origin", "main"], cwd=work_dir)
print("[*] Done! Check your GitHub profile.")
except Exception as e:
print(f"[!] An error occurred: {e}")
finally:
print(f"[*] Cleaning up temporary directory: {work_dir}")
shutil.rmtree(work_dir, ignore_errors=True)
def main():
print(f"[*] Grass Generator Target: {TARGET_EMAIL}")
print(f"[*] Range: {START_DATE.date()} ~ {END_DATE.date()}")
commits = generate_dates()
if commits:
confirm = input(f"[*] Ready to create {len(commits)} human-like commits in {DUMP_REPO_URL}. Proceed? (y/n): ")
if confirm.lower() == 'y':
plant_grass(commits)
else:
print("[*] Operation cancelled.")
if __name__ == "__main__":
main()