Inyectar files en un repository git sin hacer un checkout

Estoy trabajando en un marco de localización que gestiona los activos de text para varias aplicaciones (wpf, android, ios) en una biblioteca. Usamos git como el sistema de control de versiones para todas las aplicaciones. Ahora quiero exportar esos activos directamente al repository git.

El problema es: no quiero clonar / extraer todo el repository cada vez que exporto los activos a los repositorys de git. De hecho, no quiero saber acerca de ningún file excepto esos activos. Ya me di count de que no es posible revisar los subdires con git, pero ¿hay alguna manera de "inyectar" o "forzar" esos cambios en el repository sin tener que extraer todos los otros cambios y files? (Nota: los activos solo se modifican aquí y los desarrolladores no los editan directamente). Básicamente, debe ignorar todo lo que sucede fuera de la carpeta de activos. Otra cosa importante es que no debería cambiar el flujo de trabajo de nuestros desarrolladores, por lo que los submodules no son realmente una opción, ya que tendrían que extraer el submodule todo el time.

¿Hay una buena manera de hacer esto con git, excepto? ¡Gracias por adelantado!

En git, un object de commit hace reference a un object de tree . Ese tree de objects luego hace reference a objects blob . Cada blob es (generalmente) un file en su copy de trabajo.

El identificador de confirmación es un hash del object commit, que contiene el hash del object tree, que a su vez contiene el hash de todos los blobs.

Por lo tanto, para realizar una confirmación, debe conocer el estado de todos los blobs en la confirmación . La confirmación es, de hecho, una instantánea de toda la copy de trabajo (técnicamente, el índice). Esto significa que no puede simplemente "ignorar los cambios fuera del directory X", porque si lo hiciera, su confirmación produciría una copy de trabajo sin esos files (si no los incluyó en el tree) o con copys obsoletas ( si echa un vistazo una vez y luego asume que no han cambiado, colocando los hashes obsoletos en el object de tree).

Esta es la razón por la cual no se puede simplemente verificar un subtree en git e ignorar los cambios fuera de él. Esta es también la razón por la que lo que está pidiendo (realizar una confirmación sin tener en count el estado de otros files) es imposible.

Sin embargo, creo que si tuvieras que probar la "manera GIT" de hacer las cosas, clonar una vez, y luego comprometerte muchas veces con ese clon, rápidamente descubrirías que es una manera de hacer las cosas muy baja.

De lo contrario, podría hacer que sus "activos" sean un repository separado (posiblemente un submodule de git, en realidad no requieren un "cambio significativo en el flujo de trabajo de los desarrolladores"). Entonces solo tiene que clonar el repository "assets" para realizar commits allí.

También podría enviar parches al server ya actualizado y hacer las confirmaciones localmente. Esto no involucraría nunca la clonación del repository, ya que, por supuesto, el server debe tener los últimos cambios en otros files (¡es la fuente desde la que extraerías!).

Es posible escribir un script que pueda inyectar blobs sin tener que extraer un tree de trabajo, siempre que el repository esté disponible localmente. Aunque no es trivial. He escrito una secuencia de commands antes, que voy a omitir debido a su longitud y no está a disposition del público, pero básicamente implica realizar los siguientes commands de git en un bucle (reiniciando el bucle si algo falla):

# Find the current head. head="$(GIT_DIR="$repo" git show-ref --heads --hash master)" # Get the current version of the file. GIT_DIR="$repo" git cat-file blob "$head:path/to/file" >"$tmpdir/tempfile" # [Modify the file if necessary.] # Write the blob into the repository. blob="$(GIT_DIR="$repo" git hash-object -w "$tmpdir/tempfile")" # Read the tree into an index file. GIT_INDEX_FILE="$index" GIT_DIR="$repo" git read-tree "$head" # Add the ref of the blob into the index file. GIT_INDEX_FILE="$index" GIT_DIR="$repo" git update-index --add \ --cacheinfo 100644 "$blob" path/to/file # Write the index file into the repo as a tree. tree="$(GIT_INDEX_FILE="$index" GIT_DIR="$repo" git write-tree)" # Write a commit to the repo. commit="$(echo "autocommit" |GIT_DIR="$repo" git comm it-tree "$tree" -p "$head")" # Update the head of the repository to be the new commit. GIT_DIR="$repo" git update-ref refs/heads/master "$commit" "$head" 

Esto no está completo (he omitido algún código de event handling errores que reinicia el ciclo), pero es más que un seudocódigo. Espero que sea suficiente para ser útil. Esto lo convierte en un script más complicado que si simplemente clona el repository, pero es mucho, mucho más rápido. Cuál usar depende de lo que necesita.

Por cierto, si el repository está en NFS, el locking no funciona correctamente, y debe verificar una condición de carrera (su ref podría reiniciarse, forzándole a reiniciar todo el process).