Saya memiliki repositori Git yang berisi sejumlah subdirektori. Sekarang saya telah menemukan bahwa salah satu subdirektori tidak berhubungan dengan yang lain dan harus dilepaskan ke repositori yang terpisah.
Bagaimana saya bisa melakukan ini sambil menjaga sejarah file dalam subdirektori?
Saya kira saya bisa membuat klon dan menghapus bagian yang tidak diinginkan dari masing-masing klon, tetapi saya kira ini akan memberi saya pohon lengkap ketika memeriksa revisi yang lebih tua dll. Ini mungkin dapat diterima, tetapi saya lebih suka untuk dapat berpura-pura bahwa dua repositori tidak memiliki riwayat bersama.
Untuk memperjelasnya, saya memiliki struktur berikut:
XYZ/
.git/
XY1/
ABC/
XY2/
Tapi saya ingin ini sebagai gantinya:
XYZ/
.git/
XY1/
XY2/
ABC/
.git/
ABC/
git filter-branch
melihat jawaban saya di bawah ini.Jawaban:
Pembaruan : Proses ini sangat umum, sehingga tim git membuatnya lebih sederhana dengan alat baru
git subtree
,. Lihat di sini: Lepaskan (pindah) subdirektori ke repositori Git yang terpisahAnda ingin mengkloning repositori Anda dan kemudian gunakan
git filter-branch
untuk menandai semuanya tetapi subdirektori yang Anda inginkan dalam repo baru Anda dikumpulkan dari sampah.Untuk mengkloning repositori lokal Anda:
(Catatan: repositori akan dikloning menggunakan tautan keras, tetapi itu tidak menjadi masalah karena file yang ditautkan tidak akan dimodifikasi sendiri - yang baru akan dibuat.)
Sekarang, mari kita lestarikan cabang-cabang menarik yang ingin kita tulis ulang juga, dan kemudian hapus asal untuk menghindari mendorong di sana dan untuk memastikan bahwa komit lama tidak akan dirujuk oleh asal:
atau untuk semua cabang jarak jauh:
Sekarang Anda mungkin ingin juga menghapus tag yang tidak ada hubungannya dengan proyek; Anda juga dapat melakukannya nanti, tetapi Anda mungkin harus memangkas repo lagi. Saya tidak melakukannya dan mendapat
WARNING: Ref 'refs/tags/v0.1' is unchanged
semua tag (karena semuanya tidak terkait dengan sub proyek); selain itu, setelah menghapus tag semacam itu, lebih banyak ruang akan direklamasi. Tampaknyagit filter-branch
harus dapat menulis ulang tag lain, tetapi saya tidak dapat memverifikasi ini. Jika Anda ingin menghapus semua tag, gunakangit tag -l | xargs git tag -d
.Kemudian gunakan filter-branch dan reset untuk mengecualikan file lain, sehingga mereka dapat dipangkas. Mari kita juga menambahkan
--tag-name-filter cat --prune-empty
untuk menghapus komit kosong dan menulis ulang tag (perhatikan bahwa ini harus menghapus tanda tangan mereka):atau sebagai alternatif, untuk hanya menulis ulang cabang HEAD dan mengabaikan tag dan cabang lainnya:
Kemudian hapus reflog cadangan sehingga ruang dapat benar-benar direklamasi (meskipun sekarang operasinya destruktif)
dan sekarang Anda memiliki repositori git lokal dari sub-direktori ABC dengan semua riwayatnya dipertahankan.
Catatan: Untuk sebagian besar penggunaan,
git filter-branch
memang harus memiliki parameter yang ditambahkan-- --all
. Ya itu benar --space--all
. Ini perlu menjadi parameter terakhir untuk perintah. Seperti Matli ditemukan, ini membuat cabang proyek dan tag termasuk dalam repo baru.Sunting: berbagai saran dari komentar di bawah ini dimasukkan untuk memastikan, misalnya, bahwa repositori benar-benar menyusut (yang tidak selalu terjadi sebelumnya).
sumber
--no-hardlinks
? Menghapus satu hardlink tidak akan memengaruhi file lainnya. Objek Git juga tidak berubah. Hanya jika Anda ingin mengubah izin pemilik / file yang Anda butuhkan--no-hardlinks
.filter-branch
adalah--prune-empty
, untuk menghapus commit yang sekarang kosong.-- --all
. Saya juga berlarigit remote rm origin
, dangit tag -l | xargs git tag -d
sebelumgit filter-branch
komando. Ini menyusutkan.git
direktori saya dari 60M ke ~ 300K. Perhatikan bahwa saya perlu menjalankan kedua perintah ini untuk mendapatkan pengurangan ukuran.The Easy Way ™
Ternyata ini adalah praktik yang umum dan bermanfaat sehingga tuan Git membuatnya sangat mudah, tetapi Anda harus memiliki versi Git yang lebih baru (> = 1.7.11 Mei 2012). Lihat lampiran untuk cara menginstal Git terbaru. Juga, ada contoh dunia nyata dalam penelusuran di bawah ini.
Siapkan repo lama
Catatan:
<name-of-folder>
harus TIDAK mengandung karakter yang memimpin atau mengikuti. Misalnya, folder bernamasubproject
HARUS dilewatkan sebagaisubproject
, BUKAN./subproject/
Catatan untuk pengguna Windows: Ketika kedalaman folder Anda> 1,
<name-of-folder>
harus memiliki pemisah folder gaya * nix (/). Misalnya, folder bernamapath1\path2\subproject
HARUS dilewatkan sebagaipath1/path2/subproject
Buat repo baru
Tautkan repo baru ke GitHub atau di mana pun
Bersihkan di dalam
<big-repo>
, jika diinginkanCatatan : Ini meninggalkan semua referensi historis dalam repositori. Lihat Lampiran di bawah ini jika Anda benar-benar khawatir tentang melakukan kata sandi atau Anda perlu mengurangi ukuran file
.git
folder Anda ....
Panduan
Ini adalah langkah yang sama seperti di atas , tetapi mengikuti langkah-langkah tepat saya untuk repositori saya alih-alih menggunakan
<meta-named-things>
.Ini adalah proyek yang saya miliki untuk mengimplementasikan modul browser JavaScript di node:
Saya ingin membagi satu folder
btoa
,, ke dalam repositori Git yang terpisahSaya sekarang memiliki cabang baru
btoa-only
,, yang hanya memiliki komitbtoa
dan saya ingin membuat repositori baru.Selanjutnya saya membuat repo baru di GitHub atau Bitbucket, atau apa pun dan menambahkannya sebagai
origin
Hari bahagia!
Catatan: Jika Anda membuat repo dengan
README.md
,.gitignore
danLICENSE
, Anda harus menarik lebih dulu:Terakhir, saya ingin menghapus folder dari repo yang lebih besar
...
Lampiran
Git terbaru di macOS
Untuk mendapatkan versi terbaru dari Git menggunakan Homebrew :
Git terbaru di Ubuntu
Jika itu tidak berhasil (Anda memiliki versi Ubuntu yang sangat lama), coba
Jika itu masih tidak berhasil, coba
Terima kasih kepada rui.araujo dari komentarnya.
Menghapus riwayat Anda
Secara default menghapus file dari Git tidak benar-benar menghapusnya, itu hanya menyatakan bahwa mereka tidak ada lagi. Jika Anda ingin benar-benar menghapus referensi historis (yaitu Anda memiliki kata sandi yang dikomit), Anda perlu melakukan ini:
Setelah itu Anda dapat memeriksa apakah file atau folder Anda tidak lagi muncul di riwayat Git sama sekali
Namun, Anda tidak dapat "mendorong" menghapus ke GitHub dan sejenisnya. Jika Anda mencoba, Anda akan mendapatkan kesalahan dan Anda harus melakukannya
git pull
sebelum Anda bisagit push
- dan kemudian Anda kembali memiliki segalanya dalam riwayat Anda.Jadi, jika Anda ingin menghapus riwayat dari "asal" - artinya menghapusnya dari GitHub, Bitbucket, dll - Anda harus menghapus repo dan mendorong kembali salinan repo yang sudah dipangkas. Tapi tunggu - masih ada lagi ! - Jika Anda benar-benar khawatir tentang menghilangkan kata sandi atau sesuatu seperti itu, Anda harus memangkas cadangan (lihat di bawah).
Membuat
.git
lebih kecilPerintah hapus riwayat yang disebutkan di atas masih menyisakan banyak file cadangan - karena Git terlalu baik dalam membantu Anda untuk tidak merusak repo Anda secara tidak sengaja. Pada akhirnya akan menghapus file yatim selama berhari-hari dan berbulan-bulan, tetapi meninggalkannya di sana untuk sementara waktu jika Anda menyadari bahwa Anda secara tidak sengaja menghapus sesuatu yang tidak Anda inginkan.
Jadi jika Anda benar-benar ingin mengosongkan sampah untuk mengurangi ukuran klon repo segera Anda harus melakukan semua hal yang sangat aneh ini:
Yang mengatakan, saya sarankan tidak melakukan langkah-langkah ini kecuali Anda tahu bahwa Anda perlu - kalau-kalau Anda memangkas subdirektori yang salah, Anda tahu? File cadangan tidak boleh dikloning ketika Anda mendorong repo, mereka hanya akan ada di salinan lokal Anda.
Kredit
sumber
git subtree
masih merupakan bagian dari folder 'contrib' dan tidak diinstal secara default di semua distro. github.com/git/git/blob/master/contrib/subtreepopd
danpushd
perintah make ini agak implisit dan lebih sulit untuk grok apa yang hendak melakukan ...Jawaban Paul menciptakan repositori baru yang berisi / ABC, tetapi tidak menghapus / ABC dari dalam / XYZ. Perintah berikut akan menghapus / ABC dari dalam / XYZ:
Tentu saja, uji terlebih dahulu dalam repositori 'clone --no-hardlinks', dan ikuti dengan perintah reset, gc, dan prune yang didaftar Paul.
sumber
git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD
dan itu akan jauh lebih cepat. index-filter bekerja pada indeks sementara tree-filter harus checkout dan mem-stage semua untuk setiap commit .--index-filter
metode ini, Anda mungkin juga ingin membuatnyagit rm -q -r -f
, sehingga setiap doa tidak akan mencetak baris untuk setiap file yang dihapus.Saya telah menemukan bahwa untuk menghapus dengan benar riwayat lama dari repositori baru, Anda harus melakukan lebih banyak pekerjaan setelah
filter-branch
langkah.Lakukan klon dan filter:
Hapus setiap referensi ke riwayat lama. "Asal" melacak klon Anda, dan "asli" adalah tempat cabang-filter menyimpan hal-hal lama:
Bahkan sekarang, riwayat Anda mungkin terjebak dalam paket yang fsck tidak akan menyentuh. Sobek-sobek, buat file pack baru dan hapus objek yang tidak terpakai:
Ada penjelasan tentang ini dalam manual untuk cabang-filter .
sumber
git gc --aggressive --prune=now
masih hilang, bukan?git gc --aggressive --prune=now
mengurangi banyak repo baruEdit: Skrip Bash ditambahkan.
Jawaban yang diberikan di sini hanya berfungsi sebagian untuk saya; Banyak file besar tetap ada di cache. Apa yang akhirnya berhasil (setelah berjam-jam di #git di freenode):
Dengan solusi sebelumnya, ukuran repositori sekitar 100 MB. Yang ini membawanya ke 1,7 MB. Mungkin itu membantu seseorang :)
Skrip bash berikut mengotomatiskan tugas:
sumber
Ini tidak lagi begitu rumit, Anda hanya dapat menggunakan perintah git filter-branch pada klon repo Anda untuk menyisihkan subdirektori yang tidak Anda inginkan dan kemudian mendorong ke remote baru.
sumber
The result will contain that directory (and only that) as its project root.
dan memang inilah yang akan Anda dapatkan, yaitu struktur proyek asli tidak dipertahankan.Pembaruan : Modul git-subtree sangat berguna sehingga tim git menariknya ke inti dan membuatnya
git subtree
. Lihat di sini: Lepaskan (pindah) subdirektori ke repositori Git yang terpisahgit-subtree mungkin berguna untuk ini
http://github.com/apenwarr/git-subtree/blob/master/git-subtree.txt (usang)
http://psionides.jogger.pl/2010/02/04/sharing-code-between-projects-with-git-subtree/
sumber
Berikut ini adalah modifikasi kecil untuk CoolAJ86 's 'The Easy Way ™' jawaban untuk membagi beberapa sub folder (katakanlah
sub1
dansub2
) ke repositori git baru.The Easy Way ™ (beberapa sub folder)
Siapkan repo lama
Catatan:
<name-of-folder>
harus TIDAK mengandung karakter yang memimpin atau mengikuti. Misalnya, folder bernamasubproject
HARUS dilewatkan sebagaisubproject
, BUKAN./subproject/
Catatan untuk pengguna windows: ketika kedalaman folder Anda> 1,
<name-of-folder>
harus memiliki * nix style folder separator (/). Misalnya, folder bernamapath1\path2\subproject
HARUS dilewatkan sebagaipath1/path2/subproject
. Apalagi tidak menggunakanmv
perintah tetapimove
.Catatan akhir: perbedaan unik dan besar dengan jawaban dasar adalah baris kedua dari skrip "
git filter-branch...
"Buat repo baru
Tautkan repo baru ke Github atau di mana pun
Bersihkan, jika diinginkan
Catatan : Ini meninggalkan semua referensi historis dalam repositori. Lihat Lampiran dalam jawaban asli jika Anda benar-benar khawatir tentang melakukan kata sandi atau Anda perlu mengurangi ukuran file
.git
folder Anda .sumber
sub1
dansub2
folder tidak ada dengan versi awal, saya harus memodifikasi saya--tree-filter
skrip sebagai berikut:"mkdir <name-of-folder>; if [ -d sub1 ]; then mv <sub1> <name-of-folder>/; fi"
. Untukfilter-branch
perintah kedua saya mengganti <sub1> dengan <sub2>, menghapus kreasi dari <name-of-folder>, dan menyertakan-f
setelahfilter-branch
mengganti peringatan cadangan yang ada.Pertanyaan aslinya ingin XYZ / ABC / (* file) menjadi ABC / ABC / (* file). Setelah menerapkan jawaban yang diterima untuk kode saya sendiri, saya perhatikan bahwa itu benar-benar mengubah XYZ / ABC / (* file) menjadi ABC / (* file). Halaman manual filter-branch bahkan mengatakan,
Dengan kata lain, ini mempromosikan folder tingkat atas "naik" satu tingkat. Itu perbedaan penting karena, misalnya, dalam sejarah saya, saya telah mengganti nama folder tingkat atas. Dengan mempromosikan folder "naik" satu tingkat, git kehilangan kontinuitas di komit di mana saya mengganti nama.
Jawaban saya atas pertanyaan kemudian adalah membuat 2 salinan repositori dan secara manual menghapus folder yang ingin Anda simpan di masing-masing. Halaman manual mendukung saya dengan ini:
sumber
targetdir
telah diganti nama pada suatu titik dangit filter-branch
hanya memanggilnya sehari, menghapus semua komitmen yang dilakukan sebelum mengganti nama! Mengejutkan, mengingat betapa mahirnya Git dalam melacak hal-hal seperti itu dan bahkan migrasi potongan konten individual!git rm
dibutuhkan beberapa argumen, jadi tidak ada alasan untuk menjalankannya untuk setiap file / folder:BYEBYE="dir/subdir2 dir2 file1 dir/file2"; git filter-branch -f --index-filter "git rm -q -r -f --cached --ignore-unmatch $BYEBYE" --prune-empty -- --all
Untuk menambah jawaban Paul , saya menemukan bahwa untuk akhirnya memulihkan ruang, saya harus mendorong HEAD ke repositori bersih dan yang memangkas ukuran direktori .git / objek / paket.
yaitu
Setelah pemangkasan gc, lakukan juga:
Maka Anda bisa melakukannya
dan ukuran ABC / .git berkurang
Sebenarnya, beberapa langkah yang memakan waktu (mis. Git gc) tidak diperlukan dengan push to clean repository, yaitu:
sumber
Cara yang tepat sekarang adalah sebagai berikut:
git filter-branch --prune-empty --subdirectory-filter FOLDER_NAME [first_branch] [another_branch]
GitHub sekarang bahkan memiliki artikel kecil tentang kasus-kasus seperti itu.
Tetapi pastikan untuk mengkloning repo asli Anda ke direktori yang terpisah terlebih dahulu (karena itu akan menghapus semua file dan direktori lain dan Anda mungkin perlu bekerja dengannya).
Jadi algoritma Anda harus:
git filter-branch
hanya file yang tersisa di bawah beberapa subdirektori, dorong ke remote barusumber
Tampaknya sebagian besar (semua?) Jawaban di sini bergantung pada beberapa bentuk
git filter-branch --subdirectory-filter
dan sejenisnya. Namun ini dapat berfungsi "paling sering" untuk beberapa kasus, misalnya kasus ketika Anda mengganti nama folder, mis:Jika Anda melakukan gaya git filter normal untuk mengekstrak "move_me_renamed", Anda akan kehilangan riwayat perubahan file yang terjadi dari belakang ketika awalnya move_this_dir ( ref ).
Dengan demikian nampak bahwa satu-satunya cara untuk benar-benar menyimpan semua perubahan sejarah (jika milik Anda adalah kasus seperti ini), adalah, pada dasarnya, untuk menyalin repositori (membuat repo baru, atur yang menjadi asal), lalu nuke semua yang lain dan ganti nama subdirektori ke induk seperti ini:
git branch -a
git checkout --track origin/branchABC
cp -r oldmultimod simple
cd simple
git rm otherModule1 other2 other3
git mv moduleSubdir1/* .
rmdir moduleSubdir1
git status
git remote set-url origin http://mygithost:8080/git/our-splitted-module-repo
git remote -v
git push
git checkout branch2
Ini mengikuti dokumen github "Memisahkan subfolder menjadi repositori baru" langkah 6-11 untuk mendorong modul ke repo baru.
Ini tidak akan menghemat ruang apa pun di folder .git Anda, tetapi itu akan mempertahankan semua riwayat perubahan Anda untuk file-file itu bahkan di seluruh nama. Dan ini mungkin tidak layak jika tidak ada "banyak" sejarah yang hilang, dll. Tapi setidaknya Anda dijamin tidak akan kehilangan komitmen yang lebih tua!
sumber
Saya merekomendasikan panduan GitHub untuk memisahkan subfolder menjadi repositori baru . Langkah-langkahnya mirip dengan jawaban Paul , tetapi saya menemukan instruksi mereka lebih mudah dimengerti.
Saya telah memodifikasi instruksi sehingga mereka menerapkan repositori lokal, bukan satu yang di-host di GitHub.
sumber
If you create a new clone of the repository, you won't lose any of your Git history or changes when you split a folder into a separate repository.
Namun menurut komentar pada semua jawaban di sini baikfilter-branch
dansubtree
script mengakibatkan hilangnya sejarah di mana subdirektori telah diubah namanya. Adakah yang bisa dilakukan untuk mengatasi hal ini?Saat menjalankan
git filter-branch
menggunakan versi yang lebih baru darigit
(2.22+
mungkin?), Dikatakan untuk menggunakan alat baru ini git-filter-repo . Alat ini tentu menyederhanakan hal bagi saya.Penyaringan dengan filter-repo
Perintah untuk membuat
XYZ
repo dari pertanyaan awal:asumsi: * repo XYZ jauh baru dan kosong sebelum push
Memfilter dan bergerak
Dalam kasus saya, saya juga ingin memindahkan beberapa direktori untuk struktur yang lebih konsisten. Awalnya, saya menjalankan
filter-repo
perintah sederhana yang diikutigit mv dir-to-rename
, tetapi saya menemukan saya bisa mendapatkan sedikit sejarah "lebih baik" menggunakan--path-rename
opsi. Alih-alih melihat modifikasi terakhir5 hours ago
pada file yang dipindahkan dalam repo baru sekarang saya melihatlast year
(di GitHub UI), yang cocok dengan waktu yang dimodifikasi dalam repo asli.Dari pada...
Saya akhirnya berlari ...
Catatan:git filter-repo --subdirectory-filter dir-matching-new-repo-name
). Perintah itu dengan benar mengkonversi subdirektori tersebut ke root dari repo lokal yang disalin, tetapi itu juga menghasilkan riwayat hanya tiga komit yang diperlukan untuk membuat subdirektori. (Saya tidak menyadari bahwa--path
dapat ditentukan beberapa kali; dengan demikian, menghilangkan kebutuhan untuk membuat subdirektori dalam repo sumber.) Karena seseorang telah berkomitmen untuk repo sumber pada saat saya perhatikan bahwa saya gagal meneruskan sejarah, saya baru saja menggunakangit reset commit-before-subdir-move --hard
setelahclone
perintah, dan ditambahkan--force
kefilter-repo
perintah untuk membuatnya beroperasi pada klon lokal yang sedikit dimodifikasi.git
, tetapi akhirnya saya kloning git-filter-repo dan menghubungkannya dengan$(git --exec-path)
:sumber
filter-repo
alat baru (yang saya presentasikan bulan lalu di stackoverflow.com/a/58251653/6309 )git-filter-repo
tentunya harus menjadi pendekatan yang disukai pada saat ini. Ini jauh, jauh lebih cepat dan lebih aman daripadagit-filter-branch
, dan perlindungan terhadap banyak kesulitan yang dapat ditemui ketika menulis ulang sejarah git seseorang. Semoga jawaban ini mendapat perhatian lebih, karena itu yang harus diatasigit-filter-repo
.Saya memiliki masalah ini, tetapi semua solusi standar berdasarkan git filter-branch sangat lambat. Jika Anda memiliki repositori kecil maka ini mungkin bukan masalah, itu untuk saya. Saya menulis program penyaringan git lain berdasarkan libgit2 yang sebagai langkah pertama membuat cabang untuk setiap penyaringan repositori primer dan kemudian mendorongnya untuk membersihkan repositori sebagai langkah selanjutnya. Pada repositori saya (500Mb 100000 komit) metode cabang-standar git filter membutuhkan waktu berhari-hari. Program saya membutuhkan beberapa menit untuk melakukan penyaringan yang sama.
Ia memiliki nama luar biasa git_filter dan tinggal di sini:
https://github.com/slobobaby/git_filter
di GitHub.
Semoga bermanfaat bagi seseorang.
sumber
Gunakan perintah filter ini untuk menghapus subdirektori, sambil mempertahankan tag dan cabang Anda:
sumber
Untuk apa nilainya, inilah cara menggunakan GitHub pada mesin Windows. Katakanlah Anda memiliki repo kloning yang berada di
C:\dir1
. Struktur direktori terlihat seperti ini:C:\dir1\dir2\dir3
. Thedir3
direktori adalah yang saya ingin menjadi repo terpisah baru.Github:
MyTeam/mynewrepo
Bash Prompt:
$ cd c:/Dir1
$ git filter-branch --prune-empty --subdirectory-filter dir2/dir3 HEAD
Dikembalikan:
Ref 'refs/heads/master' was rewritten
(fyi: dir2 / dir3 peka huruf besar-kecil.)$ git remote add some_name [email protected]:MyTeam/mynewrepo.git
git remote add origin etc
. tidak bekerja, dikembalikan "remote origin already exists
"$ git push --progress some_name master
sumber
Seperti yang saya sebutkan di atas , saya harus menggunakan solusi terbalik (menghapus semua komit yang tidak menyentuh saya
dir/subdir/targetdir
) yang tampaknya bekerja dengan sangat baik menghilangkan sekitar 95% dari komit (seperti yang diinginkan). Namun, ada dua masalah kecil yang tersisa.PERTAMA ,
filter-branch
melakukan pekerjaan mematikan menghapus komit yang memperkenalkan atau memodifikasi kode tetapi tampaknya, menggabungkan komit berada di bawah stasiunnya di Gitiverse.Ini adalah masalah kosmetik yang mungkin bisa saya jalani (katanya ... mundur perlahan dengan mata dihindari) .
KEDUA , beberapa komit yang tersisa hampir SEMUA diduplikasi! Saya sepertinya telah memperoleh timeline kedua yang mubazir yang mencakup hampir seluruh sejarah proyek. Hal yang menarik (yang dapat Anda lihat dari gambar di bawah), adalah bahwa tiga cabang lokal saya tidak semuanya berada di timeline yang sama (yang tentu saja mengapa ada dan bukan hanya sampah yang dikumpulkan).
Satu-satunya hal yang dapat saya bayangkan adalah bahwa salah satu dari komit yang dihapus adalah, mungkin, komit gabungan tunggal yang
filter-branch
benar-benar menghapus , dan yang menciptakan garis waktu paralel ketika setiap untai yang sekarang tidak tergabung mengambil salinan komitnya sendiri. ( mengangkat bahu Di mana TARDi saya?) Saya cukup yakin saya dapat memperbaiki masalah ini, meskipun saya benar - benar ingin memahami bagaimana hal itu terjadi.Dalam kasus gila mergefest-O-RAMA, saya mungkin akan meninggalkan yang itu sendirian karena sudah begitu melekat dalam sejarah komit saya — mengancam saya setiap kali saya mendekat—, sepertinya itu tidak benar-benar menyebabkan masalah non-kosmetik dan karena itu cukup cantik di Tower.app.
sumber
Cara Lebih Mudah
git splits
. Saya membuatnya sebagai ekstensi git, berdasarkan solusi jkeating .Membagi direktori menjadi cabang lokal
#change into your repo's directory cd /path/to/repo #checkout the branch git checkout XYZ
#split multiple directories into new branch XYZ git splits -b XYZ XY1 XY2
Buat repo kosong di suatu tempat. Kami akan menganggap kami telah membuat repo kosong bernama
xyz
GitHub yang memiliki path:[email protected]:simpliwp/xyz.git
Dorong ke repo baru.
#add a new remote origin for the empty repo so we can push to the empty repo on GitHub git remote add origin_xyz [email protected]:simpliwp/xyz.git #push the branch to the empty repo's master branch git push origin_xyz XYZ:master
Klon repo jarak jauh yang baru dibuat ke direktori lokal baru
#change current directory out of the old repo cd /path/to/where/you/want/the/new/local/repo #clone the remote repo you just pushed to git clone [email protected]:simpliwp/xyz.git
sumber
git splits
)Anda mungkin memerlukan sesuatu seperti "git reflog kedaluwarsa - expire = now --all" sebelum pengumpulan sampah untuk benar-benar membersihkan file. git filter-branch hanya menghilangkan referensi dalam sejarah, tetapi tidak menghapus entri reflog yang menyimpan data. Tentu saja, ujilah ini dulu.
Penggunaan disk saya turun drastis dalam melakukan ini, meskipun kondisi awal saya agak berbeda. Mungkin --subdirectory-filter meniadakan kebutuhan ini, tapi saya ragu.
sumber
Lihat proyek git_split di https://github.com/vangorra/git_split
Ubah direktori git menjadi repositori mereka sendiri di lokasi mereka sendiri. Tidak ada bisnis lucu subtree. Script ini akan mengambil direktori yang ada di repositori git Anda dan mengubah direktori itu menjadi repositori independennya sendiri. Sepanjang jalan, itu akan menyalin seluruh perubahan sejarah untuk direktori yang Anda berikan.
sumber
Masukkan ini ke gitconfig Anda:
sumber
Saya yakin subtree git baik-baik saja dan luar biasa, tetapi subdirektori dari kode yang dikelola git yang ingin saya pindahkan semuanya dalam gerhana. Jadi jika Anda menggunakan egit, itu sangat mudah. Ambil proyek yang ingin Anda pindahkan dan tim-> putuskan sambungannya, lalu tim-> bagikan ke lokasi baru. Ini akan menjadi standar untuk mencoba menggunakan lokasi repo yang lama, tetapi Anda dapat menghapus centang pada pilihan yang sudah ada yang digunakan dan memilih tempat baru untuk memindahkannya. Semua salam egit.
sumber
Anda dapat dengan mudah mencoba https://help.github.com/enterprise/2.15/user/articles/splitting-a-subfolder-out-into-a-new-repository/
Ini berhasil untuk saya. Masalah yang saya hadapi dalam langkah-langkah yang diberikan di atas adalah
dalam perintah ini
git filter-branch --prune-empty --subdirectory-filter FOLDER-NAME BRANCH-NAME
TheBRANCH-NAME
adalah Masterjika langkah terakhir gagal ketika melakukan karena masalah perlindungan ikuti - https://docs.gitlab.com/ee/user/project/protected_branches.html
sumber
Saya telah menemukan solusi yang cukup mudah, idenya adalah menyalin repositori dan kemudian menghapus bagian yang tidak perlu. Begini Cara kerjanya:
1) Mengkloning repositori yang ingin Anda bagi
2) Pindah ke folder git
2) Hapus folder yang tidak perlu dan komit
3) Hapus riwayat formulir folder yang tidak perlu dengan BFG
4) Periksa apakah riwayat tidak mengandung file / folder yang baru saja Anda hapus
5) Sekarang Anda memiliki repositori bersih tanpa ABC, jadi cukup dorong ke asal baru
Itu dia. Anda dapat mengulangi langkah-langkah untuk mendapatkan repositori lain,
hapus saja XY1, XY2 dan ganti nama XYZ -> ABC pada langkah 3
sumber