Łączę się w odległej gałęzi, która może mieć wiele konfliktów. Jak mogę stwierdzić, czy będzie to powodować konflikty, czy nie?
Nie widzę niczego podobnego w --dry-run
pozycji ON git-merge
.
Łączę się w odległej gałęzi, która może mieć wiele konfliktów. Jak mogę stwierdzić, czy będzie to powodować konflikty, czy nie?
Nie widzę niczego podobnego w --dry-run
pozycji ON git-merge
.
Odpowiedzi:
Jak wspomniano wcześniej, przekaż --no-commit
flagę, ale aby uniknąć zatwierdzenia przewijania do przodu, przekaż także --no-ff
:
$ git merge --no-commit --no-ff $BRANCH
Aby zbadać zmiany etapowe:
$ git diff --cached
Możesz cofnąć scalanie, nawet jeśli jest to scalanie do przodu:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
lub git diff --show-conflicts <commit>
byłoby naprawdę przydatne. Szkoda, że to jeszcze nie możliwe, czy coś mi umknęło?
git pull --ff-only
!
Musiałem tylko zaimplementować metodę, która automatycznie wykryje konflikty między repozytorium a jego zdalnym. To rozwiązanie scala pamięć, aby nie dotknąć indeksu ani drzewa roboczego. Myślę, że jest to najbezpieczniejszy możliwy sposób rozwiązania tego problemu. Oto jak to działa:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( mergebase to szesnastkowy identyfikator, który scalono -bazę wydrukowano w poprzednim kroku)Załóżmy teraz, że chcesz połączyć zdalny master z lokalnym master, ale możesz użyć dowolnych gałęzi. git merge-tree
wykona scalenie w pamięci i wydrukuje wynik na standardowe wyjście. Grep dla wzoru <<
lub >>
. Lub możesz wydrukować dane wyjściowe do pliku i to sprawdzić. Jeśli znajdziesz linię zaczynającą się od „zmieniono w obu”, najprawdopodobniej wystąpi konflikt.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
prostu niesamowita! +100
+<<<<<<< .our
więc używam wyrażenia grep, takiego jakgrep -q '^+<* \.our$'
Moje proste rozwiązanie tego problemu to:
Utwórz gałąź „pre-master” (oczywiście od master)
Połącz wszystkie rzeczy, które chcesz, w ten przed-mistrz.
Następnie możesz zobaczyć, jak doszło do scalenia bez dotykania wzorca.
W każdym razie postępowałbym zgodnie z radą @ orange80.
git merge --abort
jeśli występują konflikty, git reset --hard HEAD~1
jeśli nastąpiło scalenie lub git reset --hard origin/master
. Utworzenie kolejnej gałęzi daje poczucie bezpieczeństwa, ale jeśli nauczysz się, jak działa git, zrozumiesz, że to stracony strach. Jeśli chodzi o to, aby nie zmieniać kopii roboczej, nie ma rozwiązania.
git merge --no-commit
nie przerwie scalania, jeśli można je szybko przesłać dalej. git merge --abort
nie działa, jeśli został scalony. Jeśli chcesz napisać to jako skrypt, jest to niewygodne, ponieważ git merge
nie odpowiada wystarczająco dobrymi kodami błędów, aby wyjaśnić różne typy konfliktów. Praca z nową gałęzią zapobiega pozostawieniu uszkodzonego skryptu w repozytorium w stanie wymagającym ręcznej interwencji. Pewnie, że nic nie możesz stracić. Ale łatwiej jest zbudować inaczej.
Cofanie scalenia za pomocą git jest tak łatwe, że nie powinieneś nawet martwić się suchym przebiegiem:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
EDYCJA: Jak zauważono w komentarzach poniżej, jeśli masz zmiany w katalogu roboczym lub obszarze przejściowym, prawdopodobnie zechcesz je ukryć przed wykonaniem powyższej czynności (w przeciwnym razie znikną po wykonaniu git reset
powyższych czynności)
git branch --contains HEAD
a nawet bardziej bezpośrednio, wystarczy użyćgit merge --ff-only
--dry-run
nie „po prostu sprawdzałby, czy scalenie będzie przewijać do przodu”. Zwróciłoby to dokładnie dane wyjściowe scalenia: pliki, konflikty itp. Czy ff nie jest tak naprawdę interesujące, prawda?
git stash; git reset --hard
? @BrianPhillips
Stworzyłem alias, aby to zrobić i działa jak urok, robię to:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Teraz dzwonię
git mergetest <branchname>
Aby dowiedzieć się, czy są jakieś konflikty.
Po prostu różnicuj swoją obecną gałąź z gałęzią zdalną, to powie ci, co się zmieni, kiedy wykonasz ściąganie / scalanie.
#see diff between current master and remote branch
git diff master origin/master
Używam do tego polecenia git request-pull . Pozwala zobaczyć każdą zmianę, która miałaby miejsce podczas łączenia, ale bez robienia czegokolwiek na lokalnych lub zdalnych repozytoriach .
Na przykład wyobraź sobie, że chcesz scalić gałąź o nazwie „feature-x” z gałęzią master
git request-pull master origin feature-x
pokaże podsumowanie tego, co by się stało (bez robienia czegokolwiek):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Jeśli dodasz -p
parametr, otrzymasz również pełny tekst poprawki, dokładnie tak, jakbyś robił różnicę git dla każdego zmienionego pliku.
master
i origin
robię w opcjach wiersza poleceń, a co jeśli na przykład jestem na komputerze lokalnym branch1
i chcę zrobić request-pull
na lokalnej gałęzi funkcji branch2
? Czy nadal potrzebuję origin
? Oczywiście zawsze można przeczytać dokumentację.
Dziwię się, że nikt jeszcze nie sugerował używania łatek.
Że chcesz przetestować scalania od your_branch
do master
(Ja zakładając masz master
wyrejestrowany):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
To powinno wystarczyć.
Jeśli wystąpią błędy, takie jak
error: patch failed: test.txt:1
error: test.txt: patch does not apply
oznacza to, że łatka nie powiodła się, a scalenie spowodowałoby konflikty. Brak danych wyjściowych oznacza, że łatka jest czysta i można łatwo połączyć gałąź
Zauważ, że tak naprawdę nie zmieni to twojego działającego drzewa (oprócz tworzenia pliku łatki oczywiście, ale później możesz go bezpiecznie usunąć). Z dokumentacji git-Apply:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Uwaga dla każdego, kto jest mądrzejszy / bardziej doświadczony w git ode mnie: daj mi znać, jeśli się mylę, a ta metoda wykazuje inne zachowanie niż zwykłe scalanie. Dziwne wydaje się, że w ciągu ponad 8 lat istnienia tego pytania nikt nie sugerowałby tego pozornie oczywistego rozwiązania.
git diff master your_branch | git apply --check
.
To może być interesujące: Z dokumentacji:
Jeśli próbowałeś scalenia, które zakończyły się złożonymi konfliktami i chcesz zacząć od nowa, możesz odzyskać za pomocą git merge --abort .
Ale możesz to zrobić naiwnie (ale powoli):
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Uwaga: nie będzie działało po prostu klonowanie do / tmp, potrzebujesz kopii, aby mieć pewność, że niezatwierdzone zmiany nie spowodują konfliktu).
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(na wszelki wypadek), git status
(aby sprawdzić, że jest czysty).
Wiem, że to stare pytanie, ale pierwsze pojawia się w wyszukiwarce Google.
Podczas łączenia Git wprowadził opcję --ff-only.
Od: http://git-scm.com/docs/git-merge
--ff-only
Odmów scalenia i wyjdź ze stanu niezerowego, chyba że bieżący HEAD jest już aktualny lub scalenie można rozwiązać jako przewijanie do przodu.
Wykonanie tego spowoduje połączenie i szybkie przewijanie do przodu, a jeśli nie będzie możliwe, przerywa działanie i wyświetla monit o niemożność wykonania szybkiego przewijania do przodu, ale pozostawia działającą gałąź bez zmian. Jeśli może szybko przewinąć do przodu, wówczas wykona scalenie w działającym oddziale. Ta opcja jest również dostępna w dniu git pull
. W ten sposób możesz wykonać następujące czynności:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Używam git log, aby zobaczyć, co zmieniło się w gałęzi funkcji od gałęzi master
git log does_this_branch..contain_this_branch_changes
np. - aby zobaczyć, jakie zatwierdzenia znajdują się w gałęzi funkcji, która została / nie została scalona z master:
git log master..feature_branch
Jeśli chcesz przewinąć do przodu z B do A, musisz upewnić się, że git log B..A niczego nie pokazuje, tzn. A nie ma niczego, czego B nie ma. Ale nawet jeśli B..A ma coś, nadal możesz być w stanie łączyć się bez konfliktów, więc powyższe pokazuje dwie rzeczy: że nastąpi szybkie przewijanie do przodu, a zatem nie dostaniesz konfliktu.
Moim rozwiązaniem jest scalenie wstecz.
Zamiast scalać gałąź w zdalną gałąź „docelową”, scal ją z własną.
git checkout my-branch
git merge origin/target-branch
Zobaczysz, czy są jakieś konflikty i możesz zaplanować, jak je rozwiązać.
Następnie możesz albo przerwać scalanie za pomocą git merge --abort
, albo (jeśli nie było żadnych konfliktów i scalenie się zdarzyło) wycofać do poprzedniego zatwierdzenia przezgit reset --hard HEAD~1