github: dodawanie zatwierdzeń do istniejącego żądania ściągnięcia

88

Otworzyłem żądanie ściągnięcia do repozytorium rails na github, używając przycisku Rozwidlaj i edytuj ten plik .

Teraz, po otrzymaniu opinii na temat mojego PR, chciałem dodać więcej zatwierdzeń. więc oto co zakończyłem, robiąc

$ git clone [email protected]:gaurish/rails.git #my forked repo
$ git rebase -i 785a2e5 #commit hash of my commit using which PR was opened
$ git checkout patch-3 #branch name I had to send my commits under to be shown in that PR
$ git commit -am "Changes done as per feedback"
$ git push origin patch-3

To działało dobrze, ale wydaje się dość złożonym przepływem pracy. Może się mylę, coś nie tak?

moje pytanie brzmi: czy robię to we właściwy sposób? jeśli nie, to jaki jest właściwy sposób, aby to zrobić?

CuriousMind
źródło
4
Niektórzy, którzy tu przyjeżdżają, mogą uznać, że to lepiej pasuje do ich scenariusza: stackoverflow.com/questions/9790448/ ...
AaronLS
4
Również ta wersja pytania / odpowiedzi jest bardziej przejrzysta: stackoverflow.com/questions/7947322/…
Ben Wheeler

Odpowiedzi:

62

Ponieważ używasz narzędzi GitHub i zmieniasz tylko jeden plik, możesz również przejść do pliku na GitHub, wybrać odpowiednią gałąź z lewego górnego rogu pod menu rozwijanym „drzewo:” ( patch-3w twoim przypadku), a teraz wybrać „Edytuj ten plik". Teraz zmiany zostaną zatwierdzone w tej gałęzi i pojawią się w żądaniu ściągnięcia

Abe Voelker
źródło
10

Niedawno pisałem na blogu na ten temat:

W jaki sposób aktualizujemy tę gałąź funkcji? Scalanie najnowszych zatwierdzeń nadrzędnych jest łatwe, ale chcesz uniknąć tworzenia zatwierdzeń scalających, ponieważ nie zostaną one docenione po wypchnięciu ich do wyższego poziomu: wtedy efektywnie ponownie zatwierdzasz zmiany nadrzędne, a te zatwierdzenia nadrzędne otrzymają nowy skrót ( gdy mają nowego rodzica). Jest to szczególnie ważne, ponieważ te scalone zatwierdzenia zostaną odzwierciedlone w żądaniu ściągnięcia GitHub, gdy wypchniesz te aktualizacje do swojej osobistej gałęzi funkcji GitHub (nawet jeśli zrobisz to po wydaniu żądania ściągnięcia).

Dlatego musimy zmienić bazę zamiast scalać:

git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel

Zarówno opcja rebase, jak i polecenie rebase do git utrzymają twoje drzewo w czystości i unikną scalania zatwierdzeń. Pamiętaj jednak, że są to twoje pierwsze zatwierdzenia (z którymi wydałeś pierwsze żądanie ściągnięcia), które są ponownie bazowane i które mają teraz nowy skrót zatwierdzenia, który różni się od oryginalnych skrótów, które nadal znajdują się w zdalnej gałęzi repozytorium github .

Teraz wypychanie tych aktualizacji do twojej osobistej gałęzi funkcji GitHub zakończy się niepowodzeniem, ponieważ obie gałęzie się różnią: lokalne drzewo gałęzi i zdalne drzewo gałęzi są „niezsynchronizowane” z powodu tych różnych skrótów zatwierdzania. Git powie ci najpierw git pull --rebase, a potem pchnij ponownie, ale nie będzie to proste szybkie pchnięcie do przodu, ponieważ twoja historia została przepisana. Nie rób tego!

Problem polega na tym, że ponownie pobrałbyś swoje pierwsze zmienione zatwierdzenia, tak jak były pierwotnie, a te zostaną scalone na górze twojego lokalnego oddziału. Ze względu na stan niezsynchronizowania to ściąganie nie jest stosowane w sposób czysty. Otrzymasz zepsutą historię, w której twoje zatwierdzenia pojawiają się dwa razy. Kiedy wrzucisz to wszystko do gałęzi funkcji GitHub, zmiany te zostaną odzwierciedlone w pierwotnym żądaniu ściągnięcia, które stanie się bardzo, bardzo brzydkie.

AFAIK, tak naprawdę nie ma na to całkowicie czystego rozwiązania. Najlepszym rozwiązaniem, jakie znalazłem, jest wymuszenie wypchnięcia lokalnego oddziału do oddziału GitHub (w rzeczywistości wymuszenie aktualizacji bez przewijania do przodu):

Zgodnie z git-push (1):

Update the origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository.

Więc nie ciągnij, po prostu pchaj siłą w ten sposób:

git push svg +user-non-unique

lub:

git push svg user-non-unique --force

To faktycznie po prostu nadpisze twój zdalny oddział, ze wszystkim w twoim lokalnym oddziale. Zatwierdzenia, które znajdują się w zdalnym strumieniu (i spowodowały awarię) pozostaną tam, ale będą wiszącymi zatwierdzeniami, które ostatecznie zostaną usunięte przez git-gc (1). Nie ma sprawy.

Jak powiedziałem, jest to AFAICS najczystsze rozwiązanie. Wadą tego jest to, że twój PR zostanie zaktualizowany o te najnowsze commity, które otrzymają późniejszą datę i mogą pojawić się niezsynchronizowane w historii komentarzy do PR. Nie ma dużego problemu, ale może być mylące.

Serge van Ginderachter
źródło
5

Możesz także utworzyć nowe żądanie ściągnięcia, które jest powiązane z masterzamiast określonej abc1234wersji.

W ten sposób każde nowe zatwierdzenie / wypychanie do repozytorium zostanie dodane do żądania ściągnięcia.

cfedermann
źródło
3

Tak - wykonujesz dużo więcej pracy niż potrzebujesz. Po prostu wykonaj dodatkowe zatwierdzenie, a następnie wymuś to. Zobaczysz oryginalne zatwierdzenie, a także nowo przesłane, po odświeżeniu github w przeglądarce.

$ git commit -m "These changes are in response to PR comments"
$ git push -f origin HEAD
Forrest
źródło
to najłatwiejsza i najprostsza droga, nie wiem, dlaczego nie jest to najlepsza odpowiedź
Banjo Obayomi