如何冻结存储库中的文件

时间:2014-05-07 20:46:40

标签: git

我们的仓库中的文件应该锁定到位,不可更改的情况。

我已将文件添加到.gitignore但是当我在本地修改它时,git仍然会跟踪它 - 我现在的理解是将文件/文件夹添加到.gitignore之后它们已经在repo不起作用,一种可能性就是使用git rm --cached file来解决它们。

如果我这样做,那么克隆它的下一个人的仓库中的文件是否会再次出现?有没有更好的方法来冻结回购中的这个文件?

5 个答案:

答案 0 :(得分:4)

配置自己的回购并不太难,所以他们永远不会改变这条路径,其他回购'所有者必须合作执行一些一次性配置命令。

以下是您为自己的回购做的事情:

  • 设置内容过滤器,不会改变工作树或存储库中的现有内容。

    git config filter.pinned-content.clean  'git show HEAD:%f 2>&- || cat'
    git config filter.pinned-content.smudge 'cat %f 2>&- || cat'
    
    每当你登台(clean)这样的文件时,git都会执行git add命令来生成要放在repo中的内容。在这里,命令试图显示已经为文件提交的内容,如果这不起作用,如果没有为它提交任何内容,那么他​​们将采取您正在进行的操作。同样,git执行smudge命令以生成应该在结帐时放入工作树中的内容,这里使用已经存在的任何内容,否则将存储库中的内容作为默认值。 / p>
  • 宣传您希望以这种方式处理路径/到/文件

    echo path/to/file filter=pinned-content >>.gitattributes
    
  • 使该处理适用于此回购中的所有未来结帐/添加,即使已经存在的提交

    mkdir -p .git/info
    echo path/to/file filter=pinned-content >> .git/info/attributes
    

以下是分发请求和合作指示的一种方式:

# commit the new .gitattributes and explain what you need by way of cooperation:

git add .gitattributes
git commit -F- -- .gitattributes <<EOD
How to set up to preserve existing file content

# set up a content filter that will not alter existing content
# either in the worktree or in the repository:

git config filter.pinned-content.clean  'git show HEAD:%f 2>&- || cat'
git config filter.pinned-content.smudge 'cat %f 2>&- || cat'

# make the treatment apply to all future checkouts/adds in this repo

mkdir -p .git/info
echo path/to/file filter=pinned-content >> .git/info/attributes

-------    
Please do the above configuration to avoid mistakenly committing local changes
to files marked with the `pinned-content` filter.  Currently path/to/file is 
marked in the committed `.gitattributes` to be treated this way, you can locally
mark files to be treated this way for even preexisting commits by adding a 
similar line to your repository's `.git/info/attributes` file.
EOD

%f能力包含在1.7.4中,所以已经有四年时间了,预计发行版的可用性似乎是合理的。

您可以使用git的稀疏结帐获得非常类似的效果,但不会处理提供默认内容,并且无法通过.gitattributes启用。


这已经过了几次烟熏试验和几个小时的敲击声,它看起来并不像我第一次尝试它。

答案 1 :(得分:3)

如果你想&#34;冻结&#34;该文件(防止在Git中跟踪进一步的更改),您可以运行git update-index --assume-unchanged somefile

来自文档:

  

当&#34;假设不变&#34;位已打开,用户承诺不会更改   该文件并允许Git假定工作树文件匹配   索引中记录了什么。

进一步阅读:git-update-index

注意:这不会阻止其他人更改文件。如果您希望文件在Git中真正永不改变,那么每个克隆回购的人都必须运行此命令。 / p>

答案 2 :(得分:1)

.gitignore做的是告诉git在给定的命令中忽略哪些文件,除非它们已经是存储库的一部分(或者你要求它覆盖)。

E.g。我的*.png中有.gitignore用于我写作的讲义(一些图像被包含在PNG中以供包含),但是存储库包含的是原始PNG图像。没问题,旧的跟踪好了,重建创建的那些被忽略了。更改old.png只是git commit -m "Old image was changed" old.png。如果我想添加一个新的,它距离git add -f some-new.png; git commit -m "Some new image"只有{{1}}。

您不能通过在某处提及它们来排除存储库中已有的文件,并且从现在开始将它们永远排除在外仍无法工作。

答案 3 :(得分:1)

git rm --cached file确实会从存储库中删除该文件,因此只存在于当前工作目录中的未跟踪文件中。将来的克隆将不包含该文件。

Git并没有真正提供冻结文件的方法,因此无法对其进行修改。您可以做的最好的事情是创建一个预提交挂钩,在提交之前重置文件,或者最好中止提交,直到您自己重置文件。

答案 4 :(得分:0)

这可以解决问题(根据this):

# Did some change in any file in the local repo
$ git commit anyFile
$ git update-index --skip-worktree myFile
$ git ls-files -v myFile
S myFile
$ git push

最好的是,我什至不需要在git update-index ...之后在其他PC上键入git pull