管道中合并请求目标分支和源分支之间的GitLab差异

4

我的使用涉及查找合并请求与主分支或发布分支之间的差异(我想要进行差异比较的任何分支),合并请求将设置CI_MERGE_REQUEST_TARGET_BRANCH

CHANGED_DIRS=$(git diff --name-only ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...${CI_COMMIT_REF_NAME} | xargs -L1 dirname | uniq | cut -d'/' -f1 |tail -n+2 | uniq)

但是似乎gitlab无法识别合并请求的目标分支差异并给出此输出。

fatal: ambiguous argument 'master...source': unknown revision or path not in the working tree.

我该如何查找差异(即哪些是目录)。

感谢您的帮助!


不是没有 - 而是 git fetch 什么?默认情况下,GitLab 首先初始化仓库并执行 git add remote 和 checkout 分支(即合并请求分支)。您的意思是我在进行差异比较之前应该先执行 git fetch origin master 吗? - vgdub
get fetch 单独使用时,无需参数,它将获取所有的分支。默认情况下,GitLab首先初始化仓库,执行git add remote并checkout该分支(也就是合并请求分支)。不完全正确,GitLab-CI 在没有分支checkout的情况下会进入分离头状态,但这取决于配置。甚至还有一个默认的提交数目在项目配置中被检查,我想默认值为50个。 - KamilCuk
好的,仍然出现相同的错误,我很惊讶它在本地可以运行但在GitLab CI中却不行,很奇怪。* [新分支] master -> origin/master 致命错误:模糊参数 'origin/master...whatever':未知的修订或路径不在工作树中。 - vgdub
但是是的,git fetch确实正确获取了所有分支。因此在本地,我认为它必须具有与我的本地相同的结构。 - vgdub
git fetch && git checkout ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME} && git pull,这个命令可行。 - vgdub
显示剩余2条评论
3个回答

5

正如之前提到的,这是因为GitLab-CI执行的是浅克隆而不是完整克隆。然而,与其设计一种方法来进行完整克隆或使用远程比较,我使用了GitLab-CI中的内置变量:CI_MERGE_REQUEST_DIFF_BASE_SHA

要获取文件,请使用: git diff --name-only ${CI_MERGE_REQUEST_DIFF_BASE_SHA}

CI_MERGE_REQUEST_DIFF_BASE_SHA - 合并请求差异的基本SHA。Ref


4
我通过更改命令来解决这个错误,将命令从 git diff --name-only ${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...${CI_COMMIT_REF_NAME} 改为 git diff --name-only remotes/origin/${CI_MERGE_REQUEST_TARGET_BRANCH_NAME}...remotes/origin/${CI_COMMIT_REF_NAME}
看起来GitLab Runner没有任何本地分支。因此,我们必须告诉它比较远程分支之间的差异。

3
这不是一个真正的Git问题,而是一个GitLab-CI问题。然而,在多个CI/CD系统中都会出现这些特定的问题,总是有相同的一般原因:
  • 克隆大型存储库需要很长时间。
  • CI系统通常通过克隆存储库来开始工作。
  • 因此,CI系统通常从存储库中进行不完全克隆
  • Git过去只提供了两种方法来做到这一点:1浅克隆单分支克隆。实际上,它们倾向于一起使用:使用git clone --depth number进行浅克隆,也会进行单分支克隆,除非你通过添加--no-single-branch来强制覆盖Git的默认设置。
现在,任何CI/CD系统中的克隆命令可能是可控的,或者可能由CI/CD系统在提供给您作为开发人员的任何软件旋钮之前完成。如果您可以影响命令,那通常是正确的方法,但如果不能,您仍然可以通过运行其他Git命令来纠正问题(这又取决于CI/CD系统):
- `git remote set-branches --add` 允许您将各种分支添加到除单个分支克隆之外的克隆中; - `git fetch --depth `,`git fetch --deepen ` 和 `git fetch --unshallow` 是三种改变现有浅克隆深度或完全删除深度限制的方法。
如果您的CI/CD系统创建了一个浅层、单分支克隆,并且您需要一个具有更多远程跟踪名称的更深层次的克隆,则可以使用 `git remote` 和/或 `git fetch` 来实现。
由于我没有使用过GitLab的CI系统,因此我无法在这里提供具体步骤,但根据评论,听起来他们默认使用--depth 50。 如果您有深度控制开关,则将其设置为零(0)是禁用--depth参数的常规方法,这也会禁用单分支性。
请注意,无论系统如何克隆您的存储库,您通常只会拥有一个分支名称,甚至可能没有任何分支(分离的HEAD)当通过标签进行克隆时。 完整克隆将拥有完整的远程跟踪名称集合,而单分支克隆将仅有一个远程跟踪名称,直到您使用git remote调整此设置并运行后续的git fetch以添加更多远程跟踪名称。
对于GitHub Actions,v2 checkout默认进行浅层单分支克隆,而v1 checkout则进行完整克隆。
现在有第三种方法,所谓的“部分克隆”和“承诺远程”。这可能是CI系统实现的正确方式,但由于许多原因,部分克隆还不够好,因此这可能需要等待实现方面的改进。

感谢@torek,我现在对fetch的深度有了更好的理解,所以我现在对我的主分支/发布分支执行git fetch --depth 30。问题实际上出在Gitlab上,就像你的Merge Requests(即Pull requests)一样,它们将其标记为新的refs/merge_requests/:id/,如果您想要执行git diff merge_request....master,它无法识别master,因为它认为只有一个分支,所以在CI运行的容器中,我不得不本地获取和克隆主分支/发布分支,以便我可以得到正确的差异来工作。但是你的答案在克隆方面是完美的。 - vgdub

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接