Jak odblokować tylko niektóre pliki?


385

Ukryłem swoje zmiany. Teraz chcę rozpakować tylko niektóre pliki ze skrytki. W jaki sposób mogę to zrobić?


4
Myślę, że musisz zastosować całą skrytkę, ale wtedy możesz selektywnie ponownie schować.
— Richard

4
@AbdouTahiri Co jest nie tak ze skrytką?
— alex

32
@AbdouTahiri Uhhhh .. git stash jest legalną funkcją i niezwykle przydatną. Używam tego codziennie. Powiedzmy, że współpracownik potrzebuje mojej recenzji, ale jestem w trakcie złożonego zestawu zmian. Nie zamierzam zatwierdzać stosu zepsutego kodu tylko po to, by móc zmieniać gałęzie. Zamierzam ukryć, zamienić gałęzie, przejrzeć, przełączyć z powrotem, odblokować. Czy zastanawiasz się nad tym, kto lub dlaczego skrytka git jest rzekomo „nie zalecana”? To, że twoja historia gitów jest zamazana i trudna do odczytania, nie oznacza, że ​​wszyscy są inni. Brudny zestaw skrytek git to po prostu zły przepływ pracy, a nie wada Gita.
— dudewad

6
@alex Nic. Nic nie jest nie tak z Git Stash. Nadal go używaj.
— dudewad

Odpowiedzi:


460

Jak wspomniano poniżej i szczegółowo opisano w „ Jak wyodrębnić pojedynczy plik (lub zmiany w pliku) z skrytki git? ”, Możesz zastosować użycie git checkoutlub git showprzywrócić określony plik.

git checkout stash@{0} -- <filename>

To powoduje nadpisywanie filename : upewnij się, że nie masz lokalnych modyfikacji, albo możesz zamiast tego scalić ukryty plik .

(Jak skomentował przez Jaime M. , dla niektórych muszli jak tcsh, gdzie trzeba uciec znaków specjalnych, składnia będzie: git checkout 'stash@{0}' -- <filename>)

lub aby zapisać go pod inną nazwą pliku:

git show stash@{0}:<full filename>  >  <newfile>

(zwróć uwagę, że tutaj <full filename>jest pełna ścieżka do pliku w stosunku do górnego katalogu projektu (pomyśl: w odniesieniu do stash@{0})).

Yumper sugeruje w komentarzach :

Jeśli chcesz ręcznie wybrać zmiany, które chcesz zastosować z tego pliku:

git difftool stash@{0}..HEAD -- <filename>

Vivek dodaje w komentarzach :

Wygląda na to, że „ git checkout stash@{0} -- <filename>” przywraca wersję pliku z momentu wykonania skrytki - NIE stosuje (tylko) ukrytych zmian dla tego pliku.
Aby zrobić to drugie:

git diff stash@{0}^1 stash@{0} -- <filename> | git apply

(jak skomentował przez peterflynn , może być konieczne | git apply -p1w niektórych przypadkach usunięcie jednego ( p1) prowadzącej ukośnik od tradycyjnych ścieżek różnice)


Jak skomentowano: „unstash” ( git stash pop), a następnie:

  • dodaj to, co chcesz zachować do indeksu ( git add)
  • schować resztę: git stash --keep-index

Ostatni punkt pozwala zachować niektóre pliki podczas ukrywania innych.
Ilustruje to „ Jak ukryć tylko jeden plik z wielu plików, które uległy zmianie ”.


5
To nie działa, jeśli nie możesz z git stash poppowodu konfliktu plików. Odpowiedź Balamurugana A pomogła mi w tym przypadku.
— Andrey

1
Jeśli chcesz ręcznie wybrać zmiany, które chcesz zastosować z tego pliku, możesz użyć skrytki git difftool @ {0} .. HEAD - <nazwa_pliku>
— yucer

5
Wygląda na to, że „git Checkout stash @ {0} - <nazwa pliku>” przywraca wersję pliku z momentu wykonania skrytki - NIE stosuje (tylko) ukrytych zmian dla tego pliku. Aby to zrobić: „git diff stash @ {0} ^ 1 stash @ {0} - <nazwa_pliku> | git stosuje się”
— Vivek

1
@JaimeM. Dziękuję Ci. W odpowiedzi umieściłem twój komentarz dla większej widoczności.
— VonC

1
Zakładając, że unstashoznacza to pop, jak mi się wydaje, że w większości przypadków prawdopodobnie tak by było, to tylko częściowo odpowiada na pytanie. Jak następnie usunąć selektywnie zastosowane elementy ze skrytki, aby uniknąć późniejszych konfliktów i / lub zamieszania podczas usuwania pozostałych zmian?
— DylanYoung

115
git checkout stash@{N} <File(s)/Folder(s) path> 

Na przykład. Aby przywrócić tylko plik ./test.c i folder ./include z ostatniego składowania,

git checkout stash@{0} ./test.c ./include

12
To poprawna odpowiedź! Jednoliniowe polecenie, aby zastosować tylko ukryte zmiany z określonych plików, działa jak urok!
— poziomy

1
Aby zastosować (tylko) ukryte zmiany w pliku: „git diff stash @ {N} ^ 1 skrytka {{N} - <nazwa pliku> | git Apply”
— Vivek

To też działa dla mnie. Po prostu wybiórczo kasuj pliki potrzebne do skasowania i gotowe. Utknąłem w tym i użyłem -aflagi podczas tworzenia skrytki.
— Rajeev Ranjan

1
@ 4levels Myślę, że „zastosowanie ukrytych zmian” nie jest tym, co się dzieje, prawda? Wydaje mi się, że „nadpisuj wszystko, co masz, kopią ze skrytki”.
— msouth

35

Myślę, że odpowiedź VonC jest prawdopodobnie tym, czego chcesz, ale oto sposób na selektywne „zastosuj git”:

git show stash@{0}:MyFile.txt > MyFile.txt

4
W niektórych przypadkach może to być pożądane, ale należy pamiętać, że to polecenie zastąpi, a nie scali ze zmianami katalogu roboczego.
— Rhubbarb,

To działa dla mnie, ponieważ chciałem po prostu skopiować plik, który istnieje tylko w skrytce i nic mnie to nie obchodziło checkout.
— Tom Russell

1
W przypadku Windows PowerShell: git show stash@`{0`}:Path/To/MyFile.txt |sc Path/To/MyFile.txt- backsticks są konieczne, aby PS nie interpretował specjalnie nawiasów klamrowych, i scjest to konieczne, ponieważ >operator PS domyślnie przyjmuje UTF-16 (właściwie UCS-2), co prawdopodobnie nie jest tym, czego chcesz. Odpowiedź @Balamurugan A nie cierpi z powodu tych problemów.
— Ian Kemp,

19

Najpierw wypisz wszystkie skrytki

git stash list

↓

stash@{0}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{1}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{2}: WIP on master: 7e450c81 Merge branch 'Offlineseite'

Następnie pokaż, które pliki są w skrytce (wybierzmy skrytkę 1):

git stash show 1 --name-only

//Hint: you can also write
//git stash show stash@{1} --name-only

↓

 ajax/product.php
 ajax/productPrice.php
 errors/Company/js/offlineMain.phtml
 errors/Company/mage.php
 errors/Company/page.phtml
 js/konfigurator/konfigurator.js

Następnie zastosuj plik, który chcesz:

git checkout stash@{1} -- <filename>

lub cały folder:

git checkout stash@{1} /errors

Działa również bez, --ale zaleca się ich użycie. Zobacz ten post.

Konwencjonalne jest również uznawanie podwójnego myślnika za sygnał do zatrzymania interpretacji opcji i traktowania wszystkich następujących argumentów dosłownie.


1
Dzięki tej edycji jest to wyraźniejsze. +1
— VonC

1
Próbowałem na wiele sposobów i właśnie tego potrzebowałem. Stałem przed problemem, który git stash popzgłosił błąd dotyczący nieśledzonych plików. Dziękuję Ci.
— Ramin Firooz,

10

Jeśli ty git stash pop(bez konfliktów) usunie skrytkę po jej zastosowaniu. Ale jeśli git stash applyzastosujesz łatkę bez usuwania jej z listy skrytek. Następnie możesz cofnąć niechciane zmiany za pomocągit checkout -- files...


2
Aby wyjaśnić konflikty w części tego postu, jeśli Ty git stash popi tam JESTEŚ konflikty, będziesz musiał je naprawić ręcznie, a skrytka NIE zostanie usunięta.
— Thomas McCabe

6

Jeszcze jeden sposób:

git diff stash@{N}^! -- path/to/file1 path/to/file2  | git apply -R

2
To jedyna poprawna odpowiedź IMO. Użycie checkoutlub showspowoduje zastąpienie pliku na ślepo zamiast po prostu wprowadzania zmian. „Jeszcze jeden sposób” to mało powiedziane.
— kambuzowy

1
Nie otrzymuję tego, path/to/file2co chcesz odróżnić od tego samego pliku w obszarze roboczym. Wyjście z drugiej ścieżki działa dla mnie dobrze. - I pojawia się komunikat o błędzie przy użyciu -Ropcji („zastosować łatkę w odwrotnej kolejności”, próbując załatać ukrytą wersję ?!). Tak wygląda moja działająca wersja git diff stash@{N}^! -- path/to/file | git apply -.
— ThomasH

„łatka nie powiodła się”? Wypróbuj połączenie 3-kierunkowe. ...| git apply -3 -
— John Mee

6

Dla użytkowników systemu Windows: nawiasy klamrowe mają specjalne znaczenie w programie PowerShell. Możesz albo otoczyć pojedyncze cudzysłowy, albo uciec za pomocą backsticka. Na przykład:

git checkout 'stash@{0}' YourFile

Bez tego może pojawić się błąd:

Unknown switch 'e'


3
Pełne oceny w programie PowerShell za najmniej pomocny komunikat użytkownika, jaki widziałem w tym miesiącu.
— holdenweb,
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.