2011-12-13 9 views
27
git mv file1 file2 

git status 
# On branch master 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
# renamed: file1 -> file2 

git stash 
git stash pop 

# On branch master 
# Changes to be committed: 
# (use "git reset HEAD <file>..." to unstage) 
# 
# new file: file2 
# 
# Changes not staged for commit: 
# (use "git add/rm <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# deleted: file1 

Come si può vedere, git perde il rapporto rinominato dopo una scorta/pop. C'è un modo per riacquistare questa relazione o sapere che i file sono stati spostati? Spesso mi nascondo per vedere quale è il mio stato di sistema come pre-modifiche, ma averlo perso la relazione di rinomina è un problema per me. Non so come risolverlo se non cancellando il nuovo file, facendo di nuovo un git mv e sostituendo il contenuto del nuovo file.git stash e pop mostra il file non è più contrassegnato come spostato?

+1

Nota: che wo Sarebbe interessante provare di nuovo con Git 2.12 (primo trimestre 2017). Vedi http: // StackOverflow.it/a/41307892/6309 – VonC

risposta

26

Se non l'hai già spuntato vostra scorta, do:

git stash pop --index 

Questa conserva correttamente spostati (ma non impegnati) relazioni tra file in una scorta. Secondo git help stash:

Se si utilizza l'opzione --index, poi cerca di ripristinare non solo i cambiamenti del albero di lavoro, ma anche quelli della indice. Tuttavia, questo può fallire, quando si hanno conflitti (che sono memorizzati nell'indice, dove quindi non si possono più applicare le modifiche come erano originariamente).

Se hai già spuntato vostra scorta e vogliono ricreare il rapporto spostato, fare:

git rm --cached file1 

Ciò elimina la "vecchia" di file impassibile dall'indice:

utilizzare questa opzione per unstage e rimuovere percorsi solo dall'indice

+2

Non so se questa è una risposta migliore di @ Jefromi's –

+2

'git stash pop --index' è meglio se ti ricordi di farlo la prima volta. Ma se in precedenza hai dimenticato di inserire l'indice, 'git rm --cached file1' ti riporterà a dove file2 viene rinominato a prescindere. –

+0

È un po 'annyo. Perché git ha sempre queste piccole debolezze che sembrano essere lì solo per prenderti fuori !? – Steve

18

Risposta breve: git rm --cached file1

Tutti git mv realtà non è rinominare il file (sul filesystem) e quindi aggiungere un cancellazione del file e la creazione per l'indice (area di gestione temporanea). Non è appositamente indicato. Successivamente, altri macchinari si rendono conto che si trattava di un cambio di nome, osservando che il contenuto chiamato prima file1 ora è chiamato file2.

Dal git stash comandi modificano l'indice, possono perturbare le cose. Nota che ora hai messo in scena la creazione, ma non la cancellazione! (Normalmente git-stash lascia tutto libero da un pop, ma in questo caso penso che non abbia molta scelta se non inserire il nuovo file nell'indice, per evitare di non avere idea di quale mantenere. sempre accade con git stash pop --index, ma che le bombe se i cambiamenti stashed non possono essere applicate in modo pulito, quindi non è di default.) git status non si può forse mostrare come una ridenominazione più, perché la ridenominazione viene efficacemente diviso tra l'indice e il lavoro albero, e nessuna delle due sezioni può rivendicarla pienamente.

Basta eseguire git rm --cached file1 per mettere in scena la cancellazione (ovvero rimuovere file1 dall'indice) e verrà nuovamente visualizzato come un nuovo nome. È inoltre possibile eseguire git add -u per aggiungere automaticamente le modifiche, purché non siano presenti altre modifiche che non si desidera eseguire.

Nota che ciò significa che in pratica non ti devi preoccupare: quando metti in ordine tutto in preparazione per il commit (ad esempio con git add -u), il "problema" si prende cura di se stesso.