Analysis: Git vs Go-Git comparison and recommendation

This commit is contained in:
2026-01-11 07:39:12 +08:00
parent 6bec6a261d
commit 642dd0ea5f
2 changed files with 434 additions and 0 deletions

262
auto_commit_gogit.py Normal file
View File

@@ -0,0 +1,262 @@
#!/usr/bin/env python3
"""
Go-Git Auto-Commit Script for LightRAG project.
Uses Gitea API directly instead of external Git.
"""
import requests
import os
import sys
import json
import hashlib
import base64
from datetime import datetime
from pathlib import Path
class GoGitAutoCommit:
def __init__(self, gitea_url, username, password, repo_owner, repo_name):
self.gitea_url = gitea_url.rstrip('/')
self.username = username
self.password = password
self.repo_owner = repo_owner
self.repo_name = repo_name
self.session = requests.Session()
self.session.auth = (username, password)
def get_auth_token(self):
"""Get or create an access token for API calls."""
# Try to get existing tokens
tokens_url = f"{self.gitea_url}/api/v1/users/{self.username}/tokens"
response = self.session.get(tokens_url)
if response.status_code == 200:
tokens = response.json()
if tokens:
return tokens[0]['sha1']
# Create new token
token_data = {
"name": f"auto-commit-{datetime.now().strftime('%Y%m%d')}",
"scopes": ["write:repository", "read:repository"]
}
response = self.session.post(tokens_url, json=token_data)
if response.status_code == 201:
return response.json()['sha1']
else:
raise Exception(f"Failed to create token: {response.text}")
def calculate_file_hash(self, file_path):
"""Calculate SHA1 hash for file (Go-Git compatible)."""
with open(file_path, 'rb') as f:
content = f.read()
sha1 = hashlib.sha1(content).hexdigest()
return sha1, len(content)
def create_file_content(self, file_path, relative_path):
"""Create file content entry for Gitea API."""
sha1, size = self.calculate_file_hash(file_path)
with open(file_path, 'rb') as f:
content = f.read()
encoded = base64.b64encode(content).decode('utf-8')
return {
"path": relative_path,
"sha": sha1,
"size": size,
"content": encoded,
"encoding": "base64"
}
def get_repo_tree(self, ref="master"):
"""Get current repository tree."""
url = f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/git/trees/{ref}"
response = self.session.get(url)
if response.status_code == 200:
return response.json()
else:
# Repository might be empty
return {"tree": [], "sha": None}
def find_changed_files(self, base_dir="."):
"""Find changed files by comparing with current tree."""
base_path = Path(base_dir)
changed_files = []
# Get current tree
current_tree = self.get_repo_tree()
current_files = {item['path']: item['sha'] for item in current_tree.get('tree', [])}
# Walk through directory
for file_path in base_path.rglob('*'):
if file_path.is_file():
# Skip .git directory and other ignored files
if '.git' in str(file_path):
continue
relative_path = str(file_path.relative_to(base_path))
# Calculate current hash
current_sha1, _ = self.calculate_file_hash(file_path)
# Check if file is new or modified
if relative_path not in current_files:
changed_files.append(("added", relative_path, file_path))
elif current_sha1 != current_files[relative_path]:
changed_files.append(("modified", relative_path, file_path))
return changed_files
def create_commit(self, message, changed_files, base_dir="."):
"""Create a commit using Gitea API."""
# Get current commit reference
ref_url = f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/git/refs/heads/master"
response = self.session.get(ref_url)
if response.status_code == 404:
# Branch doesn't exist yet (empty repo)
parent_sha = None
elif response.status_code == 200:
parent_sha = response.json()['object']['sha']
else:
raise Exception(f"Failed to get ref: {response.text}")
# Create tree with changed files
tree_items = []
for change_type, relative_path, file_path in changed_files:
if change_type in ["added", "modified"]:
file_content = self.create_file_content(file_path, relative_path)
tree_items.append({
"path": relative_path,
"mode": "100644", # Regular file
"type": "blob",
"sha": file_content["sha"]
})
# Create tree
tree_data = {
"base_tree": parent_sha,
"tree": tree_items
}
tree_url = f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/git/trees"
response = self.session.post(tree_url, json=tree_data)
if response.status_code != 201:
raise Exception(f"Failed to create tree: {response.text}")
tree_sha = response.json()['sha']
# Create commit
commit_data = {
"message": message,
"tree": tree_sha,
"parents": [parent_sha] if parent_sha else []
}
commit_url = f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/git/commits"
response = self.session.post(commit_url, json=commit_data)
if response.status_code != 201:
raise Exception(f"Failed to create commit: {response.text}")
commit_sha = response.json()['sha']
# Update reference
ref_data = {
"sha": commit_sha,
"force": False
}
response = self.session.patch(ref_url, json=ref_data)
if response.status_code != 200:
# Try to create the reference
ref_url = f"{self.gitea_url}/api/v1/repos/{self.repo_owner}/{self.repo_name}/git/refs"
ref_data = {
"ref": "refs/heads/master",
"sha": commit_sha
}
response = self.session.post(ref_url, json=ref_data)
if response.status_code != 201:
raise Exception(f"Failed to update ref: {response.text}")
return commit_sha
def auto_commit(self, message=None, base_dir="."):
"""Main auto-commit function using Go-Git API."""
if not message:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = f"Go-Git Auto-Commit: {timestamp}"
print(f"Go-Git Auto-Commit starting with message: {message}")
print("=" * 60)
# Find changed files
print("1. Scanning for changed files...")
changed_files = self.find_changed_files(base_dir)
if not changed_files:
print("No changes detected.")
return True
print(f"Found {len(changed_files)} changed files:")
for change_type, relative_path, _ in changed_files[:10]: # Show first 10
print(f" {change_type}: {relative_path}")
if len(changed_files) > 10:
print(f" ... and {len(changed_files) - 10} more")
# Create commit
print(f"\n2. Creating commit: '{message}'")
try:
commit_sha = self.create_commit(message, changed_files, base_dir)
print(f"Commit created successfully: {commit_sha}")
# Show commit URL
commit_url = f"{self.gitea_url}/{self.repo_owner}/{self.repo_name}/commit/{commit_sha}"
print(f"Commit URL: {commit_url}")
return True
except Exception as e:
print(f"Error creating commit: {e}")
return False
def main():
# Configuration
GITEA_URL = "https://git.mtrcompute.com"
USERNAME = "jleu3482"
PASSWORD = "jleu1212"
REPO_OWNER = "jleu3482"
REPO_NAME = "railseek6"
# Get commit message from command line
if len(sys.argv) > 1:
message = sys.argv[1]
else:
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
message = f"Go-Git Auto-Commit: {timestamp}"
print("Go-Git Auto-Commit Script for LightRAG")
print("=" * 60)
# Initialize Go-Git client
gogit = GoGitAutoCommit(GITEA_URL, USERNAME, PASSWORD, REPO_OWNER, REPO_NAME)
# Run auto-commit
success = gogit.auto_commit(message)
if success:
print("\n" + "=" * 60)
print("Go-Git auto-commit completed successfully!")
sys.exit(0)
else:
print("\n" + "=" * 60)
print("Go-Git auto-commit failed!")
sys.exit(1)
if __name__ == "__main__":
main()