2013-01-31 21 views
9

Mam zmiany w moim obszarze przemieszczania, a inne nie są jeszcze uruchomione (niektóre pliki mają zmiany zarówno w obszarze przemieszczania, jak i poza nim). Chciałbym odwrócić zawartość obszaru przemieszczania i zmiany, które nie są etapowe. Czy istnieje skrót umożliwiający wykonanie tego, bez wykonywania bardziej złożonych czynności, takich jak lokalne zatwierdzenia side-branch, diffs lub skrypty [etc.]? Dzięki.Git invert staging area

+8

możliwe duplikat [? Jaka jest najkrótsza droga do wymiany wystawił i Unstaged zmiany git] (http://stackoverflow.com/questions/3573410/what-is- najkrótsza droga do zamiany, zainscenizowana i niezaangażowana-zmiany-w-gicie) –

+0

Wow, dzięki za link. Nie te same wyszukiwane hasła, ale ten sam problem. – moala

Odpowiedz

0

Oto, czego używam, aby rozwiązać ten problem.

Najpierw git reset spowoduje usunięcie wszystkich plików z "przemieszczania" do "plików nie wystawionych na zatwierdzenie". Pliki, które znajdują się zarówno „inscenizacji” i „pliki nie wystawiono popełnić” zachowa swoje najnowsze zmiany, które aktualnie znajdują się w swoje „nie plików wystawił do popełnienia”

następnie

git add /path/to/file konkretne pliki potrzebne aby dodać do inscenizacji

Niezupełnie krótkie cięcia, ale dostaje zadanie

Odwrotnie, Po git reset, można git checkout /path/to/file dla plików, które są obecnie „nie wystawiono popełnić”, które don” t chcesz dodać do inscenizacji. Spowoduje to usunięcie wybranych plików z „nie wystawił do popełnienia”

następnie uruchomić git add . który doda wszystkie pliki „nie wystawił do popełnienia” do „inscenizacji” - cokolwiek jest łatwiejsza do sytuacji

+0

Właściwie, wolałbym tego nie robić ręcznie, ponieważ limit między etapami i etapami jest dość złożony: nawet w niektórych plikach niektóre wiersze są wystawiane, a inne nie. – moala

+0

Czy ostatnio wydawało się, że moja edycja dotyczy zarówno plików wystawionych, jak i nie wystawionych? –

+0

Co masz na myśli, mówiąc: "mógłbyś odprawić pliki, których nie chcesz [...]"? to jest dla mnie dość niejasne ... – moala

3

Istnieje prawdopodobnie więcej niż jednym ze sposobów, aby to zrobić, ale myślę, że takie podejście - nie ma jeszcze gotowych skrót do tego, ale można dość łatwo napisać własny skrypt, aby śledzić ten proces:

  1. generować łatka dla rzeczy, która jest aktualnie w twoim wo rking katalogu, ale nie w indeksie jeszcze (rzeczy nie zrobili dla git add)

    git diff-files -p > /tmp/unstaged.patch 
    
  2. Generowanie poprawkę na to, co zostało już dodane do indeksu przeciwko aktualnej HEAD

    git diff-index --cached -p HEAD > /tmp/staged.patch 
    
  3. Resetowanie indeksu i katalog roboczy do HEAD

    git reset --hard HEAD 
    
  4. A pply swoją Unstaged poprawkę zarówno do katalogu roboczego i indeksu, powodując zmiany te są wystawiane

    git apply --index /tmp/unstaged.patch 
    
  5. Zastosuj wystawił plaster przeciwko jedynej katalogu roboczym

    git apply /tmp/staged.patch 
    

w zależności od dokładnego charakter zmian, kroki 4 i/lub 5 mogą powodować konflikty scalania, które należy rozwiązać ręcznie, ale nie jestem pewien, czy istnieje czysty sposób na całkowite uniknięcie takiej możliwości.

Pewnie przydałby git stash wykonać kroki 1 i 4 zamiast z powyższych poleceń, ale nie jestem pewien, że będzie naprawdę zyskać nic ...

Ponadto, może chcesz przejrzeć strony człowiek dla git diff-* i git apply najpierw komendy, aby sprawdzić, czy istnieją inne opcje, które mogą być użyteczne.

4

Oto jak to zrobić:

  1. Commit indeks do tymczasowego popełnić
  2. Commit pozostałą do wtórnego tymczasowy popełnić
  3. przełączyć kolejność zatwierdzeń z interaktywnym rebase
  4. Mieszanego resetowanie
  5. Miękki reset

To może być wpisany ręcznie dość szybko, zwłaszcza jeśli używasz Vima do popełnienia wiadomości:

git commit -m tmp1 
git add . # optionally with `git add -u` if there are deletions 
git commit -m tmp2 
git rebase -i HEAD~2 # swap the order of the commits; `ddp:wq` in vi 
git reset HEAD~1 
git reset HEAD~1 --soft 
+0

Podoba mi się to, z wyjątkiem ręcznej edycji, aby zamienić zatwierdzenia. http://stackoverflow.com/questions/16203562/programmatically-swap-last-two-commits –

+0

Dobra uwaga. Ale problemem dla mnie osobiście jest to, że nie robię tego na tyle, aby napisać skrypt skrótu i ​​zapamiętać, jak to się nazywa i jak działa. Interaktywne przebieranie robię prawie codziennie i jest to dla mnie niezwykle intuicyjne i wydajne. – gtd

3

podstawie odpowiedzi GTD i zdolność do skryptu odwrócenie zobowiązuje to co używam teraz:

[alias]                                                    
    swaplast = !git tag _invert && git reset --hard HEAD~2 && git cherry-pick _invert _invert~1 && git tag -d _invert                        
    invertindex = !git commit -m tmp1 && git add -A && git commit -m tmp2 && git swaplast && git reset HEAD~1 && git reset HEAD~1 --soft 

Zamieszczone na moim blogu tutaj: http://blog.ericwoodruff.me/2013/12/inverting-git-index.html

+2

Zrobiłem kilka badań i testów, a to jest moja nieautoryzowana dokumentacja: 'swaplast' zamienia ostatni i jeden przed ostatnim zatwierdzeniem. Uwaga: Odrzuca niezatwierdzone zmiany bez powiadomienia. 'invertindex' zamienia zmiany etapowe i nieza strojone, w tym nieśledzone. – Melebius

+0

Jeśli z jakiegoś powodu to się nie powiedzie, może być konieczne uruchomienie 'git cherry-pick --abort', zanim będzie można ponownie uruchomić' git invertindex'. – u01jmg3