Git忽略被跟踪的文件而不删除它们

时间:2012-05-18 04:26:10

标签: git version-control

我在理解基本的git概念时遇到了一些麻烦:/

我在我的本地Windows机器上进行测试,然后在我的git控制的网站上尝试了一些东西。

我有:

gittesting/repo1:
    file.txt
    ignoreme:
        ignore.txt

gittesting/repo2
    file.txt
    ignoreme:
        ignore.txt

Repo2是repo1的副本,并且已经跟踪了ignoreme。 ignore.txt文件在repo2中被更改,但我想停止跟踪它并让git完全忽略它。问题是,如果我创建一个.gitignore文件并添加ignoreme,它已经太晚了,因为它已经被跟踪了,所以我不得不做git rm --cached ignore,但是它被标记为已删除,如果我将提交删除repo1,该目录将被删除而不是单独留下..

总结一下:

  1. ignore.txt在两个repos之间有不同的内容。
  2. 我希望ignore.txt内容保持原样并被git
  3. 完全忽略

    我在网上看过,在IRC问过,并查看了相关的问题,但找不到办法做到这一点。我知道这个例子似乎微不足道,但这正是我需要在我的网站上做的事情,目录是论坛/缓存。


    编辑:

    这有点像黑客,我更喜欢更好的答案,但我最终做了:

    cd repo2
    echo "ignoreme" > .gitignore
    echo "ignoreme/*" > .gitignore
    git rm --cache -r ignoreme
    git commit -m "Should ignore now"
    cd ../repo1
    mv ignoreme ignoreme2
    git pull ../repo2
    mv ignoreme2 ignoreme
    

5 个答案:

答案 0 :(得分:18)

试试这个

git update-index --assume-unchanged ignoreme/ignore.txt

Git将忽略此文件的任何未来更改而不更改存储库。要再次开始跟踪更改,请使用

git update-index --no-assume-unchanged ignoreme/ignore.txt

请注意,这仅对当前工作副本生效,因此每次克隆存储库时都需要执行此操作。

答案 1 :(得分:7)

如果我正确理解了您的问题,您希望repo2了解ignoreme/目录,但您不希望Git关心对该目录的任何修改。并且git rm --cached对您没有帮助,因为您告诉Git 从现在开始停止跟踪此内容。

Git用于跟踪内容但通过子模块修复的解决方案。这除了Git Book解释(强调添加):

  

虽然rack是您工作目录中的子目录,但Git将其视为子模块,当您不在该目录中时,不会跟踪其内容。相反, Git将其作为特定提交从该存储库中记录。

您可以尝试以下方法:

  1. ignoreme/目录复制到新位置,并将其设为git存储库

  2. 将其添加为repo2中的子模块:

    git submodule add file:///path/to/ignoreme ignoreme
    git commit -m"Add ignoreme/ as a submodule"
    
  3. ignoreme子模块现在已固定为特定提交。 repo2仍在跟踪子模块中的任何内容,但ignoreme/中的文件更改将不会在repo2中跟踪,除非您在子模块中提交它们。假设ignoreme/ignore.txt以某种方式被修改:

    $ git status
    # On branch master
    # Changes not staged for commit:
    #   (use "git add <file>..." to update what will be committed)
    #   (use "git checkout -- <file>..." to discard changes in working directory)
    #   (commit or discard the untracked or modified content in submodules)
    #
    #       modified:   ignoreme (modified content)
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    

    即使您运行git add .ignoreme/ignore.txt中的更改也不会添加到索引中,除非它们像这样提交到子模块:

    $ cd ignoreme
    $ git commit -am"Time to change ignore.txt"
    $ cd ..
    $ git add .
    $ git status
    # On branch master
    # Changes to be committed:
    #   (use "git reset HEAD <file>..." to unstage)
    #
    #       modified:   ignoreme
    #
    

    但是如果你想忘记子模块中的局部修改:

    $ cd ignoreme
    $ git reset --hard
    $ cd ..
    

答案 2 :(得分:1)

Git不存储目录。如果你想在Git中保留一个空目录,那么惯例是在那里放一个名为.keepme的空文件,并提交它。

至于问题,就我所知,你将无法在其克隆的上游分支中隐藏文件。这不是Git旨在做的事情。考虑其他选项,例如拆分为两个存储库(也许,使用子树或子模块)。或者在上游保留一个单独的分支以由下游跟踪,并通过post-receive钩子从该分支过滤ignore.txt

告诉我们更多你为什么要这样做,也许还有更好的方法。

无论如何,我希望你不要因为“安全”的原因而试图隐藏这个文件 - 否则问题就会复杂得多(例如你必须从整个历史中清除它等)。

答案 3 :(得分:0)

签出具有该文件的提交将替换它,并且从提交转换到没有它的提交将删除它。 Git不能做任何其他事情。 .gitignore不会覆盖回购,这样可以方便您的状态报告。

你可以让文件成为git领域之外某个地方的符号链接,这样可以通过查看糟糕的历史记录轻松恢复损坏。如果那不是一个选项,那就是filter-branch。

答案 4 :(得分:0)

Git仅将忽略模式应用于未跟踪文件。您不能使用忽略模式来忽略已经由git跟踪的文件的更改。不过,请参阅https://gist.github.com/1423106了解人们解决问题的方法。

请注意,如果您担心.gitignore本身,您可以尝试使用.git / info / excludes作为本地repo-only .gitignore文件。请注意,这将解决更改跟踪文件的问题,只会为您提供无法跟踪的补充.gitignores。