¿Cómo elimino un submódulo Git?
Por cierto, ¿hay alguna razón que no pueda simplemente hacer
git submodule rm whatever
?
fuente
¿Cómo elimino un submódulo Git?
Por cierto, ¿hay alguna razón que no pueda simplemente hacer
git submodule rm whatever
?
Desde git1.8.3 (22 de abril de 2013) :
No había forma de porcelana de decir "Ya no estoy interesado en este submódulo", una vez que expresas tu interés en un submódulo con "
submodule init
".
"submodule deinit
" es la forma de hacerlo.
El proceso de eliminación también utiliza git rm
(desde git1.8.5 de octubre de 2013).
El proceso de eliminación de 3 pasos sería:
0. mv a/submodule a/submodule_tmp
1. git submodule deinit -f -- a/submodule
2. rm -rf .git/modules/a/submodule
3. git rm -f a/submodule
# Note: a/submodule (no trailing slash)
# or, if you want to leave it in your working tree and have done step 0
3. git rm --cached a/submodule
3bis mv a/submodule_tmp a/submodule
rm -rf
: Esto se menciona en la respuesta de Daniel Schroeder y Eonil lo resume en los comentarios :
Esto deja
.git/modules/<path-to-submodule>/
sin cambios.
Entonces, si una vez elimina un submódulo con este método y lo vuelve a agregar, no será posible porque el repositorio ya está dañado.
git rm
: Ver commit 95c16418 :
Actualmente, el uso de "
git rm
" en un submódulo elimina el árbol de trabajo del submódulo del superproyecto y el gitlink del índice.
Pero la sección del submódulo.gitmodules
se deja intacta, lo que es un remanente del submódulo ahora eliminado y puede irritar a los usuarios (a diferencia de la configuración.git/config
, esto debe permanecer como un recordatorio de que el usuario mostró interés en este submódulo, por lo que se repoblará más tarde cuando una confirmación más antigua está desprotegida).Deje que "
git rm
" ayude al usuario no solo eliminando el submódulo del árbol de trabajo, sino también eliminando lasubmodule.<submodule name>
sección " " del.gitmodules
archivo y organice ambos.
git submodule deinit
: Se deriva de este parche :
Con "
git submodule init
" el usuario puede decirle a git que se preocupa por uno o más submódulos y quiere que se complete en la próxima llamada a "git submodule update
".
Pero actualmente no hay una manera fácil de decirle a git que ya no se preocupan por un submódulo y quieren deshacerse del árbol de trabajo local (a menos que el usuario sepa mucho sobre las partes internas del submódulo y elimine lasubmodule.$name.url
configuración " ".git/config
junto con el trabajo árbol mismo).Ayude a esos usuarios proporcionando un
deinit
comando ' '.
Esto elimina lasubmodule.<name>
sección completa de.git/config
cualquiera de los submódulos dados (o de todos los que se han inicializado si.
se da ' ').
Falla si el árbol de trabajo actual contiene modificaciones a menos que sea forzado.
Quejarse cuando para un submódulo dado en la línea de comando no se puede encontrar la configuración de URL.git/config
, pero no falla.
Esto tiene cuidado si los pasos de (de) inicialización ( .git/config
y.git/modules/xxx
)
Desde git1.8.5, la git rm
tomas también se preocupan de la:
add
' paso que registra la url de un submódulo en el.gitmodules
archivo: es necesario eliminarlo por usted.git rm --cached path_to_submodule
(sin barra diagonal) Si olvida el último paso e intenta agregar lo que era un submódulo como directorio normal, recibirá un mensaje de error como:
git add mysubmodule/file.txt
Path 'mysubmodule/file.txt' is in submodule 'mysubmodule'
Nota: desde Git 2.17 (Q2 2018), git submodule deinit ya no es un script de shell.
Es una llamada a una función C.
Ver commit 2e61273 , commit 1342476 (14 de enero de 2018) por Prathamesh Chavan ( pratham-pc
) .
(Fusionada por Junio C Hamano - gitster
- en commit ead8dbe , 13 feb 2018)
git ${wt_prefix:+-C "$wt_prefix"} submodule--helper deinit \
${GIT_QUIET:+--quiet} \
${prefix:+--prefix "$prefix"} \
${force:+--force} \
${deinit_all:+--all} "$@"
submodule deinit
?
.gitmodules
debería estar bien, pero aún así verificaría dos veces cualquier cosa con el .git
directorio (es decir, la configuración local , dentro de su repositorio local: eso no es modificado por a git pull
)
.gitmodules
entrada y la eliminación de la entrada especial en el índice, y empuja ese repositorio, otros pueden extraerlo y ese submódulo desaparecerá.
git rm submodule
hace exactamente lo que quieres como ya han dicho otras personas.
A través de la página Git Submodule Tutorial :
Para eliminar un submódulo, debe:
.gitmodules
archivo..gitmodules
cambios:git add .gitmodules
.git/config
.git rm --cached path_to_submodule
(sin barra inclinada)..git
directorio del submódulo :rm -rf .git/modules/path_to_submodule
git commit -m "Removed submodule <name>"
rm -rf path_to_submodule
Ver también : pasos alternativos a continuación .
git submodule rm
simplemente elimina el registro de submódulos, y se sorprendería si el comando también eliminara el repositorio local. Cualquier cambio local se perdería irremediablemente. Y tal vez otra persona pensaría que solo se eliminarían los archivos.
Solo una nota. Desde git 1.8.5.2, dos comandos harán:
git rm the_submodule
rm -rf .git/modules/the_submodule
Como señaló correctamente la respuesta de @Mark Cheverton, si la segunda línea no se usa, incluso si eliminó el submódulo por ahora, la carpeta remanente .git / modules / the_submodule evitará que el mismo submódulo se vuelva a agregar o reemplazar en el futuro . Además, como mencionó @VonC,git rm
hará la mayor parte del trabajo en un submódulo.
--Actualización (07/05/2017) -
Solo para aclarar, the_submodule
es la ruta relativa del submódulo dentro del proyecto. Por ejemplo, es subdir/my_submodule
si el submódulo está dentro de un subdirectorio subdir
.
Como se señaló correctamente en los comentarios y otras respuestas , los dos comandos (aunque funcionalmente suficientes para eliminar un submódulo), dejan un rastro en la [submodule "the_submodule"]
sección .git/config
(a partir de julio de 2017), que se puede eliminar con un tercer comando:
git config -f .git/config --remove-section submodule.the_submodule 2> /dev/null
.git/config
. Consulte stackoverflow.com/a/36593218/1562138 para ver la forma completa de eliminar un submódulo.
git init && git submodule add <repository> && git rm <name>
deja atrás la .git/config
entrada y el .git/modules/<name>
directorio y sus contenidos. ¿Quizás no inicializó el submódulo antes de eliminarlo?
La mayoría de las respuestas a esta pregunta son obsoletas, incompletas o innecesariamente complejas.
Un submódulo clonado usando git 1.7.8 o posterior dejará como máximo cuatro rastros de sí mismo en su repositorio local. El proceso para eliminar esos cuatro rastros viene dado por los tres comandos a continuación:
# Remove the submodule entry from .git/config
git submodule deinit -f path/to/submodule
# Remove the submodule directory from the superproject's .git/modules directory
rm -rf .git/modules/path/to/submodule
# Remove the entry in .gitmodules and remove the submodule directory located at path/to/submodule
git rm -f path/to/submodule
Pasos simples
git config -f .git/config --remove-section submodule.$submodulename
git config -f .gitmodules --remove-section submodule.$submodulename
git rm --cached $submodulepath
rm -rf $submodulepath
rm -rf .git/modules/$submodulename
Tenga en cuenta: $submodulepath
no contiene barras inclinadas iniciales o finales.
Antecedentes
Cuando lo hace git submodule add
, solo lo agrega .gitmodules
, pero una vez que lo hizo git submodule init
, lo agregó .git/config
.
Entonces, si desea eliminar los módulos, pero poder restaurarlo rápidamente, haga lo siguiente:
git rm --cached $submodulepath
git config -f .git/config --remove-section submodule.$submodulepath
Es una buena idea hacer git rebase HEAD
primero y git commit
al final, si pones esto en un script.
También eche un vistazo a una respuesta a ¿Puedo despoblar un submódulo Git? .
for dir in directory/*; do git rm --cached $dir; done
.
git config -f .git/config -l | cut -d'=' -f1 | grep "submodule.$MODPATH" | sed 's/^submodule\.//' | sed 's/\.url$//'
- - parece que realmente tiene que hacer esto en caso de que haya algo desordenado, de lo contrario, sologit submodule | grep -v '^+' | cut -d' ' -f3
git submodule | grep '^+' | cut -d' ' -f2
submodulename
entre comillas dobles "submodulename"
.. refiriéndose al .git/config
archivo
Además de las recomendaciones, también tuve que rm -Rf .git/modules/path/to/submodule
poder agregar un nuevo submódulo con el mismo nombre (en mi caso, estaba reemplazando un tenedor con el original)
Para eliminar un submódulo agregado usando:
git submodule add blah@blah.com:repos/blah.git lib/blah
Correr:
git rm lib/blah
Eso es.
Para versiones antiguas de git (alrededor de ~ 1.8.5) use:
git submodule deinit lib/blah
git rm lib/blah
git config -f .gitmodules --remove-section submodule.lib/blah
git rm
Todavía deja cosas adentro .git/modules/
. (2.5.4)
git rm
, no lo hace; Una prueba rápida con 2.5.4 en mi mac actualiza el archivo .gitmodules, como se describe en la documentación aquí: git-scm.com/docs/git-rm#_submodules ... pero si ha encontrado algún tipo de combinación de plataforma / versión donde esto no sucede, probablemente deberías presentar un error al respecto.
git rm
deja cosas en .git/modules/
dir y .git/config
file (ubuntu, git 2.7.4). Otra respuesta funciona al 100%: stackoverflow.com/a/36593218/4973698
Debe eliminar la entrada en .gitmodules
y .git/config
, y eliminar el directorio del módulo del historial:
git rm --cached path/to/submodule
Si escribes en la lista de correo de git, probablemente alguien hará un script de shell por ti.
Puede usar un alias para automatizar las soluciones proporcionadas por otros:
[alias]
rms = "!f(){ git rm --cached \"$1\";rm -r \"$1\";git config -f .gitmodules --remove-section \"submodule.$1\";git config -f .git/config --remove-section \"submodule.$1\";git add .gitmodules; }; f"
Pon eso en tu configuración de git, y luego puedes hacer: git rms path/to/submodule
git clone https://github.com/hilbix/empty.git; cd empty; git submodule add https://github.com/hilbix/empty.git one; git mv one two; git rms two
. SEGUNDO: debe ejecutar esto desde la ruta correcta. git
los alias deberían funcionar en cualquier parte del árbol de trabajo (o fallar con gracia). TERCERO: git config -f .git/config
falla dentro de los submódulos, ya que .git
generalmente hay un archivo allí.
Para resumir, esto es lo que debe hacer:
Establecer path_to_submodule
var (sin barra inclinada):
path_to_submodule=path/to/submodule
Elimine la línea relevante del archivo .gitmodules:
git config -f .gitmodules --remove-section submodule.$path_to_submodule
Eliminar la sección relevante de .git / config
git config -f .git/config --remove-section submodule.$path_to_submodule
Desensamblar y eliminar $ path_to_submodule solo del índice (para evitar perder información)
git rm --cached $path_to_submodule
Rastree los cambios realizados en .gitmodules
git add .gitmodules
Cometer el superproyecto
git commit -m "Remove submodule submodule_name"
Eliminar los archivos de submódulos ahora sin seguimiento
rm -rf $path_to_submodule
rm -rf .git/modules/$path_to_submodule
git submodule update
. Y si las rutas de los submódulos no se actualizaron correctamente (git arroja un error), elimínelas:rm -rf .git/modules/<submodule> && rm -rf <submodule> && git submodule update
Si el submódulo se agregó accidentalmente porque agregó, confirmó y empujó una carpeta que ya era un repositorio Git (contenido .git
), no tendrá un .gitmodules
archivo para editar ni nada .git/config
. En este caso todo lo que necesitas es:
git rm --cached subfolder
git add subfolder
git commit -m "Enter message here"
git push
FWIW , también eliminé la .git
carpeta antes de hacer el git add
.
Encontré deinit
trabajos buenos para mí:
git submodule deinit <submodule-name>
git rm <submodule-name>
De git docs :
deinit
Anule el registro de los submódulos dados, es decir, elimine toda la
submodule.$name
sección de .git / config junto con su árbol de trabajo.
git
s , que saben de deinit
, como la otra respuesta quita el .git/modules/submodule
directorio demasiado pronto, lo que parece hacer más reciente git
s fallar ahora o después. Además (vea mi comentario allí), la eliminación .git/modules/submodule
podría ser la ruta incorrecta, por lo que este es un paso peligroso, que se tomará más adelante solo cuando se git
queje (o si está 299% seguro de que lo que quiere es la ruta correcta y realmente necesaria).
git commit
confirmar cambios por etapas en el directorio de trabajo: modified .gitmodules
y deleted <submodule-path>
.
Después de experimentar con todas las diferentes respuestas en este sitio, terminé con esta solución:
#!/bin/sh
path="$1"
if [ ! -f "$path/.git" ]; then
echo "$path is no valid git submodule"
exit 1
fi
git submodule deinit -f $path &&
git rm --cached $path &&
rm -rf .git/modules/$path &&
rm -rf $path &&
git reset HEAD .gitmodules &&
git config -f .gitmodules --remove-section submodule.$path
Esto restaura exactamente el mismo estado que antes de agregar el submódulo. Puede agregar de inmediato el submódulo nuevamente, lo que no fue posible con la mayoría de las respuestas aquí.
git submodule add $giturl test
aboveScript test
Esto te deja con un pago limpio sin cambios para confirmar.
Esto fue probado con:
$ git --version
git version 1.9.3 (Apple Git-50)
git rm --cached $path
entonces en rm -rf $path
lugar de git rm -r $path
?
git submodule add https://github.com/hilbix/empty.git 'dangerous .. submodule'
-> cuando intentas eliminar 'submódulo peligroso ...' con tu script, rm -rf ..
lo más probable es que no sea lo que quieres ...
Lo que estoy haciendo actualmente en diciembre de 2012 (combina la mayoría de estas respuestas):
oldPath="vendor/example"
git config -f .git/config --remove-section "submodule.${oldPath}"
git config -f .gitmodules --remove-section "submodule.${oldPath}"
git rm --cached "${oldPath}"
rm -rf "${oldPath}" ## remove src (optional)
rm -rf ".git/modules/${oldPath}" ## cleanup gitdir (optional housekeeping)
git add .gitmodules
git commit -m "Removed ${oldPath}"
Aquí esta lo que hice :
1.) Eliminar la sección relevante del archivo .gitmodules. Puede usar el siguiente comando:
git config -f .gitmodules --remove-section "submodule.submodule_name"
2.) Etapa los .gitmodules
cambios
git add .gitmodules
3.) Eliminar la sección relevante de .git/config
. Puede usar el siguiente comando:
git submodule deinit -f "submodule_name"
4.) Elimine el gitlink (sin barra inclinada):
git rm --cached path_to_submodule
5.) Limpieza de .git/modules
:
rm -rf .git/modules/path_to_submodule
6.) Comprometerse:
git commit -m "Removed submodule <name>"
7.) Eliminar los archivos de submódulos ahora sin seguimiento
rm -rf path_to_submodule
fatal: no submodule mapping found in .gitmodules for path 'submodule_name'
en el paso 3. Sin embargo, ambos pasos fueron necesarios. (git v2.8.2)
Recientemente descubrí un proyecto git que incluye muchos comandos útiles relacionados con git: https://github.com/visionmedia/git-extras
Instálalo y escribe:
git-delete-submodule submodule
Entonces las cosas están hechas. El directorio de submódulos se eliminará de su repositorio y seguirá existiendo en su sistema de archivos. A continuación, puede confirmar el cambio como: git commit -am "Remove the submodule"
.
git delete-submodule
, ya que git-extras
debe estar en el camino al trabajo. También tenga en cuenta que recomiendo no usargit-extras
, ya que muchas partes son extremadamente defectuosas y peligrosas . Es git-delete-submodule
posible que IE elimine la ruta incorrecta a continuación .git/modules/*
, ya que supone que el módulo y la ruta son idénticos (que a menudo no es el caso), y no funciona correctamente si intenta eliminar un submódulo dentro de un submódulo. git-extras
puede ser útil al 99%, pero no se queje si las cosas salen mal al usarlo. ¡USTED HA SIDO ADVERTIDO!
Tuve que seguir los pasos de John Douthat un paso más allá y cd
en el directorio del submódulo, y luego eliminar el repositorio de Git:
cd submodule
rm -fr .git
Entonces podría confirmar los archivos como parte del repositorio principal de Git sin la referencia anterior a un submódulo.
git rm --cache
paso.
Estos son los 4 pasos que encontré necesarios o útiles (los importantes primero):
git rm -f the_submodule
rm -rf .git/modules/the_submodule
git config -f .git/config --remove-section submodule.the_submodule
git commit -m "..."
En teoría , git rm
en el paso 1 debería ocuparse de ello. Con suerte, la segunda parte de la pregunta de OP se puede responder positivamente un día (que se puede hacer en un comando).
Pero a partir de julio de 2017, paso 2 es necesario para eliminar datos, .git/modules/
de lo contrario, por ejemplo, no puede agregar el submódulo en el futuro.
Probablemente pueda salirse con los dos pasos anteriores para git 1.8.5+ como señaló la respuesta de tinlyx , ya que todos los git submodule
comandos parecen funcionar.
El paso 3 elimina la sección para the_submodule
en el archivo .git/config
. Esto debe hacerse para completar. (La entrada puede causar problemas para versiones anteriores de git, pero no tengo una para probar).
Para esto, la mayoría de las respuestas sugieren usar git submodule deinit
. Me resulta más explícito y menos confuso de usar git config -f .git/config --remove-section
. De acuerdo con la documentación de git-submodule , git deinit
:
Anular el registro de los submódulos dados ... Si realmente desea eliminar un submódulo del repositorio y confirmar que use git-rm [1] en su lugar .
Por último, pero no menos importante, si no lo hace git commit
, recibirá / puede recibir un error al hacerlo git submodule summary
(a partir de git 2.7):
fatal: Not a git repository: 'the_submodule/.git'
* the_submodule 73f0d1d...0000000:
Esto es independientemente de si realiza los pasos 2 o 3.
project dir: ~/foo_project/
submodule: ~/foo_project/lib/asubmodule
- - - - - - - - - - - - - - - - - - - - - - - - -
run:
1. cd ~/foo_project
2. git rm lib/asubmodule &&
rm .git/modules/lib/asubmodule &&
git submodule lib/asubmodule deinit --recursive --force
Acabo de encontrar el archivo oculto .submodule (olvidé el nombre exacto), tiene una lista ... puedes borrarlos individualmente de esa manera. Acabo de tener uno, así que lo eliminé. Simple, pero podría estropear a Git, ya que no sé si hay algo adjunto al submódulo. Parece correcto hasta ahora, aparte del problema de actualización habitual de libetpan, pero eso (con suerte) no está relacionado.
Noté que nadie publicó borrado manual, así que agregó
.gitmodules
Con git 2.17 y superior es solo:
git submodule deinit -f {module_name}
git add {module_name}
git commit
git 2.17.1
ni git 2.20.1
. Sin embargo, en git rm
lugar de git add
trabajar para ambos. Notas: -f
no es necesario si las cosas están limpias. Asegúrese de no usar nunca opciones con git
si desea protegerse contra la pérdida involuntaria de datos. También tenga en cuenta que esto deja .git/modules/{module_name}
en su lugar. Es una buena práctica mantenerlo allí porque git
imprime la ayuda correcta (!) Sobre cómo proceder si algo está bloqueado debido a esto.
Si acaba de agregar el submódulo y, por ejemplo, simplemente agregó el submódulo incorrecto o lo agregó al lugar incorrecto, simplemente git stash
elimine la carpeta. Esto supone que agregar el submódulo es lo único que hizo en el repositorio reciente.
Para el beneficio del lector, esto aquí trata de resumirlo y brindar una guía paso a paso sobre cómo hacerlo si las cosas no funcionan como se esperaba. A continuación se muestra la forma probada y segura para la git
versión 2.17
y superior para deshacerse de un submódulo :
submodule="path/to/sub" # no trailing slash!
git submodule deinit -- "$submodule"
git rm -- "$submodule"
2.20.1
y Ubuntu 18.04 2.17.1
."$submodule"
es solo para enfatizar dónde poner el nombre, y que hay que tener cuidado con los espacios y similares"$submodule"
con la forma de Windows de una ruta de acceso especificada correctamente al submódulo. (No soy Windows)¡Advertencia!
¡Nunca toque el interior del
.git
directorio usted mismo! La edición en el interior.git
entra en el lado oscuro. Manténgase alejado a toda costa!Y sí, puedes culpar
git
por esto, ya que muchas cosas útiles faltabangit
en el pasado. Como una forma adecuada de eliminar submódulos nuevamente.Creo que hay una parte muy peligrosa en la documentación de
git submodule
. Recomienda eliminarse$GIT_DIR/modules/<name>/
. En mi opinión, esto no solo es incorrecto, ¡es extremadamente peligroso y provoca grandes dolores de cabeza en el futuro! Vea abajo.
Tenga en cuenta que
git module deinit
es el inverso directo de
git module init
pero
git submodule deinit -- module
git rm -- module
También es todo lo contrario a
git submodule add -- URL module
git submodule update --init --recursive -- module
porque algunos comandos básicamente necesitan hacer más que una sola cosa:
git submodule deinit -- module
.git/config
git rm
.gitmodules
git submodule add
.git/modules/NAME/
git submodule init
, así que actualizaciones.git/config
git submodule update
, por lo tanto, extrae el módulo de forma no recursiva.gitmodules
git submodule update --init --recursive -- module
Esto no puede ser completamente simétrico, ya que mantenerlo estrictamente simétrico no tiene mucho sentido. Simplemente no hay necesidad de más de dos comandos. También "extraer los datos" está implícito, porque lo necesita, pero no se elimina la información almacenada en caché, porque esto no es necesario en absoluto y podría borrar datos valiosos.
Esto realmente es desconcertante para los recién llegados, pero básicamente es algo bueno: git
simplemente hace lo obvio y lo hace bien, y ni siquiera trata de hacer más. git
es una herramienta que debe hacer un trabajo confiable, en lugar de ser simplemente otra "Eierlegende Wollmilchsau" ("Eierlegende Wollmilchsau" se traduce para mí como "una versión malvada de una navaja suiza").
Entonces entiendo las quejas de la gente, diciendo "¿Por qué no hace git
lo obvio por mí?". Esto se debe a que "obvio" aquí depende del punto de vista. La fiabilidad en todas y cada una de las situaciones es mucho más importante. Por lo tanto, lo que es obvio para usted a menudo no es lo correcto en todas las situaciones técnicas posibles. Recuerde que: AFAICS git
sigue el camino técnico, no el social. (De ahí el nombre inteligente: git)
Los comandos anteriores pueden fallar debido a lo siguiente:
git
es demasiado viejo. Luego usa uno nuevogit
. (Vea a continuación cómo hacerlo).git clean
sentido. Luego, primero limpie su submódulo usando ese comando. (Vea abajo.)git
. Entonces estás en el lado oscuro y las cosas se ponen feas y complicadas. (Quizás usar otra máquina lo arregle).git
usuario avanzado).Posibles soluciones siguen.
git
Si su máquina es demasiado vieja, no hay submodule deinit
en su git
. Si no desea (o no puede) actualizar su git
, ¡simplemente use otra máquina con una más nueva git
! git
está destinado a estar completamente distribuido, por lo que puede usar otro git
para hacer el trabajo:
workhorse:~/path/to/worktree$ git status --porcelain
no debe dar salida a nada! Si es así, ¡primero limpia las cosas!workhorse:~/path/to/worktree$ ssh account@othermachine
othermachine:~$ git clone --recursive me@workhorse path/to/worktree/.git TMPWORK && cd TMPWORK
othermachine:~/TMPWORK$ git commit . -m . && exit
workhorse:~/path/to/worktree$ git fetch account@othermachine:TMPWORK/.git
workhorse:~/path/to/worktree$ git merge --ff-only FETCH_HEAD
. Si esto no funciona, usegit reset --soft FETCH_HEAD
git status
esté limpio nuevamente. Puede hacerlo, porque lo ha tenido limpio antes, gracias al primer paso.Esto othermachine
puede ser alguna VM, o algún Ubuntu WSL bajo Windows, lo que sea. Incluso un chroot
(pero supongo que usted no es root, porque si lo root
fuera, debería ser más fácil actualizar a la más reciente git
).
Tenga en cuenta que si no puede ssh
entrar, existen muchas formas de transportar git
repositorios. Puede copiar su árbol de trabajo en una memoria USB (incluido el .git
directorio) y clonar desde la memoria. Clone la copia, solo para que las cosas vuelvan a estar limpias. Esto podría ser un PITA, en caso de que sus submódulos no sean accesibles directamente desde otra máquina. Pero también hay una solución para esto:
git config --add url.NEWURLPREFIX.insteadOf ORIGINALURLPREFIX
Puede usar esta multiplicación, y esto se guarda en $HOME/.gitconfig
. Algo como
git config --add 'url./mnt/usb/repo/.insteadof' https://github.com/
reescribe URL como
https://github.com/XXX/YYY.git
dentro
/mnt/usb/repo/XXX/YYY.git
Es fácil si comienza a acostumbrarse a git
funciones potentes como esta.
La limpieza manual es buena, porque de esta manera quizás detecte algunas cosas que olvidó.
git status
y git clean -ixfd
es tu amigorm
y deinit
siempre que pueda. Las opciones (como -f
) para git
son buenas si eres un profesional. Pero como vino aquí, probablemente no tenga tanta experiencia en el submodule
área. Así que más vale prevenir que curar.Ejemplo:
$ git status --porcelain
M two
$ git submodule deinit two
error: the following file has local modifications:
two
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'two' contains local modifications; use '-f' to discard them
$ cd two
$ git submodule deinit --all
error: the following file has local modifications:
md5chk
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'md5chk' contains local modifications; use '-f' to discard them
$ cd md5chk
$ git submodule deinit --all
error: the following file has local modifications:
tino
(use --cached to keep the file, or -f to force removal)
fatal: Submodule work tree 'tino' contains local modifications; use '-f' to discard them
$ cd tino
$ git status --porcelain
?? NEW
$ git clean -i -f -d
Would remove the following item:
NEW
*** Commands ***
1: clean 2: filter by pattern 3: select by numbers 4: ask each
5: quit 6: help
What now> 1
Removing NEW
$ cd ../../..
$ git status --porcelain
$ git submodule deinit two
Cleared directory 'two'
Submodule 'someunusedname' (https://github.com/hilbix/src.git) unregistered for path 'two'
Ya ves, no hay -f
necesidad de submodule deinit
. Si las cosas están limpias, en cierto git clean
sentido. También tenga en cuenta que git clean -x
no es necesario. Esto significa que git submodule deinit
elimina incondicionalmente los archivos no rastreados que se ignoran. Esto suele ser lo que quieres, pero no lo olvides. A veces, los archivos ignorados pueden ser valiosos, como los datos almacenados en caché que tardan horas o días en calcularse nuevamente.
$GIT_DIR/modules/<name>/
?Probablemente las personas quieran eliminar el repositorio en caché, porque tienen miedo de tener un problema más tarde. Esto es cierto, pero encontrarse con ese "problema" es la forma correcta de resolverlo. Debido a que la solución es fácil y si se hace bien, podrá vivir feliz para siempre. Esto evita problemas más engorrosos que cuando elimina los datos usted mismo.
Ejemplo:
mkdir tmptest &&
cd tmptest &&
git init &&
git submodule add https://github.com/hilbix/empty.git two &&
git commit -m . &&
git submodule deinit two &&
git rm two &&
git commit -m . &&
git submodule add https://github.com/hilbix/src.git two
La última línea muestra el siguiente error:
A git directory for 'two' is found locally with remote(s):
origin https://github.com/hilbix/empty.git
If you want to reuse this local git directory instead of cloning again from
https://github.com/hilbix/src.git
use the '--force' option. If the local git directory is not the correct repo
or you are unsure what this means choose another name with the '--name' option.
¿Por qué este error? Porque .git/modules/two/
anteriormente se rellenó desde https://github.com/hilbix/empty.git y ahora se volverá a llenar de otra cosa, a saber, https://github.com/hilbix/src.git . No verá esto si lo vuelve a llenar desde https://github.com/hilbix/empty.git
¿Qué hacer ahora? Bueno, ¡haz exactamente lo que te dijeron! Utilizar--name someunusedname
git submodule add --name someunusedname https://github.com/hilbix/src.git two
.gitmodules
entonces parece
[submodule "someunusedname"]
path = two
url = https://github.com/hilbix/src.git
ls -1p .git/modules/
da
someunusedname/
two/
De esta manera, en el futuro, puede cambiar ramas / commit hacia adelante y hacia atrás y nunca volverá a tener problemas , debido a que two/
tiene dos repositorios ascendentes diferentes (y posiblemente incompatibles). Y lo mejor es: también mantiene ambos en caché localmente.
git
).Sin embargo, si eliminó el directorio almacenado en caché, ambos pagos diferentes se toparán entre sí, porque no utilizará las --name
opciones, ¿verdad? Entonces, cada vez que realice el pago, tal vez tenga que eliminar el .git/modules/<module>/
directorio una y otra vez. Esto es extremadamente engorroso y hace que sea difícil usar algo así git bisect
.
Por lo tanto, hay una razón muy técnica para mantener este directorio de módulos como marcador de posición. Las personas que recomiendan eliminar algo a continuación .git/modules/
no lo saben mejor o se olvidan de decirle que esto hace que las funciones potentes sean git bisect
casi imposibles de usar si cruza esa incompatibilidad de submódulos.
Otra razón se muestra arriba. Mira el ls
. Que ves alli
Bueno, la segunda variante del módulo two/
no está debajo .git/modules/two/
, ¡está debajo .git/modules/someunusedname/
! ¡Así que cosas como git rm $module; rm -f .git/module/$module
están totalmente mal! ¡Debes consultar module/.git
o .gitmodules
encontrar lo correcto para eliminar!
Entonces, no solo la mayoría de las otras respuestas caen en esta peligrosa trampa, incluso las git
extensiones muy populares tenían este error ( ahora está solucionado )! ¡Así que mejor mantenga sus manos en el .git/
directorio si no lo hace exactamente, lo que está haciendo!
Y desde el punto de vista filosófico, ¡borrar la historia siempre está mal! Excepto por la mecánica cuántica , como de costumbre, pero esto es algo completamente diferente.
Para tu información, probablemente lo hayas adivinado: hilbix es mi cuenta de GitHub.
Para resumir, esto es lo que debe hacer:
Establezca path_to_submodule var (sin barra inclinada):
path_to_submodule=path/to/submodule
Elimine la línea relevante del archivo .gitmodules:
git config -f .gitmodules --remove-section submodule.$path_to_submodule
Eliminar la sección relevante de .git / config
git config -f .git/config --remove-section submodule.$path_to_submodule
Desensamblar y eliminar $ path_to_submodule solo del índice (para evitar perder información)
git rm --cached $path_to_submodule
Rastree los cambios realizados en .gitmodules
git add .gitmodules
Cometer el superproyecto
git commit -m "Remove submodule submodule_name"
Eliminar los archivos de submódulos ahora sin seguimiento
rm -rf $path_to_submodule
rm -rf .git/modules/$path_to_submodule
Ver también: líneas de guía alternativas
git rm --cached $path_to_submodule
y git add .gitmodules
no? Obtuve un error en el primer comando: fatal: Please stage your changes to .gitmodules or stash them to proceed
porque tenía cambios no organizados en .gitmodules
. Hacer lo git add .gitmodules
primero resuelve eso.
Eso es fácil:
.gitmodules
git add .gitmodules
git submodule deinit <path to submodule>
git rm <path to submodule>
Tendrá que eliminar los archivos del módulo en su proyecto manualmente.
git submodule deinit <submodule_name>
y git rm <path_to_submodule>
. El último comando elimina automáticamente la entrada dentro de .gitmodules
. Git 2.17
He creado un script bash para facilitar el proceso de eliminación. También verifica si hay cambios en el repositorio sin guardar y solicita confirmación. Ha sido probado en os x
sería interesante saber si funciona igual que en las distribuciones de Linux comunes:
https://gist.github.com/fabifrank/cdc7e67fd194333760b060835ac0172f
En el último git solo se necesita 4 operaciones para eliminar el submódulo git.
.gitmodules
git add .gitmodules
git rm --cached <path_to_submodule>
git commit -m "Removed submodule xxx"
En caso de que necesite hacerlo en un comando de línea con el script bash como se muestra a continuación:
$ cd /path/to/your/repo && /bin/bash $HOME/remove_submodule.sh /path/to/the/submodule
Cree un archivo de script bash en el $HOME
directorio llamado ie remove_submodule.sh
:
#!/bin/bash
git config -f .gitmodules --remove-section submodule.$1
git config -f .git/config --remove-section submodule.$1
git rm --cached $1
git add .gitmodules
git commit -m "Remove submodule in $1"
rm -rf $1
rm -rf .git/modules/$1
git push origin $(git rev-parse --abbrev-ref HEAD) --force --quiet
git rm <submodule path> && git commit
. Esto se puede deshacer usando git revert
.
.gitmodules
archivo.$GIT_DIR/modules/<name>/
.Fuente: git help submodules
Para eliminar un git
submódulo debajo de 4 pasos son necesarios.
.gitmodules
archivo. La entrada puede ser como se menciona a continuación[submodule "path_to_submodule"]
path = path_to_submodule
url = url_path_to_submodule
git add .gitmodules
git rm --cached <path_to_submodule>
.git commit -m "Removed submodule xxx"
y empuja.Se necesitan 2 pasos adicionales adicionales que se mencionan a continuación para limpiar completamente el submódulo en una copia clonada local.
.git/config
archivo. La entrada puede ser como se menciona a continuación[submodule "path_to_submodule"]
url = url_path_to_submodule
rm -rf .git/modules/path_to_submodule
Estos pasos quinto y sexto no crean ningún cambio que deba comprometerse.
git submodule deinit
git-scm.com/docs/git-submodule#Documentation/…
git rm modulename
yrm -rf .git/modules/modulename
.git/config
. La respuesta aceptada muestra la forma actualizada de eliminar completamente un submódulo. También se explica más sucintamente en esta respuesta: stackoverflow.com/a/36593218/1562138