2009-09-10 10 views
74

Weź ten scenariusz:Korzystając z GIT, w jaki sposób mogę selektywnie pobierać/scalać zmiany z "widelca" innego?

  1. Postanawiam 'widelec' w kodzie na github.com i zacząć robić moje rutynowe: Edycja - Commit - Push; aka hack hack hack.
  2. Po dokonaniu pewnych zmian widzę zmiany, które inna osoba zrobiła w tym samym projekcie i lubię je!
  3. Postanawiam, że chcę je połączyć w moje. Problem polega na tym, że chcę tylko "części" jednego konkretnego zobowiązania, z kilku popełnionych przez niego zobowiązań.

Jaka byłaby najskuteczniejsza metoda uzyskania wybranej ilości zmian, połączona z moim "widelcem"?

Odpowiedz

112

Po trolling fale świata IRC, ktoś dał wspaniałe rozwiązanie:

git cherry-pick SHA1 --no-commit 
git add --patch 

miejmy nadzieję, że pomoże nikogo innego z tym samym pytaniem!

EDYCJA: OK, może to nie jest takie proste. Oto pełne kroki:

  1. Najpierw trzeba być w repozytorium, wykonaj niezbędne cd -ing dostać się do katalogu roboczego.

  2. Musisz teraz dodać gałąź zdalną, a następnie ją pobrać. Czy to poprzez:

    git remote add someUser git://github.com/someUser/someRepo.git

    git fetch someUser

  3. Można teraz uruchomić polecenia takie jak git log someUser/master znaleźć SHA1 popełnienia chcesz scalić w 'częściowo'.

  4. Gdy masz SHA, można teraz uruchomić:

    git cherry-pick -n SHA1

    gdzie SHA1 jest popełnić SHA, duh!

  5. Prawdopodobnie wystąpią konflikty, w zależności od tego, ile lat ma zatwierdzenie i jak często zmienia się ten konkretny obszar projektu. Przepraszamy, ale musisz ręcznie rozwiązać te problemy za pomocą zaufanego edytora. Więc wyciągnij VIM, lub cokolwiek innego używasz, i zhakuj się konfliktami, aż dojdziesz do etapu, w którym lubisz zmiany.

  6. Teraz trzeba zresetować wskaźnik do wersji HEAD, a następnie można użyć sprawdzony polecenie GIT add --patch wybierać jakie zmiany chcesz:

    git reset HEAD

    git add --patch lub git add -p

  7. Yay! Popełnić czas:

    git commit -m "I merged a select amount of changes"

  8. posprzątać ten bałagan (rzeczy pan nie mówi się w git add --patch) i tylko zachować wybrane zmiany w repozytorium roboczej, uruchom:

    git reset --hard HEAD

    Widocznie git checkout -f to także inna opcja.

+0

Cieszę się, że znalazłeś 'git add -p'; jest niezwykle potężny. Jeśli masz już dane zatwierdzenie (np. Nie użyłeś '--no-commit' na wiku-pick, lub jest to jedno z twoich zatwierdzeń), możesz użyć' git reset HEAD^', aby przewinąć indeks do zatwierdzenia z powrotem, a następnie dodaj zmiany z powrotem za pomocą 'git add -p', zatwierdzając w krokach. Jeśli commit nie znajduje się na końcu gałęzi, możesz użyć 'git rebase -i' i wybrać edycję danego commit. – Cascabel

+0

Bardzo dziękuję za to! –

+1

ładne przejście. Pamiętaj, jeśli chcesz po prostu ** cały ** zatwierdzić, po prostu wyemituj '-n' w kroku 4. W ten sposób:' git cherry-pick SHA1' – Hulvej

1

Jeśli potrzebujesz tylko portu zatwierdzenia, prawdopodobnie najlepiej jest wybrać odpowiedni zatwierdzenie i zresetować pliki, których nie chcesz dotykać.

git cherry-pick SHA1 
git checkout HEAD file1 file2 ... fileN 

Oczywiście, jeśli masz kilka zmodyfikowanych części w pliku, a jedynie chcą zachować niektóre z nich nie masz wyboru, ale edytować plik ręcznie, wycinanie ich zmiany.

+2

Czy wymeldowanie jest konieczne? Czy polecenie cherry pick nie umieszcza zmian w twoim katalogu roboczym? –

2

Nie jestem pewien, czego chcesz. Jeśli chcesz wprowadzić tylko określone zatwierdzenia z innych widelców, możesz użyć git cherry-pick SHA. Pełne wyjaśnienie na gitready.

+0

Jestem po "porcji"/"sekcji"/"kilku linijkach" jednego konkretnego zatwierdzenia, scalone z moim repozytorium. Nieszczególnie specyficzny dla pliku. – Tim

+0

W takim przypadku, git format-patch SHA, git apply jest opcją – hgmnz

2

Bardzo podoba mi się rozwiązanie Tima, jednak czasami lubię majsterkować w vimdiff. Moje rozwiązanie tego problemu jest proste, ale działa dla mnie, ponieważ lubię vim.

Mam vimdiff ustawiony jako mój difftool, a następnie do selektywnego scalania I diff oddziału:

git difftool <branch> <file> 

Potem idę do okienka z wersją obecnego oddziału i edytowania oryginału w vim (czasami tego ISN „t konieczne, ale czasami vimdiff otwiera wersję w/tmp) i wyłączyć read-only mode:

:e <file> 
:set readonly! 

teraz mogę użyć narzędzia Patch vim takich jak do i dp zastosować to, co chcę, i uczynić inny mały edytuje, jak idę. Kiedy skończę, zapiszę plik, wyjdę z vima, a następnie przejrzę i zatwierdzę plik w git jak zwykłą edycję.

Tak jak powiedziałem, nie jest to szczególnie wyrafinowane, ale jest bardzo potężne i nadal działa w linii poleceń. Po prostu pamiętaj o dodaniu wyraźnego komunikatu zatwierdzenia, ponieważ git nie będzie automatycznie zawierał wiadomości o scaleniu.

vimdiff example http://j.mp/1dZVllt

+0

Nie sądzę, że ta odpowiedź w pełni kwalifikuje się jako godna niezależna, w pełni rozwinięta odpowiedź. Przydatne informacje, ale niezbyt istotne. (dlaczego jest na szczycie odpowiedzi?) –

Powiązane problemy