Mostrando entradas con la etiqueta GIT. Mostrar todas las entradas
Mostrando entradas con la etiqueta GIT. Mostrar todas las entradas

[GIT] Git Flow - GitHub Flow


A la hora de trabajar con git, existen varios formas de lograr con éxito una buena organización. Existen 2 métodos que proponen una forma de trabajar bajo ciertas normas, ninguna resulta ser perfecta, ninguna cubre todos los casos y es posible que necesitemos nuestra forma de realizar un flujo de trabajo y conocer estos métodos nos brindará una idea como hacerlo.


GitFlow



Gitflow o flujo de git es una manera de trabajar ordenando el repositorio en varias ramas que se corresponden con cada fase del desarrollo de la aplicacion.


La propuesta de este flujo de trabajo cuenta con 5 ramas:

  • master
  • hot-fix
  • release
  • develop
  • feature

Master

Este modo de trabajo nos propone dejar master donde se encuentren las versiones finales, similar a los tags.

Desde master de desprende hot-fix, para tratar incidentes urgentes generalmente rapidos y cortitos.


Develop

Desde master nace la rama de develop, una especie de borrador de master. Desde aqui cada desarrollador crearia su propia rama de trabajo feature-xxx.

Desde ahi uno es libre de seguir creando tantos branch locales como se necesite. Lo importante es, un vez finalizado el trabajo, mergear a develop.

En este punto, nace release, para corregir los ultimos detalles y adecuar al entorno del cliente. Una vez lograda cerrar las caracteristicas del nuevo desarrollo, se integra en develop y desde esta ultima se devolveria a master. Para finalizar se crea el tag.



GitHubFlow



Githubflow o flujo de github, es una manera de trabajar mas minimalista, con solo una rama principal(master) y la rama de turno para generar cambios.


Las caracteristicas principales son:


Todo en master es deployable(desplegable a nivel productivo), esto es ideal a la hora de trabajar con integracion continua y delivery continuo.


Cada nueva caracteristica requiere hacer un branch desde master, y pusheando al remoto hasta lograr una version de pruebas.


Podria haber tantas ramas como caracteristicas simulteneas se requieran.


Si un compañero finalizo su trabajo e integro en master, al crear la nuestra desde la misma instancia, se puede traer sus cambios y sumarlos a los propios.



Los pasos a seguir en flujo de trabajo son:

  • Crea tu propia rama, desde master
  • Trabajar de manera local pusheando los commits a la rama remota
  • Cuando la rama este lista para el merge con master se abre un pull request.
  • Se conversa y revisa el codigo con el grupo de trabajo
  • Deploy y testing en produccion, los arreglos y adecuaciones de configuracion se realizan en este punto
  • Merge a master, luego tag.

[GIT] Operadores - Pull, Push y Fecth

Operadores en GIT

Colaborando: (ver también: git --help workflows)

       
    • Fetch
    • Descarga objetos y referencias de otro repositorio, pero no realiza ningun cambio, es como preguntar ¿Qué hay de nuevo?
  •    
    • Pull
    • Recupera e integra con otro repositorio o un branch local. Hace el fetch y actualiza el branch actual.
  •    
    • Push
    • Actualiza referencias remotas junto con objetos asociados, envia la serie de commits al repositorio remoto.

Actualizando referencias remotas >fetch<

Desde la documentacion local git-fetch

Syntaxis

git fetch [] [ […​]]
git fetch []
git fetch --multiple [] [( | )…​]
git fetch --all []
--all

Permite buscar en todos los branches remotos

--verbose ó -v

Vuelve la salida verbosa, o esa detalla en como han ido el procesamiento del comando

--tags ó -t

Fetchea todos todos los tags remotos dentro de los tags local con el mimsmo nombre

<repository>

Nombre o direccion del repositorio remoto donde se realizará el fetch


Fetch y Merge en una sola operacion: >pull<

Desde la documentacion local git-pull

Syntaxis

git pull [options] [ […​]]

Es la combinación de hacer git fetch && git merge FETCH_HEAD

Opciones de fetch

Son validas todas las opciones de fetch como --all --verbose, etc y las estrategias de merge --ignore-all-space

--rebase

Ejecuta fetch pero en lugar de hacer 'merge' realizará un 'rebase'


Commits
master A -- B -- C
feature  \ -- D -- E

Merge
master A -- B -- C -- F
feature  \ -- D -- E -- /

Rebase
master A -- B -- C
feature                \ -- D -- E
--commit y --no-commit

Realiza el merge y genera un auntocommit, caso contrario da la chance al usuario de tomar acciones

--squash y --no-squash

Realiza el mergue de los commits que se trae como uno solo, caso contrario actualiza cada commit en forma individual


Commiteando en el repositorio remoto: >push<

Desde la documentacion local git-push

Syntaxis

git push [--all | --mirror | --tags] [--follow-tags] [--atomic] [-n | --dry-run] [--receive-pack=]
[--repo=] [-f | --force] [-d | --delete] [--prune] [-v | --verbose]
[-u | --set-upstream] [--push-option=]
[--[no-]signed|--sign=(true|false|if-asked)]
[--force-with-lease[=[:]]]
[--no-verify] [ […​]]
--all

Pushea todos los cambios en todos los branches locales

--tags

Pushea todos los tags, por defecto no se envian

-u ó --set-upstream

Agrega una referencia remota(tracking) al corriente branch

--verbose ó -v

Se ejecuta verbosamente

[Git] Comandos Rápidos para casos puntuales




  • Obtener la version que estoy usando

    git --version
    
    git version 2.14.3.windows.1
    

  • Ver y editar user/email

    #ver nombre de usuario
    git config user.name
    #ver email
    git config user.email
    
    #crear todas las propiedades de config
    git config --list
    
    #crear nombre de usuario
    git config --global user.name "<nombre>"
    
    #crear email
    git config --global user.email "<email>"
    

  • Ver y crear alias

    #ver lista de alias
    git config --get-regexp alias
    
    #crear alias
    git config --global alias.<nombre> "git <comando>"
    
    #crear alias del alias
    git config --global alias.alias "config --get-regexp ^alias\."
    

  • Crear branch local y pushearlo al remoto

    #crear branch y cambiarse al el
    git branch <nombre_branch> && git branch <nombre_branch>
    
    git push --set-upstream <remote_name> <nombre_branch>
    

  • Agregar y cambiar la url del repositorio remoto

    #para ver el repositorio remoto
    git remote -v
    #Cambiar el repositorio remoto existente
    git remote set-url <remote_name> <url>
    #Agregar un nuevo repositorio
    git remote add <remote_name> <url>
    

  • Clonar un solo branch remoto especifico

    git clone -b <branch_name> <url>
    #para version anteriores a 1.7.10
    git clone -b --single-branch <branch_name> <url>
    

  • Realizar un merge ignorando los espacios en blancos

    git merge -Xignore-all-space
    #O siendo mas espeficicos
    git merge -Xignore-space-change
    

  • Moverse a otro branch remoto especifico

    git fetch
    git checkout test
    #Multiples remotos
    git fetch <remote_name>
    git checkout -b <branch_name> <remote_name>/<branch_name>
    

  • Generar tags y pushearlos

    #ver tags locales
    git tag
    #crear un nuevo tag
    git tag -a <nombre_tag> -m "comentario"
    #enviar el tag al remoto
    git push <remote_name> --tags
    

  • Borrar un branch local y remoto

    git branch --delete <branch_name>
    git push <remote_name> --delete <branch_name>
    

  • Descartar cambios modificados o agregados al staged index

    #descartar cambios not staged
    git checkout -- .
    #descartar cambios to be committed
     git reset --hard
    

  • Borrar un commit local y remoto

    #hacer de cuenta que aca no paso nada
    git reset HEAD~1
    #no perder los cambios
    git reset HEAD^ --soft
    
    #borrar el commit en el remoto
    git reset HEAD^ --hard && git push <remote_name> -f
    
    #alt + 94 = ^  alt + 126 = ~
    

[GIT] Ramas - Branch


Ramas


Un 'branch' (rama) en git es simplemente un apuntador móvil a un commit.
La rama por defecto que GIT crea por nosotros es la rama 'master'
Como buenas practicas, deberia ser ésta la versión estable de la aplicación y deberá usarse otras para el desarrollo.

Con la primera confirmación de cambios, se creará automaticamente apuntando a el commit realizado. A medida que realicemos mas confirmaciones de cambios la rama irá avanzando sola y 'master' irá puntando siempre al ultimo commit hecho.


¿Qué sucede si creamos una nueva rama?


Se creara un nuevo apuntador para que se pueda mover libremente sin afectar a 'master', todas las modificaciones y commits que hagamos 'master' no las verá reflejas.
En la siguiente imagen se ven 3 commits realizados(en verde) a los cuales tanto la rama 'master' puede verlos y la nueva rama 'testing' tambien, pero de aqui en mas harán camino separados.



Para crear una nueva rama utilizamos branch seguido del nombre de la nueva rama:

  $ git branch testing

Por defecto git branch listara todas las ramas existente, al igual que con el parametro --list

¿Cómo sabemos entonces en que rama estamos parado?


Al ejecutar el comando git branch debemos obtener algo similiar a :

  $ git branch
  * master
    testing

Pero existe un apuntador especial llamado HEAD (Cabeza) que apunta a la rama local actual.
Para poder intercambiar de ramas se utliza el comando chekout

  $ git checkout testing
  Switched to branch 'testing'

Ahora la situacion del repositorio a pasado, a tener 2 ramas, y se ha movido el HEAD a 'testing'




Tambien podremos observar que en la lineas de comandos donde se encuetra el repositorio a cambio de (master) a (testing) indicando en que rama estamos parado:




La idea de branches se clarifica mas al continuar realizando commiteos en esta nueva rama. Una forma rápita de realizar muchos commits es hacerlos vacios, lo cual no tiene mucho sentido pero en este caso de aprendizaje es ideal, para hacerlo:

  $ git commit --allow-empty -m "1er commit vacio"
  [testing 29fa38e] 1er commit vacio

Ahora la situación gráficamente se vuelve:



Hay que notar que la rama testing avanza, mientra que master continua en el ultimo commit que se realizó.
Si nos movemos a la rama master...

  $ git checkout master

Al realizar este comando estariamos movilizando el HEAD al ultimo commit realizado en master, pudiendo observar todos los commits que realizaron aqui, pero no las modificaciones realizadas en testing.



Este comando realiza 2 aciones en simultaneo:
  • Mueve el apuntador HEAD a la rama master.
  • Revierte los archivos de tu directorio de trabajo al momento de realizar el ultimo commit en master
Esto supone que los cambios realizados de acá en adelante solo rigiran para la rama master y solo en esta dirección.
De continuar trabajando sobre esta rama, se revierte las modificaciones hechas en testing y habra 2 versiones de un mismo proyecto.
Al realizar modificaciones, incluirlas en el staging index, y confirmar los cambios, la situacion gráficamente se verá tal como:




Una rama en git es solamente un archivo que contiene 40 caracteresde una suma de control SHA-1 (basado en el contenido de los archivos y no en su metadata) no cuesta nada al construir y destruir ramas en GIT.

Esto aventaja a GIT como software de control de versiones, ya que otros para crear una rama nueva, se necesitaba copiar el contenido existente del ultimo commit, y depediendo del proyecto podria tardar minutos si es lo suficientemente grande.
Para GIT es rápido y sencillo, solo le lleva 41 bytes entre los 40 caracteres y un retorno de carro.

Diferentes formas de llamar a un branch


Existen varias formas de apuntar a un branch:
  • A través de su nombre:
    • $ git branch master
  • A través de su codigo abreviado de 7 caracteres:
    • $ git branch 29fa38e
  • A través de su codigo de 40 caracteres:
    • $ git branch 29fa38e8b214015dc6e289d13e802b346b66d931
  • A través del HEAD si este lo esta apuntando:
    • $ git branch HEAD
  • Y atraves de los operadores de GIT



Fusión de Branchs (Merge)


Unificar ramas supone haber cumplido con la tarea (issue, track, ticket, etc), la cual nos incentivo a generar la rama en si. Pero esta fusión de ramas trae aparejada que estrategia seguir ya que no todos los casos de repositorios son iguales:
  • Podriamos tener una branch con commits hechos a partir de la separación y el otro no.
  • Tener un branch con archivos 'a', 'b', 'c' y el otro con 'd', 'e' y 'g'.
  • O podriamos tener los mismos archivos pero de diferentes tamaños y con distintas metadata.


Basicamente nuestro procedimiento deberia de ser:
  • Creamos una rama a partir de otra
    • $ git branch test
  • Realizamos nuestra tarea, requerimiento, etc
    • Trabajando =)
  • Comprometemos los cambios
    • $ git commit -m "implementacion hecha"
  • Nos movemos a la rama para fusionar sobre la que trabajamos(gralmente suele fusionarse contra master)
    • $ git checkout master
  • Realizamos el mergeo
    • $ git merge test
  • También en este punto podríamos eliminar la rama que ya no necesitaremos
    • $ git branch -d test


Ahora, después que nuestro merge se realiza con éxito en nuestro repositorio puede darse dos posibles casos:
  • Una unión de ramas con una estrategia fast-forward(avance rápido)
  • O ua estrategia 3-way (merge a tres bandas).

Fast-Forward (ff)


La estrategia de fast-forward es cuando al momento de hacer el nuevo brnach, se deja de hacer modificaciones en master y por ende al momento de mergear solo se le incluyen los commits de la rama altenativa como propia.
Para GIT lo unico que hace es mover el HEAD de master a el HEAD del nuevo branch:


Tambien existe el caso, de hacer un commit al momento de hacer el merge poniendo los parametros --no-ff en el comando para hacer la union de ramas.

  $ git merge --no-ff test

Visualmente el repositorio quedaría asi:


Three ways (3-way)


Pero por otro lado, si al momento de hacer el mergeo, exiten mas confirmaciones de cambio en una de las ramas, (master en nuestro caso) nya no podra ser posible la estrategia fast-forward y será necesario hacer un commit (como en el caso anterior --no-ff) para unificar las ramas:


GIT realiza un merge 3-way (tres bandas), es decir que genera un 'commit' para unificar las ramas, tomando en cuenta el HEAD de cada una de ellas y el antepasado común, de ahi su nombre.
De aquí en mas, dependiendo del proyecto, será necesaria la intervención humana para la resolución de conflictos y decidir con cual archivo conflictivo quedarnos, del mismo que al pegar el contenido de una carpeta nuestro sistema operativo nos advierte y nos da la opcion de reemplazar u omitir.

Por ejemplo al intentar fusionar 2 branchs (master y feature) con un solo archivo llamado README.txt donde varian el contenido en una sola linea, la consola se veria de la siguiente forma:

  $ git merge feature
  Auto-merging README.txt
  CONFLICT (content): Merge conflict in README.txt
  Automatic merge failed; fix conflicts and then commit the result.

  $ git status
  On branch master
  You have unmerged paths.
      (fix conflicts and run "git commit")
 
  Unmerged paths:
      (use "git add ..." to mark resolution)
 
           both modified: README.txt
 
  no changes added to commit (use "git add" and/or "git commit -a")

  $ git diff
  diff --cc README.txt
  index 6007a7c,e8d6d88..0000000
  --- a/README.txt
  +++ b/README.txt
  @@@ -1,1 -1,1 +1,5 @@@
 
  ++<<<<<<< HEAD
  +Unica linea en master
  ++=======
  + linea conflictiva de feature

  ++>>>>>>> feature

  $ git commit -a
  [master caaf175] Merge branch 'feature'

Al realizar esta acción forzamos a realizar el mergeo, simplemente nos genera un archivo "híbrido" con el contenido de ambos, tal como nos muestra en la consola, resultado final es:

  <<<<<<< HEAD
 +Unica linea en master
 + linea conflictiva de feature
 ++>>>>>>> feature

Por lo cual es recomendable realizar al obtener el error de merge, modificar el archivo tal como queremos, en este caso bastara con:

  $ vim README.txt
  <<<<<<< HEAD
 +Unica linea en master
 + linea conflictiva de feature
 ++>>>>>>> feature

'i' para editar:

 +Unica linea en master

salimos con esc ':wq'


Resolviendo conflictos: Ours - Theirs


Otra manera de resolver estos conflictos, es avisarle a GIT con cual archivo queremos quedarnos sabiendo o no que pueden haber conflicto, con ours(nuestros) y theirs(suyos) hablando de cambios.

  $ git merge -s recursive -X ours testing

o

  $ git merge -s recursive -X theirs testing

Cancelando un merge


Tal como nos decia la ayuda, si al momento de hacer un merge nos rejectea podemos deshacer los nuevos cambios con:

  $ git merge --abort

Deshaciendo un merge


Para deshacer un merge, podemos intentar:

  $ git reset --merge ORIG_HEAD




[GIT] Primeros Pasos

Configuración:


Primero podemos decirle a GIT quienes somos: un nombre de usuario y un mail para identificarnos esto será importante para hacer commits, para ello siempre tipeamos en la consola "git ", donde git representa el archivo git.exe seguido de un espacio y los parámetro que introduciremos:

  $ git config --global user.name "John Doe"
  $ git config --global user.email johndoe@example.com

Solo necesita declarar esta información una sola vez, ya que git usara estos datos para todo lo que hagamos en este sistema. Para sobreescribir por otros datos, se puede tipear sin la opción --global. Para ver esta información seteado debemos tipear y obtener algo similiar, donde las 2 ultimas lineas son las que editamos recientemente:

  $ git config --list
  core.symlinks=false
  core.autocrlf=true
  core.fscache=true
  color.diff=auto
  color.status=auto
  color.branch=auto
  color.interactive=true
  help.format=html
  http.sslcainfo=C:/Program Files/Git/mingw64/ssl/certs/ca-bundle.crt
  diff.astextplain.textconv=astextplain
  rebase.autosquash=true
  credential.helper=manager
  user.name=John Doe
  user.email=johndoe@example.com


Obteniendo un repositorio git:


Existen 2 maneras de obtener un repositorio en git.
  • La primera es tomar un proyecto existente(Por ejemplo el directorio raiz que nos crea NetBeans o Eclipse) y convertirlo en un repositorio local.
  • Y la segunda forma es clonar un repositorio remoto proveniente de un servidor.

Repositorio local:

De la primera manera, deberemos pararnos primero sobre la carperta raiz del proyecto, utlizando los comandos cd para ir a ese lugar, o dir para que nos mouestre el contenido de la carpeta en que estemos situado, o también mkdir para agregar una carpeta nueva.

  $ cd C:/Developer/Blog01
  $ git init

Yo por ejemplo, me movilizo con el comando cd a la carpeta donde tengo configurado el WorkSpace de eclipse, y sobre un proyecto que inicie en él.
Con git init se crea un nuevo subdirectorio llamado ".git" que contiene todos los archivos necesarios para el repositorio. Todavia es un repositorio vacio, solo creamos el "Working Directory" es hora de pasarlos al area de ensayo: "Staging area" con el comando git add

Repositorio remoto:

Para obtener una copia de un repositorio GIT existente, deberemos posicionarnos sobre la carpeta existente y tener acceso a la URL.

  $ cd C:/Developer && git clone git@github.com:DarioZubaray/T-esta.git

  • De esta manera, con el comando cd C:/Developer me estoy dirigiendo desde donde me encuentre a esa carpeta del sistema.
  • Con && los 2 amperson seguidos sirven para ejecutar otra linea de comandos en linux(En windows es ||).
  • Por ultimo con git clone [url] estoy descarndo desde ese repositorio remoto, una copia local para trabajar con él, en mi caso es un proyecto que inicie brevemente.

De esta manera, descargue los archivos que contiene el proyecto, y solo necesita hacer un git init para convertirlo en la rama maestra de un nuevo repositorio local.


Estados de un repositorio GIT



  • Untracked: Es un estado ajeno a GIT, son los archivos que se encuentran en la carpeta pero no forman parte del repositorio, ni estan siendo tratados para su implementación.
  • Unmodified: Son los archivos que fueron "agregados a git" y forman parte del Staging area, pero aun no estan de manera permanente en el repositorio.
  • Modified: Son los archivos que como su nombre lo dice, forman parte del Staging area, pero han sufrido modificaciones y requiere nuestra intervencion, para actualizar la version o descartarla.
  • Storaged: Almacenados. Son los archivos que forman parte de nuestro repositorio local.

Normalmente la información es redundante, solo se muestran los cambios sufridos ultimamente y no todos los archivos, de esta manera no visualizaremos todo el contenido del repositorio.
Para consultar el estado de nuestro repositorio, el comando es:

  $ git status

La respuesta al comando seria algo como esto:

 On branch master

 Initial commit

 nothing to commit (create/copy files and use "git add" to track)


Con estamos viendo en la primer linea sobre que rama estamos parados, On branch master nos indica que estamos sobre la rama principal. Initial commit nos informa que es la primera vez que vamos a comprometer los cambios.
Y nothing to commit, nada para commitear, y nos da una ayuda de como seguir.

Agregar archivos:


Rapidamente podemos crear un archivo con el comando touch <nombreArchivo>  :

  $ git touch README.txt

Esto creará el famoso archivo aunque vacio de texto. Ahora podemos ver que resultado nos trae el git status, (La respuesta deberia ser que que README es un archivo Untracked). Para pasar al area de ensayo utilizamos el comando git add <nombreArchivo>  seguido del nombre del archivo.

  $ git add README.txt

Hemos movido el archivo desde "untracked" a "unmodified". Esto se refleja al hacer git status

 $ git status
 On branch master

 Initial commit

 Changes to be committed:
   (use "git rm --cached ..." to unstage)

         new file: README.txt


Deberá aparecernos bajo el titulo de "archivos para ser commiteados" el area que conocemos como unmodified.

Comprometer los cambios:

"Luego quedará la acción de comprometer los cambios, con el comando git commit para entrar en el modo de edición de la consola, donde se requiere pulsar la tecla "i" para poder editar y para salir se necesita pulsar "esc" y luego :wq seguido de un "enter" o simplemente agregando -m "mi mensaje entre comillas dobles" nos ahorraremos este camino.

  $ git commit -m "Incluyendo el archivo vacio README.txt"

Luego de haber commiteado, el status volverá a ser el inicial nothing to commit, working directory clean con la salvedad que ya no nos informa que es el commit inicial.

Modificar archivos:

Ahora veamos que pasa al modificar archivo, para ello vim abre el editor de texto de la consola, al igual que con el mensaje: se requiere pulsar la tecla "i" para poder editar y para salir se necesita pulsar "esc" y luego :wq seguido de un "enter"

  $ vim README.txt




Modificamos brevemente el contenido, ESC + :wq para salir. Y visualizamos el cambio de estado con git status :

  $ git status
  On branch master
  Changes not staged for commit:
    (use "git add ..." to update what will be committed)
    (use "git checkout -- ..." to discard changes in working directory)

         modified: README.txt

  no changes added to commit (use "git add" and/or "git commit -a")


Ahora veremos que el estado del archivo cambio a "rojo", al estado de archivos modificados, y además también nos sugiere el uso de git add o git cheackout -- ya sea para agregar el archivo a "unmodified" o removerlo.
Para ver los archivos que han sufrido modificaciones y un pequeño resumen, usamos el comando git diff

  $ git diff
  diff --git a/README.txt b/README.txt
  index e69de29..979e5c3 100644
  --- a/README.txt
  +++ b/README.txt
  @@ -0,0 +1 @@
  +editado
  warning: LF will be replaced by CRLF in README.txt.
  The file will have its original line endings in your working directory.

Eliminar archivos:

Para remover un archivo del working directory y del staging index lo hacemos con el comando rm <nombreARchivo> seguido del nombre del archivo.

  $ rm README.txt

Logeo


Para ver el registro de commits de nuestro repositorio, utilizamos git log, el cual también tiene su versión más reducida con el parámetro --oneline y su version extendida -p

  $ git log
  commit 9a50f43c1468c5e9b3a306c2e77857df339aed0d
  Author: Dario Zubaray
  Date: Tue Jul 5 21:06:58 2016 -0300

        Incluyendo el archivo vacio README.txt


Tips


Para ir limpiando la pantalla podemos usar el comando:

  $ clear

Para ver todos los comando ejecutados recientemente:

  $ history

Para cerrar la consola

  $ exit

[GIT] Introducción, Instalación

¿Qué es GIT?



Git es un software de control de versiones.
Un Sistema de control de versión debe permitir:
  • Almacenar todo el código fuente de un proyecto (de cualquier lenguaje) y los elementos adicionales que pueda contener (ej. archivos de texto, imágenes, iconos, sonidos, documentación, etc)
  • Realizar cambios sobre el todo proyecto: el código y sus elementos almacenados (ej. modificaciones parciales, añadir, borrar, renombrar o mover archivos).
  • LLevar un registro histórico de los estados en que el proyecto se encontraba al momento de ser fue almacenado, pudiendo obtener asi las distintas versiones por la que fue pasando.


Existen de 2 tipos de software de control de versiones:
  • Centralizados:
    • Existe un único repositorio de datos, se accede a través de la red
    • La comunicación/colaboración entre desarrolladores se lleva a cabo (forzosamente) utilizando el repositorio centralizado
    • Son fáciles de usar
    • Los modelos de trabajo son más restringidos

  • Distribuidos:
    • Existe un repositorio local, en cada pc como programdores trabajen sobre el proyecto, y además de otro remoto, en la nube.
    • La comunicación/colaboración entre programadores es más abierta.
    • Es un poco más difícil de usar
    • Los modelos de trabajo son flexibles
    • “Los branches/merges son más simples”

Git, es entonces un software de control de versiones distribuido o descentralizado.




Terminología

La mayor parte de los términos usados en git están en inglés, por si fuera poco no sólo al no saber su significado uno no puede deducirlo, pero aca en más hay que entenderlos y usarlos en su idioma de origen.
Repository (Repositorio) Es la fuente de datos. Es la carpeta y sub-carpetas donde se encuentran todos los archivos necesario para el proyecto.
Head (Cabeza) Versión actual del proyecto
blob (gota) Es la forma en que GIT almacena un archivo del repositorio.
Tree (árbol) Es una archivo propio de GIT que indica como se relacionan los blobs
Commit (Comprometer) Es la acción de comprometer los cambios realizados sobre el repositorio.
Branch (Rama) Son las distintas ramas en que se pueden separar los diferentes commits.
Merge (Unir) Es la acción de unir las ramas
Mater (Maestra-Principal) Es la rama principal, la que se crea por defecto. Se suele usar para contener la version estable estable del proyecto, sobre otras ramas se implementan modificaciones.
Trunk (Maletero) Localización dentro del repositorio que contiene la rama principal de desarrollo.
Pull (Traer) Trae una rama en particular alojada en un repositorio remoto.
Push (Tirar) Envía la rama actual a el repositorio remoto.
Clone (Clonar) Duplica un repositorio remoto para hacerlo local.
Fork (Bifurcar) Genera entre mis repositorios locales, algún repositorio remoto de alguien mas, como si lo estuviera clonando.


Estructura interna de GIT


La estructura de GIT se divide:
  • Working Directory: El directorio de nuestro proyecto.
  • Staging area/index: Es el área de ensayo, donde agregaremos cada uno de los nuevos archivos.
  • Commit: Es la accion de "guardar" sobre el directorio de trabajo, la estructura del staging index
  • Remote Repository: Es la nube, donde podremos o no, almacenar el repositorio.
A través de las diferentes acciones que iremos realizando, estas partes se irán comunicando.

  • Lo primero será crear el directorio de trabajo o tener acceder a uno.
  • Luego habrá que ir agregando las modificaciones al área de ensayo.
  • Posteriormente se comprometen los cambios
  • Y se puede actualizar estos cambios de la nueva versión a la nube, primeramente descargando el repositorio remoto a el local, para el caso de que existan diferencias que requieran la atención humana (Como por ejemplo decidir sobre que archivos quedarnos)
  • Luego podremos subir la ultima versión del proyecto a la nube (Esta vez sin conflictos)
  • De aqui en mas podremos intercambiar de ramas o restaurar los archivos del árbol de trabajo
  • Unificar ramas, gralmente cuando la tarea que derivó en separar ha sido cumplida.




Para GIT cada acción de comprometer los cambios(git commit) se traduce como la codificación de cada archivo a un cógido hexadecimal de 40 dígitos, el cual actuará como un identificador para para dicho archivo. En caso de tener 2 archivos iguales el identificador será identico. Este Archivo para GIT será conocido como Blob.
A su vez cada blob esta ubicado a nivel directorio con toda su metdata (creación, autor, etc) y relacionado con otros blobs, dentro otro archivo conocido como Tree. Este también contiene a partir de su contenido un identificador de 40 digitos.
Nuevamente cada tree esta relacionado con otro archivo que se genera a partir de contenido con un identificador, llamado Commit.
En la siguiente imagen podemos observar, un primer "git commit" con 3 blobs (archivos), relacionados a 1 solo tree y este a un commit. Luego de eso se produjo otro "git commit" incluyendo un nuevo blob, relacionado a través de un tree, que no solo contiene la información del blob sino que además relaciona los 3 blobs anteriores a través de su tree. Y por ultimo vemos que cada commit, genera el archivo commit relacionando cada tree propio, pero el ultimo commit se relaciona con el "parent commit", esto es la relacion que hubo entre las 2 acciones de commiteo.


Instalación

Para hacernos con GIT deberemos ir a su página oficial: https://git-scm.com/downloads y descargar la última versión:


Desde ubuntu tambien se puede realizar a través de su consola:

sudo apt-get install git-core


Para Windows, podremos seguir la instalción por defecto, salvo en la siguiente pantalla:


Y ya estamos listos para iniciar "GIT Bash" y tirar comandos como locos! xD