17

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

在我的 git 控制的站点上尝试一些东西之前,我正在我的本地 Windows 机器上进行测试。

我有:

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 完全忽略

我在网上查看,在 IRC 中询问,并查看了非常相关的问题,但找不到这样做的方法。我知道这个例子看起来微不足道,但这正是我需要在我的网站上做的,而目录是 Forum/cache。


编辑:

这有点骇人听闻,我更喜欢更好的答案,但我最终做了:

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
4

5 回答 5

20

试试这个

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

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

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

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

于 2012-05-18T05:18:55.343 回答
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"
    

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 ..
于 2012-05-30T06:17:02.167 回答
1

Git 不存储目录。如果你想在 Git 中保留一个空目录,约定是放一个名为 的空文件.keepme,然后提交。

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

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

无论如何,我希望您不要出于“安全”原因尝试隐藏此文件 - 否则事情会更加复杂(例如,您必须从整个历史记录中清除它等)

于 2012-05-18T05:06:45.380 回答
0

签出包含该文件的提交将替换它,并从包含该文件的提交转换为不包含该文件的提交将删除它。Git 不能理智地做任何其他事情。.gitignore 不会覆盖 repo,它可以方便地避免您的状态报告。

您可以使该文件成为 git 领域之外某个地方的符号链接,这样可以通过检查不良历史记录轻松地从损坏中恢复。如果这不是一个选项,则有过滤器分支。

于 2012-05-18T05:17:52.270 回答
0

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

请注意,如果您担心 .gitignore 本身,您可以尝试将 .git/info/excludes 用于仅本地存储库的 .gitignore 文件。请注意,这不会解决更改跟踪文件的问题,只会为您提供不会被跟踪的补充 .gitignores。

于 2012-07-19T00:12:33.913 回答