¿Cómo puedo agregar un directory vacío a un repository de Git?

¿Cómo puedo agregar un directory vacío (que no contiene files) a un repository de Git?

Otra forma de hacer que un directory permanezca vacío (en el repository) es crear un file .gitignore dentro de ese directory que contenga cuatro líneas:

 # Ignore everything in this directory * # Except this file !.gitignore 

Entonces no tiene que get el pedido de la manera que tiene que hacer en la solución de m104.

No puedes. Vea las preguntas frecuentes de Git .

En la actualidad, el layout del índice git (área de transición) solo permite listr files, y nadie lo suficientemente competente como para realizar el cambio para permitir directorys vacíos se ha preocupado lo suficiente sobre esta situación como para remediarlo.

Los directorys se agregan automáticamente al agregar files dentro de ellos. Es decir, los directorys nunca deben agregarse al repository y no se rastrean por sí solos.

Puedes decir " git add <dir> " y agregará files allí.

Si realmente necesita que exista un directory en las cajas, debe crear un file en él. .gitignore funciona bien para este propósito; puede dejarlo vacío o completar los nombres de los files que espera que aparezcan en el directory.

Cree un file vacío llamado .gitkeep en el directory y agréguelo.

Siempre puede poner un file README en el directory con una explicación de por qué quiere este, de lo contrario, vacío, directory en el repository.

 touch .keep 

En Linux, esto crea un file vacío llamado .keep . Este nombre es preferido sobre .gitkeep ya que el primero es agnóstico para Git, mientras que el último es específico para Git. En segundo lugar, como ha señalado otro usuario, la convención de prefijo .git debe reservarse para los files y directorys que usa Git.

Alternativamente, como se señala en otra respuesta , el directory puede contener un file README o README.md descriptivo en README.md lugar.

Por supuesto, esto requiere que la presencia del file no haga que su aplicación se rompa.

¿Por qué necesitaríamos carpetas con versiones vacías?

Un directory vacío no puede ser parte de un tree bajo el sistema de control de versiones Git . Pero hay muchos escenarios en los que un directory vacío podría ser útil, por ejemplo:

  • build una estructura de carpetas pnetworkingefinida para carpetas de proyectos útiles, como un vendor/ carpeta para packages de compositores , y hacer que esta estructura esté disponible para cada usuario / queueborador del repository; o, como caso especializado de los anteriores, crear una carpeta para files temporales , como un cache/ o logs/ directorys
  • algunos proyectos simplemente no funcionarán sin algunas carpetas (que a menudo es un indicio de un proyecto mal diseñado, pero es un escenario frecuente en el mundo real y tal vez podría haber, por ejemplo, problemas de permissions).

Algunas soluciones sugeridas

Muchos usuarios sugieren:

  1. Colocando un file README u otro file con algún contenido para que el directory no esté vacío, o
  2. Creando un file .gitignore con una especie de "lógica inversa" (es decir, para include todos los files) que, al final, sirve para el mismo propósito del acercamiento # 1.

Si bien ambas soluciones seguramente funcionan , no hay duda al respecto, las encuentro inconsistentes con un enfoque significativo para el control de versiones de Git.

  • ¿Por qué se supone que debes poner files falsos o README que quizás no quieras en tu proyecto?
  • ¿Por qué usar .gitignore para hacer una cosa ( mantener files) que es .gitignore lo contrario de lo que significa ( excluyendo files), aunque es posible?

enfoque .gitkeep

Use un file vacío llamado .gitkeep para forzar la presencia de la carpeta en el sistema de versiones.

Aunque puede parecer una diferencia no tan grande:

  • Utiliza un file que tiene el único propósito de mantener la carpeta. No colocas allí ninguna información que no quieras poner.

    Por ejemplo, debe usar README como README, no como una excusa para save la carpeta.

    La separación de las preocupaciones siempre es algo bueno, y aún puede agregar un .gitignore para ignorar los files no deseados.

  • .gitkeep deja muy claro y directo desde el nombre del file (y también a otros desarrolladores , que es bueno para un proyecto compartido y uno de los propósitos principales de un repository de Git) que este file es

    • Un file no relacionado con el código (debido al punto inicial y el nombre)
    • Un file claramente relacionado con Git
    • Su propósito ( mantener ) está claramente establecido y es consistente y semánticamente opuesto en su significado para ignorar

Adopción

He visto el enfoque .gitkeep adoptado por frameworks muy importantes como Laravel , Angular-CLI .

Como se describe en otras respuestas, Git no puede representar directorys vacíos en su área de preparación. (Consulte las preguntas frecuentes de Git ). Sin embargo, si, para su propósito, un directory está lo suficientemente vacío si contiene un file .gitignore solamente, entonces puede crear files .gitignore en directorys vacíos solo a través de:

 find . -type d -empty -exec touch {}/.gitignore \; 

Andy Lester tiene razón, pero si su directory solo necesita estar vacío, y no está vacío, puede poner un file .gitignore vacío allí como una solución alternativa.

Como un aparte, este es un problema de implementación, no un problema fundamental de layout de almacenamiento Git. Como se ha mencionado muchas veces en la list de correo de Git, la razón por la que esto no se ha implementado es que nadie se ha preocupado lo suficiente como para enviar un parche para ello, no es que no pueda o no deba hacerse.

El path de Ruby on Rails :

 mkdir log && touch log/.gitkeep && git add log/.gitkeep 

Ahora el directory de logging se includeá en el tree. Es súper útil cuando se implementa, por lo que no tendrá que escribir una rutina para crear directorys de logging.

Los files de logging pueden mantenerse fuera emitiendo,

 echo log/dev.log >> .gitignore 

pero probablemente lo sabías.

Git no rastrea los directorys vacíos. Consulte las preguntas frecuentes de Git para get más explicaciones. La solución sugerida es colocar un file .gitignore en el directory vacío. No me gusta esa solución, porque el .gitignore está "oculto" por la convención de Unix. Además, no hay explicación de por qué los directorys están vacíos.

Sugiero poner un file README en el directory vacío explicando por qué el directory está vacío y por qué necesita ser rastreado en Git. Con el file README en su lugar, en lo que respecta a Git, el directory ya no está vacío.

La verdadera pregunta es ¿por qué necesitas el directory vacío en git? ¿No tienes algún tipo de script de compilation que pueda crear el directory vacío antes de comstackr / ejecutar? Usualmente cuando realmente necesitas el directory vacío en git hay una razón para eso. Entonces pones esa razón en el file README. De esta forma, otros desarrolladores saben por qué el directory vacío debe estar allí. Futuro también sabrá que puede eliminar el directory vacío cuando se haya resuelto el problema que requiere el directory vacío.

Para enumerar todos los directorys vacíos, use el siguiente command:

 find -name .git -prune -o -type d -empty -print 

Para crear LÍMITES de marcador de position en cada directory vacío:

 find -name .git -prune -o -type d -empty -exec sh -c \ "echo this directory is intentionally left empty > {}/README.emptydir" \; 

Para ignorar todo en el directory, excepto el file README, ponga las siguientes líneas en su .gitignore :

 path/to/emptydir/* !path/to/emptydir/README.emptydir path/to/otheremptydir/* !path/to/otheremptydir/README.emptydir 

Alternativamente, podría excluir cada file README de ser ignorado:

 path/to/emptydir/* path/to/otheremptydir/* !README.emptydir 

Para enumerar cada LÉAME después de que ya estén creados:

 find -name README.emptydir 

ADVERTENCIA: Este ajuste no funciona realmente como resulta. Lo siento por los inconvenientes ocasionados.

Publicación original a continuación:

¡Encontré una solución mientras jugaba con Git Internal!

  1. Supongamos que está en su repository.
  2. Crea tu directory vacío:

     $ mkdir path/to/empty-folder 
  3. Agréguelo al índice usando un command de plomería y el tree vacío SHA-1 :

     $ git update-index --index-info 040000 tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904 path/to/empty-folder 

    Escriba el command y luego ingrese la segunda línea. Presione Enter y luego Ctrl + D para finalizar su input. Nota: el formatting es modo [ESPACIO] tipo [ESPACIO] SHA-1hash [TAB] ruta (la pestaña es importante, el formatting de respuesta no lo conserva).

  4. ¡Eso es! Su carpeta vacía está en su índice. Todo lo que tienes que hacer es comprometerte.

Esta solución es corta y aparentemente funciona bien ( ver el EDITAR! ), Pero no es tan fácil de recordar …

El tree vacío SHA-1 se puede encontrar creando un nuevo repository de Git vacío, cd en él y emitir git write-tree , que genera el tree vacío SHA-1.

EDITAR:

He estado usando esta solución desde que la encontré. Parece que funciona exactamente de la misma manera que crear un submodule, excepto que ningún module está definido en ningún lado. Esto genera errores al emitir el git submodule init|update . El problema es que git update-index reescribe la parte del 040000 tree en 160000 commit .

Además, Git nunca notará ningún file colocado bajo esa ruta, ya que cree que pertenece a algún otro repository. Esto es desagradable, ya que puede pasarse por alto fácilmente!

Sin embargo, si aún no (y no) usará ningún submodule Git en su repository, y la carpeta "vacía" permanecerá vacía o si desea que Git conozca su existencia e ignore su contenido, puede ir con este ajuste Ir de la manera habitual con los submodules requiere más pasos que este ajuste.

Quizás agregar un directory vacío parece ser la ruta de menor resistencia porque tienes scripts que esperan que ese directory exista (tal vez porque es un objective para los binarys generados). Otro enfoque sería modificar sus scripts para crear el directory según sea necesario .

 mkdir --parents .generated/bin ## create a folder for storing generated binaries mv myprogram1 myprogram2 .generated/bin ## populate the directory as needed 

En este ejemplo, puede verificar un enlace simbólico (roto) al directory para que pueda acceder a él sin el prefijo "generado" (pero esto es opcional).

 ln -sf .generated/bin bin git add bin 

Cuando desee limpiar su tree fuente, puede simplemente:

 rm -rf .generated ## this should be in a "clean" script or in a makefile 

Si adopta el enfoque frecuentemente sugerido de registrar en una carpeta casi vacía, tiene la menor complejidad de eliminar los contenidos sin eliminar también el file ".gitignore".

Puede ignorar todos sus files generados agregando lo siguiente a su raíz .gitignore:

 .generated 

Digamos que necesitas un directory vacío llamado tmp :

 $ mkdir tmp $ touch tmp/.gitignore $ git add tmp $ echo '*' > tmp/.gitignore $ git commit -m 'Empty directory' tmp 

En otras palabras, debe agregar el file .gitignore al índice antes de decirle a Git que lo ignore (y todo lo demás en el directory vacío).

También me he enfrentado al problema con directorys vacíos. El problema con el uso de files de marcador de position es que debe crearlos y eliminarlos, si ya no son necesarios (porque más adelante se agregaron subdirectorys o files. Con grandes treees de código fuente, la gestión de estos files de marcador de position puede ser engorrosa y generar errores propenso.

Es por eso que decidí escribir una herramienta de código abierto que puede administrar la creación / eliminación de dichos files de marcador de position automáticamente. Está escrito para la plataforma .NET y se ejecuta bajo Mono (.NET para Linux) y Windows.

Solo eche un vistazo a: http://code.google.com/p/markemptydirs

Usted no puede y lamentablemente nunca podrá. Esta es una decisión tomada por el propio Linus Torvald. Él sabe lo que es bueno para nosotros.

Hay una diatriba por ahí en algún lugar que leí una vez.

Encontré Re: directorys vacíos … , pero tal vez haya otro.

Tienes que vivir con las soluciones … desafortunadamente.

Cuando agrega un file .gitignore , si va a poner cualquier cantidad de contenido en él (que desea que ignore Git), puede agregar una sola línea con solo un asterisco * para asegurarse de que no agrega el contenido ignorado accidentalmente.

Como se mencionó, no es posible agregar directorys vacíos, pero aquí hay un trazador de líneas que agrega files .gitignore vacíos a todos los directorys.

ruby -e 'require "fileutils" ; Dir.glob(["target_directory","target_directory/**"]).each { |f| FileUtils.touch(File.join(f, ".gitignore")) if File.directory?(f) }'

He pegado esto en un Rakefile para un fácil acceso.

Siempre construyo una function para verificar la estructura de mi carpeta deseada y buildla para mí dentro del proyecto. Esto evita este problema ya que las carpetas vacías se guardan en Git por proxy.

 function check_page_custom_folder_structure () { if (!is_dir(TEMPLATEPATH."/page-customs")) mkdir(TEMPLATEPATH."/page-customs"); if (!is_dir(TEMPLATEPATH."/page-customs/css")) mkdir(TEMPLATEPATH."/page-customs/css"); if (!is_dir(TEMPLATEPATH."/page-customs/js")) mkdir(TEMPLATEPATH."/page-customs/js"); } 

Esto está en PHP, pero estoy seguro de que la mayoría de los idiomas admiten la misma funcionalidad, y debido a que la aplicación se ocupa de la creación de las carpetas, las carpetas siempre estarán allí.

No hay forma de que Git rastree los directorys, por lo que la única solución es agregar un file de marcador de position dentro del directory que desea que Git rastree.

El file se puede nombrar y contener todo lo que desee, pero la mayoría de la gente usa un file vacío llamado .gitkeep (aunque algunas personas prefieren el .keep VCS-agnostic).

El prefijo . lo marca como un file oculto.

Another idea would be to add a README file explaining what the directory will be used for.

The solution of Jamie Flournoy works great. Here is a bit enhanced version to keep the .htaccess :

 # Ignore everything in this directory * # Except this file !.gitignore !.htaccess 

With this solution you are able to commit a empty folder, for example /log , /tmp or /cache and the folder will stay empty.

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.

 find . -type d -empty -exec touch {}/.gitkeep \; 

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, I put together a build file to accomplish this independently of the platform.

 <?xml version="1.0" encoding="ISO-8859-1"?> <project name="Gitkeep" basedir="." default="keep"> <!--Apply to all subdirs of this dir--> <target name="keep" description="-> Add a .gitkeep file to all empty subdir's of this dir."> <!--Create a ref to all the subdirs in the tree of this dir--> <dirset id="dirs.ref" dir="./" includes="**/*"/> <!--Create a list of the subdirs under this dir--> <property name="dirs.list" refid="dirs.ref" /> <!--For each subdir--> <for list="${dirs.list}" delimiter=";" param="dir"> <sequential> <!--If the subdir is empty this target will add a .gitkeep file to it--> <antcall target="gitkeep" inheritall="false"> <param name="dir" value="@{dir}"/> </antcall> </sequential> </for> </target> <!--Add a .gitkeep file to a directory if it's empty--> <target name="gitkeep" description="-> Add a .gitkeep file to a specific subdir of this dir. Use -Ddir=relative/path/to/dir"> <!--Create a ref of the files inside this dir--> <fileset dir="${dir}" id="contents.ref"/> <!--Create a path to the contents of this directory, ONLY if it's not empty--> <pathconvert refid="contents.ref" property="contents.path" setonempty="false"/> <if> <!--If the dir is empty create the .gitkeep file--> <not><isset property="contents.path"/></not> <then> <!--Create the .gitkeep file--> <echo message="Version this dir in Git even if its empty." file="./${dir}/.gitkeep" force="true" append="false"/> </then> </if> </target> </project> 

Now I can simply run

 ant -f gitkeep.xml 

And this creates a .gitkeep file in any empty subdir. Even on Windows 🙂 Note: This build file requires the Ant Contrib jar.

I continue to work on this concept here .

https://github.com/mig82/gitkeep

Here is a hack, but it's funny that it works (Git 2.2.1). Similar to what @Teka suggested, but easier to remember:

  • Add a submodule to any repository ( git submodule add path_to_repo )
  • This will add a folder and a file .submodules . Commit a change.
  • Delete .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:

fatal: Not a valid object name b64338b90b4209263b50244d18278c0999867193

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.

No puedes. This is an intentional design decision by the Git maintainers. Basically, the purpose of a Source Code Management System like Git is managing source code and empty directories aren't source code. Git is also often described as a content tracker, and again, empty directories aren't content (quite the opposite, actually), so they are not tracked.

You can save this code as create_readme.php and run the PHP code from the root directory of your Git project.

 > php create_readme.php 

It will add README files to all directories that are empty so those directories would be then added to the index.

 <?php $path = realpath('.'); $objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST); foreach($objects as $name => $object){ if ( is_dir($name) && ! is_empty_folder($name) ){ echo "$name\n" ; exec("touch ".$name."/"."README"); } } function is_empty_folder($folder) { $files = opendir($folder); while ($file = readdir($files)) { if ($file != '.' && $file != '..') return true; // Not empty } } ?> 

Then do

 git commit -m "message" git push 

Adding one more option to the fray.

Assuming you would like to add a directory to git that, for all purposes related to git , 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:

 * !.gitignore 

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:

 $ echo "*" > .gitignore && echo '!.gitignore' >> .gitignore && git add .gitignore 

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:

 #!/bin/bash dir='' if [ "$1" != "" ]; then dir="$1/" fi echo "*" > $dir.gitignore && \ echo '!.gitignore' >> $dir.gitignore && \ git add $dir.gitignore 

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:

 $ ignore_dir ./some/directory 

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:

 !.gitignore 

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.

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:

 mkdir empty 

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):

 ln -s .this.directory empty/.keep 

To ignore files in this directory, you can add it in your root .gitignore :

 echo "/empty" >> .gitignore 

To add the ignonetworking file, use a parameter to force it:

 git add -f empty/.keep 

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:

 find empty -type f 

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:

 $ php -r "var_export(glob('empty/.*'));" array ( 0 => 'empty/.', 1 => 'empty/..', ) 

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…)

Sometimes I have repositories with folders that will only ever contain files considenetworking to be "content"—that is, they are not files that I care about being versioned, and therefore should never be committed. With Git's .gitignore file, you can ignore entire directories. But there are times when having the folder in the repo would be beneficial. Here's a excellent solution for accomplishing this need.

What I've done in the past is put a .gitignore file at the root of my repo, and then exclude the folder, like so:

 /app/some-folder-to-exclude /another-folder-to-exclude/* 

However, these folders then don't become part of the repo. You could add something like a README file in there. But then you have to tell your application not to worry about processing any README files.

If your app depends on the folders being there (though empty), you can simply add a .gitignore file to the folder in question, and use it to accomplish two goals:

Tell Git there's a file in the folder, which makes Git add it to the repo. Tell Git to ignore the contents of this folder, minus this file itself. Here is the .gitignore file to put inside your empty directories:

 * !.gitignore 

The first line (*) tells Git to ignore everything in this directory. The second line tells Git not to ignore the .gitignore file. You can stuff this file into every empty folder you want added to the repository.

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 ignonetworking. 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! 😉

enter image description here