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

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

问题描述

当您使用

  git rm --cached myfile 

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



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



编辑:澄清,我希望。

解决方案

我不认为Git commit可以记录像停止跟踪此文件但不删除它的意图。 b
$ b

制定这样的意图需要在合并(或重新绑定)删除文件的提交的任何存储库中的Git之外进行干预。






保存副本,应用删除,还原



可能最简单的做法是告诉下游用户保存复制文件,拉你的删除,然后恢复文件。
如果他们通过rebase拉动并且对文件进行携带修改,他们将会发生冲突。要解决这种冲突,请使用 git rm foo.conf&& git rebase --continue (如果冲突提交的内容除已删除文件以外的内容有变化)或 git rebase --skip

将文件还原为未拖拽后提取删除的文件



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

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

git checkout (每个评论由William Pursell提供;但请记住将其从索引中重新删除!) :

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

如果他们在删除您的删除操作后采取了其他操作他们可能需要一些不同于 @ @ {1} 的东西。他们可以在删除之前使用 git log -g 来查找提交。






在一个评论中,你提到你想要解开但保留的文件是运行软件所需的某种配置文件(直接存储在仓库中)。



将文件保存为默认并手动/自动激活它

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

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

通过这种违约机制,用户应该能够将一个提交重命名 foo.conf 改为 foo.conf.default ,而无需执行任何操作加班。
此外,如果将来还有其他安装/存储库,则可避免手动复制配置文件。



重写历史记录需要手动干预... h2>

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


  1. 保存
  2. 从重写中恢复。

  3. 恢复配置文件。

>




忽略它以防止复发



无论使用什么方法,可能希望将配置文件名包含在存储库中的 .gitignore 文件中,这样就不会有人无意中 git add foo.conf -f / - force )。
如果你有多个配置文件,你可能会考虑将它们全部移动到一个目录中,而忽略整个事物(通过移动我意思是改变程序希望找到它的配置文件的位置,用户(或启动/部署机制)将文件复制/移动到新的位置;显然,您不希望将文件git mv 移动到您将忽略的目录中)。


When you use

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?

Edit: Clarified, I hope.

解决方案

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

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


Save a Copy, Apply Deletion, Restore

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).

Restore File as Untracked After Pulling a Commit That Deletes It

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

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

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).

Keep File as a ‘Default’ and Manually/Automatically Activate It

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

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.

Rewriting History Requires Manual Intervention Anyway…

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. Save a copy of the configuration file.
  2. Recover from the rewrite.
  3. Restore the configuration file.


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天全站免登陆