2010-06-29 5 views
53

ı bu dizin yapısını içeren bir repo var diyelim: Ben repo en üst düzeyine _posts taşımak istediğinizTüm öğeler için bir dizini Git yanıtında nasıl taşıyabilirim?

repo/ 
    blog/ 
    _posts/ 
     some-post.html 
    another-file.txt 

, bu nedenle yapı aşağıdaki gibi görünecektir:

repo/ 
    _posts/ 
    some-post.html 
    another-file.txt 

Bu git mv ile yeteri kadar basit, ama tarihinrepo'nun kökeninde her zaman varmış gibi görünmesini istiyorum ve git log -- _posts/some-post.html aracılığıyla some-post.html'un tüm geçmişini alabilmek istiyorum. Bunu gerçekleştirmek için git filter-branch ile biraz sihir kullanabileceğimi hayal ediyorum, ama tam olarak bunu nasıl yapacağımı anlayamadım. Herhangi bir fikir?

cevap

68

Sen ulaşmak için alt dizin filtre kullanabilirsiniz bu

$ git filter-branch --subdirectory-filter blog/ -- --all 

DÜZENLEME 1:

$ git filter-branch --tree-filter 'mv blog/_posts .' HEAD 
: etkili _posts kökünü yapmak istemiyorum
bunun yerine bir ağaç filtre kullanın

DÜZEN 2: Bazı işlemlerde blog/_posts yoksa, yukarıdakiler başarısız olur. Bunu kullanın:

$ git filter-branch --tree-filter 'test -d blog/_posts && mv blog/_posts . || echo "Nothing to do"' HEAD 
+3

Ayrıca" - index-filter "kullanmak için * çok * daha hızlıdır, çünkü bu ağacın çıkış yapmasına gerek yoktur. – Cascabel

+6

Evet index -filtre daha hızlıdır, ancak işe yaramaz çünkü komutlar _not_ dizinini etkiler. İndeks filtrelerini kullanmak istediğinizde indeks manipülasyonları yapmanız gerekir (örn. 'rm' yerine rm --cached' – sehe

+0

Etiketleri de saklayabilir miyim? Benim durumumda kaybolmuş gibi görünüyor. – Michael

31

Ramkumar'ın yanıtı çok yararlı ve değerli bir yanıt olsa da, pek çok durumda çalışmayacaktır. Örneğin, bir dizini diğer alt dizinlerle yeni bir konuma taşımak istediğinizde.

git filter-branch --index-filter \ 
    'git ls-files -s | sed "s-\t\"*-&NEWSUBDIR/-" | 
    GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ 
    git update-index --index-info && 
    mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD 

Sadece istediğiniz yeni dizine ile NEWSUBDIR değiştirin: Bunun için

, adam sayfası mükemmel bir komut içerir. Ayrıca iç içe dirs kullanabilirsiniz dir1/dir2/dir3/- "

+9

Bu komut veya ortaya çıkan hatalar, \ t os x'in sed'deki versiyonu. Bunun etrafında birçok yol var, ama belki de en hızlı olan \ t silmek ve ctrl-v, yazarak bir literal sekmesi ile değiştirmektir. –

+2

Orijinal klasörü nasıl belirlersiniz, yoksa bu yalnızca tüm şubeyi mi taşır? Bunu bir klasörden çalıştırmayı denediğimde, Taşımayı isterim “Bu ağacın üst düzeyinden bu komutu çalıştırmanız gerekiyor” – joshcomley

+1

“Sed” komutu ne yapar? Bunu Windows üzerinde deniyorum ve bir alternatife ihtiyacım var. – Lucius