Ganti nama cabang master untuk repositori Git lokal dan jarak jauh

821

Saya memiliki cabang masteryang melacak cabang jarak jauh origin/master.

Saya ingin mengubah nama mereka menjadi master-oldlokal dan pada remote. Apakah ini mungkin?

Untuk pengguna lain yang dilacak origin/master(dan yang selalu memperbarui mastercabang lokal mereka melalui git pull), apa yang akan terjadi setelah saya mengganti nama cabang jarak jauh?
Akankah mereka git pullmasih berfungsi atau akankah mereka melakukan kesalahan yang tidak dapat ditemukan origin/masterlagi?

Kemudian, lebih jauh, saya ingin membuat mastercabang baru (baik lokal maupun jarak jauh). Sekali lagi, setelah saya melakukan ini, apa yang akan terjadi sekarang jika pengguna lain melakukannya git pull?

Saya kira semua ini akan menghasilkan banyak masalah. Apakah ada cara bersih untuk mendapatkan yang saya inginkan? Atau haruskah saya pergi masterbegitu saja dan membuat cabang baru master-newdan bekerja lebih lanjut di sana?

Albert
sumber
2
Resep yang diberikan dalam jawaban yang diterima berlaku untuk cabang dengan nama apa pun, tetapi peringatan (seperti yang disebutkan) tidak, karena (secara default) peran khusus dari cabang master di Git.
kynan
3
@ kynan: Saya rasa saya tidak mengerti. Peringatan apa yang berlaku untuk dikuasai dan tidak diterapkan pada cabang lain? Jika itu adalah cabang bernama xy dan orang lain telah melacak cabang itu, bagaimana bedanya?
Albert
4
Peringatan bahwa Anda biasanya tidak dapat menghapus master jarak jauh. Itu tidak berlaku untuk jawaban Aristoteles, jadi Anda mungkin ingin menandainya sebagai jawaban yang diterima. Anda benar, semua git push -fmemengaruhi kemampuan pulldari cabang pelacakan jarak jauh.
kynan
Anda bisa membuat cabang baru master-oldyang menunjuk ke komit yang sama dengan mastercabang sebelumnya . Kemudian Anda bisa menimpa mastercabang dengan perubahan baru Anda dengan melakukan mergedengan oursstrategi. Melakukan penggabungan berfungsi saat jarak jauh tidak memungkinkan perubahan yang tidak cepat. Itu juga berarti pengguna lain tidak akan memaksa pembaruan.
dnozay
1
@kynan masterhanya istimewa selama itu satu-satunya cabang yang ada. Segera setelah Anda memiliki lebih dari satu, semua cabang memiliki posisi yang sama.
jub0bs

Jawaban:

615

Hal yang paling dekat dengan penggantian nama adalah menghapus dan kemudian menciptakan kembali pada remote. Sebagai contoh:

git branch -m master master-old
git push remote :master         # delete master
git push remote master-old      # create master-old on remote

git checkout -b master some-ref # create a new local master
git push remote master          # create master on remote

Namun ini memiliki banyak peringatan. Pertama, tidak ada checkout yang ada yang tahu tentang rename - git tidak mencoba melacak renungan cabang. Jika yang baru masterbelum ada, git pull akan error keluar. Jika yang baru mastertelah dibuat. tarikan akan mencoba untuk menggabungkan masterdan master-old. Jadi itu umumnya ide yang buruk kecuali jika Anda memiliki kerjasama dari semua orang yang telah memeriksa repositori sebelumnya.

Catatan: Versi git yang lebih baru tidak memungkinkan Anda untuk menghapus cabang master dari jarak jauh secara default. Anda dapat menimpanya dengan mengatur nilai receive.denyDeleteCurrentkonfigurasi ke warnatau ignorepada repositori jarak jauh . Jika tidak, jika Anda siap untuk membuat master baru segera, lewati git push remote :masterlangkah, dan lolos --forceke git push remote masterlangkah. Perhatikan bahwa jika Anda tidak dapat mengubah konfigurasi jarak jauh, Anda tidak akan dapat menghapus cabang master sepenuhnya!

Peringatan ini hanya berlaku untuk cabang saat ini (biasanya mastercabang); cabang lain dapat dihapus dan diciptakan kembali seperti di atas.

omong kosong
sumber
2
cabang hanya sepasang (nama, hash) - tidak lebih, tidak kurang. Ada reflog di cabang, tetapi ini tidak pernah terpapar ke klien jarak jauh.
bdonlan
122
Saya akan membuat master-old di remote sebelum menghapus master di remote. Saya hanya paranoid.
Adam Dymitruk
6
Jawaban Aristoteles di bawah ini memungkinkan Anda untuk melakukan ini tanpa menghapus master, jadi saya pikir itu lebih baik.
Clay Bridges
13
itu akan menjadi jelas dan AMAN jika Anda dapat menggunakan new-branch-namedan old-branch-namebukannya master/ master-old, jadi ini adalah masalah umum.
Jaider
2
Jika cabang yang dihapus (di sini: master) tidak direferensikan oleh cabang lain, git mungkin akan mengumpulkan sampah semua komit pada ... yah ... "cabang". - Beberapa perintah porselen git memicu pengumpulan sampah. - Oleh karena itu: buat nama baru terlebih dahulu (menunjuk komit yang sama), lalu hapus nama lama.
Robert Siemer
257

Dengan asumsi Anda sedang aktif master:

git push origin master:master-old        # 1
git branch master-old origin/master-old  # 2
git reset --hard $new_master_commit      # 3
git push -f origin                       # 4
  1. Pertama-tama buat master-oldcabang di originrepositori, berdasarkan dari masterkomit di repositori lokal.
  2. Buat cabang lokal baru untuk cabang baru ini origin/master-old(yang secara otomatis akan diatur dengan benar sebagai cabang pelacakan).
  3. Sekarang arahkan lokal Anda masterke komit mana pun yang Anda inginkan.
  4. Terakhir, paksakan perubahan masterdi originrepositori untuk mencerminkan lokal baru Anda master.

(Jika Anda melakukannya dengan cara lain, Anda memerlukan setidaknya satu langkah lagi untuk memastikan bahwa master-oldsudah diatur dengan benar untuk melacak origin/master-old. Tidak ada solusi lain yang diposting pada saat penulisan ini termasuk itu.)

Aristoteles Pagaltzis
sumber
11
Saya setuju, ini jawaban yang lebih baik daripada "jawabannya", tetapi bagi orang-orang yang datang ke sini hanya untuk mengganti nama cabang (tidak secara eksplisit menguasai), langkah ke-3 tidak masuk akal.
knocte
Tidak ada bedanya dengan jawaban apakah Anda berada di masteratau cabang lain. Pertanyaan itu berjudul buruk, ia menanyakan tentang tugas yang lebih kompleks dari sekadar mengganti nama cabang.
Aristoteles Pagaltzis
3
Ini ternyata menjadi solusi yang berhasil untuk saya. Saya mencoba mengganti tuan dengan cabang lain. Saya melakukan git log -1 origin / what_i_want_as_new_master untuk mendapatkan $ new_master_commit untuk langkah 3. Setelah push (langkah 4), pengembang lain akan menarik dan menerima pesan "cabang Anda unggul dari master dengan 295 komitmen." Untuk memperbaikinya, saya mengirim email yang memberi tahu mereka setiap kali menjalankan: git pull; git checkout some_random_branch; git branch -D master; git pull; git checkout master; Pada dasarnya, mereka perlu menghapus master lokal mereka dan menarik versi baru kalau tidak mereka berada di tempat yang salah secara lokal.
nairbv
Anda bisa melakukannya dengan lebih mudah: dengan asumsi mereka sudah aktif mastermaka mereka bisa saja git fetch && git reset --hard origin/mastermemaksa lokal mereka mastersama dengan yang aktif origin. Saya telah mendokumentasikan ini, serta kasus yang lebih kompleks di mana Anda memiliki komit lokal di atas masteryang ingin Anda pertahankan, di stackoverflow.com/q/4084868
Aristotle Pagaltzis
Pastikan file konfigurasi jarak jauh memiliki "denyNonFastforwards = false" atau Anda akan mendapatkan "remote: error: menolak referensi / kepala / master non-fast-forward (Anda harus menarik dulu)"
gjcamann
160

Dengan Git v1.7, saya pikir ini telah sedikit berubah. Memperbarui referensi pelacakan cabang lokal Anda ke kendali jarak jauh sekarang sangat mudah.

git branch -m old_branch new_branch         # Rename branch locally    
git push origin :old_branch                 # Delete the old branch    
git push --set-upstream origin new_branch   # Push the new branch, set local branch to track the new remote
Excalibur
sumber
10
Alternatif untuk --set-upstreamadalah sebagai berikut: Setelah cabang Anda diganti namanya secara lokal dan dihapus pada asalnya, cukup lakukan: git push -u --all
lucifurious
4
Ini tidak akan berfungsi dengan cabang master, karena git tidak akan memungkinkan Anda untuk menghapus master jarak jauh.
Alexandre Neto
4
@AlexandreNeto Dalam hal ini Anda dapat mengeksekusi baris ke-3 sebelum tanggal 2, atur cabang default ke new_branchdan kemudian akhirnya menghapus remote masterdengan baris ke-2.
Tristan Jahier
3
Langkah luar biasa sederhana. Ini adalah jawaban terbaik dari pertanyaan
siddhusingh
13
Untuk menghapus cabang jarak jauh git push origin --delete old_branchsedikit lebih mudah dibaca.
ThomasW
35
git checkout -b new-branch-name
git push remote-name new-branch-name :old-branch-name

Anda mungkin harus beralih secara manual new-branch-namesebelum menghapusold-branch-name

Treken
sumber
Apakah ada bagian dari solusi ini yang menghapus nama cabang lama setempat, atau apakah itu latihan serparate?
GreenAsJade
4
Saya pikir pada akhirnya harus dijalankan git branch -d old-branch-nameuntuk menghapus cabang lama lokal.
Nabi KAZ
Anda dapat mendorong perubahan dengan hanya satu perintah: git push remote-name new-branch-name :old-branch-name.
sigod
Dengan cara ini, tidakkah Anda akan mempersulit sejarah git? Karena Anda membuka cabang baru alih-alih hanya mengganti nama cabang saat ini.
androidevil
1
@androider No. Cabang di git adalah referensi sederhana .
sigod
29

Ada banyak cara untuk mengubah nama cabang, tetapi saya akan fokus pada masalah yang lebih besar: "bagaimana memungkinkan klien untuk mempercepat dan tidak harus mengacaukan cabang mereka secara lokal" .

Pertama gambar cepat: mengganti nama cabang utama dan memungkinkan klien untuk maju cepat

Ini adalah sesuatu yang sebenarnya mudah dilakukan; tapi jangan menyalahgunakannya. Seluruh ide bergantung pada gabungan melakukan; karena mereka memungkinkan fast-forward, dan menghubungkan sejarah cabang dengan yang lain.

mengganti nama cabang:

# rename the branch "master" to "master-old"
# this works even if you are on branch "master"
git branch -m master master-old

membuat cabang "master" baru:

# create master from new starting point
git branch master <new-master-start-point>

membuat komit gabungan untuk memiliki riwayat orang tua-anak:

# now we've got to fix the new branch...
git checkout master

# ... by doing a merge commit that obsoletes
# "master-old" hence the "ours" strategy.
git merge -s ours master-old

dan voila.

git push origin master

Ini berfungsi karena membuat mergekomit memungkinkan penerusan cabang dengan cepat ke revisi baru.

menggunakan pesan commit gabungan yang masuk akal:

renamed branch "master" to "master-old" and use commit ba2f9cc as new "master"
-- this is done by doing a merge commit with "ours" strategy which obsoletes
   the branch.

these are the steps I did:

git branch -m master master-old
git branch master ba2f9cc
git checkout master
git merge -s ours master-old
tidak tahu
sumber
3
Terima kasih! git merge -s ours master-oldadalah bagian penting yang dilewatkan oleh jawaban lain. Juga, "mudah dilakukan" tidak berarti "mudah dimengerti, atau mencari tahu" yang tampaknya menjadi masalah dengan banyak git, tetapi saya ngelantur.
Martin Vidner
3
Saya suka fakta bahwa tidak ada penghapusan yang disebutkan dan bahwa transisi untuk mereka yang bekerja dengan klon hulu adalah "mulus". Terima kasih!
Piotrek
12

Saya berasumsi Anda masih bertanya tentang situasi yang sama seperti pada pertanyaan Anda sebelumnya . Yaitu, master-new tidak akan berisi master-old dalam sejarahnya. * Jika Anda memanggil master-new "master", Anda akan secara efektif memiliki sejarah yang ditulis ulang. Tidak masalah bagaimana Anda masuk ke kondisi di mana master bukan merupakan keturunan dari posisi master sebelumnya, hanya saja itu berada dalam kondisi itu.

Pengguna lain yang mencoba menarik sementara master tidak ada hanya akan memiliki tarikan gagal (tidak ada referensi pada jarak jauh), dan begitu ada lagi di tempat baru, tarikan mereka harus mencoba untuk menggabungkan master mereka dengan master jarak jauh baru, sama seperti jika Anda menggabungkan master-lama dan master-baru di repositori Anda. Mengingat apa yang Anda coba lakukan di sini, penggabungan tersebut akan memiliki konflik. (Jika mereka diselesaikan, dan hasilnya didorong kembali ke repositori, Anda akan berada dalam keadaan yang lebih buruk - kedua versi sejarah ada di sana.)

Untuk menjawab pertanyaan Anda secara sederhana: Anda harus menerima bahwa kadang-kadang akan ada kesalahan dalam sejarah Anda. Ini tidak apa-apa Itu terjadi pada semua orang. Ada komit yang dikembalikan dalam repositori git.git. Yang penting adalah bahwa begitu kita menerbitkan sejarah, itu adalah sesuatu yang dapat dipercaya semua orang.

* Jika ya, ini akan sama dengan mendorong beberapa perubahan ke master, dan kemudian membuat cabang baru di tempat sebelumnya. Tidak masalah.

Cascabel
sumber
Ya, itu masalah yang sama, hanya satu ide bagaimana menyelesaikannya. Tetapi bahkan jika saya tidak akan melakukan penggantian nama cabang ini, saya menarik jika memungkinkan. Saya pikir referensi seperti "master" hanyalah referensi untuk melakukan tertentu. Saya benar-benar tidak ingin mengubah riwayat apa pun. Saya pikir saya hanya akan mengarahkan referensi master ke kepala yang lain. Ini juga berarti, saya tidak akan pernah bisa menggunakan nama cabang lagi jika saya pernah menggunakannya sebelumnya?
Albert
Memang, cabang adalah rujukan untuk dilakukan. Masalahnya adalah, kita berharap kepala cabang berkembang dengan cara tertentu (yaitu, selalu maju cepat). Dari sudut pandang orang lain, memindahkan cabang di repo publik Anda sama dengan menulis ulang sejarah cabang. Itu tidak lagi menunjuk ke komit yang berisi semua yang dulu.
Cascabel
8

The jawaban yang dipilih gagal ketika saya mencoba. Ini melempar kesalahan: refusing to delete the current branch: refs/heads/master. Saya kira saya akan memposting apa yang berfungsi untuk saya:

git checkout master             # if not in master already

git branch placeholder          # create placeholder branch
git checkout placeholder        # checkout to placeholder
git push remote placeholder     # push placeholder to remote repository

git branch -d master            # remove master in local repository
git push remote :master         # remove master from remote repository.

Caranya adalah dengan checkout ke placeholder tepat sebelum mendorongnya ke repositori jarak jauh. Sisanya cukup jelas, menghapus cabang master dan mendorongnya ke repositori jarak jauh seharusnya berfungsi sekarang. Dikutip dari sini .

Hendra Uzia
sumber
Ini akan gagal pada git push remote: master jika ini dicentang pada sisi remote - Anda akan melihat "remote: error:" sebagai awalan di baris log kesalahan.
rafalmag
2

Baik. 2 sen saya. Bagaimana dengan masuk di server, pergi ke direktori git dan mengganti nama cabang di repositori kosong. Ini tidak memiliki semua masalah yang terkait dengan mengunggah kembali cabang yang sama. Sebenarnya, 'klien' akan secara otomatis mengenali nama yang dimodifikasi dan mengubah referensi jarak jauh mereka. Setelah itu (atau sebelumnya) Anda juga dapat memodifikasi nama lokal cabang.


sumber
8
Saya lupa kredensial untuk masuk ke server github. Siapa pun yang memiliki kredensial di luar sana :-P
Daniel Fisher lennybacon
1

Bagaimana dengan:

git checkout old-branch-name
git push remote-name new-branch-name
git push remote-name :old-branch-name
git branch -m new-branch-name
Hannes Tydén
sumber
mengacaukan pelacakan cabang - pengguna mungkin harus memperbaiki cabang mereka secara lokal?
dnozay
1

Ini adalah cara paling sederhana dan paling 'mudah dibaca' yang saya tahu:

Cabang lokal 'Pindahkan' menggunakan -m

git branch -m my_old_branch_name my_new_branch_name

Dorong cabang 'pindah' ​​ke jarak jauh, atur 'hulu' menggunakan -u

git push origin -u my_new_branch_name

(pengaturan 'hulu' pada dasarnya 'menghubungkan' cabang lokal Anda ke jarak jauh, sehingga hal-hal seperti mengambil, menarik, dan mendorong akan bekerja)

Hapus cabang lama dari jarak jauh

git push origin -D <old_name>

(cabang lokal Anda sudah tidak ada, karena Anda 'memindahkannya' pada langkah pertama)

Chris Halcrow
sumber
1

OKE , mengganti nama cabang baik secara lokal dan pada remote cukup mudah! ...

Jika Anda berada di cabang, Anda dapat dengan mudah melakukan:

git branch -m <branch>

atau jika tidak, Anda perlu melakukan:

git branch -m <your_old_branch> <your_new_branch>

Kemudian, dorong penghapusan ke kendali jarak jauh seperti ini:

git push origin <your_old_branch>

Sekarang Anda selesai, jika Anda mendapatkan kesalahan hulu saat Anda mencoba mendorong, cukup lakukan:

git push --set-upstream origin <your_new_branch>

Saya juga membuat gambar di bawah ini untuk menunjukkan langkah-langkah di baris perintah nyata, cukup ikuti langkah-langkahnya dan Anda akan menjadi baik:

masukkan deskripsi gambar di sini

Alireza
sumber
0

Anda dapat melakukan hal berikut:

git -m master master-old #rename current master
git checkout -b master   #create a new branch master
git push -f origin master #force push to master

Tapi memaksakan dorongan adalah ide yang buruk jika orang lain berbagi repositori ini. Force push akan menyebabkan riwayat revisi mereka bertentangan dengan yang baru.

Riyafa Abdul Hameed
sumber
0

Berikut ini dapat disimpan ke skrip shell untuk melakukan pekerjaan:

Sebagai contoh:

remote="origin"

if [ "$#" -eq 0 ] # if there are no arguments, just quit
then
    echo "Usage: $0 oldName newName or $0 newName" >&2
    exit 1
elif
    [ "$#" -eq 1 ] # if only one argument is given, rename current branch
then 
    oldBranchName="$(git branch | grep \* | cut -d ' ' -f2)" #save current branch name
    newBranchName=$1
else
    oldBranchName=$1
    newBranchName=$2
fi

git branch -m $oldBranchName $newBranchName

git push $remote :$oldBranchName #delete old branch on remote
git push --set-upstream $remote $newBranchName # add new branch name on remote and track it

Harap dicatat bahwa di sini nama jarak jauh default "asal" adalah kode-keras, Anda dapat memperluas skrip untuk membuatnya jika dapat dikonfigurasi!

Maka skrip ini dapat digunakan dengan alias bash, alias git atau, misalnya, tindakan kustom sumber daya.

Do-do-new
sumber
-1

Saya percaya kuncinya adalah kesadaran bahwa Anda melakukan perubahan nama ganda : mastermenjadi master-olddan juga master-newuntuk master.

Dari semua jawaban lain saya telah mensintesiskan ini:

doublerename master-new master master-old

tempat pertama kita harus mendefinisikan doublerenamefungsi Bash:

# doublerename NEW CURRENT OLD
#   - arguments are branch names
#   - see COMMIT_MESSAGE below
#   - the result is pushed to origin, with upstream tracking info updated
doublerename() {
  local NEW=$1
  local CUR=$2
  local OLD=$3
  local COMMIT_MESSAGE="Double rename: $NEW -> $CUR -> $OLD.

This commit replaces the contents of '$CUR' with the contents of '$NEW'.
The old contents of '$CUR' now lives in '$OLD'.
The name '$NEW' will be deleted.

This way the public history of '$CUR' is not rewritten and clients do not have
to perform a Rebase Recovery.
"

  git branch --move $CUR $OLD
  git branch --move $NEW $CUR

  git checkout $CUR
  git merge -s ours $OLD -m $COMMIT_MESSAGE

  git push --set-upstream --atomic origin $OLD $CUR :$NEW
}

Ini mirip dengan perubahan-sejarah git rebasedi mana konten cabang sangat berbeda, tetapi berbeda bahwa klien masih dapat maju dengan aman dengan aman git pull master.

Martin Vidner
sumber
-5
git update-ref newref oldref
git update-ref -d oldref newref
dlamotte
sumber
2
Ini sepertinya tidak berfungsi untuk saya, saya dapatkan: git update-ref trunk2 fatal: trunk2: bukan SHA1 yang valid
Gregg Lind