Git-worktree'yi ne için kullanırdım?


211

Okuduğum git-worktree üzerinde Github adlı kullanıcının yayınını . Onlar yazar:

Diyelim ki feature, kullanıcı acil bir hatayı bildirdiğinde, adlı bir dalda Git deposunda çalışıyorsunuz master. Öncelikle yeni bir dal ile bağlantılı bir çalışma ağacı oluşturmak hotfix, ana göre kontrol dışarı […] Hata düzeltebilirsiniz, düzeltme itin ve bir çekme isteği oluşturabilirsiniz.

Feature adlı bir dal üzerinde çalıştığımda ve master'da bazı yüksek aciliyetli hatalar rapor edildiğinde, genellikle üzerinde çalıştığım her şeyi saklıyorum ve yeni bir dal oluşturuyorum. İşim bittiğinde çalışmaya devam edebilirim. Bu çok basit bir model, yıllardır böyle çalışıyorum.

Öte yandan, git-worktree kullanmanın kendi sınırlamaları vardır:

Örneğin, aynı şubenin aynı anda iki bağlantılı çalışma ağacında kontrol edilmesine izin verilmez, çünkü bu, bir çalışma ağacında yapılan değişikliklerin diğerini senkronize etmesini sağlar.

Zaten çözülmüş bir sorun için neden daha karmaşık bir iş akışı seçeyim?

Bu konuda git-worktreeönceden yapılamayan ve tüm bu yeni, karmaşık özelliği haklı çıkaran bir şey var mı ?


12
Saklayamayacağınız bir şey, birleşme veya çatışmalarla yeniden birleşme sonrasında birleştirilmemiş yollar.
chirlu

11
Derlenmiş bir dille çalışıyorsanız, saklamak, sökme işlemi sırasında her şeyi yeniden derlemeniz gerektiği anlamına gelir.
mb14

Aynı (300 MB) kaynak koduna dayanan birkaç farklı ürünümüz var ve hepsini tek bir büyük repoda birleştirmeyi ve her bir ürünü devasa bir grup yerine farklı bir klasörde kontrol etmek için worktree kullanmayı planlıyorum. senkronize olmayan klonlar
endolith

Yanıtlar:


196

Benim için git worktree uzun zamandan beri en büyük gelişmedir. Kurumsal yazılım geliştirmede çalışıyorum. Orada, 3 yıl önce yayınladığınız gibi eski sürümleri korumanız çok yaygın. Elbette her sürüm için bir dalınız var, böylece kolayca geçip bir hatayı düzeltebilirsiniz. Bununla birlikte, anahtarlama pahalıdır, çünkü bu arada depo ve belki de inşa sistemini tamamen yeniden yapılandırdınız. Geçerseniz, IDE'niz proje ayarlarını uyarlamaya çalışırken çıldırır.

Çalışma ağacı ile bu sürekli yeniden yapılandırmayı önleyebilirsiniz. Çalışma ağacını kullanarak bu eski dalları ayrı klasörlerde kullanıma alın. Her şube için bağımsız bir IDE projeniz var.

Tabii ki bu geçmişte repoyu birkaç kez klonlayarak yapılabilirdi ve bu benim yaklaşımımdı. Bununla birlikte, bu aynı zamanda hardrive alanı boşa harcamak ve aynı değişiklikleri depodan birkaç kez almak için daha kötü bir ihtiyaç anlamına geliyordu.


4
Repodan birkaç kez aynı değişiklikleri almak zorunda kalmadınız. İlk klonun .git dizinini kopyalamış olabilirsiniz.
misiu_mp

1
@ jdk1.0 karışıklık için üzgünüm, yorum misiu_mp yönelikti
mxttie

2
2-3 tane çoğaltılmış depo kullanan biri olarak, diğeri üzerinde gelişirken bir özellik dalı inşa edebildiğim için, diğerlerinin uzaktan kumandaları olarak her yerel repo'yu aldım ve Sebi'nin olumsuz yönleri (çok fazla getirme ve itme!) ) Ayrıca, çalışma ağacına geçtikten sonra, artık yerel, aynı adlı dalların birbirinden ayrılması konusunda endişelenmeme gerek kalmayacağını topluyorum (günler boyunca birden çok kez kesintiye uğradığımda ve sonunda sona erdiğimde 6-10 ayda bir olur) aynı özellik dalını birden çok depodan çıkarıyor, ancak onları senkronize etmeyi unutma ...)
adaçayı

3
@iheanyi - (1). IDE'nin belirli bir diziyle ilişkilendirilmiş harici veri dosyalarını (dizinleme veritabanları gibi) tutması daha hızlıdır. Aynı dizindeki içeriği çökerseniz , bu genellikle IDE veri önbelleklerini geçersiz kılar ve yeniden dizine eklemesi gerekir.
Steve Hollasch

5
@iheanyi - (2) Zamanla, her şeyin tarihi herhangi bir noktada çalışan ağaç dosyalarından çok daha büyük büyüyecektir. Her şeyin tarihi == .gitdizin. Yukarı akıştaki birçok yerel klonla, her bir klonun kendi .gitveritabanı olduğundan, aynı veritabanının birçok yerel kopyasına sahip olursunuz . Birçok yerel çalışma ağacında, her ağaç aynı .gitveritabanını kullanır . Evet, yerel çalışma ağacınızın yerel klonlarına sahipseniz Git, .git içeriğinin çoğunu sabit olarak bağlar, ancak Windows'a bağlamaz.
Steve Hollasch

70

Bunun bazı kullanımlarını görebiliyorum.

Uzun süre çalışan bir test paketiniz varsa, saatleri hayal edin ve başlatırsanız, testler tamamlanana kadar bu çalışma kopyasını etkili bir şekilde engeller. Bu testler sırasında dalların değiştirilmesi, anlaşılması zor yollarla onları kırabilir.

Böylece git-worktreeorada başka bir şube için ikinci bir fikrim olabilirdi.

Ayrıca, hızlı bir araştırma yapmak için başka bir şubeye geçtiğimde, IDE'm aniden değiştiğini düşünüyor ve tüm bu değişiklikleri dizine ekleyeceğim, sadece geri döndüğümde onları tekrar endekslemek zorundayım.

Üçüncü bir kullanım durumu , iki dal yerine iki dizin arasında git-diffnormalden farklı başka araçlar kullanarak dosya karşılaştırması yapmak olacaktır diff.


6
Olmaz git clonetüm bunlar için olduğu gibi iyi çalışır?
jthill

12
Uzaktan kumandanın büyük bir deposunu klonlamak uzun zaman alabilir. Klonlanması birkaç dakika süren bir depoya karşı çalışıyorum. Sanırım bunu yapabilirsin git clone --reference. Ayrıca, tüm diğer şubelerin yönetimi, her çalışma dizini için bir kez yerine sadece bir kez yapılacaktır.
Andreas Wederbrand

6
Uzaktan klonlama, yerel olandan klonlama. Şube yönetimi konusunu anlamıyorum, netleştirebilir misiniz?
jthill

14
Klonları kullanmaya çalıştım ve gerçekten bir yönetim sorunu var. Tek dal kümesi yerine, tek bir kullanıcı arayüzünde hep birlikte göremediğim bir dizi klonum var. Eğer bazı değişiklikleri seçmek zorunda kalırsam, onları getirmeli ya da itmeliyim. Tüm eylemlere ek adımlar ekler. Her şey yapılabilir, ancak her zaman bir sürtünme vardır.
max630

2
Ve bir yedekleme ayarlamak söz konusu olduğunda, tek bir depo çok daha kolaydır.
max630

64

Bariz bir kullanım, farklı sürümlerin davranışını (kaynak değil) eşzamanlı olarak karşılaştırmaktır - örneğin bir web sitesinin veya yalnızca bir web sayfasının farklı sürümleri.

Bunu yerel olarak denedim.

  • dizin yarat page1.

  • içinde dizin srcve git initonu oluşturun.

  • içinde srcoluşturmak page1.htmlbiraz içerikli ve bunu taahhüt.

  • $ git branch ver0

  • $ git worktree add ../V0 ver0

  • içinde srcusta fazla metin ekleyebilir page1.htmlve bunu taahhüt.

  • $ git branch sty1

  • düzenlemek page1.htmliçinde sty1şube (bazı ayırt edici CSS stil eklemek) ve bunu taahhüt ekleyin.

  • $ git worktree add ../S1 sty1

Artık bu 3 sürümü aynı anda açmak ve görüntülemek için bir web tarayıcısı kullanabilirsiniz:

  • ..\page1\src\page1.html // git ne olursa olsun git

  • ..\page1\V0\page1.html // ilk sürüm

  • ..\page1\S1\page1.html // deneysel olarak tasarlanmış sürüm


2
Bunun, bir klon üzerinde bu amaç için çalışma ağacını kullanmanın yararını nasıl açıkladığını görmüyorum.
iheanyi

@iheanyi Aynı şeyi söyleyebilirsiniz branch; cevap da aynı: daha hafif ve iş için tasarlandı.
OJFord

1
@OJFord bu biraz doğru. Bu cevap bana, bunun hangi çalışma ağacının farklı olduğunu açıklamıyor. Açıkçası dal veya klon için bir takma ad değil, ancak burada gördüğüm etki aynı görünüyor. Bunun sadece dal veya klon kullanmaktan daha hafif olduğunu görmüyorum.
iheanyi

@iheanyi Dal kullanmaktan farklıdır - aynı anda birden fazla çalışma durumu elde etmek için dalları tek başına kullanamazsınız - ve ikinci (.., nth) klondan daha hafiftir. Demek istediğim, 'neden sadece klonlama ve değişikliklerinizi yapmıyorsunuz', ancak tek bir repodaki çoklu dalların daha hafif bir ağırlık ve daha kolay yönetilen bir yol olduğunu da söyleyebilirsiniz.
OJFord

@OJFord Bunun çalışma ağacı ile olan karışıklığımı çözdüğünü sanmıyorum. Şunu söyleyeyim, ister dal ister klon veya başka bir şey kullansın, burada açıklanan sürecin nihai amacı, bir şeyin üç farklı versiyonunu aynı anda karşılaştırmaktır. Cevabın içeriğine dayanarak, bazı alternatifler üzerinde neden çalışma ağacı kullanacağımı anlamıyorum. Bu sorunun cevabı, alternatiflerin olmadığını düşündüğü çalışma dizisini açıklamıyor. Bir şeyin hafif (veya daha hafif) olması hakkında bir iddiada bulunuyorsunuz, ancak worktree'nin dalları nasıl daha az "ağırlık" yaptığını görmüyorum.
iheanyi

29
  1. Dosya sisteminde aynı anda birden fazla çalışma ağacının olmasını isteyebileceğiniz / gereksinim duyabileceğinizin geçerli nedenleri vardır.

    • teslim dosyaları manipüle ederken marka gerek başka bir yere değişir (örn. derleme / test)

    • dosyaları normal fark araçlarıyla ayırma

    • Birleştirme çatışmaları sırasında, sık sık kaynak tarafında olduğu gibi kaynak koduna göz atarak istediğiniz ederken dosyalarında çatışmaları çözmek.

    • Çok fazla ileri ve geri geçiş yapmanız gerekiyorsa, zaman ödünç verme ve birden fazla çalışma dersi ile yapmanız gerekmediğini yeniden kontrol etme.

    • Git depolaması ile dallar arasında geçiş yapan zihinsel bağlamın zihinsel maliyeti gerçekten ölçülemez. Bazı insanlar sadece farklı bir dizinden dosyaları açarak saklamanın zihinsel maliyeti olduğunu buluyor.

  2. Bazı insanlar "neden birden fazla yerel klon yapmıyor" diye soruyor. "--Local" bayrağı ile fazladan disk alanı kullanımı hakkında endişelenmenize gerek olmadığı doğrudur. Bu (ya da benzer fikirler) şimdiye kadar yaptığım şey. Yerel klonlara göre bağlantılı çalışma yöntemlerinin fonksiyonel avantajları:

    1. Yerel klonlar ile (yerel klonlarda bulunan) ekstra çalışma ağaçlarınızın menşe veya yukarı akış dallarına erişimi yoktur. Klondaki 'köken', ilk klondaki 'köken' ile aynı olmayacaktır.

      • Koşmak git log @{u}..veya git diff origin/feature/other-featureçok yardımcı olabilir ve bunlar artık mümkün değil veya daha zor. Bu fikirler, bir dizi geçici çözüm aracılığıyla yerel klonlarla teknik olarak mümkündür, ancak yapabileceğiniz her geçici çözüm bağlantılı çalışma yöntemleri aracılığıyla daha iyi ve / veya daha basit yapılır.
    2. Referansları çalışma saatleri arasında paylaşabilirsiniz. Başka bir yerel şubedeki değişiklikleri karşılaştırmak veya ödünç almak istiyorsanız, şimdi yapabilirsiniz.


11
Ayrıca, tüm çalışma takımlarını tek bir komutla listeleyebilirsiniz, klonlarla bunları kendiniz takip etmeniz gerekir.
Ian Ringrose

hı. Git 2.7.0 itibariyle durum böyle görünüyor. Bilmek güzel.
Alexander Bird

9

tl; dr: Ne zaman olursa olsun, aynı anda iki çalışma ağacını kontrol ettirmek istediğinizde, git-worktreebunu yapmanın hızlı ve az yer kaplayan bir yoludur.

Başka bir çalışma ağacı oluşturursanız, repo'nun çoğu bölümü .gitpaylaşılacaktır, yani bir çalışma ağacındayken bir şube oluşturursanız veya veri alırsanız, buna sahip olduğunuz diğer çalışma ağaçlarından da erişilebilir. Diyelim ki test paketinizi klonlamak için bir yere itmek zorunda kalmadan dal foo üzerinde çalıştırmak istiyorsunuz ve deponuzu yerel olarak klonlama zahmetinden kaçınmak istiyorsanız, kullanmak git-worktree, geçici veya kalıcı olarak ayrı bir yer. Tıpkı bir klonda olduğu gibi, işiniz bittiğinde yapmanız gereken tek şey onu silmek ve ona referans bir süre sonra çöp toplanacak.


2
Dokümanlar, her iki çalışma kopyasında da aynı şubeye sahip olamayacağınızı söylüyor, bu da ciddi bir sınırlama. Mercurial ile sadece küçük sorunlarla çalıştı.
hypersw

Tabi ki yapabilirsin. Man sayfası nasıl; arayın --force. Ancak, şubeyi bir yerde güncellemeniz ve başka bir yerde çalışmayı beklemeniz zordur, çünkü çalışma ağacı güncellenmez.
jsageryd

Evet, Mercurial'daki dallar bu açıdan daha şeffaf bir kavram. Bir çalışma ağacından dallar diğerinde nasıl görünür? Birden fazla bağlantıyla aynı şekilde mi? Worktrees ile ilk deneylerim, her ikisinde de getirme ile, adlandırılan iki (!) Farklı (!) İşaretçi ile sona erdi origin/master.
hypersw

Bir çalışma ağacı (adından da anlaşılacağı gibi), yalnızca bazı ekstra özellikler içeren bir çalışma ağacıdır; veri havuzu tüm çalışma grupları arasında paylaşılır. İki çalışma ağacı arasındaki tek fark, kullanıma alınmış dalın (ve aklı başında iş akışları için) farklı olabilmesidir. Ayrı bir çalışma ağacında işlem yapmak mümkündür, bu yüzden bu işi yapmak için kendi indeksine (sahne alanı olarak da bilinir) sahiptir. .gitAyrı worktree dosya orijinal depoda bulunan yapılandırmasına, yolunu içeren bir metin dosyasıdır.
jsageryd

2
@WilsonF: git checkout --ignore-other-worktrees <branch> git-scm.com/docs/git-checkout/…
jsageryd

7

Başlangıçta bu süslü çalışmaların ne için kullanılabileceğini merak ettikten sonra bu soru üzerine tökezledim. O zamandan beri onları iş akışımla bütünleştirdim ve ilk şüpheciliğime rağmen onları oldukça faydalı bulmaya geldim.

Derlemek oldukça zaman alan oldukça büyük bir kod tabanı üzerinde çalışıyorum. Genellikle şu anda üzerinde çalıştığım özellik dalının yanı sıra canlı sistemin geçerli durumunu temsil eden ana dal ile birlikte makinemdeki geçerli geliştirme dalına sahibim.

Benim için en büyük faydalardan biri, şubeleri her değiştirdiğimde (yani çalışma saatleri) her şeyi yeniden derlemem gerekmediği. Güzel bir yan etkisi, geliştirme çalışma ağacına gidebilir, orada bir şeyler yapabilir, mevcut özellik dalım için çalışma ağacına dizini değiştirebilir ve sonra ilk önce çekmeye gerek kalmadan yeniden oluşturabilirim.


4

Oldukça sıradışı bir tane var: Aynı makinede Windows ve Linux geliştirme yapıyorum . Windows kutumun içinde Linux çalıştıran bir VirtualBox var. VirtualBox bazı Windows dizinlerini bağlar ve bunları doğrudan Linux makinesinin içinde kullanır. Bu, dosyaları yönetmek için Linux kullanmamı ancak Linux içinde oluşturmamı sağlıyor. Bu, çapraz platformlu bir projedir, bu nedenle aynı dizin yapısından hem Windows hem de Linux üzerine kurulur.

Sorun şu ki, Linux ve Windows derleme sistemleri aynı dizinde kullanıldıklarında birbirine çarpıyor; aynı dizin adlarını kullanan kütüphaneleri vb. indirmek için bazı karmaşık oluşturma adımları vardır. Derleme sisteminin Windows sürümü Windows'a özel kütüphaneleri indirir ve derleme sisteminin Linux sürümü Linux'a özel kütüphaneleri indirir.

İdeal bir dünyada, Windows ve Linux dizinde birlikte bulunabilecek şekilde yapı sistemi değiştirilecek, ancak şimdilik sorun çalışma ağaçlarıyla ilgileniliyor. "Linux" klasörü Linux'a özgü yapı yapıları oluşturabilir ve "Windows" klasörü Windows'a özgü yapı yapıları oluşturabilir. Bu neredeyse ideal bir çözüm olmasa da, derleme sistemi hatalarının ele alınmasını beklerken hoş bir durma aralığı oluşturur.

Kuşkusuz, çalışma ağacı bunun için tasarlanmamıştır; Gerçekten aynı dalda olmalarını tercih etsem de, Windows sürümünü ve Linux sürümünü ayrı dallarda tutmam gerekiyor. Yine de, bu işi yapıyor ve günü kurtarmak biraz alışılmadık bir çalışma vakası.


+1 Bu, yapılandırma başına derleme çıktı dizinlerini yerel olarak yapmamak için çok etkili bir geçici çözüm gibi görünüyor. Ubuntu ve macOS misafirleriyle benzer bir VMware Workstation kurulumum var.
Tanz87

1

Benim için yeni projede bir özellik yarattım. Ancak bazı özellikler başarısız oldu. Sonuçları karşılaştırmak için masterbir work-treerepo oluşturdum . Neyin yanlış gittiğini anlayana kadar sonuçları çalışma kodunda adım adım karşılaştırdım.


Bir çalışma ağacı bunu bir klondan nasıl daha kolay hale getirir? Soru kişisel tercih değil, somut farklılıklar.
Tahmin edilemez

1

git worktreeMakine öğrenimi gelişimi için kullanıyorum .

Ben bir ana fonksiyonel kod var ve sonra farklı deneyler (farklı algoritmalar ve farklı hiperparametreler) dallarını bölmek istiyorum. dvc kodumun farklı algoritmalara özel farklı sürümleri git worktreeile entegre etmemi sağlıyor . Tüm eğitim işlerini yürüttükten sonra son metrikleri değerlendirir ve en iyi şube / modelde ustalaşmak için birleşirim.

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.