Saya memiliki repositori Git dalam folder bernama XXX , dan saya memiliki repositori Git kedua yang disebut YYY .
Saya ingin mengimpor repositori XXX ke dalam repositori YYY sebagai subdirektori bernama ZZZ dan menambahkan semua riwayat perubahan XXX ke YYY .
Struktur folder sebelumnya:
├── XXX
│ ├── .git
│ └── (project files)
└── YYY
├── .git
└── (project files)
Struktur folder setelah:
YYY
├── .git <-- This now contains the change history from XXX
├── ZZZ <-- This was originally XXX
│ └── (project files)
└── (project files)
Apakah ini bisa dilakukan, atau haruskah saya menggunakan sub-modul?
Jawaban:
Mungkin cara paling sederhana adalah dengan menarik barang XXX ke cabang di YYY dan kemudian menggabungkannya menjadi master:
Di YYY :
Saya sebenarnya hanya mencoba ini dengan beberapa repo saya dan itu berhasil. Tidak seperti jawaban Jorg, itu tidak akan membiarkan Anda terus menggunakan repo yang lain, tapi saya rasa Anda tidak menentukannya.
Catatan: Karena ini awalnya ditulis pada tahun 2009, git telah menambahkan gabungan subtree yang disebutkan dalam jawaban di bawah ini. Saya mungkin akan menggunakan metode itu hari ini, walaupun tentu saja metode ini masih berfungsi.
sumber
git mv $(ls|grep -v <your foldername>) <your foldername>/
Ini akan menyalin semua file dan folder ke folder baru AndaJika Anda ingin mempertahankan histori komit yang tepat dari repositori kedua dan karena itu juga mempertahankan kemampuan untuk dengan mudah menggabungkan perubahan hulu di masa depan maka inilah metode yang Anda inginkan. Ini menghasilkan riwayat subtree yang tidak dimodifikasi yang diimpor ke dalam repo Anda ditambah satu komitmen gabungan untuk memindahkan repositori yang digabungkan ke subdirektori.
Anda dapat melacak perubahan hulu seperti:
Git mencari tahu sendiri di mana root sebelum melakukan penggabungan, jadi Anda tidak perlu menentukan awalan pada penggabungan berikutnya.
The downside adalah bahwa dalam sejarah gabungan file tidak diperbaiki (tidak dalam subdirektori). Akibatnya
git log ZZZ/a
akan menampilkan semua perubahan (jika ada) kecuali yang ada dalam riwayat gabungan. Anda dapat melakukan:tapi itu tidak akan menampilkan perubahan selain dari itu di riwayat gabungan.
Dengan kata lain, jika Anda tidak mengubah
ZZZ
file dalam repositoriXXX
, maka Anda perlu menentukan--follow
dan jalur yang tidak diperbaiki. Jika Anda mengubahnya di kedua repositori, maka Anda memiliki 2 perintah, tidak ada yang menunjukkan semua perubahan.Versi Git sebelum 2.9 : Anda tidak perlu meneruskan
--allow-unrelated-histories
opsi kegit merge
.Metode di jawaban lain yang menggunakan
read-tree
dan melewatkanmerge -s ours
langkah secara efektif tidak berbeda dari menyalin file dengan cp dan melakukan hasilnya.Sumber asli berasal dari artikel bantuan "Subtree Merge" github . Dan tautan lain yang bermanfaat .
sumber
git log
salah satu file yang saya tarik, saya hanya melihat satu komit gabungan dan tidak ada dari kehidupan sebelumnya di repo lain? Git 1.8.0git log -- myfile
alih-alihgit log -- rack/myfile
--allow-unrelated-histories
saat melakukan penggabungan.git-subtree
adalah skrip yang dirancang untuk kasus penggunaan yang tepat untuk menggabungkan beberapa repositori ke dalam satu sembari mempertahankan sejarah (dan / atau memisah riwayat subtree, meskipun tampaknya tidak relevan dengan pertanyaan ini). Ini didistribusikan sebagai bagian dari pohon git sejak rilis 1.7.11 .Untuk menggabungkan repositori
<repo>
pada revisi<rev>
sebagai subdirektori<prefix>
, gunakangit subtree add
sebagai berikut:git-subtree mengimplementasikan strategi gabungan subtree dengan cara yang lebih ramah pengguna.
Untuk kasus Anda, di dalam repositori YYY, Anda akan menjalankan:
The downside adalah bahwa dalam sejarah gabungan file tidak diperbaiki (tidak dalam subdirektori). Akibatnya
git log ZZZ/a
akan menampilkan semua perubahan (jika ada) kecuali yang ada dalam riwayat gabungan. Anda dapat melakukan:tapi itu tidak akan menampilkan perubahan selain dari itu di riwayat gabungan.
Dengan kata lain, jika Anda tidak mengubah
ZZZ
file dalam repositoriXXX
, maka Anda perlu menentukan--follow
dan jalur yang tidak diperbaiki. Jika Anda mengubahnya di kedua repositori, maka Anda memiliki 2 perintah, tidak ada yang menunjukkan semua perubahan.Lebih lanjut di sini .
sumber
git subtree add -P name-of-desired-prefix ~/location/of/git/repo-without-.git branch-name
Ada contoh yang terkenal dari hal ini di repositori Git itu sendiri, yang secara kolektif dikenal di komunitas Git sebagai " penggabungan paling keren yang pernah ada " (setelah baris subjek Linus Torvalds digunakan dalam email ke mailinglist Git yang menggambarkan ini menggabungkan). Dalam hal ini,
gitk
GUI GUI yang sekarang merupakan bagian dari Git yang tepat, sebenarnya merupakan proyek yang terpisah. Linus berhasil menggabungkan repositori itu ke dalam repositori Git dengan cara itugit pull
diedit.E-mail berisi langkah-langkah yang diperlukan untuk mereproduksi, tetapi itu bukan untuk orang yang lemah hati: pertama, Linus menulis Git, jadi dia mungkin tahu sedikit lebih banyak tentang hal itu daripada Anda atau saya, dan kedua, ini hampir 5 tahun yang lalu dan Git telah meningkat pesat sejak saat itu, jadi mungkin sekarang jauh lebih mudah.
Secara khusus, saya kira saat ini orang akan menggunakan submodule gitk, dalam kasus tertentu.
sumber
git-subtree
alat pihak ketiga yang dapat membantu Anda dengan ini: github.com/apenwarr/git-subtreesubtree
strategi penggabungan, terutama dalam hubungannya dengangit-subtree
alat adalah bagus, mungkin alternatif bahkan unggul submodul.Cara mudah untuk melakukannya adalah dengan menggunakan git format-patch.
Asumsikan kita memiliki 2 repositori git foo and bar .
foo berisi:
bilah berisi:
dan kami ingin mengakhiri dengan foo yang berisi riwayat bilah dan file-file ini:
Jadi untuk melakukan itu:
Dan jika kita ingin menulis ulang semua komit pesan dari bar dapat kita lakukan, misalnya di Linux:
Ini akan menambahkan "[bilah]" di awal setiap pesan komit.
sumber
git am
kemungkinan akan gagal.[ ]
dari pesan commit. Jadi, Anda harus menggunakan penanda yang berbeda dari[bar]
Fungsi ini akan mengkloning repo jarak jauh ke dir repo lokal, setelah menggabungkan semua komit akan disimpan,
git log
akan ditampilkan komit asli dan jalur yang benar:Cara Penggunaan:
Jika membuat sedikit perubahan, Anda bahkan dapat memindahkan file / dir repo yang digabungkan ke jalur yang berbeda, misalnya:
Jalur Pemberitahuan menggantikan via
sed
, jadi pastikan jalur tersebut dipindahkan di jalur yang benar setelah penggabungan.The
--allow-unrelated-histories
parameter hanya ada sejak git> = 2,9.sumber
gnu-sed
agargit-add-repo
fungsi berfungsi. Terima kasih lagi Andrey!Berdasarkan artikel ini , menggunakan subtree adalah yang berhasil untuk saya dan hanya riwayat yang berlaku yang ditransfer. Posting di sini kalau-kalau ada yang membutuhkan langkah-langkah (pastikan untuk mengganti penampung dengan nilai yang berlaku untuk Anda):
di repositori sumber Anda, pisahkan subfolder ke cabang baru
git subtree split --prefix=<source-path-to-merge> -b subtree-split-result
di repo tujuan Anda bergabung di cabang hasil split
verifikasi perubahan Anda dan komit
Jangan lupa
Bersihkan dengan menghapus
subtree-split-result
cabanggit branch -D subtree-split-result
Hapus remote yang Anda tambahkan untuk mengambil data dari repo sumber
git remote rm merge-source-repo
sumber
Menambahkan jawaban lain karena saya pikir ini sedikit lebih sederhana. Tarik repo_dest dilakukan ke repo_to_import dan kemudian push --set-upstream url: master repo_dest dilakukan.
Metode ini berhasil bagi saya mengimpor beberapa repo yang lebih kecil ke yang lebih besar.
Cara mengimpor: repo1_to_import ke repo_dest
Ganti nama atau pindahkan file dan dir ke posisi yang diinginkan dalam repo asli sebelum Anda melakukan impor. misalnya
Metode yang dijelaskan pada tautan berikut menginspirasi jawaban ini. Saya menyukainya karena sepertinya lebih sederhana. TAPI Waspadalah! Ada naga! https://help.github.com/articles/importing-an-external-git-repository
git push --mirror url:repo_dest
mendorong riwayat repo lokal Anda dan menyatakan ke remote (url: repo_dest). TAPI menghapus sejarah lama dan keadaan remote. Menyenangkan kemudian terjadi! : -Esumber
Saya ingin mengimpor hanya beberapa file dari repositori lain (XXX) dalam kasus saya. Subtree terlalu rumit untuk saya dan solusi lainnya tidak berhasil. Inilah yang saya lakukan:
Ini memberi Anda daftar yang dipisahkan oleh ruang dari semua komit yang memengaruhi file yang ingin saya impor (ZZZ) dalam urutan terbalik (Anda mungkin harus menambahkan - ikuti untuk mengambil nama juga). Saya kemudian pergi ke repositori target (YYY), menambahkan repositori lain (XXX) sebagai remote, melakukan pengambilan dari itu dan akhirnya:
yang menambahkan semua komit ke cabang Anda, dengan demikian Anda akan memiliki semua file dengan sejarahnya dan dapat melakukan apa pun yang Anda inginkan dengannya seolah-olah mereka selalu berada di repositori ini.
sumber
Lihat contoh dasar dalam artikel ini dan pertimbangkan pemetaan seperti pada repositori:
A
<->YYY
,B
<->XXX
Setelah semua aktivitas yang dijelaskan dalam bab ini (setelah penggabungan), hapus cabang
B-master
:Lalu, dorong perubahan.
Ini bekerja untuk saya.
sumber
Saya berada dalam situasi di mana saya mencari
-s theirs
tetapi tentu saja, strategi ini tidak ada. Sejarah saya adalah bahwa saya telah melakukan proyek pada GitHub, dan sekarang karena alasan tertentu, lokal sayamaster
tidak dapat digabung denganupstream/master
walaupun saya tidak membuat perubahan lokal pada cabang ini. (Benar-benar tidak tahu apa yang terjadi di sana - saya kira hulu telah melakukan beberapa dorongan kotor di belakang layar, mungkin?)Apa yang akhirnya saya lakukan adalah
Jadi sekarang saya
master
lagi sinkron denganupstream/master
(dan Anda bisa mengulangi di atas untuk cabang lain yang juga ingin Anda sinkronkan).sumber
git reset --hard upstream/master
dimaster
cabang lokal Anda akan melakukan pekerjaan itu. Dengan cara ini Anda tidak kehilangan conflg cabang lokal - hal-hal seperti hulu default.Saya dapat menyarankan solusi lain (alternatif untuk git-submodules ) untuk masalah Anda - gil (git links) alat
Hal ini memungkinkan untuk menggambarkan dan mengelola dependensi repositori git yang kompleks.
Juga memberikan solusi untuk masalah ketergantungan submodules git rekursif .
Pertimbangkan Anda memiliki dependensi proyek berikut: grafik dependensi repositori sampel git
Kemudian Anda dapat mendefinisikan
.gitlinks
file dengan deskripsi relasi repositori:Setiap baris menggambarkan tautan git dalam format berikut:
Akhirnya Anda harus memperbarui repositori sampel root Anda:
Sebagai hasilnya, Anda akan mengkloning semua proyek yang diperlukan dan menghubungkannya satu sama lain dengan cara yang benar.
Jika Anda ingin mengkomit semua perubahan dalam beberapa repositori dengan semua perubahan dalam repositori terkait anak Anda dapat melakukannya dengan satu perintah:
Perintah tarik, tekan bekerja dengan cara yang sama:
Alat Gil (git links) mendukung perintah berikut:
Lebih lanjut tentang masalah ketergantungan submodul git rekursif .
sumber
Biarkan saya menggunakan nama
a
(di tempatXXX
danZZZ
) danb
(di tempatYYY
), karena itu membuat deskripsi sedikit lebih mudah dibaca.Katakanlah Anda ingin menggabungkan repositori
a
keb
(Saya berasumsi mereka berada di satu sama lain):Untuk ini, Anda perlu
git-filter-repo
menginstal (filter-branch
tidak disarankan ).Contoh menggabungkan 2 repositori besar, menempatkan salah satunya ke dalam subdirektori: https://gist.github.com/x-yuri/9890ab1079cf4357d6f269d073fd9731
Lebih lanjut di sini .
sumber
Saya tidak tahu cara mudah untuk melakukan itu. Anda BISA melakukan ini:
Saya dapat mengedit dengan detail jika itu terdengar menarik.
sumber
Saya pikir Anda bisa melakukan ini menggunakan 'git mv' dan 'git pull'.
Saya seorang git noob yang adil - jadi berhati-hatilah dengan repositori utama Anda - tetapi saya baru saja mencoba ini dalam direktori temp dan sepertinya berhasil.
Pertama - ganti nama struktur XXX agar sesuai dengan yang Anda inginkan ketika berada dalam YYY:
Sekarang XXX terlihat seperti ini:
Sekarang gunakan 'git pull' untuk mengambil perubahan:
Sekarang YYY terlihat seperti ini:
sumber