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

Básico

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.

Temario

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

    1. Local
    2. Centralizado
    3. Distribuido
  2. Introducción a git

    1. Inicializar un repositorio
    2. Clonar un repositorio existente
    3. Agregar archivos
    4. Guardar cambios en el repositorio
    5. Borrar archivos
    6. Mover archivos
    7. Enviar cambios al servidor
    8. Revisar el estado de los archivos en el directorio de trabajo
    9. Bitácora de revisiones del proyecto

Temario (cont)

  1. Configuración del cliente git

    1. Datos del usuario
    2. Reparar fin de línea en los archivos
    3. Ignorar espacios en blanco
  2. Trabajando con repositorios existentes

    1. Clonar un repositorio existente
    2. Resolución de conflictos
    3. Corregir el commit anterior

Temario (cont 2)

  1. Introducción a Github

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

    1. Fork
    2. Pull requests
    3. gist
    4. Github Pages
    5. 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

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

2. Introducción a git

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
root@debian:~# aptitude install git
[root@centos ~]# yum install git

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

$ 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
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
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
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>...]
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
#
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
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
git-rm - Remove files from the working tree and from the index
 
git rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
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
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>
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%)
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)
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
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 😅 🔫 😡 Es necesario hacer merge 😱
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)
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
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 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
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")
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
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
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
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
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

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

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

5. Introducción a Github

6. Trabajo colaborativo en Github

Got 15 minutes and want to learn Git?

try-git by CodeSchool and Github

Referencias