gitRouter.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import os,json
  2. from fastapi import APIRouter,BackgroundTasks
  3. from models.gitModels import *
  4. from git import Repo
  5. from pydantic import BaseModel
  6. class RequestBody(BaseModel):
  7. uuid: str
  8. repo_url: str
  9. def generate_repo_path(uuid, repo_url):
  10. repo_name = repo_url.split("/")[-1].replace(".git", "")
  11. base_path = os.path.join("C:/Users/32965/repo", uuid)
  12. return os.path.join(base_path, repo_name), repo_name
  13. def get_repo(uuid, repo_url):
  14. path, _ = generate_repo_path(uuid, repo_url)
  15. if not os.path.exists(path):
  16. return 0
  17. return Repo(path)
  18. gitrouter=APIRouter()
  19. @gitrouter.post("/clone")
  20. async def clone(request: RequestBody, background_tasks: BackgroundTasks):
  21. local_path, repo_name = generate_repo_path(request.uuid, request.repo_url)
  22. if os.path.exists(local_path):
  23. return {"status": "400", "msg": "仓库已存在", "uuid": request.uuid, "repo_url": request.repo_url, "path": local_path}
  24. else:
  25. background_tasks.add_task(Repo.clone_from, request.repo_url, local_path)
  26. response= {"status":"200","msg": "成功创建克隆任务","uuid":request.uuid,"repoName":repo_name,"local_path":local_path}
  27. return response
  28. @gitrouter.post("/log")
  29. async def log(request: RequestBody):
  30. local_path, _ = generate_repo_path(request.uuid, request.repo_url)
  31. repo=get_repo(request.uuid,request.repo_url)
  32. if not repo:
  33. return {"status": "400", "msg": "仓库不存在", "uuid": request.uuid, "repo_url": request.repo_url,
  34. "local_path": local_path}
  35. log_=repo.git.log('--pretty={"commit":"%h","author":"%an","summary":"%s","date":"%cd"}', max_count=50,
  36. date='format:%Y-%m-%d %H:%M').split("\n")
  37. log=list(map(json.loads, log_))
  38. response= {"status":"200","msg": "成功获取日志","uuid":request.uuid,"repo_url":request.repo_url,
  39. "local_path":local_path,"git_log":log}
  40. return response
  41. @gitrouter.post("/status")
  42. async def status(request: RequestBody):
  43. repo=get_repo(request.uuid,request.repo_url)
  44. # 手动获取所有数据
  45. active_branch = repo.active_branch
  46. tracking_branch = active_branch.tracking_branch()
  47. ahead = sum(1 for _ in repo.iter_commits(f"{active_branch}..{tracking_branch}"))
  48. behind = sum(1 for _ in repo.iter_commits(f"{tracking_branch}..{active_branch}"))
  49. conflicts = repo.index.unmerged_blobs()
  50. conflicted = [path for path, entries in conflicts.items()]
  51. created_files = repo.untracked_files
  52. current = repo.active_branch.name
  53. head_commit = repo.head.commit
  54. tree = head_commit.tree
  55. all_files = [item.path for item in tree.traverse() if item.type == 'blob']
  56. diffs = repo.index.diff(None)
  57. deleted = [d.a_path for d in diffs if d.change_type == 'D']
  58. detached = repo.head.is_detached
  59. ignored_files = repo.git.execute(["git", "ls-files", "--others", "--ignored", "--exclude-standard"]).split("\n")
  60. modified_files = [d.a_path for d in diffs]
  61. untracked_files = repo.untracked_files
  62. staged_entries = repo.index.entries
  63. staged = [path[0] for path, _ in staged_entries.items()]
  64. tracking = active_branch.tracking_branch().name
  65. status = {"ahead": ahead, "behind": behind, "conflicted": conflicted, "created": created_files,
  66. "current": current,"deleted": deleted, "detached": detached, "files": all_files, "ignored": ignored_files,
  67. "modified": modified_files,"not_added": untracked_files, "staged": staged, "tracking": tracking}
  68. return status