Come posso rinominare una scorta git?


203

Ho una scorta con un nome errato. Vorrei correggere il nome in modo che sia accurato.

Come posso rinominare una scorta?


5
pop e salvarlo di nuovo con un nome diverso?
Bartlomiej Lewandowski,

5
Fare una pausa e riporlo di nuovo non è sempre un'opzione, perché lo stash potrebbe essere basato su uno stato obsoleto e provocare conflitti quando scoppiano. (Lo stato obsoleto non deve nemmeno più esistere nella storia.)
Tom,

Risposte:


259

Supponiamo che la tua lista di oggetti sia simile a questa:

$ git stash list
stash@{0}: WIP on master: Add some very important feature 
stash@{1}: WIP on master: Fix some silly bug

Innanzitutto, è necessario rimuovere la voce stash che si desidera rinominare:

$ git stash drop stash@{1}
Dropped stash@{1} (af8fdeee49a03d1b4609f294635e7f0d622e03db)

Ora aggiungilo di nuovo con un nuovo messaggio usando sha of commit restituito dopo averlo lasciato cadere:

$ git stash store -m "Very descriptive message" af8fdeee49a03d1b4609f294635e7f0d622e03db

E questo è tutto:

$ git stash list
stash@{0}: Very descriptive message
stash@{1}: WIP on master: Add some very important feature

Questa soluzione richiede git 1.8.4 o successive, e sì, funziona anche con directory di lavoro sporche.


3
git show stash@{0}mostra ancora le vecchie informazioni in seguito. Come risolverlo? (Si noti che la scorta ha quindi un SHA diverso.)
Tino

4
È meglio avere l'hash git showe iniziare git stash store. Quindi con git stash listte vedrai la vecchia e la nuova scorta. Finalmente puoi ripulire la vecchia scorta con git stash drop.
hogi,

6
Git Stash Drop non perderà le modifiche?
Shravya Boggarapu,

4
@ShravyaBoggarapu, no, git non rimuove il commit fino a quando non git gcviene eseguito. Dopo stash droppuoi facilmente trovare questo commit normalmente inaccessibile usando il git fsck | grep commitcomando.
qzb

2
@ ÐerÆndi semplicemente applicare e salvare è un'opzione facile, ma non funziona quando le modifiche non possono essere riapplicate a causa di conflitti. Nel frattempo far cadere e conservare le opere in qualsiasi circostanza. Ho testato ancora una volta la mia soluzione: funziona perfettamente sull'ultima versione di git (2.17.0).
qzb

62

A meno che tu non lo faccia manualmente o contribuisca a migliorare Git, puoi usare un alias:

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git diff-index --quiet HEAD; s=$?; [ $s != 0 ] && git stash save "tmp stash from stash-rename"; git stash apply $rev && shift && git stash save "$@" && [ $s != 0 ] && git stash pop stash@{1}; }; _'

Utilizzo: " git stash-rename <stash> [save options] [<message>]"

Con [save options]qualsiasi opzione di git stash save:[-p|--patch] [-k|--[no-]keep-index] [-q|--quiet] [-u|--include-untracked] [-a|--all]

Esempio:

$ 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

Funzionerà anche se hai modifiche locali non in scena :)

MODIFICA 22/02/2016

Script semplificato, crediti a qzb , https://stackoverflow.com/a/35549615/515973

git config --global alias.stash-rename '!_() { rev=$(git rev-parse $1) && git stash drop $1 || exit 1 ; git stash store -m "$2" $rev; }; _'

Utilizzo: " git stash-rename <stash> [<message>]"


1
Eccezionale! Ancora più git stash-rename 'tests with deployAtEnd' 'NXP-13971-deployAtEnd'
bello

3
quindi la risposta è 1) copia di lavoro pulita, 2) applica lo stash che vuoi rinominare, 3) eliminalo dall'elenco degli stash, 4) crea un nuovo stash con il messaggio corretto.
gcb,

2
Per chiarire, stai rinominando l'ultima scorta e dopo tale azione diventa la scorta maggiore?
onebree,

2
Elimina lo stash per rinominarlo, salvo eventuali modifiche correnti, ricrea lo stash eliminato con il nome desiderato, riapplico le eventuali modifiche correnti.
Julien Carsique,

3
Questa versione verifica che entrambi gli argomenti siano presenti, in modo da non eliminare accidentalmente l'ultima scorta. Richiede anche solo il numero di stash, non l'intero stash@{0}riferimento. gist.github.com/jdforsythe/f248bf6c72fc020225cc3e315a32e922 git 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

È molto semplice. Innanzitutto, annulla l'ultima scorta con:

git stash pop

Successivamente, puoi salvare lo stash con un nome personalizzato in questo modo:

git stash save "your explanatory name"

Spero sia utile per te. :)


La scorta rinominata potrebbe non essere la più recente.
Mikemaccana,

Pollice in alto dal momento che questo più semplice (SOLO) per la scorta più recente.
Kaihua,

3

Non credo sia possibile farlo. C'è stata una proposta per rinominare lo stash, ma non è stata ancora implementata.

La mia idea generale è:

  1. Implementare un nuovo git reflog updatecomando che aggiorna il messaggio associato a una voce di reflog specifica. Per fare ciò, una nuova update_reflog_ent()funzione (in reflog.c ) cambierebbe il messaggio associato alla voce reflog specifica da aggiornare. Una update_reflog()funzione userebbe for_each_reflog_ent()con update_reflog_entper fare effettivamente il cambiamento.

  2. Un git stash renamecomando dovrebbe quindi solo chiamare git reflog updatecon il riferimento appropriato e il nuovo messaggio.

Oppure potresti, ovviamente, aprire la scorta e fare un git stash save [message]


3

A beneficio del lettore, ecco un'estensione della risposta attualmente accettata e corretta .

Se non si desidera solo correggere il messaggio stash e si desidera anche correggere il messaggio di commit dello stash, tale

git stash list

e

git log --oneline -1 stash

entrambi sono d'accordo su ciò che viene mostrato, è necessario un po 'di più. Ci potrebbe essere un modo migliore per farlo, ma spero che questa ricetta sia facile da capire.

Per poterlo fare git commit --amenddevi essere sulla PUNTA di un ramo. Quindi la soluzione è:

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

Ha spiegato:

  • Crea un nuovo ramo "scratch" (non ancora esistente) dallo "stash in questione" e passa ad esso
  • Rimuovi la vecchia scorta. Questo è sicuro, poiché abbiamo ancora questo sul ramo.
  • Utilizzare git commit --amendper sostituire il messaggio di commit, questo cambia lo SHA dello "stash in questione"
  • Conservare lo stash, in base alla risposta di qzb
  • Torna indietro (il che presuppone che tu provenga da "master") e pulisci

svantaggi:

  • Questo cambia temporaneamente i rami. Quindi questa ricetta può essere applicata solo quando git status --porcelainè pulita (leggi: non produce nulla)

  • Rinomina gli stash, quindi lo stash modificato diventa stash@{0}

  • È necessario inserire il $MESSAGEdue volte o utilizzare qualche variabile d'ambiente (nell'esempio: MESSAGE)

  • Devi trovare un nome di ramo inutilizzato

Ci sono modi per farlo senza cambiare ramo, ma questo va oltre lo scopo di questa risposta.

Esempio

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

Produzione

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

Ora senza modificare il commit (nota: lo SHA di seguito sarà diverso al tuo fianco):

git stash drop stash@{1}
git stash store -m ...changed... 2fbf9007dfdfb95ae269a19e13b8b9ca3e24181c
git log --oneline --graph --decorate --all; git stash list

Produzione

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

Come puoi vedere, stash@{0}viene ancora mostrato come 2fbf900 (refs/stash) WIP on master: 8bdcc32 Din git log. Se osservi attentamente, vedrai che diversi commit hanno cambiato SHA. Ciò è dovuto alla gestione degli stash (i genitori sono inclusi nello SHA e gli stash hanno i loro stash come genitore).

Risolvi che:

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

Produzione

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

Come puoi vedere, anche refs/stashSHA è cambiato.


Vale la pena menzionare: questo distrugge l'indice che è stato salvato con lo stash originale, sostituendolo con un nuovo indice che corrisponde al commit principale dello stash originale. Se uno non stava pianificando di utilizzare l'indice originale salvato (o corrispondeva già al genitore dello stash originale), questo non è un problema.
Torek,

1

Ecco una versione modificata dell'alias di Julien che ti consente di gestire correttamente il On <branch>prefisso solitamente anteposto ai nomi di stash:

git config --global alias.stash-rename '!_() { newmsg="$1" && stash=${2:-"stash@{0}"} && newbranch="$3" && sha=$(git rev-parse "$stash") && olddesc="$(git stash list --format=%gs -1 "$stash")" && newdesc="$(if [[ "$newbranch" = "." ]]; then echo "$newmsg"; else if [[ -n "$newbranch" ]]; then echo "On $newbranch: $newmsg"; else if [[ "$olddesc" =~ ":" ]]; then echo "$(echo "$olddesc" | cut -f1 -d":"): $newmsg"; else echo "$newmsg"; fi; fi; fi)" && git stash drop "$stash" > /dev/null || exit 1; git stash store -m "$newdesc" "$sha" && git stash list; }; _'

Sintassi:

git stash-rename <new-name> [<stash> [<new-branch-name> | .]]

Esempio di utilizzo:

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

La maggior parte del comando serve per analizzare gli argomenti e capire cosa si dovrebbe fare per il nome del ramo. Gli gitstrumenti utilizzati sono i seguenti:

  • git rev-parse <stash> per trovare lo SHA della scorta.
  • git stash list --format=%gs -1 <stash>per trovare l' oggetto reflog della scorta. Si noti che questo è diverso dal messaggio di commit dello stash, che non viene modificato da questo comando. L'oggetto reflog è ciò che appare git stash liste puoi cambiare l'oggetto reflog senza cambiare gli hash dei commit associati agli stash. Tuttavia, puoi sempre trovare il messaggio di commit originale, quindi non utilizzare git stash-renameper rimuovere informazioni riservate!
  • git stash drop <stash>per eliminare il vecchio riferimento alla scorta (ma abbiamo ancora lo SHA, quindi non è perso).
  • git stash store -m <new-message> <sha>per salvare un nuovo riferimento allo stash con le stesse informazioni di commit ma un oggetto reflog diverso .
  • git stash listper elencare gli stash al termine dell'operazione. Si noti che i nuovi blocchi vengono sempre spinti all'inizio dell'elenco. Sarebbe necessario ripremere tutti gli stash prima dello stash di interesse per ripristinare la sua posizione originale.

0

Il modo più semplice: fai scoppiare la tua scorta con git stash pop quindi salvala di nuovo con git stash salva il tuo nome


La scorta rinominata potrebbe non essere la più recente.
Mikemaccana,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.