Bagaimana saya bisa mendorong komit tertentu ke remote, dan bukan komit sebelumnya?

Jawaban:

1087

Untuk mendorong melalui komit yang diberikan, Anda dapat menulis:

git push <remotename> <commit SHA>:<remotebranchname>

asalkan <remotebranchname>sudah ada di remote. (Jika tidak, Anda dapat menggunakannya git push <remotename> <commit SHA>:refs/heads/<remotebranchname>untuk membuat otomatis.)

Jika Anda ingin mendorong komit tanpa mendorong komit sebelumnya, Anda harus terlebih dahulu menggunakan git rebase -iuntuk memesan ulang komit.

Geoff Reedy
sumber
66
git push <remotename> <commit SHA>:<remotebranchname>bekerja. triknya adalah menggabungkannya dengan git rebase -imemindahkan komit yang Anda inginkan sebagai komit pertama, dan tentukan komit itu
shmin
29
Tip lain yang bagus adalah memastikan Anda menyalin SHA dari commit yang ingin Anda dorong setelah melakukan rebase -i, dan tidak sebelumnya, seperti yang baru saja saya lakukan :)
estan
33
Ingatlah bahwa ini gagal jika cabang jarak jauh belum ada. Membuat cabang dapat dilakukan dengan git push <remotename> <commit SHA>:refs/heads/<new remote branch name>. Setelah ini, tekan seperti dijelaskan di jawaban.
Wes Oldenbeuving
32
Misalnya, untuk mendorong semuanya kecuali komit terakhir dengan beberapa nama standar git push origin HEAD~1:master.
kebisingan tanpa suara
3
Juga perhatikan, bahwa jika Anda telah mendorong SHA yang lebih baru ke cabang jarak jauh itu, maka Anda harus memaksa mendorong yang ini. Gunakan -fbendera.
Ian Vaughan
79

Jawaban lainnya kurang pada uraian pemesanan ulang.

git push <remotename> <commit SHA>:<remotebranchname>

akan mendorong satu komit, tetapi komit tersebut harus menjadi TERTUA dari komit lokal Anda, tanpa dorongan, tidak boleh dikacaukan dengan komit teratas, pertama, atau tip, yang semuanya merupakan deskripsi yang ambigu menurut pendapat saya. Komit perlu untuk komitmen tertua Anda, yaitu komitmen terjauh dari komit terbaru Anda. Jika itu bukan komitmen terlama maka semua komit dari SHA Anda yang tertua, lokal, tanpa dorongan ke SHA yang ditentukan akan didorong. Untuk menyusun ulang komit, gunakan:

git rebase -i HEAD~xxx

Setelah memesan ulang komit, Anda dapat dengan aman mendorongnya ke repositori jarak jauh.

Untuk meringkas, saya menggunakan

git rebase -i HEAD~<number of commits to SHA>
git push origin <post-rebase SHA>:master

untuk mendorong satu komit ke cabang master jarak jauh saya.

Referensi:

  1. http://blog.dennisrobinson.name/push-only-one-commit-with-git/
  2. http://blog.dennisrobinson.name/reorder-commits-with-git/

Lihat juga:

  1. git: Duplikat Melakukan Setelah Rebase Lokal Diikuti oleh Tarik
  2. git: Mendorong Komit Tunggal, Menyusun-ulang dengan rebase, Komitmen Gandakan
Samuel
sumber
3
Beberapa asal mungkin tidak mengizinkan ini, tampaknya. Misalnya dengan GitLab, saya melihat 'Anda tidak diperbolehkan memaksakan kode push ke cabang yang dilindungi pada proyek ini.'. Yang agak aneh karena saya tidak berpikir saya memaksa apa pun, hanya melakukan dorongan normal. Adakah yang tahu bagaimana melakukannya tanpa 'memaksa'?
Ed Avis
1
@ Id Tidak Perlu memaksa paksa. Sepertinya Anda memiliki masalah dengan pengaturan git spesifik Anda. Mungkin Anda rebased melewati komit HEAD terpencil? Saya tidak tahu apa itu cabang yang dilindungi, kedengarannya seperti masalah izin.
Samuel
1
Samuel - itu masuk akal, tetapi git rebase -saya hanya menunjukkan Anda komit lokal yang lebih lambat dari HEAD terpencil, jadi saya tidak tahu bagaimana saya bisa melakukan itu.
Ed Avis
1
Samuel - memang saya bisa melakukan push parsial sekarang jadi saya tidak tahu apa yang salah tetapi itu pasti mencoba untuk mendorong commit yang tidak berasal dari HEAD jarak jauh dengan satu atau lain cara.
Ed Avis
1
@ Id Anda berkata "git rebase -saya hanya menunjukkan komit lokal yang lebih lambat dari HEAD remote", saya rasa ini tidak benar. Saya diuji dan mampu rebase melewati HEAD remote.
Samuel
25

Saya sarankan menggunakan git rebase -i; pindahkan komit yang ingin Anda dorong ke atas komit yang telah Anda buat. Kemudian gunakan git loguntuk mendapatkan SHA dari komit rebased, memeriksanya, dan mendorongnya. Rebase akan memastikan bahwa semua komit Anda yang lain sekarang adalah anak-anak dari yang Anda dorong, sehingga dorongan di masa depan akan bekerja dengan baik juga.

Walter Mundt
sumber
3
Bisakah Anda memberikan langkah lengkap contoh esp. kembali git loglangkahnya?
Drux
4
Katakanlah Anda memiliki 3 komit yang relatif independen dengan pesan "A", "B", "C" yang dilakukan dalam urutan itu dan Anda ingin menekan "B". 'git rebase -i' seharusnya membuat Anda dan editor mencantumkan ketiganya; naikkan B dan simpan / keluar. 'git log --pretty = oneline -n3' akan mencantumkan B, A, C dengan hash sebelum setiap pesan, dengan B sekarang terakhir. 'git checkout -b temp $ hash_of_B; git push 'seharusnya mendorong B pada saat itu. Anda mungkin akan ingin 'checkout checkout -b master; git branch -d temp 'untuk kembali ke keadaan sebelumnya, dengan anggapan Anda berada di cabang master lokal Anda; ganti yang berlaku.
Walter Mundt
1
+1 Apakah Anda pernah menemukan "murka para dewa git" setelah rebase-push-rebase? (Bisa dibayangkan juga terjadi secara kebetulan, kan?)
Drux
2
Jika Anda membaca jawaban saya dengan cermat, Anda melihat bahwa push hanya terjadi setelah rebase, dan komit rebased hanya bergerak di atas komit lain yang belum didorong. Setelah komit didorong, umumnya harus dianggap diatur dalam batu; biarkan saja dalam rebasing di masa depan. Teknik ini hanya agar Anda dapat memilah beberapa perubahan lokal menjadi urutan yang baik sebelum mendorongnya. Jika Anda telah mengatur pelacakan dengan benar, 'git rebase -i' tanpa args lain akan default untuk bahkan tidak menunjukkan Anda mendorong komit, jadi lebih aman dari kecelakaan daripada beberapa metode lain.
Walter Mundt
21

Cherry-pick bekerja paling baik dibandingkan dengan semua metode lain sambil mendorong komit tertentu.

Cara untuk melakukannya adalah:

Buat cabang baru -

git branch <new-branch>

Perbarui cabang baru Anda dengan cabang asal Anda -

git fetch

git rebase

Tindakan ini akan memastikan bahwa Anda memiliki barang yang sama persis seperti asal Anda.

Ceri-pilih sha idyang ingin Anda dorong -

git cherry-pick <sha id of the commit>

Anda bisa mendapatkannya sha iddengan menjalankan

git log

Dorong ke tempat asal Anda -

git push

Jalankan gitkuntuk melihat bahwa semuanya tampak seperti yang Anda inginkan.

David
sumber
2
Menggunakan git rebase -iakan menjadi solusi ideal seperti yang disarankan dalam solusi di atas. Cherry pick harus digunakan hanya ketika Anda ingin menduplikasi komit.
Vinay Bhargav
13

Saya percaya Anda harus "git kembali" ke komit itu dan kemudian mendorongnya. Atau Anda bisa cherry-pickmengkomit ke cabang baru, dan mendorongnya ke cabang di repositori jarak jauh. Sesuatu seperti:

git branch onecommit
git checkout onecommit
git cherry-pick 7300a6130d9447e18a931e898b64eefedea19544 # From the other branch
git push origin {branch}
Josh K.
sumber
9
git revert adalah ide yang buruk di sini - itu menciptakan komit baru
hasen
1
@ Hasen: Anda kemudian bisa hanya cherry-pickkomit yang Anda inginkan.
Josh K
4
baik revert dan cherry-pick adalah ide yang buruk. git rebase -i adalah teman Anda di sini, lihat jawaban dari Walter Mundt di bawah ini.
Nicolas C
3
@ Nicolas, mengapa ceri-pilih ide yang buruk?
Antoine
3
@Antoine, biasanya Anda ingin cabang Anda tetap sinkron dengan yang dilacaknya dari tempat asalnya. Jika Anda memilih, Anda melakukan copy / paste, dan Anda harus berurusan dengan salinan yang tidak didorong di beberapa titik. Jika Anda rebase -i, Anda melakukan "cut dan paste", dan menjaga cabang Anda sinkron dengan remote hingga ke tempat yang Anda inginkan.
Nicolas C
0

Anda juga bisa, di direktori lain:

  • git clone [repositori Anda]
  • Timpa direktori .git di repositori asli Anda dengan direktori .git dari repositori yang baru saja Anda kloning.
  • git add dan git melakukan original Anda
NunoSempere
sumber