将Git工作目录转换为类似裸仓库的存储库?

5
我们的开发环境使用多个仓库作为整个构建系统的一部分。构建会根据您检出的仓库动态适应:如果您不需要构建特定组件,只需不克隆它即可。
但是,一旦您已经克隆了一个组件,从构建中删除它就很棘手:
  • 您可以删除工作目录中的文件,但git status将显示未提交的更改
  • 您可以删除仓库,但这样做需要再次克隆时付出代价
  • 您可以移动仓库,但您的多仓库工具可能会“有益地”重新克隆
是否有更好的方法来删除工作目录中的文件?类似于hg co nullp4 sync ...#none的东西?
3个回答

3

在找到了一些不太符合我的需求的类似 问题之后,这篇文章给出了答案:创建一个空分支。

git checkout --orphan empty
git rm -rf .
git commit --allow-empty -m "An empty working directory"

当然,在进行以下操作之前,请确保您已经将任何重要文件提交到您的仓库中。我称这个分支为empty,但是您可以通过checkout命令给它任何名称。
设置完成后,您可以切换到任何一个分支来获取您的文件:
git checkout master

当您需要“移除”工作目录时,请提交更改,然后运行以下命令:
git checkout empty

这将删除所有已跟踪的文件。如果您还需要删除未跟踪的文件和目录,请执行以下操作:

git clean -fdx

1
您可以使用 --assume-unchanged 功能:
git ls-files big-unused-component | xargs git update-index --assume-unchanged

然后,您可以删除您的文件:

rm -rf big-unused-component

第一个命令列出了big-unused-component目录中所有已跟踪的文件,然后update-index --assume-unchanged在Git索引中设置“假定此文件未更改”的标志。然后,当您删除整个目录时,Git不会将其视为更改。
要撤消上一个命令的效果,请使用--no-assume-unchanged重复执行它。git ls-files -v命令可以向您显示以这种方式被忽略的文件。

1
这个命令比 git checkout empty 更难记。 - Syeberman
@Syeberman:我担心我无法看出创建一个空分支如何解决您的问题。难道创建一个分支不会从存储库中删除所有文件吗? - Greg Hewgill
实际上,那正是我想要做的事情。Mercurial有hg co null,而Perforce有p4 sync ...#none。我需要一种方法来删除已跟踪的文件,同时仍然保留.git目录中所有的历史记录。 - Syeberman

0

git clean 可以使用各种参数来删除未检入和提交的项目,听起来比你上面想出的任何选项都要好得多。创建一个新分支似乎完全不符合直觉,提交虚假更改以擦除东西只是为了单独恢复也是如此。

对于我自己的许多 CI 构建脚本,我确实使用类似这样的东西来确保构建区域与 git 的内容完全一致:git clean -f -x -d

然而,进一步阅读后,您的问题的混乱性变得稍微更加明显。听起来您在一个共同的文件夹中有多个单独的存储库,并且您的“构建”过程单独使用它们进行各种操作。

我可以想出两种明显的方法来解决问题:
1. 子树合并:创建一个仓库/分支,其唯一目的是将其他仓库的所需版本子树合并在一起,以便您拥有可重复的构建
2. 在“构建”目录中使用符号链接,以便您可以清除不想参与给定构建的存储库的符号链接,而不会清除存储库的存在,只需稍后重新克隆即可。


那会删除未跟踪的文件和目录,是的。我需要的是一种暂时删除已跟踪文件的方法。 - Syeberman
更新。此外,删除已跟踪的文件意味着您在错误地使用 Git。也许,您可以直接提出关于您想要实现的目标的问题,而不是询问如何实施涉及众多糟糕实践的奇怪方案。 - UpAndAdam
我应该澄清一下我的上述声明;删除已跟踪的文件本身并不是错误的。这当然就是为什么存在git rm:-p。我试图说的是,仅仅为了“构建”而删除它们,并不是真正意义上的从GIT中删除它们,这是“错误”的。 - UpAndAdam
无论对错,这就是我所处的开发环境。 - Syeberman

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