Etiquetar / Marcar un grupo de files en Git

¿Hay alguna manera de marcar lógicamente un grupo de files con una label en Git? Entiendo cómo funcionan las tags y las tags de Gitlab pero … en ambos casos, esos marcadores se aplican a las confirmaciones.

Las aplicaciones que utilizamos, ETL, utilizan un tree de directorys específico que no es muy flexible cuando se trata de identificar que 3 files pertenecen a la Solución X y otros 2 files (en el mismo directory) pertenecen a la Solución Y.

Marcar / labelr un subset de files en lugar de colocarlos en carpetas específicas de características o encoding en la convención de nomenclatura … los haría más fáciles de identificar.
Los files, por cierto, son XML (trabajos ETL) o files planos (SQL / DDL).

¿Cómo harías esto?

Como otros han dicho, no hay nada integrado para hacer esto. Sin embargo, podríamos observar que Git almacena cuatro types de objects en el propio repository: blobs (files), trees (que representan directorys-full-of-files), commits (que forman un gráfico acíclico dirigido a través de identificadores padre , con cada commit portando un object de tree , un autor, un committer, su set de padres y un post de logging arbitrario) y objects de label anotada (que no tienen una relación fuertemente definida, pero cada label tiene exactamente un object de destino, normalmente un commit )

Aparte: cómo funcionan las git notes

Las notas de Git se representan internamente como commits. Cada commit tiene, como su tree, un set de "files" cuyos nombres simplemente son, por crash 🙂 … tose, ejem-exactamente el mismo 1 que algunos commits en el repository. Cuando git log va a mostrar un commit cuyo ID es C , "accidentalmente" verifica si existe refs/notes/commits , y si es así, si existe un file llamado C en el commit al cual refs/notes/commits , y si es así, agrega los contenidos de ese file al post de logging. Así que así es como se adjuntan notas a commits: una parte incorporada de Git comtesting si una reference especial ( refs/notes/commits ) apunta a una confirmación que contiene un tree que contiene un "file" (y realmente es un file en el final, ya que es un object ordinario blob Git) que debe agregarse al post de logging de compromiso.

Cuando revisas el set de notas, Git simplemente hace un nuevo commit con un nuevo tree. La nueva confirmación apunta a la confirmación previa de refs/notes/commits como su padre, de modo que las notas más antiguas siguen existiendo y pueden (con cierta dificultad) ser vistas como lo fueron en el pasado (esto solía ser muy difícil; cree que se ha vuelto más fácil). La compression natural de packages de file de Git maneja estas cosas bastante bien, de modo que el espacio ocupado por las notas crece solo linealmente con nuevas adiciones de notas.


1 Para mayor eficiencia, el "nombre" se modifica un poco, por lo que, en lugar de deadbeefcafebabec0ffeedecadefadedbedcede file de notas deadbeefcafebabec0ffeedecadefadedbedcede , por ejemplo, podría llamarse de/ad/beefcafe...


Por lo tanto, la solución es obvia (ejem)

Desea representar un set de files dispuestos en un directory o serie de directorys. Eso es, por supuesto, un tree , y Git tiene objects de tree. Por lo tanto, debe crear un object de tree para contener uno de estos estados.

No dijo si desea mantener múltiples versiones históricas de este tree. Si lo hace, la solución es obvia: git notes como lo hace git notes , usando un nuevo object de commit para almacenar cada nuevo tree, encadenando los commits para hacer que las versiones anteriores sean recuperables. De lo contrario, depende de usted si crear un object de confirmación, ya que un solo object de label podría apuntar directamente al object de tree. (Algunas herramientas que no son de Git pueden tener problemas con las tags en otra cosa que no sea una confirmación u otra label. Sin embargo, hay algunas de estas tags en el repository de Git para Git).

En cualquier caso, también necesitará una reference de nivel superior para apuntar a su object de label commit-o-annotated que apunta al tree más actual.

Crear el tree es fácil: simplemente llene un file de índice, no el habitual, sino un file alternativo, cuyo nombre escriba en la variable de entorno GIT_INDEX_FILE con los nombres de file que desee que aparezcan en su tree, por git add -ing los files (esto también includeá los blobs necesarios en el repository si aún no están allí), luego invoque git write-tree . Esto convertirá el índice en el object de tree deseado (después del cual puede, y probablemente debería, descartar la configuration GIT_INDEX_FILE exportada), imprimiendo el ID del nuevo object a la salida estándar como de costumbre. Escribir un compromiso y / o un object de label para apuntar a este tree es simplemente una cuestión de invocar git commit-tree y / o git mktag (que escribirá sus propios objects nuevos en el repository, imprimiendo los ID a la salida estándar como antes) . Por último, use git update-ref para crear o actualizar una reference que apunte a la label o al object de confirmación, y ahora ha implementado de nuevo las git notes , pero de una forma más adecuada para sus propios deseos.

Puede extraer cualquier tree guardado en cualquier momento, a cualquier tree de trabajo de su elección, con un simple git checkout usando otro índice temporal.

Dado que no es práctico agrupar esos files en un commit cada vez que quiera aplicar una label, al less puede considerar dejarle una nota que le recuerde cuáles son los files que pertenecen a Solution.

Vea las git notes : esa sería una nota de text, administrada por usted, listndo los files que se considerarán para una solución dada.
Para una confirmación determinada, puede adjuntar varias notas.

Esta es una solución, para tener en count el hecho de que Git, en function de confirmaciones, no podría labelr los files.

¿Estás tratando de rastrearlos por separado? Si es así, me pregunto si puedes usar dos repositorys de git locales diferentes para lograr esto. Echa un vistazo a esta respuesta para ver cómo administrar dos repositorys de git diferentes en el mismo directory.

De lo contrario, si solo necesitas una forma de labelr files en tu sistema de files, git no ayudará mucho. ¿Qué tal si .sol1 dos files .sol1 y .sol2 que enumeran los files en la solución respectiva, y luego escribimos un pequeño script para sus operaciones de git. Por ejemplo, cuando haces git status -sol1 , primero hace el git status en todo el directory, luego lo filtra por files en .sol y así sucesivamente. Escribir un guión así no debería ser difícil, y creo que también podría ser útil en otros escenarios. Si necesitas ayuda, házmelo saber.

Git no tiene una forma natural de lograr esto, ya que realmente solo le importan los cambios en los files que se le ordera monitorear.

Una solución a esto, aunque hodgepodge, sería usar tags de compromiso para poder referirse al proyecto en un estado particular. Nuevamente, a Git no le importan los files individuales o incluso si están relacionados; es su responsabilidad crear esa relación.