该索引在您的工作站本地,您在那里所做的任何更改都不会传播到同一远程的其他克隆。
(更新,问题更新后)
.gitignore 文件
在某些情况下,我不能使用 .gitignore 文件,否则,在 git push 上,关键文件会从远程清除。
这不是真的。git ignore 文件不会影响已在存储库中跟踪的文件。如果您在提交文件.gitignore
后添加文件,它将保留在存储库中;它不会被清除。事实上,它的行为就好像它根本没有被忽略一样。
您可以在临时存储库中轻松检查:
$ mkdir -p /tmp/repo
$ cd /tmp/repo
$ git init
Initialized empty Git repository in /tmp/repo/.git/
$ echo red > a.txt
$ git commit -am '1'
1 file changed, 1 insertion(+)
create mode 100644 a.txt
$ echo a.txt > .gitignore
$ echo b.txt >> .gitignore
$ git commit -am '2'
1 file changed, 2 insertions(+)
create mode 100644 .gitignore
存储库现在包含两个文件:a.txt
和.gitignore
. 两者都表现正常,您可以在克隆它时看到:
$ cd ..
$ git clone file://repo repo2
$ ls -A repo2
.git .gitignore a.txt
$ cd repo
如果我们同时修改忽略的文件和请求git status
,我们会看到它a.txt
被视为已修改,尽管已被 gitignored。我们可以正常添加和提交;实际上,如果您将跟踪文件添加到 gitignore,它的行为就像它根本不在 gitignore 中一样。
$ echo green > a.txt
$ echo blue > b.txt
$ git status --short
M a.txt
$ git add a.txt
该b.txt
文件不同,因为在 git 开始跟踪它之前它被忽略了。该文件通常不会进入存储库,但如果我们愿意,我们可以强制它。
$ git add b.txt
The following paths are ignored by one of your .gitignore files:
b.txt
Use -f if you really want to add them.
fatal: no files added
$ git add -f b.txt
发布git commit
现在提交两个都被 git 忽略的文件:
$ git commit -m '3'
2 files changed, 1 insertion(+), 1 deletion(-)
create mode 100644 b.txt
长话短说,将 git 忽略规则视为指南 :-)
传播假设不变
在应用假设不变的规则并调用 git push 后,这些规则是否会附加到远程分支,以便所有后续拉取(来自其他客户端)将继承它们?或者,这些客户端是否也必须在他们的机器上单独运行 git update-index --assume-unchanged 命令?
后者。您可以获得的最接近的方法是将 shell 脚本添加到为您进行更改的存储库中。
服务器挂钩?
如果命令没有被继承——之前有没有人为此编写过服务器挂钩?而不是强制所有当前和未来的客户防范它?
如果您的目标是编写一个服务器挂钩来删除关键文件,就好像它们根本不是推送的一部分,那是不可能的。Git push 主要处理提交 对象(和refs)。它们的依赖对象,如树和 blob,根据需要传输,受提交的可达性影响。它归结为,如果它没有被提交,你就不能将它推送到远程(这是一个过度简化,但它适用于存储库中的文件)。此外,git 提交受到加密保护。如果不更改提交哈希,则无法更改提交,并且如果更改提交哈希,则基本上会有不同的新提交(可能恰好与旧提交具有相同的差异)。
这意味着服务器不能重写提交;至少不会严重混淆进行推送的客户端(它仍然会有旧提交对象的副本)。
您可以做的是编写一个 post-receive 钩子,如果它们包含您不想更新的文件,则拒绝提交。这并不能真正解决您的问题,因为如果您在git commit --assume-unchanged
向同事解释时遇到困难,那么您可能会在解释他们如何使用交互式 rebase 来重新创建他们的提交而不包含不需要的文件时遇到更多麻烦。
长话短说,我认为如果您正在处理应该提交一次且此后永远不会提交的文件,就像您现在一样,追逐每个人继续使用假设不变(可能与接收后挂钩)是您最不糟糕的选择。
一种可能的解决方法
如果您可以将这些文件完全排除在 git 之外,您的生活会变得轻松得多。我能想到的一件事:
- 将存储库中的文件移动到 lib 目录,它们不会一直被修改
.gitignore
文件在它们的最终位置,它们必须在那个位置,但总是得到不需要的更改
- 在您的存储库中添加一个“init”脚本,人们需要在克隆之后和开始工作之前运行一次。此脚本将文件复制到正确的位置。