Yalnızca yerel şubemde aşağıdaki işleme geçmişine sahip olduğumu varsayalım:
A -- B -- C
Nasıl ekler yeni arasındaki taahhüt yapmak Ave B?
Yalnızca yerel şubemde aşağıdaki işleme geçmişine sahip olduğumu varsayalım:
A -- B -- C
Nasıl ekler yeni arasındaki taahhüt yapmak Ave B?
Yanıtlar:
OP'nin cevabından bile daha kolay.
git rebase -i <any earlier commit>. Bu, yapılandırılmış metin düzenleyicinizde işlemlerin bir listesini görüntüler.a1b2c3d). Düzenleyicinizde, o satır için, değiştirmek pickiçin edit.a1b2c3d) sanki henüz kaydedilmiş gibi bir komut isteminde bırakır .git commit( DEĞİL en aksine değiştiren edits). Bu, seçtiğiniz bir işlemden sonra yeni bir işlem oluşturur .git rebase --continue. Bu, ardışık kaydetmeleri yeniden oynatır ve yeni kaydetmenizi doğru yere yerleştirir.Bunun tarihi yeniden yazacağına ve çekmeye çalışan herkesi kıracağına dikkat edin.
A -- B -- C -- Darzulanmak yerine oldu A -- D -- B -- C.
Dherhangi bir yerde taahhüt olabilir. Varsayalım ki bu dalda olmayan A - B - Cbazı taahhütlerimiz var D. SHA'sını biliyoruz ancak yapabiliriz git rebase -i HEAD~3. Şimdi Ave B picksatırları arasına istenen hash değerini veren yeni bir pick satır pick SHAekliyoruz D. Tam hash olması gerekmez, sadece kısaltılmış olanı. git rebase -isadece kiraz seçer pick, arabellekteki satırlara göre listelenen taahhütler ; sizin için listeledikleri orijinal olanlar olmak zorunda değiller.
breakanahtar kelimeyi düzenleyicideki kendi satırında iki kaydetme arasında (veya ilk satırda, belirttiğiniz commitden önce bir commit eklemek için) kullanabilirsiniz.
Cevap burada bulundu oldukça basit çıktı . Bir dalda olduğunuzu varsayalım branch. Şu adımları uygulayın:
yeni kaydetmeyi eklemek istediğinizde kaydetmeden geçici bir dal oluşturun (bu durumda kesinleştirme A):
git checkout -b temp A
değişiklikleri yapın ve onları kesin, bir commit yaratın, hadi buna diyelim N:
git commit -a -m "Message"
(veya git addardından git commit)
Yeni taahhütten sonra (bu durumda taahhüt eder Bve C) sahip olmak istediğiniz taahhütleri yeni taahhüde yeniden ekleyin:
git rebase temp branch
(muhtemelen kullanmak gerekir -pherhangi olsaydı, birleştirmeleri korumak için - sayesinde hiç bir artık mevcut comment tarafından ciekawy )
geçici şubeyi silin:
git branch -d temp
Bundan sonra tarih şu şekildedir:
A -- N -- B -- C
Yeniden yapılanma sırasında bazı çatışmaların ortaya çıkması elbette mümkündür.
Şubenizin yalnızca yerel olmaması durumunda, bu, yeniden yazma geçmişini ortaya çıkarır, bu nedenle ciddi sorunlara neden olabilir.
git push --force, uzak depoyu değiştirmek zorunda kaldım .
git rebase temp branch -Xtheirs. Bir komut dosyasına enjekte etmek için faydalı cevap!
git rebase temp branch, ancak öncesinde git branch -d tempyapmanız gereken tek şey, çatışmaları ve sorunları düzeltmek ve sahneye git rebase --continuekoymak, yani hiçbir şey işlemeye gerek yok, vb.
Daha da kolay çözüm:
Sonunda yeni commitinizi oluşturun, D. Artık şunlara sahipsiniz:
A -- B -- C -- D
O zaman koş:
$ git rebase -i hash-of-A
Git, editörünüzü açacak ve şöyle görünecektir:
pick 8668d21 B
pick 650f1fc C
pick 74096b9 D
Sadece D'yi bu şekilde en üste taşıyın, sonra kaydedin ve çıkın
pick 74096b9 D
pick 8668d21 B
pick 650f1fc C
Şimdi sahip olacaksınız:
A -- D -- B -- C
Tarih taahhüt varsayarsak preA -- A -- B -- CBir arasına taahhüt eklemek istiyorsanız, Ave B, adımlar aşağıdaki gibi şunlardır:
git rebase -i hash-of-preA
Git, editörünüzü açacaktır. İçerik bundan hoşlanabilir:
pick 8668d21 A
pick 650f1fc B
pick 74096b9 C
İlk değiştirme pickiçin edit:
edit 8668d21 A
pick 650f1fc B
pick 74096b9 C
Kaydet ve çık.
Kodunuzu değiştirin ve ardından git add . && git commit -m "I"
git rebase --continue
Artık Git kaydetme geçmişiniz preA -- A -- I -- B -- C
Bir çakışma ile karşılaşırsanız, Git bu işlemde duracaktır. Sen kullanabilirsiniz git diffçatışma işaretleri bulmak ve bunları çözmek için. Tüm çatışmaları çözdükten sonra, git add <filename>Git'e çatışmanın çözüldüğünü söylemeniz ve ardından yeniden çalıştırmanız gerekir.git rebase --continue .
Yeniden temellemeyi geri almak istiyorsanız, kullanın git rebase --abort.
İşte okuduğum diğer cevaplarda görülen yeniden temelde "düzenleme hilesi" yapmaktan kaçınan bir strateji.
Kullanarak git rebase -i, o commit'den beri bir commit listesi elde edersiniz. Dosyanın en üstüne bir "ara" eklemeniz yeterlidir, bu, yeniden ödemenin bu noktada kırılmasına neden olur.
break
pick <B's hash> <B's commit message>
pick <C's hash> <C's commit message>
Bir kez başlatıldığında, git rebaseşimdi "kırılma" noktasında duracaktır. Artık dosyalarınızı düzenleyebilir ve kaydetmenizi normal şekilde oluşturabilirsiniz. Daha sonra ile yeniden ödemeye devam edebilirsiniz git rebase --continue. Bu, düzeltmeniz gereken çatışmalara neden olabilir. Eğer kaybolursanız, kullanmayı her zaman iptal edebileceğinizi unutmayın git rebase --abort.
Bu strateji herhangi bir yere bir commit eklemek için genelleştirilebilir, sadece "break" u bir commit eklemek istediğiniz noktaya koyun.
Geçmişi yeniden yazdıktan sonra unutmayınız git push -f. Şubenizi getiren diğer kişilerle ilgili olağan uyarılar geçerlidir.
rebaseburada. Taahhüdü yeniden ödeme sırasında mı yoksa önceden mi oluşturacağınız çok fark etmez.
Zaten burada birçok iyi cevap var. Sadece 4 kolay adımda "geri ödemesiz" bir çözüm eklemek istedim.
özet
git checkout A
git commit -am "Message for commit D"
git cherry-pick A..C
git branch -f master HEAD
açıklama
(Not: Bu çözümün bir avantajı, son adıma kadar şubenize dokunmamanızdır, sonuçtan% 100 emin olduğunuzda, çok kullanışlı bir "ön onay" adımınız olur. AB testine izin veriyor .)
Başlangıç durumu ( masterŞube adınızı varsaydım )
A -- B -- C <<< master <<< HEAD
1) HEAD'i doğru yere doğrultarak başlayın
git checkout A
B -- C <<< master
/
A <<< detached HEAD
(İsteğe bağlı olarak burada, HEAD'i git checkout -b temp Aayırmak yerine, sürecin sonunda silmemiz gereken geçici bir dal oluşturabilirdik . Her iki değişken de çalışır, her şey aynı kaldığı için tercih ettiğiniz gibi yapın)
2) Eklenecek yeni D kaydını oluşturun
# at this point, make the changes you wanted to insert between A and B, then
git commit -am "Message for commit D"
B -- C <<< master
/
A -- D <<< detached HEAD (or <<< temp <<< HEAD)
3) Ardından, son eksik olan B ve C işlemlerinin kopyalarını getirin (daha fazla işlem varsa aynı satır olacaktır)
git cherry-pick A..C
# (if any, resolve any potential conflicts between D and these last commits)
B -- C <<< master
/
A -- D -- B' -- C' <<< detached HEAD (or <<< temp <<< HEAD)
(gerekirse burada rahat AB Testi)
Şimdi kodunuzu inceleme, test edilmesi gereken her şeyi test etme zamanı ve ayrıca sahip olduklarınızı ve işlemlerden sonra ne elde edeceğinizi ayırt edebilir / karşılaştırabilir / inceleyebilirsiniz .
4)C ve arasındaki testlerinize bağlı olarak C'ya OK ya da KO.
(EITHER) 4-OK) Son olarak,master
git branch -f master HEAD
B -- C <<< (B and C are candidates for garbage collection)
/
A -- D -- B' -- C' <<< master
(OR) 4-KO) Sadece ayrılmaster Değiştirmeden
Geçici bir dal oluşturduysanız, sadece ile silin git branch -d <name>, ancak ayrılmış HEAD yoluna gittiyseniz, bu noktada hiçbir işlem yapmanız gerekmez, yeni taahhütler, yeniden bağladıktan hemen sonra çöp toplama için uygun olacaktır.HEAD a ilegit checkout master
Her iki durumda da (Tamam veya KO), bu noktada masteryeniden bağlamak için tekrar kontrol edin HEAD.