Jadikan cabang Git saat ini cabang utama

1657

Saya memiliki repositori di Git. Saya membuat cabang, lalu melakukan beberapa perubahan baik untuk master dan ke cabang.

Kemudian, puluhan komitmen kemudian, saya sadari cabang itu dalam keadaan yang jauh lebih baik daripada tuannya, jadi saya ingin cabang itu "menjadi" tuan dan mengabaikan perubahan pada tuan.

Saya tidak dapat menggabungkannya, karena saya tidak ingin menyimpan perubahan pada master. Apa yang harus saya lakukan?

Ekstra : Dalam hal ini, master 'lama' telah push-ed ke repositori lain seperti GitHub. Bagaimana ini mengubah banyak hal?

Karel Bílek
sumber
2
Periksa jawaban untuk pertanyaan yang sangat mirip, stackoverflow.com/q/2862590/151641
mloskot
4
Punya masalah yang sama, namun saya hanya menghapus master dan mengganti nama cabang lain menjadi master: stackoverflow.com/a/14518201/189673
jayarjo
10
@jayarjo Anda harus menghindari ini jika Anda bisa karena itu akan menulis ulang sejarah dan menyebabkan masalah bagi orang lain ketika mereka selanjutnya mencoba menarik master.
joelittlejohn
3
Inilah mengapa saya menyukai jawaban @Jefromi. Tidak ada dekonstruksi sejarah arsip yang terjadi.
froggythefrog

Jawaban:

2134

Masalah dengan dua jawaban lainnya adalah bahwa master baru tidak memiliki master lama sebagai leluhur, jadi ketika Anda mendorongnya, semua orang akan menjadi kacau. Inilah yang ingin Anda lakukan:

git checkout better_branch
git merge --strategy=ours master    # keep the content of this branch, but record a merge
git checkout master
git merge better_branch             # fast-forward master up to the merge

Jika Anda ingin riwayat Anda menjadi sedikit lebih jelas, saya sarankan menambahkan beberapa informasi ke pesan gabungan gabung untuk memperjelas apa yang telah Anda lakukan. Ubah baris kedua menjadi:

git merge --strategy=ours --no-commit master
git commit          # add information to the template merge message
Cascabel
sumber
25
Catatan tentang "strategi" gabungan git: --strategy=oursberbeda dari --strategy=recursive -Xours. Yaitu "milik kita" dapat menjadi strategi itu sendiri (hasilnya akan menjadi cabang saat ini tidak peduli apa), atau disahkan sebagai opsi untuk strategi "rekursif" (membawa perubahan cabang lain, dan secara otomatis lebih suka perubahan cabang saat ini ketika ada konflik ).
Kelvin
5
Saya harus membuat baris kedua git merge --strategy=ours master -m "new master"agar bisa berfungsi.
pijar
5
@ Johsm Itulah tepatnya kalimat pertama dari jawaban saya bicarakan. Jika Anda melakukan itu, master baru tidak akan memiliki sejarah yang sama dengan master lama, yang sangat buruk jika Anda ingin mendorong / menarik. Anda harus memiliki nenek moyang yang sama agar dapat berfungsi dengan benar; jika sebaliknya Anda melakukan apa yang Anda katakan, maka ketika Anda mencoba mendorongnya akan gagal kecuali Anda memaksanya (karena ini buruk dan berusaha menghentikan Anda), dan jika Anda memaksanya, maka siapa pun yang kemudian menariknya akan mencoba untuk menggabungkan master lama dan master baru, yang mungkin akan menjadi kecelakaan kereta api.
Cascabel
4
Jika vi editor selama penggabungan muncul, ketik: w (untuk menyimpan): q (untuk keluar dari vi)
Tomas Kubes
9
Jawaban ini sangat bagus. Saya hanya ingin menambahkan (untuk orang-orang yang mungkin baru atau tidak yakin) bahwa Anda harus melakukan yang git pushbenar setelah ini jika Anda ingin kode Anda didorong ke jarak jauh. Anda mungkin melihat peringatan seperti Your branch is ahead of 'origin/master' by 50 commits.ini diharapkan. Dorong saja! : D
chapeljuice
388

Pastikan semuanya didorong ke repositori jarak jauh Anda (GitHub):

git checkout master

Timpa "master" dengan "better_branch":

git reset --hard better_branch

Paksa dorongan ke repositori jarak jauh Anda:

git push -f origin master
Brandon Howard
sumber
81
Ini mungkin jawaban yang kebanyakan orang cari. Semua jawaban lain dengan penggabungan strategi BS tidak mengganti cabang sepenuhnya. Ini membuat semuanya seperti yang saya inginkan, cukup menimpa cabang dan mendorongnya.
Gubatron
31
walaupun ini memang yang dicari banyak orang, perlu dicatat bahwa salinan lokal lain dari repo akan perlu untuk git reset --hard origin/masterwaktu berikutnya mereka ingin menarik, kalau tidak git akan mencoba untuk menggabungkan perubahan ke lokal mereka (sekarang) yang berbeda. Bahaya dari hal ini dijelaskan lebih lanjut dalam jawaban ini
7yl4r
3
harap perhatikan juga bahwa Anda harus diizinkan untuk memaksa mendorong ke repositori - mis. dalam lingkungan bisnis ini tidak akan berhasil
inetphantom
Sisi positifnya di sini juga bisa menjadi downside tergantung pada apa yang orang inginkan. Jika Anda ingin mengganti sejarah master dengan sejarah cabang lain, ini adalah jawaban Anda.
B15
75

Sunting: Anda tidak mengatakan Anda telah mendorong repo publik! Itu membuat dunia berbeda.

Ada dua cara, cara "kotor" dan cara "bersih". Misalkan cabang Anda bernama new-master. Ini cara bersih:

git checkout new-master
git branch -m master old-master
git branch -m new-master master
# And don't do this part.  Just don't.  But if you want to...
# git branch -d --force old-master

Ini akan membuat file konfigurasi berubah agar cocok dengan cabang yang diganti nama.

Anda juga dapat melakukannya dengan cara yang kotor, yang tidak akan memperbarui file konfigurasi. Ini semacam apa yang terjadi di bawah tenda di atas ...

mv -i .git/refs/new-master .git/refs/master
git checkout master
Dietrich Epp
sumber
2
Terima kasih. Satu pertanyaan lagi. Saya mendorongnya ke github. Apa yang akan terjadi di sana, jika saya melakukan ini?
Karel Bílek
3
@ Karel: Ini akan membuat sedikit kekacauan untuk pengguna lain; mereka harus mengatur ulang masternya ke master github. Jika Anda ingin menghindari masalah, lihat jawaban saya.
Cascabel
6
@Dietrick Epp: Saya tidak yakin apakah itu ide yang baik untuk bahkan menyarankan cara kotor. Ini akan mengacaukan pelacakan jarak jauh, reflog ... tidak bisa memikirkan alasan apa pun Anda pernah melakukannya.
Cascabel
2
Ah, itu poin bagus. Anda dapat mendapatkan keduanya, meskipun: git branch old-master master; git branch -f master new-master. Buat cabang cadangan segar, lalu langsung pindahkan master ke master baru. (Dan maaf karena salah mengeja nama Anda, perhatikan saja)
Cascabel
2
@FakeName Saya tidak menyimpulkan tidak ada alasan untuk melakukannya, hanya saja tidak ada alasan untuk melakukannya dengan cara yang kotor . Anda dapat melakukannya dengan menggunakan perintah normal (seperti dalam komentar saya sebelumnya) dan mendapatkan hasil yang sama, kecuali dengan reflog yang utuh dan tidak ada kemungkinan borking hal. Dan itu dijamin bekerja, karena Anda tidak mucking dengan detail implementasi.
Cascabel
46

Ubah nama cabang menjadi masterdengan:

git branch -M branch_name master
Alan Haggai Alavi
sumber
11
Sayangnya git tidak melacak penggantian cabang, jadi jika Anda sudah mendorong repo Anda ke jarak jauh dan orang lain memiliki perubahan lokal di cabang master lama lokal mereka, mereka akan dalam masalah.
thSoft
apakah ada perbedaan antara ini dan git checkout master&&git reset --hard better_branch?
wotanii
26

Dari apa yang saya mengerti, Anda bisa mem-branch-kan cabang saat ini menjadi cabang yang sudah ada. Intinya, ini akan menimpa masterapa pun yang Anda miliki di cabang saat ini:

git branch -f master HEAD

Setelah Anda selesai melakukannya, Anda biasanya dapat mendorong mastercabang lokal Anda , mungkin memerlukan parameter kekuatan di sini juga:

git push -f origin master

Tidak ada penggabungan, tidak ada perintah yang panjang. Cukup branchdan push- tapi, ya, ini akan menulis ulang sejarah dari mastercabang, jadi jika Anda bekerja dalam tim Anda harus tahu apa yang Anda lakukan.




Atau, saya menemukan bahwa Anda dapat mendorong cabang apa saja ke cabang jarak jauh mana pun, jadi:

# This will force push the current branch to the remote master
git push -f origin HEAD:master

# Switch current branch to master
git checkout master

# Reset the local master branch to what's on the remote
git reset --hard origin/master
fregante
sumber
Sangat sederhana dan bekerja dengan sempurna! Dua perintah git yang sederhana dan mudah dimengerti. Repo git saya disimpan dan sekarang terlihat sangat bersih. Terima kasih!
thehelix
16

Saya menemukan jawaban yang saya inginkan di posting blog. Ganti cabang master dengan cabang lain di git :

git checkout feature_branch
git merge -s ours --no-commit master
git commit      # Add a message regarding the replacement that you just did
git checkout master
git merge feature_branch

Ini pada dasarnya sama dengan jawaban Cascabel . Kecuali bahwa "opsi" tambahnya di bawah solusinya sudah tertanam di blok kode utama saya.

Lebih mudah untuk menemukan cara ini.

Saya menambahkan ini sebagai jawaban baru, karena jika saya memerlukan solusi ini nanti, saya ingin memiliki semua kode I saya akan gunakan dalam satu blok kode.

Kalau tidak, saya boleh salin-tempel, lalu baca detail di bawah untuk melihat baris yang seharusnya saya ubah - setelah saya menjalankannya.

SherylHohman
sumber
14

Solusi yang diberikan di sini (mengganti nama cabang di 'master') tidak menekankan konsekuensi untuk repo jarak jauh (GitHub):

    -f
    --memaksa

Biasanya, perintah tersebut menolak untuk memperbarui referensi jarak jauh yang bukan merupakan nenek moyang dari referensi lokal yang digunakan untuk menimpanya. Bendera ini menonaktifkan centang. Ini dapat menyebabkan repositori jarak jauh kehilangan komit; gunakan dengan hati-hati.

Jika orang lain sudah menarik repo Anda, mereka tidak akan dapat menarik sejarah master baru tanpa mengganti master mereka sendiri dengan cabang master GitHub baru (atau berurusan dengan banyak penggabungan).
Ada alternatif untuk push - force git untuk repo publik .
Jawaban Jefromi (menggabungkan perubahan yang tepat kembali ke master asli) adalah salah satunya.

VONC
sumber
14

Saya menemukan metode sederhana ini bekerja yang terbaik. Itu tidak menulis ulang sejarah dan semua check-in cabang sebelumnya akan ditambahkan ke master. Tidak ada yang hilang, dan Anda dapat dengan jelas melihat apa yang terjadi di log komit.

Tujuan: Membuat status "cabang" "master" saat ini

Bekerja di cabang, komit dan dorong perubahan Anda untuk memastikan repositori lokal dan jauh Anda mutakhir:

git checkout master      # Set local repository to master
git reset --hard branch  # Force working tree and index to branch
git push origin master    # Update remote repository

Setelah ini, master Anda akan menjadi kondisi pasti dari komit cabang terakhir Anda dan log komit master Anda akan menampilkan semua lapor-masuk cabang.

Mark Dietel
sumber
10

Satu juga dapat checkout semua file dari cabang lain ke master:

git checkout master
git checkout better_branch -- .

dan kemudian komit semua perubahan.

pengguna2064284
sumber
5

Untuk menambahkan jawaban Jefromi, jika Anda tidak ingin menempatkan penggabungan yang tidak berarti dalam sejarah sourcecabang, Anda bisa membuat cabang sementara untuk ourspenggabungan, lalu membuangnya:

git checkout <source>
git checkout -b temp            # temporary branch for merge
git merge -s ours <target>      # create merge commit with contents of <source>
git checkout <target>           # fast forward <target> to merge commit
git merge temp                  # ...
git branch -d temp              # throw temporary branch away

Dengan begitu komit gabungan hanya akan ada dalam sejarah targetcabang.

Atau, jika Anda tidak ingin membuat penggabungan sama sekali, Anda bisa mengambil konten sourcedan menggunakannya untuk komit baru di target:

git checkout <source>                          # fill index with contents of <source>
git symbolic-ref HEAD <target>                 # tell git we're committing on <target>
git commit -m "Setting contents to <source>"   # make an ordinary commit with the contents of <source>
staafl
sumber
3

Bagi saya, saya ingin iblis saya kembali ke tuan setelah itu di depan.

Saat berkembang:

git checkout master
git pull

git checkout develop
git pull

git reset --hard origin/master
git push -f
Braden Borman
sumber
2

Cara saya melakukan sesuatu adalah sebagai berikut

#Backup branch
git checkout -b master_backup
git push origin master_backup
git checkout master
#Hard Reset master branch to the last common commit
git reset --hard e8c8597
#Merge
git merge develop
ar-g
sumber
2

Jika Anda menggunakan eGit di Eclipse :

  • Klik kanan pada simpul proyek.
  • Pilih Tim → kemudian Tingkat Lanjut → kemudian Ubah nama cabang
  • Kemudian perluas folder pelacakan jarak jauh .
  • Pilih cabang dengan nama yang salah, lalu klik tombol ganti nama, ubah nama menjadi apa pun nama baru itu.
  • Pilih master baru, lalu ganti namanya menjadi master.
Junchen Liu
sumber
Saya melakukan itu tetapi tidak yakin apakah itu berhasil. Di github, tidak ada yang berubah kecuali pada ekstensi git saya bisa melihat cabang diganti namanya.
Pramod
0

Langkah-langkah berikut dilakukan di browser Git yang didukung oleh Atlassian (server Bitbucket)

Jadikan {current-branch} sebagai master

  1. Buat cabang dari masterdan beri nama "master-duplikat".
  2. Buat cabang dari {current-branch} dan beri nama "{current-branch} -copy".
  3. Dalam pengaturan repositori (Bitbucket) ubah "Cabang Default" untuk menunjuk pada "duplikat master" (tanpa langkah ini, Anda tidak akan dapat menghapus master - "Pada langkah Berikutnya").
  4. Hapus cabang "master" - Saya melakukan langkah ini dari source tree (Anda dapat melakukannya dari browser CLI atau Git)
  5. Ganti nama "{current-branch}" menjadi "master" dan dorong ke repositori (ini akan membuat cabang "master" baru masih "{current-branch}" akan ada).
  6. Dalam pengaturan repositori, ubah "Cabang Default" untuk menunjuk pada "master".
Purushothaman
sumber