Git:如何从索引中删除文件而不从任何存储库中删除文件 [英] Git: How to remove file from index without deleting files from any repository

查看:31
本文介绍了Git:如何从索引中删除文件而不从任何存储库中删除文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用时

git rm --cached myfile

它不会从本地文件系统中删除,这是目标.但是,如果您已经对文件进行了版本控制和提交,将其推送到中央存储库,然后在使用该命令之前将其拉入另一个存储库,则它会从该系统中删除该文件.

it doesn't delete from the local filesystem, which is the goal. But if you've already versioned and committed the file, pushed it to a central repository, and pulled it into yet another repository before using the command, it will delete the file from that system.

有没有办法只从版本控制中删除文件而不从任何文件系统中删除它?

Is there a way to just remove the file from versioning without deleting it from any filesystem?

澄清,我希望.

推荐答案

我不认为 Git 提交可以记录停止跟踪此文件,但不要删除它"这样的意图.

I do not think a Git commit can record an intention like "stop tracking this file, but do not delete it".

要实现这样的意图,需要在 Git 之外对任何合并(或变基到)删除文件的提交的存储库进行干预.

Enacting such an intention will require intervention outside Git in any repositories that merge (or rebase onto) a commit that deletes the file.

可能最简单的方法是告诉您的下游用户保存文件的副本,删除您的删除内容,然后恢复文件.如果他们通过 rebase 拉取并携带"对文件的修改,他们就会发生冲突.要解决此类冲突,请使用 git rm foo.conf &&git rebase --continue(如果冲突提交除了删除的文件之外还有其他更改)或 git rebase --skip(如果冲突提交仅更改为删除的文件).

Probably the easiest thing to do is to tell your downstream users to save a copy of the file, pull your deletion, then restore the file. If they are pulling via rebase and are ‘carrying’ modifications to the file, they will get conflicts. To resolve such conflicts, use git rm foo.conf && git rebase --continue (if the conflicting commit has changes besides those to the removed file) or git rebase --skip (if the conflicting commit has only changed to the removed file).

如果他们已经拉取了你的删除提交,他们仍然可以使用 git show:

If they have already pulled your deletion commit, they can still recover the previous version of the file with git show:

git show @{1}:foo.conf >foo.conf

或者使用 git checkout(根据 William 的评论Pursell;但请记住将其从索引中重新删除!):

Or with git checkout (per comment by William Pursell; but remember to re-remove it from the index!):

git checkout @{1} -- foo.conf && git rm --cached foo.conf

如果他们在拉取您的删除后采取了其他操作(或者他们通过 rebase 拉入分离的 HEAD),则他们可能需要 @{1} 以外的其他内容.他们可以使用 git log -g 在删除您的删除之前找到提交.

If they have taken other actions since pulling your deletion (or they are pulling with rebase into a detached HEAD), they may need something other than @{1}. They could use git log -g to find the commit just before they pulled your deletion.

在评论中,您提到要取消跟踪但保留"的文件是运行软件(直接从存储库外)所需的某种配置文件.

In a comment, you mention that the file you want to "untrack, but keep" is some kind of configuration file that is required for running the software (directly out of a repository).

如果继续在存储库中维护配置文件的内容并非完全不可接受,您可以将跟踪文件从(例如)foo.conf 重命名为 foo.conf.default 然后在应用重命名提交后指示您的用户 cp foo.conf.default foo.conf.或者,如果用户已经使用存储库的某些现有部分(例如脚本或由存储库中的内容(例如 Makefile 或类似)配置的其他程序)来启动/部署您的软件,您可以在启动/部署过程中加入默认机制:

If it is not completely unacceptable to continue to maintain the configuration file's content in the repository, you might be able to rename the tracked file from (e.g.) foo.conf to foo.conf.default and then instruct your users to cp foo.conf.default foo.conf after applying the rename commit. Or, if the users already use some existing part of the repository (e.g. a script or some other program configured by content in the repository (e.g. Makefile or similar)) to launch/deploy your software, you could incorporate a defaulting mechanism into the launch/deploy process:

test -f foo.conf || test -f foo.conf.default &&
    cp foo.conf.default foo.conf

有了这样的默认机制,用户应该能够拉取一个将 foo.conf 重命名为 foo.conf.default 的提交,而无需做任何额外的事情工作.此外,如果您将来进行其他安装/存储库,则不必手动复制配置文件.

With such a defaulting mechanism in place, users should be able to pull a commit that renames foo.conf to foo.conf.default without having to do any extra work. Also, you avoid having to manually copy a configuration file if you make additional installations/repositories in the future.

如果在存储库中维护内容是不可接受的,那么您可能希望使用诸如 git filter-branch --index-filter ....这相当于重写历史记录,这将需要对每个分支/存储库进行手动干预(请参阅 git rebase 手册页).配置文件所需的特殊处理只是从重写中恢复时必须执行的另一个步骤:

If it is unacceptable to maintain the content in the repository then you will likely want to completely eradicate it from history with something like git filter-branch --index-filter …. This amounts to rewriting history, which will require manual intervention for each branch/repository (see "Recovering From Upstream Rebase" section in the git rebase manpage). The special treatment required for your configuration file would be just another step that one must perform while recovering from the rewrite:

  1. 保存配置文件的副本.
  2. 从重写中恢复.
  3. 恢复配置文件.

<小时>

忽略它以防止再次发生

无论您使用哪种方法,您可能都希望将配置文件名包含在存储库中的 .gitignore 文件中,以便没有人可以在不经意间 git add foo.conf再次(这是可能的,但需要 -f/--force).如果您有多个配置文件,您可能会考虑将它们全部移动"到一个目录中并忽略整个内容(移动"是指更改程序期望找到其配置文件的位置,并获取用户(或启动/部署机制)将文件复制/移动到它们的新位置;您显然不希望 git mv 将文件放入您将忽略的目录中).


Ignore It to Prevent Recurrence

Whatever method you use, you will probably want to include the configuration filename in a .gitignore file in the repository so that no one can inadvertently git add foo.conf again (it is possible, but requires -f/--force). If you have more than one configuration file, you might consider ‘moving’ them all into a single directory and ignoring the whole thing (by ‘moving’ I mean changing where the program expects to find its configuration files, and getting the users (or the launch/deploy mechanism) to copy/move the files to to their new location; you obviously would not want to git mv a file into a directory that you will be ignoring).

这篇关于Git:如何从索引中删除文件而不从任何存储库中删除文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆