Skip to content

code status: behind_count 在 local_head 领先 remote_head 时误报大量落后 #18

Description

@Guo-Zhang

Bug

qtcloud-devops code status 中,当子模块的 local_head 领先于 remote_head(即本地有未推送提交、且父仓库记录的指针恰好等于 local_head)时,behind_count 会错误地回溯到根 commit,显示大量虚假的"落后"提交数。

复现步骤

  1. 在子模块中创建 1 个本地提交,但不推送
  2. 父仓库记录该子模块指针为 local_head
  3. 运行 qtcloud-devops code status

实际结果

status 显示 冲突(落后 N 提交),其中 N 是 local_head 到根 commit 的父链总长度(非 local_head..remote_head 的实际距离)。

期望结果

local_head 领先于 remote_head 时,behind_count 应为 0,status 应为 AheadOfParent待推送)。

根因

git.rsscan_single_submodule 第 396-407 行:

let ahead = sm_repo
    .as_ref()
    .map(|r| gix_count_between(r, *parent_pointer, local_head))
    .unwrap_or(0);
let behind = if remote_unreachable {
    0
} else {
    sm_repo
        .as_ref()
        .map(|r| gix_count_between(r, local_head, remote_head))
        .unwrap_or(0)
};

gix_count_between(from, to) 只单向从 to 往 parent 回溯,直到遇到 from。但如果 local_headremote_head 的后代(即本地领先),回溯永远不会遇到 local_head,会一直走到根 commit 才停下,导致 behind 被错误地设置为整个历史长度。

修复建议

scan_single_submodule 中计算 behind 前先判断 local_head 是否为 remote_head 的祖先(用 gix_count_between(local_head, remote_head) 能否到达 local_head),若不是则 behind = 0is_orphaned 的判断也需考虑这种情况。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions