Jak ukrywasz nieśledzony plik?

1432

Mam zmiany w pliku oraz nowy plik i chciałbym użyć git stash, aby je odłożyć, gdy przechodzę do innego zadania. Ale git sam w sobie ukrywa tylko zmiany w istniejącym pliku; nowy plik pozostaje w moim pracującym drzewie, zaśmiecając moją przyszłą pracę. Jak ukryć ten nieśledzony plik?

skiphoppy
źródło
27
Pamiętaj, że jeśli masz tylko nieśledzone pliki w swojej skrytce, będzie wyglądać, jakby był pusty, ponieważ git stash shownic nie zwraca i możesz ulec pokusie, aby go upuścić (tak jak zrobiłem, gdy zawierał przydatny skrypt, który napisałem kilka miesięcy temu → jak odzyskać upuszczoną skrytkę )
Maxime R.

Odpowiedzi:

1918

Aby ukryć swój katalog roboczy, w tym nieśledzone pliki (szczególnie te, które znajdują się w .gitignore), prawdopodobnie prawdopodobnie chcesz użyć tego cmd:

git stash --include-untracked

Więcej szczegółów:

Aktualizacja 17 maja 2018 r .:

Nowe wersje git mają teraz git stash --allprzechowywanie wszystkich plików, w tym plików nieśledzonych i ignorowanych.
git stash --include-untrackednie dotyka już ignorowanych plików (testowane na git 2.16.2).

Oryginalna odpowiedź poniżej:

Uwaga, zrobienie tego spowoduje trwałe usunięcie plików, jeśli masz jakieś wpisy katalogu / * w pliku gitignore.

Począwszy od wersji 1.7.7 możesz używać git stash --include-untrackedlub git stash save -uprzechowywać ukryte pliki bez umieszczania ich w stosie.

Dodaj ( git add) plik i zacznij go śledzić. Następnie ukryj. Ponieważ cała zawartość pliku jest nowa, zostaną one ukryte i można w razie potrzeby nimi manipulować.

sykora
źródło
4
Dlaczego ukrywanie nadal ukrywa zmieniające istniejące pliki, mimo że te zmiany nie zostały wprowadzone?
Alan Christensen
6
@ alan-christensen Przeczytaj OPIS kernel.org/pub/software/scm/git/docs/git-stash.html . Chodzi o to, aby mieć czyste drzewo po schowaniu.
Kelvin,
3
@Kelvin, co miałem na myśli w moim komentarzu, to to, że nie przechowuje nowych plików, chyba że zostały one ustawione, ale ukrywa istniejące pliki, nawet jeśli nie zostały ustawione. Wydaje mi się niespójne.
Alan Christensen
11
@AlanChristensen chodzi o to, aby ukryć rzeczy, które mogą zostać zastąpione przez kasę innego oddziału.
jwg
3
Ponieważ masz tutaj najlepszą odpowiedź, z dwóch powodów poprosiłbym o podanie jej git stash --include-untrackedwcześniej git stash --all. Po pierwsze, lepiej odpowiada na pytanie OP w 2019 r., A po drugie, ponieważ - wszystko robi coś, czego większość użytkowników prawdopodobnie nie chce, ponieważ usuwa wszystkie pliki, które są
.gitignored
411

Począwszy od git 1.7.7, git stashakceptuje --include-untrackedopcję (lub skrót -u). Aby dołączyć do pliku ukryte pliki, użyj jednego z następujących poleceń:

git stash --include-untracked
git stash -u

Uwaga, zrobienie tego spowoduje trwałe usunięcie plików, jeśli masz jakieś wpisy katalogu / * w pliku gitignore.

John Kary
źródło
15
Cool - w końcu działa zgodnie z opisem na stronie podręcznika. Brak ukrywania (i czyszczenia) nowych plików jest zepsutym zachowaniem.
Steve Bennett,
1
moja wersja git to 1.9.1 i nawet jeśli to, co mam, .gitignorewygląda tak ignoredDirectoryi nie ignoredDirectory/*usuwa tych, które nie są śledzone. Nawet nieśledzone pliki nie tylko katalogi.
theNieznany777
22
Czy możesz wyjaśnić ostrzeżenie? Dlaczego miałby usuwać te pliki? Czy je usuwa i nie ukrywa? Używam Gita przez jakiś czas i nie napotkałem tego problemu.
Aleksandr Dubinsky
Czy ostrzeżenie dotyczy również *.extensionwpisów?
arekolek
3
@ aleksandr-dubinsky, @arekolek - git1.8.3 -u( --include-untracked) może przechowywać i usuwać nieśledzone pliki w porządku, ale git stash shownie wyświetla nieśledzonych plików, które są w
skrytce
77

Dodaj plik do indeksu:

git add path/to/untracked-file
git stash

Cała zawartość indeksu, a także wszelkie nieustawione zmiany w istniejących plikach, wszystkie znajdą się w schowku.

skiphoppy
źródło
Co jeśli nie chcesz ukrywać zmian, które są już w indeksie? Czy ukrywanie nowego pliku jest nadal możliwe?
allyourcode
Zatwierdź indeks, ukryj nowy plik, a następnie cofnij zatwierdzenie i / lub sprawdź pliki z zatwierdzenia. To niechlujne rozwiązanie, ale powinno działać.
Gdalya
git add .z jakiegoś powodu nie wziął tego pod uwagę
TheBilTheory
53

W git bash, ukrywanie nieśledzonych plików odbywa się za pomocą polecenia

git stash --include-untracked

lub

git stash -u

http://git-scm.com/docs/git-stash

git stash usuwa wszelkie nieśledzone lub niezaangażowane pliki z twojego obszaru roboczego. I możesz przywrócić skrytkę git za pomocą następujących poleceń

git stash pop

Spowoduje to umieszczenie pliku z powrotem w lokalnym obszarze roboczym.

Moje doświadczenie

Musiałem wykonać modyfikację mojego pliku gitIgnore, aby uniknąć przenoszenia plików .classpath i .project do zdalnego repozytorium. Od tej chwili nie wolno mi przenosić tego zmodyfikowanego .gitIgnore w zdalne repozytorium.

Pliki .classpath i .project są ważne dla środowiska Eclipse - mojego edytora Java.

Najpierw wybiórczo dodałem resztę plików i zobowiązałem się do inscenizacji. Ostateczne wypychanie nie może być jednak wykonane, chyba że zmodyfikowane pliki .gitIgnore i pliki nieśledzone będą mieć na myśli. .project i .classpath nie są ukryte.

użyłem

 git stash 

do ukrywania zmodyfikowanego pliku .gitIgnore.

Do schowania pliku .classpath i .project użyłem

git stash --include-untracked

i usunął pliki z mojego obszaru roboczego. Brak tych plików pozbawia mnie możliwości pracy w miejscu pracy w środowisku Eclipse. Kontynuowałem wykonywanie procedury wypychania zatwierdzonych plików do pilota. Kiedy udało się to zrobić, użyłem

git stash pop

To wkleiło te same pliki z powrotem w moim obszarze roboczym. To dało mi moją zdolność do pracy nad tym samym projektem w środowisku Eclipse. Mam nadzieję, że odrzuci to nieporozumienia.

DolphinJava
źródło
2
Dlaczego nie używasz globalnego gitignore dla plików IDE? To znaczy. użyć ~/.gitignore.
Antti Pihlaja,
20

Jak już powiedziano w innym miejscu, odpowiedź znajduje się git addw pliku. na przykład:

git add path/to/untracked-file
git stash

Jednak pytanie pojawia się również w innej odpowiedzi: Co, jeśli tak naprawdę nie chcesz dodać pliku? O ile mogę powiedzieć, musisz. I następujące działania NIE będą działać:

git add -N path/to/untracked/file     # note: -N is short for --intent-to-add
git stash

to się nie powiedzie, jak następuje:

path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

Więc co możesz zrobić? Cóż, musisz naprawdę dodać plik, jednak możesz później skutecznie go usunąć, używając git rm --cached:

git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop   # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file

Następnie możesz kontynuować pracę, w takim samym stanie, w jakim byłeś wcześniej git add(mianowicie z nieśledzonym plikiem o nazwie path/to/untracked-file; oraz innymi zmianami, które mogłeś mieć do śledzenia plików).

Inną możliwością przepływu pracy w tym przypadku byłoby coś takiego:

git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack

[Uwaga: Jak wspomniano w komentarzu @mancocapac, możesz chcieć dodać --exclude-standarddo git ls-filespolecenia (tak, git ls-files -o --exclude-standard).]

... które można również łatwo napisać w skrypcie - wystarczyłyby nawet aliasy (przedstawione w składni zsh; dostosuj w razie potrzeby) [skróciłem też nazwę pliku, aby pasowała do ekranu bez przewijania w tej odpowiedzi; możesz zamienić alternatywną nazwę pliku]:

alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'

Zauważ, że ten drugi może być lepszy jako skrypt powłoki lub funkcja, aby umożliwić dostarczanie parametrów git stash, na wypadek, gdybyś nie chciał, popale applyi / lub chcesz móc określić konkretną skrytkę, zamiast tylko zajmować pierwsze miejsce jeden. Być może to (zamiast drugiego aliasu powyżej) [białe spacje pasują bez przewijania; dodaj ponownie, aby zwiększyć czytelność]:

function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}

Uwaga : W tym formularzu musisz podać argument akcji, a także identyfikator, jeśli chcesz podać identyfikator skrytki, np. unstashall apply stash@{1}Lubunstashall pop stash@{1}

Które oczywiście umieścisz w swoim .zshrclub jego odpowiedniku, aby istniało długoterminowo.

Mam nadzieję, że ta odpowiedź jest dla kogoś pomocna, łącząc wszystko w jedną odpowiedź.

Lindes
źródło
1
git ls-files -o pokazuje o wiele więcej plików niż te, którymi jestem zainteresowany. z następującego statusu git, który znalazłem dodając --exclude-standardowe działa. git ls-files -o --exclude-standard. Podejrzewam, że „zawiera” tylko nieśledzone pliki, których normalnie nie zignorowałbyś, tzn. Pokazuje tylko nieśledzone pliki, których Twój .gitignore nie odfiltrowałby
mancocapac
20

W wersji git 2.8.1: następujące działa dla mnie.

Aby zapisać zmodyfikowane i nieśledzone pliki w skrytce bez nazwy

git stash save -u

Aby zapisać zmodyfikowane i nieśledzone pliki w skrytce z nazwą

git stash save -u <name_of_stash>

Możesz użyć pop lub zastosować później w następujący sposób.

git stash pop

git stash apply stash@{0}
użytkownik1012513
źródło
Nie usunęło to nieśledzonych plików z mojego komputera, chociaż nie były już wyświetlane jako nieśledzone. git stash shownie pokazałem ich. Kiedy próbowałem git stash apply, pojawiło się „błąd: nie można przywrócić nieśledzonych plików ze skrytki”. Pliki zostały jednak ponownie wymienione jako nieśledzone, ale zmiany w plikach śledzonych nie zostały przywrócone. Myślę, że te pliki można przywrócić indywidualnie, sprawdzając je ze skrytki, ale to rozwiązanie nie było tym, na co liczyłem.
hBrent
9

Byłem w stanie ukryć tylko nieśledzone pliki, wykonując:

git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}

Ostatni wyskakuje skrytka śledzonych plików, pozostawiając w ten sposób tylko te nieśledzone.

Oded
źródło
git stash save -unie tylko zapisuje untrackedpliki, ale zapisuje zarówno pliki, jak trackedi untracked. Myślę, że pierwsze uratowanie, które robisz, nie jest w tym przypadku koniecznością. Jest to dobry schemat w atlassian.com/git/tutorials/saving-changes/...
Drenajów
2
Pytanie brzmi, jak ukryć tylko nieśledzone pliki. Jeśli pominiesz pierwszą skrytkę, to co wyskoczysz? Chodzi o: 1) Śledzenie zapasów. 2) Skrytka bez ładunku. 3) Pop śledzony. Wynik: Nieśledzony pozostaje schowany.
Oded
3

Jeśli chcesz ukryć nieśledzone pliki, ale zachowaj indeksowane pliki (na przykład te, które zamierzasz zatwierdzić), po prostu dodaj -kopcję (zachowaj indeks) do-u

git stash -u -k
Tdy
źródło
2

Możesz to po prostu zrobić za pomocą poniższego polecenia

git stash save --include-untracked

lub

git stash save -u

Aby uzyskać więcej informacji o git stash, odwiedź ten post (kliknij tutaj)

Shubham Mishra
źródło
2

załóżmy, że nowy i nieśledzony plik nazywa się: „views.json”. jeśli chcesz zmienić gałąź poprzez ukrywanie stanu twojej aplikacji, zazwyczaj piszę:

git add views.json

Następnie:

git stash

I byłoby schowane. Następnie mogę po prostu zmienić gałąź za pomocą

git checkout other-nice-branch
martline1
źródło
1

Istnieje kilka poprawnych odpowiedzi tutaj, ale chciałem zwrócić uwagę, że w przypadku nowych całych katalogów, 'git add path'będzie NIE pracę. Więc jeśli masz kilka nowych plików w ścieżce bez śledzenia i zrób to:

git add untracked-path
git stash "temp stash"

spowoduje to wyświetlenie następującego komunikatu:

Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty

a jeśli ścieżka bez śledzenia jest jedyną ścieżką, którą chowasz , skrytka „skrytka tymczasowa” będzie pustą skrytką. Prawidłowym sposobem jest dodanie całej ścieżki, a nie tylko nazwy katalogu (tj. Zakończenie ścieżki znakiem „/”):

git add untracked-path/
git stash "temp stash"
DrStrangepork
źródło
Przynajmniej w moim systemie twoje założenie jest błędne. Działa bez cięcia! Puste katalogi i tak są ignorowane. (macos git 2.6.2)
phobie
0

Pomyślałem, że można to rozwiązać, mówiąc gitowi, że plik istnieje, zamiast przekazywać całą jego zawartość do obszaru pomostowego, a następnie wywołać git stash. Araqnid opisuje jak to zrobić.

git add --intent-to-add path/to/untracked-file

lub

git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file

Jednak to ostatnie nie działa:

$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state
Andrew Grimm
źródło
1
Z tego co wiem, ten pierwszy też nie działa. Zobacz moją odpowiedź na rozwiązanie tego problemu.
Lindes
0
git stash --include-untracked

mój ulubiony, ponieważ zapisuje także pliki, które dodałeś i których nie wystawiłeś.

Hovhannes Babayan
źródło
0

Napotkałem podobny problem podczas korzystania z Sourcetree z nowo utworzonymi plikami (nie byłyby one również uwzględnione w skrytce).

Kiedy najpierw wybrałem opcję „stage all”, a następnie ukryłem nowo dodane komponenty, które były śledzone, a zatem włączone do skrytki.

Ivo van Leeuwen
źródło
To pytanie ma 11 lat i ma już 14 odpowiedzi. Czy przeczytałeś je przed opublikowaniem?
Mickael B.
-7

Kiedyś zastanawiałem się i pragną tej samej funkcji. Ale z czasem zauważyłem, że to naprawdę nie jest potrzebne. Podczas przechowywania możesz pozostawić nowe pliki. Nic „złego” nie może im się przytrafić (gdy sprawdzisz coś innego, git popełni błąd i nie zastąpi istniejącego nieśledzonego pliku)

A ponieważ zazwyczaj przedział czasowy między git stashi git stash popjest raczej niewielki, szybko będziesz potrzebować nieśledzonego pliku. Powiedziałbym więc, że niedogodności związane z wyświetlaniem pliku git statuspodczas pracy nad czymś innym (między git stashi git stash pop) są mniejsze niż niedogodności spowodowane pracą i wymaganą uwagą, w przeciwnym razie próba dodania nieśledzonego pliku do twój zapas.

Dieter_be
źródło
15
To zależy od projektu. Powiedzmy, że nieśledzony plik to (w połowie zapisany) test jednostkowy, a wiązka testowa uruchamia wszystkie testy jednostkowe w katalogu. Itd.
Steve Bennett,
1
Innym przykładem jest praca na dwóch komputerach i możesz przenosić dane z A do B, ale nie z B do A. Jeśli utworzysz nowy fragment kodu, aby rozwiązać problem, który najpierw pojawia się na B, ale że chcesz zarówno na A, jak i na B, chcesz mieć możliwość ukrycia pliku na B, aby po odtworzeniu tego pliku na A, a następnie przeniesieniu go w pakiecie, mogłeś sprawdzić wersję ukrytą, aby sprawdzić, czy nie zrobić błąd.
Gdalya
7
To, że plik nie jest śledzony w jednej gałęzi, nie oznacza, że ​​nie będzie w konflikcie ze plikiem śledzonym w innej gałęzi.
jwg
3
prosty kontrprzykład: plik konfiguracyjny w katalogu .conf.d lub inny, który tylko przez to, że tam jest, modyfikuje zachowanie oprogramowania.
fotanus
Oczywiście potrzebna jest funkcjonalność. Jako dodatkowy przykład nie jest możliwe przełączanie się z jednej gałęzi do drugiej, jeśli masz lokalnie niewyśledzone pliki, które chcesz ukryć.
Demitrian