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 proyecto
| 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 |
apt-get o aptituderoot@debian:~# aptitude install gityum[root@centos ~]# yum install gitPara 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 .gitgit inittonejito@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--sharedtonejito@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 .gitSe 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.gittonejito@linux:~$ ls -A curso-git/.git .gitignore LICENSE.md presentation.mdimg index.html Makefile README.mdgit 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 addtonejito@linux:~/repositorio$ git add README.mdgit 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 commitman 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 committonejito@linux:~/repositorio$ git commit README.md# serán ignoradascommit$GIT_EDITOR, core.editor, $VISUAL o $EDITORCommit 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 logtonejito@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-rmgit rmrm o borrar mediante el navegador de archivos.git se utiliza el comando git rmman 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 committonejito@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-borrargit 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-renombrargit 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 mastergit remotetonejito@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 pushtonejito@linux:~/repositorio$ git pushUsername push.defaultgit 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 addgit 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 rmgit 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 rmgit 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.mdAuthor 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.mxtonejito@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 = inputUn 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-tabindent-with-non-tab y tab-in-indentcr-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