ver tag oneline modificados log crear archivos git git-submodules

oneline - git tag



Actualizar el submódulo de Git al último commit en origen (9)

Tengo un proyecto con un submódulo Git. Es de una URL ssh: // ... y está en confirmación A. La confirmación B ha sido enviada a esa URL, y quiero que el submódulo recupere la confirmación y cambie a ella.

Ahora, mi entendimiento es que la git submodule update debería hacer esto, pero no lo hace. No hace nada (sin salida, código de salida exitosa). Aquí hay un ejemplo:

$ mkdir foo $ cd foo $ git init . Initialized empty Git repository in /.../foo/.git/ $ git submodule add ssh://user@host/git/mod mod Cloning into mod... user@host''s password: hunter2 remote: Counting objects: 131, done. remote: Compressing objects: 100% (115/115), done. remote: Total 131 (delta 54), reused 0 (delta 0) Receiving objects: 100% (131/131), 16.16 KiB, done. Resolving deltas: 100% (54/54), done. $ git commit -m "Hello world." [master (root-commit) 565b235] Hello world. 2 files changed, 4 insertions(+), 0 deletions(-) create mode 100644 .gitmodules create mode 160000 mod # At this point, ssh://user@host/git/mod changes; submodule needs to change too. $ git submodule init Submodule ''mod'' (ssh://user@host/git/mod) registered for path ''mod'' $ git submodule update $ git submodule sync Synchronizing submodule url for ''mod'' $ git submodule update $ man git-submodule $ git submodule update --rebase $ git submodule update $ echo $? 0 $ git status # On branch master nothing to commit (working directory clean) $ git submodule update mod $ ...

También he intentado git fetch mod , que parece hacer un fetch (¡pero no puedo, porque no solicita una contraseña!), Pero git log y git show niegan la existencia de nuevas confirmaciones. Hasta el momento, acabo de estar reiniciando el módulo y volviéndolo a agregar, pero en principio esto es incorrecto y tedioso en la práctica.


@Jason es correcto de una manera pero no del todo.

actualizar

Actualice los submódulos registrados, es decir, clone los submódulos que faltan y verifique la confirmación especificada en el índice del repositorio que lo contiene. Esto hará que los submódulos HEAD se separen a menos que se especifique --rebase o --merge o que el submódulo clave. $ Name.update esté establecido en rebase o fusionar.

Por lo tanto, git submodule update realiza el checkout, pero lo que pasa es que está comprometido en el índice del repositorio que lo contiene. Todavía no sabe nada del nuevo compromiso en sentido ascendente. Así que vaya a su submódulo, obtenga la confirmación que desea y confirme el estado de submódulo actualizado en el repositorio principal y luego haga la git submodule update


Aquí hay una impresionante de una sola línea para actualizar todo lo último en master:

git submodule foreach ''git fetch origin --tags; git checkout master; git pull'' && git pull && git submodule update --init --recursive

Gracias a Mark Jaquith


El comando git submodule update realidad le dice a Git que desea que sus submódulos comprueben el compromiso ya especificado en el índice del superproyecto. Si desea actualizar sus submódulos al último compromiso disponible desde su control remoto, deberá hacerlo directamente en los submódulos.

Así que en resumen:

# get the submodule initially git submodule add ssh://bla submodule_dir git submodule init # time passes, submodule upstream is updated # and you now want to update # change to the submodule directory cd submodule_dir # checkout desired branch git checkout master # update git pull # get back to your project root cd .. # now the submodules are in the state you want, so git commit -am "Pulled down update to submodule_dir"

O, si eres una persona ocupada:

git submodule foreach git pull origin master


En mi caso, quería que git actualizara a la última versión y, al mismo tiempo, rellene los archivos faltantes.

Lo siguiente restauró los archivos faltantes (gracias a --force que no parece haber sido mencionado aquí), pero no hizo ningún nuevo comentario:

git submodule update --init --recursive --force

Esto hizo

git submodule update --recursive --remote --merge --force


Git 1.8.2 presenta una nueva opción: --remote que permitirá exactamente este comportamiento. Corriendo

git submodule update --remote --merge

buscará los últimos cambios desde el nivel superior en cada submódulo, los combinará y verificará la última revisión del submódulo. Como dicen los documentos :

--remoto

Esta opción solo es válida para el comando de actualización. En lugar de utilizar el SHA-1 grabado del superproyecto para actualizar el submódulo, use el estado de la rama de seguimiento remoto del submódulo.

Esto es equivalente a ejecutar git pull en cada submódulo, que generalmente es exactamente lo que quieres.


Parece que en esta discusión se mezclan 2 escenarios diferentes:

escenario 1

Usando los punteros de mi repo principal para los submódulos, quiero verificar la confirmación en cada submódulo, a la que apunta el repositorio principal, posiblemente después de la primera iteración de todos los submódulos y la actualización / extracción de estos desde el control remoto.

Esto es, como se señaló, hecho con

git submodule foreach git pull origin BRANCH git submodule update

Escenario 2, que creo que es a lo que apunta OP

Han ocurrido cosas nuevas en 1 o más submódulos, y quiero 1) extraer estos cambios y 2) actualizar el repositorio principal para que apunte a la confirmación HEAD (más reciente) de estos / submódulos.

Esto se haría por

git submodule foreach git pull origin BRANCH git add module_1_name git add module_2_name ...... git add module_n_name git push origin BRANCH

No es muy práctico, ya que tendría que codificar n rutas a todos los n submódulos en, por ejemplo, un script para actualizar los punteros de confirmación del repo principal.

Lo que sería genial sería una iteración automatizada a través de cada submódulo, actualizando el puntero del repositorio principal (usando git add) para apuntar a la cabeza del submódulo (s).

Para esto, hice este pequeño bash-script:

git-update-submodules.sh

#!/bin/bash APP_PATH=$1 shift if [ -z $APP_PATH ]; then echo "Missing 1st argument: should be path to folder of a git repo"; exit 1; fi BRANCH=$1 shift if [ -z $BRANCH ]; then echo "Missing 2nd argument (branch name)"; exit 1; fi echo "Working in: $APP_PATH" cd $APP_PATH git checkout $BRANCH && git pull --ff origin $BRANCH git submodule sync git submodule init git submodule update git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true" for i in $(git submodule foreach --quiet ''echo $path'') do echo "Adding $i to root repo" git add "$i" done git commit -m "Updated $BRANCH branch of deployment repo to point to latest head of submodules" git push origin $BRANCH

Para ejecutarlo, ejecute

git-update-submodules.sh /path/to/base/repo BRANCH_NAME

Elaboración

En primer lugar, asumo que la rama con el nombre $ BRANCH (segundo argumento) existe en todos los repo. Siéntase libre de hacer esto aún más complejo.

Las primeras secciones de la pareja son algunas comprobaciones de que los argumentos están ahí. Luego saco las últimas cosas del repo de los padres (prefiero usar --ff (avance rápido) siempre que estoy haciendo pulls. Tengo rebase off, por cierto).

git checkout $BRANCH && git pull --ff origin $BRANCH

Entonces podría ser necesaria alguna inicialización de submódulos, si se agregaron nuevos submódulos o no se han iniciado aún:

git submodule sync git submodule init git submodule update

Luego actualizo / extraigo todos los submódulos:

git submodule foreach "(git checkout $BRANCH && git pull --ff origin $BRANCH && git push origin $BRANCH) || true"

Observe algunas cosas: en primer lugar, estoy encadenando algunos comandos git usando && , lo que significa que el comando anterior debe ejecutarse sin error.

Después de un posible tirón exitoso (si se encontraron nuevas cosas en el control remoto), hago un empuje para asegurar que no se quede un posible compromiso de fusión en el cliente. Una vez más, solo sucede si un tirón en realidad trajo nuevas cosas.

Finalmente, la final || true || true es asegurar que el script continúe en los errores. Para hacer que esto funcione, todo en la iteración debe estar envuelto en comillas dobles y los comandos git están envueltos en paréntesis (precedencia del operador).

Mi parte favorita:

for i in $(git submodule foreach --quiet ''echo $path'') do echo "Adding $i to root repo" git add "$i" done

Iterar todos los submódulos - con --quiet , lo que elimina la salida ''Ingresando MODULE_PATH''. Usando ''echo $path'' (debe estar entre comillas simples), la ruta al submódulo se escribe en la salida.

Esta lista de rutas de submódulo relativas se captura en una matriz ( $(...) ) - finalmente itere esto y git add $i para actualizar el repositorio principal.

Finalmente, una confirmación con algún mensaje que explica que el repositorio principal se actualizó. Esta confirmación será ignorada por defecto, si no se hizo nada. Empuje esto a su origen, y ya está.

Tengo un script ejecutando esto en un trabajo de Jenkins, que se encadena a un despliegue automatizado programado después, y funciona como un encanto.

Espero que esto sea de ayuda para alguien.


Sencillo y sencillo, para buscar los submódulos:

git submodule update --init --recursive

y ahora continúe actualizándolos a la última rama maestra (por ejemplo):

git submodule foreach git pull origin master


Su proyecto principal apunta a un compromiso particular en el que debería estar el submódulo. Lo que hace la git submodule update es tratar de desproteger ese compromiso en cada submódulo que se ha inicializado. El submódulo es realmente un repositorio independiente: simplemente creando un nuevo compromiso en el submódulo y presionando eso no es suficiente, también debe agregar explícitamente la nueva versión del submódulo en el proyecto principal.

Entonces, en su caso, debe encontrar el compromiso correcto en el submódulo. Supongamos que es la punta del maestro:

cd mod git checkout master git pull origin master

Ahora vuelve al proyecto principal, prepara el submódulo y confirma que:

cd .. git add mod git commit -m "Updating the submodule ''mod'' to the latest version"

Ahora empuje su nueva versión del proyecto principal:

git push origin master

A partir de este momento, si alguien más actualiza su proyecto principal, entonces git submodule update para ellos actualizará el submódulo, asumiendo que se haya inicializado.


en su proyecto, ejecute el directorio padre:

git submodule update --init

o si tienes submódulos recursivos ejecuta:

git submodule update --init --recursive

a veces esto todavía no funciona porque de alguna manera usted tiene cambios locales en el directorio de submódulos locales mientras se actualiza el submódulo.

La mayoría de las veces, el cambio local puede no ser el que desea confirmar. Puede suceder debido a la eliminación de un archivo en su submódulo, etc. Si es así, reinicie su directorio de submódulo local y vuelva a ejecutar el directorio principal del proyecto:

git submodule update --init --recursive