Apuntes de Git

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
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.

1
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.

1
2
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

1
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:

1
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:

1
git checkout -b old-state <old-commit-hash>

A fuego (quemando las naves)

Si no tienes nada en la historia compartida puedes hacer reset:

1
2
3
4
5
6
7
8
# 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:

1
2
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.

1
2
3
git branch -m <New_Branch_Name>
git push origin :<Old_Branch_Name> <New_Branch_Name>
git push --set-upstream origin <New_Branch_Name>

Crear una nueva rama

1
2
3
4
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:

1
2
3
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

1
2
3
4
5
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)