Pindahkan komit terakhir ke cabang baru dengan Git

Saya ingin memindahkan beberapa komit terakhir yang saya buat untuk mengambil alih cabang baru dan membawa master kembali sebelum komit ini dibuat. Sayangnya, git -fu saya masih belum cukup kuat, ada bantuan?

yaitu Bagaimana saya bisa pergi dari ini

 master A - B - C - D - E 

untuk ini?

 newbranch C - D - E / master A - B 
3467
27 окт. Ditetapkan oleh Mark A. Nicolosi 27 Okt 2009-10-27 06:07 '09 pada pukul 6:07 pagi 2009-10-27 06:07
@ 8 jawaban

Pergi ke cabang baru

Jika tidak ada keadaan lain, ini dapat dengan mudah dilakukan dengan bercabang dan kembalikan.

 git reset --hard a1b2c3d4 

* 1 hanya akan "kehi>

PERINGATAN: Saat menggunakan Git versi 2.0 dan yang lebih baru, jika nanti git rebase cabang baru ke cabang asli ( master ), Anda mungkin memerlukan opsi --no-fork-point selama rebase untuk menghindari kehi>branch.autosetuprebase always diatur membuatnya lebih mungkin. Untuk detailnya, lihat John Mellor .

Pergi ke cabang yang ada

PERINGATAN: Metode di atas berfungsi karena Anda membuat cabang baru dengan perintah pertama: git branch newbranch . Jika Anda ingin menggunakan cabang yang ada , sebelum melakukan git reset --hard HEAD~3 Anda harus menggabungkan perubahan Anda ke cabang yang ada . Jika Anda tidak terlebih dahulu menggabungkan perubahan Anda, mereka akan hi>

4382
27 окт. balas diberikan sykora 27 oktober. 2009-10-27 06:15 '09 jam 06:15 2009-10-27 06:15

Bagi mereka yang bertanya-tanya mengapa ini bekerja (seperti saya di awal):

Anda ingin kembali ke C dan memindahkan D dan E ke cabang baru. Begini tampilannya pada awalnya:

 ABCDE (HEAD) ↑ master 

Setelah git branch newBranch :

  newBranch ↓ ABCDE (HEAD) ↑ master 

Setelah git reset --hard HEAD~2 :

  newBranch ↓ ABCDE (HEAD) ↑ master 

Karena cabang hanyalah sebuah pointer, master menunjuk ke komit terakhir. Saat Anda membuat newBranch, Anda cukup membuat pointer baru ke komit terakhir. Kemudian, dengan menggunakan git reset , Anda memindahkan pointer utama kembali ke dua commit. Tetapi karena Anda tidak memindahkan newBranch, itu tetap menunjuk ke komit yang awalnya dibuat.

801
23 июля '11 в 1:37 2011-07-23 01:37 jawabannya diberikan oleh Ryan Lundy 23 Juli '11 di 1:37 2011-07-23 01:37

Secara umum ...

Dalam hal ini, opsi terbaik adalah metode sykora terbuka. Tetapi terkadang ini bukan metode yang paling mudah dan paling umum. Untuk metode umum, gunakan git-pick cherry:

Untuk mencapai OP yang diinginkan, ini adalah proses dua >

>newbranch

Lari

 git checkout master git log 

Perhatikan bahwa hash (katakanlah, 3) mengikat Anda ke newbranch . Di sini saya akan menggunakan:
C commit: 9aa1233
D commit: 453ac3d
E commit: 612ecb3

Catatan . Anda dapat menggunakan tujuh karakter pertama atau seluruh hash dari commit.

>newbranch

 git checkout newbranch git cherry-pick 612ecb3 git cherry-pick 453ac3d git cherry-pick 9aa1233 

ATAU (dalam git 1.7.2+, gunakan rentang)

 git checkout newbranch git cherry-pick 612ecb3~1..9aa1233 

git cherry-pick menerapkan ketiga komitmen ini pada cabang baru.

315
07 февр. Balas Ivan 07 Feb. 2012-02-07 19:58 '12 pada 19:58 2012-02-07 19:58

Cara lain untuk melakukan ini adalah hanya menggunakan 2 perintah. Juga menjaga pohon kerja Anda saat ini utuh.

 git checkout -b newbranch # switch to a new branch git push . +HEAD~3:master # make master point to some older commit 

Kemampuan untuk push . - ini trik yang bagus.

Pengeditan nanti: Sekarang saya tahu tentang git branch -f , cara yang benar untuk melakukannya adalah:

 git checkout -b newbranch # switch to a new branch git branch -f master HEAD~3 # make master point to some older commit 

Sama, tetapi kurang "ajaib"

235
26 марта '14 в 11:13 2014-03-26 11:13 jawabannya diberikan aragaer 26 Maret '14 di 11:13 2014-03-26 11:13

Sebagian besar jawaban sebelumnya salah!

JANGAN lakukan ini:

 git reset --keep HEAD~3 git checkout -t -b newbranch git cherry-pick ..HEAD@{2} 
  • Pertama, dia membuang 3 commit terakhir ( --keep mirip dengan --hard , tetapi lebih aman, karena gagal, daripada melemparkan perubahan yang tidak dikomit).
  • Lalu dia menonaktifkan newbranch .
  • Kemudian ia mengambil ceri yang 3 ini bawa kembali ke newbranch . Karena mereka tidak lagi merujuk ke cabang, ia melakukan ini dengan git reflog : HEAD@{2} adalah perbaikan yang digunakan HEAD untuk merujuk hingga 2 operasi kembali, mis. sebelum kita 1. memeriksa newbranch dan 2. menggunakan git reset untuk membuang 3 commit.

Peringatan: reflog diaktifkan secara default, tetapi jika Anda menonaktifkannya secara manual (misalnya, menggunakan repositori bare git), Anda tidak akan bisa mendapatkan 3 git reset --keep HEAD~3 setelah menjalankan git reset --keep HEAD~3 .

Alternatif yang tidak bergantung pada reflog adalah:

adalah bahwa mereka meninggalkan reflog dalam kondisi yang salah. git melihat newbranch sebagai cabang bercabang atas revisi yang mencakup 3 komit, kemudian reset --hard menimpa riwayat upstream untuk menghapus komit, dan saat berikutnya Anda menjalankan git rebase ia menjatuhkan mereka dihapus dari hulu.

Tetapi dalam kasus khusus ini, kami ingin 3 fiksasi ini dipertimbangkan sebagai bagian dari utas topik. Untuk mencapai hal ini, kita perlu membuangnya di revisi sebelumnya yang tidak termasuk 3 komitmen. Inilah yang diusulkan solusi saya lakukan, sehingga mereka berdua meninggalkan reflog dalam keadaan yang benar.

Untuk detailnya, lihat definisi --fork-point di git rebase dan git merge base .

179
07 апр. Balas diberikan oleh John Mellor 07 Apr 2016-04-07 01:38 '16 pada 1:38 pm 2016-04-07 01:38

Ini tidak "memindahkan" mereka dalam arti teknis, tetapi memiliki efek yang sama:

 A--B--C (branch-foo) \ ^-- I wanted them here! \ D--E--F--G (branch-bar) ^--^--^-- Opps wrong branch! While on branch-bar: $ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range) A--B--C (branch-foo) \ \ D-(E--F--G) detached ^-- (branch-bar) Switch to branch-foo $ git cherry-pick E..G A--B--C--E'--F'--G' (branch-foo) \ E--F--G detached (This can be ignored) \ / D--H--I (branch-bar) Now you won't need to worry about the detached branch because it is basically like they are in the trash can waiting for the day it gets garbage collected. Eventually some time in the far future it will look like: A--B--C--E'--F'--G'--L--M--N--... (branch-foo) \ \ D--H--I--J--K--.... (branch-bar) 
26
19 окт. Jawabannya diberikan oleh Sukima pada 19 Oktober. 2013-10-19 17:12 '13 pada 17:12 2013-10-19 17:12

Untuk melakukan ini tanpa menulis u>

 git checkout master git revert <commitID(s)> git checkout -b new-branch git cherry-pick <commitID(s)> 

Kedua cabang dapat ditekan tanpa usaha!

17
21 янв. jawaban diberikan teh_senaus 21 Jan 2016-01-21 19:10 '16 pada 19:10 2016-01-21 19:10

Jika situasi seperti itu:

 Branch one: ABCDEFJLM \ (Merge) Branch two: GIKN 

Saya menyelesaikan:

 git branch newbranch git reset --hard HEAD~8 git checkout newbranch 

Saya berharap perbaikannya menjadi KEPALA, tetapi komit L sekarang ...

Untuk mendarat di tempat yang tepat dalam sejarah, lebih mudah untuk bekerja dengan hash komit.

 git branch newbranch git reset --hard ######### git checkout newbranch 
11
20 сент. Jawabannya diberikan oleh Darkglow 20 Sep. 2013-09-20 13:17 '13 pada 13:17 2013-09-20 13:17

Pertanyaan lain tentang atau Ajukan Pertanyaan