Ignorar la carpeta .git en la subcarpeta

6 minutos de lectura

avatar de usuario
Znarkus

¿Es posible agregar una subcarpeta con una carpeta .git a un repositorio, sin que Git lo trate como un submódulo? Probé diferentes métodos para ignorar esa carpeta .git, pero hasta ahora nada ha funcionado.

Lo he intentado en /.gitignore:

/vendor/**/.git/

..y en /proveedor/.gitignore:

.git/

La carpeta .git que quiero ignorar está en /vendor/foo/bar/.

  • .git/ es ignorado automáticamente por git

    – Vinay Prajápati

    09/03/2018 a las 21:45


  • ¿Puedes aclarar lo que quieres? ¿Está seguro de que su cliente de Git GUI no está tratando erróneamente una subcarpeta con un .git directorio como un submódulo? ¿Qué cliente de Git estás usando?

    – Gregorio Pakosz

    10 de marzo de 2018 a las 17:56


  • Doce búsquedas en Google más tarde, Vinay Prajapati proporciona la respuesta que busco en los comentarios.

    – Matt Lemon

    6 de noviembre de 2021 a las 10:35

Puede hacer esto agregando directamente algún (cualquier) contenido interno primero. Git detecta submódulos al encontrar el .git entrada al buscar en un directorio recién encontrado, pero si le da una ruta real para buscar dentro de ese directorio, no busca.

Asi que

git add path/to/some/submodule/file     # bypass initial search that detects .git
git add path/to/some/submodule          # now git's index has it as ordinary dir

avatar de usuario
Janes Botis

Puedes usar ganchos de git para lograr lo que quieres. Pensando fuera de la caja, podría crear un pre cometido gancho que renombra el .git directorio de su proyecto incluido, por ejemplo. a “.git2”, agregue todos los archivos en el último proyecto excepto el directorio “.git2”, confirme todo, empújelo y finalmente use gancho posterior a la confirmación para cambiar el nombre de la carpeta “.git2” a “.git” en su módulo.

1) Crear pre cometido archivar bajo .git/ganchos/ de tu raíz repositorio con contenido:

#!/bin/sh
mv "vendor/foo/bar/.git" "vendor/foo/bar/.git2"

git rm --cached vendor/foo/bar
git add vendor/foo/bar/*
git reset vendor/foo/bar/.git2

2) Crear post-compromiso archivar bajo .git/ganchos/ también con contenidos:

#!/bin/sh
mv "vendor/foo/bar/.git2" "vendor/foo/bar/.git"

3) Cambie un archivo en su repositorio y finalmente:

git commit -a -m "Commit msg"
git push

Mi respuesta original

  • Gracias por esto. Inspiró una solución basada en husky.

    – Xunnamius

    25 de febrero a las 18:58

Tu pregunta me intrigó, así que lo probé:

$ cd /tmp
$ git init foo
Initialized empty Git repository in /private/tmp/foo/.git/
$ cd foo
$ git init bar
Initialized empty Git repository in /private/tmp/foo/bar/.git/
$ cd bar
$ echo "this is bar" > bar.txt
$ git add bar.txt
$ git commit -m "initial commit"
[master (root-commit) c9d6507] initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 bar.txt
$ cd ..
$ pwd
/tmp/foo
$ git status
On branch master

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        bar/

nothing added to commit but untracked files present (use "git add" to track)
$ git add bar
$ git commit -m "parent initial commit"
[master (root-commit) b23e106] parent initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 bar/bar.txt
$ echo "baz" > bar/.git/baz.txt
$ git status
On branch master
nothing to commit, working tree clean

Según tu pregunta, /tmp/foo es un repositorio Git. Y con respecto a /tmp/foo, /tmp/foo/bar es un subdirectorio que a su vez tiene un .git directorio.

Como puede ver, el padre foo repositorio ignoró por completo el bar/.git subdirectorio y ni siquiera necesitaba un .gitignore expediente.

Y no hay forma de que Git trate una ruta que contenga un .git carpeta como un submódulo sin tenerlo registrado en el .gitmodules expediente.

  • Podría haberlo hecho un comentario, pero no podría haber elaborado los pasos exactos que usé para llegar a mi conclusión. Así que aquí está como una respuesta.

    – Gregorio Pakosz

    9 de marzo de 2018 a las 21:47

  • Su transcripción no coincide con mis expectativas ni con los documentos de git, y no puedo reproducirla yo mismo. ¿En qué versión de Git estás ejecutando esto? He probado 2.16 y 2.12 y 2.10 hasta ahora.

    – jthill

    10 de marzo de 2018 a las 22:03

  • git version 2.16.2 en Mac OS

    – Gregorio Pakosz

    11 de marzo de 2018 a las 8:35

  • Puedo reproducirlo con 2.16.2 en linux

    – Gregorio Pakosz

    11 de marzo de 2018 a las 9:20

Si bien es cierto .git se ignora automáticamente, el repositorio principal tratará /vendor/foo/bar como un gitlink (entrada especial en el índice principal del repositorio) y no como archivos normales.

Un truco sería simplemente para Muevete bar/.git fuera de el repositorio principal:

  • vendor/foo/bar se trataría como una subcarpeta regular, que se agregaría al repositorio principal si fuera necesario.
  • el repositorio de barras puede en cualquier momento detectar cambios y hacer commit si precedió a su git comando con GIT_DIR=/path/to/bar/.git git ...

Por ejemplo:

cd /path/to/main/repo/vendor/foo/bar
GIT_DIR=/path/to/bar/.git git status
GIT_DIR=/path/to/bar/.git git add .
GIT_DIR=/path/to/bar/.git git commit -m "changes to bar"
GIT_DIR=/path/to/bar/.git git push

avatar de usuario
Luna sincera _Max_

Como en jthill answer, puede agregar cualquier elemento del subdirectorio con .git y se tratará como un subdirectorio en lugar de un submódulo.

Pero si ya registró este subdirectorio como submódulo que tiene .git primero debe eliminar ese submódulo pero dejarlo en su árbol de trabajo: git rm --cached a/submodule.

Más información sobre: ¿Cómo elimino un submódulo?

Luego puede repetir los pasos de jthill answer.

De mi investigación no hay manera de dejar de tratar .git carpeta como submódulo. Así que la mejor solución que se me ocurre ahora mismo es tener bash o cualquier script similar que pueda ejecutar en cualquier carpeta de la consola. Debería encontrar cualquier subcarpeta que tenga .git e intente agregar cualquier archivo de esa carpeta a la principal .gitpor lo que dejaría de tratarlos como submódulos.

Fuente del código a continuación: Bash script para convertir automáticamente submódulos de git en archivos normales

#!/bin/bash

# Get a list of all the submodules
submodules=($(git config --file .gitmodules --get-regexp path | awk '{ print $2 }'))

# Loop over submodules and convert to regular files
for submodule in "${submodules[@]}"
do  
   echo "Removing $submodule"
   git rm --cached $submodule # Delete references to submodule HEAD
   rm -rf $submodule/.git* # Remove submodule .git references to prevent confusion from main repo
   git add $submodule # Add the left over files from the submodule to the main repo
   git commit -m "Converting submodule $submodule to regular files" # Commit the new regular files!
done

# Finally remove the submodule mapping
git rm.gitmodules

Recuerde siempre confirmar/hacer una copia de seguridad de los cambios antes de probar nuevos scripts para evitar cualquier pérdida de trabajo/datos.

avatar de usuario
Klaatu de Schlacker

Puede usar las exclusiones de Git para esto.

Primero, cree un archivo .gitexclude:

$ echo "vendor/*/.git" >> .gitexclude

Luego agregue este archivo a su configuración de Git como fuente de exclusiones:

$ git config core.excludesFile .gitexclude

Ahora puede agregar archivos y Git no ofrece agregarlos como submódulos:

$ git add vendor
$

Puede verificar que un archivo es realmente “invisible” para Git con git check-ignore:

$ git check-ignore vendor/foo/.git
vendor/foo/.git
$ git check-ignore vendor/foo/bar.txt
$

Referencia: man git-add(1) man git-check-ignore(1)

avatar de usuario
Oculto

¿Has probado los comodines?

**/vendor/.git/

¿Ha sido útil esta solución?