diff --git a/API.md b/API.md index b5acaf3..c534999 100644 --- a/API.md +++ b/API.md @@ -57,14 +57,15 @@ SYNC_DIR = os.getenv("SYNC_DIR", "/tmp/sync_dir/") } ``` ## 仓库粒度同步 -允许用户通过此接口执行单个仓库同步。 +允许用户通过此接口执行单个仓库同步(或强制同步)。 - **URL**:`/cerobot/sync/repo/{repo_name}` - **Method**:`POST` ### 请求参数(body) -| 参数 | 类型 | 示例输入 | 是否必须 | 说明 | -| --- | --- | --- | --- | --- | -| repo_name | string | | yes | 仓库名称 | +| 参数 | 类型 | 示例输入 | 是否必须 | 说明 | +| --- |--------| --- |------|--------| +| repo_name | string | | yes | 仓库名称 | +| force_flag | bool | | no | 是否强制同步 | ### 成功响应 **条件**:同步执行成功。
**状态码:**`0 操作成功`
**响应示例**: @@ -85,16 +86,17 @@ SYNC_DIR = os.getenv("SYNC_DIR", "/tmp/sync_dir/") } ``` ## 分支粒度同步 -允许用户通过此接口执行单个分支同步。 +允许用户通过此接口执行单个分支同步(或强制同步)。 - **URL**:`/cerobot/sync/{repo_name}/branch/{branch_name}` - **Method**:`POST` ### 请求参数(body) -| 参数 | 类型 | 示例输入 | 是否必须 | 说明 | -|-------------| --- | --- | --- |-------| -| repo_name | string | | yes | 仓库名称 | +| 参数 | 类型 | 示例输入 | 是否必须 | 说明 | +|-------------| --- | --- | --- |--------------------------------------------| +| repo_name | string | | yes | 仓库名称 | | sync_direct | int | 1/2 | yes | 同步方向:
1 表示内部仓库同步到外部
2 表示外部仓库同步到内部 | -| branch_name | string | | yes | 分支名称 | +| branch_name | string | | yes | 分支名称 | +| force_flag | bool | | no | 是否强制同步 | 注: 仓库由内到外同步时,分支输入内部仓库分支名;仓库由外到内同步时,分支输入外部仓库分支名; ### 成功响应 diff --git a/src/api/Sync_config.py b/src/api/Sync_config.py index d5a0d16..274b26e 100644 --- a/src/api/Sync_config.py +++ b/src/api/Sync_config.py @@ -137,7 +137,8 @@ class SyncDirection(Controller): @router.post("/repo/{repo_name}", response_model=SYNCResponse, description='执行仓库同步') async def sync_repo( self, request: Request, user: str = Depends(user), - repo_name: str = Path(..., description="仓库名称") + repo_name: str = Path(..., description="仓库名称"), + force_flag: bool = Query(False, description="是否强制同步") ): api_log(LogType.INFO, f"用户 {user} 使用 POST 方法访问接口 {request.url.path} ", user) repo = await self.service.get_repo(repo_name=repo_name) @@ -147,7 +148,7 @@ class SyncDirection(Controller): return SYNCResponse(code_status=Status.NOT_ENABLE.code, msg=Status.NOT_ENABLE.msg) try: - await sync_repo_task(repo, user) + await sync_repo_task(repo, user, force_flag) except GITMSGException as GITError: return SYNCResponse( code_status=GITError.status, @@ -164,7 +165,8 @@ class SyncDirection(Controller): self, request: Request, user: str = Depends(user), repo_name: str = Path(..., description="仓库名称"), branch_name: str = Path(..., description="分支名称"), - sync_direct: int = Query(..., description="同步方向: 1 表示内部仓库同步到外部, 2 表示外部仓库同步到内部") + sync_direct: int = Query(..., description="同步方向: 1 表示内部仓库同步到外部, 2 表示外部仓库同步到内部"), + force_flag: bool = Query(False, description="是否强制同步") ): api_log(LogType.INFO, f"用户 {user} 使用 POST 方法访问接口 {request.url.path} ", user) repo = await self.service.get_repo(repo_name=repo_name) @@ -179,7 +181,7 @@ class SyncDirection(Controller): return SYNCResponse(code_status=Status.NOT_ENABLE.code, msg=Status.NOT_ENABLE.msg) try: - await sync_branch_task(repo, branches, direct, user) + await sync_branch_task(repo, branches, direct, user, force_flag) except GITMSGException as GITError: return SYNCResponse( code_status=GITError.status, diff --git a/src/service/cronjob.py b/src/service/cronjob.py index 80fdcd5..03e4134 100644 --- a/src/service/cronjob.py +++ b/src/service/cronjob.py @@ -70,17 +70,17 @@ def init_repos(repo, log_name: str, user: str): exter_repo_addr = get_repo_address_with_token(repo.external_repo_address, repo.exter_token) if repo.sync_direction == SyncDirect.to_outer: # 克隆内部仓库到同步目录下 - shell(f'git clone -b master {inter_repo_addr} {repo_dir}', SYNC_DIR, log_name, user) + shell(f'git clone {inter_repo_addr} {repo_dir}', SYNC_DIR, log_name, user) else: # 克隆外部仓库到同步目录下 - shell(f'git clone -b master {exter_repo_addr} {repo_dir}', SYNC_DIR, log_name, user) + shell(f'git clone {exter_repo_addr} {repo_dir}', SYNC_DIR, log_name, user) # 添加internal远程仓库,并强制使用 shell(f'git remote add -f internal {inter_repo_addr}', repo_dir, log_name, user) # 添加external远程仓库,并强制使用 shell(f'git remote add -f external {exter_repo_addr}', repo_dir, log_name, user) -def inter_to_outer(repo, branch, log_name: str, user: str): +def inter_to_outer(repo, branch, log_name: str, user: str, force_flag): repo_dir = os.path.join(SYNC_DIR, repo.repo_name) inter_name = branch.internal_branch_name outer_name = branch.external_branch_name @@ -90,7 +90,10 @@ def inter_to_outer(repo, branch, log_name: str, user: str): # 切换到inter_name分支,并将internal仓库的分支强制 checkout 到当前分支。 shell(f"git checkout -B {inter_name} internal/{inter_name}", repo_dir, log_name, user) # 将本地仓库的inter_name分支推送到external仓库的outer_name分支上。 - shell(f"git push external {inter_name}:{outer_name}", repo_dir, log_name, user) + if force_flag: + shell(f"git push --force external {inter_name}:{outer_name}", repo_dir, log_name, user) + else: + shell(f"git push external {inter_name}:{outer_name}", repo_dir, log_name, user) # commit id # result = shell(f"git log HEAD~1..HEAD --oneline", repo_dir, log_name, user) # commit_id = result.stdout.split(" ")[0] @@ -102,7 +105,7 @@ def inter_to_outer(repo, branch, log_name: str, user: str): raise -def outer_to_inter(repo, branch, log_name: str, user: str): +def outer_to_inter(repo, branch, log_name: str, user: str, force_flag): repo_dir = os.path.join(SYNC_DIR, repo.repo_name) inter_name = branch.internal_branch_name outer_name = branch.external_branch_name @@ -112,7 +115,10 @@ def outer_to_inter(repo, branch, log_name: str, user: str): # 切换到本地仓库的outer_name分支,并将origin仓库的outer_name分支强制 checkout 到当前分支。 shell(f"git checkout -B {outer_name} external/{outer_name}", repo_dir, log_name, user) # 将本地仓库的outer_name分支推送到internal仓库的inter_name分支上。 - shell(f"git push internal {outer_name}:{inter_name}", repo_dir, log_name, user) + if force_flag: + shell(f"git push --force internal {outer_name}:{inter_name}", repo_dir, log_name, user) + else: + shell(f"git push internal {outer_name}:{inter_name}", repo_dir, log_name, user) # commit id # result = shell(f"git log HEAD~1..HEAD --oneline", repo_dir, log_name, user) # commit_id = result.stdout.split(" ")[0] @@ -124,7 +130,7 @@ def outer_to_inter(repo, branch, log_name: str, user: str): raise -async def sync_repo_task(repo, user): +async def sync_repo_task(repo, user, force_flag): if repo.sync_granularity == SyncType.one: branches = await sync_branch_dao.sync_branch(repo_id=repo.id) await sync_branch_task(repo, branches, repo.sync_direction, user) @@ -142,7 +148,7 @@ async def sync_repo_task(repo, user): branch_name = branch.split('/')[-1].strip() branch = SyncBranchDTO(enable=1, internal_branch_name=branch_name, external_branch_name=branch_name) sync_log(LogType.INFO, f'Execute inter to outer {branch_name} branch Sync', log_name, user) - inter_to_outer(repo, branch, log_name, user) + inter_to_outer(repo, branch, log_name, user, force_flag) else: exter_repo_addr = get_repo_address_with_token(repo.external_repo_address, repo.exter_token) stm = shell(f"git ls-remote --heads {exter_repo_addr}", SYNC_DIR, log_name, user) @@ -152,7 +158,7 @@ async def sync_repo_task(repo, user): branch_name = branch.split('/')[-1].strip() branch = SyncBranchDTO(enable=1, internal_branch_name=branch_name, external_branch_name=branch_name) sync_log(LogType.INFO, f'Execute outer to inter {branch_name} branch Sync', log_name, user) - outer_to_inter(repo, branch, log_name, user) + outer_to_inter(repo, branch, log_name, user, force_flag) sync_log(LogType.INFO, f'************ {repo.repo_name}仓库同步完成 ************', log_name, user) finally: if config.DELETE_SYNC_DIR: @@ -163,7 +169,7 @@ async def sync_repo_task(repo, user): os.remove(os.path.join(log_path, log_name)) -async def sync_branch_task(repo, branches, direct, user): +async def sync_branch_task(repo, branches, direct, user, force_flag): for branch in branches: log_name = f'sync_{repo.repo_name}_{branch.id}.log' @@ -173,10 +179,10 @@ async def sync_branch_task(repo, branches, direct, user): sync_log(LogType.INFO, f'************ 执行分支同步 ************', log_name, user) if direct == SyncDirect.to_inter: sync_log(LogType.INFO, f'Execute outer to inter {branch.external_branch_name} branch Sync', log_name, user) - commit_id = outer_to_inter(repo, branch, log_name, user) + commit_id = outer_to_inter(repo, branch, log_name, user, force_flag) else: sync_log(LogType.INFO, f'Execute inter to outer {branch.internal_branch_name} branch Sync', log_name, user) - commit_id = inter_to_outer(repo, branch, log_name, user) + commit_id = inter_to_outer(repo, branch, log_name, user, force_flag) sync_log(LogType.INFO, f'************ 分支同步完成 ************', log_name, user) finally: if config.DELETE_SYNC_DIR: