git - git update-index --assume-unchanged 规则会在 pull 时传播给客户端吗?

标签 git gitignore

有些情况下我不能使用 .gitignore文件,否则,在 git push ,从远程清除关键文件。在这些情况下,我申请 git update-index --assume-unchanged <file>到我想忽略的文件。

在应用假设不变的规则并调用 git push 之后,这些规则是否会附加到远程分支,以便所有后续 pull (来自其他客户端)都将继承它们?或者,这些客户端是否也必须运行 git update-index --assume-unchanged <file>在他们的机器上单独命令?

如果命令不是继承的——以前有没有人为此编写过服务器钩子(Hook)?而不是强制所有当前和 future 的客户防范它?

最佳答案

该索引是您工作站的本地索引,您在那里所做的任何更改都不会传播到同一远程的其他克隆。

(更新,问题更新后)

.gitignore 文件

There are instances where I can't use a .gitignore file, otherwise, on git push, critical files are purged from the remote.



这不是真的。 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尽管已被 gitignor 忽略,但仍被视为已修改。我们可以像往常一样添加和提交它;事实上,如果你将一个跟踪文件添加到 gitignore,它的行为就像它根本不在 gitignore 中一样。
$ echo green > a.txt
$ echo blue > b.txt
$ git status --short
 M a.txt
$ git add a.txt
b.txt file 是不同的,因为在 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 ignore 规则视为指导方针:-)

传播假设不变

After applying the assume-unchanged rules and calling git push, will these rules be attached to the remote branch so that all subsequent pulls (from other clients) will inherit them? Or, must these clients also run the git update-index --assume-unchanged commands individually at their machines?



后者。您可以获得的最接近的是向存储库添加一个 shell 脚本,为您进行更改。

服务器 Hook ?

If the commands are not inherited -- has anybody written a server hook for this before? Instead of mandating that all current and future clients safeguard against it?



如果您的目标是编写一个服务器 Hook 来删除关键文件,就好像它们根本不是推送的一部分一样,那是不可能的。 Git push 主要处理 提交 objects (和 refs )。它们的依赖对象,如树和 blob,会根据需要进行传输,受提交的可达性影响。它归结为,如果它没有提交,你就不能将它推送到远程(这是一种过于简单化,但它适用于存储库中的文件)。此外,git 提交受到加密保护。您不能在不更改提交哈希的情况下更改提交,并且如果您更改提交哈希,您基本上会拥有一个不同的新提交(可能恰好与旧提交具有相同的差异)。

这意味着服务器不能重写提交;至少在没有严重混淆执行推送的客户端的情况下(它仍然会有旧提交对象的副本)。

你什么可以 做的是编写一个 post-receive hook,如果它们包含您不想更新的文件,它会拒绝提交。这并不能真正解决您的问题,因为如果您无法解释 git commit --assume-unchanged给你的同事,那么你可能会更难以解释他们如何使用交互式 rebase 来重新创建他们的提交,而不会在其中包含不需要的文件。

长话短说,我认为如果您正在处理应该提交一次且以后永远不会提交的文件,就像您现在所做的那样,让每个人继续使用假设不变(可能与 post-receive Hook )是您最不坏的选择。

一个可能的解决方法

你的生活会变成整体如果您可以将这些文件完整地保留在 git 之外,则会容易得多。我能想到的一件事:
  • 将存储库中的文件移动到 lib 目录,在那里它们不会一直被修改
  • .gitignore文件在其最终位置,即它们必须在的位置,但一直在进行不需要的更改
  • 将“init”脚本添加到您的存储库中,人们需要在克隆之后和开始工作之前运行一次。此脚本将文件复制到正确的位置。
  • 关于git - git update-index --assume-unchanged 规则会在 pull 时传播给客户端吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18570926/

    相关文章:

    git - 递归忽略特定目录中除 .json 文件之外的所有文件

    git - 只对某些 git url/域使用代理?

    svn - git-svn 和远程 git repo sync

    git - 无法从 Git 接收后 Hook 中检测到分支

    git - 在 .gitignore 中使用感叹号来专门跟踪某些内容?

    git - 为什么我的 .gitignore 中的子文件夹没有被忽略?

    macos - git checkout -- <files> 不丢弃更改?

    git - 如何在 SmartGit 中忽略文件/文件夹

    git - .gitignore 排除包含文件的文件夹但包含子目录

    node.js - gitignore 所有node_modules 目录和子目录