GIT - Guía rápida

# -------------------------------------------------------------------
# - GIT – Guía rápida 
# -------------------------------------------------------------------
 
 
 
 
# -------------------------------------------------------------------
# - Configuración Git antes de usar, después de instalar tu Git :)
# -------------------------------------------------------------------
 
1.- Comprobar si tenemos clave
    $ cd ~/.ssh
2.- Creando clave
    $ ssh-keygen -t rsa -C "wimarbueno@gmail.com"
3.- Crear cuenta en github.com
4.- SHH Public Key (añadir, copiar la clave de .ssh  que se agrega en tu usuario)
5.- comprobar en nuestra PC si esta bien
    $ ssh git@github.com
Luego escribir la clave que se puso al inicio
 
6.- configuracion de Git
    $ git config --global user.name "Wilzon Mariño Bueno"
    $ git config --global user.email "wimarbueno@gmail.com"
    $ git config --global merge.tool kdiff3
    $ git config --global mergetool.kdiff3.cmd '"C:\\Program Files\\KDiff3\\kdiff3" $BASE $LOCAL $REMOTE -o $MERGED'
 
7.- Configurar token de la api de github.com -> Acount admin
    $ git config --global github.user  wimarbueno (indicar el usuario que creamos la cuenta en github.com)
    $ git config --global github.token asdgjo545sdfg45asd5g4as64654sas
 
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
 
 
 
 
# -------------------------------------------------------------------
# - Configurar Git del proyecto (Tu primer proyecto) en el equipo si no lo ha hecho.
# -------------------------------------------------------------------
 
# -------------------------------------------------------------------
# Si estas comenzando desde cero, configura tu directorio local
$ mkdir /path/to/your/project
$ cd /path/to/your/project
$ git init
$ git remote add origin git@bitbucket.org:wilzonmj/wilzonmb.git
 
# Crear tu primer archivo, commit, y push
$ echo "wilzon m" >> contributors.txt
$ git add contributors.txt
$ git commit -m 'Commit inicial con los contribuyentes'
$ git push -u origin master
 
# Ahora ya está todo listo para arriba! Comienza la codificación o crear un equipo e invitar a la gente a trabajar contigo.
 
# -------------------------------------------------------------------
# Si ya tienes un proyecto existente
$ cd /path/to/my/repo
$ git remote add origin git@bitbucket.org:wilzonmj/wilzonmb.git
$ git push -u origin --all # pushes up the repo and its refs for the first time (empuja hacia arriba el repo y sus árbitros por primera vez)
$ git push -u origin --tags # pushes up any tags (empuja hacia arriba las etiquetas)
 
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
 
 
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
==== ------ Comandos basicos mas usados() ------ ====
$ git status                                   # Ver el estatus
$ git add .                                    # Agregar al commit
$ git commit -m "este es mensaje del commit"   # confirmando cambios
$ git pull                                     # Descargando ultimos cambios
$ git push                                     # Enviando cambios
 
$ git checkout -b <nombre_rama>                # Crear rama en el punto actual y hacerle checkout (Crea la rama y se mueve a esa nueva rama). (Esta es la misma operacion para crear rama remota  y local)
$ git checkout <nombre_rama>                   # Movernos a esa rama
$ git push -u origin <nombre_rama>             # Subiendo nuestra rama para que sea rama remota
$ git push origin --delete <nombre_rama>       # Eliminar rama remota
$ git push origin :<nombre_rama>               # Eliminar rama remota
$ git branch -d <nombre_rama>                  # Eliminar rama local. (si aun no esta fusionado muestra un error en ese caso para forzar el borrado hacerlo así: git branch -D nombre_rama)
$ git fetch                                    # Para actualizar ramas del servidor
$ git fetch origin nombre_rama                 # Para recuperar información sólo de una rama (si estas trabajando en esta rama, es como si lo hicieras en rama master)
$ git pull origin nombre_rama_remota           # Recibiendo de la rama remota, en el local se crea esa rama con el mismo nombre
$ git pull origin nom_rama_remota:nuevo_nombre # Recibiendo de la rama remota, con esto lo ponemos otro nombre en nuestro local
$ git push origin nombre_rama_remota           # Enviando a la rama remota
$ git diff nombre_rama nombre_rama_dos         # comparando las dos ramas
$ git add .                                    # Agrega a todos los archivos y directorios
$ git add -u                                   # Si ha sido eliminado algun archivos directamente del directorio, lo elimina y lo pone listo para hacer el commit :)
$ git trash save "anterior_cambio"             # Se envia al trash algun cambio si lo deseas y recuperarlo cuando gutes
$ git trash list                               # Para listar los que estan en trash
$ gitk &                                       # Para ver los cambios realizados en modo grafico (se pone el & para que permita escribir en la consola)
 
- Las ramas remotas son referencias al estado de ramas en tus repositorios remotos. Son ramas locales que no puedes mover; se mueven automáticamente cuando estableces comunicaciones en la red. Las ramas remotas funcionan como marcadores, para recordarte en qué estado se encontraban tus repositorios remotos la última vez que conectaste con ellos.
 
=> Tip
--Si creamos la rama en la web en Bitbucket, podemos obtener la informacion con (git fetch) y luego ir en la rama con(git checkout nombre_rama)
$ git fetch && git checkout nombre_rama        # Con esto sctualizamos y nos movemos a la rama
 
==>Merge
-- Primero nos situamos en la rama hacia donde se va realizar la fusión, en este caso la rama desarrollo se va a fusionar con la rama master, y realizamos la fusión especificando la otra rama
$ git checkout master
$ git merge desarrollo
 
--El proceso de la fusión con merge, se creará un nuevo commit donde se realizará la fusión y el apuntador master se moverá a ese nuevo commit
--Otro  escenario para merge sería a lo que se denomina fast-forward. En este caso, no se crearía un nuevo commit con la fusión, simplemente se adelantaría la posición del apuntador master al commit más reciente. Dependiendo del escenario el merge se ejecutará de una forma u otra.
== /------ Comandos basicos mas usados() ------ ==
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
 
 
-> Notas:
- Cambios locales se refiere a los ficheros del directorio de trabajo (working dir) que hayan sido modificados desde el último commit.
- COMMIT es un indicador cualquiera en el repositorio: SHA1 de un commit, tag, HEAD (ultimo commit de la rama actual), HEAD~1 (antecesor de HEAD)… La mayoría de las veces, si no se indica se asume HEAD (último commit de la rama actual).
 
-> Enlaces:
http://git-scm.org
http://www-cs-students.stanford.edu/~blynn/gitmagic/intl/es/ch02.html
 
 
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------
---- apuntes termporales------
$ git config --global -e                # muestra la configuracion de git
$ git config --global core.editor vim   # Aignacion de editor vim por defecto
 
 
 
------------------------------------------------------------------------------------------
== Inicializar repositorio ==
------------------------------------------------------------------------------------------
$ git init
$ git add .                           # Marca todos los ficheros para el próximo commit.
$ git commit -m "Estado inicial"      # Crea un nuevo commit con los ficheros marcados.
 
------------------------------------------------------------------------------------------
== Crear ramas ==
------------------------------------------------------------------------------------------
Una rama es un puntero a un commit específico en el repositorio.
 
$ git branch <nombre>                 # Crear la rama en el punto actual. Es necesario hacer checkout a la misma.
$ git branch <nombre> <COMMIT>        # Crea la rama a partir del commit dado. Es necesario hacer checkout.
$ git checkout -b <nombre>            # Crear rama en el punto actual y hacerle checkout (Crea la rama y se mueve a esa nueva rama). (Esta es la misma operacion para crear rama remota  y local)
$ git checkout -b <nombre> <COMMIT>   # Crear la rama a partir del commit dado y hacerle checkout.
$ git checkout <nombre>               # Movernos a esa rama
$ git branch -m <actual> <nuevo>      # Renombrar la rama
$ git branch -d <nombre>              # Eliminar rama local. (si aun no esta fusionado muestra un error en ese caso para forzar el borrado hacerlo así: git branch -D nombre_rama)
Al crear una rama nueva y hacerle checkout los cambios locales se trasladan a esa rama, con lo que el siguiente commit será sobre la rama nueva.
 
------------------------------------------------------------------------------------------
== Listar ramas ==
------------------------------------------------------------------------------------------
$ git branch                          # Listar todas las ramas
$ git branch -r                       # Listar ramas remotas
$ git branch -a                       # Listar ramas remotas y locales
$ git branch -v                       # Mostrar último commit en cada rama y su situación respecto a su rama remota (si hay)
$ git branch --merged                 # Mostrar ramas que se han fusionado con la actual, y por tanto pueden borrarse
$ git branch --no-merged              # Mostrar ramas con trabajos sin funsionar. Intentar borrarlas dará un error.
$ git remote -v show                  # Listar los repositorios remotos y sus URLs
 
------------------------------------------------------------------------------------------
== Moverse a una rama o a un commit específico ==
------------------------------------------------------------------------------------------
$ git checkout <COMMIT>            # No toca los cambios locales
$ git checkout -f <COMMIT>         # Sobreescribe los cambios locales
Se puede hacer una rama desde el commit actual para continuar el desarrollo (git branch). Si se hacen cambios en un commit intermedio (no es un HEAD) y se commitean sin hacer una rama, se crea un commit separado que sale del actual (rama sin nombre).
 
------------------------------------------------------------------------------------------
== Fusionar ramas (merge) ==
------------------------------------------------------------------------------------------
-- Primero nos situamos en la rama hacia donde se va realizar la fusión, en este caso la rama desarrollo se va a fusionar con la rama master, y realizamos la fusión especificando la otra rama
$ git checkout <master>
$ git merge <desarrollo>
Las diferencias se resuelven automáticamente si es posible. En caso de conflictos (código o ficheros binarios modificados en ambas ramas) el proceso se detiene (merging) a la espera de una resolución manual.
 
------------------------------------------------------------------------------------------
== Resolver conflictos de fusionado: ==
------------------------------------------------------------------------------------------
Dentro de cada fichero en conflicto se añaden marcas alrededor del código conflictivo, mostrando al mismo tiempo la versión de una y otra rama (excepto en ficheros binarios).
$ git status                       # Muestra la situación actual del merge (Unmerged paths)
$ git diff                         # Muestra los ficheros conflictivos y las diferencias
$ git add <file>                   # Marca el fichero como corregido una vez resuelto el conflicto
$ git rm <file>                    # Marca el fichero como eliminado en la revisión resuelta
 
La sección “Unmerged paths” de git status muestra los ficheros que requieren atención. Debe resolverse cada conflicto manualmente dentro del fichero (eliminando las marcas agregadas por git) y marcarlo como resuelto con git add.
En vez de editar los ficheros es posible escoger una de las dos versiones disponibles (rama actual o rama que se está fusionando):
 
$ git checkout --ours -- <file>    # Obtener la versión del fichero en la rama actual
$ git checkout --theirs -- <file>  # Obtener la versión del fichero en la rama que se está fusionando con la actual
 
-- Para abortar la acción o anularla una vez realizada:
$ git reset                        # Abortar el proceso y volver a la situación anterior al intento de merge (si es que estas en un merge y estas a media osea aun no terminar de unirlo, con este comando lo pones al estado anterior)
$ git reset --hard HEAD            # Abortar el proceso y volver a la situación anterior al intento de merge
$ git reset --hard ORIG_HEAD       # Deshacer si ya se había confirmado con git commit
 
--Una vez resueltos todos los conflictos se confirma el proceso
$ git commit                       # Confirmar la fusión (merge) una vez resueltos todos los conflictos
 
------------------------------------------------------------------------------------------
== Resolución gráfica de conflictos: ==
------------------------------------------------------------------------------------------
$ git mergetool                    # Inicia la herramienta gráfica de resolución de conflictos
 
La herramienta crea ficheros adicionales por cada fichero en conflicto (backup, base, local, remote) para que la herramienta de resolución pueda mostrarlos al usuario al mismo tiempo y éste establecer la versión final. Estos ficheros deberían borrarse automáticamente tras la edición (en caso de que persistan es necesario borrarlos manualmente).
 
La resolución básica sólo sirve para ficheros de texto. En ficheros binarios usar git checkout –ours o git checkout –theirs para escoger una de las dos versiones disponibles.
 
-- Configurar una herramienta gráfica para resolver conflictos:
http://www.davesquared.net/2010/03/easier-way-to-set-up-diff-and-merge.html (Windows)
http://gitguru.com/2009/02/22/integrating-git-with-a-visual-merge-tool (Mac)
 
------------------------------------------------------------------------------------------
== Deshacer cambios ==
------------------------------------------------------------------------------------------
$ git revert <COMMIT>              # La recuperación hace un nuevo commit en la rama actual sin ir "hacia atrás" en la historia
$ git reset --hard                 # Deshace los cambios locales
$ git reset --hard HEAD~1          # Elimina el último commit
$ git reset --hard version_commit_aqui          # Elimina cualquier version de commit (Ejemplo version commit: 5b208371bedcf5395f10a3944fb2ff9fc14fe7c3), para buscar la lista de commit hacemos con "git log". 
 
-- Recuperar una versión determinada de un fichero o path:
$ git reset <COMMIT> -- <path>     # git reset NO sobreescribe cambios locales
$ git reset -p <COMMIT> -- <path>  # Seleccionar interactivamente las partes a restaurar
$ git checkout <COMMIT> -- <path>  # Sobreescribe cambios locales sin preguntar
 
-- En Windows se puede abrir git-bash directamente en cualquier subcarpeta carpeta del proyecto (boton derecho – git bash here). Entonces para recuperar un fichero o path local:
$ git checkout <COMMIT> -- ./<path>
 
------------------------------------------------------------------------------------------
== Conocer el historial de un fichero ==
------------------------------------------------------------------------------------------
$ git log <path>                       # Mostrar todos los commits para un fichero especifico con info detallada
$ git log -n 2 -- <path>               # Mostrar sólo los dos últimos commits para ese fichero
$ git log -oneline -- <path>           # Formato abreviado con id de commit y comentario
 
$ git log <SINCE>..<UNTIL> -- <path>   # Mostrar los commits para ese fichero entre dos commits indicados
 
-- Abrir GITK mostrando gráficamente el historial para un fichero o ruta dado:
$ gitk <path>
 
------------------------------------------------------------------------------------------
== Localizar y restaurar ficheros borrados ==
------------------------------------------------------------------------------------------
$ git log --diff-filter=D --summary      # Mostrar los ficheros borrados en los últimos commits
$ git checkout <COMMIT>^ -- <path>       # Restaurar un fichero borrado en un commit dado
 
El ^ al final del commit es para restaurar el fichero desde el commit anterior al que fue borrado. Equivale a <commit>~1.
 
------------------------------------------------------------------------------------------
== Guardar cambios actuales para recuperarlos después ==
------------------------------------------------------------------------------------------
Guarda los cambios desde el último commit. Al recuperarlos, si hay colisiones se hace un merge.
$ git stash                    # Guarda cambios hechos desde el ultimo commit
$ git stash pop                # Recupera los cambios guardados
$ git stash list               # Lista los estados guardados
$ git stash apply              # Aplica cambios guardados sin borrarlos de la lista
 
------------------------------------------------------------------------------------------
== Marcar el commit actual (Tag) ==
------------------------------------------------------------------------------------------
$ git tag -s <nombre> -m <mensaje>
 
El tag queda firmado usando la firma GPG asociada al autor (ver Creating SSH keys).
El nombre identifica al tag y se usa en los demás comandos (ej. git checkout). Por ejemplo, v2.32.45r1
 
$ git tag                              # Mostrar lista de tags
$ git tag -n                           # Mostrar lista y descripción
 
$ git tag -d <nombre>                  # Eliminar Tag
$ git tag -a <nombre>                  # Crear Tag no firmado
$ git push --tags                      # Subir Tags al repositorio remoto
$ git push origin :refs/tags/<nombre>  # Eliminar Tag borrado localmente
 
------------------------------------------------------------------------------------------
== Localizar ficheros con una cadena de texto ==
------------------------------------------------------------------------------------------
$ git grep <texto>                     # Mira en todos los ficheros del repositorio
$ git grep <texto> -- <ruta>           # Mira sólo en la ruta o rutas especificadas
                                       # Admite patrones (ej. *.cpp)
 
------------------------------------------------------------------------------------------
== Trabajo con repositorios remotos ==
==Obtener el repositorio desde otra localización (fork):
------------------------------------------------------------------------------------------
$ git clone <ruta al repositorio>      # Clonar y hacer checkout del HEAD de la rama actual
$ git clone -n <ruta al repositorio    # Clonar pero no hacer checkout
 
No hay que hacer git init ni crear directorio (se crea automáticamente a partir de la carpeta actual). La ruta puede ser una carpeta local, carpeta en red, URL, o cualquier otra referencia a un repositorio remoto. Si es privado será necesario tener la clave SSH configurada adecuadamente (ejemplo: http://projects.edy.es/trac/edy_vehicle-physics/wiki/GitSetup).
 
------------------------------------------------------------------------------------------
== Recibir los cambios desde el repositorio original: ==
------------------------------------------------------------------------------------------
$ git pull
 
-- Es equivalente a:
$ git fetch                            # Trae los cambios
$ git merge origin                     # Fusionarlos con la versión actual
 
------------------------------------------------------------------------------------------
== Subir cambios al repositorio: ==
------------------------------------------------------------------------------------------
$ git push origin <branch>                # Subir sólo la rama indicada
$ git push --all                          # Subir y actualizar todas las referencias remotas
$ git push -u origin <nombre_rama>        # Subiendo nuestra rama al remoto
$ git fetch origin nombre_rama            # Para recuperar información sólo de una rama (si estas trabajando en esta rama, es como si lo hicieras en rama master)
$ git push origin nombre_rama_remota      # Enviando a la rama remota
 
------------------------------------------------------------------------------------------
== Gestionar Tags en el repositorio: ==
------------------------------------------------------------------------------------------
$ git push --tags                      # Subir Tags (no suben de otra forma)
$ git push origin :refs/tags/<nombre>  # Eliminar Tag borrado localmente
 
------------------------------------------------------------------------------------------
== Borrar una rama remota: ==
------------------------------------------------------------------------------------------
$ git push origin :<branch>
$ git push origin --delete <branch>       # GIT versión 1.7.0+
$ git push origin --delete <nombre_rama>  # Eliminando rama remota
 
------------------------------------------------------------------------------------------
== Cambiar la URL de un repositorio remoto (cambia ambos fetch y push) ==
------------------------------------------------------------------------------------------
$ git remote set-url origin <nueva URL>
 
------------------------------------------------------------------------------------------
== Revertir un commit en local y también en el repositorio remoto: ==
------------------------------------------------------------------------------------------
(lo lógico es que no hubiera sido subido)
$ git reset --hard HEAD~1
$ git push origin +master:master
 
"El +master:master Lo principal es necesario decirle a git que usted realmente desea rebobinar la historia aquí, (definitivamente no es parte del flujo normal)."
Tutotial: http://www.zorched.net/2008/04/14/start-a-new-branch-on-your-remote-git-repository/
Push and delete branches: http://gitready.com/beginner/2009/02/02/push-and-delete-branches.html
 
------------------------------------------------------------------------------------------
== Tareas especiales ==
== Marcar para commit sólo determinadas partes de un fichero ==
------------------------------------------------------------------------------------------
$ git add --patch              # Preguntar individualmente por cada cambio en todos los ficheros modificados
$ git add --patch <file>       # Preguntar individualmente por cada cambio en un fichero determinado
 
-- Se muestra cada cambio en el fichero individualmente y se pregunta qué hacer con él. Respuestas inmediatas:
    y     aceptar este cambio para que entre en el próximo commit.
    n     no marcar este cambio. No entrará en el próximo commit.
    q     no marcar este cambio y salir. Se mantendrán los que ya se hayan marcado pero no los restantes.
    a     marcar este cambio y todos los demás de este fichero.
    d     no marcar este cambio ni ninguno de los restantes de este fichero.
Otras respuestas disponibles permiten saltar entre los cambios (g j k), reducirlos a partes más pequeñas (s), o editarlos manualmente (e). (https://www.kernel.org/pub/software/scm/git/docs/git-add.html)
 
== Añadir un nuevo fichero o patrón a .gitignore ==
Añadirlo a .gitignore sigue controlando aquellos ficheros que ya están en el repositorio, y
 
-- Eliminaría el fichero del directorio de trabajo.
git rm <file>
 
-- Para dejar de controlar el fichero o patrón manteniendo las copias actuales añadirlo a .gitignore y entonces:
$ git rm --cached <file>
$ git rm --cached -r <pattern>        # Eliminar ocurrencias en todo el arbol
 
Borrar el fichero completamente del repositorio implica reescribir toda la historia (https://help.github.com/articles/remove-sensitive-data/). Nada recomendable.
 
------------------------------------------------------------------------------------------
== Localizar el cambio que originó un problema ==
------------------------------------------------------------------------------------------
$ git bisect start
$ git bisect bad                      # La versión actual va mal
$ git bisect good v2.6.13-rc2         # Esta versión es buena
 
Información: http://www-cs-students.stanford.edu/~blynn/gitmagic/ch05.html#_where_did_it_all_go_wrong
Manual para git bisect: https://www.kernel.org/pub/software/scm/git/docs/git-bisect.html
 
------------------------------------------------------------------------------------------
== Trabajar con submódulos (submodules) ==
------------------------------------------------------------------------------------------
Los submódulos son carpetas dentro de un repositorio cuyo contenido es a su vez un repositorio de GIT autogestionado.
 
------------------------------------------------------------------------------------------
== Añadir un submódulo a un repositorio ==
------------------------------------------------------------------------------------------
$ git submodule add <ruta al repositorio> <carpeta>       # Añade el repositorio dado como submódulo
                                                          # en la carpeta indicada del repositorio actual.
 
El submódulo se inicializa en la carpeta indicada y se le hace checkout a la rama Master.
 
Los cambios locales en el repositorio anfitrión se limitan al fichero .gitmodules y a la nueva carpeta, pero no al contenido (untracked content). Desde el punto de vista del repositorio anfitrión, un submódulo sólo consta de una definición en el fichero .gitmodules y de una carpeta. Esta carpeta es especial y hace referencia a un commit determinado en el origen del submódulo.
 
La carpeta con el submódulo es un repositorio GIT independiente. Se pueden usar comandos GIT desde esa carpeta, o git gui / gitk en ella. Los cambios afectarán sólo al contenido de la misma. Es posible crear y usar ramas, sincronizar con el origen, etc.
                                                           
 
-- Notas:
- El repositorio a añadir como submódulo debe tener contenido (no sirve un repositorio recién creado, sin commits).
- Si  agregar el submódulo produce alguno de estos fallos:
    fatal: Not a git repository: <carpeta>/../../.git/<carpeta>
     
The following path is ignored by one of your .gitignore files: <carpeta>
La solución es: (fuente: http://stackoverflow.com/questions/11749515/why-is-git-telling-me-that-a-submodule-i-removed-is-ignored/11764522#11764522)
$ rm -fr <carpeta> .git/modules/<carpeta>
 
------------------------------------------------------------------------------------------
== Actualizar los submódulos ==
------------------------------------------------------------------------------------------
El repositorio anfitrión gestiona la referencia a un commit en el origen del submódulo, pero no gestiona el contenido de ese commit. Esta referencia se puede mover entre ramas, clonar, sincronizar con el origen, etc. Esto significa, por ejemplo, que al clonar un repositorio los submódulos estarán vacíos. El valor de la referencia sólo cambia (aparece en git status) cuando el submódulo se hace apuntar a un commit diferente en el origen. Por ejemplo, como resultado de commits locales en el submódulo, cambios de ramas, o sincronización con el origen.
 
Cuando la referencia cambia por operaciones en el repositorio anfitrión (ej. cambios de rama o checkout a revisiones anteriores),  es necesario recrear el contenido apropiado dentro del submódulo para que coincida con el commit al que apuntaba en la revisión actual del anfitrión.
 
$ git submodule update --init               # Clona los submódulos que falten por clonar y hace checkout del commit referenciado.
                                            # --init asegura que los submódulos estén inicializados (ej. tras un clone).
$ git submodule update --init --recursive   # Si los submódulos contienen otros submódulos, actualizarlos a su vez.
 
El contenido de los submódulos se actualiza y gestiona con las operaciones GIT normales dentro del submódulo.
 
 
------------------------------------------------------------------------------------------
== Mover un submódulo a otra carpeta del repositorio ==
------------------------------------------------------------------------------------------
Asegurarse que el repositorio y los submódulos están actualizados. Entonces seguir las instrucciones (fuente).
 
Ejemplo: mover un submódulo desde “Datos” a “var/Datos”.
 
1.- Editar .gitmodules cambiando name y path a “var/Datos”
2.- Mover la carpeta GIT del submódulo desde “.git/modules/Datos” a “.git/modules/var/Datos”
3.- Mover la carpeta del submódulo desde “Datos” a “var/Datos”
4.- Editar “.git/modules/var/Datos/config” y corregir la linea
[core] worktree
- En este ejemplo cambia de
../../../Datos
 a
../../../../var/Datos
 
5.- Editar “ext/Datos/.git” y corregir
gitdir
- Aquí cambia de
../.git/modules/Datos
 a
../../git/modules/var/Datos
 
6.- git add .gitmodules
7.- git rm --cached Datos
8.- git submodule add -f <url> var/Datos
 
-- En git status aparece
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   .gitmodules
#   renamed:    Datos -> var/Datos
 
En el último paso podría aparecer alguno de los fallos descritos al final del apartado Añadir un submódulo a un repositorio. En ese caso aplicar la misma resolución y repetir el paso 8.
 
------------------------------------------------------------------------------------------
== Hacer un submódulo de una carpeta existente en un repositorio ==
------------------------------------------------------------------------------------------
El nuevo repositorio con el submódulo conservará el historial de los cambios en los ficheros de la carpeta (Fuente 1, Fuente 2).
 
1. Usar git subtree para crear una nueva rama que sólo contendrá a esa carpeta
    $ git subtree split -P <carpeta> -b <nueva-rama>
 
2. Borrar la carpeta en la rama actual del repositorio
    $ git rm -rf <carpeta>
 
3. Recrear la carpeta e inicializar un nuevo repositorio GIT en ella. El repositorio remoto para el submódulo debe estar ya creado.
    $ mkdir <carpeta>
    $ pushd <carpeta>
    $ git init
    $ git remote add origin <ruta-al-repositorio-submodulo>
 
4. Traer (pull) al nuevo repositorio el contenido de <nueva-rama> en el repositorio anfitrión, y subir al repositorio remoto.
    $ git pull ../ <nueva-rama>              # usar ../../ ó ../../../ etc. según la profundidad de <carpeta>
    $ git push origin -u master
    ../ es la carpeta raíz del repositorio anfitrión. Si <carpeta> tiene varios niveles de profundidad será necesario encadenar ../../ ó ../../../ etc hasta llegar a la raíz del anfitrión.
 
5. Añadir <carpeta> como submódulo al repositorio anfitrión
    $ popd
    $ git submodule add <ruta-al-repositorio-submodulo> <carpeta>
    Hacer commit de los cambios para completar el proceso.
 
     
------------------------------------------------------------------------------------------
== Eliminar un submódulo de un repositorio ==
------------------------------------------------------------------------------------------
Debe hacerse manualmente, no hay un comando para ello:
 
1. Eliminar la entrada del submódulo en el fichero .gitmodules. Si sólo hay un submódulo se puede borrar el fichero entero. Ejemplo:
    [submodule "Assets/Common"]
    path = Assets/Common
    url = ssh://git@gitserver.com/user/assets-common.git
 
2. Eliminar la entrada del submódulo en el fichero .git/config. Ejemplo:
    [submodule "Assets/Common"]
    url = ssh://git@gitserver.com/user/assets-common.git
 
3. Borrar del índice la carpeta del submódulo
    $ git rm --cached <carpeta>
 
4. Borrar las carpetas del submódulo en en el repositorio anfitrión
    $ rm -fr <carpeta> .git/modules/<carpeta>
    Hecho. El submódulo queda completamente eliminado del repositorio.

 

Tips vim

Si al unir los archivos, para comentar y salir de la edición de comentarios usar este codigo:

<esc> :wq <enter>