43
loading...
This website collects cookies to deliver better user experience
7f347041e695151cbe8493b8ed842949150095c4
. Muchas veces, por no llenar la pantalla con claves largas, se suele usar la una clave abreviada, por ejemplo 7f34704
, que vienen a ser los primeros caracteres de la clave hash. Nada garantiza que una clave abreviada sea única, pero si se detecta que esta repetida solo hay que mostrar más caracteres, hasta que deje de haber conflicto, por ejemplo 7f347041e
.# Acabo de hacer un commit con un error en el texto.
$ git commit -m "mi tercre commit"
[master 7f34704] mi tercre commit
1 file changed, 1 insertion(+)
# Para cambiarlo
# Primero me aseguro de que no haya ningún cambio en el área de stage.
$ git status
En la rama master
Cambios a ser confirmados:
(usa "git reset HEAD <archivo>..." para sacar del área de stage)
modificado: dates.txt
# Si los hay los saco del área de stage.
$ git reset HEAD dates.txt
Cambios fuera del área de stage tras el reset:
M dates.txt
# Y modifico el mensaje del commit.
$ git commit --amend -m "mi tercer commit"
[master 19ffda6] mi tercer commit
1 file changed, 1 insertion(+)
7f34704
, por otro con el mismo contenido, pero con otro mensaje y hash 19ffda6
.git commit --amend -m
, es importante asegurarse qué se va a commitear para no incluir nada que se desee.077c45d
, se podría hacer algo como esto# La virgulilla es importante
$ git rebase -i 077c45d~
# Se abrirá un editor de texto con algo como
##--------------
pick 077c45d mi segunod commit
pick 19ffda6 mi tercer commit
# Rebase bced58d..11a0995 en bced58d (2 comandos)
#
# Comandos:
# p, pick = usar commit
# r, reword = usar commit, pero editar el mensaje
# ....
## ----------------
# Edito el archivo para tener
r 077c45d mi segundo commit
pick 19ffda6 mi tercer commit
## Guardo.
## Se abre un editor de texto con el mensaje a modificar,
## escribo el texto correcto y guardo.
077c45d
, por otro con el mensaje correcto y un nuevo hash, así como todos los commits que vengan después.$ git log --pretty=format:"%h %s" --graph
* 52190c2 mi tercer commit
* 247f469 mi segundo commit
* bced58d first commit
19ffda6
hayan cambiado, si ha cambiado el commit que venía antes que él, y por lo tanto ha hecho falta reemplazarlo para reflejar ese cambio.git revert <hash a deshacer>
, o en el GUI, click derecho en el commit a deshacer, y "Revert commit".git revert
no elimina el commit objetivo, si no que crea un commit con cambios para deshacer el commit objetivo.git revert
? Se puede hacer un git revert
de ese commit.git revert --no-commit <hash a deshacer>
, revisar el "revert commit" y git commit
$ git log -1 73d8766 --patch-with-stat
commit 73d8766f13198c5da71e2759b1c659f5c5a3bf8a (HEAD -> master)
commit con error
---
log.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/log.txt b/log.txt
index f14e7df..7c5c54a 100644
--- a/log.txt
+++ b/log.txt
@@ -1,5 +1,6 @@
dom may 24 16:17:36 CEST 2020: log
+esto no es un log
dom may 24 16:17:37 CEST 2020: log
$ git revert 73d8766
[master e9bac4c] Revert "commit con error"
1 file changed, 1 deletion(-)
$ git log -1 e9bac4c --patch-with-stat
commit e9bac4c003bc41640c29a12b21b70a5eb0d99193 (HEAD -> master)
Revert "commit con error"
This reverts commit 73d8766f13198c5da71e2759b1c659f5c5a3bf8a.
---
log.txt | 1 -
1 file changed, 1 deletion(-)
diff --git a/log.txt b/log.txt
index 7c5c54a..f14e7df 100644
--- a/log.txt
+++ b/log.txt
@@ -1,6 +1,5 @@
dom may 24 16:17:36 CEST 2020: log
-esto no es un log
dom may 24 16:17:37 CEST 2020: log
$ git revert 5139b956
error: el commit 5139b9560d954dd0c20320ecb3bac404e8bee7dc es una fusión pero no se proporcionó la opción -m.
fatal: falló al revertir
git reset <hash>
hará que todo sea como en el commit de indicado, incluido el histórico de commits. git revert
tiene varios modos:--soft
deja todos los cambios como staged.--mixed
(el modo por defecto) deja todos los cambios como unstage o untracked.--hard
descarta todos los cambios. Hay que intentar hacerlo solo cuando se este seguro, porque no siempre es posible recuperar todos los cambios. Para más detalles ver Deshacer un git reset.--merge
, nunca he llegado a entenderlo...--keep
, nunca he llegado a entenderlo...--soft
y --mixed
no es apreciable, ya que el GUI hace su magia por debajo y el resultado final es el mismo; si se usa consola, con --soft
se podría hacer directamente un commit con todos los cambios, sin tener que añadir los archivos con git add
, mientras que con --mixed
si habría que hacerlo.# Consulto el histórico de commits.
$ git log --pretty=format:"%h %s" --graph
* b2cd87b mi tercer commit
* 247f469 mi segundo commit
* bced58d first commit
$ git reset --hard bced58d
HEAD is now at bced58d reset
$ git log --pretty=format:"%h %s" --graph
* bced58d first commit
git reset master
, para así hacer que el commit de destino sea el último commit de la rama master.git reset --hard
se pueden perder dos cosas:git reset
al punto del que que se veníagit reflog
muestra un histórico de todos los commits por los que sea ha pasado, ya sea porque se ha hecho un commit, se ha cambiado de rama, o se ha hecho un git reset
. fc2f7e1 HEAD@{1}: commit: amazing stuff
fc2f7e1
: es el hash del commit por el que se ha pasado.HEAD@{1}
: es un alias algo más amigable de ese hash. El indice indica hace cuando se produjo el cambio, siendo HEAD{0}
el punto actual, HEAD{1}
el punto anterior, HEAD{2}
lo que vino antes, etc.
Estos alias no son constantes, si por ejemplo se hiciese otro git reset
u otro git commit
, HEAD{1}
pasaría a referenciar lo que referenciase HEAD{0}
antes del cambio y sucesivamente.# Partiendo de un repositorio a estrenar.
$ git log --pretty=format:"%h %s" --graph
* 00fd1f0 inicializar repo
# Hago algunos cambios en el proyecto y hago commit.
$ git commit -am "amazing stuff"
[master fc2f7e1] amazing stuff
1 file changed, 1 insertion(+), 1 deletion(-)
# Hago un git reset por alguna razón.
$ git reset --hard 00fd1f0
HEAD is now at 00fd1f0 inicializar repo
# Reviso el histórico y me doy cuenta de que he perdido
# cosas por error.
$ git log --pretty=format:"%h %s" --graph
* 00fd1f0 inicializar repo
$ git reflog
00fd1f0 (HEAD -> master) HEAD@{0}: reset: moving to 00fd1f0
fc2f7e1 HEAD@{1}: commit: amazing stuff
00fd1f0 (HEAD -> master) HEAD@{2}: commit (initial): inicializar repo
# Hago reset al punto al que quiero volver.
$ git reset --hard HEAD@{1}
HEAD is now at fc2f7e1 amazing stuff
$ git log --pretty=format:"%h %s" --graph
* fc2f7e1 amazing stuff
* 00fd1f0 inicializar repo
git push
; quedará un commit de más en la rama (se si usa git merge--squash
ni siquiera eso), pero es una solución rápida y a prueba de errores.# Antes del "Amend commit".
$ git log --pretty=format:"%h %s" --graph
* b2cd87b mi tercer commit
* 247f469 mi segundo commit
* bced58d first commit
# Después del "Amend commit".
$ git log --pretty=format:"%h %s" --graph
* d9822c9 mi tercer commit
* 247f469 mi segundo commit
* bced58d first commit
# Modificao un archivo.
# Revisar el status.
$ git status
En la rama master
Cambios no rastreados para el commit:
(usa "git add <archivo>..." para actualizar lo que será confirmado)
(usa "git checkout -- <archivo>..." para descartar los cambios en el directorio de trabajo)
modificado: dates.txt
# Añado el archivo modificado al área de stage.
$ git add dates.txt
# Hago un commit con la opción ammend para modificar
# el commit y el mensaje.
$ git commit --amend -m "mi tercer commit más un cambio"
[master d9822c9] mi tercer commit más un cambio
1 file changed, 2 insertions(+)
git rebase -i
(ver Cambiar el mensaje de un commit, a parte de pick y reword tiene la opción de editar o borrar un commit. Es una opción que existe, pero intento evitarla ya que es probable que implique resolver conflictos varias veces: si se edita un archivo en un commit antiguo, es probable que ese mismo archivo haya sido editado commits posteriores y habrá resolver conflictos por cada uno de esos commits.git add -p
(o --patch
) y seleccionar que trozos de un archivo se quieren añadir; o con git commit -i
(o --interactive
) , que permite elegir como tratar todos los archivos que se incluirían en el commit al hacer git commit -a
.$ git add -p recursive.php
diff --git a/recursive.php b/recursive.php
index 215ddd0..590b3ac 100644
--- a/recursive.php
+++ b/recursive.php
@@ -1,11 +1,14 @@
<?php
function recursiveFunction(Closure $action, Closure $stopCheck, $data) : void {
+ var_dump($data);
+
if ($stopCheck($data)) {
+ var_dump("stop contidion matched");
return;
}
- $action($data);
+ $data = $action($data);
recursiveFunction($action, $stopCheck, $data);
}
\ No newline at end of file
Stage this hunk [y,n,q,a,d,s,e,?]? ?
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk or any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk or any of the later hunks in the file
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
Stage this hunk [y,n,q,a,d,s,e,?]? s
Split into 3 hunks.
@@ -1,4 +1,6 @@
<?php
function recursiveFunction(Closure $action, Closure $stopCheck, $data) : void {
+ var_dump($data);
+
if ($stopCheck($data)) {
Stage this hunk [y,n,q,a,d,j,J,g,/,e,?]? n
@@ -4,4 +6,5 @@
if ($stopCheck($data)) {
+ var_dump("stop contidion matched");
return;
}
Stage this hunk [y,n,q,a,d,K,j,J,g,/,e,?]? n
@@ -5,7 +8,7 @@
return;
}
- $action($data);
+ $data = $action($data);
recursiveFunction($action, $stopCheck, $data);
}
\ No newline at end of file
Stage this hunk [y,n,q,a,d,K,g,/,e,?]? y
$ git status
On branch test
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: recursive.php
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: recursive.php
$ git diff --staged
diff --git a/recursive.php b/recursive.php
index 215ddd0..b865da0 100644
--- a/recursive.php
+++ b/recursive.php
@@ -5,7 +5,7 @@
return;
}
- $action($data);
+ $data = $action($data);
recursiveFunction($action, $stopCheck, $data);
}
\ No newline at end of file
git cherry-pick
git cherry-pick <hash>
crea un commit que añade exactamente los mismos objetos que los que contiene el commit indicado (para más información ahí va un buen artículo de como se organiza Git por debajo).git cherry-pick -x <hash>
( -x
añade al commit el texto cherry picked from commit <hash>
, lo cual puede ser un buen añadido)# La rama amazing contiene una una interfaz que
# quiero traerme.
(amazing)$ git log -2 --stat
commit c30dd31081fc390465d9ef1a7f3d0a8422d90408 (HEAD -> amazing)
AMAZING: implementación en proceso
src/AmazingImplementation.php | 10 ++++++++++
1 file changed, 10 insertions(+)
commit e10c9b91860d182b4985c843a502de653e44c500
AMAZING: new inteface
src/AmazingInterface.php | 7 +++++++
1 file changed, 7 insertions(+)
# Mi rama actual es comercial, y me traigo los cambios
# que me interesan.
(comercial)$ git cherry-pick -x e10c9b91860d182b4985c843a502de653e44c500
[comercial 1ef28f9] AMAZING: new inteface
1 file changed, 7 insertions(+)
create mode 100644 src/AmazingInterface.php
# Hago algún otro commit.
$ git log -2 --stat
commit f55e27bb46ae08c6dfb97a69e3f9ab4dc2ef18e3 (HEAD -> comercial)
COMERCIAL: Comercial.php
src/Comercial.php | 15 +++++++++++++++
1 file changed, 15 insertions(+)
commit 1ef28f9e31adb6d6191d1b2f224daf5357dd217d
AMAZING: new inteface
(cherry picked from commit e10c9b91860d182b4985c843a502de653e44c500)
src/AmazingInterface.php | 7 +++++++
1 file changed, 7 insertions(+)
# Cuando en el futuro se haga el merge no debería
# haber conflictos...
# a menos que se hayan tocado mucho los archivos en
# las dos ramas.
(master)$ git merge --no-ff amazing
Merge made by the 'recursive' strategy.
src/AmazingImplementation.php | 10 ++++++++++
src/AmazingInterface.php | 7 +++++++
2 files changed, 17 insertions(+)
create mode 100644 src/AmazingImplementation.php
create mode 100644 src/AmazingInterface.php
(master)$ git merge --no-ff comercial
Merge made by the 'recursive' strategy.
src/AmazingInterface.php | 1 +
src/Comercial.php | 15 +++++++++++++++
2 files changed, 16 insertions(+)
create mode 100644 src/Comercial.php
cherry-pick
de archivos que no están en la rama, es que si por ejemplo ese archivo se ha creado en un commit y modificado en otro, y se intenta hacer cherry-pick
de ese último commit, se producirá un conflicto.git cherry-pick -x <hash-primer-commit> <hash-segundo-commit>
<hash-commit-X>
contiene cambios que no queremos, como por ejemplo la clase que implementa la interfaz que queremos traernos?git cherry-pick -x --no-commit <hash-commit-X>
, que lo dejara todo listo para hacer el commit. En ese momento se podría quitar alguno de los archivos que no se quisiesen.# Hay una rama que en uno de sus commits tiene la interfaz
# que me interesa junto con más cosas.
$ git log -2 --stat
commit dbcf29746184e8d9d3969fc4e008a80f140d7df6 (HEAD -> amazing-II)
implementación de método
src/AmazingImplementation.php | 10 ++++++++++
1 file changed, 10 insertions(+)
commit 61b38431b7b6cdcc279515b3467370d1d8cd64ca
añadida interfaz y algo más
log.txt | 3 +++
src/AmazingInterface.php | 6 ++++++
2 files changed, 9 insertions(+)
# Estoy en la rama comercial-II, y me quiero traer
# la interfaz
(comercial-II)$ git cherry-pick -x --no-commit 61b38431b7b6cdcc279515b3467370d1d8cd64ca
# Reviso los cambios.
(comercial-II)$ git status
On branch comercial-II
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: log.txt
new file: src/AmazingInterface.php
# Quito los cambios que no necesito.
(comercial-II)$ git reset HEAD log.txt
Unstaged changes after reset:
M log.txt
# Hago el commit.
(comercial-II)$ git commit -m "añadida solo interfaz"
[comercial-II 16908dd] añadida solo interfaz
1 file changed, 6 insertions(+)
create mode 100644 src/AmazingInterface.php
# Reviso el status, donde veo que tengo cambios que no he
# commiteado y que tendré que quitar.
(comercial-II)$ git status
On branch comercial-II
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: log.txt
no changes added to commit (use "git add" and/or "git commit -a")
# Reviso los cambios que he incluido en el commit.
(comercial-II)$ git log -1 --stat
commit 16908dd4cf9d15e2bf8feafce1d1b3e296f1bede (HEAD -> comercial-II)
Author: claudio <[email protected]>
Date: Sun Aug 23 13:32:11 2020 +0200
añadida solo interfaz
(edited cherry picked from commit 61b38431b7b6cdcc279515b3467370d1d8cd64ca)
src/AmazingInterface.php | 6 ++++++
1 file changed, 6 insertions(+)
cherry-pick
de rangos de commits# la ~ en el primer commit es importante
$ git cherry-pick -x <hash-primer-commit>~..<hash-ultimo-commit>
git commit
? git commit
cuando el archivo no estaba en área de stage o porque cumple alguna de las expresiones del archivo .gitignore
git commit -a
git add <nuevo archivo>
se le dice a Git que lo tiene que registrar; el archivo pasara a estar en el estado tracked y se moverá al área de stage.git commit
se incluirá en el nuevo commit, se sacará del área de stage y pasará a estar no modificado.git commit -a
no registra archivos en estado untracked, y por lo tanto estos no se incluirían en el commit. Hay que incluirlo con git add
. git add <nuevo archivo>
se moverá al área de stage.git commit
se incluirá en el nuevo commit, se sacará del área de stage y pasará a estar no modificado.git commit -a
, así que es posible ahorrarse el git add
.git add
, se vuelve a modificar el archivo y se hace git commit
, los últimos cambios no estarán incluidos en commit.git add
.git status
, tanto antes como después del commit. $ git status
On branch master
nothing to commit, working tree clean
# Creo un archivo.
$ echo "TODO" > README.md
# Git status indicará que hay un archivo nuevo
$ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
README.md
nothing added to commit but untracked files present (use "git add" to track)
# Si intento hacer un commit fallará, ya que README.md
# esta untracked.
$ git commit -m "creación de README.md"
On branch master
Untracked files:
README.md
nothing added to commit but untracked files present
$ git add README.md
# Tras git add README.md pasa a estar tracked y en
# el area de stage.
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: README.md
# Ahora si que es posible hacer commit.
$ git commit -m "creación de README.md"
[master ccd62fa] creación de README.md
1 file changed, 1 insertion(+)
create mode 100644 README.md
$ git status
On branch master
nothing to commit, working tree clean
$ echo "# Introducción" > README.md
$ git status
On branch 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: README.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git add README.md
$ echo "# Instalación" >> README.md
# Los cambios de antes antes de git add están en
# el area de stage; y los de después están fuera.
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README.md
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: README.md
$ git commit -m "añadir secciones"
[master f4df7c2] añadir secciones
1 file changed, 1 insertion(+), 1 deletion(-)
# Al haber hecho el commit sin la opción -a, solo los cambios
# en el area de stage se han incluido en el commit;
# si el commit se hubise hecho con -a, se habrían incluido
# todos los cambios
$ git status
On branch 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: README.md
no changes added to commit (use "git add" and/or "git commit -a")
$ git diff
diff --git a/README.md b/README.md
index 28429bb..ab9e81e 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,2 @@
# Introducci<C3><B3>n
+# Instalaci<C3><B3>n
~/.bashrc
, el prompt incluirá, cuando se esté dentro de un repositorio de Git, la rama actual y un *
si hay cambios pendientes de commitearYELLOW="\[\033[0;33m\]"
GREEN="\[\033[0;32m\]"
LIGHT_BLUE="\[\033[1;34m\]"
WHITE="\[\033[1;37m\]"
COLOR_NONE="\[\e[0m\]"
function parse_git_dirty {
[[ $(git status 2> /dev/null | tail -n1) != "nothing to commit, working directory clean" ]] &&
[[ $(git status 2> /dev/null | tail -n1) != "nothing to commit, working tree clean" ]] &&
[[ $(git status 2> /dev/null | tail -n1) != "nada para hacer commit, el árbol de trabajo está limpio" ]] &&
echo "*"
}
function parse_git_branch {
git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e "s/* \(.*\)/(\1$(parse_git_dirty))/"
}
PS1="$GREEN\u$WHITE@$YELLOW\H:$LIGHT_BLUE\w${COLOR_NONE}\$(parse_git_branch)\$ "