Saya menggunakan Git subtree dengan beberapa proyek yang sedang saya kerjakan, untuk berbagi beberapa kode dasar di antara mereka. Kode dasar sering diperbarui, dan peningkatan dapat terjadi di salah satu proyek, dengan semuanya diperbarui, pada akhirnya.
Saya mengalami masalah saat git melaporkan bahwa subtree saya sudah diperbarui, tetapi mendorong ditolak. Sebagai contoh:
#! git subtree pull --prefix=public/shared project-shared master
From github.com:****
* branch master -> FETCH_HEAD
Already up-to-date.
Jika saya mendorong, saya akan mendapat pesan bahwa tidak ada yang perlu didorong ... Benar? BAIK? :(
#! git subtree push --prefix=public/shared project-shared master
git push using: project-shared master
To [email protected]:***
! [rejected] 72a6157733c4e0bf22f72b443e4ad3be0bc555ce -> master (non-fast-forward)
error: failed to push some refs to '[email protected]:***'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Merge the remote changes (e.g. 'git pull')
hint: before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
Apa alasannya? Mengapa mendorong gagal?
git
git-subtree
mateusz
sumber
sumber
--rejoin
untuk mempercepat dorongan subtree. Ketika saya melangkah melalui dorongan subpohon secara manual, berjalansubtree split --rejoin
, cabang subpohon yang terpisah hanya memiliki riwayat kembali ke penggabungan kembali terakhir, ketika biasanya berisi seluruh riwayat subpohon. Bagi saya, itulah penyebab langsung kesalahan non-fast-forward. Saya masih tidak yakin mengapa pembagian subpohon menghasilkan riwayat yang terpotong.Jawaban:
Saya menemukan jawabannya di komentar blog ini https://coderwall.com/p/ssxp5q
sumber
error: unknown option 'prefix'
heroku
danpythonapp
jawabannya. Menerjemahkan ini dari bahasa khusus Heroku:git push <your subtree's origin> `git subtree split --prefix=Path/to/subtree master`:master --force
Di windows, perintah bersarang tidak berfungsi:
Anda bisa menjalankan bit bersarang terlebih dahulu:
Ini akan (setelah banyak angka) mengembalikan token, mis
Gunakan ini dalam perintah yang memuatnya, misalnya:
sumber
git subtree
perintah sebelumnya. Setelah menggunakan solusi Anda, saya dapat menerapkan folder ke heroku alih-alih semua repo sayaGunakan
--onto
bendera:[EDIT: sayangnya
subtree push
tidak meneruskan--onto
ke yang mendasarinyasplit
, jadi operasi harus dilakukan dalam dua perintah! Setelah itu selesai, saya melihat bahwa perintah saya identik dengan yang ada di salah satu jawaban lain, tetapi penjelasannya berbeda jadi saya akan meninggalkannya di sini.]Atau jika Anda tidak menggunakan bash:
Saya menghabiskan berjam-jam meneliti sumber git-subtree untuk mencari tahu yang satu ini, jadi saya harap Anda menghargainya;)
subtree push
dimulai dengan menjalankansubtree split
, yang menulis ulang riwayat komit Anda ke dalam format yang harus siap untuk diterapkan. Cara melakukannya adalah, inipublic/shared/
menghapus bagian depan jalur mana pun yang memilikinya, dan menghapus informasi apa pun tentang file yang tidak memilikinya. , atau menggabungkan komit yang identik dengan induk, juga diciutkan. [EDIT: Juga, saya telah menemukan beberapa deteksi squash, jadi sekarang saya berpikir itu hanya jika Anda menarik non-squash, dan kemudian komit gabungan sederhana runtuh yang dijelaskan dalam jawaban lain berhasil memilih jalur non-squash dan buang jalur squashed.]) Hasilnya adalah, hal-hal yang coba didorong akhirnya berisi pekerjaan yang dilakukan seseorang pada repositori host saat ini yang Anda dorong,Itu berarti bahkan jika Anda menarik non-squashed, semua komit sub-repositori upstream akan diabaikan karena mereka memberi nama file dengan jalur kosongnya. (Komitmen yang tidak menyentuh file apa pun di bawahpublic/shared/
Namun, jika Anda menggunakan
--onto
, maka semua komit upstream dicatat sebagai OK untuk digunakan secara verbatim, jadi ketika proses penulisan ulang menemukan mereka sebagai salah satu induk gabungan yang ingin ditulis ulang, itu akan membuat mereka tetap bukannya mencoba menulis ulang mereka dengan cara biasa.sumber
git remote -v
.--onto
pilihan membantu git untuk mengidentifikasi komit yang sudah di sub repositori.Untuk aplikasi jenis "GitHub pages", di mana Anda menerapkan subpohon "dist" ke cabang gh-pages, solusinya mungkin terlihat seperti ini
Saya menyebutkan ini karena tampilannya sedikit berbeda dari contoh heroku yang diberikan di atas. Anda dapat melihat bahwa folder "dist" saya ada di cabang master repo saya, dan kemudian saya mendorongnya sebagai subtree ke cabang gh-pages yang juga ada di origin.
sumber
Saya telah mengalami masalah ini sebelumnya juga, dan inilah cara saya menyelesaikannya.
Apa yang saya temukan adalah saya memiliki cabang yang tidak terhubung ke cabang master lokal. Cabang ini ada dan hanya tergantung di kehampaan. Dalam kasus Anda, itu mungkin disebut
project-shared
. Dengan asumsi hal ini terjadi dan ketika Anda melakukannya,git branch
Anda dapat melihatproject-shared
cabang lokal , maka Anda dapat ' menambahkan ' komit baru keproject-shared
cabang yang ada dengan melakukan:git subtree split --prefix=public/shared --onto public-shared --branch public-shared
Cara saya memahaminya adalah
git subtree
akan mulai membuat cabang baru dari--onto
, dalam hal inipublic-shared
cabang lokalnya . Kemudian cabang berarti membuat cabang, yang menggantikanpublic-shared
cabang lama .Ini akan menyimpan semua SHA
public-shared
cabang sebelumnya. Terakhir, Anda dapat melakukangit push project-shared project-shared:master
Dengan asumsi bahwa Anda memiliki
project-shared
remote juga; ini akan mendorong penggantung lokal diproject-shared
cabang kosong kemaster
cabang remoteproject-shared
.sumber
Ini karena keterbatasan algoritma asli. Saat menangani komit gabungan, algoritme asli menggunakan kriteria yang disederhanakan untuk memotong orang tua yang tidak terkait. Secara khusus, ia memeriksa, jika ada induk, yang memiliki pohon yang sama. Jika orang tua seperti itu ditemukan, itu akan menciutkan komit gabungan dan menggunakan komit induk sebagai gantinya, dengan asumsi bahwa orang tua lain memiliki perubahan yang tidak terkait dengan sub-pohon. Dalam beberapa kasus, hal ini akan mengakibatkan hilangnya bagian sejarah, yang memiliki perubahan aktual pada sub-pohon. Secara khusus itu akan menjatuhkan urutan komit, yang akan menyentuh sub-pohon, tetapi menghasilkan nilai sub-pohon yang sama.
Mari kita lihat contoh (yang dapat Anda gandakan dengan mudah) untuk lebih memahami cara kerjanya. Pertimbangkan sejarah berikut (format barisnya adalah: commit [tree] subject):
Dalam contoh ini, kita akan membagi
dir
. KomitD
danE
memiliki pohon yang samaz
, karena kita memiliki komitC
, yang dibatalkan komitB
, jadiB-C
urutan tidak melakukan apadir
pun meskipun ada perubahan padanya.Sekarang mari lakukan pemisahan. Pertama kita berpisah saat komit
C
.Selanjutnya kita berpisah saat komit
E
.Ya, kami kehilangan dua komitmen. Ini menghasilkan kesalahan saat mencoba mendorong pemisahan kedua, karena tidak memiliki dua commit tersebut, yang sudah masuk ke asalnya.
Biasanya Anda dapat mentolerir kesalahan ini dengan menggunakan
push --force
, karena komit yang dihapus umumnya tidak akan memiliki informasi penting di dalamnya. Dalam jangka panjang, bug perlu diperbaiki, sehingga riwayat terpisah benar-benar memiliki semua komitmen, yang menyentuhdir
, seperti yang diharapkan. Saya mengharapkan perbaikan untuk menyertakan analisis yang lebih dalam tentang komitmen orang tua untuk dependensi tersembunyi.Sebagai referensi, berikut adalah bagian dari kode asli, yang bertanggung jawab atas perilaku tersebut.
copy_or_skip() ... for parent in $newparents; do ptree=$(toptree_for_commit $parent) || exit $? [ -z "$ptree" ] && continue if [ "$ptree" = "$tree" ]; then # an identical parent could be used in place of this rev. identical="$parent" else nonidentical="$parent" fi ... if [ -n "$identical" ]; then echo $identical else copy_commit $rev $tree "$p" || exit $? fi
sumber
Jawaban Eric Woodruff tidak membantu saya, tetapi yang berikut berhasil:
Saya biasanya 'git subtree pull' dengan opsi '--squash'. Tampaknya hal ini membuat segalanya lebih sulit untuk didamaikan, jadi saya perlu melakukan tarikan subtree tanpa menekan kali ini, menyelesaikan beberapa konflik dan kemudian mendorong.
Saya harus menambahkan bahwa tarikan yang terjepit tidak mengungkapkan konflik apa pun, memberi tahu saya bahwa semuanya baik-baik saja.
sumber
Solusi [sederhana] lainnya adalah memajukan head dari remote dengan membuat commit lain jika Anda bisa. Setelah Anda menarik kepala lanjutan ini ke subpohon lokal maka Anda akan dapat mendorongnya lagi.
sumber
Anda dapat memaksa mendorong perubahan lokal ke repo subpohon jarak jauh
sumber
PowerShell cepat untuk pengguna windows berdasarkan solusi Chris Jordan
sumber
Jadi ini yang saya tulis berdasarkan apa yang dikatakan @entheh.
sumber
Punya masalah ini juga. Inilah yang saya lakukan, berdasarkan jawaban teratas:
Diberikan:
Masukkan ini:
Perhatikan bahwa token yang dikeluarkan oleh 'git subtree push' digunakan dalam 'git push'.
sumber