如何从合并请求中删除跟踪的文件

Posted

技术标签:

【中文标题】如何从合并请求中删除跟踪的文件【英文标题】:How do I remove a tracked file from merge request 【发布时间】:2022-01-13 13:29:31 【问题描述】:

我已经提交了一些文件并将其推送到远程功能分支并创建了一个合并请求。我用过

git commit -a -m "blah blah"
git push

所以它推送了所有修改过的文件。不应该推送其中一个文件(这是主文件中的现有文件)(例如可执行文件)。如何从合并请求中删除此文件,以便当 MR 合并到 master 时,不需要的文件不会被合并(好像它从未在 MR 中存在)。我发现这个page 提到了以下命令

git rm filename --cached
git commit -m "[...]"
git push

我尝试了这些命令,但在 Gitlab 的合并请求中没有看到文件被删除。这是正确的做法吗?

更新1:

使用上面的命令,我可以在上面的提交中看到deleted 提到的文件。但是当我将更新的 MR 合并到 master 时,该文件也会从 master 中删除。

更新2:

删除引起混淆的句子并更新标题

【问题讨论】:

您在删除文件之前检查了合并请求分支吗? 【参考方案1】:

你使用的是什么版本的 Gitlab?

刚刚使用最新版本 (14.5.2) 进行了测试:

git checkout -b feature-123
git add package.json package-lock.json
git commit -m 'Commit with extra file.'
git push --set-upstream origin feature-123

创建 MR,显示两个文件已更改

现在,从同一个分支:

git rm --cached package-lock.json
git commit -m 'Removing extra file.'
git push

MR 现在只显示一个修改过的文件。

但如果这个 MR 在没有 squash 的情况下被接受,git 历史记录将包含添加和删除额外文件。

如果您提交了一个非常大的文件,最好让维护者在合并之前压缩您的更改。或者删除 MR 并通过一次提交创建一个新的。

【讨论】:

在我的功能/测试分支中,我只推送了一个文件README.md。我按照您的命令删除了该文件。我可以在合并请求README.md deletedChanges 下看到。所以现在如果我与Squash commits when merge request is accepted 合并到主分支中,我应该看到主分支中没有任何变化......对吗? 是的,您将看到一个提交,其中包含对您的分支所做的所有更改的最终结果。 @ontherocks 如果您只更改 1 个文件并删除该 1 个文件进行测试,您应该不会看到任何更改,并且 MR 应该没有文件更改(您应该能够在之前看到你完成它)。如果你完成它并 squash,它应该什么都不做(或者可能创建一个没有更改的空提交)。但是,如果您 squash,您将向目标分支添加两个提交,并且总共没有任何更改 - 自述文件仍将作为添加然后删除在历史记录中。 @TTT 不幸的是,合并到 master 后,master 的 README.md 文件不见了:( @ontherocks 好的-那是因为最初的问题让我们找错了树。 :D 更新现在更清楚了。【参考方案2】:

更新:根据更新后的问题,我们现在知道您正在尝试撤消您对提交中已跟踪的文件所做的修改。请注意,您关于 .gitignore 的陈述具有误导性,因为 .gitignore 用于 未跟踪 文件。一旦跟踪它,就不能使用.gitignore 文件忽略它。

实现目标的一种方法是简单地撤消对文件的更改。如果您的分支上的最新提交是您需要更改的提交,那么只需修改它。如果不是,则使用您的更改创建一个新的提交,以撤消先前的更改,然后交互式地重新设置您的分支并将这个新的提交压缩到前一个中。这在here 中有更详细的描述。如果您从未使用过,交互式 rebase 是 Git 的一个很棒的功能,我建议大家学习它,尽管一开始有点令人生畏。

原始答案(主要针对如何撤消新添加的文件,该文件在问题更新后不再相关):

合并请求(在其他 SCM 工具中也称为拉取请求)是一种正式的方式,用于对源分支(您的)进行代码审查并将更改合并到目标分支(通常是共享分支,例如 main、@ 987654328@、develop等)

鉴于此,有多种方法可以从合并请求中删除文件,例如:

    按照您的建议,您可以向源分支添加新的提交,从而有效地撤消对您不再希望包含的文件的更改。这可能意味着撤消对现有跟踪文件的更改,或删除未跟踪文件。正如xy2's answer 中指出的那样,添加额外提交以删除文件的缺点是,除非您在完成 MR 时 squash,否则不需要的文件将保留在历史记录中。 通常更好的方法是从包含它们的提交中删除文件。这在这个问题中有详细描述:Remove files from Git commit。在本地分支上重写提交以不再包含您希望删除的文件后,您将需要再次强制推送您的分支:git push --force-with-lease。 (注意 --force-with-lease 通常是使用 --force 的良好默认值。)推送分支后,您的 MR 应自动更新为不包括文件的分支的最新版本。

旁注:尽管我个人倾向于选项 #2,但您描述的选项 #1 的尝试应该在概念上有效。我怀疑你并没有完全按照你认为你对你的分支所做的那样做。

【讨论】:

阅读选项#2的另一个问题,我可以收集到git reset --soft HEAD^,然后是git commit -c ORIG_HEAD,然后是git push --force-with-lease,然后将更新的MR合并到master中 @ontherocks 很接近,但您仍然需要在软重置后取消暂存有问题的文件,然后重新提交。这仅在它是最近的提交时才有效,如果是这样,修改它可能会稍微容易一些。我刚刚更新了答案以反映您的问题更新。 所以简单来说,没有办法从MR中删除跟踪的文件。只需撤消更改(即使其与 master 中的相同)并使其成为 MR 的一部分。然后,当您将其合并到 master 中时,该文件实际上是在 master 中替换自身。

以上是关于如何从合并请求中删除跟踪的文件的主要内容,如果未能解决你的问题,请参考以下文章

如何从当前 Git 工作树中删除本地(未跟踪)文件

如何从Git跟踪文件中删除Redis文件dump.rdb

如何从从 git 克隆的项目中删除版本跟踪?

如何在不删除任何文件的情况下从跟踪中分离文件夹?

如何修剪远程不再存在的本地跟踪分支

nxlog 如何跟踪行号?