Git Stash Unbached: jak odłożyć wszystkie zmiany niestacjonarne?

100

Załóżmy, że dwa zestawy zmian są wprowadzane w projekcie wersjonowanym przez git. Jeden zestaw jest wystawiony, a drugi nie.

Chciałbym ponownie sprawdzić zmiany etapowe, uruchamiając projekt w tym stanie (przed zatwierdzeniem). Jaki jest prosty sposób na odłożenie wszystkich niestopowanych zmian i pozostawienie ich tylko w fazie inscenizacji?Potrzebuję więc niestopowanych zmian, aby zniknęły z mojego projektu, ale zostały gdzieś zapisane do dalszej pracy.

To brzmi bardzo podobnie do git stashpolecenia. Ale git stashodsunąłby od mojego projektu zarówno zmiany niestacjonarne, jak i zainscenizowane. I nie mogę znaleźć czegoś takiego git stash uncached.

klm123
źródło
1
Na dzień dzisiejszy w moim git 2.21 nadal nie ma dobrej odpowiedzi. Wszystkie poniższe odpowiedzi są niepoprawne ( -kopcja) lub uciążliwe w użyciu.
Penghe Geng

Odpowiedzi:

100

Aktualizacja 2:
Nie jestem pewien, dlaczego ludzie narzekają na tę odpowiedź, wydaje się, że działa idealnie ze mną, dla plików bez zmian możesz dodać -uflagę

Pełne polecenie staje się git stash --keep-index -u

A oto fragment git-stashpomocy

Jeśli zostanie użyta opcja --keep-index, wszystkie zmiany już dodane do indeksu pozostaną nienaruszone.

Jeśli zostanie użyta opcja --include-untracked, wszystkie nieśledzone pliki są również przechowywane, a następnie czyszczone za pomocą git clean, pozostawiając katalog roboczy w bardzo czystym stanie. Jeśli zamiast tego zostanie użyta opcja --all, ignorowane pliki są ukrywane i czyszczone razem z nieśledzonymi plikami.

A oto gif pokazujący, jak to wygląda:

wprowadź opis obrazu tutaj

Aktualizacja:

Mimo że jest to wybrana odpowiedź, wiele osób zwróciło uwagę, że [odpowiedź poniżej] (https://stackoverflow.com/a/34681302/292408) jest poprawna, polecam ją sprawdzić.

Dzisiaj (31.01.2020) ponownie przetestowałem swoją odpowiedź z wersją git 2.24.0i nadal uważam, że jest poprawna, dodałem powyżej małą notatkę o nieśledzonych plikach. Jeśli uważasz, że to nie działa, podaj również swoją wersję git.

Stara odpowiedź :
Jeśli ta --keep-indexopcja jest używana, wszystkie zmiany już dodane do indeksu pozostają nienaruszone:

git stash --keep-index

Z dokumentacjigit-stash :

Testowanie częściowych zatwierdzeń

Możesz użyć, git stash save --keep-indexgdy chcesz dokonać dwóch lub więcej zatwierdzeń ze zmian w drzewie roboczym i chcesz przetestować każdą zmianę przed zatwierdzeniem:

# ... hack hack hack ...
$ git add --patch foo            # add just first part to the index
$ git stash save --keep-index    # save all other changes to the stash
$ edit/build/test first part
$ git commit -m 'First part'     # commit fully tested change
$ git stash pop                  # prepare to work on all other changes
# ... repeat above five steps until one commit remains ...
$ edit/build/test remaining parts
$ git commit foo -m 'Remaining parts'

Ale jeśli chcesz tylko wizualnie sprawdzić tylko zmiany etapowe, możesz spróbować difftool:

git difftool --cached
Mohammad AbuShady
źródło
4
zobacz także, git stash [-p|--patch]co przypomina interaktywne przechowywanie. Z man git stash"--patch można interaktywnie wybierać porcje z różnicy między HEAD a drzewem roboczym, które mają zostać schowane."
tutaj
1
Zwykle add -p, checkout -pi reset -pnigdy nie próbowałem stash -p, dziękuję za wskazówkę: D
Mohammad AbuShady
20
Zwróć uwagę, że ta odpowiedź również ukryje wprowadzone zmiany.
Ben Flynn,
1
Ta odpowiedź nie jest naprawdę przydatna, ponieważ spowoduje zamieszanie. Ta odpowiedź brzmi lepiej stackoverflow.com/a/34681302/292408 .
Elijah Lynn
1
@ElijahLynn Połączyłem się z inną odpowiedzią, ponieważ znalazłem wiele osób mówiących, że to lepsza odpowiedź, dzięki za komentarz
Mohammad AbuShady
107

Zaakceptowana odpowiedź zawiera również zainscenizowane zmiany, jak wskazało kilku z nich. Oto sposób na zrobienie tego bez wprowadzania zmian w skrytce.

Chodzi o to, aby wykonać tymczasowe zatwierdzenie zmian etapowych, następnie ukryć zmiany niestacjonarne, a następnie cofnąć zatwierdzenie tymczasowe:

# temp commit of your staged changes:
$ git commit --message "WIP"

# -u option so you also stash untracked files
$ git stash -u

# now un-commit your WIP commit:
$ git reset --soft HEAD^

W tym momencie będziesz mieć zapas swoich niestopowanych zmian, aw kopii roboczej będą znajdować się tylko te wprowadzane.

stephen.hanson
źródło
22
To jest naprawdę poprawna odpowiedź IMO. --keep-indexRozwiązaniem w obecnej odpowiedź akceptowanego jeszcze stashes co w indeksie, to po prostu także utrzymuje ją w indeksie. Więc to się powiela i następuje wesołość.
Ken Williams,
4
@KenWilliams <del> hilarity </del> <ins> tragedy </ins>
tuespetre
@KenWilliams To naprawdę mnie irytowało. OP, czy możesz zmienić wybraną odpowiedź?
MikeMurko
2
Ten git add .krok może chcieć zostać ulepszony, git add --allponieważ powinien również pobrać pliki w katalogu powyżej bieżącego katalogu roboczego.
Elijah Lynn
1
Jak dotąd jest to najlepsza odpowiedź, ponieważ opcja --keep-index w zaakceptowanej odpowiedzi jest myląca. To powinna być akceptowana odpowiedź.
Elijah Lynn
22

Okazało się, że zaznaczona odpowiedź nie działa dla mnie, ponieważ potrzebowałem czegoś, co naprawdę przechowywało tylko moje niestrzelone zmiany. Zaznaczona odpowiedź, git stash --keep-indexukrywa zmiany zainscenizowane i niestacjonarne. Plik--keep-indexCzęść tylko opuści indeks nienaruszone na kopii roboczej, jak również. To działa w przypadku OP, ale tylko dlatego, że zadał nieco inne pytanie, niż w rzeczywistości oczekiwał odpowiedzi.

Jedynym prawdziwym sposobem, w jaki udało mi się ukryć zmiany nieokreślone, jest w ogóle nie używać skrytki:

git diff > unstaged.diff
git apply -R unstaged.diff

git checkout -- .będzie również działać zamiast apply -R.

Praca Praca praca...

git apply unstaged.diff
rm unstaged.diff
Plik binarny
źródło
1
Tutaj, na git version 2.6.1.windows.1, git stash -kpracował jako opisane.
koppor
To powinna być akceptowana odpowiedź! Jest jedynym w wielu wątkach przepełnienia stosu, który robi to, co twierdzi i nie polega na wykonywaniu tymczasowych zatwierdzeń!
user643011
1
@ user643011: Zatwierdzenia tymczasowe nie są złą rzeczą w git. Nic nie kosztują i nikogo nie krzywdzą.
Fritz
1
@Fritz: Żadne tymczasowe zatwierdzenia nie są możliwe w niektórych scenariuszach. Może się nie powieść, jeśli masz punkt zaczepienia przed zatwierdzeniem, który sprawdza bieżący działający kod. Jeśli zmiany etapowe są dobre, ale zmiany niestacjonarne nie, to podejście nie spowoduje zatwierdzenia zmian etapowych.
Penghe Geng
1
Nie obejmuje to nieśledzonych plików. Musisz użyć "git ls-files", aby znaleźć i uwzględnić te w
łatce różnicowej
5

Git: Przechowuj niestalizowane zmiany

Spowoduje to przechowywanie wszystkich modyfikacji, których nie dodałeś:

git stash -k

Zauważ, że nowo utworzone (i nie dodane) pliki pozostaną w katalogu roboczym, chyba że użyjesz również -uprzełącznika.

git stash -k -u 

Ponadto, twój katalog roboczy musi być czysty (tj. Wszystkie zmiany muszą zostać dodane), kiedy później git stash pop.

http://makandracards.com/makandra/853-git-stash-unstaged-changes

Cory Danielson
źródło
13
Jest to równoważne z git stash --keep-index. Pliki z etapami są zawarte w schowku.
Benjamin Cheah