Cómo agregar un repositorio git como módulo independiente
JGit proporciona API que implementan la mayoría de los comandos del submódulo de Git, que les presentaré aquí.
Configuración
Los fragmentos de código utilizados en este artículo se utilizarán como un programa de prueba de aprendizaje. Los programas de prueba simples ayudan a comprender cómo funcionan las bibliotecas de terceros y cómo utilizar nuevas API. Puede considerar estas pruebas como experimentos controlados que le ayudarán a obtener una comprensión más intuitiva del rendimiento de su código de terceros.
Además de esto, también puede ayudarte a comprobar nuevas versiones de código de terceros si continúas escribiendo pruebas. Si su programa de prueba cubre cómo llamar a estas bibliotecas, los cambios incompatibles en el código de terceros aparecerán temprano.
Volviendo al tema anterior, todos los programas de prueba *** comparten la misma configuración; consulte el código fuente para obtener más detalles. Ahora tiene una biblioteca vacía llamada padre y otra biblioteca llamada biblioteca que se agregará como un submódulo a la biblioteca principal del programa de prueba. Hay un método setUp en el programa de prueba, que se utiliza para crear estos dos repositorios, de la siguiente manera:
1
Git git = Git.init().setDirectory( "/ tmp/path/to/repo" ).call();
Estos dos repositorios están representados por variables Git de tipo principal y variables Git de tipo biblioteca, respectivamente. Esta clase encapsula un repositorio y permite el acceso a todos los comandos disponibles de JGit. Como mencioné antes, cada clase Commnad corresponde a un comando local de Git pocelain. Las instrucciones de llamada requieren el uso de un patrón generador. Por ejemplo, el resultado de ejecutar Git.commit() es efectivamente equivalente a un CommitCommand, y puedes llamar a su método call() con los parámetros necesarios para ejecutar el comando.
Agregar submódulo
El primer paso es, por supuesto, agregar un submódulo al repositorio existente. Con el paso de configuración anterior, el repositorio de la biblioteca debe agregarse como un submódulo al directorio de módulos/biblioteca del repositorio principal.
1
2
3
4
5
6 p> p>
7
8
9
10
11
12 p>
13
14
15
16
@Test
prueba pública vacíaAddSubmodule( ) arroja una excepción {
String uri
= biblioteca.getRepository().getDirectory() .setPath( "módulos/biblioteca" );
Repositorio repositorio = addCommand. call();
repository.close();
F?ile workDir = parent.getRepository().getWorkTree();
F? ile readme = new F?ile( workDir, "modules/library/readme.txt" );
F?ile gitmodules = new F?ile( workDir, ".gitmodules" );
assertTrue( readme.isF?ile() );
assertTrue( gitmodules.isF?ile() );
}
El objeto SubmoduleAddCommand necesita saber dos cosas, primero, desde dónde se clonó el submódulo y segundo, dónde debe almacenarse. El atributo URI especifica la dirección del repositorio clonado, que se pasará al comando de clonación. Después de ejecutar este comando, el directorio de trabajo del repositorio principal se verá así:
El repositorio de la biblioteca se almacena en el directorio módulos/biblioteca y su árbol de directorios de trabajo se ha extraído. El método call() devolverá un objeto de repositorio que puede utilizar como repositorio normal. Esto también significa que debe cerrar explícitamente el repositorio devuelto en su programa para evitar fugas de identificadores de archivos.
En la figura anterior podemos ver que SubmoduleAddCommand solo hace una cosa, que es crear un archivo de módulo .git en el directorio de trabajo raíz del repositorio principal y agregarlo al índice.
1
2
3
[Submódulo "módulos/biblioteca"]
ruta = módulos / biblioteca
url = git@example.com:ruta/a/lib.git
Si ha abierto el archivo de configuración de Git, notará la sintaxis anterior. Este archivo enumera todos los submódulos del repositorio actual. El archivo enumera la URL del repositorio y la ruta local para cada módulo. Una vez que confirme y envíe el archivo, la parte que clona el repositorio sabrá dónde obtener el submódulo correspondiente (más sobre esto más adelante).
Lista de submódulos
Cuando agregamos un submódulo, es posible que queramos saber si el repositorio principal conoce el submódulo. En la primera prueba, realizamos una prueba básica para verificar que existieran ciertos archivos y directorios.
También podemos usar la API para listar los submódulos del repositorio, de la siguiente manera:
1
2
3
4
5
6
7
8
9
10
11
@ Test
public void testListSubmodules() lanza una excepción {
addLibrarySubmodule();
Asignar submódulos
= parent.suboduleStatus().call();
assertEquals( 1, submodules.size() );
Estado de SubmoduleStatus = submodules.get( " módulos/biblioteca" );
assertEquals( INITIALIZED, status.getType() );
}
El comando SubmoduleStatus devuelve el estado de una colección de mapas de submódulo, donde clave es la ruta del submódulo y valor es el valor de estado del módulo. A través del código anterior, podemos verificar si el submódulo ha sido agregado y si su estado es inicializado (INITIALIZADO). El comando también permite agregar una o más rutas para limitar el estado de los submódulos.
Hablando de estado, StatusCommand de JGit no es un comando nativo de Git. Si agrega la opción --ignore-submodules=dirty al ejecutar el comando, se ignorarán todos los cambios en el directorio de trabajo de los submódulos.
Actualización de submódulos
Los submódulos suelen apuntar a una confirmación específica en el repositorio en el que se encuentran. Si alguien clona el repositorio principal, obtendrá exactamente el mismo estado de submódulo que el repositorio principal, incluso si hay nuevas confirmaciones en sentido ascendente del submódulo.
Para modificar un submódulo, es necesario actualizarlo explícitamente así:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test
público void testUpdateSubmodule() lanza una excepción {
addLibrarySubmodule();
ObjectId newHead = biblioteca.commit().setMessage( "msg" ).call()
<; p>Archivo workDir = parent.getRepository().getWorkTree();Git libModule = Git.open( new F?ile( workDir, "módulos/biblioteca" );
libModule.pull().call();
libModule.close();
parent.add().addF?
parent.commit().setMessage( "Actualizar submódulo").call();
assertEquals(newHead, getSubmoduleHead( "módulos/biblioteca")
}
En este fragmento de código más largo, lo primero que debe hacer es enviar contenido al repositorio de la biblioteca (línea 4) y luego actualizar el submódulo al último contenido confirmado
Para conservar esta actualización, el submódulo debe estar confirmado (líneas 10, 11). La confirmación guarda el ID de confirmación actualizado bajo el nombre del submódulo (módulos/biblioteca en el ejemplo /p>
Finalmente). , a menudo es necesario enviar cambios a otros repositorios
Actualizar cambios en los submódulos en el repositorio principal
Extraer confirmaciones ascendentes al repositorio principal. Sin embargo, la configuración del submódulo también se modifica. el submódulo en sí no se actualiza automáticamente.
SubmoduleUpdateCommand se puede utilizar para resolver este problema y actualizará todos los submódulos registrados sin especificar parámetros adicionales. Este comando clona el submódulo que falta y verifica las confirmaciones especificadas en su configuración. Al igual que otros comandos de submódulos, existe un método addPath() para garantizar que solo se actualicen los submódulos en una ruta determinada.
Clonar un repositorio que contiene submódulos
En este punto, es posible que haya aprendido la regla de que todas las operaciones en los submódulos son manuales. Al clonar un repositorio que contiene una configuración de submódulo, sus submódulos no se clonan de forma predeterminada. Sin embargo, el comando CloneCommand tiene un atributo cloneSubmodules que, si se establece en "verdadero", clonará todos los submódulos configurados. Internamente, después de clonar el repositorio principal, los comandos SubmoduleInitCommand y SubmoduleUpdateCommand se ejecutan de forma recursiva y se extrae el directorio de trabajo del repositorio principal.
Eliminar un submódulo
Para eliminar un submódulo, escribe:
1
git.submoduleRm(). .).call();
Pero desafortunadamente, ni Git nativo ni JGit proporcionan instrucciones integradas para eliminar submódulos. Espero que dichas instrucciones se puedan agregar en el futuro. Aquí Anteriormente, teníamos que hacerlo manualmente. ver y eliminar submódulos. Si te desplazas hacia abajo hasta el método removeSubmodule(), verás que esto no es algo complicado.
Primero, elimine los submódulos individuales de los archivos de configuración .gitsubmodules y .git/config. En segundo lugar, elimine la entrada del submódulo del índice. Finalmente, confirme las modificaciones en el archivo e índice .gitsubmodules y elimine el contenido del submódulo del directorio de trabajo.
Submódulos transversales
Native Git proporciona el submódulo git para cada comando, que se utiliza para ejecutar comandos de shell para cada submódulo. El siguiente programa de ejemplo extrae las confirmaciones ascendentes de todos los submódulos.
1
2
3
4
5
6 p>
6
p>
7
8
9
10
11
12
13
14
15 afirmarEquals(1, submoduleCount);
} p>
El objeto Walk puede pasar el método next() Apunta al siguiente submódulo. Si no hay más submódulos, el método devolverá falso. Al utilizar SubmoduleWalk, puede liberar los recursos asociados con el submódulo llamando al método release(). Del mismo modo, si obtiene una instancia de repositorio de un submódulo, no olvide cerrarla.
SubmoduleWalk también se puede utilizar para obtener los detalles de un submódulo. La mayoría de sus métodos getter le permiten acceder a las propiedades del submódulo actual, como ruta, encabezado, URL remota, etc.
Sincronizar URL remota
De lo anterior podemos saber que la configuración de los submódulos se almacena en el archivo .gitsubmodules en el directorio de trabajo raíz del repositorio principal. Al menos, en el archivo .git/config podemos anular la URL remota del submódulo. El comando SubmoduleSyncCommand se puede utilizar para restablecer todas las URL remotas a la configuración en .gitmodules.
En resumen, el soporte de JGit para submódulos es casi idéntico al de Git nativo. La mayoría de los comandos de Git se implementan en JGit o se pueden emular de alguna manera. Si descubre que falta algo o no está implementado, puede pedir ayuda a la amigable y servicial comunidad JGit.