Tarihi diğer geliştiricilere yayınladıysanız, yapmak istediğiniz şey oldukça rahatsız edicidir. Geçmişinizi onardıktan sonra gerekli adımlar için git rebase
dokümantasyondaki “Yukarı Akış Rebase'den Kurtarma” başlığına bakın .
En az iki seçeneğiniz vardır: git filter-branch
ve ikisi de aşağıda açıklanan etkileşimli bir yeniden temel.
kullanma git filter-branch
Bir Subversion içe aktarımından hantal ikili test verileri ile benzer bir sorun yaşadım ve git deposundan veri kaldırma hakkında yazdım .
Git geçmişinizin:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A login.html
* cb14efd Remove DVD-rip
| D oops.iso
* ce36c98 Careless
| A oops.iso
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
Bunun git lola
standart olmayan ancak son derece kullanışlı bir takma ad olduğunu unutmayın. İle --name-status
anahtar, her taahhüt ilişkili ağaç değişiklikleri görebilirsiniz.
"Dikkatsiz" komutunda (SHA1 nesne adı ce36c98 olan) dosya oops.iso
, kazayla eklenen ve sonraki işlem olan cb14efd'de kaldırılan DVD ripidir. Yukarıda adı geçen blog gönderisinde açıklanan tekniği kullanarak, yürütme komutu şöyledir:
git filter-branch --prune-empty -d /dev/shm/scratch \
--index-filter "git rm --cached -f --ignore-unmatch oops.iso" \
--tag-name-filter cat -- --all
Seçenekler:
--prune-empty
filtre işlemi sonucunda boş kalan ( yani ağacı değiştirmeyen) taahhütleri kaldırır . Tipik durumda, bu seçenek daha temiz bir geçmiş oluşturur.
-d
filtrelenmiş geçmişi oluşturmak için henüz kullanılmayan geçici bir dizini adlandırır. Modern bir Linux dağıtımında çalışıyorsanız, bir ağacın/dev/shm
belirtilmesi daha hızlı yürütmeye neden olur .
--index-filter
ana olaydır ve geçmişin her adımında dizine karşı çalışır. Bulunduğu yeri kaldırmak istiyorsunuz oops.iso
, ancak tüm taahhütlerde mevcut değil. Komut git rm --cached -f --ignore-unmatch oops.iso
, DVD rip'i mevcut olduğunda siler ve aksi halde başarısız olmaz.
--tag-name-filter
etiket adlarının nasıl yeniden yazılacağını açıklar. Bir filtre cat
kimlik işlemidir. Deponuzda, yukarıdaki örnekte olduğu gibi, herhangi bir etiket olmayabilir, ancak tam genellik için bu seçeneği ekledim.
--
için seçeneklerin sonunu belirtir git filter-branch
--all
Aşağıdaki --
tüm referanslar için kestirme. Deponuzda, yukarıdaki örnekte olduğu gibi, yalnızca bir ref (master) olabilir, ancak tam genelleme için bu seçeneği ekledim.
Bazı çalkalamalardan sonra, tarih şimdi:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A login.html
* e45ac59 Careless
| A other.html
|
| * f772d66 (refs/original/refs/heads/master) Login page
| | A login.html
| * cb14efd Remove DVD-rip
| | D oops.iso
| * ce36c98 Careless
|/ A oops.iso
| A other.html
|
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
Yeni "Dikkatsiz" komutunun yalnızca eklediğine other.html
ve "DVD-rip'i Kaldır" komutunun artık ana dalda olmadığına dikkat edin. Etiketli şube refs/original/refs/heads/master
, bir hata yapmanız durumunda orijinal taahhütlerinizi içerir. Kaldırmak için, “Bir Depoyu Küçültmek İçin Denetim Listesi” bölümündeki adımları izleyin .
$ git update-ref -d refs/original/refs/heads/master
$ git reflog expire --expire=now --all
$ git gc --prune=now
Daha basit bir alternatif için, istenmeyen bitleri atmak için havuzu klonlayın.
$ cd ~/src
$ mv repo repo.old
$ git clone file:///home/user/src/repo.old repo
Bir file:///...
klon URL'si kullanmak, nesneleri yalnızca sabit bağlantılar oluşturmak yerine kopyalar.
Şimdi geçmişiniz:
$ git lola --name-status
* 8e0a11c (HEAD, master) Login page
| A login.html
* e45ac59 Careless
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
İlk iki işlemin (“Dizin” ve “Yönetici sayfası”) SHA1 nesne adları aynı kaldı, çünkü filtre işlemi bu taahhütleri değiştirmedi. Kayıp “Dikkatsiz” oops.iso
onların SHA1s böylece ve “Giriş sayfası”, yeni bir ebeveyn var yaptılar değişikliği.
Etkileşimli rebase
Geçmişi ile:
$ git lola --name-status
* f772d66 (HEAD, master) Login page
| A login.html
* cb14efd Remove DVD-rip
| D oops.iso
* ce36c98 Careless
| A oops.iso
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
oops.iso
daha önce hiç eklememişsiniz gibi “Dikkatsiz” öğesinden kaldırmak istiyorsunuz ve daha sonra “DVD-rip'i Kaldır” işinize yaramaz. Bu nedenle, etkileşimli bir yeniden plana girme planımız “Yönetici sayfası” nı “Dikkatsiz” olarak düzenlemeyi ve “DVD-rip'i Kaldır” a atmayı amaçlıyor.
Running $ git rebase -i 5af4522
, aşağıdaki içeriğe sahip bir düzenleyici başlatır.
pick ce36c98 Careless
pick cb14efd Remove DVD-rip
pick f772d66 Login page
# Rebase 5af4522..f772d66 onto 5af4522
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#
Planımızı uygulayarak,
edit ce36c98 Careless
pick f772d66 Login page
# Rebase 5af4522..f772d66 onto 5af4522
# ...
Yani, “DVD-rip'i Kaldır” ile çizgiyi sileriz ve “Dikkatsiz” üzerindeki işlemi edit
yerine değiştiririz pick
.
Düzenleyiciyi kaydetmeyi bırak, aşağıdaki mesajla birlikte bir komut isteminde bizi bırakır.
Stopped at ce36c98... Careless
You can amend the commit now, with
git commit --amend
Once you are satisfied with your changes, run
git rebase --continue
Mesajın söylediği gibi, düzenlemek istediğimiz “Dikkatsiz” taahhüt üzerindeyiz, bu yüzden iki komut çalıştırıyoruz.
$ git rm --cached oops.iso
$ git commit --amend -C HEAD
$ git rebase --continue
Birincisi, rahatsız edici dosyayı dizinden kaldırır. İkincisi “Dikkatsiz” i güncellenmiş endeks olarak değiştirir veya değiştirir ve git'e -C HEAD
eski işlem mesajını yeniden kullanma talimatı verir. Son olarak, git rebase --continue
geri kalan operasyonun geri kalanıyla devam ediyor.
Bu şu tarihçeyi verir:
$ git lola --name-status
* 93174be (HEAD, master) Login page
| A login.html
* a570198 Careless
| A other.html
* 5af4522 Admin page
| A admin.html
* e738b63 Index
A index.html
istediğin şey bu.