Pracuję z innym programistą nad projektem i używamy Github jako naszego zdalnego repozytorium. Jestem na Macu z git 1.7.7.3, on na Windowsie używa git 1.7.6.
Oto, co się dzieje
- Jeden z nas (nazwijmy go deweloperem A, ale nie ma znaczenia który) wypycha zestaw zatwierdzeń do GitHub.
- Drugi (programista B) wykonuje pewne lokalne zatwierdzenia.
- B robi a
git pull
. - B robi a
git push
. - Patrząc na dziennik historii zmian , widzę Merge branch „master” na github.com:foo/bar
Dziennik zatwierdzeń jest z czasem zaśmiecony komunikatami „Merge branch”, a także pokazuje programistę B jako zatwierdzającego zmiany wprowadzone przez programistę A. Jedynym sposobem, w jaki udało nam się zapobiec temu problemowi, jest wykonanie a git pull --rebase
w kroku 3, ale nie wiem, jakie skutki uboczne wprowadzi zmiana bazy. Po raz pierwszy pracuję nad repozytorium git dla wielu programistów, więc czy to tylko normalne zachowanie? Jakieś przemyślenia, jak rozwiązać ten problem?
git log --no-merges
Odpowiedzi:
Zobowiązanie, które widzisz, jest w porządku.
pull
Skutecznie działagit fetch
, a następniegit merge
tak scalanie zwykle dzieje podczas uruchamianiagit pull
.Alternatywa polegająca na zmianie bazy zamiast scalania jest możliwa, ale zwykle należy jej unikać. Rebasing pozwala zachować liniową historię, ale także usuwa wszelkie informacje o rozgałęzieniach, które pierwotnie miały miejsce. Spowoduje to również przepisanie historii bieżącej gałęzi, odtworzenie wszystkich zatwierdzeń, które nie są zawarte w gałęzi docelowej (w twoim przypadku zdalnej). Ponieważ odtworzone zatwierdzenia są różnymi zatwierdzeniami, może to spowodować wiele zamieszania podczas opracowywania razem z innymi, zwłaszcza gdy ludzie już wyewidencjonowali części tych zatwierdzeń, zanim zostaną przepisane (na przykład z odgałęzieniami funkcji). Dlatego z reguły nigdy nie należy przepisywać żadnego zatwierdzenia, które zostało już przesłane.
Zobowiązania, które widzisz, łączą dwie (lub więcej) gałęzie. Bardzo dobrze jest mieć zatwierdzenie, które nie robi nic innego niż scalanie wielu gałęzi. W rzeczywistości jest to bardzo jasne, gdy masz zatwierdzenie scalające, które łączy gałęzie, gdy patrzysz na historię. W porównaniu z rebasingiem, scalanie pozwala również efektywnie zobaczyć oryginalną historię w takiej postaci, w jakiej została opracowana, w tym faktyczne gałęzie, które współistniały.
Krótko mówiąc: tak, posiadanie zatwierdzeń scalających jest w porządku i nie należy się nimi martwić.
źródło
Ta odpowiedź została poprawiona, ponieważ moje rozumienie, diagramy i wnioski były niepoprawne.
git pull
powoduje, że merge zatwierdza się, ponieważ git jest scalany. Można to zmienić, ustawiając swoje gałęzie tak, aby używały rebase zamiast scalania. Użycie rebase zamiast scalania podczas ściągania zapewnia bardziej liniową historię do współdzielonego repozytorium. Z drugiej strony, zmiany typu merge pokazują równoległe prace rozwojowe w gałęzi.Na przykład dwie osoby pracują w tej samej branży. Oddział zaczyna się jako:
Pierwsza osoba kończy pracę i przepycha się do gałęzi:
Druga osoba kończy pracę i chce naciskać, ale nie może, ponieważ musi zaktualizować. Lokalne repozytorium dla drugiej osoby wygląda następująco:
Jeśli pull jest ustawiony na scalanie, repozytorium drugiej osoby będzie wyglądać jak.
Gdzie M1 jest zatwierdzeniem scalającym. Ta nowa historia gałęzi zostanie przeniesiona do repozytorium. Jeśli zamiast tego pull jest ustawiony na ponowne bazowanie, lokalne repozytorium wyglądałoby następująco:
Nie ma zatwierdzenia łączenia. Historia stała się bardziej linearna.
Oba wybory odzwierciedlają historię branży. git pozwala wybrać preferowaną historię.
Rzeczywiście istnieją miejsca, w których rebase może powodować problemy ze zdalnymi oddziałami. To nie jest jeden z tych przypadków. Wolimy używać rebase, ponieważ upraszcza to już skomplikowaną historię gałęzi, a także pokazuje wersję historii w odniesieniu do współdzielonego repozytorium.
Możesz ustawić branch.autosetuprebase = always tak, aby git automatycznie ustalał twoje zdalne gałęzie jako rebase zamiast master.
To ustawienie powoduje, że git automatycznie tworzy ustawienie konfiguracyjne dla każdej zdalnej gałęzi:
Możesz ustawić to samodzielnie dla swoich zdalnych oddziałów, które są już skonfigurowane.
Chciałbym podziękować @LaurensHolst za przesłuchanie i kontynuację moich poprzednich wypowiedzi. Z pewnością dowiedziałem się więcej o tym, jak działa git z zatwierdzeniami pull i merge.
Więcej informacji na temat zatwierdzeń scalających można znaleźć w artykule Współtworzenie projektu w ProGit-Book . Sekcja Private Small Team pokazuje zatwierdzenia scalenia.
źródło
Możesz to zrobić:
Jednak to zawsze umieszcza Twoje zmiany na wierzchu plików współpracowników. Ale nie otrzymasz żadnej zanieczyszczającej wiadomości o scalaniu.
źródło
W rzeczywistości istnieje znacznie prostsza odpowiedź na to pytanie. Po prostu poproś programistę B o wykonanie pociągnięcia PRZED podjęciem decyzji. Zapobiegnie to tym zatwierdzeniom scalającym, ponieważ są one spowodowane historią utworzoną w lokalnym repozytorium z lokalnego zatwierdzenia próbującego scalić się z historią zatwierdzeń w zdalnym repozytorium. Jeśli podczas wyciągania pojawi się komunikat mówiący coś w rodzaju „zmiany zostaną nadpisane”, oznacza to po prostu, że oboje dotknęliście tego samego pliku, więc zrób:
wtedy możesz rozwiązać wszelkie konflikty scalania, jeśli takie istnieją.
źródło
stash
przed sobąpull
. Ugh git wymaga, żebym cały czas był na szczycie mojej gry.git pull --rebase
integracji zdalnych zmian przed lokalne, niezależnie.Wykonanie polecenia git pull spowoduje wstawienie wiadomości „Merge branch”, po prostu to robi. Wykonując git pull, połączyłeś zdalną gałąź z lokalną.
Kiedy wykonujesz polecenie git pull i wystąpią konflikty, dziennik git pokaże aktualizacje plików będących w konflikcie jako pochodzące od użytkownika, który rozwiązał konflikty. Zakładam, że dzieje się tak, ponieważ osoba, która rozwiązuje konflikt, ponownie zatwierdza plik.
O ile wiem, właśnie tak działa git i nie ma sposobu na obejście tego.
Rebasing zniszczy historię git, więc nie będziesz w stanie zobaczyć, kiedy nastąpiło połączenie.
źródło