Introducción
Preparé este documento como guía para un grupo de personas con las que estaré trabajando. Vamos a desarrollar una aplicación web y decidimos gestionar el trabajo con Git. Algunas personas del grupo son nuevas en git, así que este artículo está pensado como una guía para ellas.
Qué es git
En pocas palabras: Git es una utilidad de control de versiones. Registra los cambios que realizás en los documentos para que puedas revisarlos y volver a cualquier estado anterior en cualquier momento. Es como una máquina del tiempo para tu proyecto.
Git es en realidad mucho más que eso y es muy poderoso, pero por simplicidad vamos a dejarlo así por ahora.
Primeros pasos
Podés empezar con git principalmente de dos maneras.
Estás iniciando el proyecto
Cuando sos vos quien inicia el proyecto, lo primero que tenés que hacer es inicializar el repositorio git.
Creemos la carpeta donde vamos a trabajar.
mkdir ~/mi-proyecto
cd ~/mi-proyecto
Ahora necesitamos iniciar git.
git init
Eso creará una nueva carpeta ~/mi-proyecto/.git que contiene toda la información que git necesita para registrar tus cambios. Nunca tenés que editar ni modificar nada en esa carpeta manualmente, y si la borrás, perderás el historial del proyecto.
Ya tenés el proyecto git iniciado, ahora empezás a trabajar.
Supongamos que creás dos documentos adentro:
emacs main-app.c
emacs sub-rutinas.c
Una vez terminado, tenés que agregar la información a git.
Si revisás el estado del proyecto, vas a ver que hay archivos que git no está siguiendo. Veámoslo:
git status
Vas a obtener esto:
# On branch main
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
main-app.c
sub-rutinas.c
nothing added to commit but untracked files present (use "git add" to track)
Lo que git dice es que hay dos documentos nuevos en la carpeta que está monitoreando, pero ninguno fue agregado explícitamente para seguimiento. Hay que agregarlos.
git add main-app.c
git add sub-rutinas.c
Ya están agregados. Si hay demasiados archivos y querés agregarlos todos de una vez:
git add -A
Revisemos el estado nuevamente:
git status
El resultado es:
# On branch main
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
new file: main-app.c
new file: sub-rutinas.c
Los archivos están agregados pero todavía no confirmados. Todavía podés dejar de seguir o desestabilizar un archivo. Si querés hacerlo podés usar git rm [archivo]. En nuestro caso no queremos, así que hagamos nuestro primer commit.
git commit -m 'Mi primer commit. Agrego main-app.c que es el código principal de la app, y llamará algunas subrutinas desde sub-rutinas.c. Este último archivo todavía está vacío'
Ya tenemos los archivos confirmados. Si revisamos el estado una vez más, veremos esto:
git status
El resultado es:
# On branch main
nothing to commit (working directory clean)
El proyecto ya existe en algún lugar, lo estás clonando
Lo que es genial de git es que no hay una autoridad central. Clonás un proyecto y podés trabajar con él en tu PC sin necesidad de estar conectado al repositorio clonado, a menos que quieras compartir tus cambios.
Clonemos un proyecto.
cd ~/
git clone git://servidor.com/mi-proyecto.git
También podés clonar desde tu propio disco o una unidad de red: git clone /compartido/red/proyecto.git
Ahora que tenés el proyecto podés trabajar en él y enviar tus cambios al repositorio "central".
vim README.txt
Agregaste un archivo readme. Revisemos el estado:
git status
Vas a ver esto:
# On branch main
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
README.txt
nothing added to commit but untracked files present (use "git add" to track)
Ahora necesitamos agregar el archivo que acabamos de crear. A partir de acá procedemos igual que antes.
git add README.txt
git commit -m 'agregado archivo README con descripción de la app e instrucciones de instalación'
Eso es todo. Ya empezaste con git.
Resumen
Ahora sabés cómo:
- Crear un repositorio git
- Agregar archivos sin seguimiento al proyecto
- Hacer commits
- Clonar repositorios y trabajar en ellos
Trabajando con repositorios remotos
En la sección anterior creé un repositorio en ~/mi-proyecto/, y luego lo cloné en ~/segundo-proyecto/, por lo que la segunda carpeta de trabajo es ~/segundo-proyecto/mi-proyecto.
Llamaremos al primero origin, que es como git nombra el repositorio clonado por defecto. Vayamos al primero.
cd ~/mi-proyecto/
Y revisemos los logs:
git log
El resultado es:
commit a6787b87ee36050f58014caa916bf85801771d34
Author: Guillermo Garron - Mac- <ggarron@localhost>
Date: Mon May 13 15:28:37 2013 -0400
Mi primer commit. Agrego main-app.c que es el código principal de la app, y llamará algunas subrutinas desde sub-rutinas.c. Este último archivo todavía está vacío
Si ahora vamos a la segunda carpeta:
cd ../segundo-proyecto/mi-proyecto/
Y revisamos el log:
git log
El resultado es:
commit b355a28868f5ac19b6ee949e110d0575dd5ed2dc
Author: Guillermo Garron - Mac- <ggarron@localhost>
Date: Mon May 13 15:45:07 2013 -0400
agregado archivo README con descripción de la app e instrucciones de instalación
commit a6787b87ee36050f58014caa916bf85801771d34
Author: Guillermo Garron - Mac- <ggarron@localhost>
Date: Mon May 13 15:28:37 2013 -0400
Mi primer commit. Agrego main-app.c que es el código principal de la app, y llamará algunas subrutinas desde sub-rutinas.c. Este último archivo todavía está vacío
Como podés ver, el segundo está un commit adelante. Si queremos compartir los cambios introducidos en el segundo, podemos hacerle push. Pero primero veamos los repositorios bare:
Repositorios bare
Para compartir el trabajo, estos dos desarrolladores virtuales —uno trabajando en ~/mi-proyecto/ y el otro en ~/segundo-proyecto/mi-proyecto/— necesitan un repositorio bare. Un repositorio bare es uno sin árbol de trabajo, compuesto únicamente por la carpeta .git.
En los dos repositorios que tenemos hay una carpeta .git dentro de las carpetas de trabajo. El repositorio bare será solo esa carpeta .git sin carpeta de trabajo. Creemos ese repositorio bare.
mkdir -p ~/tmp/mi-proyecto.git
cd ~/tmp/mi-proyecto.git
git init --bare
Ya tenemos el repositorio bare. Vayamos al segundo proyecto.
cd ~/segundo-proyecto/mi-proyecto/
git remote rm origin
git remote add origin ~/tmp/mi-proyecto.git
Tuvimos que eliminar el origin anterior para agregar uno nuevo, lo tenía porque fue clonado. Básicamente podrías haberlo dejado y simplemente agregar un nuevo remoto, pero prefiero nombrar el repositorio "central" como origin. Revisemos el remoto:
git remote -v
El resultado será algo así:
origin /Users/ggarron/tmp/mi-proyecto.git (fetch)
origin /Users/ggarron/tmp/mi-proyecto.git (push)
Ahora podemos hacer push de nuestros cambios:
git push origin main
El resultado:
Counting objects: 7, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (7/7), 739 bytes, done.
Total 7 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (7/7), done.
To /Users/ggarron/tmp/mi-proyecto.git
* [new branch] main -> main
Supongamos que ahora el primer desarrollador virtual quiere obtener nuestros cambios en su carpeta.
cd ~/mi-proyecto/
Necesitamos agregar el origin acá para poder hacer pull de los cambios.
git remote add origin ~/tmp/mi-proyecto.git
No fue necesario eliminar nada acá porque este repositorio no fue clonado, no tiene origin definido.
Hagamos pull de los cambios.
git pull origin main
El resultado es:
From /Users/ggarron/tmp/mi-proyecto
* branch main -> FETCH_HEAD
Updating a6787b8..b355a28
Fast-forward
README.txt | 2 ++
1 file changed, 2 insertions(+)
create mode 100644 README.txt
Como podés ver, el archivo README.txt fue creado con 2 inserciones (era un archivo pequeño). Ahora ambas carpetas están sincronizadas con el repositorio "central".
Resumen
Ahora sabemos cómo:
- Crear repositorios bare
- Eliminar y agregar remotos
- Hacer push de cambios confirmados al repositorio remoto
- Hacer pull de contenidos desde un repositorio remoto
Trabajando con ramas
Una de las características más poderosas de Git es el trabajo con ramas. Una rama es como un segundo conjunto de carpetas para trabajar, de modo que no arruinás el proyecto real. Es similar a cuando trabajás con un archivo de configuración, digamos http.conf. Querés hacer algunos cambios, pero si algo sale mal querés poder volver rápidamente. Normalmente creás una copia del archivo cp http.conf http.conf.original y ya tenés un respaldo. Git usa ramas para eso.
Por defecto estás trabajando en la rama main, y podés crear tantas ramas como quieras para probar localmente antes de modificar la rama main.
En nuestro ejemplo, supongamos que el primer desarrollador (el jefe) crea una rama llamada testing y la comparte con el otro desarrollador a través del repositorio "central".
cd ~/mi-proyecto/
git checkout -b testing
El resultado es:
Switched to a new branch 'testing'
Git creó la nueva rama y cambió a ella. Probemos una nueva subrutina en nuestra app.
vim sub-rutinas.c
Después de hacer algunos cambios:
git status
El resultado es:
# On branch testing
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
modified: sub-rutinas.c
#
no changes added to commit (use "git add" and/or "git commit -a")
Agreguemos y confirmemos esos cambios.
git add -A
git commit -m 'cambios en la subrutina principal, solo para pruebas. Se recomienda depurar antes de enviar a producción'
Ahora podemos ver el estado de ambas ramas.
git branch -v
El resultado es:
main b355a28 agregado archivo README con descripción de la app e instrucciones de instalación
* testing bf211b2 cambios en la subrutina principal, solo para pruebas. Se recomienda depurar antes de enviar a producción
Como podés ver, estamos trabajando en testing (fijate el asterisco), y también podés ver que testing está adelante. Ahora el jefe quiere compartir su cambio con el otro desarrollador para que lo depure.
git push origin testing
Acá estamos haciendo push de la rama testing a origin (nuestro repositorio central). El resultado que verás es:
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 429 bytes, done.
Total 3 (delta 1), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To /Users/ggarron/tmp/mi-proyecto.git
* [new branch] testing -> testing
Ahora el segundo desarrollador hará pull de esos cambios y trabajará con ellos:
cd ~/segundo-proyecto/mi-proyecto/
git checkout -b testing
git pull origin testing
El resultado es:
From /Users/ggarron/tmp/mi-proyecto
* branch testing -> FETCH_HEAD
Updating b355a28..bf211b2
Fast-forward
sub-rutinas.c | 8 ++++++++
1 file changed, 8 insertions(+)
Revisemos el estado:
git branch -v
El resultado es:
main b355a28 agregado archivo README con descripción de la app e instrucciones de instalación
* testing bf211b2 cambios en la subrutina principal, solo para pruebas. Se recomienda depurar antes de enviar a producción
El segundo desarrollador puede ahora trabajar en los cambios.
emacs sub-rutinas.c
git add sub-rutinas.c
git commit -m 'todo probado y corregido, listo para producción'
git push origin testing
Por su parte, el jefe tomará su copia, hará las pruebas finales y luego fusionará con la rama main (producción).
cd ~/mi-proyecto/
git checkout testing
git pull origin testing
Después de que todas las pruebas estén hechas, es momento de fusionar.
Fusionando ramas en Git
El jefe de desarrollo fusionará ahora la rama testing en la rama main.
Veamos el estado de las ramas:
git branch -v
El resultado muestra:
main b355a28 agregado archivo README con descripción de la app e instrucciones de instalación
* testing 0b38a32 todo probado y corregido, listo para producción
Main está muy por detrás de testing. Cambiamos a main:
git checkout main
Y fusionamos ambas:
git merge testing
El resultado es:
Updating b355a28..0b38a32
Fast-forward
sub-rutinas.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
Notas adicionales
Podés crear tantas ramas como quieras en tu PC local, trabajar y probar con ellas sin necesidad de compartirlas todas.
Para eliminar una rama del origin el comando es:
git push origin --delete testing
testing es solo en nuestro caso; tenés que usar el nombre de la rama que querés eliminar. Considerá que otros podrían estar trabajando en ella antes de borrarla.
Resumen
Ahora sabés cómo:
- Crear ramas
- Cambiar entre ramas
- Hacer push y pull de ramas
- Fusionar ramas
Conclusión
Git es mucho más que esto, pero estos comandos deberían ser suficientes para proyectos simples y con pocas personas trabajando en ellos.
- Creado: 13 de mayo de 2013
- Última edición: 7 de julio de 2026