Nie sądzę, aby zaakceptowana odpowiedź @ bukzor była poprawną odpowiedzią na pytanie, jakie zostało zadane. git stash --keep-indexzachowuje indeks, ale ukrywa wszystko - zarówno w indeksie, jak i poza nim.
Raman,
@Antonio Wydaje mi się, że twoja nagroda powinna być osobnym pytaniem, ponieważ pierwotne pytanie nie ma nic wspólnego z TortoiseGit.
JesusFreke
1
@JesusFreke Tak, biorąc pod uwagę wynik, mogłem oszczędzić 50 powtórzeń :) Po prostu to jest pytanie, na które zostaniesz przekierowany, jeśli spróbujesz wyszukać „częściowe skrytki żółwia”. Tortoisegit nie wydaje się być popularnym tematem tutaj stackoverflow.com/questions/tagged/tortoisegit
Antonio
7
>>>>>>>>> git diff -- *filename* > ~/patchpotem git checkout -- *filename*i później możesz ponownie zastosować łatkę za pomocągit apply ~/patch
neaumusic
36
Większość istniejących odpowiedzi poniżej jest nieaktualna. Od wersji 2.13 (Q2 2017) jest obsługiwany przez git stash push [--] [<pathspec>...].
Ohad Schneider,
Odpowiedzi:
1372
Uwaga : następująca odpowiedź dotyczy git przed git 2.13. W przypadku wersji 2.13 i nowszych sprawdź kolejną odpowiedź poniżej .
Ostrzeżenie
Jak zauważono w komentarzach, umieszcza to wszystko w skrytce, zarówno inscenizowane, jak i niestacjonarne. --Keep-index po prostu pozostawia indeks sam po zakończeniu skrytki. Może to powodować konflikty scalania, gdy później wyskakujesz skrytka.
Spowoduje to ukrycie wszystkiego, czego wcześniej nie dodałeś. Tylko git addrzeczy, które chcesz zachować, a następnie uruchom.
git stash --keep-index
Na przykład, jeśli chcesz podzielić stary zatwierdzenie na więcej niż jeden zestaw zmian, możesz użyć tej procedury:
git rebase -i <last good commit>
Oznacz niektóre zmiany jako edit.
git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
Napraw wszystko w razie potrzeby. Nie zapomnij o git addżadnych zmianach.
Nie jestem pewien, dlaczego jest to głosowane. Wszyscy muszą mieć inne oczekiwania niż ja. W oryginalnym poście jest pytanie „jak ukryć tylko część niezaangażowanych zmian?” Kiedy używam git stash save -k, tak, indeks (zielony w git stat) jest zachowany, ale cały zestaw zmian (zarówno zielony, jak i czerwony) trafia do schowka. Jest to sprzeczne z żądaniem PO: „ukryj tylko niektóre zmiany”. Chcę ukryć tylko część czerwonego (do wykorzystania w przyszłości).
@Raman: Doskonale! git stash -pjest dokładnie tym, czego szukałem. Zastanawiam się, czy ten przełącznik został dodany dopiero niedawno.
Pistos
14
OSTRZEŻENIE: git stash --keep-indexjest zepsuty. Jeśli wprowadzisz więcej zmian, spróbuj git stash poppóźniej uzyskać konflikty scalania, ponieważ skrytka zawiera zmienione pliki, które trzymałeś, a nie tylko te, których nie zachowałeś. Na przykład: zmieniam pliki A i B, a następnie przechowuję B, ponieważ chcę przetestować zmiany w A; Znajduję problem z A, który następnie naprawiam; Popełniam A; Teraz nie mogę odblokować, ponieważ stara wersja A znajduje się w schowku bez wyraźnego powodu powodującego konflikt scalania. W praktyce A i B mogą być wieloma plikami, być może nawet obrazami binarnymi lub czymś takim, więc w zasadzie muszę się poddać i stracić B.
rjmunro
3015
Możesz także użyć git stash save -p "my commit message". W ten sposób możesz wybrać, które przystawki mają być dodane do skrytki, a także całe pliki.
Zostaniesz poproszony o kilka działań dla każdego przystojniaka:
y - stash this hunk
n - do not stash this hunk
q - quit; do not stash this hunk or any of the remaining ones
a - stash this hunk and all later hunks in the file
d - do not stash this hunk or any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
Nie było. Został pożyczony od Darcs, około 7 lat po fakcie.
nomen
6
Jestem uzależnionym od TortoiseGit. Jednak TortoiseGit nie obsługuje stash -p. Przyznaję tę odpowiedź, ponieważ pozostaje ona najbardziej interaktywna / przyjazna dla użytkownika.
Antonio
27
możesz dodać git stash save -p my stash message:; ponieważ kolejność argumenstów nie jest zbyt intuicyjna ...
Chris Maes,
15
Pomiędzy tym a git log -p, myślę, że -pflaga musi oznaczać „rób fajne rzeczy, które chcę, ale nie umiem wyrazić”.
Kyle Strand
2
dlaczego, u licha, ta świetna odpowiedź jest na 12. pozycji? po tych wszystkich odpowiedziach 0, +1, +2 ??????
DenisFLASH
547
Ponieważ git zasadniczo polega na zarządzaniu całą zawartością i indeksem repozytorium (a nie jednym lub kilkoma plikami), git stashzajmuje się, co nie dziwi,z całym katalogiem roboczym.
W rzeczywistości od wersji Git 2.13 (II kwartał 2017 r.) Można przechowywać poszczególne pliki za pomocą git stash push:
git stash push [--] [<pathspec>...]
Gdy pathspecpodano „ git stash push”, nowa skrytka rejestruje zmodyfikowane stany tylko dla plików, które pasują do specyfikacji ścieżki. Zobacz „Ukrywanie zmian w określonych plikach ”, aby uzyskać więcej.
To ( stash --patchoryginalne rozwiązanie) jest fajne, ale często modyfikowałem wiele plików, więc używanie łatki jest denerwujące
bukzor „s odpowiedź (upvoted, listopad 2011) sugeruje bardziej praktyczne rozwiązanie, oparte na git add+git stash --keep-index .
Idź i poproś jego odpowiedź, która powinna być oficjalna (zamiast mojej).
O tej opcji chhh wskazuje w komentarzach alternatywny przepływ pracy:
powinieneś „ git reset --soft” po takim skrytce, aby przywrócić czystą inscenizację:
Aby wrócić do pierwotnego stanu - który jest czystym obszarem inscenizacji i tylko z kilkoma wybranymi nieustawionymi modyfikacjami, można delikatnie zresetować indeks, aby uzyskać (bez popełnienie czegoś takiego jak ty - bukzor - zrobiłeś).
(Oryginalna odpowiedź z czerwca 2010: skrytka ręczna)
Jednak git stash save --patchmoże pozwolić na osiągnięcie częściowego ukrywania, którego szukasz:
Za pomocą --patchmożna interakcyjnie wybierać przystawki między różnicą między HEAD a działającym drzewem, które ma być ukryte.
Wpis skrytki jest skonstruowany w taki sposób, że jego stan indeksu jest taki sam jak stan indeksu repozytorium, a jego drzewo robocze zawiera tylko zmiany wybrane interaktywnie. Wybrane zmiany są następnie przywracane z twojego środowiska roboczego.
Spowoduje to jednak zapisanie pełnego indeksu (który może nie być tym, czego chcesz, ponieważ może on zawierać inne pliki już zindeksowane) oraz częściowego drzewa roboczego (które może wyglądać jak ten, który chcesz ukryć).
git stash --patch --no-keep-index
może być lepsze dopasowanie.
Jeśli --patchnie działa, proces ręczny może:
W przypadku jednego lub kilku plików rozwiązaniem pośrednim byłoby:
To miłe, ale często modyfikowałem wiele plików, więc używanie łatki jest denerwujące
Casebash
6
@VonC: Dobrze jest mieć tylko jedną odpowiedź na odpowiedź. Także kopiowanie i wklejanie odpowiedzi innych na własne to złe maniery.
bukzor 12.12.11
3
@bukzor: Przykro mi, jeśli moja zredagowana odpowiedź wydawała się niewłaściwa. Moim jedynym zamiarem było zwiększenie widoczności twojej odpowiedzi. Zredagowałem ponownie swój post, aby wyjaśnić ten zamiar.
git is fundamentally about managing a all repository content and index and not one or several files- to implementacja przesłaniająca rozwiązywany problem; to wyjaśnienie, ale nie uzasadnienie. Każdy system kontroli źródła ma na celu „zarządzanie wieloma plikami”. Zobacz, jakie komentarze są najczęściej oceniane.
Victor Sergienko,
90
Kiedy git stash -p(lub git add -pz stash --keep-index) byłoby zbyt uciążliwe, znalazłem to łatwiejsze w użyciu diff, checkoutoraz apply:
Interesująca alternatywa dla git add -pwspomnianej powyżej w mojej odpowiedzi. +1.
VCC
11
Zauważ, że jeśli masz pliki binarne (takie jak PNG), nie będą one wyprowadzane do pliku diff. To nie jest w 100% rozwiązanie.
void.pointer
1
@RobertDailey: To interesujący punkt dla mnie, ponieważ git diff > file.diffi git applysą to moje zwykłe narzędzia do częściowego ukrywania. Być może będę musiał rozważyć zmianę git stash -pna większe zestawy zmian.
thekingoftruth
1
@ thehekingoftruth Oto alias, którego używam do tworzenia plików łatek i tak się dzieje binarnych wsparcia: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Pamiętaj jednak, że wymaga to wprowadzenia zmian do zatwierdzenia poprawki.
void.pointer
2
Nie działało to dla mnie dobrze, jeśli plik do ukrycia był podobny ../../foo/bar.txt. Łatka generuje OK, ale muszę przejść do katalogu głównego repozytorium, aby zastosować łatkę. Więc jeśli masz z tym problem - po prostu upewnij się, że robisz to z katalogu głównego repozytorium.
Michael Anderson,
86
Użyj git stash push, jak to:
git stash push [--] [<pathspec>...]
Na przykład:
git stash push -- my/file.sh
Jest to dostępne od Gita 2.13, wydanego wiosną 2017 roku.
Cieszę się, że Git rozwija się tak szybko, przez długi czas nie było to możliwe, a następnie wydano 2.13 i nagle dostępne jest proste rozwiązanie!
sandstrom
1
@VonC masz rację, wspominasz również poprawną odpowiedź, jednak między dwiema odpowiedziami ta jest łatwiejsza do odczytania (bez mylącego tekstu i jest też przykład). Może zamiast tego powinni byli zredagować twoją odpowiedź
Utopik,
@Utopik Miałeś mnie w „masz rację” ... ale tak, zredagowałem swoją odpowiedź, aby podać przykład.
VonC
Czy następnie używa się go git stash applydo odzyskania ukrytych zmian?
Czad
49
Załóżmy, że masz 3 pliki
a.rb
b.rb
c.rb
i chcesz ukryć tylko b.rb i c.rb, ale nie a.rb
możesz zrobić coś takiego
# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp"
# then stash the other files
git stash save "stash message"
# then undo the previous temp commit
git reset --soft HEAD^
git reset
# Save everything
git stash
# Re-apply everything, but keep the stash
git stash apply
git checkout <"files you don't want in your stash"># Save only the things you wanted saved
git stash
# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}
git checkout <"files you put in your stash">
Wymyśliłem to po tym, jak (ponownie) trafiłem na tę stronę i nie podobały mi się dwie pierwsze odpowiedzi (pierwsza odpowiedź po prostu nie odpowiada na pytanie i nie bardzo lubiłem pracę w -ptrybie interaktywnym).
Pomysł jest taki sam, jak sugerowany przez @VonC przy użyciu plików poza repozytorium, zapisujesz zmiany, które chcesz gdzieś, usuwasz zmiany, których nie chcesz, w skrytce, a następnie ponownie stosujesz zmiany, które usunąłeś z drogi. Jednak użyłem skrytki git jako „gdzieś” (w rezultacie na końcu jest jeden dodatkowy krok: usunięcie blokad, które umieściłeś w skrytce, ponieważ również je usunąłeś).
Najbardziej podoba mi się to podejście. Zapewnia łatwy przepływ pracy w żółwie przy użyciu tylko poleceń ukrywania i przywracania.
Mark Ch
Odwoływanie się do odpowiedzi dotyczących SO przy użyciu pozycji nie jest wskazane. Pozycje zmieniają się wraz ze zmianami ocen.
Bryan Ash
2
@BryanAsh Cóż, tutaj nie ma to znaczenia. Podaję anegdotę, a nie nawiązuję do innych odpowiedzi. Wiadomość jest taka, że nie podobały mi się odpowiedzi, które lubiła społeczność, a nie to, co one faktycznie zawierają. Poza tym różnica 900 głosów między drugą a trzecią odpowiedzią sprawia, że jest mało prawdopodobne, aby zmieniła się ona w najbliższej przyszłości, a jeśli powinna się zmienić, zawsze mogę ją edytować, aby powiedzieć „top of the respond at the time”. Naprawdę nie rozumiem, w jaki sposób jest to jakiś problem w tej sytuacji.
Jasper
23
Aktualizacja (14.02.2015) - Napisałem nieco skrypt, aby lepiej obsługiwać przypadki konfliktów, które powinny być teraz przedstawiane jako konflikty nie połączone, a nie pliki .rej.
Często intuicyjnie jest robić odwrotność podejścia @ bukzora. To znaczy, aby wprowadzić pewne zmiany, a następnie ukryć tylko te zmiany etapowe.
Niestety, git nie oferuje skrytki git - tylko indeksowej lub podobnej, więc wymyśliłem skrypt, aby to zrobić.
#!/bin/sh
# first, go to the root of the git repo
cd `git rev-parse --show-toplevel`
# create a commit with only the stuff in staging
INDEXTREE=`git write-tree`
INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD`
# create a child commit with the changes in the working tree
git add -A
WORKINGTREE=`git write-tree`
WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT`
# get back to a clean state with no changes, staged or otherwise
git reset -q --hard
# Cherry-pick the index changes back to the index, and stash.
# This cherry-pick is guaranteed to succeed
git cherry-pick -n $INDEXCOMMIT
git stash
# Now cherry-pick the working tree changes. This cherry-pick may fail
# due to conflicts
git cherry-pick -n $WORKINGCOMMIT
CONFLICTS=`git ls-files -u`
if test -z "$CONFLICTS"; then
# If there are no conflicts, it's safe to reset, so that
# any previously unstaged changes remain unstaged
#
# However, if there are conflicts, then we don't want to reset the files
# and lose the merge/conflict info.
git reset -q
fi
Możesz zapisać powyższy skrypt git-stash-indexgdzieś na swojej ścieżce, a następnie wywołać go jako git stash-index
# <hack hack hack>
git add <files that you want to stash>
git stash-index
Teraz skrytka zawiera nowy wpis, który zawiera tylko zmiany, które zainscenizowałeś, a twoje drzewo robocze nadal zawiera wszelkie zmiany niestacjonarne.
W niektórych przypadkach zmiany działającego drzewa mogą zależeć od zmian indeksu, więc gdy ukryjesz zmiany indeksu, zmiany w drzewie roboczym będą powodowały konflikt. W takim przypadku otrzymasz zwykłe nierozłączone konflikty, które możesz rozwiązać za pomocą git merge / git scaletool / etc.
Polecaj pushdzamiast cdi popdna końcu skryptu, więc jeśli skrypt się powiedzie, użytkownik znajdzie się w tym samym katalogu, co przed uruchomieniem.
Nate
1
@Nate: o ile wiem, powinien zmienić katalog dla użytkownika, tylko jeśli pozyskał skrypt. Jeśli skrypt zostanie uruchomiony normalnie (~ / bin / git-stash-index) lub za pomocą git (git stash-index), zostanie on uruchomiony w osobnej sesji terminala, a wszelkie zmiany katalogu roboczego w tej sesji nie będą miały wpływu na katalog roboczy w sesji terminalu użytkownika. Czy zdajesz sobie sprawę z typowego przypadku użycia, gdy nie jest to prawda? (poza pozyskiwaniem skryptu, którego nie
uważałbym
20
Jeśli nie chcesz określać wiadomości z ukrytymi zmianami, podaj nazwę pliku po podwójnym myślniku.
$ git stash -- filename.ext
Jeśli jest to nieśledzony / nowy plik, najpierw musisz go wyeksponować.
Ta odpowiedź jest pełna, to jest zwięzłe. Jeśli to komuś pomoże, zostawię to. Nikt na tej stronie nie wspomina o tej składni i wyniku - zamiast tego wspomina o `git stash push`.
sealocal
Oto odpowiedź, której szukałem. Dzięki! +1
nicodp
19
Ponieważ tworzenie gałęzi w Git jest banalne, możesz po prostu utworzyć gałąź tymczasową i sprawdzić w niej poszczególne pliki.
Nie można utworzyć gałęzi bez edycji etapowej. Możesz łatwo przenieść wszystkie zmiany do nowej gałęzi (ukryty / ukryty pop), ale potem wracasz do pierwszej: jak przetestujesz swoją gałąź tylko z niektórymi edycjami, nie tracąc pozostałych?
bukzor
7
Nie możesz zmieniać oddziałów, jeśli masz zmiany lokalne. Możesz jednak utworzyć nową gałąź i selektywnie dodawać / zatwierdzać pliki, a następnie utworzyć inną gałąź i zrobić to samo rekurencyjnie ... następnie pobrać oryginalną gałąź i selektywnie scalić się ponownie. Właśnie to zrobiłem. W rzeczywistości wydaje się to naturalnym sposobem na robienie rzeczy, ponieważ zasadniczo tworzysz gałęzie funkcji.
iain
3
@iain możesz zmieniać oddziały, jeśli masz zmiany lokalne, o ile nie wymagają one scalenia. Zobacz przykład Gist . Dotyczy to przynajmniej wersji Git v2.7.0.
To nie dodaje nic nowego. Git stash push jest już wspomniany w wielu odpowiedziach
JesusFreke
12
Zapisz następujący kod w pliku, na przykład o nazwie stash. Wykorzystanie jest stash <filename_regex>. Argument jest wyrażeniem regularnym dla pełnej ścieżki pliku. Na przykład, aby ukryć plik a / b / c.txt stash a/b/c.txtlub stash .*/c.txtitp.
Świetna metoda. Wybrałbym to jako odpowiedź. Wskazówka dla przyszłych czytelników: musisz dopasować pełną ścieżkę. np. stash subdir / foo.c
er0
12
Na wypadek, gdybyś naprawdę miał na myśli odrzucić zmiany za każdym razem, gdy używasz git stash(i tak naprawdę nie używasz git stash do tymczasowego przechowywania), w takim przypadku możesz użyć
git checkout -- <file>
[ UWAGA ]
To git stashtylko szybsza i prosta alternatywa dla rozgałęziania i robienia rzeczy.
Problem z „pośrednim” rozwiązaniem VonC polegającym na kopiowaniu plików poza repozytorium Git polega na tym, że tracisz informacje o ścieżce, co sprawia, że kopiowanie wiązki plików jest nieco kłopotliwe.
Łatwiej jest użyć tar (prawdopodobnie podobne narzędzia); zamiast kopiować:
tar cvf /tmp/stash.tar path / to / some / file path / to / some / other / file (... itd.)
git checkout path / to / some / file path / to / some / other / file
checkout -fnie jest potrzebne, wystarczy checkout(bez -f), zaktualizowałem odpowiedź.
eleotlecram
8
Czasami dokonałem niepowiązanej zmiany w moim oddziale, zanim go dokonałem, i chcę przenieść go do innej gałęzi i zatwierdzić osobno (np. Master). Robię to:
git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...
Uwaga pierwsza stashi stash popmogą być wyeliminowane, można nosić wszystkie swoje przejście do masteroddziału po kasę, ale tylko wtedy, gdy nie ma żadnych konfliktów. Również jeśli tworzysz nową gałąź dla częściowych zmian, będziesz potrzebował skrytki.
Możesz to uprościć, zakładając brak konfliktów i brak nowej gałęzi:
git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...
Tymczasowo popełnij wszystko, czego nie chcesz przechowywać.
Dodaj wszystko inne, a następnie schowaj.
Pop tymczasowe zatwierdzenie, uruchamiając git reset, celując w zatwierdzenie przed tymczasowym.
Można to wszystko zrobić w ciągu kilku sekund w SourceTree, gdzie możesz po prostu kliknąć pliki (lub nawet pojedyncze linie), które chcesz dodać. Po dodaniu wystarczy zatwierdzić je do tymczasowego zatwierdzenia. Następnie kliknij pole wyboru, aby dodać wszystkie zmiany, a następnie kliknij ukryj, aby ukryć wszystko. Po usunięciu ukrytych zmian, rzuć okiem na listę zatwierdzeń i zanotuj skrót dla zatwierdzenia przed tymczasowym zatwierdzeniem, a następnie uruchom polecenie „git reset hash_b4_temp_commit”, co w zasadzie przypomina „wyskakiwanie” zatwierdzenia przez zresetowanie gałęzi do popełnić tuż przed tym. Teraz masz tylko rzeczy, których nie chciałeś schować.
Chciałbym użyć git stash save --patch. Uważam, że interaktywność nie jest denerwująca, ponieważ istnieją opcje pozwalające zastosować żądaną operację do całych plików.
Próbowałem, ale nic się nie stało. Gdy nie git applymam błędu, ale zmiany nie są przywracane
ClementWalter 10.04.17.04
Plik poprawki wygenerowany w / tmp został prawdopodobnie usunięty. Możliwe, że uruchomiłeś się ponownie między różnicą a aplikacją. Wypróbuj inną, bardziej stałą lokalizację. To działa. Sprawdź także zawartość pliku poprawki.
Christophe Fondacci
4
Przejrzałem odpowiedzi i komentarze na ten temat i kilka podobnych wątków. Należy pamiętać, że żadne z poniższych poleceń nie jest poprawne, aby móc przechowywać określone pliki śledzone / nieśledzone :
Do przechowywania jednego pliku użyj git stash --patch [file].
To będzie szybka: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Po prostu wpisz a(ukryj ten kawałek i wszystkie późniejsze fragmenty w pliku) i nic ci nie będzie.
@FilipeEsperandio pushdziała tylko w nowszych wersjach Git, kiedyś save. W obu przypadkach pushlub savesą implikowane przez wywołanie stash: „Wywołanie git stash bez żadnych argumentów jest równoważne z git stash push”, docs
Patrick
2
Podobna sytuacja. Zatwierdziłem i zdałem sobie sprawę, że to nie jest w porządku.
git commit -a -m "message"
git log -p
Na podstawie odpowiedzi pomogło mi to.
# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
Nie wiem, jak to zrobić w wierszu poleceń, używając tylko SourceTree. Powiedzmy, że zmieniłeś plik A i masz dwa porcje zmian w pliku B. Jeśli chcesz ukryć tylko drugi przystojniak w pliku B i pozostawić wszystko inne bez zmian, wykonaj następujące czynności:
Pokaż wszystko
Wprowadź zmiany w kopii roboczej, które cofną wszystkie zmiany w pliku A. (np. Uruchom zewnętrzne narzędzie do porównywania i dopasuj pliki).
Spraw, aby plik B wyglądał tak, jakby zastosowano do niego tylko drugą zmianę. (np. uruchom zewnętrzne narzędzie do porównywania i cofnij pierwszą zmianę).
Utwórz skrytkę za pomocą opcji „Zachowaj zmiany etapowe”.
git add . //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash //stash the file(s)
git reset . // unstage all staged files
git stash pop // unstash file(s)
Nie powinieneś tego robić. Odpowiedź powinna stanowić rozwiązanie kwestii. Możesz po prostu zadać własne pytanie.
L_J
to rozwiązanie jest jedną z najłatwiejszych odpowiedzi na to pytanie. przeczytaj pytanie, porównaj wszystkie odpowiedzi i moje, a jeśli masz jakiekolwiek wątpliwości, że ta odpowiedź nie jest odpowiednim rozwiązaniem ani niewystarczającą informacją o pytaniu, możemy porozmawiać ponownie.
celikz
To nie zadziała, ponieważ trzecie polecenie „git stash” nie będzie honorować przemieszczanych plików. Zarówno pliki etapowe, jak i niestacjonarne trafią do magazynu. Pytania w szczególności dotyczą sposobu
przechowywania
0
Jednym skomplikowanym sposobem byłoby najpierw zatwierdzenie wszystkiego:
git add -u
git commit // creates commit with sha-1 A
Zresetuj z powrotem do pierwotnego zatwierdzenia, ale pobieraj plik_jedna z nowego zatwierdzenia:
git reset --hard HEAD^
git checkout A path/to/the_one_file
Teraz możesz ukryć jeden_plik_pliku:
git stash
Oczyszczanie poprzez zapisanie zatwierdzonej zawartości w systemie plików podczas resetowania do pierwotnego zatwierdzenia:
git stash --keep-index
zachowuje indeks, ale ukrywa wszystko - zarówno w indeksie, jak i poza nim.git diff -- *filename* > ~/patch
potemgit checkout -- *filename*
i później możesz ponownie zastosować łatkę za pomocągit apply ~/patch
git stash push [--] [<pathspec>...]
.Odpowiedzi:
Uwaga : następująca odpowiedź dotyczy git przed git 2.13. W przypadku wersji 2.13 i nowszych sprawdź kolejną odpowiedź poniżej .
Ostrzeżenie
Jak zauważono w komentarzach, umieszcza to wszystko w skrytce, zarówno inscenizowane, jak i niestacjonarne. --Keep-index po prostu pozostawia indeks sam po zakończeniu skrytki. Może to powodować konflikty scalania, gdy później wyskakujesz skrytka.
Spowoduje to ukrycie wszystkiego, czego wcześniej nie dodałeś. Tylko
git add
rzeczy, które chcesz zachować, a następnie uruchom.Na przykład, jeśli chcesz podzielić stary zatwierdzenie na więcej niż jeden zestaw zmian, możesz użyć tej procedury:
git rebase -i <last good commit>
edit
.git reset HEAD^
git add <files you want to keep in this change>
git stash --keep-index
git add
żadnych zmianach.git commit
git stash pop
git rebase --continue
źródło
git stash save -k
, tak, indeks (zielony wgit stat
) jest zachowany, ale cały zestaw zmian (zarówno zielony, jak i czerwony) trafia do schowka. Jest to sprzeczne z żądaniem PO: „ukryj tylko niektóre zmiany”. Chcę ukryć tylko część czerwonego (do wykorzystania w przyszłości).git stash -p
jest dokładnie tym, czego szukałem. Zastanawiam się, czy ten przełącznik został dodany dopiero niedawno.git stash --keep-index
jest zepsuty. Jeśli wprowadzisz więcej zmian, spróbujgit stash pop
później uzyskać konflikty scalania, ponieważ skrytka zawiera zmienione pliki, które trzymałeś, a nie tylko te, których nie zachowałeś. Na przykład: zmieniam pliki A i B, a następnie przechowuję B, ponieważ chcę przetestować zmiany w A; Znajduję problem z A, który następnie naprawiam; Popełniam A; Teraz nie mogę odblokować, ponieważ stara wersja A znajduje się w schowku bez wyraźnego powodu powodującego konflikt scalania. W praktyce A i B mogą być wieloma plikami, być może nawet obrazami binarnymi lub czymś takim, więc w zasadzie muszę się poddać i stracić B.Możesz także użyć
git stash save -p "my commit message"
. W ten sposób możesz wybrać, które przystawki mają być dodane do skrytki, a także całe pliki.Zostaniesz poproszony o kilka działań dla każdego przystojniaka:
źródło
stash -p
. Przyznaję tę odpowiedź, ponieważ pozostaje ona najbardziej interaktywna / przyjazna dla użytkownika.git stash save -p my stash message
:; ponieważ kolejność argumenstów nie jest zbyt intuicyjna ...git log -p
, myślę, że-p
flaga musi oznaczać „rób fajne rzeczy, które chcę, ale nie umiem wyrazić”.Ponieważ git zasadniczo polega na zarządzaniu całą zawartością i indeksem repozytorium (a nie jednym lub kilkoma plikami),
git stash
zajmuje się, co nie dziwi,z całym katalogiem roboczym.W rzeczywistości od wersji Git 2.13 (II kwartał 2017 r.) Można przechowywać poszczególne pliki za pomocą
git stash push
:Uproszczony przykład:
Przypadek testowy tej funkcji pokazuje kilka dodatkowych opcji:
Oryginalna odpowiedź (poniżej, czerwiec 2010 r.) Dotyczyła ręcznego wybierania tego, co chcesz ukryć.
Komentarze Casebash :
bukzor „s odpowiedź (upvoted, listopad 2011) sugeruje bardziej praktyczne rozwiązanie, oparte na
git add
+git stash --keep-index
.Idź i poproś jego odpowiedź, która powinna być oficjalna (zamiast mojej).
O tej opcji chhh wskazuje w komentarzach alternatywny przepływ pracy:
(Oryginalna odpowiedź z czerwca 2010: skrytka ręczna)
Jednak
git stash save --patch
może pozwolić na osiągnięcie częściowego ukrywania, którego szukasz:Spowoduje to jednak zapisanie pełnego indeksu (który może nie być tym, czego chcesz, ponieważ może on zawierać inne pliki już zindeksowane) oraz częściowego drzewa roboczego (które może wyglądać jak ten, który chcesz ukryć).
może być lepsze dopasowanie.
Jeśli
--patch
nie działa, proces ręczny może:W przypadku jednego lub kilku plików rozwiązaniem pośrednim byłoby:
(w rzeczywistości eleotlecram proponuje ciekawą alternatywę )
git stash
git stash
# tym razem ukryte są tylko te pliki, które chceszgit stash pop stash@{1}
# zastosuj ponownie wszystkie modyfikacje plikówgit checkout -- afile
# zresetuj plik do zawartości HEAD, przed wszelkimi lokalnymi modyfikacjamiPod koniec tego dość uciążliwego procesu będziesz mieć tylko jeden lub kilka plików ukrytych.
źródło
git reset
(mieszany)git is fundamentally about managing a all repository content and index and not one or several files
- to implementacja przesłaniająca rozwiązywany problem; to wyjaśnienie, ale nie uzasadnienie. Każdy system kontroli źródła ma na celu „zarządzanie wieloma plikami”. Zobacz, jakie komentarze są najczęściej oceniane.Kiedy
git stash -p
(lubgit add -p
zstash --keep-index
) byłoby zbyt uciążliwe, znalazłem to łatwiejsze w użyciudiff
,checkout
orazapply
:Aby „ukryć” tylko określony plik / katalog:
Potem
źródło
git add -p
wspomnianej powyżej w mojej odpowiedzi. +1.git diff > file.diff
igit apply
są to moje zwykłe narzędzia do częściowego ukrywania. Być może będę musiał rozważyć zmianęgit stash -p
na większe zestawy zmian.patch = log --pretty=email --patch-with-stat --reverse --full-index --binary
. Pamiętaj jednak, że wymaga to wprowadzenia zmian do zatwierdzenia poprawki.../../foo/bar.txt
. Łatka generuje OK, ale muszę przejść do katalogu głównego repozytorium, aby zastosować łatkę. Więc jeśli masz z tym problem - po prostu upewnij się, że robisz to z katalogu głównego repozytorium.Użyj
git stash push
, jak to:Na przykład:
Jest to dostępne od Gita 2.13, wydanego wiosną 2017 roku.
źródło
git stash push
już w mojej odpowiedzi powyżej w marcu, 5 miesięcy temu. I wyszczególniłem tutaj nowe polecenie Git 2.13: stackoverflow.com/a/42963606/6309 .git stash apply
do odzyskania ukrytych zmian?Załóżmy, że masz 3 pliki
i chcesz ukryć tylko b.rb i c.rb, ale nie a.rb
możesz zrobić coś takiego
I gotowe! HTH.
źródło
Inny sposób to zrobić:
Wymyśliłem to po tym, jak (ponownie) trafiłem na tę stronę i nie podobały mi się dwie pierwsze odpowiedzi (pierwsza odpowiedź po prostu nie odpowiada na pytanie i nie bardzo lubiłem pracę w
-p
trybie interaktywnym).Pomysł jest taki sam, jak sugerowany przez @VonC przy użyciu plików poza repozytorium, zapisujesz zmiany, które chcesz gdzieś, usuwasz zmiany, których nie chcesz, w skrytce, a następnie ponownie stosujesz zmiany, które usunąłeś z drogi. Jednak użyłem skrytki git jako „gdzieś” (w rezultacie na końcu jest jeden dodatkowy krok: usunięcie blokad, które umieściłeś w skrytce, ponieważ również je usunąłeś).
źródło
Aktualizacja (14.02.2015) - Napisałem nieco skrypt, aby lepiej obsługiwać przypadki konfliktów, które powinny być teraz przedstawiane jako konflikty nie połączone, a nie pliki .rej.
Często intuicyjnie jest robić odwrotność podejścia @ bukzora. To znaczy, aby wprowadzić pewne zmiany, a następnie ukryć tylko te zmiany etapowe.
Niestety, git nie oferuje skrytki git - tylko indeksowej lub podobnej, więc wymyśliłem skrypt, aby to zrobić.
Możesz zapisać powyższy skrypt
git-stash-index
gdzieś na swojej ścieżce, a następnie wywołać go jako git stash-indexTeraz skrytka zawiera nowy wpis, który zawiera tylko zmiany, które zainscenizowałeś, a twoje drzewo robocze nadal zawiera wszelkie zmiany niestacjonarne.
W niektórych przypadkach zmiany działającego drzewa mogą zależeć od zmian indeksu, więc gdy ukryjesz zmiany indeksu, zmiany w drzewie roboczym będą powodowały konflikt. W takim przypadku otrzymasz zwykłe nierozłączone konflikty, które możesz rozwiązać za pomocą git merge / git scaletool / etc.
źródło
pushd
zamiastcd
ipopd
na końcu skryptu, więc jeśli skrypt się powiedzie, użytkownik znajdzie się w tym samym katalogu, co przed uruchomieniem.Jeśli nie chcesz określać wiadomości z ukrytymi zmianami, podaj nazwę pliku po podwójnym myślniku.
Jeśli jest to nieśledzony / nowy plik, najpierw musisz go wyeksponować.
Ta metoda działa w wersjach git 2.13+
źródło
Ponieważ tworzenie gałęzi w Git jest banalne, możesz po prostu utworzyć gałąź tymczasową i sprawdzić w niej poszczególne pliki.
źródło
Możesz po prostu to zrobić:
lub z opcjonalnym komunikatem
źródło
Zapisz następujący kod w pliku, na przykład o nazwie
stash
. Wykorzystanie jeststash <filename_regex>
. Argument jest wyrażeniem regularnym dla pełnej ścieżki pliku. Na przykład, aby ukryć plik a / b / c.txtstash a/b/c.txt
lubstash .*/c.txt
itp.Kod do skopiowania do pliku:
źródło
Na wypadek, gdybyś naprawdę miał na myśli odrzucić zmiany za każdym razem, gdy używasz
git stash
(i tak naprawdę nie używasz git stash do tymczasowego przechowywania), w takim przypadku możesz użyć[ UWAGA ]
To
git stash
tylko szybsza i prosta alternatywa dla rozgałęziania i robienia rzeczy.źródło
Problem z „pośrednim” rozwiązaniem VonC polegającym na kopiowaniu plików poza repozytorium Git polega na tym, że tracisz informacje o ścieżce, co sprawia, że kopiowanie wiązki plików jest nieco kłopotliwe.
Łatwiej jest użyć tar (prawdopodobnie podobne narzędzia); zamiast kopiować:
źródło
checkout -f
nie jest potrzebne, wystarczycheckout
(bez-f
), zaktualizowałem odpowiedź.Czasami dokonałem niepowiązanej zmiany w moim oddziale, zanim go dokonałem, i chcę przenieść go do innej gałęzi i zatwierdzić osobno (np. Master). Robię to:
Uwaga pierwsza
stash
istash pop
mogą być wyeliminowane, można nosić wszystkie swoje przejście domaster
oddziału po kasę, ale tylko wtedy, gdy nie ma żadnych konfliktów. Również jeśli tworzysz nową gałąź dla częściowych zmian, będziesz potrzebował skrytki.Możesz to uprościć, zakładając brak konfliktów i brak nowej gałęzi:
Skrytka nawet nie potrzebna ...
źródło
Można to zrobić w 3 krokach za pomocą SourceTree.
Można to wszystko zrobić w ciągu kilku sekund w SourceTree, gdzie możesz po prostu kliknąć pliki (lub nawet pojedyncze linie), które chcesz dodać. Po dodaniu wystarczy zatwierdzić je do tymczasowego zatwierdzenia. Następnie kliknij pole wyboru, aby dodać wszystkie zmiany, a następnie kliknij ukryj, aby ukryć wszystko. Po usunięciu ukrytych zmian, rzuć okiem na listę zatwierdzeń i zanotuj skrót dla zatwierdzenia przed tymczasowym zatwierdzeniem, a następnie uruchom polecenie „git reset hash_b4_temp_commit”, co w zasadzie przypomina „wyskakiwanie” zatwierdzenia przez zresetowanie gałęzi do popełnić tuż przed tym. Teraz masz tylko rzeczy, których nie chciałeś schować.
źródło
Chciałbym użyć
git stash save --patch
. Uważam, że interaktywność nie jest denerwująca, ponieważ istnieją opcje pozwalające zastosować żądaną operację do całych plików.źródło
git stash -p
pozwala szybko schować cały plik i wyjść z niego później.Każda odpowiedź tutaj jest tak skomplikowana ...
Co z tym „ukryć”:
Aby cofnąć zmianę pliku:
Dokładnie takie samo zachowanie, jak ukrycie jednego pliku i ponowne włożenie go z powrotem.
źródło
git apply
mam błędu, ale zmiany nie są przywracanePrzejrzałem odpowiedzi i komentarze na ten temat i kilka podobnych wątków. Należy pamiętać, że żadne z poniższych poleceń nie jest poprawne, aby móc przechowywać określone pliki śledzone / nieśledzone :
git stash -p (--patch)
: wybierz porcje ręcznie, z wyłączeniem nieśledzonych plikówgit stash -k (--keep-index)
: ukryj wszystkie śledzone / nieśledzone pliki i przechowuj je w katalogu roboczymgit stash -u (--include-untracked)
: ukryj wszystkie śledzone / nieśledzone plikigit stash -p (--patch) -u (--include-untracked)
: niepoprawna komendaObecnie najbardziej rozsądnym sposobem na ukrycie określonych plików śledzonych / nieśledzonych jest:
Napisałem prosty skrypt dla tej procedury w odpowiedzi na inne pytanie , a tutaj są kroki do wykonania procedury w SourceTree .
źródło
Rozwiązanie
Zmiany lokalne:
Aby utworzyć skrytkę „my_stash” ze zmianami tylko w file_C :
Gotowy.
Wyjaśnienie
Możesz użyć statusu git między krokami, aby zobaczyć, co się dzieje.
źródło
Taka sytuacja występuje podczas próby przełączenia między dwiema gałęziami.
Spróbuj dodać pliki, używając „
git add filepath
”.Później wykonaj tę linię
źródło
Do przechowywania jednego pliku użyj
git stash --patch [file]
.To będzie szybka:
Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?
. Po prostu wpisza
(ukryj ten kawałek i wszystkie późniejsze fragmenty w pliku) i nic ci nie będzie.źródło
push
jak wgit stash push --patch [file]
push
działa tylko w nowszych wersjach Git, kiedyśsave
. W obu przypadkachpush
lubsave
są implikowane przez wywołaniestash
: „Wywołanie git stash bez żadnych argumentów jest równoważne z git stash push”, docsPodobna sytuacja. Zatwierdziłem i zdałem sobie sprawę, że to nie jest w porządku.
Na podstawie odpowiedzi pomogło mi to.
źródło
W tej sytuacji ja
git add -p
(interaktywnie),git commit -m blah
a następnie chowam, co pozostało, jeśli to konieczne.źródło
Nie wiem, jak to zrobić w wierszu poleceń, używając tylko SourceTree. Powiedzmy, że zmieniłeś plik A i masz dwa porcje zmian w pliku B. Jeśli chcesz ukryć tylko drugi przystojniak w pliku B i pozostawić wszystko inne bez zmian, wykonaj następujące czynności:
źródło
źródło
Jednym skomplikowanym sposobem byłoby najpierw zatwierdzenie wszystkiego:
Zresetuj z powrotem do pierwotnego zatwierdzenia, ale pobieraj plik_jedna z nowego zatwierdzenia:
Teraz możesz ukryć jeden_plik_pliku:
Oczyszczanie poprzez zapisanie zatwierdzonej zawartości w systemie plików podczas resetowania do pierwotnego zatwierdzenia:
Tak, trochę niezręcznie ...
źródło
Nie znalazłem odpowiedzi na to, czego potrzebowałem, a to jest tak proste, jak:
Skrywa to dokładnie jeden plik.
źródło
Szybka odpowiedź
Aby przywrócić określony zmieniony plik w git, możesz wykonać następujący wiersz:
Oto rzeczywisty przykład:
źródło
Jeśli chcesz ukryć niektóre zmienione pliki, po prostu
Przechowa wszystkie niestabilne zmienione pliki
źródło