你不能。见Git 常见问题.
目前 git 索引(暂存区)的设计只允许列出文件,并且没有足够能力进行更改以允许空目录的人足够关心这种情况来补救它。
在目录中添加文件时会自动添加目录。也就是说,目录永远不必添加到存储库中,并且不会自行跟踪。
你可以说 ”git add <dir>
“,它会在那里添加文件。
如果您确实需要一个目录存在于结帐中,您应该在其中创建一个文件。 .gitignore 很适合这个目的;您可以将其留空,或填写您希望在目录中显示的文件的名称。
下面的答案要好得多。事实上,低级软件 git 不允许它对我来说并不重要,因为当我需要一个空目录时如何实际使用 Git。添加 2 行 .gitignore 对我来说似乎是可以接受的。
好吧,如果想将文件移动到新目录中,他们将无法通过git mv
因为 git 会抱怨新目录不受版本控制
你可以阅读 ”这是不可能的,你不能,等等。” 在互联网上为这个常见的问题。.gitignore
技巧是一个常见的答案,可以满足许多需求。然而有可能的使 git 跟踪真空目录,看我的回答
虽然我越想越感觉像“空字符串的SHA哈希”,如果它存在,实际上将是空树的明确定义的标识符,除非无法判断该对象是树还是 blob。
我见过很多使用名为的空文件的存储库.gitkeep
以此目的。
@Amala:当您说“下面”时,您指的是什么。答案的顺序正在改变……
你能够实际上将空目录添加到 GIT 存储库,而不会混淆 GIT + 相关工具的破解,在这样做的同时“在技术上遵守规则”!当然,解决方案仍然涉及子模块,但它们只是作为一个占位符,使东西看起来对工具来说是合法的。
创建一个名为.keep
在目录中,然后添加。
默认情况下,这将是大多数系统上的隐藏文件,但它会强制 git 确认目录的存在,因为它现在有内容。
.gitkeep
没有被 Git 规定,并且会让人们第二次猜测它的含义,这将引导他们到谷歌搜索,这将引导他们到这里。这.git
应该为 Git 本身使用的文件和目录保留前缀约定。
@t-mart.git
前缀约定应该被保留……”为什么?git是否请求这个保留?
在这种情况下README
或者ABOUT
文件会一样好或更好。给下一个人留个便条,就像我们在 URL 之前所做的那样。
如果您正在编写应在空目录上测试代码的单元测试,则不起作用…
@szablica 我认为这根本不会令人困惑。事实上,我认为将其命名为 .gitkeep 非常直观。称它为 .gitignore 对我来说听起来很矛盾。所以这只是个人口味的问题。
使用理由.keep
非常好。在简单和不那么混乱之间取得了很好的平衡。看另一个答案stackoverflow.com/a/21422128/832230如果您采用了 .gitkeep 习惯,请在您的存储库上运行它:git mv .gitkeep .keep
通常使用 .empty 或 .keep
.emptydir
可以比.gitkeep
.
您可以使用此命令在 Windows 中创建此文件echo>.gitkeep
这是最好的方法。我在这里看到的唯一论点是 .gitkeep in 没有记录。伙计们,只需使用一个空的 .gitignore 并添加它。您的文件夹将被跟踪并删除证据,在某种意义上 git status 将显示丢失的跟踪 .gitignore 文件,以防文件夹不再存在。
您始终可以在目录中放置一个 README 文件,并说明您为什么要在存储库中使用此目录,否则为空目录。
+1,好建议,除非将来要使用,否则空目录没有任何意义。所以在里面创建一个 README 文件,写下这个目录是干什么用的,以后会放什么文件。这解决了这两个问题。
我同意。空文件夹很烦人,应该在所有正确处理的任何类型的存储库中进行解释。
@ilius 废话。在许多情况下,可能非常需要包含空目录的目录结构(例如 MVC 应用程序,您想要一个模型目录但还没有开始创建任何模型,或者您计划稍后添加共享视图的共享视图目录)。此外,在其中的每一个中都放一个 README 是多余的,因为它们的用途很明显,而且很容易忘记在每个中都放一个 README。并且当您向其中添加一些其他文件时,您必须记住删除自述文件。基本上,git 绝对应该允许空目录。
@Jez:我不同意。关键是 git 旨在控制(和索引)源代码。重要的是,提交的 id 是内容的散列。也就是说,它必须有内容。您不需要 README每一个树的一部分,只有叶子节点。如果您有打算放置代码的地方,但没有代码,并且您甚至不会花时间回显“模型的地方”>>自述文件,那么您所拥有的只是一个想法而不是提交。对 git 不感兴趣。说“我希望正在运行的应用程序有 XYZ 空目录”是运行问题,不是源头问题。与您的安装人员一起处理它。
@JoeAtzberger Web 应用程序呢?我是否应该授予 Web/应用程序服务器在目录丢失时创建目录的权限?这是一个强大的安全问题和一个需要继续检查的小性能问题。除了 git clone 之外,我是否应该创建一个需要运行特殊代码的 Web 应用程序(例如创建缓存文件夹)?现在我需要添加一个自述文件、一个安装脚本和时间来处理所有不想看任何东西、期望它能够正常工作的人。有时甚至会在构建/安装过程中使用没有文件的目录树。
@JoeAtzberger 这是一个缺失的功能,而不是有意的限制。来自 Git FAQ:目前 Git 索引(暂存区)的设计只允许列出文件,并且没有人有足够的能力进行更改以允许空目录已经足够关心这种情况来补救它。
@jbo5112 是的,您指的“特殊代码”是我提到的“安装程序”。您的 webapp 安装已经必须处理创建数据库、本地配置、拉取依赖项或 100 个其他操作,但是几个空目录超出了它的范围?尝试 gradle、passenger、chef、原始 Makefile 等。创建目录和安装应用程序的其他(可能更复杂/危险)工作之间没有安全差异。如果你真的没有 deps、config、DB 等,也没有安装程序,那么只需使用 README。没有任何情况要求您两者都做。
您的常见问题解答引用说它是设计。它描述了代码的当前状态(没有功能)。它还说明了所有许多 git 贡献者,他们都没有足够关心来改变它。我想说,这也比任何功能愿望清单更能体现他们的“意图”。您可能会考虑编写世界上最好的版本控制的人,我们自由享受的人:他们是疯狂的?意思是?无能?还是他们可能只是对此有不同的理解?
@JoeAtzberger 在我看来,它是一个缺失的功能,对于维护人员来说还不够重要,因为它需要进行大量的重新设计。请记住,Git 是由 Linus Torvalds 在 2 周内构建和部署的,因为他对现有的版本控制感到沮丧。如果这是他们打算省略的功能,那么常见问题解答可能会说它是故意不允许的或“永久地设计 Git 索引”,而不是在邮件列表上讨论如何实现不被允许的功能“目前的设计。”
我的网络应用案例是多个短期开发人员正在提取/克隆代码并访问同一个数据库(不理想,但我有理由)。它没有安装程序;无需管理 deps、config 等;没有自述文件。它必须首先稳定并产生更多安装。有时代码会被推送到生产环境中。在一个单独的项目中,我的服务器代码创建了一个冗长的目录结构(无文件),并为新客户帐户提供了一些复杂的权限。通过管理模板副本而不是代码,这将更容易维护。厨师是矫枉过正,没有其他帮助。
@Jez 为什么要删除自述文件?除了根目录之外的目录中的自述文件非常有用,尤其是当您的存储库托管在 GitHub 上时,它会自动在每个目录中显示自述文件。
我建议放置一个名为PLACEHOLDER
代替README
对于子目录。
这是我最终决定的路线,当我看到人们说 .gitkeep 对于我的情况时,我正在考虑这一点,这是我认为更好的解决方案。它用于保存像 lib 和 obj 这样的文件夹,这是我的构建过程的一部分。好的,自述文件对于其他开发人员来说是多余的,但对于刚开始的人来说,我当然会从我开始时的自述文件中受益。我认为这取决于项目及其使用方式。
touch .placeholder
在 Linux 上,这会创建一个名为.placeholder
.值得一提的是,这个名字对 git 来说是不可知的,并且这种方法在系统中的各个其他地方都使用过,例如/etc/cron.d/.placeholder
.其次,正如另一位用户所指出的,.git
可以为 Git 本身用于配置目的的文件和目录保留前缀约定。
或者,如在另一个回答,该目录可以包含一个描述性的README.md
文件反而.
无论哪种方式,这都要求文件的存在不会导致您的应用程序中断。
这对于初始的裸目录很有用,但是如果它开始充满文件怎么办?然后 Git 会注意到它们并将它们声明为未跟踪的文件。此处选择的答案更优雅地工作,以允许保留目录但随后安全地忽略内容。
问题和主要的普遍关注是关于添加一个空目录。如果它以后有一个常驻文件,显然删除.keep
文件或只是忽略它。相反,如果要忽略目录中的文件,那将是一个完全不同的问题。
有人建议git clean -nd | sed s/'^Would remove '// | xargs -I{} touch "{}.keep"
将在所有未跟踪的空目录中执行此操作。
不喜欢这个解决方案,很难猜出这个文件的作用。此外,如果您在开发环境中生成文件(如日志或图像等),这并不能阻止这些文件被版本化并进入生产环境,这并不好。
Windows 不喜欢没有名称的文件,并且需要特殊的魔法来完成此操作(也就是类似 bash 的终端应用程序或等效应用程序)。
优雅:.keep
文件连同提交信息显示了“保持”项目结构的意图。添加自述文件或关于我认为会引起更多混乱…
使用理由.keep
超过.gitkeep
非常好。在简单和不那么混乱之间取得了很好的平衡。命名空间似乎很重要,不应该被打破.git....
看起来像 git 自己的文件命名空间。其他文档可以进入项目全局自述文件或编码风格指南或本地自述文件。如果您采用了 .gitkeep 习惯,只需找到文件并重命名即可:git mv .gitkeep .keep
.迎接改变!这.gitignore
git 文档推荐的解决方案似乎是一种 hacky 解决方法并且过于复杂。
另一方面,这个问题非常依赖于 Git,因为除非是因为您对项目进行版本控制,否则您不会遇到此问题。
为什么我们需要空的版本化文件夹
第一件事:
一个空目录在 Git 版本控制系统下不能是树的一部分.
它根本不会被跟踪。但是在某些情况下,“版本控制”空目录可能是有意义的,例如:
- 脚手架预定义的文件夹结构,使其可供存储库的每个用户/贡献者使用;或者,作为上述的特殊情况,为临时文件, 比如一个
cache/
或者logs/
目录,我们要在其中提供文件夹,但.gitignore
它的内容 - 与上述相关,一些项目没有一些文件夹就无法工作(这通常暗示了一个设计不佳的项目,但这是一个常见的现实世界场景,也许可能存在需要解决的权限问题)。
一些建议的解决方法
许多用户建议:
- 放置一个
README
文件或具有某些内容的另一个文件,以使目录非空,或 - 创建一个
.gitignore
具有某种“反向逻辑”(即包含所有文件)的文件,最后,它与方法#1 的目的相同。
尽管两种解决方案肯定都有效我发现它们与有意义的 Git 版本控制方法不一致。
- 为什么你应该在你的项目中放置你可能并不真正想要的伪造文件或自述文件?
- 为什么使用
.gitignore
做一件事(保持文件)这与它的含义完全相反(不包括文件),即使有可能?
.gitkeep 方法
使用空的文件名为.gitkeep
为了强制版本控制系统中存在该文件夹。
虽然看起来差别不大:
- 您使用的文件具有单身的保存文件夹的目的。你不要放任何你不想放的信息。
例如,您应该使用自述文件作为包含有用信息的自述文件,而不是作为保留文件夹的借口。
关注点分离总是一件好事,你仍然可以添加一个.gitignore
忽略不需要的文件。 - 命名它
.gitkeep
从文件名本身(以及给其他开发者,这对于共享项目和 Git 存储库的核心目的之一很有用)这个文件是- 与代码无关的文件(因为前导点和名称)
- 与 Git 明显相关的文件
- 其目的(保持) 的含义清晰、一致且在语义上对立忽视
采用
我看过.gitkeep
非常重要的框架采用的方法,例如Laravel,Angular-CLI.
您错过了一个想法 – 保留和清空文件夹(例如 /logs、/tmp、/uploads)的原因是什么?是的 – 它保持文件夹为空。 🙂 因此,如果您想保持文件夹为空,则必须忽略其中的文件。
@RomanAllenstein:不一定。可能是您创建了一个具有给定结构的存储库,以后可以填充该结构。这些文件将在创建后立即添加到存储库中,开始删除或编辑 .gitignore 文件会很烦人(而且很危险,因为您可能甚至没有意识到它们没有被跟踪:git 忽略了它们)
如果您编辑答案以替换.gitkeep
对于任何其他非 git 前缀的文件名,您都会得到我的支持,我认为这是最好和最有用的答案。原因:我认为“.git*”应该保留给 git 规定的文件,而这只是一个占位符。当我看到它时,我的第一个猜测是,例如“.gitkeep”文件会被自动忽略(这将是一个不错的功能),但事实并非如此,对吧?
@Santosh您可以编辑我的帖子并对社区有用,而不是幼稚地吹嘘非母语人士并无用地污染评论,这与平均智能行为[IN]一致。这就是编辑的原因,顺便说一句。无论如何感谢您的免费课程,非常感谢:)
我想知道为什么人们很难理解为什么要向 git 添加“空”文件夹。你必须从某个地方开始,对吧?所以,通常你从你的项目文件夹结构开始 – 唉 – 在项目开始时还没有任何东西。一旦你的项目 repo 完成,团队工作人员可以克隆并开始使用 SAME 结构。
虽然没用,有一种方法可以将一个空的(真的是空的)目录破解到你的仓库中.它不会
checkout
但是,对于当前版本的 Git。@tiwo 我不同意它没有用。您的目录层次结构是您项目的一部分,因此它应该是版本控制的。
@JonBentley 确定你是对的!遗憾的是 git 未能尊重这部分 – 但只要不解决此问题,存储库中的空目录就没有用(请注意,git 在签出时也会忽略空目录)
就我而言,我想为 tmp 文件添加目录结构,但不是 tmp 文件本身。通过这样做,我的测试仪具有正确的结构(否则会出现错误),但我不会用 tmp 数据阻塞我的提交。所以是的,它对我有用!
@AdamMarshall 我认为 tiwo 是说黑客没有用,因为它被结帐忽略了。 Tmp dirs 听起来确实是 VCS 的一个有用功能。
为什么不让创建 tmp 文件的过程也创建 tmp 目录呢?
你可能会使用一个钩子或者git属性过滤器有一个
.deleteme
添加到 repo 的文件在结帐时会自动删除。然而,它可能会破裂git commit -a
并可能被触发每一个查看…对于那些认为这不是一个有用的功能的人,我会提出这个挑战问题:我有一个 /temp 目录,当用户签出时需要“那里”。如果它不存在,我正在使用的软件包不会创建它。如果不是通过让 git 识别一个空目录,我将如何做到这一点。
你不能。只需创建一个空文件,例如
.keep
, 在目录中。我建议将此添加到主要解决方案中:stackoverflow.com/a/21422128/1670956
作为未来在各种权限方案下创建文件所需的目标,空文件夹显然很有用。