Jaka jest różnica między `git merge ' a 'git merge --no-FF'?
Używając gitk log
, nie mogłem dostrzec różnicy między tymi dwoma. Jak mogę zaobserwować różnicę (za pomocą polecenia git lub jakiegoś narzędzia)?
5 answers
Znacznik --no-ff
uniemożliwia git merge
wykonywanie "przewijania do przodu", jeśli wykryje, że bieżący HEAD
jest przodkiem zatwierdzonego commita, który próbujesz scalić. Przewijanie do przodu polega na tym, że zamiast tworzyć commit scalający, git po prostu przesuwa wskaźnik gałęzi, aby wskazać nadchodzący commit. Często zdarza się to podczas wykonywania git pull
bez żadnych lokalnych zmian.
Jednak od czasu do czasu chcesz zapobiec temu zachowaniu, zazwyczaj dlatego, że chcesz zachować określone topologia gałęzi (np. łączysz się w gałęzi tematycznej i chcesz mieć pewność, że tak wygląda podczas czytania historii). Aby to zrobić, możesz przekazać znacznik --no-ff
i git merge
będzie zawsze skonstruować merge zamiast fast-forwarding.
Podobnie, jeśli chcesz wykonać git pull
lub użyć git merge
w celu jawnego przewijania do przodu, a jeśli nie możesz przewijać do przodu, możesz użyć znacznika --ff-only
. W ten sposób możesz regularnie robić coś takiego jak git pull --ff-only
bez myślenie, a następnie, jeśli to błąd, możesz wrócić i zdecydować, czy chcesz scalić lub rebase.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-30 18:51:29
Graficzna odpowiedź na to pytanie
Oto strona z jasnym wyjaśnieniem i ilustracją graficzną użycia git merge --no-FF:
Dopóki tego nie zobaczyłem, byłem całkowicie zagubiony z Gitem. Uĺźycie --no-FF pozwala ktoĹ "przejrzeÄ ‡ historiÄ ™ jasno zobaczyÄ ‡ branĺźä™, na ktĂłrÄ ... sprawdziĺ' eĹ " do pracy. (ten link wskazuje na narzędzie wizualizacji "sieciowej" Githuba) i oto kolejna świetna Referencja z ilustracje. To odniesienie ładnie uzupełnia pierwszy z nich, skupiając się bardziej na tych, którzy są mniej zaznajomieni z Gitem.
Podstawowe informacje dla początkujących jak ja
Jeśli jesteś taki jak ja, a nie Git-guru, moja odpowiedź tutaj opisuje obsługę usuwania plików ze śledzenia Gita bez usuwania ich z lokalnego systemu plików, co wydaje się słabo udokumentowane, ale często występuje. Kolejną sytuacją newb jest uzyskanie bieżącego kodu, który wciąż udaje się umykaj mi.
Przykładowy Przepływ Pracy
Zaktualizowałem pakiet na mojej stronie internetowej i musiałem wrócić do moich notatek, aby zobaczyć mój przepływ pracy; pomyślałem, że warto dodać przykład do tej odpowiedzi.
Mój workflow poleceń git:
git checkout -b contact-form
(do your work on "contact-form")
git status
git commit -am "updated form in contact module"
git checkout master
git merge --no-ff contact-form
git branch -d contact-form
git push origin master
Poniżej: rzeczywiste użycie, w tym wyjaśnienia.
Uwaga: poniższy wynik jest wycięty; git jest dość gadatliwy.
$ git status
# On branch master
# Changed but not updated:
# (use "git add/rm <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: ecc/Desktop.php
# modified: ecc/Mobile.php
# deleted: ecc/ecc-config.php
# modified: ecc/readme.txt
# modified: ecc/test.php
# deleted: passthru-adapter.igs
# deleted: shop/mickey/index.php
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# ecc/upgrade.php
# ecc/webgility-config.php
# ecc/webgility-config.php.bak
# ecc/webgility-magento.php
Zauważ 3 rzeczy z góry:
1) na wyjściu widać zmiany z Aktualizacja pakietu ECC, w tym dodanie nowych plików.
2) zauważ również, że są dwa pliki (nie w folderze /ecc
), które usunąłem niezależnie od tej zmiany. Zamiast mylić te usunięcia plików z ecc
, zrobię później inną gałąź cleanup
, aby odzwierciedlić usunięcie tych plików.
3) nie śledziłem mojego przepływu pracy! Zapomniałem o git ' IE, gdy próbowałem ponownie uruchomić ecc.
Poniżej: zamiast robić all inclusive git commit -am "updated ecc package"
normalnie bym to zrobił, chciałem tylko dodać pliki w folderze /ecc
. Te usunięte pliki nie były częścią mojej git add
, ale ponieważ były już śledzone w git, muszę je usunąć z commita tej gałęzi:
$ git checkout -b ecc
$ git add ecc/*
$ git reset HEAD passthru-adapter.igs
$ git reset HEAD shop/mickey/index.php
Unstaged changes after reset:
M passthru-adapter.igs
M shop/mickey/index.php
$ git commit -m "Webgility ecc desktop connector files; integrates with Quickbooks"
$ git checkout master
D passthru-adapter.igs
D shop/mickey/index.php
Switched to branch 'master'
$ git merge --no-ff ecc
$ git branch -d ecc
Deleted branch ecc (was 98269a2).
$ git push origin master
Counting objects: 22, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (14/14), done.
Writing objects: 100% (14/14), 59.00 KiB, done.
Total 14 (delta 10), reused 0 (delta 0)
To [email protected]:me/mywebsite.git
8a0d9ec..333eff5 master -> master
Skrypt do automatyzacji powyższego
Po użyciu tego procesu 10 + razy dziennie, podjąłem się pisania skryptów wsadowych, aby wykonać polecenia, więc zrobiłem prawie odpowiedni skrypt git_update.sh <branch> <"commit message">
do wykonywania powyższych kroków. Oto źródło Gist do tego scenariusz.
Zamiast git commit -am
wybieram pliki z listy "zmodyfikowanych" wytworzonych przez git status
i wklejam je do tego skryptu. Stało się tak, ponieważ zrobiłem dziesiątki edycji, ale chciałem zróżnicowanych nazw gałęzi, aby pomóc pogrupować zmiany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:34
Opcja --no-ff
zapewnia, że fast forward merge nie nastąpi, a nowy obiekt zatwierdzania zostanie zawsze utworzony . Może to być pożądane, jeśli chcesz, aby git utrzymywał historię gałęzi funkcji.
Na powyższym obrazku, lewa strona jest przykładem historii Gita po użyciu git merge --no-ff
, A prawa strona jest przykładem użycia git merge
Gdzie możliwe było połączenie ff.
EDIT : poprzednia wersja tego obrazka wskazywała tylko jednego rodzica dla commit merge. Merge commity mają wiele nadrzędnych commitów , których git używa do utrzymywania historii "feature branch" i oryginalnej gałęzi. Wiele linków nadrzędnych jest podświetlonych na Zielono.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-30 00:41:32
To jest stare pytanie i jest to nieco subtelnie wspomniane w innych postach, ale wyjaśnienie, które sprawiło, że to kliknięcie dla mnie jest takie, że non fast forward merges będzie wymagało osobnego commita.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-02 19:56:06
Strategie Scalania
- Explicit, non fast-forward merge
- Implicit poprzez rebase lub fast-forward merge
- Squash on merge
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-04 02:21:15