Git - seçili dosyada birleştirme çakışması ve manuel birleştirmeye nasıl zorlanır


83

Ortak ana şubeye ve her kurulum için bir tane olmak üzere birçok paralel şubeye sahip olan web uygulamasını sürdürüyoruz, her birinin birkaç spesifik değişikliği var. Kaynak kodu git'te yönetilir ve ana daldan paralel olanlara aktarım özelliklerine ve hata düzeltmelerine ihtiyaç duyduğumuzda harika bir araçtır. Ancak hassas olan ve otomatik birleştirme genellikle kötü sonuçlar veren birkaç dosyadır. Dolayısıyla, bir şekilde işaretlenebilirlerse ve her birleştirme, manuel birleştirme gerektiren çatışmalara neden olursa, birleştirme çok daha kolay olacaktır.

Bir cevap aradım:

  1. Ben --no-commit ve --no-ff birleştirme seçeneklerini kullanıyorum, ancak bu aynı değil.
  2. Burada ve burada birisi aynı soruyu sorar ama çözümü yoktur.
  3. Benzer durum, dosyanın .gitattributes kullanılarak birleştirilmesinin nasıl engelleneceği gibi görünüyor : somefile.php merge = bizim . Çatışma yaratacak veya manuel birleştirmeye zorlayacak bir birleştirme seçeneği bulmaya çalıştım, ancak şimdiye kadar hiçbirini bulamadım.
  4. somefile.php -merge içeren .git öznitelikleri hiçbir zaman otomatik olarak birleştirilmez ve bu nedenle el ile birleştirmeye zorlar. Bu% 90 çözüm, ancak aradığım şey otomatik birleştirmeyi denemek ve başarılı olsun ya da olmasın bunu çatışma olarak işaretlemek. Ancak bu şimdiye kadar çözüme en yakın olanıdır. (... açıklama için teşekkürler Charles Bailey ...)
  5. Birisi özel birleştirme sürücüsü ( 1 , 2 ) yazmayı öneriyor , ancak bunun nasıl yapılacağı bana açık değil.

düzenleme: varyant 4. açıklama


6
Bu tam olarak aradığınız cevap olmayacaktır, ancak aynı sebepten dolayı önce yapıyorum git fetch, sonra kullanıyorum git difftool <file> FETCH_HEAD, böylece uzak şubedeki değişikliği yerel olarak manuel olarak uygulayabilirim.
MHC

MHC: Bu güzel bir numara (özellikle her paralel dal için komut dosyasına kaydedilmişse + dosyaların otomatik olarak birleştirilmesini engelleyerek). Ana dezavantaj, ekip iş akışında şansın birinin bu adımı unutması ve bunun yerine normal birleştirme yapmasıdır.
Stepan

2
Ayarlama -merge, dosyaları birleştirmenizi engellemez, sadece sizi manuel olarak, örneğin bir birleştirme aracı ile yapmaya zorlar. İhtiyacın olan bu değil mi?
CB Bailey

İstediğimin% 90'ı. Birleştirme işleminin otomatik olarak yapılmasını isterim, ancak bu hassas dosya için birleştirme, hiçbiri olmasa bile çakışma olarak kabul edilir, bu nedenle her seferinde manuel kontrol zorunludur.
Stepan

@Stepan Ben de benzer bir durumdayım, bu yüzden bir şeyi açıklığa kavuşturmak istiyorum. Birlikte ne söyleyeceksin -mergeiçinde .gitatttributes git mergehiçbir şey yapmaz ve tüm çalışma birleştirme aracı ile aşağı olmalıdır? Yani birleştirme aracının kullanabileceği bir <<<<< ===== >>>> yok, değil mi? Ve Dan'in çözümü bunu sağlıyor mu?
Nero gris

Yanıtlar:


60

Özel bir birleştirme sürücüsü olan Seçenek 5, muhtemelen istediğiniz şeye en yakın hale getirmenin yoludur. Yapması şaşırtıcı derecede kolaydır. Aşağıda, sizi arzuladığınız davranışa oldukça yaklaştıracağını düşündüğüm bir örnek var.

İlk olarak, adlı bir birleştirme sürücüsü komut dosyası oluşturun merge-and-verify-driver. Çalıştırılabilir hale getirin ve uygun bir konuma koyun (bu betiği depoda kontrol etmeyi düşünebilirsiniz, hatta deponun yapılandırma dosyası buna bağlı olacaktır). Git, hassas dosyaların birleştirilmesini gerçekleştirmek için bu kabuk komut dosyasını çalıştıracak:

#!/bin/bash
git merge-file "${1}" "${2}" "${3}"
exit 1

Bu sadece Git'in normalde yaptığı varsayılan birleştirme davranışını gerçekleştirir. Temel fark, komut dosyasının her zaman sıfır olmayan bir değer döndürmesidir (birleştirme aslında çakışmalar olmadan çözülmüş olsa bile bir çakışma olduğunu belirtmek için).

Ardından, Git'e özel birleştirme sürücünüzün varlığından bahsetmeniz gerekir. Bunu deponun yapılandırma dosyasında ( .git/config) yaparsınız :

[merge "verify"]
        name = merge and verify driver
        driver = ./merge-and-verify-driver %A %O %B

Bu örnekte, merge-and-verify-driverdeponun üst düzey dizinine ( ./) koydum . Komut dosyasına giden yolu buna göre belirlemeniz gerekecektir.

Şimdi, bu dosyaları birleştirirken özel birleştirme sürücüsünün kullanılması için hassas dosyalara uygun öznitelikleri vermeniz yeterlidir. Bunu .gitattributesdosyanıza ekleyin :

*.sensitive merge=verify

Burada Git'e desenle eşleşen bir ada sahip herhangi bir dosyanın *.sensitiveözel birleştirme sürücüsünü kullanması gerektiğini söyledim . Açıkçası, dosyalarınız için uygun olan desen kullanmanız gerekir.


Bu ayrıntılı rehber için çok teşekkürler!
Stepan

13
Görünüşe göre birleştirme sürücüsü "bariz" çözümlerde çağrılmıyor. Örneğin, dosya yalnızca bir dalda değiştirildiyse ve birleştirme yaparsanız, "hassas" dosyanın üzerine yazılır ve birleştirme sürücüsü çağrılmaz. Bunu düzeltmenin bir yolu var mı?
VitalyB

Bu gerçekten @VitalyB'nin önerdiği gibi davranır mı? Teşekkürler!
filippo

1
Bu işe yarıyor, ancak bunu bir makinedeki tüm depolarda küresel bir seçenek haline getirmenin herhangi bir yolu var mı? Ayrıca, komut satırıyla çağırmanın bir yolu var mı? Keşke bunu komut satırında birleştirme stratejisini değiştirmek kadar basit bir şekilde yapmanın bir yolu olsaydı.
user1748155

4
@VitalyB yorumuna ekleyerek. Her iki dal da bir dosyada aynı değişikliği yaptıysa, birleştirme de görünmez . Örneğin, her iki dal da sürümü 1 artırdı ve siz birleştirmeye çalışırken 2 artırmak istiyorsunuz ... Çok pratik bir sorun, henüz çözülmedi. :(
VasiliNovikov

1

Bu iki komut, özel birleştirme sürücüsünü kullanmakla aynı etkiye sahip görünüyor:

git merge --no-commit your_target_branch
git checkout --conflict merge .   (do not forget the . and run it in the top dir of the repository)

İlk komut, birleştirme işleminin oluşturulmasından önce birleştirmeyi durdurur ve ikincisi, iki dalda değiştirilen tüm dosyaları, başlangıçta herhangi bir çakışma olmasa bile çözülmesi gereken bir çakışma olarak işaretler.


"Tek seferlik" çözüm fikrini seviyorum (böyle bir vakayla karşılaştım), ancak bu benim için işe yaramadı. Git, hatalı bir birleştirmeyle sonuçlanan bir FF yaptı (aslında bu ve bizimki birleşti).
Nero gris

@Nerogris Gerçekten de hızlı ileri birleştirme için işe yaramayacak. Her zaman --no-ff seçeneğini ekleyebilirsiniz, ancak birleştirmenin iki dalından birinde ortak atadan herhangi bir değişiklik olmadığı için ikinci komut herhangi bir çakışma oluşturmayacaktır.
louisiuol

Global yapılandırmamda ff'yi false olarak ayarladım. Bunun bir FF birleştirmesi olduğunu söylediğimde, Git'e bunları yapmamasını söylememiş olsaydım, öyle olurdu.
Nero gris

0

Not: " PO dosyaları için git birleştirme sürücüsü yazma " bu makale , bir dosyayı manuel olarak birleştirirken yapabileceğiniz işlemlerin türünü gösterir: manuel birleştirmenizin belirli verileri hazır hale getirmesi için önceden işleyebilirsiniz.

git merge-fileörneğin, dosyaları birleştirmeden önce (!) DECRYPT (ve yeniden şifrelemek ) için kullanılabilir

Sizin durumunuzda, birleştirme sürücünüzden 0 olmayan bir durumla çıkmanız, birleştirmenin manuel bir sürücü olmasını sağlar.


2
"PO dosyaları için birleştirme sürücüsü" bağlantısı hakkında daha fazla bilgi verebilir misiniz, çünkü bu benim için erişimin reddedilmesine neden oluyor gibi görünüyor? Stackoverflow.com/questions/16214067/…
Mikko Rantalainen

@MikkoRantalainen iş yerinde engellendi, bu yüzden bu akşam evden deneyeceğim.
VonC

1
"PO dosyaları için birleştirme sürücüsü" benim için de çalışmıyor :(

1
@sampablokuper Aynı fikirdeyim: makale "yetkisiz" okuyucu için engellenmiş. Neden bilmiyorum.
VonC

1
@sampablokuper Şu anda bu bloga erişimim yok. İçeriğini aramaya devam edeceğim.
VonC
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.