Geçerli Git dalını ana dal yapma


1657

Git'te bir depom var. Bir dal yaptım, daha sonra hem efendide hem de dalda bazı değişiklikler yaptım.

Sonra, onlarca taahhüt daha sonra, şubenin efendiden çok daha iyi durumda olduğunu fark ettim, bu yüzden şubenin efendi "olmasını" ve efendideki değişiklikleri göz ardı etmesini istiyorum.

Birleştiremiyorum, çünkü değişiklikleri efendide tutmak istemiyorum. Ne yapmalıyım?

Ekstra : Bu durumda, 'eski' master zaten pushGitHub gibi başka bir depoya gönderildi. Bu bir şeyleri nasıl değiştirir?


2
Çok benzer soruların cevaplarını kontrol edin stackoverflow.com/q/2862590/151641
mloskot

4
Aynı sorun vardı, ancak sadece ustayı kaldırdım ve master için başka bir dalı yeniden adlandırdım: stackoverflow.com/a/14518201/189673
jayarjo

10
@jayarjo Eğer mümkünse bundan kaçınmalısınız çünkü geçmişi yeniden yazacak ve bir sonraki ustayı çekmeye çalıştıklarında herkes için sorunlara neden olacaktır.
joelittlejohn

3
Bu yüzden @Jefromi'nin cevabını seviyorum. Arşiv tarihinin yapısökümü devam etmiyor.
froggythefrog

Yanıtlar:


2134

Diğer iki cevapla ilgili sorun, yeni ustanın bir ata olarak eski ustaya sahip olmamasıdır, bu yüzden ittiğinizde diğer herkes berbat olur. Yapmak istediğiniz budur:

git checkout better_branch
git merge --strategy=ours master    # keep the content of this branch, but record a merge
git checkout master
git merge better_branch             # fast-forward master up to the merge

Geçmişinizin biraz daha net olmasını istiyorsanız, yaptığınız işlemi netleştirmek için birleştirme taahhüdü mesajına bazı bilgiler eklemenizi tavsiye ederim. İkinci satırı şu şekilde değiştirin:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message

25
Git'in birleşmesi "stratejileri" ile ilgili not: --strategy=oursfarklıdır --strategy=recursive -Xours. Yani "bizim" kendi başına bir strateji olabilir (sonuç ne olursa olsun mevcut dal olacaktır) veya "özyinelemeli" stratejiye bir seçenek olarak (diğer dalın değişikliklerini getirebilir ve bir çatışma olduğunda otomatik olarak mevcut dalın değişikliklerini tercih edebilir) ).
Kelvin

5
git merge --strategy=ours master -m "new master"Çalışması için ikinci çizgiyi yapmak zorunda kaldım .
incandescentman

5
@Johsm Cevabımın ilk cümlesi tam olarak bundan bahsediyor. Bunu yaparsanız, yeni master eski master ile aynı tarihe sahip olmayacaktır, bu da itmek / çekmek istiyorsanız Çok Kötü. Bunun doğru çalışması için soyları paylaşmış olmanız gerekir; bunun yerine söylediklerinizi yaparsanız, itmeye çalıştığınızda zorlamadığınız sürece başarısız olur (çünkü bu Kötü ve sizi durdurmaya çalışıyor) ve zorlarsanız, daha sonra çeken herkes muhtemelen bir tren kazası olacak olan eski ustayı ve yeni ustayı birleştirmeye çalışacaktır.
Cascabel

4
Birleştirme sırasında vi düzenleyicisi görünürse, şunu yazın: w (kaydetmek için): q (
vi'dan

9
Bu cevap harika çalışıyor. Ben sadece (yeni ya da emin olmayabilir insanlar git pushiçin) kodunuzu uzaktan yukarı itmek istiyorsanız bundan sonra bir sağ yapmak zorunda olduğunu eklemek istedim . Your branch is ahead of 'origin/master' by 50 commits.Bu beklenen bir uyarı görebilirsiniz . Sadece it! : D
chapeljuice

387

Her şeyin uzak deponuza (GitHub) aktarıldığından emin olun:

git checkout master

"Better_branch" ile "master" ın üzerine yaz:

git reset --hard better_branch

Push'u uzak deponuza zorlayın:

git push -f origin master

81
Bu muhtemelen çoğu insanın aradığı cevaptır. BS strateji birleşimindeki diğer tüm cevaplar şubenin yerini tamamen almaz. Bu her şeyi istediğim gibi yaptı, dalın üzerine yaz ve onu zorla.
Gubatron

31
bu gerçekten de pek çok kişinin aradığı şey olsa da, repo'nun diğer yerel kopyalarının bir git reset --hard origin/masterdaha çekmek istedikleri zamana ihtiyaç duyacağı unutulmamalıdır , aksi takdirde git değişiklikleri (şimdi) ıraksak yerellerine birleştirmeye çalışacaktır. Bunun tehlikeleri bu cevapta
7yl4r

3
ayrıca havuza zorla göndermeye izin vermeniz gerektiğini lütfen unutmayın - örneğin bir iş ortamında bu işe yaramaz
inetphantom

Burada ters, insanların ne istediğine bağlı olarak bir dezavantaj olabilir. Eğer ustanın tarihini diğer dalın tarihiyle değiştirmek kadar ileri gitmek istiyorsanız, bu sizin cevabınızdır.
b15

75

Edit: Sen halka açık bir repo itti söylemedin! Bu fark yaratan bir dünya.

İki yol vardır, "kirli" yol ve "temiz" yol. Diyelim ki dalınız adlandırıldı new-master. Temiz yol budur:

git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part.  Just don't.  But if you want to...
# git branch -d --force old-master

Bu, yapılandırma dosyalarını yeniden adlandırılan dallarla eşleşecek şekilde değiştirir.

Ayrıca, yapılandırma dosyalarını güncellemeyen kirli bir şekilde de yapabilirsiniz. Bu, yukarıdaki başlık altında devam eden bir şey ...

mv -i .git/refs/new-master .git/refs/master
git checkout master

2
Teşekkür ederim. Bir soru daha. Bunu github'a itiyorum. Bunu yaparsam orada ne olacak?
Karel Bílek

3
@Karel: Diğer kullanıcılar için biraz karışıklık yaratacak; master'larını github master'a sıfırlamak zorunda kalacaklar. Onlara herhangi bir soruna neden olmaktan kaçınmak istiyorsanız, cevabıma bir bakın.
Cascabel

6
@Dietrick Epp: Kirli yolu önermenin iyi bir fikir olup olmadığından emin değilim. Uzaktan izlemeyi bozacak, refloglar ... bunu yapmak için herhangi bir sebep düşünemiyorum.
Cascabel

2
Ah, bu iyi bir nokta. Gerçi her ikisine de sahip olabilir: git branch old-master master; git branch -f master new-master. Yedek dalı taze oluşturun, ardından master'ı doğrudan yeni master'a taşıyın. (Ve adınızı yanlış yazdığınız için üzgünüm, bunu fark
ettiniz

2
@FakeName Bunu yapmak için hiçbir neden olmadığı sonucuna varamadım, sadece kirli bir şekilde yapmak için hiçbir neden yok . Normal komutları kullanarak (önceki yorumumda olduğu gibi) yapabilir ve aynı sonucu elde edebilirsiniz, ancak refleksler bozulmamış ve bir şeyleri canlandırma şansı yoktur. Uygulama ayrıntılarıyla uğraşmadığınız için çalışması garanti edilir.
Cascabel

46

Şube adını şu şekilde değiştirin master:

git branch -M branch_name master

11
Ne yazık ki git şube yeniden adlandırmalarını izlemez, bu nedenle repo'nuzu zaten bir uzaktan kumandaya ittiyseniz ve diğerlerinin yerel eski ana dalında yerel değişiklikler varsa, sorun yaşarlar.
thSoft

ve arasında bir fark var git checkout master&&git reset --hard better_branchmı?
wotanii

26

Anladığım kadarıyla, mevcut dalı mevcut bir şubeye ayırabilirsiniz. Aslında, bu mastermevcut dalda ne varsa üzerine yazacaktır :

git branch -f master HEAD

Bunu yaptıktan sonra, normalde yerel masterşubenizi zorlayabilirsiniz , muhtemelen burada force parametresini de gerektirir :

git push -f origin master

Birleştirme yok, uzun komutlar yok. Basitçe branchve push- ama evet, bu tarihi yeniden yazmak olacaktır arasında mastersize ne yaptığınızı bilmek var bir ekip çalışması eğer öyleyse, şube.




Alternatif olarak, herhangi bir dalı herhangi bir uzak dala itebileceğinizi buldum, bu yüzden:

# This will force push the current branch to the remote master
git push -f origin HEAD:master

# Switch current branch to master
git checkout master

# Reset the local master branch to what's on the remote
git reset --hard origin/master

Çok basit ve mükemmel çalıştı! İki basit ve anlaşılması kolay git komutları. Git depom kaydedildi ve şimdi çok temiz görünüyor. Teşekkürler!
thehelix

16

Blog yazısında istediğim cevabı buldum Ana dalı git'te başka bir dalla değiştir :

git checkout feature_branch
git merge -s ours --no-commit master
git commit      # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch

Aslında Cascabel'in cevabı ile aynı . Çözümünün altına eklediği "seçenek" dışında ana kod bloğuma zaten gömülü.

Bu yolu bulmak daha kolay.

Daha sonra bu çözümü gerekirse, ben olmasını istiyorum çünkü yeni cevap olarak bu ekliyorum tüm kodu ben bir kod bloğu kullanmak için gidiyorum.

Aksi takdirde, kopyalayıp yapıştırabilir ve daha sonra değiştirmem gereken satırı görmek için aşağıdaki ayrıntıları okuyabilirim - zaten yürüttükten sonra.


14

Burada verilen çözümler (şubeyi 'master' olarak yeniden adlandırmak) uzak (GitHub) repo sonuçları için ısrar etmiyor:

  • o dalı yaptığınızdan beri hiçbir şey itmediyseniz, yeniden adlandırabilir ve sorunsuz bir şekilde itebilirsiniz.
  • GitHub'da push master'ınız varsa, yeni dalı 'git push -f' yapmanız gerekir: artık hızlı ileri sarma moduna geçemezsiniz .
    -f
    --güç

Genellikle, komut, üzerine yazmak için kullanılan yerel ref'nin atası olmayan bir uzak ref'yi güncellemeyi reddeder. Bu bayrak denetimi devre dışı bırakır. Bu, uzak deponun taahhütlerini kaybetmesine neden olabilir; dikkatli kullanın.

Başkaları repo'yu zaten çektiyse, kendi master'larını yeni GitHub master şubesiyle değiştirmeden (veya çok sayıda birleşmeyle uğraşmadan) yeni master geçmişini çekemezler. Halka açık depolar için bir git pushforforce'a alternatifler
vardır . Jefromi'nin cevabı (doğru değişiklikleri orijinal ustaya geri birleştirmek) bunlardan biridir.


14

En iyi şekilde çalışmak için bu basit yöntemi buldum. Geçmişi yeniden yazmaz ve şubenin önceki tüm check-in'leri yöneticiye eklenir. Hiçbir şey kaybolmaz ve kayıt günlüğünde ne olduğunu açık bir şekilde görebilirsiniz.

Amaç: "Şube" nin mevcut durumunu "ana" yapmak

Bir şube üzerinde çalışırken, yerel ve uzak depolarınızın güncel olduğundan emin olmak için değişikliklerinizi yapın ve aktarın:

git checkout master      # Set local repository to master
git reset --hard branch  # Force working tree and index to branch
git push origin master    # Update remote repository

Bundan sonra, master'ınız son şube taahhüdünüzün tam durumu olacak ve master taahhüt günlüğünüz şubenin tüm check-in'lerini gösterecektir.


10

Ayrıca, diğer daldaki tüm dosyaları master'a da alabilirsiniz:

git checkout master
git checkout better_branch -- .

ve sonra tüm değişiklikleri yapın.


5

Jefromi'nin cevabına eklemek için, sourcedalın tarihine anlamsız bir birleştirme yerleştirmek istemiyorsanız , oursbirleştirme için geçici bir dal oluşturabilir , sonra atabilirsiniz:

git checkout <source>
git checkout -b temp            # temporary branch for merge
git merge -s ours <target>      # create merge commit with contents of <source>
git checkout <target>           # fast forward <target> to merge commit
git merge temp                  # ...
git branch -d temp              # throw temporary branch away

Bu şekilde birleştirme taahhüdü sadece targetşube tarihinde var olacaktır .

Alternatif olarak, bir birleştirme oluşturmak istemiyorsanız, içeriğini alabilir sourceve yeni bir taahhüt için kullanabilirsiniz target:

git checkout <source>                          # fill index with contents of <source>
git symbolic-ref HEAD <target>                 # tell git we're committing on <target>
git commit -m "Setting contents to <source>"   # make an ordinary commit with the contents of <source>

3

Benim için, şeytanımın ilerledikten sonra ustaya geri dönmesini istedim.

Gelişirken:

git checkout master
git pull

git checkout develop
git pull

git reset --hard origin/master
git push -f

2

Bir şeyler yapma şeklim şu

#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop

2

Eğer kullanıyorsanız Eğit içinde Eclipse :

  • Proje düğümüne sağ tıklayın.
  • Ekip → ardından Gelişmiş → ardından Şubeyi yeniden adlandır'ı seçin
  • Ardından uzaktan izleme klasörünü genişletin .
  • Yanlış ada sahip dalı seçin, ardından yeniden adlandır düğmesini tıklayın, yeni adla yeniden adlandırın.
  • Yeni master'ı seçin, ardından master olarak yeniden adlandırın.

Bunu yaptım ama işe yarayıp yaramadığından emin değilim. Github'da hiçbir şey değişmedi ama git uzantılarında şubenin yeniden adlandırıldığını görebiliyorum.
Pramod

0

Atlassian (Bitbucket sunucusu) tarafından desteklenen Git tarayıcısında aşağıdaki adımlar gerçekleştirilir

{Current-branch} öğesini şu şekilde yapma: master

  1. Bir dalı çıkarın masterve "master-duplicate" olarak adlandırın.
  2. {Current-branch} dışında bir dal oluşturun ve "{current-branch} -copy" olarak adlandırın.
  3. Havuz ayarında (Bitbucket) “Varsayılan Şube” yi “master-duplicate” olarak gösterecek şekilde değiştirin (bu adım olmadan master'ı silemezsiniz - “Sonraki adımda”).
  4. "Ana" dalını sil - Bu adımı kaynak ağacından yaptım (bunu CLI veya Git tarayıcısından yapabilirsiniz)
  5. “{Current-branch}” öğesini “master” olarak yeniden adlandırın ve veri havuzuna aktarın (bu yeni bir “master” dal yaratacaktır, yine de “{current-branch}” mevcut olacaktır).
  6. Havuz ayarlarında, “Varsayılan Şube” yi “ana” olarak işaretleyin.
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.