You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.1 KiB
261 lines
7.1 KiB
10 months ago
|
---
|
||
|
weight: 4
|
||
|
title: "Apuntes de Git"
|
||
|
date: 2022-07-28T20:30:52+0200
|
||
|
draft: false
|
||
|
summary: "Pues eso, apuntes sueltos de git"
|
||
|
categories:
|
||
|
- notes
|
||
|
tags:
|
||
|
- git
|
||
|
---
|
||
|
|
||
|
|
||
|
## Detached-HEAD
|
||
|
|
||
|
Lo normal es que te enteres después de hacer uno o varios *commits* en *Detached*
|
||
|
|
||
|
### Con rama temporal
|
||
|
|
||
|
```bash
|
||
|
git branch tmp
|
||
|
git checkout main
|
||
|
git merge tmp
|
||
|
git branch -d tmp
|
||
|
```
|
||
|
|
||
|
### Directamente
|
||
|
|
||
|
```bash
|
||
|
git checkout main
|
||
|
git merge HEAD@{1}
|
||
|
```
|
||
|
|
||
|
## Dejar de seguir un fichero
|
||
|
|
||
|
### Sin borrarlo del directorio de trabajo
|
||
|
|
||
|
1. Primero añadimos el fichero o directorio que quieres ignorar al .gitignore.
|
||
|
2. Ejecutamos:
|
||
|
|
||
|
```bash
|
||
|
git rm -r --cached <file>
|
||
|
git add .
|
||
|
```
|
||
|
|
||
|
Vale para ficheros o directorios, la opción `-r` es para hacerlo recursivo, la opción `--cached` esta para que no borre nada en el _working tree_ solo borra en _index_
|
||
|
|
||
|
__OJO__: Este método borra los ficheros para el resto del equipo cuando hagan un `git pull`
|
||
|
|
||
|
### Queremos hacer modificaciones del fichero en local sin propagarlas al resto del equipo
|
||
|
|
||
|
```bash
|
||
|
git --update-index --skip-worktree <file>
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
## Hacer un merge
|
||
|
|
||
|
1. Asegúrate de completar todas las tareas para dejar lista la rama que vas a fusionar
|
||
|
2. Asegúrate de cambiár a la rama receptora (`git checkout`) y de que estás en ella (`git status`)
|
||
|
3. Actualiza la rama receptora con el _remote_ (puedes usar `git fetch` y `git pull`)
|
||
|
4. Ejecuta el _merge_ con `git merge`
|
||
|
|
||
|
## Borrar submódulo
|
||
|
|
||
|
La forma correcta de hacerlo, conservando el contenido del módulo si es necesario.
|
||
|
|
||
|
```bash
|
||
|
mv a/submodule a/submodule_tmp # keeps a backup of module contents
|
||
|
# do this only if keeping the contents
|
||
|
|
||
|
git submodule deinit -f a/submodule # removes submodule from repo
|
||
|
rm -rf .git/modules/a/submodule # removes submodule reference
|
||
|
git rm -f a/submodule # Note: a/submodule (no trailing slash)
|
||
|
|
||
|
# or, if you want to leave it in your working tree and have done step 0
|
||
|
git rm --cached a/submodule
|
||
|
mv a/submodule_tmp a/submodule
|
||
|
```
|
||
|
|
||
|
|
||
|
## Clonar cuando hay submódulos
|
||
|
|
||
|
La opción `-jn` asigna n recursos para las tareas de clonado.
|
||
|
|
||
|
```bash
|
||
|
git clone --recursive -j8 git://github.com/foo/bar.git
|
||
|
```
|
||
|
|
||
|
## Deshacer un _amend_
|
||
|
|
||
|
Siempre y cuando no la hayas pifiado ya en la historia compartida.
|
||
|
|
||
|
```bash
|
||
|
git reset --soft HEAD@{1}
|
||
|
git commit -C HEAD@{1}
|
||
|
```
|
||
|
|
||
|
La primera orden mueve el _HEAD_ a donde estaba apuntando el _commit_ antiguo. Además dejamos el _index_ intacto para poder hacer otra vez un _commit_ con los cambios pendientes.
|
||
|
|
||
|
`HEAD@{1}` nos da el _commit_ al que _HEAD_ estaba apuntando antes de apuntar al que está apuntando (léelo un par de veces más). No es lo mismo que `HEAD~1` que devuelve el _commit_ padre del _commit_ al que está apuntando _HEAD_.
|
||
|
|
||
|
La segunda sentencia es más retorcida. Significa: _haz un commit del tree actual, usando los detalles del commit erroneo_. Fíjate que `HEAD@{1}` ahora apunta al _commit_ erróneo, puesto que apunta al _commit_ al que apuntaba _HEAD_ antes de apuntar a donde apunta ahora mismo.
|
||
|
|
||
|
## _Revert_ a un _commit_ previo
|
||
|
|
||
|
### _Detached Head_
|
||
|
|
||
|
```bash
|
||
|
git checkout <old-commit-hash>
|
||
|
```
|
||
|
|
||
|
__¡Ojo!__ ahora mismo estás en un _detached head_ es decir no estás en ningún _branch_. Si haces cambios en el _commit_ `<old-commit-hash>` vas a tener muchos problemas. Antes de hacer cambios puedes crear una nueva rama:
|
||
|
|
||
|
```bash
|
||
|
git switch -c <new-branch-name>
|
||
|
```
|
||
|
|
||
|
O volver a donde estabas con `git checkout`
|
||
|
|
||
|
### Con una rama
|
||
|
|
||
|
Si quieres hacer cambios es lo más recomendable:
|
||
|
|
||
|
```bash
|
||
|
git checkout -b old-state <old-commit-hash>
|
||
|
```
|
||
|
|
||
|
### A fuego (quemando las naves)
|
||
|
|
||
|
__Si no tienes nada en la historia compartida__ puedes hacer reset:
|
||
|
|
||
|
```bash
|
||
|
# Perderás todos los cambios locales!
|
||
|
git reset --hard <old-commit-hash>
|
||
|
|
||
|
# Si quieres guardar cambios pendientes
|
||
|
git stash
|
||
|
git reset --hard <old-commit-hash>
|
||
|
git stash pop
|
||
|
# Salvar modificaciones y reaplicar
|
||
|
```
|
||
|
|
||
|
|
||
|
__Si ya has compartido la historia__ tendrás que trabajar con _revert_.
|
||
|
|
||
|
Esta también es la forma más segura y recomendable si quieres conservar la historia completa:
|
||
|
|
||
|
```bash
|
||
|
git revert --no-commit <old-commit-hash>..HEAD
|
||
|
git commit
|
||
|
```
|
||
|
|
||
|
El _flag_ `--no-commit` permite hacer un _revert_ de todos los _commits_ de un golpe, si no lo pasas hará un nuevo _commit_ por cada _commit_ "revertido" y la historia va a quedar un poco enrevesada.
|
||
|
|
||
|
## Cambiar el nombre a una rama
|
||
|
|
||
|
En _Gitlab_ hay que usar _main_ en lugar de _master_.
|
||
|
|
||
|
|
||
|
```bash
|
||
|
git branch -m <New_Branch_Name>
|
||
|
git push origin :<Old_Branch_Name> <New_Branch_Name>
|
||
|
git push --set-upstream origin <New_Branch_Name>
|
||
|
```
|
||
|
|
||
|
|
||
|
## Cambiar de master a main (otro método)
|
||
|
|
||
|
En local:
|
||
|
|
||
|
```bash
|
||
|
git branch -m master main
|
||
|
git status
|
||
|
git push -u origin main
|
||
|
git push origin --delete master
|
||
|
```
|
||
|
|
||
|
Resto del equipo:
|
||
|
|
||
|
```bash
|
||
|
git checkout master
|
||
|
git branch -m master main
|
||
|
git fetch
|
||
|
git branch --unset-upstream
|
||
|
git branch -u origin/main
|
||
|
```
|
||
|
|
||
|
|
||
|
|
||
|
## Crear una nueva rama
|
||
|
|
||
|
```bash
|
||
|
git branch <newbranch_name> # Crea una nueva rama
|
||
|
git checkout <newbranch_name> # Cambia a la nueva rama
|
||
|
git switch <newbranch_name> # También cambia a la nueva rama
|
||
|
git push -u origin <newbranch_name> # Sube la nueva rama al repo remoto
|
||
|
```
|
||
|
|
||
|
Hay otras alternativas:
|
||
|
|
||
|
```bash
|
||
|
git branch <new_branch> ffeeddaa # Crea una rama a partir de un commit
|
||
|
git branch <new_branch> v1.2 # Crea una rama a partir de un tag
|
||
|
git branch --track <new_branch> origin/<base_branch> # Crea una rama a partir de una rama remota
|
||
|
```
|
||
|
|
||
|
## Borrar un fichero con información sensible de la historia del repo
|
||
|
|
||
|
|
||
|
### Usando solo git
|
||
|
```bash
|
||
|
git filter-branch --force --index-filter \
|
||
|
"git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA" \
|
||
|
--prune-empty --tag-name-filter cat -- --all
|
||
|
git push --force --verbose --dry-run
|
||
|
git push --force
|
||
|
```
|
||
|
|
||
|
### Usando git-filter-repo
|
||
|
|
||
|
Es una herramienta escrita en Python (ver [github](https://github.com/newren/git-filter-repo))
|
||
|
|
||
|
|
||
|
## rebase interactive
|
||
|
|
||
|
- <https://jordanelver.co.uk/blog/2020/06/04/fixing-commits-with-git-commit-fixup-and-git-rebase-autosquash/>
|
||
|
|
||
|
|
||
|
## Escribir mensajes de commit significativos
|
||
|
|
||
|
- <https://www.freecodecamp.org/news/how-to-write-better-git-commit-messages/>
|
||
|
|
||
|
**Mis tipos de _commit_**
|
||
|
|
||
|
Para usar con este formato:
|
||
|
|
||
|
```bash
|
||
|
<type>[optional scope]: <description>
|
||
|
|
||
|
[optional body]
|
||
|
|
||
|
[optional footer(s)]
|
||
|
```
|
||
|
|
||
|
|
||
|
| Type | Tipo | Descripción |
|
||
|
|:--|:--|:--|
|
||
|
| dev | desarrollo | Es un _commit_ de desarrollo en las fases iniciales del proyecto |
|
||
|
| fix | fix | Se arregla un _bug_ |
|
||
|
| chore | mantenimiento | El _commit_ no implica ni cambios de código ni de test |
|
||
|
| refactor | | refactorización de código que no arregla un _bug_ ni añade features |
|
||
|
| docs | | Añade o retoca documentación del proyecto |
|
||
|
| style | | Cambios que no afectan el significado del código, probablemente relacionados con el formateado del código, y similares |
|
||
|
| test | | Crea nuevos test o corrige test existentes |
|
||
|
| perf | | mejoras de _performance_ |
|
||
|
| ci | | Relacionados con integración contínua (_continuous integration_) |
|
||
|
| build | | cambios que afecta al _build_ del proyecto, p.ej. cambios de dependencias |
|
||
|
| revert | | Vuelta a un _commit_ previo |
|