`Git merge` ve` git merge --no-ff` arasındaki fark nedir?


Yanıtlar:


1080

--no-ffBayrak önler git mergebunun geçerli olduğunu tespit ederse, bir "hızlı ileri" yürütülmesini HEAD, birleştirme çalıştığınız taahhüt bir atası. Hızlı ileri sarma, git bir birleştirme taahhüdü oluşturmak yerine, şube işaretçinizi gelen taahhüdü gösterecek şekilde hareket ettirdiğinde ortaya çıkar. Bu genellikle git pullherhangi bir yerel değişiklik yapılmadan yapılır.

Bununla birlikte, zaman zaman bu davranışın olmasını önlemek istersiniz, tipik olarak belirli bir dal topolojisini korumak istediğinizden (örneğin, bir konu dalında birleşiyorsunuz ve geçmişi okurken bu şekilde göründüğünden emin olmak istiyorsunuz). Bunu yapmak için, geçebilir --no-ffbayrağı ve git mergeedecektir her zaman hızlı yönlendirme yerine birleştirme inşa.

Benzer şekilde, açıkça ileri sarmak için bir komut yürütmek git pullveya kullanmak git mergeistiyorsanız ve hızlı ileri saramıyorsa kefaletle kullanmak istiyorsanız, --ff-onlybayrağı kullanabilirsiniz . Bu şekilde düzenli olarak git pull --ff-onlydüşünmeden bir şey yapabilirsiniz ve daha sonra hata verirse geri dönüp birleştirmek mi yoksa yeniden birleştirmek mi istediğinize karar verebilirsiniz.


87
Daha doğrudan OP'ın soruyu cevaplamak için: onlar her zaman farklı değildir, ama eğer olurlarsa, o da görüleceği üzere gitkya git log --grapholmayan hızlı ileri bir yaptı ise, birleştirme yaratmadı hızlı ileri birleştirme taahhüt söyledi.
Cascabel

11
Ff'den kaçınma nedenini genişletmek güzel olurdu: yazar "belirtilen dal topolojisi" ifadesi --no-ff durumunda ek birleştirme işleminin birleştirmenin işareti olarak hizmet ettiği anlamına gelir. Artıları yazar ve birleşme adları ile açık birleştirme işaretleyicisidir. Eksileri, bir dizi yakınsak demiryolu raylarına benzeyen doğrusal olmayan bir tarihtir. Birleşmenin olası psikolojik yan etkisi, daha uzun bir inceleme süreci nedeniyle katkıda bulunanların ilgisini kaybetmesidir: blog.spreedly.com/2014/06/24/…
Vlad

6
--no-ffBir özellikten geliştirmeye veya geliştirmeye hakim olmak, bir çekme talebini birleştirmeye benzer olduğunu söylemek adil olur mu?
merlinpatt

9
@merlinpatt Elbette. GitHub'da bir çekme isteği birleştirirseniz, bunun eşdeğeri yapılır --no-ff.
Lily Ballard

1
Bu iyi bir açıklama. Dostum, insanların temiz git tarihinin neden gerçekten, gerçekten önemli olduğunu anlamaları için yeterince iyi git açıklaması yok (ben dahil!)
dudewad

1037

Bu soruya grafik cevap

İşte açık bir açıklaması ve grafik kullanımı ile bir sitegit merge --no-ff :

git merge --no-ff ve git merge arasındaki fark

Bunu görene kadar git ile tamamen kayboldum. Kullanmak --no-ff, geçmişi inceleyen birinin üzerinde çalışmak için teslim aldığınız dalı açıkça görmesini sağlar . (bu bağlantı github'ın "ağ" görselleştirme aracını gösterir) Ve işte örneklerle bir başka harika referans . Bu referans birinciyi git ile daha az tanışanlara daha fazla odaklanarak tamamlar.


Benim gibi yeni başlayanlar için temel bilgiler

Benim gibi ve bir Git-guru değilseniz, cevabım , dosyaların iyi belgelenmemiş, ancak çoğu zaman gerçekleşen yerel dosya sisteminden silmeden git'in izlemesinden silinmesini ele almayı açıklar. Başka bir yeni durum hala beni atlatmayı başaran mevcut kodu almaktır.


Örnek İş Akışı

Web siteme bir paket güncelledim ve iş akışımı görmek için notlarıma geri dönmek zorunda kaldım; Bu cevaba bir örnek eklemenin yararlı olduğunu düşündüm.

Git komutlarımın iş akışı:

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

Aşağıda: açıklamalar dahil gerçek kullanım.
Not: aşağıdaki çıktı kesilmiştir; git oldukça ayrıntılı.

$ 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

Uyarı Yukarıdan 3 şey:
1) Çıktıda, yeni dosyaların eklenmesi de dahil olmak üzere ECC paketinin yükseltilmesindeki değişiklikleri görebilirsiniz.
2) Ayrıca /ecc, bu değişiklikten bağımsız olarak sildiğim iki dosya ( klasörde değil ) olduğuna dikkat edin. Bu dosya silme işlemlerini karıştırmak yerine, daha sonra bu dosyaların silinmesini yansıtacak eccfarklı bir cleanupdal oluşturacağım .
3) İş akışımı takip etmedim! Ben ecc tekrar çalışma almaya çalışırken git unuttum.

Aşağıda: git commit -am "updated ecc package"Normalde yaptığım her şey dahil olmak yerine, dosyaları sadece /eccklasöre eklemek istedim . Silinen dosyalar özellikle benim bir parçam değildi git add, ama zaten git'te izlendikleri için onları bu şubenin taahhüdünden kaldırmam gerekiyor:

$ 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 git@github.com:me/mywebsite.git
   8a0d9ec..333eff5  master -> master



Yukarıdakileri otomatikleştirmek için komut dosyası

Bu işlemi günde 10+ kez kullandıktan sonra, komutları yürütmek için toplu komut dosyaları yazmaya başladım, bu yüzden git_update.sh <branch> <"commit message">yukarıdaki adımları yapmak için neredeyse uygun bir komut dosyası hazırladım. İşte bu komut dosyasının Gist kaynağı .

Bunun yerine, git commit -amüretilen "değiştirilmiş" listeden dosyaları seçip git statusbu komut dosyasındaki dosyaları yapıştırarak kullanıyorum. Bunun nedeni düzinelerce düzenleme yaptığım ancak değişikliklerin gruplanmasına yardımcı olmak için çeşitli şube adları istediğimden kaynaklandı.


11
--no-ffSeçeneği birleştirdikten sonra da bir şubeyi güvenli bir şekilde silebilir misiniz ?
Andy Fleming

17
@DesignerGuy evet eski şubeyi güvenle silebilirsiniz. Branşları belirli bir taahhüdün sadece bir göstergesi olarak düşünün.
Zyphrax

2
Bağlantılı sayfadan bu metni faydalı buldum: --no-ff olmadan "Git geçmişinden hangi taahhüt nesnelerinin birlikte bir özellik uyguladığını görmek mümkün değil - tüm günlük mesajlarını manuel olarak okumak zorunda kalacaksınız."
Lorne Laliberte

bir görüntü her zaman bin kelimeden daha iyi!
rupps

1
Grafik, ikinci görüntüdeki özellikler dalını göstermiyor, neden olmasın? Hala var değil mi?
ADJenks

269

Birleştirme Stratejileri

Açık Birleştirme : Yeni bir birleştirme taahhüdü oluşturur. (Kullandıysanız alacağınız şey budur --no-ff.)

resim açıklamasını buraya girin

Hızlı İleri Birleştirme: Yeni bir taahhüt oluşturmadan hızlı bir şekilde ileri gidin:

resim açıklamasını buraya girin

Rebase : Yeni bir taban seviyesi oluşturun:

resim açıklamasını buraya girin

Squash: Düz olması için ezin veya sıkın (bir şey):

resim açıklamasını buraya girin


11
İlginç bir grafik ama gerçekten - no-ff davasını göstermiyor ve bu nedenle burada soruya tam olarak cevap vermiyor
Vib

22
İlki, burada "birleştirme" olarak adlandırılan "açık birleştirme", ff olmayan bir birleştirme.
bkribbs

3
bu grafikler bana çok yardımcı oldu
exexzian

2
söz konusu soruya cevap vermez, ancak bu grafik şaşırtıcı, UPVOTE!
SovietFrontier

3
Peki, Rebase ile hızlı ileri birleştirme arasındaki fark nedir?
ThanosFisherman

217

Bu --no-ffseçenek, hızlı ileri bir birleştirme işleminin yapılmamasını ve her zaman yeni bir taahhüt nesnesinin oluşturulmasını sağlar . Git'in özellik dallarının geçmişini tutmasını istiyorsanız bu istenebilir.             git merge --no-ff vs git merge Yukarıdaki görüntüde, sol taraf kullanıldıktan sonra git geçmişinin bir örneğidir git merge --no-ffve sağ taraf git mergeff birleşmesinin mümkün olduğu yerlerde kullanımın bir örneğidir .

DÜZENLE : Bu görüntünün önceki bir sürümü, birleştirme taahhüdü için yalnızca tek bir üst öğe belirtiyordu. Birleştirme işlemlerinde, git'in "özellik dalı" ve orijinal dalın geçmişini korumak için kullandığı birden çok üst öğe taahhüdü bulunur. Birden çok üst bağlantı yeşil renkle vurgulanır.


3
Yeşil ok kara okla neyi belirtir?
rtconner

11
yeşil ok, bir taahhüt ile bir ebeveyn arasında birden fazla ebeveynin bulunduğu bir bağlantıyı gösterir. Normal işlemlerin (siyah) yalnızca bir üst öğesi vardır.
Daniel Smith

9
@DanielSmith Bu zarif grafiği nasıl çizersiniz?
chancyWu

4
Adobe Illustrator ile @chancyWu
Daniel Smith

Şirketimde tüm çekme istekleri --no-ff seçeneği ile birleştirildi. Bu şartlar altında, bir çekme isteği oluşturmadan önce yeniden taban oluşturmak mantıklı geliyor mu?
Nickpick

37

Bu eski bir sorudur ve bu diğer yazılarda biraz zekice belirtilmiştir, ancak bu tıklamayı benim için yapan açıklama, hızlı olmayan ileri birleştirme işlemlerinin ayrı bir taahhüt gerektireceğidir .


Lütfen yukarıdaki cevabımdaki iş akışını gözden geçirir misiniz: bu, şu an sahip olduğumun ötesinde ek taahhütlere ihtiyacım olduğu anlamına mı geliyor? Teşekkürler.
Chris K

3
@ChrisK git merge --no-ff eccsadece git logşube master için ek birleştirme taahhüdü olacak . Usta, taahhütlü ecc'nin doğrudan bir atasını işaret ediyorsa teknik olarak gerekli değildir, ancak --no-ff seçeneğini belirterek bu birleştirme taahhüdünün oluşturulmasını zorlarsınız. Başlık:Merge branch 'ecc'
Ankur Agarwal

Harika özet! :)
Eduard

4

--No-ff bayrağı, birleştirme bir ileri sarma ile gerçekleştirilse bile birleştirme işleminin her zaman yeni bir taahhüt nesnesi oluşturmasına neden olur. Bu, bir özellik dalının tarihsel varlığı hakkında bilgi kaybını önler ve birlikte özelliği ekleyen tüm taahhütleri gruplar

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.