Amaç
- Kullanım (ilham Smar , ödünç Exherbo )
git am
- Kopyalanan / taşınan dosyaların işleme geçmişini ekle
- Bir dizinden diğerine
- Ya da bir depodan diğerine
sınırlama
- Etiketler ve şubeler tutulmaz
- Yol dosyasının yeniden adlandırılmasında geçmiş kesiliyor (dizin yeniden adlandırılıyor)
özet
- Kullanarak geçmişi e-posta biçiminde ayıklayın
git log --pretty=email -p --reverse --full-index --binary
- Dosya ağacını yeniden düzenleyin ve dosya adlarını güncelleyin
- Kullanarak yeni geçmiş ekle
cat extracted-history | git am --committer-date-is-author-date
1. Geçmişi e-posta biçiminde ayıklayın
Örnek: hulasası geçmişi file3
, file4
vefile5
my_repo
├── dirA
│ ├── file1
│ └── file2
├── dirB ^
│ ├── subdir | To be moved
│ │ ├── file3 | with history
│ │ └── file4 |
│ └── file5 v
└── dirC
├── file6
└── file7
Hedefi ayarlayın / temizleyin
export historydir=/tmp/mail/dir # Absolute path
rm -rf "$historydir" # Caution when cleaning the folder
Her dosyanın geçmişini e-posta biçiminde ayıklayın
cd my_repo/dirB
find -name .git -prune -o -type d -o -exec bash -c 'mkdir -p "$historydir/${0%/*}" && git log --pretty=email -p --stat --reverse --full-index --binary -- "$0" > "$historydir/$0"' {} ';'
Ne yazık ki seçenek --follow
veya --find-copies-harder
birleştirilemez --reverse
. Dosya yeniden adlandırıldığında (veya bir üst dizin yeniden adlandırıldığında) geçmişin kesilmesinin nedeni budur.
E-posta biçimindeki geçici geçmiş:
/tmp/mail/dir
├── subdir
│ ├── file3
│ └── file4
└── file5
Dan Bonachea , git günlüğü komutunun döngülerini bu ilk adımda tersine çevirmeyi önerir: dosya başına git günlüğünü çalıştırmak yerine, komut satırında bir dosya listesi ile tam olarak bir kez çalıştırın ve tek bir birleştirilmiş günlük oluşturun. Bu şekilde, birden fazla dosyayı değiştirmenin sonuçta tek bir taahhüt olarak kalması ve tüm yeni taahhütlerin orijinal göreceli sıralarının korunması söz konusudur. Bunun ayrıca (şimdi birleştirilmiş) günlüğünde dosya adlarını yeniden yazarken aşağıdaki ikinci adımda değişiklik yapılmasını gerektirir.
2. Dosya ağacını yeniden düzenleyin ve dosya adlarını güncelleyin
Bu üç dosyayı başka bir repoda taşımak istediğinizi varsayalım (aynı repo olabilir).
my_other_repo
├── dirF
│ ├── file55
│ └── file56
├── dirB # New tree
│ ├── dirB1 # from subdir
│ │ ├── file33 # from file3
│ │ └── file44 # from file4
│ └── dirB2 # new dir
│ └── file5 # from file5
└── dirH
└── file77
Bu nedenle dosyalarınızı yeniden düzenleyin:
cd /tmp/mail/dir
mkdir -p dirB/dirB1
mv subdir/file3 dirB/dirB1/file33
mv subdir/file4 dirB/dirB1/file44
mkdir -p dirB/dirB2
mv file5 dirB/dirB2
Geçici geçmişiniz şimdi:
/tmp/mail/dir
└── dirB
├── dirB1
│ ├── file33
│ └── file44
└── dirB2
└── file5
Geçmişteki dosya adlarını da değiştirin:
cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:\1/$0:g" -i "$0"' {} ';'
3. Yeni geçmiş uygulayın
Diğer repo:
my_other_repo
├── dirF
│ ├── file55
│ └── file56
└── dirH
└── file77
Geçici geçmiş dosyalarından taahhütleri uygula:
cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am --committer-date-is-author-date
--committer-date-is-author-date
orijinal taahhüt zaman damgalarını korur ( Dan Bonachea'nın yorumu).
Diğer repo şimdi:
my_other_repo
├── dirF
│ ├── file55
│ └── file56
├── dirB
│ ├── dirB1
│ │ ├── file33
│ │ └── file44
│ └── dirB2
│ └── file5
└── dirH
└── file77
Kullanılmaya git status
hazır taahhüt miktarını görmek için kullanın :-)
Ek numara: Reponuz içindeki yeniden adlandırılmış / taşınmış dosyaları kontrol edin
Yeniden adlandırılan dosyaları listelemek için:
find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'
Daha fazla özelleştirme: veya git log
seçeneklerini kullanarak komutu tamamlayabilirsiniz . İlk iki sütunu, '{. * =>. *}' Deseninin tamamını kullanarak ve selamlayarak da kaldırabilirsiniz .--find-copies-harder
--reverse
cut -f3-
find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'
git mv
: stackoverflow.com/questions/1094269/whats-the-purpose-of-git-mv