pop-lo e salvá-lo novamente com um nome diferente?
Bartlomiej Lewandowski
5
Estocar e ocultar novamente nem sempre é uma opção, pois o stash pode ser baseado em um estado desatualizado e resultar em conflitos durante o popping. (O estado desatualizado nem sequer tem de existir em qualquer lugar na história mais.)
Tom
Respostas:
259
Vamos supor que sua lista stash seja assim:
$ git stash list
stash@{0}: WIP on master: Add some very important feature
stash@{1}: WIP on master: Fix some silly bug
Primeiro, você deve remover a entrada stash que deseja renomear:
$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)
Agora basta adicioná-lo novamente com nova mensagem usando sha of commit retornado após o drop:
$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db
E é isso:
$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature
Esta solução requer o git 1.8.4 ou posterior e, sim, também funciona com o diretório de trabalho sujo.
git show stash@{0}ainda mostra as informações antigas posteriormente. Como consertar isso? (Por favor, note que o esconderijo, em seguida, recebe um SHA diferente.)
Tino
4
É melhor começar com o hash git showe começar git stash store. Então, com git stash listvocê verá o velho e o novo esconderijo. Finalmente, você pode limpar o esconderijo antigo git stash drop.
Hogi 5/07
6
o git stash drop não perderá as alterações?
Shravya Boggarapu
4
@ShravyaBoggarapu, não, o git não remove o commit até que git gcseja executado. Depois de stash dropencontrar facilmente esse commit normalmente inacessível usando o git fsck | grep commitcomando
Qzb 21/07
2
@ ÐerÆndi simplesmente aplicar e salvar é uma opção fácil, mas não funciona quando as alterações não podem ser reaplicadas devido a conflitos. Enquanto isso, soltar e armazenar obras em qualquer circunstância. Testei minha solução mais uma vez - ela funciona muito bem na versão mais recente do git (2.17.0).
Qzb 17/04
62
A menos que você faça isso manualmente ou contribua com uma melhoria no Git, você pode usar um alias:
Com [save options]qualquer opção de git stash save:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Exemplo:
$ git stash list
stash@{0}: On master: Pep8 format
stash@{1}: On master: co other than master with local changes
stash@{2}: On master: tests with deployAtEnd
# Let's say I want to rename the stash@{2} adding an issue reference:
$ git stash-rename stash@{2} NXP-13971-deployAtEnd
$ git stash list
stash@{0}: On master: NXP-13971-deployAtEnd
stash@{1}: On master: Pep8 format
stash@{2}: On master: co other than master with local changes
Isso funcionará mesmo se você tiver alterações locais sem etapas :)
Impressionante! Ainda mais legal se você pudesse fazergit stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
mikemaccana
3
então a resposta é 1) cópia de trabalho limpa, 2) aplique o stash que você deseja renomear, 3) remova-o da lista de stash, 4) crie um novo stash com a mensagem correta.
Gcb
2
Para esclarecer, você está renomeando o último stash e, após essa ação, ele se torna o stash superior?
Onebree
2
Excluo o stash para renomear, salve as alterações atuais, se houver, recrie o stash excluído com o nome desejado, reaplique as alterações atuais, se houver.
Julien Carsique
3
Esta versão verifica se os dois argumentos estão lá, para que não solte seu último esconderijo acidentalmente. Também requer apenas o número do stash, não toda a stash@{0}referência. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
jdforsythe
6
É muito simples. Primeiro, desfaça o último estoque com:
git stash pop
Depois disso, você pode salvar o stash com um nome personalizado desta maneira:
Implemente um novo git reflog updatecomando que atualize a mensagem associada a uma entrada de reflog específica. Para fazer isso, uma nova update_reflog_ent()função (em reflog.c ) alteraria a mensagem associada à entrada de reflog específica para atualização. Uma update_reflog()função usaria for_each_reflog_ent()com update_reflog_entpara realmente fazer a alteração.
Um git stash renamecomando precisaria apenas chamar git
reflog updatecom a referência apropriada e a nova mensagem.
Ou você pode, é claro, abrir o esconderijo e fazer uma git stash save [message]
Se você não apenas deseja corrigir a mensagem stash e também deseja corrigir a mensagem de confirmação da stash, de forma que
git stash list
e
git log --oneline -1 stash
ambos concordam com o que é mostrado, você precisa de um pouco mais. Pode haver uma maneira melhor de fazer isso, mas espero que essa receita aqui seja fácil de entender.
Para poder fazer isso, git commit --amendvocê precisa estar na ponta de uma ramificação. Portanto, a solução é:
git checkout -b scratch stash@{1}
git stash drop stash@{1}
git commit --amend -m "$MESSAGE"
git stash store -m "$MESSAGE" HEAD
git checkout master
git branch -D scratch
Explicado:
Crie um novo ramo "scratch" (ainda não existente) a partir do "stash in question" e mude para ele
Retire o esconderijo antigo. Isso é seguro, pois ainda temos isso no ramo.
Use git commit --amendpara substituir a mensagem de confirmação, alterando o SHA do "stash in question"
Voltar (que assume que você veio de "mestre") e limpeza
Desvantagens:
Isso alterna ramificações temporariamente. Portanto, esta receita só pode ser aplicada quando git status --porcelainestiver limpa (leia-se: não gera nada)
Ele renumera os stashes, para que o stash alterado se torne stash@{0}
Você precisa inserir $MESSAGEduas vezes ou usar alguma variável de ambiente (no exemplo MESSAGE:)
Você precisa encontrar um nome de filial não utilizado
Existem maneiras de fazer isso sem alternar ramificações, mas isso está além do escopo desta resposta.
Exemplo
git init scratch
cd scratch
for a in A B C D; do date >$a; git add $a; git commit -m $a; done
for a in X Y; do echo $a > Z; git stash save --all; done
git log --oneline --graph --decorate --all; git stash list
Resultado
*-. e0e281b (refs/stash) WIP on master: 8bdcc32 D
|\ \
| | * 4d62f52 untracked files on master: 8bdcc32 D
| * 096f158 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: WIP on master: 8bdcc32 D
stash@{1}: WIP on master: 8bdcc32 D
Agora, sem alterar o commit (observe: o SHA a seguir será diferente ao seu lado):
git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list
Resultado
*-. 2fbf900 (refs/stash) WIP on master: 8bdcc32 D
|\ \
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D
Como você pode ver, stash@{0}ainda é mostrado como 2fbf900 (refs/stash) WIP on master: 8bdcc32 Dem git log. Se você observar atentamente, verá que vários commits alteraram o SHA. Isso ocorre devido à maneira como os stashes são manipulados (os pais são incluídos no SHA e os stashes têm seus stashes como pais).
Conserte isso:
git checkout -b scratch stash
git stash drop
git commit --amend -m ...changed...
git stash store -m ...changed... HEAD
git checkout master
git branch -D scratch
git log --oneline --graph --decorate --all; git stash list
Resultado
*-. 4d55186 (refs/stash) ...changed...
|\ \
| | * 246dc5c untracked files on master: 8bdcc32 D
| * 80c5ea0 index on master: 8bdcc32 D
|/
* 8bdcc32 (HEAD, master) D
* c84c659 C
* 49bb2da B
* b1852c6 A
stash@{0}: ...changed...
stash@{1}: WIP on master: 8bdcc32 D
Como você também pode ver, o refs/stashSHA também mudou.
Vale mencionar: isso destrói o índice que foi salvo com o stash original, substituindo-o por um novo índice que corresponda ao commit pai do stash original. Se alguém não planeja usar o índice salvo original (ou já correspondeu ao pai do stash original), isso não é um problema.
torek 01/06/19
1
Aqui está uma versão modificada do alias de Julien que permite lidar adequadamente com o On <branch>prefixo geralmente anexado aos nomes escondidos:
repo[master] % touch tmp && git add tmp && git stash save first
Saved working directory and index state On master: first
HEAD is now at bd62064 Initial commit
repo[master] % touch tmp && git add tmp && git stash save second
Saved working directory and index state On master: second
HEAD is now at bd62064 Initial commit
repo[master] % git stash list
stash@{0}: On master: second
stash@{1}: On master: first
repo[master] % git stash-rename renamed
stash@{0}: On master: renamed
stash@{1}: On master: first
repo[master] % git stash-rename also-renamed stash@{1}
stash@{0}: On master: also-renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-changed stash@{0} new-branch
stash@{0}: On new-branch: branch-changed
stash@{1}: On master: renamed
repo[master] % git stash-rename branch-name-persists
stash@{0}: On new-branch: branch-name-persists
stash@{1}: On master: renamed
repo[master] % git stash-rename no-branch stash@{0} .
stash@{0}: no-branch
stash@{1}: On master: renamed
repo[master] % git stash-rename renamed
stash@{0}: renamed
stash@{1}: On master: renamed
repo[master] % git stash-rename readd-branch stash@{0} develop
stash@{0}: On develop: readd-branch
stash@{1}: On master: renamed
A maior parte do comando é para analisar os argumentos e descobrir o que deve ser feito com o nome da ramificação. As gitferramentas utilizadas são as seguintes:
git rev-parse <stash> para encontrar o SHA do esconderijo.
git stash list --format=%gs -1 <stash>para encontrar o assunto de reflog do esconderijo. Observe que isso é diferente da mensagem de confirmação do stash, que não é alterada por este comando. O assunto do reflog é o que aparece git stash list, e você pode alterar o assunto do reflog sem alterar os hashes dos commits associados aos stashes. No entanto, você sempre pode encontrar a mensagem de confirmação original, portanto, não use git stash-renamepara remover informações confidenciais!
git stash drop <stash>para largar a antiga referência ao stash (mas ainda temos o SHA, para que não seja perdido).
git stash store -m <new-message> <sha>para salvar uma nova referência ao stash com as mesmas informações de confirmação, mas com um assunto de reflog diferente .
git stash listpara listar os stashes após a conclusão da operação. Observe que novos stashes são sempre enviados para o início da lista. Seria necessário re-empurrar todos os stashes antes do stash de interesse para restaurar sua posição original.
Respostas:
Vamos supor que sua lista stash seja assim:
Primeiro, você deve remover a entrada stash que deseja renomear:
Agora basta adicioná-lo novamente com nova mensagem usando sha of commit retornado após o drop:
E é isso:
Esta solução requer o git 1.8.4 ou posterior e, sim, também funciona com o diretório de trabalho sujo.
fonte
git show stash@{0}
ainda mostra as informações antigas posteriormente. Como consertar isso? (Por favor, note que o esconderijo, em seguida, recebe um SHA diferente.)git show
e começargit stash store
. Então, comgit stash list
você verá o velho e o novo esconderijo. Finalmente, você pode limpar o esconderijo antigogit stash drop
.git gc
seja executado. Depois destash drop
encontrar facilmente esse commit normalmente inacessível usando ogit fsck | grep commit
comandoA menos que você faça isso manualmente ou contribua com uma melhoria no Git, você pode usar um alias:
Uso: "
git stash-rename <stash> [save options] [<message>]
"Com
[save options]
qualquer opção degit stash save
:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]
Exemplo:
Isso funcionará mesmo se você tiver alterações locais sem etapas :)
EDIT 2016/02/22
Script simplificado, créditos para qzb , https://stackoverflow.com/a/35549615/515973
Uso: "
git stash-rename <stash> [<message>]
"fonte
git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
stash@{0}
referência. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922git config --global alias.stash-rename '!_() { if [ -z \"$1\" ] || [ -z \"$2\" ]; then echo \"git stash-rename 0 NewName\" && echo \"\" && git stash list && exit 1; else stash=\"stash@{$1}\"; rev=$(git rev-parse \"${stash}\"); git stash drop \"${stash}\" || exit 1; git stash store -m \"$2\" \"$rev\" || exit 1; git stash list; fi }; _'
É muito simples. Primeiro, desfaça o último estoque com:
Depois disso, você pode salvar o stash com um nome personalizado desta maneira:
Espero que seja útil para você. :)
fonte
Eu não acho que é possível fazer isso. Houve uma proposta para renomear stash, mas ainda não foi implementada.
Ou você pode, é claro, abrir o esconderijo e fazer uma
git stash save [message]
fonte
Para o benefício do leitor, aqui está uma extensão da resposta atualmente aceita e correta .
Se você não apenas deseja corrigir a mensagem stash e também deseja corrigir a mensagem de confirmação da stash, de forma que
e
ambos concordam com o que é mostrado, você precisa de um pouco mais. Pode haver uma maneira melhor de fazer isso, mas espero que essa receita aqui seja fácil de entender.
Para poder fazer isso,
git commit --amend
você precisa estar na ponta de uma ramificação. Portanto, a solução é:Explicado:
git commit --amend
para substituir a mensagem de confirmação, alterando o SHA do "stash in question"Desvantagens:
Isso alterna ramificações temporariamente. Portanto, esta receita só pode ser aplicada quando
git status --porcelain
estiver limpa (leia-se: não gera nada)Ele renumera os stashes, para que o stash alterado se torne
stash@{0}
Você precisa inserir
$MESSAGE
duas vezes ou usar alguma variável de ambiente (no exemploMESSAGE
:)Você precisa encontrar um nome de filial não utilizado
Existem maneiras de fazer isso sem alternar ramificações, mas isso está além do escopo desta resposta.
Exemplo
Resultado
Agora, sem alterar o commit (observe: o SHA a seguir será diferente ao seu lado):
Resultado
Como você pode ver,
stash@{0}
ainda é mostrado como2fbf900 (refs/stash) WIP on master: 8bdcc32 D
emgit log
. Se você observar atentamente, verá que vários commits alteraram o SHA. Isso ocorre devido à maneira como os stashes são manipulados (os pais são incluídos no SHA e os stashes têm seus stashes como pais).Conserte isso:
Resultado
Como você também pode ver, o
refs/stash
SHA também mudou.fonte
Aqui está uma versão modificada do alias de Julien que permite lidar adequadamente com o
On <branch>
prefixo geralmente anexado aos nomes escondidos:Sintaxe:
Exemplo de uso:
A maior parte do comando é para analisar os argumentos e descobrir o que deve ser feito com o nome da ramificação. As
git
ferramentas utilizadas são as seguintes:git rev-parse <stash>
para encontrar o SHA do esconderijo.git stash list --format=%gs -1 <stash>
para encontrar o assunto de reflog do esconderijo. Observe que isso é diferente da mensagem de confirmação do stash, que não é alterada por este comando. O assunto do reflog é o que aparecegit stash list
, e você pode alterar o assunto do reflog sem alterar os hashes dos commits associados aos stashes. No entanto, você sempre pode encontrar a mensagem de confirmação original, portanto, não usegit stash-rename
para remover informações confidenciais!git stash drop <stash>
para largar a antiga referência ao stash (mas ainda temos o SHA, para que não seja perdido).git stash store -m <new-message> <sha>
para salvar uma nova referência ao stash com as mesmas informações de confirmação, mas com um assunto de reflog diferente .git stash list
para listar os stashes após a conclusão da operação. Observe que novos stashes são sempre enviados para o início da lista. Seria necessário re-empurrar todos os stashes antes do stash de interesse para restaurar sua posição original.fonte
Maneira mais simples: pop seu stash com git stash pop e salve-o novamente com git stash save your-name
fonte