忽略 git 中重命名的文件夹
Ignore renamed folder in git
我有一个文件夹,比方说,
src/main/resources/basic_abc
为了运行本地化我的代码,我需要将它重命名为
src/main/resources/basic
这是我每次处理此存储库时都想执行的更改。我不希望 git 继续跟踪此文件夹并告诉我 basic_abc
已重命名为 basic
。如何阻止 git 跟踪此重命名更改?
此外,如果我 运行 命令 git status
,它确实会给出混乱的输出,因为此文件夹中有大量文件。
我该如何避免呢?
我认为这可以通过忽略“本地”目录来完成。
- 创建一个新的“基本”目录
- 将“basic_abc”中的所有内容复制进去
- 转到项目目录中的
\.git\info
,打开 exclude
文件。
- 添加一个新行
src/main/resources/basic
。
- 再次执行
git status
,您会看到git没有将新的“基本”目录视为未跟踪文件。但需要手动将其内容与“basic_abc”目录同步。只要在远程存储库中没有名为“basic”的目录或文件,就可以了。
exclude
文件用于“本地 git 忽略”。它的格式与 .gitignore
文件相同,但只适用于您的机器。
告诉 Git 忽略 basic_abc/
已经消失了
警告 此解决方案仅在您不更改沙箱中的分支时才有效。跳到此答案的末尾以获取详细信息。 结束警告
您可以使用 git update-index --skip-worktree <file>
告诉 Git 忽略您在本地对文件所做的更改,这样 git status
和所有其他命令都会将其视为未更改。
我测试过,这也适用于已删除的文件。我没有找到对整个目录执行此操作的方法,但在 bash 命令行上编写脚本并不难。
一个文件:
git update-index --skip-worktree basic_abc/file1
basic_abc/
中的所有文件:
git status --porcelain |
grep " D src/main/resources/basic_abc" |
sed "s/^ D //" |
xargs git update-index --skip-worktree
解释:
git status
是 运行 和 --porcelain
所以你有稳定的 machine-readable 输出。
- 如果需要,修复 grep 表达式,使其准确找到您希望 Git 假装不是 deleted/moved 的文件。
sed
命令只保留文件名。
- 并且
xargs
对该管道的结果调用 git update-index --skip-worktree
。
让Git忽略basic/
已经出现
正如@EddieDeng 所说,您可以使用 .git/info/exclude
或 .gitignore
来完成此操作,请参阅他的回答。
还原 --skip-worktree
操作
你没有问,但下一个合乎逻辑的问题是,当你对 basic_abc
/basic
中的文件进行更改后,将是如何提交它们。我在这里提到它是因为一旦你 运行 那个 --skip-worktree
循环,重命名 basic
回 basic_abc
和 运行ning git status
或git add
不行!
幸运的是,这个问题已经在 SO 上得到了一半的回答: 展示了如何列出跳过的文件,这个命令可以将它们恢复为未被跳过的状态:
git ls-files -v . |
grep "S src/main/resources/basic_abc" |
sed "s/^S //" |
xargs git update-index --no-skip-worktree
我不确定 git ls-files -v .
输出是否像 git status --porcelain
输出一样稳定,特别是因为 -t/-v/-f
选项在手册中标记为 semi-deprecated ,但这目前有效,我不知道如何从 Git.
中提取该列表
注意事项,或者您不应该这样做的原因
感谢@bk2204 链接到 Git FAQ: How do I ignore changes to a tracked file?,它基本上说“不要”。
update-index
有问题,因为它只更新索引,而不是其他一些持久标志。有关这些问题,请参阅 @torek's excellent write up。
我想在这里强调的关键点是,一旦您签出沙箱中的另一个分支,您将丢失之前设置的 skip-worktree 位。
刚刚测试:
# do the --skip-worktree operation above
git checkout some-feature-branch
git checkout master
现在我的沙盒有 basic/*
和 basic_abc/*
,即所有这些文件的两个完整副本。
所以我的最后一点是,只有在您不打算更改该沙箱中的分支时才使用此解决方案。 (因为我一直在改变分支,对我来说,这等同于“不要使用这个解决方案”。)
更好的解决方案?
我认为最好的方法是完全重新考虑您的设置。您不应修改沙箱,而应编写一些 install/deploy 脚本来创建沙箱外部所需的 run-time 结构。然后你有一个明确的分离和完全的灵活性:源代码在 Git 管理之下,部署的代码具有它需要的任何结构,在 Git 管理之外。如果您想避免实际复制,您可以使用符号链接使部署的结构轻量级并可动态更新。
您可以使用 git rm <folder> --cached
- 需要时您可以使用 git add <folder>
再次添加文件夹。请注意,如果您在 re-adding 文件夹之前执行 git commit -a
,删除将出现在该提交中。
重要提示:
--cached
参数很重要 - 否则,git
将从您的硬盘中删除文件夹。
我有一个文件夹,比方说,
src/main/resources/basic_abc
为了运行本地化我的代码,我需要将它重命名为
src/main/resources/basic
这是我每次处理此存储库时都想执行的更改。我不希望 git 继续跟踪此文件夹并告诉我 basic_abc
已重命名为 basic
。如何阻止 git 跟踪此重命名更改?
此外,如果我 运行 命令 git status
,它确实会给出混乱的输出,因为此文件夹中有大量文件。
我该如何避免呢?
我认为这可以通过忽略“本地”目录来完成。
- 创建一个新的“基本”目录
- 将“basic_abc”中的所有内容复制进去
- 转到项目目录中的
\.git\info
,打开exclude
文件。 - 添加一个新行
src/main/resources/basic
。 - 再次执行
git status
,您会看到git没有将新的“基本”目录视为未跟踪文件。但需要手动将其内容与“basic_abc”目录同步。只要在远程存储库中没有名为“basic”的目录或文件,就可以了。
exclude
文件用于“本地 git 忽略”。它的格式与 .gitignore
文件相同,但只适用于您的机器。
告诉 Git 忽略 basic_abc/
已经消失了
警告 此解决方案仅在您不更改沙箱中的分支时才有效。跳到此答案的末尾以获取详细信息。 结束警告
您可以使用 git update-index --skip-worktree <file>
告诉 Git 忽略您在本地对文件所做的更改,这样 git status
和所有其他命令都会将其视为未更改。
我测试过,这也适用于已删除的文件。我没有找到对整个目录执行此操作的方法,但在 bash 命令行上编写脚本并不难。
一个文件:
git update-index --skip-worktree basic_abc/file1
basic_abc/
中的所有文件:
git status --porcelain |
grep " D src/main/resources/basic_abc" |
sed "s/^ D //" |
xargs git update-index --skip-worktree
解释:
git status
是 运行 和--porcelain
所以你有稳定的 machine-readable 输出。- 如果需要,修复 grep 表达式,使其准确找到您希望 Git 假装不是 deleted/moved 的文件。
sed
命令只保留文件名。- 并且
xargs
对该管道的结果调用git update-index --skip-worktree
。
让Git忽略basic/
已经出现
正如@EddieDeng 所说,您可以使用 .git/info/exclude
或 .gitignore
来完成此操作,请参阅他的回答。
还原 --skip-worktree
操作
你没有问,但下一个合乎逻辑的问题是,当你对 basic_abc
/basic
中的文件进行更改后,将是如何提交它们。我在这里提到它是因为一旦你 运行 那个 --skip-worktree
循环,重命名 basic
回 basic_abc
和 运行ning git status
或git add
不行!
幸运的是,这个问题已经在 SO 上得到了一半的回答:
git ls-files -v . |
grep "S src/main/resources/basic_abc" |
sed "s/^S //" |
xargs git update-index --no-skip-worktree
我不确定 git ls-files -v .
输出是否像 git status --porcelain
输出一样稳定,特别是因为 -t/-v/-f
选项在手册中标记为 semi-deprecated ,但这目前有效,我不知道如何从 Git.
注意事项,或者您不应该这样做的原因
感谢@bk2204 链接到 Git FAQ: How do I ignore changes to a tracked file?,它基本上说“不要”。
update-index
有问题,因为它只更新索引,而不是其他一些持久标志。有关这些问题,请参阅 @torek's excellent write up。
我想在这里强调的关键点是,一旦您签出沙箱中的另一个分支,您将丢失之前设置的 skip-worktree 位。
刚刚测试:
# do the --skip-worktree operation above
git checkout some-feature-branch
git checkout master
现在我的沙盒有 basic/*
和 basic_abc/*
,即所有这些文件的两个完整副本。
所以我的最后一点是,只有在您不打算更改该沙箱中的分支时才使用此解决方案。 (因为我一直在改变分支,对我来说,这等同于“不要使用这个解决方案”。)
更好的解决方案?
我认为最好的方法是完全重新考虑您的设置。您不应修改沙箱,而应编写一些 install/deploy 脚本来创建沙箱外部所需的 run-time 结构。然后你有一个明确的分离和完全的灵活性:源代码在 Git 管理之下,部署的代码具有它需要的任何结构,在 Git 管理之外。如果您想避免实际复制,您可以使用符号链接使部署的结构轻量级并可动态更新。
您可以使用 git rm <folder> --cached
- 需要时您可以使用 git add <folder>
再次添加文件夹。请注意,如果您在 re-adding 文件夹之前执行 git commit -a
,删除将出现在该提交中。
重要提示:
--cached
参数很重要 - 否则,git
将从您的硬盘中删除文件夹。