--- 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 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 ``` ## 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 ``` __¡Ojo!__ ahora mismo estás en un _detached head_ es decir no estás en ningún _branch_. Si haces cambios en el _commit_ `` vas a tener muchos problemas. Antes de hacer cambios puedes crear una nueva rama: ```bash git switch -c ``` 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 ``` ### 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 # Si quieres guardar cambios pendientes git stash git reset --hard 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 ..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 git push origin : git push --set-upstream origin ``` ## 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 # Crea una nueva rama git checkout # Cambia a la nueva rama git switch # También cambia a la nueva rama git push -u origin # Sube la nueva rama al repo remoto ``` Hay otras alternativas: ```bash git branch ffeeddaa # Crea una rama a partir de un commit git branch v1.2 # Crea una rama a partir de un tag git branch --track origin/ # 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 - ## Escribir mensajes de commit significativos - **Mis tipos de _commit_** Para usar con este formato: ```bash [optional scope]: [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 |