====== 5. Control de versiones ======
En este tema vamos a ver tareas básicas en Git.
Mas información
* [[http://rogerdudler.github.io/git-guide/index.es.html|Git - La guía sencilla]]
* [[http://git-scm.com/book/es|Pro Git]]: Libro
* [[https://github.com/git-tips/tips|Git Tips]]: Muchas recetas de Git
* [[https://medium.com/blue-harvest-tech-blog/git-2-23-0-forget-about-checkout-and-switch-to-restore-ac2682b737b3|Git 2.23.0: Forget about checkout, and switch to restore.]]: Nuevas ordenes ''git restore'' y ''git switch''
* [[https://github.com/tj/git-extras|Git Extras]]: Son //recetas// para hacer cosas con Git
* [[https://git-scm.com/book/en/v2/Git-Tools-Stashing-and-Cleaning|Git Tools - Stashing and Cleaning]]: Guardar cosas temporalmente con ''git stash'' y ''git stash pop''
{{chiste_git.png|}}
{{:clase:daw:daw:1eval:git_chiste2.jpg|}}
{{:clase:daw:daw:1eval:git-command-line.jpg?330|}}
[[https://survey.stackoverflow.co/2022#version-control-vc-interaction|Source:Stack overflow Developer survey 2022]]
Código nuestro que estas en GitHub.
Santificados sean tus commits.
Venga a nosotros tu fetch.
Hágase tu merge tanto en remoto como en local.
Danos hoy nuestro branch de cada día.
Perdona nuestras pulls, así como también nosotros perdonamos a los que nos pushean más rápido;
No nos dejes caer en los conflictos,
y líbranos del checkout.
Amén
---Javier del Moral (2023)
====== Instalando Git ======
Al instalar Git en Windows hay varias opciones a tener en cuenta que explicaremos en clase.
Una vez instalado Git, hay que indicar cual es nuestro nombre y nuestro correo.
git config --global user.name "juan"
git config --global user.email juan@micorreo.com
Por último , si estás en el **instituto** , habrá que configurar el proxy:
git config --global http.proxy http://172.16.0.9:8080
git config --global https.proxy http://172.16.0.9:8080
Para instalar Git en Linux y que sea la última versión usaremos los siguientes comandos (Ya que por ejemplo en Ubuntu 18.04 la versión e un poco //vieja//):
sudo add-apt-repository ppa:git-core/ppa
sudo apt update
sudo apt install git
===== El inicio de Git =====
Los comandos básicos de Git son:
* Para iniciar un directorio y que se pueda usar Git
git init
\\
\\
* Para descargar un repositorio que ya existe
git clone https://github.com/lgonzalezmislata/prueba.git
\\
\\
===== Estados de un fichero =====
* **untracked** o archivos sin seguimiento: Son ficheros que existe en el área de trabajo pero no existen para git
* **staged** o cambios a ser confirmados: Son ficheros modificados que se añadirán al siguiente commit.
* **committed**: Son ficheros que se guardaron en el ultimo commit y que no han sido modificados desde dicho commit.
* **modified** o cambios no rastreados para el commit: Son ficheros que se han modificado desde el último commit pero que aun no se han añadido para el próximo commit.
La //**staged area**// en git también se llama a veces //**cached**// o //**index**//. Es que hay comandos que usan el modificador ''--cached'' para referirse a la //staged area// otros usan ''--staged''
* El comando [[https://git-scm.com/docs/git-rm|git rm]] usa el modificador ''--cached'' para referirse a la //staged area//
* El comando [[https://git-scm.com/docs/git-restore|git restore]] usa el modificador ''--staged'' para referirse a la //staged area//
* El comando [[https://git-scm.com/docs/git-diff|git diff]] usa el modificador ''--cached'' o ''--staged'' para referirse a la //staged area//
^ ^ ''--cached'' ^ ''--staged'' ^
^ ''git rm'' | ✓ | |
^ ''git restore'' | | ✓ |
^ ''git diff'' | ✓ | ✓ |
Por defecto todos los ficheros del anterior commit ya está en el staged area, por eso para quitar un fichero de git hay que borrarlo del staged area. ''git rm --cached fichero''.
{{:clase:daw:daw:1eval:git-estados.png|}}
* Por defecto el comando ''commit'' solo se hace "commit" de los ficheros que estén en la //staging area//.
git commit -m "mensaje"
\\
\\
* Para añadir un fichero a la //staged area// usamos el comando
git add fichero
\\
\\
* Podemos hacer que el comando ''commit'' incluya ademas de los ficheros que están //staged// se incluya ademas todos aquellos ficheros que están //modified// , usaremos el parámetro ''-a'' ( o ''--all'' )
git commit -a -m "mensaje"
{{:clase:daw:daw:1eval:commit-all.png|}}
\\
\\
* Para quitar un fichero de la //staged area//. Es como lo opuesto a ''git add''.
git restore --staged fichero
También se puede usar el comando ''git reset fichero'' pero se creo el nuevo comando ''git restore'' que se puede usar la para hacer lo mismo así que recomendamos usar el comando más nuevo.
\\
\\
* Para borrar un fichero y que ya no esté a partir de ahora en "git". Se usa ''--cached'' para que no se borre del área de trabajo y si solo de la //staged area//.
git rm --cached fichero
También se puede usar el comando ''git rm fichero'' y en ese caso se borra tanto del //staged area// como del //área de trabajo//. No hay forma de borrarlo solo del //área de trabajo// ya que para eso está ''rm'' de Linux.
\\
\\
* Para deshacer los cambios de un fichero que hay en el área de trabajo y se cambie por la versión que hay en el último //commit//.
git restore fichero
También se puede usar el comando ''git checkout fichero'' pero se creo el nuevo comando ''git restore'' que se puede usar la para hacer lo mismo así que recomendamos usar el comando más nuevo.
También se puede añadir el argumento ''--worktree'' de forma que quede ''git restore --worktree fichero'' pero no es necesario ya que se hace por defecto. Pero si se usara ''--staged'' no se modifica el área de trabajo por defecto y en ese caso sería necesario añadirlo.
^ ^ Restaura el fichero en el //área de trabajo// ^ Restaura el fichero en el //staged area// ^
| ''git restore fichero'' | ✓ | |
| ''git restore --worktree fichero'' | ✓ | |
| ''git restore --worktree --staged fichero'' | ✓ | ✓ |
| ''git restore --staged fichero'' | | ✓ |
\\
\\
* Para ver el estado de cada uno de los ficheros
git status
En la rama master
Cambios a ser confirmados:
(usa "git restore --staged ..." para sacar del área de stage)
nuevos archivos: facturas.html
Cambios no rastreados para el commit:
(usa "git add ..." para actualizar lo que será confirmado)
(usa "git restore ..." para descartar los cambios en el directorio de trabajo)
modificados: main.js
Archivos sin seguimiento:
(usa "git add ..." para incluirlo a lo que será confirmado)
cliente.html
\\
\\
Para simplificar el uso de Git se recomienda hacer el ''git add'' justo antes de hace el ''git commit'' ya que sino hacemos los siguiente:
* modificar un ficherio
* ''git add''
* modificar el fichero de nuevo
* Si hacemos ahora un ''git status''. El fichero modificado está a la vez en el estado ''staged'' y ''modified'' 8-o 8-o 8-o 8-o
* ''git commit''
En el commit solo se guardan los primeros cambios y no los segundos. Ya que al hacer el ''git add'' , git se guarda como está el fichero en ese momento y en el ''git commit'' solo se hace como está en ese momento.Aunque si hiciéramos el ''git commit -a'' si que se guardaría el segundo cambio.
Más información:
* [[https://stackoverflow.com/questions/65434544/whats-the-difference-between-git-rm-cached-git-restore-staged-and-gi|What's the difference between 'git rm --cached', 'git restore --staged', and 'git reset']]
===== Sincronización de Git =====
Una misma rama en git puede estar en varios sitios a la vez. El repositorio es el historio donde están todos los //commits// que se han hecho.
{{:clase:daw:daw:1eval:chiste-git-force.jpg?direct|}}
Vamos a explicar cada uno de ellos suponiendo que estamos en la rama ''master''.
* Carpeta local o área de trabajo o árbol de trabajo: Es donde están los ficheros con lo que trabajamos nosotros directamente mientras programamos.
* Repositorio local: Es el repositorio que tenemos en nuestro ordenador.
* Rama **master**:Es donde se guardan al hacer ''commit''
* Rama **origin/master**: Es una copia que hay del repositorio remoto. El nombre de la rama se llama ''origin/master''. Hay que fijarse que hay va todo junto y no con un espacio en medio. Ya es es simplemente el nombre de una rama local nuestra. Solo que es una copia de un remoto llamado ''origin'' de su rama ''master''.
* Repositorio remoto: Es un repositorio que está en otra máquina.
* Rama **master**: Es donde queremos copiar los //commits// de nuestra rama ''master''. Al hacer referencia a una rama de un repositorio remoto, se usara la expresión ''origin master'' con un espacio en medio. Ya que por separado está el nombre del **remote** llamado //origin// y de la rama llamada''master''
{{:clase:daw:daw:1eval:repositorios.png|}}
* Para poner en el área de trabajo una copia del último //commit// de ''master'' que es lo mismo que moverse a la rama ''master''. Tambien se puede usar con un hash de un commit.
git switch master
\\
\\
* Para copiar los //commits// que hay en nuestro repositorio local al repositorio remoto (y también a la copia del repositorio remoto ''origin/master'')
git push
o
git push origin master
\\
\\
* Para copiar lo que hay en el repositorio remoto en una rama local que es después del fetch siempre copia del repositorio remoto, es decir en ''origin/master''.
git fetch
o
git fetch origin master
\\
\\
* Para copiar lo que hay en el repositorio remoto en nuestras ramas locales, es decir en ''master'' y ''origin/master''. Como nuestra rama puede ser distinta, se hace un ''merge'' sobre nuestra rama. **Lo cual es peligroso.**
git pull
o
git pull origin master
El problema es que si hacemos ''git pull origin master'' y estamos en otra rama , se hace un merge de ''origin/master'' en la rama que estemos y eso no suele ser lo que queríamos hacer.
Así que mi recomendación es nunca usar ''git pull'' y usar siempre ''git fetch''.
Recuerda: Nunca uses ''git pull'' y usa siempre ''git fetch''.
\\
\\
* Para //mergear// lo que hay en la rama ''origin/master'' en la rama ''master''.
git merge --ff-only origin/master
\\
\\
==== Remotes ====
El Git un "remote" hace referencia a un servidor de Git donde subimos el código. Por defecto cuando hacemos ''git clone'' se crea un remote llamado ''origin''.
* Para ver la lista de remotes.
git remote -v
origin https://github.com/lgonzalezmislata/prueba.git (fetch)
origin https://github.com/lgonzalezmislata/prueba.git (push)
\\
\\
* Para añadir un nuevo remote
git remote add nombreminuevoremote https://www.otroservidor.com/lgonzalezmislata/prueba.git
Una vez creado el remote ''otroservidor'' ya podremos usarlo en los comandos ''git push'', ''git fetch'' o ''git pull'' además de usar ''origin''
===== Borrado de commits =====
El comando ''git reset '' vuelve a un commit anterior y **borrando** todos los siguientes.
* Volver a un commit anterior y **borrando** todos los posteriores pero modificando el //área de trabajo// al dejar ahí los ficheros del commit y vaciando la //staged area//.
git reset --hard 0d588ed
\\
\\
* Volver a un commit anterior y **borrando** todos los posteriores pero sin modificar ni el //área de trabajo// ni la //staged area//.
git reset --soft 0d588ed
\\
\\
* Volver a un commit anterior y **borrando** todos los posteriores , sin modificar ni el //área de trabajo// pero vaciando la //staged area//.
git reset --mixed 0d588ed
\\
\\
* Si queremos deshacer el último commit (es decir como si no hubiéramos lanzado el comando ''git commit'') se usa la siguiente orden. Ya que ''HEAD'' es el //nombre// del último commit y ''HEAD~1'' el del penúltimo commit.
git reset --soft HEAD~1
\\
La siguiente tabla resume lo que hace cada modificador:
^ ^ Borra los commits siguientes ^ Se modifica área de trabajo ^ Modifica staged area ^
^ --hard | Si | Si | Si |
^ --mixed | Si | No | Si |
^ --soft | Si | No | No |
\\
Ejemplos de como hacer un commit y lo que se necesita hacer después de borrarlo
^ ^ soft ^ mixed ^ hard ^
^ Hacer el commit |
vi fichero
git add fichero
git commit -m "mensaje malo"
|
vi fichero
git add fichero
git commit -m "mensaje malo"
|
vi fichero
git add fichero
git commit -m "mensaje malo"
|
^ Borrar el commit |
git reset --soft HEAD~1
|
git reset --mixed HEAD~1
|
git reset --hard HEAD~1
|
^ Rehacer el commit |
git commit -m "mensaje bueno"
|
git add fichero
git commit -m "mensaje bueno"
|
vi fichero
git add fichero
git commit -m "mensaje bueno"
|
\\
\\
Mas información en:
* {{deshaciendo-cambios-en-git.pdf|Deshaciendo cambios en git}}
* [[https://git-scm.com/book/en/v2/Git-Basics-Undoing-Things|2.4 Git Basics - Undoing Things]]
* [[https://styde.net/deshaciendo-cosas-en-git/|Deshaciendo cosas en Git]]
* [[https://devconnected.com/how-to-git-reset-to-head/|How To Git Reset to HEAD]]
===== Deshacer commits =====
Una vez que hemos subido un commit a GitHub es una muy mala práctica borrar un commit sin embargo si queremos deshacer algo , podemos usar ''git revert ''.
* Se hace un nuevo commit que deshace el último commit
git revert HEAD~1
* Prepara un nuevo commit que deshace el último commit pero sin realmente hacer el commit. Lo que hace el modificar los ficheros y añadirlos a la //staged area//.Después se hace el commit.
git revert --no-commit HEAD~1
git commit -am "Mensaje de commit"
La opción ''--no-commit'' es útil porque nos permite revisar que va a hacer el commit y nos permite hacer alguna modificación más.
Si no estamos interesados en hacer el commit lo podemos abortar con ''git revert --abort'' o usar el ya conocido ''git restore --staged --worktree fichero''.
En caso de un conflicto se deberá resolver el conflicto en el fichero, hacer el ''git add '' y por último ya hacer el commit.
La diferencia entre ''git revert'' y ''git reset'' es que ''git revert'' crea un nuevo commit que deshace el trabajo de otro commit , mientras que ''git reset'' borra realmente los commits.
* Estado inicial de
%%{init: { 'logLevel': 'debug', 'theme': 'default','themeVariables': { 'git0': '#6D97CA','git1': '#00ffff' }, 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'master','rotateCommitLabel': false}} }%%
gitGraph
commit id: "A"
commit id: "B"
commit id: "C"
* Si hacemos un ''git revert C'' quedará así
%%{init: { 'logLevel': 'debug', 'theme': 'default','themeVariables': { 'git0': '#6D97CA','git1': '#00ffff' }, 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'master','rotateCommitLabel': false}} }%%
gitGraph
commit id: "A"
commit id: "B"
commit id: "C"
commit id: "Revert C"
* Si hacemos un ''git reset --hard B'' quedará así
%%{init: { 'logLevel': 'debug', 'theme': 'default','themeVariables': { 'git0': '#6D97CA','git1': '#00ffff' }, 'gitGraph': {'showBranches': true, 'showCommitLabel':true,'mainBranchName': 'master','rotateCommitLabel': false}} }%%
gitGraph
commit id: "A"
commit id: "B"
===== Moverse por git =====
En git podemos //movermos// a otras ramas o a otros commit. Para movernos se usa el comando ''git switch''.
También se puede usar el comando ''git checkout'' pero se creo el nuevo comando ''git switch'' que se puede usar la para hacer lo mismo así que recomendamos usar el comando más nuevo.
==== Ramas ====
Para movernos por ramas solo hay que indicar el nombre de la rama
git switch develop
Si la rama es del tipo ''origin/nombre_rama'' hay que indicar ''--detach'' ya que sobre esa rama no se pueden crear commit puesto que esa rama viene del remoto con ''git fetch''
git switch --detach origin/develop
==== Commits ====
Podemos movernos a un commit anterior de forma que los ficheros de ese commit estén en nuestro directorio de trabajo. El lanzar esta orden no modifica ningún commit.Su utilidad es ver como estaba el código en estados anteriores. Hay que indicar ''--detach'' ya que sobre commit no se pueden añadir más commits yaque ya están añadidos ya que es un commit que está a mitad del arbol de git.
git switch --detach 2308b63
\\
\\
Si ahora lanzamos el comando ''git status'' se mostrará lo siguiente
HEAD desacoplada en 2308b63
nada para hacer commit, el árbol de trabajo está limpio
El significado de **HEAD desacoplada** o **HEAD detached** es que ahí no podemos trabajar, no pudiendo hacer nuevos commits desde ahí aunque si que podríamos hacer una nueva rama.
* Para volver al commit último de la rama solo hay que poner el nombre de la rama en vez de un commit
git switch master
===== Configuración =====
==== .gitkeep ====
Por defecto Git no sube las carpetas vacías, por lo que si queremos que las suba hay que añadir algún fichero. Por convención se suele crear un fichero llamado ''.gitkeep'' y al ya haber algún fichero, git subirá esa carpeta.
==== .gitignore ====
El fichero ''.gitignore'' permite indicar que carpetas no se deben subir a git. El fichero debe estar en el raíz del proyecto de git.
* Por ejemplo para que no se suba el fichero ''node_modules'' hay que crear el fichero ''.gitignore'' con la siguiente línea:
/node_modules
==== Almacenando contraseñas ====
Normalmente trabajamos siempre en nuestro ordenador y no queremos todas las veces volver a poner la contraseña. En ese caso se puede decir a git que la almacene y no nos la vuelva a pedir:
\\
* No te vuelve a pedir la contraseña en 15 min
git config --global credential.helper cache
\\
* Almacena la contraseña en el disco en texto plano y nunca mas te la vuelve a pedir.
git config --global credential.helper store
===== Stash =====
Hay veces que queremos guardar temporalmente los cambios para después volver a ellos, por ejemplo si queremos cambiar de rama.
git contiene una orden para hacer eso que es ''git stash''.
* Guardar solo lo modificado (estén o no en el //staged area//)
git stash push
* Guarda todos los ficheros aunque NO estén en la //stage area//. Es decir, también los ficheros nuevos. Y al hacer el ''pop'' se restaura el estado en el staged area.
git stash push --include-untracked
^ ^ //Por defecto// ^ ''--include-untracked'' ^ ''--all'' ^
| Los ficheros modificados (estén o no en el //staged area//) | ✓ | ✓ | ✓ |
| Los ficheros nuevos | | ✓ | ✓ |
| Los ficheros ignorados | | | ✓ |
Y si luego queremos recuperar los cambios se hace con:
git stash pop
* Pero en el caso de hubiera algo en el //staged area// se tendría que hacer con el argumento ''--index'' para que restaure el //staged area//
git stash pop --index
===== Log =====
El comando ''git log'' permite ver el histórico de commits
* Ver los commits en una única línea cada commit
git --no-pager log --pretty=oneline
\\
\\
* Ver los commits indicando que campos queremos mostrar e indicando el formato de la fecha. Los campos a mostrar se pueden ver en [[https://devhints.io/git-log-format|Git log format string cheatsheet]]. El formato de fecha se puede ver en [[http://man7.org/linux/man-pages/man3/strftime.3.html|strftime]] o en [[https://devhints.io/strftime|strftime format cheatsheet]]
git --no-pager log --pretty=tformat:"%h %cn %cd %s" --date=format:"%d/%m/%Y %H:%M:%S"
\\
\\
**Campos a mostrar**
{{:clase:daw:daw:1eval:git-log-format.png?direct|}}
**Formato de Fechas**
{{:clase:daw:daw:1eval:strftime.png?direct|}}
===== Mensajes de commit =====
Los mensajes de commit deben seguir el siguiente formato:
type(#issue):titulos
Explicación (opcional)
Siendo
* ''type''
* feat: Si se añade una nueva funcionalidad (feature)
* fix: Si se arregla (fix) un error
* docs: Si solo cambia cosas de la documentación
* style: Si solo se cambia el estilo del código como tabuladores, puntos y comas, formateo, etc.
* refactor: Si se cambia el código para mejorar su calidad pero sin modificar la funcionalidad. Eso se llamada refactorizar.
* test: Si se cambian cosas relacionadas con test automáticos.
* chore: Si se cambian cosas relacionadas con el despliegue.
* ''#issue'': Es el Nº de la incidencia a la que hace referencia. Mas información sobre los issues de GitHub: [[https://guides.github.com/features/issues/|aquí]]
Vamos ahora unos ejemplos:
* Se arregla el fallo 45 que se llama "Falla si la fecha está vacía"
fix(#45):Falla si la fecha está vacía
\\
\\
* Se añade la nueva funcionalidad llamada "Mostrar el listado de los pacientes" con Nº 456
feat(#456):Mostrar el listado de los pacientes
El listado se ha hecho en HTML en vez de generar un PDF.
\\
\\
Mas información:
* [[https://github.com/logongas/styleguide-git-commit-message/blob/master/README.md|Git Commit Message StyleGuide]]
* [[http://chris.beams.io/posts/git-commit/|How to Write a Git Commit Message]]
* [[https://docs.google.com/document/d/1QrDFcIiPjSLDn3EL15IJygNPiHORgU1_OOAqWjiDU5Y|Git Commit Message Conventions en el proyecto de AngularJS]]
* [[http://365git.tumblr.com/post/3308646748/writing-git-commit-messages|Writing Git commit messages]]
* [[http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html|A Note About Git Commit Messages]]
* [[https://gitmoji.carloscuesta.me/|GitMoji]]
===== Ejercicios =====
Para todos los ejercicios de este tema, se usarán los comandos de Git siempre que sea posible y los mensajes de los commits deberán seguir el formato explicado en clase.
==== Ejercicio 1 ====
* En tu ordenador instala Git y configura el usuario y el correo que usará Git.
* En una carpeta vacía inicializala para poder usar Git.
* Crea 3 ficheros y haces un commit con ellos. Los ficheros se llamarán
* index.html
* index.js
* main.css
* Haz otro commit con lo siguiente:
* Modificación de index.html
* Nuevo fichero cal.js
* Modifica 3 ficheros pero que en el commit solo sea con dos de los ficheros modificados.
* Deshaz los cambios del fichero que estaba modificado pero que no se incluyó en el commit.Y mira como está el estado de Git
* Crea un nuevo fichero , modifica otro y haz que si se hiciera un commit se incluyeran esos ficheros (pero no hagas el commit). Y mira como está el estado de Git
* Haz que los dos ficheros anteriores ahora no se incluyan si se hiciera el commit (pero no hagas el commit). Y mira como está el estado de Git
* Haz que el fichero index.html se borre de git
Siempre antes de cada commit deberás lanzar el comando ''git status'' para ver el estado de los ficheros.
==== Ejercicio 2 ====
En este ejercicio vamos a tener 2 carpetas que estarán "apuntando" al mismo repositorio de Git. Las carpetas las vamos a llamar "A" y "B".
* Crea una cuenta en Github
* Crea un repositorio llamado "banco" y al crearlo, indica que haya un fichero README.
* Desde la carpeta "A", clona el repositorio.
* Desde la carpeta "B", clona el repositorio.
* Desde la carpeta "A", crea 2 ficheros y haz un commit. Sube el commit a GitHub.
* Desde la carpeta "B", comprueba que no están los ficheros.
* Desde la carpeta "B", baja los cambios con "pull" y comprueba que ya están los cambios en el área de trabajo.
* Desde la carpeta "A", crea otros 2 ficheros y haz un nuevo commit. Sube el commit a GitHub.
* Desde la carpeta "B", baja los cambios con "fetch y merge" y comprueba que ya están los cambios en el área de trabajo.
* Desde la carpeta "A", crea otros 2 ficheros y haz un nuevo commit. Sube el commit a GitHub.
* Desde la carpeta "B", baja los cambios **UNICAMENTE** con "fetch" y comprueba que **NO** están los cambios en el área de trabajo.
* Desde la carpeta "B", ves a la rama "origin/master" y comprueba que ya están los cambios en el área de trabajo.
* Desde la carpeta "B", ves a la rama "master" y comprueba que **NO** están los cambios en el área de trabajo.
* Desde la carpeta "B", haz un merge de "origin/master" a "master" y comprueba que ya están los cambios en el área de trabajo.
==== Ejercicio 3 ====
* En una carpeta vacía inicializala para poder usar Git.
* Crea otros 2 ficheros y haz un nuevo commit.
* Crea otros 2 ficheros y haz un nuevo commit.
* Crea otros 2 ficheros y haz un nuevo commit.
* Crea otros 2 ficheros y haz un nuevo commit.
* Muestra el histórico de commits haciendo que solo salga el hash abreviado ,la fecha del commit en formato "YYYY-MM-DD", el nombre de la persona que hace el commit y el mensaje del commit.
* Borra los dos últimos commits. Y muestra ahora de nuevo el histórico como en el paso anterior.
* Haz que en el area de trabajo se muestren los ficheros del primer commit que hiciste.
* Haz que en el area de trabajo se muestren los ficheros del último commit que hay.
* Crea otros 2 ficheros y haz un nuevo commit.
* Modifica el commit que acabas de hacer para cambiar el mensaje del commit (deberás borrar el commit pero sin tocar los ficheros del area de trabajo).
* Modifica un fichero , añade un fichero y y haz un nuevo commit.
* Modifica el commit que acabas de hacer para añadir un tercer fichero.
==== Ejercicio 4 ====
Crea un nuevo proyecto de NodeJS y haz lo siguiente:
* Que esté el ''index.js''
* Instala alguna librería en la carpeta ''node_modules''
* Crea la carpeta ''dist'' pero que esté vacia.
* Que sea un proyecto de Git
Modifica el proyecto de Git de forma que no se suba la carpeta ''node_moules'' y si que se suba la carpeta ''dist''