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.
Estudiantes, pasantes o egresados de carreras afines a computación, desarrolladores y entusiastas de la programación.
Introducción a los sistemas de control de versiones
Introducción a git
Configuración del cliente git
Trabajando con repositorios existentes
Introducción a Github
Trabajo colaborativo en Github
<Enter>
prog.c prog1.c prog2.c ... prog<n>.c
tarea/prog.cversion_inicial/prog.cmodificado2/prog.cvers-28sep/prog.cProyectoFinal_2017-1_completo(Andres)/prog1.c
Se genera un correo por cada versión enviada
Puede ser tedioso encontrar una versión anterior
Algunos servicios de almacenamiento en la nube permiten regresar a versiones anteriores
Muchos de los servicios gratuitos únicamente permiten un número finito de versiones anteriores
Algunas veces los servicios de almacenamiento quitan las versiones anteriores más antiguas
Se basa en un modelo cliente-servidor
El servidor tiene una copia de todas las versiones del código
Los clientes clonan el repositorio y tienen una copia de trabajo que pueden modificar
Cuando los cambios están listos, los clientes los envían al servidor
Si el servidor falla, se pierden todas las versiones del proyecto
Cada cliente tiene una copia de todas las versiones del proyecto
Si el servidor falla es posible copiar todas las versiones desde un cliente
Es posible establecer estructuras jerárquicas
El desarrollo del kernel Linux entre los años 1991 - 2002 no utilizaba un control de versiones per-se
En 2002 se utilizó un DVCS propietario llamado BitKeeper, que se ofrecía sin costo a los miembros del proyecto
En 2005 la compañía quiso cobrar el uso del software
La comunidad de desarrolladores, incluyendo a Linus Torvalds, optó por desarrollar su propia herramienta
git
presenta tres áreas de trabajo, asociadas con los estados que puede tener un archivo.git
guarda todas las versiones de los archivos del proyectoEstado | 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 |
apt-get
o aptitude
root@debian:~# aptitude install git
yum
[root@centos ~]# yum install git
Para instalar en otras variantes de UNIX ver la documentación oficial
git init
$ 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 repositoriotonejito@linux:~$ cd repositoriotonejito@linux:~/repositorio$ git initInitialized empty Git repository in /home/tonejito/repositorio/.git/tonejito@linux:~/repositorio$ ls -lAtotal 0drwxr-xr-x 7 tonejito users 147 Jun 3 17:16 .git
git init
tonejito@linux:~$ git init otro-repoInitialized empty Git repository in /home/tonejito/otro-repo/.git/tonejito@linux:~$ ls -lA otro-repo/total 0drwxr-xr-x 7 tonejito users 147 Jun 3 17:19 .git
--shared
tonejito@linux:~$ git init --shared=group repo-compartidoInitialized 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 4drwxrwsr-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
Se utiliza el comando git clone
para guardar una copia de un repositorio existente
Es útil cuando se quiere trabajar de manera colaborativa en una aplicación (como el kernel Linux)
El código ṕuede ser modificado y se pueden seguir haciendo commits
Para clonar el repositorio es necesario conocer la URL donde se aloja el proyecto
/path/to/repo.git/
file:///path/to/repo.git/
http[s]://host.xz[:port]/path/to/repo.git/
ftp[s]://host.xz[:port]/path/to/repo.git/
ssh://[user@]host.xz[:port]/path/to/repo.git/
ssh://[user@]host.xz[:port]/~[user]/path/to/repo.git/
git://host.xz[:port]/path/to/repo.git/
git://host.xz[:port]/~[user]/path/to/repo.git/
[user@]host.xz:path/to/repo.git/
[user@]host.xz:/~[user]/path/to/repo.git/
git clone
de la siguiente maneratonejito@linux:~$ git clone https://github.com/tonejito/curso-git.gitCloning into 'curso-git'...remote: Counting objects: 108, done.remote: Compressing objects: 100% , done.remote: Total 108 , reused 0 , pack-reused 65Receiving objects: 100% , 429.40 KiB | 0 bytes/s, done.Resolving deltas: 100% , done.Checking connectivity... done.
curso-git
.git
tonejito@linux:~$ ls -A curso-git/.git .gitignore LICENSE.md presentation.mdimg index.html Makefile README.md
git add
se utiliza para especificar qué archivos incluirá git en el control de versionesman
de git add
muestra las opciones de línea de comandosgit-add - Add file contents to the indexgit 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>...]
README.md
y escribir algún mensaje simple en eltonejito@linux:~/repositorio$ editor README.md
# Mi repositorio de gitAndrés Hernández
git status
para revisar si hay cambiostonejito@linux:~/repositorio$ git statusOn branch masterInitial commitUntracked files:(use "git add <file>..." to include in what will be committed)README.mdnothing added to commit but untracked files present (use "git add" to track)
README.md
al repositorio con el comando git add
tonejito@linux:~/repositorio$ git add README.md
git status
para revisar si hay cambiosOn branch masterInitial commitChanges to be committed:(use "git rm --cached <file>..." to unstage)new file: README.md
Desapareció el mensaje que sugería utilizar git add
(comparar con la lámina anterior)
El cambio aún no está guardado, ver siguiente sección
.git
se utiliza el comando git commit
man
de git commit
muestra las opciones de línea de comandosgit-commit - Record changes to the repositorygit 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>...]
git commit
tonejito@linux:~/repositorio$ git commit README.md
#
serán ignoradascommit
$GIT_EDITOR
, core.editor
, $VISUAL
o $EDITOR
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 |
git commit
y especificar el título del commit en el mismo comandogit log
tonejito@linux:~/repositorio$ touch archivo-para-borrartonejito@linux:~/repositorio$ git add archivo-para-borrartonejito@linux:~/repositorio$ git commit -m "Archivo de prueba para probar git-rm"tonejito@linux:~/repositorio$ git log -n 1commit f552622d1a526ed0471ea260e3b99d1cef0c72f3Author: 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
rm
o borrar mediante el navegador de archivos.git
se utiliza el comando git rm
man
de git rm
muestra las opciones de línea de comandosgit-rm - Remove files from the working tree and from the indexgit rm [-f | --force] [-n] [-r] [--cached] [--ignore-unmatch] [--quiet] [--] <file>...
git rm
borra el archivo del Directorio de trabajo y marca el cambio en el Área de Stagingtonejito@linux:~/repositorio$ ls -ltotal 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.mdtonejito@linux:~/repositorio$ git rm archivo-para-borrarrm 'archivo-para-borrar'tonejito@linux:~/repositorio$ git statusOn branch masterChanges to be committed: deleted: archivo-para-borrar
.git
con git commit
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
se utiliza para mover o renombrar archivos del repositoriomv
o renombrar desde el navegador de archivosman
de git mv
muestra las opciones de línea de comandosgit-mv - Move or rename a file, a directory, or a symlinkgit 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-renombrartonejito@linux:~/repositorio$ git add archivo-para-mover archivo-para-renombrartonejito@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
git mv
moviendo un archivo a otro directorio y renombrando otro archivotonejito@linux:~/repositorio$ mkdir -v directoriomkdir: created directory ‘directorio’tonejito@linux:~/repositorio$ git mv archivo-para-mover directorio/tonejito@linux:~/repositorio$ git mv archivo-para-renombrar archivo-con-otro-nombretonejito@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 rename archivo-para-mover => directorio/archivo-para-mover
origin
y la rama por defecto se llama master
git remote
tonejito@linux:~/repositorio$ git remote add origin https://github.com/tonejito/repositorio.gittonejito@linux:~/repositorio$ git remote -vorigin https://github.com/tonejito/repositorio.git origin https://github.com/tonejito/repositorio.git
git push
de la siguiente maneratonejito@linux:~/repositorio$ git push -u origin masterUsername
git push
tonejito@linux:~/repositorio$ git pushUsername
push.default
git
reconoce cuando se realizan cambios en los archivos del Directorio de trabajo.git
es necesario ejecutar git commit
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 😱 |
git add
(ver siguiente sección)tonejito@linux:~/repositorio$ touch archivo-externotonejito@linux:~/repositorio$ git statusOn branch masterYour branch is up-to-date with 'origin/master'.Untracked files:(use "git add <file>..." to include in what will be committed)archivo-externonothing added to commit but untracked files present (use "git add" to track)
git add
git commit
para guardar el cambiotonejito@linux:~/repositorio$ git add archivo-nuevotonejito@linux:~/repositorio$ git statusOn branch masterChanges to be committed:(use "git reset HEAD <file>..." to unstage)new file: archivo-nuevo
git rm
git commit
para guardar el cambiotonejito@linux:~/repositorio$ git rm archivo-para-borrarrm 'archivo-para-borrar'tonejito@linux:~/repositorio$ git statusOn branch masterChanges to be committed:(use "git reset HEAD <file>..." to unstage)deleted: archivo-para-borrar
git rm
git commit
para guardar el cambiotonejito@linux:~/repositorio$ git mv archivo-para-mover directorio/tonejito@linux:~/repositorio$ git mv archivo-para-renombrar archivo-con-otro-nombretonejito@linux:~/repositorio$ git statusOn branch masterChanges to be committed:(use "git reset HEAD <file>..." to unstage)renamed: archivo-para-renombrar -> archivo-con-otro-nombrerenamed: archivo-para-mover -> directorio/archivo-para-mover
git commit
para guardar el cambiogit checkout <archivo>
tonejito@linux:~/repositorio$ git statusOn branch masterYour 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.htmlno changes added to commit (use "git add" and/or "git commit -a")
git log
se utiliza para visualizar la bitácora de revisiones del proyectotonejito@linux:~/repositorio$ git logcommit be47c1b99c212c0b25d7351c1d9bd8de33c06dd8Author: 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 1b75a81323d5a6befff5d4ddfd3ad3254914c8daAuthor: 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
Author
en la bitácora del repositorio?commit f020486f071bf11053547a86f4a7153b3c950f4bAuthor: Facultad de Ciencias <ciencias@debian8.local>Date: Tue 19 Jan 03:14:08 2038 +0000Título del commitMensaje 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 |
git config
puede corregir esto de manera adecuada 😁tonejito@linux:~$ git config --global core.autocrlf inputtonejito@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 |
git config
para modificar la directiva core.whitespace
-
son excluidosPara establecer el valor de core.whitespace
utilizaremos las siguientes características:
blank-at-eol
, blank-at-eof
y space-before-tab
indent-with-non-tab
y tab-in-indent
cr-at-eol
ya que no se especifica en el valortonejito@linux:~$ git config core.whitespace blank-at-eol,blank-at-eof,space-before-tab,-indent-with-non-tab,-tab-in-indenttonejito@linux:~$ cat .gitconfig[core] ... whitespace = blank-at-eol,blank-at-eof,space-before-tab,-indent-with-non-tab,-tab-in-indent