Unirse a un proyecto en Bitbucket

En este post explicaremos de manera breve cómo unirse a un grupo de trabajo de Bitbucket:

1.- Crear cuenta en Bitbucket.

2.- Facilitar la dirección de correo electrónico al administrador del grupo.

3.- Llegará una invitación por email o un aviso de que ahora pertenecéis al grupo.

4.- Conectarse a nuestra cuenta y aceptar la invitación (de ser necesario) dentro del propio Bitbucket.

Haciendo simplemente esto ya podréis entrar en un grupo de Bitbucket. Podéis ver los grupos a los que pertenecéis en la pestaña Teams.

grupos

Si en el grupo existen repositorios, podréis acceder a ellos. También podréis crear otros nuevos si disponéis de permisos de administrador (estos permisos dependerán del administrador que os haya invitado).

Git Flow

En este post se explicará el flujo de trabajo Git Flow que aplicaremos cuando usemos Git al trabajar en los proyectos con Unity. Este modelo de desarrollo que se mostrará a continuación no es más que un conjunto de procedimientos que todo miembro del equipo debe seguir en el proceso de desarrollo de un proyecto.

Empezaremos por establecer un sistema de reposiciones en el que consideraremos un repositorio central al que nos referiremos como origin. Cada desarrollador realiza operaciones de push y pull hacia origin. De igual forma puede realizar push y pull hacia otros miembros dentro de su subequipo. De este modo los miembros de ese subequipo pueden trabajar juntos sobre algo concreto antes de subirlo prematuramente a origin. Básicamente los miembros de ese subequipo se definen como Git remotos entre sí. En la siguiente imagen se describen tres subequipos (bob-alice, alice-david, david-clair) conectados entre sí además de con origin.

origin

El repositorio central tendrá dos ramas principales con tiempo de vida infinito:main-branches

  • master
  • develop

En la rama origin/master HEAD siempre estará en la última versión estable de nuestro código fuente. Por otra parte, en la rama origin/develop tendrá una versión de desarrollo con los últimos cambios de la próxima versión estable. Cuando el código fuente de develop alcanza un punto estable, estos cambios serán añadidos al código fuente en master y etiquetados con un número de versión. Se creará por lo tanto una nueva última versión en la rama master.

Junto con las ramas principales master y develop, se usarán ramas de apoyo para ayudar al desarrollo paralelo entre los miembros de equipo, facilitar el seguimiento de características, prepararse para nuevos lanzamientos y ayudar a solucionar rápidamente problemas de producción en vivo. Estas ramas de apoyo tendrán un tiempo de vida limitado y serán eliminadas llegado el momento.

Los diferentes tipos de ramas de apoyo que podríamos usar son:

feature_branch

  • Ramas de característica

Puede ramificarse o unirse a develop. Pueden tener cualquier nombre salvo master, develop, release-* o hotfix-*. Son usadas para el desarrollo de nuevas características de versiones futuras. A la hora de desarrollar una nueva característica podría no saberse la versión objetivo a la que será incorporada. Esta rama existirá mientras dure su desarrollo; hasta que se una a develop o sea descartada. Este tipo de ramas suele existir sólo en develop y no en origin.

Cuando empecemos a trabajar en una nueva característica se ramificará desde la rama develop.

git checkout -b myfeature develop
Cambiado a una nueva rama "myfeature"

Las características finalizadas podrán ser unidas a develop de manera definitiva añadiéndolas así a la próxima versión.

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff myfeature
Updating ea1b82a..05e9557
(Summary of changes)
$ git branch -d myfeature
Deleted branch myfeature (was 05e9557)
$ git push origin develop

La orden --no-ff causa que la unión siempre cree un nuevo objeto commit. Esto evita perder información de la existencia histórica de una rama de característica y agrupa todos los commits que juntos añaden una nueva característica. En la siguiente imagen podéis verlo de una manera gráfica:

feature_branch noff

En el segundo caso es imposible comprobar qué objetos commit forman la nueva característica. Revertir dicha característica en este caso sería muy difícil, mientra que usando --no-ff es muy sencillo.

  • Ramas de lanzamiento

Se ramifican desde develop y se unen a develop y master. Su nombre de rama será release-*. Este tipo de rama ayudará a la preparación de un nuevo lanzamiento. Permiten correcciones de bugs menores y preparación del meta-data para el lanzamiento (número de versión, fechas de elaboración, etc.). Haciendo este trabajo en la rama de lanzamiento, develop estará libre para recibir las nuevas características del próximo gran lanzamiento.

El momento clave para crear una rama de lanzamiento es cuando develop muestra interés en realizar un nuevo lanzamiento próximamente. Esto es cuando las características objetivo para ese lanzamiento están ya unidas a develop. En el instante que se crea una rama de lanzamiento se le asignará un número de versión al próximo lanzamiento. Hasta ese momento develop reflejaba los cambios para el «siguiente lanzamiento». Se seguiran las reglas del proyecto para la asignación del número de versión.

La rama de lanzamiento será creada desde la rama develop. Por ejemplo, tenemos la versión 1.1.5 actualmente y tenemos un gran lanzamiento próximo. El estado de develop es listo para «el siguiente lanzamiento» y decidimos será 1.2 (en vez de 1.1.6 o 2.0):

$ git checkout -b release-1.2 develop
Switched to a new branch "release-1.2"
$ ./bump-version.sh 1.2
Files modified successfully, version bumped to 1.2.
$ git commit -a -m "Bumped version number to 1.2"
[release-1.2 74d9424] Bumped version number to 1.2
1 files changed, 1 insertions(+), 1 deletions(-)

Después de crear una nueva rama y cambiar a ella, asignamos el número de versión. «bump-version.sh» es un script ficticio que cambia algunos archivos en la copia de trabajo para reflejar la nueva versión. Después esta versión es creada. La rama se mantendrá hasta que la nueva versión esté desplegada definitivamente. Durante ese tiempo, las correcciones de bugs pueden ser aplicadas en esta rama. No se podrán añadir nuevas características grandes, serán incluidas en develop o en el próximo gran lanzamiento.

Cunado el estado de la rama de lanzamiento está listo para un lanzamiento real, algunas acciones serán llevadas a cabo. Primero, la rama de lanzamiento se unirá a master (ya que todos los commit en master son por definición lanzamientos nuevos). A continuación, el commit en master debe ser etiquetado para futuras referencias de las versiones en el historial. Finalmente, los cambios realizados en la rama de lanzamiento deben ser añadidos de vuelta a develop, así los futuros lanzamientos también contendrán estas correcciones de bugs.

Los dos primeros pasos en Git:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2

El lanzamiento está ahora hecho y etiquetado para futuras referencias.

Para mantener los cambios realizados en la rama de lanzamiento, necesitamos añadirlos de vuelta en develop. En Git:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff release-1.2
Merge made by recursive.
(Summary of changes)

Este paso podría dar lugar a conflictos de unión.

Ahora la rama de lanzamiento puede ser eliminada, pues no la necesitamos más:

$ git branch -d release-1.2
Deleted branch release-1.2 (was ff452fe).

  • Ramas de revisiónhotfix-branches

Se ramifican desde master y se unen a develop y master. Su nombre de rama será hotfix-*. Se parecen a las ramas de lanzamiento puesto que también son para nuevos lanzamientos, aunque no planeados. Surgen de la necesidad de actuar inmediatamente debido a un estado indeseado en la versión actual. Cuando un bug crítico de la versión debe resolverse inmediatamente, una rama de revisión surgirá desde la etiqueta correspondiente en la rama master que marca la versión en cuestión. La idea es que el trabajo de los miembros del equipo pueda continuar, mientras otra persona prepara una corrección rápida.

La rama de revisión será creada desde la rama master. Por ejemplo, digamos que la versión 1.2 es el lanzamiento actual y causa problemas debido a un bug grave. Pero los cambios en develop son todavía inestables. Podríamos entonces crear una rama de revisión y empezar a solucionar el problema:

$ git checkout -b hotfix-1.2.1 master
Switched to a new branch "hotfix-1.2.1"
$ ./bump-version.sh 1.2.1
Files modified successfully, version bumped to 1.2.1.
$ git commit -a -m "Bumped version number to 1.2.1"
[hotfix-1.2.1 41e61bb] Bumped version number to 1.2.1
1 files changed, 1 insertions(+), 1 deletions(-)

No os olvidéis de actualizar el número de versión después de crear la rama.

Luego corregid el bug y cread el commit o commits necesarios para la corrección.

$ git commit -m "Fixed severe production problem"
[hotfix-1.2.1 abbe5d6] Fixed severe production problem
5 files changed, 32 insertions(+), 17 deletions(-)

Al acabar, la corrección debe unirse de vuelta a master, pero también a develop para asegurarse de que es incluida en el siguiente lanzamiento también. Es similar a como una rama de lanzamiento es finalizada.

Primero, se actualiza master y la etiqueta de lanzamiento:

$ git checkout master
Switched to branch 'master'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)
$ git tag -a 1.2.1

Lo siguiente será incluir la corrección en develop también:

$ git checkout develop
Switched to branch 'develop'
$ git merge --no-ff hotfix-1.2.1
Merge made by recursive.
(Summary of changes)

La única excepción a la regla es que, cuando existe una rama de lanzamiento, los cambios de la revisión deben ser añadidos a la rama de lanzamiento en lugar de a develop. La rama de lanzamiento acabará uniéndose a develop, por lo que la corrección también será añadida. Sin embargo, si la corrección es muy urgente también puede añadirse a develop además de a la rama de lanzamiento.

Finalmente eliminamos la rama:

$ git branch -d hotfix-1.2.1
Deleted branch hotfix-1.2.1 (was abbe5d6).

Aunque no hay nada nuevo realmente impactante en este modelo de ramificación, la imagen global indica que el post con el que empezamos ha resultado ser tremendamente útil en nuestros proyectos. Forma un modelo elegante que es fácil de comprender y permite a los miembros del equipo desarrollar un entendimiento compartido de la ramificación y los procesos de lanzamiento.

Usando Git con Unity

En este post aprenderemos a usar Git con Unity para mantener un control de versiones de nuestros proyectos.

Debemos decidir cuál será nuestro flujo de trabajo, el cómo trabajaremos. Esto será especialmente importante si están varias personas trabajando en un mismo proyecto. Un buen flujo de trabajo sería el denominado Git Flow.

Tendremos también que elegir una Git GUI (interfaz gráfica de usuario) en caso de que deseemos utilizar alguna. Una opción altamente recomendada sería SourceTree. Podéis descargarla desde aquí y tenéis también un tutorial de uso. A mayores una vez instaléis la aplicación tendréis una pequeña guía paso a paso dentro del propio programa que se os mostrará la primera vez que lo ejecutéis.

Además habrá que crear un archivo .gitignore en nuestro directorio del proyecto de Unity que definirá los archivos y directorios que no se suben al repositorio de Git. Crearemos un archivo nuevo de texto que llamaremos gitignore y le agregaremos el siguiente contenido:

# =============== #
# Unity generated #
# =============== #
Temp/
Library/

# ===================================== #
# Visual Studio / MonoDevelop generated #
# ===================================== #
ExportedObj/
obj/
*.svd
*.userprefs
/*.csproj
*.pidb
*.suo
/*.sln
*.user
*.unityproj
*.booproj

# ============ #
# OS generated #
# ============ #
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

Ahora seleccionaremos la opción «Guardar como» y marcaremos la opción «todos los archivos». Le pondremos por nombre .gitignore y lo guardamos.

Por último nos queda configurar Unity. Vamos a Edit->Project Settings->Editor y ahí modificaremos dos opciones. La primera será cambiando en Version Control Mode el valor a Visible Meta Files. La segunda será cambiando en Asset Serialization Mode el valor a Force Text.