如何将空目录添加到 Git 存储库?
如何将空目录(不包含文件)添加到 Git 存储库?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如何将空目录(不包含文件)添加到 Git 存储库?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(30)
我总是构建一个函数来检查我想要的文件夹结构并在项目中为我构建它。 这解决了这个问题,因为空文件夹通过代理保存在 Git 中。
这是在 PHP 中,但我确信大多数语言都支持相同的功能,并且因为文件夹的创建是由应用程序负责的,所以文件夹将始终存在。
I always build a function to check for my desired folder structure and build it for me within the project. This gets around this problem as the empty folders are held in Git by proxy.
This is in PHP, but I am sure most languages support the same functionality, and because the creation of the folders is taken care of by the application, the folders will always be there.
Jamie Flournoy 的解决方案效果很好。 这是保留
.htaccess
的一个增强版本:使用此解决方案,您可以提交一个空文件夹,例如
/log
、/tmp 或
/cache
并且该文件夹将保持为空。The solution of Jamie Flournoy works great. Here is a bit enhanced version to keep the
.htaccess
:With this solution you are able to commit a empty folder, for example
/log
,/tmp
or/cache
and the folder will stay empty.这是一个 hack,但有趣的是它有效(Git 2.2.1)。 与 @Teka 建议的类似,但更容易记住:
git submodule add path_to_repo
).submodules
。 做出改变。现在,您有了一个在签出提交时创建的目录。 但有趣的是,如果您查看该文件的树对象的内容,您将得到:
但我不鼓励使用它,因为它可能会在未来版本的 Git 中停止工作。 这可能会使您的存储库损坏。
Here is a hack, but it's funny that it works (Git 2.2.1). Similar to what @Teka suggested, but easier to remember:
git submodule add path_to_repo
).submodules
. Commit a change..submodules
file and commit the change.Now, you have a directory that gets created when commit is checked out. An interesting thing though is that if you look at the content of tree object of this file you'll get:
I wouldn't encourage to use it though since it may stop working in the future versions of Git. Which may leave your repository corrupted.
如果您想添加一个在多个语义目录中容纳大量瞬态数据的文件夹,那么一种方法是将类似的内容添加到您的根 .gitignore...
/app/data/**/*。 *
!/app/data/**/*.md
然后您可以提交描述性 README.md 文件(或空白文件,没关系,只要您可以像使用
* 一样唯一地定位它们.md 在本例中)在每个目录中,以确保所有目录仍然是存储库的一部分,但文件(带扩展名)被忽略。 限制:目录名称中不允许使用
.
!您可以使用 xml/images 文件或其他文件填充所有这些目录,并随着应用程序开发的存储需求而在
/app/data/
下添加更多目录(使用 README.md 文件提供服务)刻录每个存储目录的确切用途的描述)。无需进一步更改您的
.gitignore
或通过为每个新目录创建新的.gitignore
来进行分散。 可能不是最聪明的解决方案,但在 gitignore 方面是简洁的,并且总是适合我。 又好又简单! ;)If you want to add a folder that will house a lot of transient data in multiple semantic directories, then one approach is to add something like this to your root .gitignore...
/app/data/**/*.*
!/app/data/**/*.md
Then you can commit descriptive README.md files (or blank files, doesn't matter, as long as you can target them uniquely like with the
*.md
in this case) in each directory to ensure that the directories all remain part of the repo but the files (with extensions) are kept ignored. LIMITATION:.
's are not allowed in the directory names!You can fill up all of these directories with xml/images files or whatever and add more directories under
/app/data/
over time as the storage needs for your app develop (with the README.md files serving to burn in a description of what each storage directory is for exactly).There is no need to further alter your
.gitignore
or decentralise by creating a new.gitignore
for each new directory. Probably not the smartest solution but is terse gitignore-wise and always works for me. Nice and simple! ;)有时您必须处理编写不好的库或软件,它们需要一个“真正的”空目录和现有目录。 放置一个简单的
.gitignore
或.keep
可能会破坏它们并导致错误。 以下内容可能在这些情况下有所帮助,但不能保证...首先创建所需的目录:
然后向此目录添加损坏的符号链接(但在除上述用例之外的任何其他情况下,请使用自述文件 并附有说明):
要忽略此目录中的文件,您可以将其添加到根
.gitignore
:要添加忽略的文件,请使用参数强制它:
提交后索引中有一个损坏的符号链接,并且 git 创建目录。 断开的链接有一些优点,因为它不是常规文件并且指向任何常规文件。 因此,它甚至适合问题“(不包含文件)”的部分,不是出于意图,而是出于含义,我猜:
此命令显示空结果,因为此目录中不存在文件。 因此,大多数获取目录中所有文件的应用程序通常看不到此链接,至少在它们执行“文件存在”或“可读”时是这样。 甚至有些脚本在那里找不到任何文件:
但我强烈建议仅在特殊情况下使用此解决方案,在空目录中编写良好的 README 通常是更好的解决方案。 (我不知道这是否适用于 Windows 文件系统......)
Sometimes you have to deal with bad written libraries or software, which need a "real" empty and existing directory. Putting a simple
.gitignore
or.keep
might break them and cause a bug. The following might help in these cases, but no guarantee...First create the needed directory:
Then you add a broken symbolic link to this directory (but on any other case than the described use case above, please use a
README
with an explanation):To ignore files in this directory, you can add it in your root
.gitignore
:To add the ignored file, use a parameter to force it:
After the commit you have a broken symbolic link in your index and git creates the directory. The broken link has some advantages, since it is no regular file and points to no regular file. So it even fits to the part of the question "(that contains no files)", not by the intention but by the meaning, I guess:
This commands shows an empty result, since no files are present in this directory. So most applications, which get all files in a directory usually do not see this link, at least if they do a "file exists" or a "is readable". Even some scripts will not find any files there:
But I strongly recommend to use this solution only in special circumstances, a good written
README
in an empty directory is usually a better solution. (And I do not know if this works with a windows filesystem...)为这场战斗添加又一个选择。
假设您想向
git
添加一个目录,出于与git
相关的所有目的,该目录应保持为空并且永远不会跟踪其内容,一个.gitignore< /code> 正如这里多次建议的那样,就可以了。
如前所述,格式是:
现在,如果您想要一种方法在命令行中一次性执行此操作,而在您要添加的目录中,您可以执行:
Myself,我有一个 shell 脚本用来执行此操作。 将脚本命名为您想要的任何名称,然后将其添加到包含路径中的某个位置,或者直接引用它:
这样,您可以从要添加的目录中执行它,或者引用该目录作为它的第一个也是唯一的参数:
另一种选择(响应 @GreenAsJade 的评论),如果您想跟踪一个空文件夹,该文件夹将来可能包含跟踪文件,但目前为空,您可以省略
*
来自.gitignore
文件,并检查那个。基本上,所有文件都在说“不要忽略我” >”,但除此之外,该目录为空并被跟踪。您的
.gitignore
文件如下所示:就是这样,签入该文件,您就有一个空的但已跟踪的目录,您可以稍后在其中跟踪文件。
我建议在文件中保留这一行的原因是它给出了 .gitignore 的目的。 否则,有人可能会考虑将其删除。 如果您在该行上方发表评论可能会有所帮助。
Adding one more option to the fray.
Assuming you would like to add a directory to
git
that, for all purposes related togit
, should remain empty and never have it's contents tracked, a.gitignore
as suggested numerous times here, will do the trick.The format, as mentioned, is:
Now, if you want a way to do this at the command line, in one fell swoop, while inside the directory you want to add, you can execute:
Myself, I have a shell script that I use to do this. Name the script whatever you whish, and either add it somewhere in your include path, or reference it directly:
With this, you can either execute it from within the directory you wish to add, or reference the directory as it's first and only parameter:
Another option (in response to a comment by @GreenAsJade), if you want to track an empty folder that MAY contain tracked files in the future, but will be empty for now, you can ommit the
*
from the.gitignore
file, and check that in. Basically, all the file is saying is "do not ignore me", but otherwise, the directory is empty and tracked.Your
.gitignore
file would look like:That's it, check that in, and you have an empty, yet tracked, directory that you can track files in at some later time.
The reason I suggest keeping that one line in the file is that it gives the
.gitignore
purpose. Otherwise, some one down the line may think to remove it. It may help if you place a comment above the line.执行此操作的一个简单方法是将
.gitkeep
文件添加到您希望(当前)保持为空的目录中。请参阅此 SOF 答案 了解更多信息 - 这也解释了为什么有些人发现添加 .gitignore 文件的竞争约定(如这里的许多答案都提到过)令人困惑。
An easy way to do this is by adding a
.gitkeep
file to the directory you wish to (currently) keep empty.See this SOF answer for further info - which also explains why some people find the competing convention of adding a .gitignore file (as stated in many answers here) confusing.
在目录中创建一个名为
.gitkeep
的空文件,然后git add
它。默认情况下,这将是类 Unix 系统上的隐藏文件,但它会强制 Git 承认该目录的存在,因为它现在有内容。
另请注意,该文件的名称没有什么特别之处。 您可以将其命名为您想要的任何名称。 Git 关心的只是文件夹中有东西。
Create an empty file called
.gitkeep
in the directory, andgit add
it.This will be a hidden file on Unix-like systems by default but it will force Git to acknowledge the existence of the directory since it now has content.
Also note that there is nothing special about this file's name. You could have named it anything you wanted. All Git cares about is that the folder has something in it.
您始终可以在该目录中放置一个自述文件,并解释为什么您希望在存储库中使用此目录(否则为空目录)。
You could always put a README file in the directory with an explanation of why you want this, otherwise empty, directory in the repository.
你不能。 请参阅 Git 常见问题解答。
You can't. See the Git FAQ.
使目录保持(几乎)空(在存储库中)的另一种方法是在该目录中创建一个包含以下四行的
.gitignore
文件:然后您不必确保顺序正确您必须在 m104 的解决方案中执行的操作。
这还有一个好处,就是当您执行 git status 时,该目录中的文件不会显示为“未跟踪”。
使 @GreenAsJade 的评论持久化:
Another way to make a directory stay (almost) empty (in the repository) is to create a
.gitignore
file inside that directory that contains these four lines:Then you don't have to get the order right the way that you have to do in m104's solution.
This also gives the benefit that files in that directory won't show up as "untracked" when you do a git status.
Making @GreenAsJade's comment persistent:
为什么我们需要空的版本文件夹
首先要做的事情是:
它根本不会被跟踪。 但在某些情况下,“版本控制”空目录可能是有意义的,例如:
cache/
或logs/
目录,我们在其中想要提供文件夹,但.gitignore
其内容一些建议的解决方法
许多用户建议:
虽然这两种解决方案确实有效,但我发现它们与有意义的 Git 版本控制方法不一致。
.gitignore
来做一件与它的用途(排除文件)完全相反的事情(保留文件),尽管有可能的?.gitkeep 方法
使用名为
.gitkeep
的空文件来强制该文件夹存在于版本控制系统中。尽管看起来差别不大:
您使用的文件只有一个目的:保留文件夹。 您不要在其中放置任何您不想放置的信息。
例如,您应该将自述文件用作包含有用信息的自述文件,而不是作为保留文件夹的借口。
关注点分离始终是一件好事,您仍然可以添加
.gitignore
来忽略不需要的文件。将其命名为
.gitkeep
使其从文件名本身(以及其他开发人员)变得非常清晰和直接,这对于共享项目和核心之一来说是有好处的Git 存储库的用途)该文件是采用
相反我已经看到
.gitkeep
方法被非常重要的框架所采用,例如Laravel,Angular-CLI。Why would we need empty versioned folders
First things first:
It simply won't be tracked. But there are scenarios in which "versioning" empty directories can be meaningful, for example:
cache/
orlogs/
directories, where we want to provide the folder but.gitignore
its contentsSome suggested workarounds
Many users suggest:
README
file or another file with some content in order to make the directory non-empty, or.gitignore
file with a sort of "reverse logic" (i.e. to include all the files) which, at the end, serves the same purpose of approach #1.While both solutions surely work I find them inconsistent with a meaningful approach to Git versioning.
.gitignore
to do a thing (keeping files) that is the very opposite of what it's meant for (excluding files), even though it is possible?.gitkeep approach
Use an empty file called
.gitkeep
in order to force the presence of the folder in the versioning system.Although it may seem not such a big difference:
You use a file that has the single purpose of keeping the folder. You don't put there any info you don't want to put.
For instance, you should use READMEs as, well, READMEs with useful information, not as an excuse to keep the folder.
Separation of concerns is always a good thing, and you can still add a
.gitignore
to ignore unwanted files.Naming it
.gitkeep
makes it very clear and straightforward from the filename itself (and also to other developers, which is good for a shared project and one of the core purposes of a Git repository) that this file isAdoption
I've seen the
.gitkeep
approach adopted by very important frameworks like Laravel, Angular-CLI.在 Linux 上,这会创建一个名为
.placeholder
的空文件。 就其价值而言,这个名称与 git 无关,并且这种方法用于系统中的其他各个位置,例如/etc/cron.d/.placeholder
。 其次,正如另一位用户所指出的,.git
前缀约定可以保留给 Git 本身用于配置目的的文件和目录。或者,正如另一个答案中所述,该目录可以包含描述性
README.md
文件 。无论哪种方式,这都要求文件的存在不会导致您的应用程序崩溃。
On Linux, this creates an empty file named
.placeholder
. For what it's worth, this name is agnostic to git, and this approach is used in various other places in the system, e.g./etc/cron.d/.placeholder
. Secondly, as another user has noted, the.git
prefix convention can be reserved for files and directories that Git itself uses for configuration purposes.Alternatively, as noted in another answer, the directory can contain a descriptive
README.md
file instead.Either way this requires that the presence of the file won't cause your application to break.
在空目录中添加一个 .gitkeep 文件并提交。
.gitkeep是一个隐藏文件,在linux运行命令中列出它
Add a .gitkeep file inside the empty directory and commit it.
.gitkeep is a hidden file, to list it in linux run command
TL;DR:在目录中拍一个文件,它将被 git 跟踪。 (说真的。这是官方的解决方法)
但我建议:让构建脚本或部署脚本在站点上创建目录。
官方方式:
Git 不跟踪空目录。 有关更多详细信息,请参阅官方 Git 常见问题解答。 建议的解决方法是将
.gitignore
文件放入空目录中。 文件就位后,目录不再是空的,并且将由 git 跟踪。我不喜欢这种解决方法。 文件
.gitignore
旨在忽略某些内容。 这里它的用法相反:保留某物。一个常见的解决方法(解决方法)是将文件命名为
.gitkeep
。 这至少传达了文件名的意图。 这似乎也是一些项目之间的共识。 Git 本身并不关心文件的名称。 它只关心目录是否为空。.gitkeep
和.gitignore
都存在一个共同的问题:文件按照 unix 约定被隐藏。 诸如 ls 或 cp dir/* 之类的某些工具会假装该文件不存在,并且表现得就像该目录为空一样。 其他工具(例如find -empty
)则不会。 UNIX 新手用户可能会对此感到困惑。 经验丰富的 UNIX 用户会推断出存在隐藏文件并检查它们。 不管; 这是一个可以避免的烦恼。旁注:“隐藏文件问题”的一个简单解决方案是将文件命名为
gitkeep
(不带前导点)。 我们可以更进一步,将文件命名为README
。 然后,在文件中解释为什么目录需要为空并在 git 中进行跟踪。 这样其他开发人员(以及未来的您)就可以了解事情为何如此。摘要:在目录中添加一个文件,现在(以前是空的)目录被 git 跟踪。
潜在问题:目录不再为空。
假设您需要空目录,因为您正在其中收集文件以便稍后处理。 但现在你不仅拥有你想要的文件,而且还拥有一个流氓
.gitignore
或gitkeep
或其他什么。 这可能会使简单的 bash 构造变得复杂,例如for file in dirname/*
因为您需要排除额外的文件或特殊情况。Git 不想跟踪空目录。 通过尝试让 git 跟踪空目录,你牺牲了你试图保留的东西:空目录。
另外:项目目录中的虚假“空”目录也会出现问题。 新的开发人员,或者未来的你,会偶然发现这个空目录,并想知道为什么它需要在那里。 您可以删除该目录。 您可以将其他文件放入其中。 您甚至可以创建第二个也使用空目录的工作流程。 然后在未来的某个时候,两个使用空目录的工作流程会同时运行,并且所有脚本都会失败,因为这些文件没有意义,并且两个团队都想知道其他文件来自哪里。
我的建议:让构建脚本或部署脚本在站点上创建目录。
让我们退后几步。 在你问如何让 git 跟踪一个空目录之前。
当时您遇到的情况可能如下:您有一个需要空目录才能工作的工具。 您想要部署/分发此工具,并且还希望部署空目录。 问题:git 不跟踪空目录。
现在,我们不用尝试让 git 跟踪空目录,而是探索其他选项。 也许(希望)您有一个部署脚本。 让部署脚本在 git clone 之后创建目录。 或者你有一个构建脚本。 让构建脚本在编译后创建目录。 或者甚至可以修改工具本身以在使用前检查并创建目录。
如果该工具旨在供人类在不同的环境中使用,那么我会让该工具本身检查并创建目录。 如果您无法修改该工具,或者以高度自动化的方式使用该工具(docker 容器部署、工作、销毁),那么部署脚本将是创建目录的好地方。
我认为这是解决问题的更明智的方法。 构建脚本和部署脚本旨在为运行程序做好准备。 您的工具需要一个空目录。 因此,使用这些脚本来创建空目录。
额外的好处:在使用时该目录保证是真正的空目录。 此外,其他开发人员(以及未来的您)也不会偶然发现存储库中的“空”目录,并想知道为什么它需要在那里。
TL;DR:让构建脚本或部署脚本在站点上创建空目录。 或者让工具在使用前自行检查并创建目录。
如果您继承的项目包含空或“空”目录,以下命令可能会对您有所帮助。
列出每个空目录:
相同,但避免查看
.git
目录:列出包含名为
.gitkeep
的文件的每个目录:列出每个目录和文件数量它包含:
现在您可以检查仅包含一个文件的所有目录,并检查它是否是“git keep”文件。 请注意,此命令不会列出真正为空的目录。
TL;DR: slap a file in the directory and it will be tracked by git. (seriously. that is the official workaround)
But I recommend instead: let a build script or deploy script create the directory on site.
The official way:
Git does not track empty directories. See the official Git FAQ for more detail. The suggested workaround is to put a
.gitignore
file in the empty directory. With the file in place the directory is no longer empty and will be tracked by git.I do not like that workaround. The file
.gitignore
is meant to ignore things. Here it is used for the opposite: to keep something.A common workaround (to the workaround) is to name the file
.gitkeep
. This at least conveys the intention in the filename. Also it seems to be a consensus among some projects. Git itself does not care what the file is named. It just cares if the directory is empty or not.There is a problem shared by both
.gitkeep
and.gitignore
: the file is hidden by unix convention. Some tools likels
orcp dir/*
will pretend the file does not exists and behave as if the directory is empty. Other tools likefind -empty
will not. Newbie unix users might get stumped on this. Seasoned unix users will deduce that there are hidden files and check for them. Regardless; this is an avoidable annoyance.Side note: a simple solution to the "hidden file problematic" is to name the file
gitkeep
(without the leading dot). We can take this one step further and name the fileREADME
. Then, in the file, explain why the directory needs to be empty and be tracked in git. That way other developers (and future you) can read up why things are the way they are.Summary: slap a file in the directory and now the (formerly empty) directory is tracked by git.
Potential Problem: the directory is no longer empty.
The assumption is that you need the empty directory because you are collecting files in it to process later. But now you not only have the files you want but also one rogue
.gitignore
orgitkeep
or what have you. This might complicate simple bash constructs likefor file in dirname/*
because you need to exclude or special case the extra file.Git does not want to track empty directories. By trying to make git track the empty directory you sacrifice the very thing you were trying to preserve: the empty directory.
Also: spurious "empty" directories in the project directory are problems-to-be. A new developer, or future you, will stumble upon the empty directory and wonder why it needs to be there. You might delete the directory. You might put other files in it. You might even create a second workflow which also uses the empty directory. Then some time in the future it happens that both workflows using the empty directory run simultaneously and all scripts fail because the files make no sense and both teams wonder where the other files have come from.
My recommendation: let a build script or deploy script create the directory on site.
Lets take a few steps back. To before you asked how to make git track an empty directory.
The situation you had then was likely the following: you have a tool that needs an empty directory to work. You want to deploy/distribute this tool and you want the empty directory to also be deployed. Problem: git does not track empty directories.
Now instead of trying to get git to track empty directories lets explore the other options. Maybe (hopefully) you have a deploy script. Let the deploy script create the directory after git clone. Or you have a build script. Let the build script create the directory after compiling. Or maybe even modify the tool itself to check for and create the directory before use.
If the tool is meant to be used by humans in diverse environments then I would let the tool itself check and create the directories. If you cannot modify the tool, or the tool is used in a highly automatized manner (docker container deploy, work, destroy), then the deploy script would be good place to create the directories.
I think this is the more sensible approach to the problem. Build scripts and deploy scripts are meant to prepare things to run the program. Your tool requires an empty directory. So use those scripts to create the empty directory.
Bonus: the directory is guaranteed to be truly empty when about to be used. Also other developers (and future you) will not stumble upon an "empty" directory in the repository and wonder why it needs to be there.
TL;DR: let the build script or the deploy script create the empty directory on site. or let the tool itself check for and create the directory before use.
The following commands might help you if you inherited a project containing empty or "empty" directories.
To list every empty directory:
Same but avoid looking in the
.git
directory:To list every directory containing a file named
.gitkeep
:To list every directory and the number of files it contains:
Now you can examine all directories containing exactly one file and check if it is a "git keep" file. Note this command does not list directories that are truly empty.
Andy Lester 是对的,但如果您的目录只需为空,而不是空,您可以在其中放置一个空的 .gitignore 文件作为解决方法。
顺便说一句,这是一个实现问题,而不是基本的 Git 存储设计问题。 正如 Git 邮件列表中多次提到的,这一点尚未实现的原因是没有人足够关心为它提交补丁,而不是它不能或不应该这样做。
Andy Lester is right, but if your directory just needs to be empty, and not empty empty, you can put an empty
.gitignore
file in there as a workaround.As an aside, this is an implementation issue, not a fundamental Git storage design problem. As has been mentioned many times on the Git mailing list, the reason that this has not been implemented is that no one has cared enough to submit a patch for it, not that it couldn’t or shouldn’t be done.
正如其他答案中所述,Git 无法表示其暂存区域中的空目录。 (请参阅 Git 常见问题解答。)但是,如果您出于目的,如果目录仅包含
.gitignore
文件,则该目录足够空,那么您只能通过以下方式在空目录中创建.gitignore
文件:As described in other answers, Git is unable to represent empty directories in its staging area. (See the Git FAQ.) However, if, for your purposes, a directory is empty enough if it contains a
.gitignore
file only, then you can create.gitignore
files in empty directories only via:警告:事实证明,此调整并未真正发挥作用。对于给您带来的不便,我们深表歉意。
原帖如下:
我在使用 Git 内部时找到了一个解决方案!
创建空目录:
使用管道命令和空树将其添加到索引SHA-1:
键入命令,然后输入第二行。 按 Enter,然后按 Ctrl + D 终止输入。
注意:格式为mode [SPACE] type [SPACE] SHA-1hash [TAB]路径(tab很重要,答案格式不保留它)。
就是这样! 您的空文件夹位于您的索引中。 您所要做的就是提交。
这个解决方案很短并且显然工作得很好(请参阅编辑!),但它并不那么容易记住......
空树 SHA-1 可以通过创建一个新的空 Git 存储库来找到,
cd
进入其中并发出git write-tree
,它输出空树 SHA-1。编辑:
自从我找到这个解决方案以来,我一直在使用它。 它的工作方式似乎与创建子模块完全相同,只是没有在任何地方定义模块。
这会导致在发出 git submodule init|update 时出现错误。
问题在于
git update-index
将040000 树
部分重写为160000 commit
。此外,放置在该路径下的任何文件都不会被 Git 注意到,因为它认为它们属于其他某个存储库。 这很令人讨厌,因为它很容易被忽视!
但是,如果您还没有(也不会)在存储库中使用任何 Git 子模块,并且“空”文件夹将保持为空,或者如果您希望 Git 知道它的存在并忽略其内容,您可以使用这个调整。 使用子模块的通常方式比此调整需要更多步骤。
WARNING: This tweak is not truly working as it turns out. Sorry for the inconvenience.
Original post below:
I found a solution while playing with Git internals!
Create your empty directory:
Add it to the index using a plumbing command and the empty tree SHA-1:
Type the command and then enter the second line. Press Enter and then Ctrl + D to terminate your input.
Note: the format is mode [SPACE] type [SPACE] SHA-1hash [TAB] path (the tab is important, the answer formatting does not preserve it).
That's it! Your empty folder is in your index. All you have to do is commit.
This solution is short and apparently works fine (see the EDIT!), but it is not that easy to remember...
The empty tree SHA-1 can be found by creating a new empty Git repository,
cd
into it and issuegit write-tree
, which outputs the empty tree SHA-1.EDIT:
I've been using this solution since I found it. It appears to work exactly the same way as creating a submodule, except that no module is defined anywhere.
This leads to errors when issuing
git submodule init|update
.The problem is that
git update-index
rewrites the040000 tree
part into160000 commit
.Moreover, any file placed under that path won't ever be noticed by Git, as it thinks they belong to some other repository. This is nasty as it can easily be overlooked!
However, if you don't already (and won't) use any Git submodules in your repository, and the "empty" folder will remain empty or if you want Git to know of its existence and ignore its content, you can go with this tweak. Going the usual way with submodules takes more steps that this tweak.
你不能而且不幸的是永远也不能。 这是莱纳斯·托瓦尔德本人做出的决定。 他知道什么对我们有好处。
我曾经读过某处有一篇咆哮。
我发现回复:空目录..,但也许还有另一个。
不幸的是,您必须接受解决方法。
You can't and unfortunately will never be able to. This is a decision made by Linus Torvald himself. He knows what's good for us.
There is a rant out there somewhere I read once.
I found Re: Empty directories.., but maybe there is another one.
You have to live with the workarounds...unfortunately.
这个解决方案对我有用。
1. 将
.gitignore
文件添加到您的空目录中:*
忽略文件夹中的所有文件*/
忽略子目录!.gitignore
包含 .gitignore 文件2. 然后删除缓存、暂存文件、提交并推送:
This solution worked for me.
1. Add a
.gitignore
file to your empty directory:*
ignore all files in the folder*/
Ignore subdirectories!.gitignore
include the .gitignore file2. Then remove your cache, stage your files, commit and push:
也许添加一个空目录似乎是阻力最小的路径,因为您的脚本期望该目录存在(可能是因为它是生成的二进制文件的目标)。 另一种方法是修改脚本以根据需要创建目录。
在此示例中,您可以签入该目录的(损坏的)符号链接,以便您可以在没有“.generate”前缀的情况下访问它(但这是可选的)。
当您想要清理源代码树时,您可以:
如果您采用经常建议的方法签入几乎为空的文件夹,则删除内容的复杂性较小,而无需同时删除“.gitignore”文件。
您可以通过将以下内容添加到根 .gitignore 来忽略所有生成的文件:
Maybe adding an empty directory seems like it would be the path of least resistance because you have scripts that expect that directory to exist (maybe because it is a target for generated binaries). Another approach would be to modify your scripts to create the directory as needed.
In this example, you might check in a (broken) symbolic link to the directory so that you can access it without the ".generated" prefix (but this is optional).
When you want to clean up your source tree you can just:
If you take the oft-suggested approach of checking in an almost-empty folder, you have the minor complexity of deleting the contents without also deleting the ".gitignore" file.
You can ignore all of your generated files by adding the following to your root .gitignore:
我喜欢 Artur79 的答案 和 mjs ,所以我一直在使用两者的组合,并将其作为我们项目的标准。
然而,我们只有少数开发人员在 Mac 或 Linux 上工作。 在 Windows 上做了很多工作,但我找不到等效的简单单行代码来完成同样的任务。 有些人很幸运因为其他原因安装了 Cygwin,但仅仅为此开出 Cygwin 似乎有些过分了。
所以,由于我们大多数开发人员已经安装了 Ant,所以我首先想到的就是组装一个 Ant构建文件以独立于平台完成此操作。 这仍然可以在这里
但是找到,最好将其变成一个小的实用程序命令,因此我使用 Python 重新创建了它,并将其发布到 PyPI 此处。 您只需运行即可安装它:
它将允许您递归地创建和删除 .gitkeep 文件,并且还允许您向它们添加消息,以便您的同行了解为什么这些目录很重要。 最后一点是额外的好处。 我认为如果
.gitkeep
文件能够自我记录就好了。I like the answers by Artur79 and mjs, so I've been using a combination of both and made it a standard for our projects.
However, only a handful of our developers work on Mac or Linux. A lot work on Windows, and I could not find an equivalent simple one-liner to accomplish the same there. Some were lucky enough to have Cygwin installed for other reasons, but prescribing Cygwin just for this seemed overkill.
So, since most of our developers already have Ant installed, the first thing I thought of was to put together an Ant build file to accomplish this independently of the platform. This can still be found here
However, it would be better to make this into a small utility command, so I recreated it using Python and published it to the PyPI here. You can install it by simply running:
It will allow you to create and remove
.gitkeep
files recursively, and it will also allow you to add messages to them for your peers to understand why those directories are important. This last bit is bonus. I thought it would be nice if the.gitkeep
files could be self-documenting.假设您需要一个名为 tmp 的空目录:
换句话说,您需要将 .gitignore 文件添加到索引中,然后才能告诉 Git 忽略它(以及空目录中的其他所有内容)。
Let's say you need an empty directory named tmp :
In other words, you need to add the .gitignore file to the index before you can tell Git to ignore it (and everything else in the empty directory).
Ruby on Rails 日志文件夹创建方式:
现在日志目录将包含在树中。 它在部署时非常有用,因此您不必编写例程来创建日志目录。
可以通过发出来阻止日志文件,
但您可能知道这一点。
The Ruby on Rails log folder creation way:
Now the log directory will be included in the tree. It is super-useful when deploying, so you won't have to write a routine to make log directories.
The logfiles can be kept out by issuing,
but you probably knew that.
我也遇到了空目录的问题。 使用占位符文件的问题是,如果不再需要它们,您需要创建它们并删除它们(因为后来添加了子目录或文件。使用大型源树管理这些占位符文件可能会很麻烦并且会出错 。
开源工具,它是为 .NET 平台编写的,并在 Mono(.NET for Linux)和 Windows 下运行
这就是为什么我决定编写一个可以自动管理此类占位符文件的创建/删除的 网址:http://code.google.com/p/markemptydirs
I've been facing the issue with empty directories, too. The problem with using placeholder files is that you need to create them, and delete them, if they are not necessary anymore (because later on there were added sub-directories or files. With big source trees managing these placeholder files can be cumbersome and error prone.
This is why I decided to write an open source tool which can manage the creation/deletion of such placeholder files automatically. It is written for .NET platform and runs under Mono (.NET for Linux) and Windows.
Just have a look at: http://code.google.com/p/markemptydirs
阅读ofavre的和stanislav-bashkyrtsev的答案 使用损坏的 Git 子模块引用来创建 Git 目录,令我惊讶的是,还没有人建议对这个想法进行简单的修改,以使整个事情变得理智和安全:
而不是将一个假子模块侵入Git,只需添加一个空的真实的。
输入:https://gitlab.com/empty-repo/empty.git
A Git 存储库只有一次提交:
没有消息,没有提交的文件。
用法
向您的 GIT 存储库添加一个空目录:
将所有现有的空目录转换为子模块:
Git 将在创建子模块引用时存储最新的提交哈希,因此您不必担心我(或 GitLab)使用它来注入恶意文件。 不幸的是,我还没有找到任何方法来强制在结帐期间使用哪个提交 ID,因此您必须使用
git submodule status
手动检查引用提交 ID 是否为e84d7b81f0033399e325b8037ed2b801a5c994e0
添加存储库后。仍然不是原生解决方案,但我们可能可以拥有最好的解决方案,而无需有人在 GIT 代码库中真正、真正弄脏。
附录:重新创建此提交
您应该能够使用(在空目录中)重新创建此精确提交:
创建可重现的 Git 提交出人意料地困难......
Reading ofavre's and stanislav-bashkyrtsev's answers using broken Git submodule references to create the Git directories, I'm surprised that nobody has suggested yet this simple amendment of the idea to make the whole thing sane and safe:
Rather than hacking a fake submodule into Git, just add an empty real one.
Enter: https://gitlab.com/empty-repo/empty.git
A Git repository with exactly one commit:
No message, no committed files.
Usage
To add an empty directory to you GIT repo:
To convert all existing empty directories to submodules:
Git will store the latest commit hash when creating the submodule reference, so you don't have to worry about me (or GitLab) using this to inject malicious files. Unfortunately I have not found any way to force which commit ID is used during checkout, so you'll have to manually check that the reference commit ID is
e84d7b81f0033399e325b8037ed2b801a5c994e0
usinggit submodule status
after adding the repo.Still not a native solution, but the best we probably can have without somebody getting their hands really, really dirty in the GIT codebase.
Appendix: Recreating this commit
You should be able to recreate this exact commit using (in an empty directory):
Creating reproducible Git commits is surprisingly hard…
添加
.gitignore
文件时,如果您要在其中放入任意数量的内容(您希望 Git 忽略),您可能需要添加仅包含星号的一行*
以确保您不会意外添加忽略的内容。When you add a
.gitignore
file, if you are going to put any amount of content in it (that you want Git to ignore) you might want to add a single line with just an asterisk*
to make sure you don't add the ignored content accidentally.无法让 Git 跟踪目录,因此唯一的解决方案是在您希望 Git 跟踪的目录中添加占位符文件。
该文件可以命名并包含您想要的任何内容,但大多数人使用名为
.gitkeep
的空文件(尽管有些人更喜欢与 VCS 无关的.keep
)。前缀
.
将其标记为隐藏文件。另一个想法是添加一个 README 文件来解释该目录的用途。
There's no way to get Git to track directories, so the only solution is to add a placeholder file within the directory that you want Git to track.
The file can be named and contain anything you want, but most people use an empty file named
.gitkeep
(although some people prefer the VCS-agnostic.keep
).The prefixed
.
marks it as a hidden file.Another idea would be to add a
README
file explaining what the directory will be used for.PowerShell 版本:
A PowerShell version:
如前所述,不可能添加空目录,但这里有一个行将空 .gitignore 文件添加到所有目录。
ruby -e '需要“fileutils”; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'
我已将其粘贴在 Rakefile 中以便于访问。
As mentioned it's not possible to add empty directories, but here is a one liner that adds empty .gitignore files to all directories.
ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'
I have stuck this in a Rakefile for easy access.