Unity, git y git-media

Unity es la onda y git es la onda también. Como todos saben onda+onda=superonda -> demasiada genialidad para ser estable. Esa es la explicación simple de por qué Unity no se lleva bien con git (le versión aburrida tiene algo que ver con archivos binarios muy grandes). La solución obviamente es usar SVN.

Ja! Nunca! No… claro que no usaremos SVN, vamos a usar git-media que es una super extensión para git que le permite trabajar con esos molestos grandes archivos de Unity como las texturas y binarios. Git-media usa los filtros de git para “engañarlo” al agregar (stage) archivos con cierta extensión. Para ello, calcula un hash del archivo y guarda dicho hash en lugar del contenido del archivo mientras que el contenido real lo manda a uno de sus posibles “transports”. Al clonar un repositorio se pueden reemplazar los contenidos de los archivos con hashes por los originales de forma que git aun los maneja pero no sus contenidos. Genial, no?

Git-media maneja varios transports pero los que me parecen más interesantes son el de S3 de amazon y el que usaré en este tutorial (por su facilidad y porque no tengo un S3): scp.

El objetivo final es poder agregar todos los archivos de nuestro proyecto Unity a git (bitbucket, github o lo que sea) pero que los contenidos de los assets más pesados se almacenen en otro servidor al cual accedemos con ssh.

Requerimientos

  • Unity3d
  • git-bash
  • ruby
  • un servidor ssh y acceso con llaves (puedes usar passwords pero será muy agotador)

Crear el repositorio original

Primero necesitamos un proyecto en Unity, yo por ejemplo usaré el de un jueguito que desarrollo  llamado sala que se ve así:

Assembly-CSharp-Editor-vs.csproj
Assembly-CSharp-Editor.csproj
Assembly-CSharp-firstpass-vs.csproj
Assembly-CSharp-firstpass.csproj
Assembly-CSharp-vs.csproj
Assembly-CSharp.csproj
Assembly-UnityScript-vs.unityproj
Assembly-UnityScript.unityproj
Assets
Library
ProjectSettings
Sala-csharp.sln
Sala.apk
Sala.sln
Sala.userprefs

Luego crearemos un repositorio git y vamos a configurarlo para usar git-media

# crear un repo
git init
# indicarle a git que use los filtros de git-media
git config filter.media.clean "git-media filter-clean"
git config filter.media.smudge "git-media filter-smudge"
# apagar la funcion de crlf porque causa problemas en windows
git config core.autocrlf false
# indicarle a git cuales extensiones queremos usar con git-media, en este caso seran los tga
echo "*.tga filter=media -crlf" > .gitattributes
# decirle a git-media que usaremos scp y configurarlo
git config git-media.transport scp
git config git-media.scpuser "gus"
git config git-media.scphost "bitworks.com.mx"
git config git-media.scppath "git-media"

Obviamente deberás reemplazar los parámetros del user, host y path.

Decidí usar los tga porque según windirstat son los archivos más pesados en mi proyecto, si necesitas más extensiones solo hay que agregarla a la lista en .gitattributes.

Eso sería toda la configuración necesaria localmente. Obviamente como usaremos scp la carpeta remota indicada en scpath debe existir.

Antes de hacer el commit inicial recomiendo crear un archivo gitignore tal como se indica aquí. La razón es que Unity genera muchas cosas que no necesitamos versionar y solo crean ruido en nuestro repositorio. Una vez creado podemos agregar los archivos fuentes:


git add . 

Veremos como git-media imprime una linea por cada archivo tga que agrega. Nos indica que esos archivos serán reempalzados por su hash y su contenido se enviará al servidor indicado en la configuración de scp.

Ahora podemos hacer commit de estos cambios:


git commit -m "carga incial"

Git-media imprimirá una linea por cada archivo media agregado. Esto agrega los archivos stub (los hashes) a nuestro commit pero no hemos cargado los archivos reales al servidor, esto se puede apreciar con el commando git media status que nos indica que los archivos aun no se han sincronizado. Para hacerlo debemos usar:


git media sync

Veremos como git-media sube al servidor cada archivo. Al finalizar podemos proceder con la clonación del repo.

Clonando el repositorio

El proceso de clonar un repositorio con git-media es (a mi parecer) algo más complejo de lo que debería. En fin, todo inicia con un tradicional git clone:

# vamos a otro directorio local
cd ~/otroLugar
git clone ~/repoSala

Esto hará un clone del repoSala en otroLugar/repoSala. Este repositorio tendrá los archivos tga del original pero sus contenidos serán solo los hashes.
Además, no está configurado para git-media pero sí tiene las extensiones de archivo en .gitattributes. Será necesario repetir los pasos de configuración antes mencionados:

git config filter.media.clean "git-media filter-clean"
git config filter.media.smudge "git-media filter-smudge"
git config core.autocrlf false

git config git-media.transport scp
git config git-media.scpuser "gus"
git config git-media.scphost "bitworks.com.mx"
git config git-media.scppath "git-media"

Una vez configurado no hace falta más que el siguiente comando para que git-media descargue los contenidos de los tga y reemplace los hashes con ellos.

git media sync

Una vez hecho esto el repositorio nuevo tendrá los mismos archivos que el original pero git no se preocupará por los grandes y molestos binarios. El workflow será el mismo ya que git creerá que los archivos tga no han cambiado y si lo hiciecen solo habrá que realizar un “git media sync” en todos los repositorios para obtener los cambios.

Si usas el gitignore que recomendé debes recordar que no se clonará el archivo del proyecto. Debes abrir unity con Open Project indicarle la carpeta clonada y Unity creará los archivos faltantes ahí.

Referencias

WinDirStat es un muy útil programa que muestra visualmente el tamaño de los archivos en un directorio. Lo uso para identificar las extensiones problemáticas de archivos grandes en Unity, también puede ayudarte a identificar directorios que es mejor ignorar en git.

Para instalar Ruby en windows lo más fácil es usar RubyInstaller. Este programa argega ruby y gem al path de git-bash automáticamente así que nada de que preocuparse.

Git-media parece haberse mudado ya varias veces. La documentación que usé para este post principalmente proviende de aquí y aquí.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s