Control de versiones con git

Andrés Hernández
mail
Universidad Nacional Autónoma de México
Facultad de Ciencias
Junio 2016
html5 book version
UNAM Facultad de Ciencias

Información del curso

Nivel de especialización

Básico

Objetivo

El alumno conocerá el sistema de control de versiones git y aprenderá el uso de esta herramienta tanto desde línea de comandos, como desde un cliente de escritorio y vía web a través de Github.


Perfil del asistente

Estudiantes, pasantes o egresados de carreras afines a computación, desarrolladores y entusiastas de la programación.

Conocimientos previos


Temario

  1. Introducción a los sistemas de control de versiones
  2. Local
  3. Centralizado
  4. Distribuido

  5. Introducción a git
  6. Inicializar un repositorio
  7. Clonar un repositorio existente
  8. Agregar archivos
  9. Guardar cambios en el repositorio
  10. Borrar archivos
  11. Mover archivos
  12. Enviar cambios al servidor
  13. Revisar el estado de los archivos en el directorio de trabajo
  14. Bitácora de revisiones del proyecto


Temario (cont)

  1. Configuración del cliente git
  2. Datos del usuario
  3. Reparar fin de línea en los archivos
  4. Ignorar espacios en blanco

  5. Trabajando con repositorios existentes
  6. Clonar un repositorio existente
  7. Resolución de conflictos
  8. Corregir el commit anterior


Temario (cont 2)

  1. Introducción a Github
  2. Crear una cuenta en Github
  3. Administración de repositorios via web
  4. Cliente gráfico de git para Mac y Windows
  5. Documentación en Markdown

  6. Trabajo colaborativo en Github
  7. Fork
  8. Pull requests
  9. gist
  10. Github Pages
  11. Wikis


0. Configurar el nombre de usuario

System Settings


System Settings ⇒ Users


System Settings ⇒ Users ⇒ Username


1. Introducción a los sistemas de control de versiones

Sistema de control de versiones


1.1. Local

Guardar cambios en archivos separados

    prog.c prog1.c prog2.c ... prog<n>.c

Guardar cambios en carpetas separadas

  tarea/prog.c
  version_inicial/prog.c
  modificado2/prog.c
  vers-28sep/prog.c
  ProyectoFinal_2017-1_completo(Andres)/prog1.c

Desventajas del control de versiones local


Enviar cambios por correo electrónico

Thunderbird Gmail Apple Mail Outlook


Utilizar almacenamiento en la nube

Dropbox GoogleDrive Evernote box.net OneDrive ownCloud


1.2. Centralizado - CVCS

SVN
svn-actions


1.3. Distribuido - DVCS

git hg bzr arch BitKeeper


2. Introducción a git

BitKeeper git


2.0.1. Características de git


2.0.2. Áreas de trabajo


2.0.1.1. Estados de un archivo

Estado Descripción Comando
Modified El archivo fue editado en el directorio de trabajo editor archivo
Staged El archivo (nuevo o modificado) fue agregado al área de staging git add archivo
Staged El archivo se movió o renombró utilizando git git mv archivo1 archivo2
Staged El archivo se borró del área de staging utilizando git git rm archivo
Committed Los cambios del archivo fueron guardados en el repositorio git commit archivo

2.0.2. Instalar git en GNU/Linux

root@debian:~# aptitude install git
[root@centos ~]# yum install git

Para instalar en otras variantes de UNIX ver la documentación oficial


2.1. Inicializar un nuevo repositorio

$ man git-init

git-init - Create an empty Git repository or reinitialize an existing one

git init [-q | --quiet] [--bare] [--template=<template_directory>]
         [--separate-git-dir <git dir>] [--shared[=<permissions>]] [directory]
tonejito@linux:~$ mkdir repositorio
tonejito@linux:~$ cd repositorio
tonejito@linux:~/repositorio$ git init
Initialized empty Git repository in /home/tonejito/repositorio/.git/
tonejito@linux:~/repositorio$ ls -lA
total 0
drwxr-xr-x 7 tonejito users 147 Jun  3 17:16 .git

tonejito@linux:~$ git init otro-repo
Initialized empty Git repository in /home/tonejito/otro-repo/.git/
tonejito@linux:~$ ls -lA otro-repo/
total 0
drwxr-xr-x 7 tonejito users 147 Jun  3 17:19 .git
tonejito@linux:~$ git init --shared=group repo-compartido
Initialized empty shared Git repository in /home/tonejito/repo-compartido/.git/
tonejito@linux:~$ chmod -R g+rw repo-compartido/
tonejito@linux:~$ ls -la repo-compartido/
total 4
drwxrwsr-x  3 tonejito users   17 Jun  6 09:50 .
drwxr-xr-x 57 tonejito users 4096 Jun  6 09:50 ..
drwxrwsr-x  7 tonejito users  147 Jun  6 09:50 .git

2.2. Clonar un repositorio existente


2.2.1. Ejemplo de git-clone

tonejito@linux:~$ git clone https://github.com/tonejito/curso-git.git
Cloning into 'curso-git'...
remote: Counting objects: 108, done.
remote: Compressing objects: 100% (42/42), done.
remote: Total 108 (delta 24), reused 0 (delta 0), pack-reused 65
Receiving objects: 100% (108/108), 429.40 KiB | 0 bytes/s, done.
Resolving deltas: 100% (45/45), done.
Checking connectivity... done.
tonejito@linux:~$ ls -A curso-git/
.git  .gitignore  LICENSE.md  presentation.md
img   index.html  Makefile    README.md

2.3. Agregar archivos

git-add - Add file contents to the index

git add [-n]  [-v]  [--force | -f]  [--interactive | -i]  [--patch | -p]
        [--edit | -e]  [--[no-]all | --[no-]ignore-removal | [--update | -u]]
        [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing]
        [--]  [<pathspec>...]

tonejito@linux:~/repositorio$ editor README.md
# Mi repositorio de git

Andrés Hernández

tonejito@linux:~/repositorio$ git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    README.md

nothing added to commit but untracked files present (use "git add" to track)

tonejito@linux:~/repositorio$ git add README.md
On branch master

Initial commit

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

    new file:   README.md

2.4. Guardar cambios en el repositorio

git-commit - Record changes to the repository

git commit [-a | --interactive | --patch]  [-s]  [-v]  [-u<mode>]  [--amend]
           [--dry-run]  [(-c | -C | --fixup | --squash) <commit>]
           [-F <file> | -m <msg>]  [--reset-author]  [--allow-empty]
           [--allow-empty-message]  [--no-verify]  [-e]  [--author=<author>]
           [--date=<date>]  [--cleanup=<mode>]  [--[no-]status]
           [-i | -o]  [-S[<key-id>]]  [--]  [<file>...]

2.4.1. git-commit interactivo

tonejito@linux:~/repositorio$ git commit README.md
Commit inicial del proyecto

+ Se agrega el archivo README.md
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# Explicit paths specified without -i or -o; assuming --only paths...
# On branch master
#
# Initial commit
#
# Changes to be committed:
#       new file:   README.md
#

2.4.2. Estructura del mensaje de un commit

Línea Elemento Contenido
1 Título del commit Descripción breve y concreta del cambio aplicado, menos de 50 caracteres
2 Línea en blanco Se utiliza para separar el título del cuerpo
3 Descripción del commit Mensaje que explica el cambio aplicado a profundidad
Puede abarcar varias líneas de texto
Es posible insertar elementos de sintáxis de Markdown
Se pueden utilizar listas para enumerar elementos de manera vertical

2.4.3. git-commit - one-liner

tonejito@linux:~/repositorio$ touch archivo-para-borrar
tonejito@linux:~/repositorio$ git add archivo-para-borrar
tonejito@linux:~/repositorio$ git commit -m "Archivo de prueba para probar git-rm"
tonejito@linux:~/repositorio$ git log -n 1
commit f552622d1a526ed0471ea260e3b99d1cef0c72f3
Author: Andrés Hernández <andres.hernandez@ciencias.unam.mx>
Date:   Wed Jun 8 13:52:04 2016 -0500

    Archivo vacío para probar git-rm

2.5. Borrar archivos

git-rm - Remove files from the working tree and from the index

git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...

2.5.1. Ejemplo de git-rm

tonejito@linux:~/repositorio$ ls -l
total 4
-rw-r--r-- 1 tonejito users  0 Jun  8 13:45 archivo-para-borrar
-rw-r--r-- 1 tonejito users 44 Jun  6 18:01 README.md
tonejito@linux:~/repositorio$ git rm archivo-para-borrar
rm 'archivo-para-borrar'
tonejito@linux:~/repositorio$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    archivo-para-borrar
tonejito@linux:~/repositorio$ git commit -m "Prueba de git-rm" archivo-para-borrar
[master 1f6d57a] Prueba de git-rm
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 archivo-para-borrar

2.6. Mover archivos

git-mv - Move or rename a file, a directory, or a symlink

git mv [-v] [-f] [-n] [-k] <source>     <destination>
git mv [-v] [-f] [-n] [-k] <source> ... <destination directory>

2.6.1. Ejemplo de git-mv

tonejito@linux:~/repositorio$ touch archivo-para-mover archivo-para-renombrar
tonejito@linux:~/repositorio$ git add archivo-para-mover archivo-para-renombrar
tonejito@linux:~/repositorio$ git commit -m "Archivos vacíos para prueba de git-rm" archivo-para-*
[master 657aa04] Archivos vacíos para prueba de git-rm
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 archivo-para-mover
 create mode 100644 archivo-para-renombrar
tonejito@linux:~/repositorio$ mkdir -v directorio
mkdir: created directory ‘directorio’
tonejito@linux:~/repositorio$ git mv archivo-para-mover directorio/
tonejito@linux:~/repositorio$ git mv archivo-para-renombrar archivo-con-otro-nombre
tonejito@linux:~/repositorio$ git commit -m "Prueba de git-mv"
[master 4f30937] Prueba de git-mv
 2 files changed, 0 insertions(+), 0 deletions(-)
 rename archivo-para-renombrar => archivo-con-otro-nombre (100%)
 rename archivo-para-mover => directorio/archivo-para-mover (100%)

2.7. Enviar cambios al servidor


2.7.1. Listar la URL del repositorio remoto

tonejito@linux:~/repositorio$ git remote add origin https://github.com/tonejito/repositorio.git
tonejito@linux:~/repositorio$ git remote -v
origin  https://github.com/tonejito/repositorio.git (fetch)
origin  https://github.com/tonejito/repositorio.git (push)

2.7.2. Enviar cambios con git-push

tonejito@linux:~/repositorio$ git push -u origin master
Username for 'https://github.com': tonejito
Password for 'https://tonejito@github.com':
Counting objects: 12, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (8/8), done.
Writing objects: 100% (12/12), 1.35 KiB | 0 bytes/s, done.
Total 12 (delta 1), reused 0 (delta 0)
To https://github.com/tonejito/repositorio.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.
tonejito@linux:~/repositorio$ git push
Username for 'https://github.com': tonejito
Password for 'https://tonejito@github.com':
Counting objects: 3, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 462 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/tonejito/repositorio.git
   4f30937..be47c1b  master -> master

2.8. Revisar el estado de los archivos en el directorio de trabajo

Estado del archivo Comando Descripción
Untracked touch <file> Se creó un nuevo archivo en el Directorio de trabajo
Aún no se agrega al control de versiones
new file git add <file> Se agregó un nuevo archivo para ser versionado
deleted git rm <file> El archivo se borró del repositorio
renamed git mv <src> <dst> El archivo cambió de nombre o fue movido
modified gedit <file> El contenido del archivo fue modificado
both modified :sweat_smile: :gun: :rage: Es necesario hacer merge :scream:

2.8.1. Untracked files - Archivos nuevos sin versionar

tonejito@linux:~/repositorio$ touch archivo-externo
tonejito@linux:~/repositorio$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    archivo-externo

nothing added to commit but untracked files present (use "git add" to track)

2.8.2. git addnew file

tonejito@linux:~/repositorio$ git add archivo-nuevo
tonejito@linux:~/repositorio$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   archivo-nuevo

2.8.3. git rmdeleted

tonejito@linux:~/repositorio$ git rm archivo-para-borrar
rm 'archivo-para-borrar'
tonejito@linux:~/repositorio$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    archivo-para-borrar

2.8.4. git mvrenamed

tonejito@linux:~/repositorio$ git mv archivo-para-mover directorio/
tonejito@linux:~/repositorio$ git mv archivo-para-renombrar archivo-con-otro-nombre
tonejito@linux:~/repositorio$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    archivo-para-renombrar -> archivo-con-otro-nombre
    renamed:    archivo-para-mover -> directorio/archivo-para-mover

2.8.5. modified - Archivos editados

tonejito@linux:~/repositorio$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
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:   pagina.html

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

2.9. Bitácora de revisiones del proyecto

tonejito@linux:~/repositorio$ git log
commit be47c1b99c212c0b25d7351c1d9bd8de33c06dd8
Author: Andrés Hernández <andres.hernandez@ciencias.unam.mx>
Date:   Thu Jun 9 10:53:34 2016 -0500

    Página de prueba para `curso-git`
    
    + Código base `html5` sin estilos

... ... ... ... ... ... más entradas del log    ...

commit 1b75a81323d5a6befff5d4ddfd3ad3254914c8da
Author: Andrés Hernández <andres.hernandez@ciencias.unam.mx>
Date:   Wed Jun 8 13:46:21 2016 -0500

    Commit inicial del proyecto
    
    + Se agrega el archivo README.md

3. Configuración del cliente git

commit f020486f071bf11053547a86f4a7153b3c950f4b
Author: Facultad de Ciencias <ciencias@debian8.local>
Date:   Tue 19 Jan 03:14:08 2038 +0000

    Título del commit
    
    Mensaje del commit

3.0.1. Secciones de configuración de git

Ubicación Directorio Descripción
System-wide
Sistema
/etc/gitconfig Archivo de configuración global para todos los repositorios presentes en el sistema
Global
Usuario
~/.gitconfig Archivo de configuración que aplica para todos los repositorios del usuario
Local
Repositorio
$GIT_DIR/config Aplica únicamente para el repositorio actual

3.1. Datos del usuario

3.1.1. Configuración global para el usuario

tonejito@linux:~$ git config --global user.name  'Andrés Hernández'
tonejito@linux:~$ git config --global user.email 'andres.hernandez@unam.mx'
tonejito@linux:~$ cat ~/.gitconfig
[user]
    name  = Andrés Hernández
    email = andres.hernandez@unam.mx

3.1.2. Configuración local para el repositorio

tonejito@linux:~/repositorio$ git config --local user.name  'Andrés Hernández'
tonejito@linux:~/repositorio$ git config --local user.email 'andres.hernandez@ciencias.unam.mx'
tonejito@linux:~/repositorio$ cat .git/config
[user]
    name  = Andrés Hernández
    email = andres.hernandez@ciencias.unam.mx

3.2. Reparar fin de línea en los archivos

Sistema operativo Retorno de línea Descripción
UNIX / BSD / Solaris / MacOSX / Linux LF El salto de línea se representa con el caracter \n
MacOS <= 9.2.2
Classic
CR El salto de línea se representa con el caracter \r
Windows CR-LF El salto de línea se representa con el caracter \r seguido de \n

tonejito@linux:~$ git config --global core.autocrlf input
tonejito@linux:~$ cat .gitconfig
[core]
   ...
    autocrlf = input

3.3. Ignorar espacios en blanco

Un problema común con algunos editores es que agregan espacios en blanco sin que el usuario se de cuenta

Elemento Activo
por defecto
Descripción
blank-at-eol SI Quita espacios en blanco al final de la línea
blank-at-eof SI Quita lineas vacías al final del archivo
space-before-tab SI Quita espacios antes de un caracter <TAB> en el principio de la línea
indent-with-non-tab NO Busca lineas que estan identadas con espacios, se controla con la directiva tabwidth
tab-in-indent NO Busca <TAB> en la identación de las lineas
cr-at-eol NO Identifica el caracter <CR> como válido al final de la linea

Ejemplo de core.whitespace

Para establecer el valor de core.whitespace utilizaremos las siguientes características:

tonejito@linux:~$ git config core.whitespace blank-at-eol,blank-at-eof,space-before-tab,-indent-with-non-tab,-tab-in-indent
tonejito@linux:~$ cat .gitconfig
[core]
   ...
    whitespace = blank-at-eol,blank-at-eof,space-before-tab,-indent-with-non-tab,-tab-in-indent

4. Trabajando con repositorios existentes

4.1. Clonar un repositorio existente

4.2. Resolución de conflictos

4.3. Corregir el commit anterior


5. Introducción a Github

5.1. Crear una cuenta en Github

5.2. Administración de repositorios via web

5.3. Cliente gráfico de git para Mac y Windows

5.4. Documentación en Markdown


6. Trabajo colaborativo en Github

6.1. Fork

6.2. Pull requests

6.3. gist

6.4. Github Pages

6.5. Wikis


Got 15 minutes and want to learn Git?

try-git by CodeSchool and Github

Referencias