Ubah HEAD jarak jauh Git agar mengarah ke sesuatu selain master


124

Bagaimana cara menyetel referensi HEAD remote Git untuk mengarah ke sesuatu selain "master"?

Proyek saya memiliki kebijakan untuk tidak menggunakan cabang "master" (semua cabang memiliki nama yang bermakna). Selain itu, repositori master kanonik hanya dapat diakses melalui ssh: //, tanpa akses shell (seperti GitHub atau Unfuddle).

Masalah saya adalah bahwa repositori jarak jauh masih memiliki referensi HEAD ke refs / heads / master, tetapi saya membutuhkannya untuk menunjuk ke cabang yang berbeda. Ini menyebabkan dua masalah:

  1. Saat mengkloning repo, ini dia,

    peringatan: HEAD jarak jauh mengacu pada ref yang tidak ada, tidak dapat melakukan pembayaran.

    Itu membingungkan dan tidak nyaman.

  2. Browser kode berbasis web bergantung pada HEAD sebagai dasar untuk menjelajahi pohon. Saya perlu HEAD untuk menunjuk ke cabang yang valid.


Hanya menambahkan satu kemungkinan untuk merekam, tetapi tidak cocok untuk kasus Anda.
VonC

Trik "tidak-sama-leluhur": menarik. Anda dapat mempostingnya sebagai jawaban terperinci dan memilihnya sebagai jawaban resmi jika Anda merasa berhasil.
VonC

12
FWIW, karena Anda menyebutkan GitHub dalam pertanyaan - jika Anda ingin mengubah referensi HEAD di GitHub, cukup buka layar "Admin" repositori, dan ubah menu tarik-turun "Cabang Default" ke cabang mana pun yang Anda inginkan untuk ditunjuk HEAD.
Joe


Jawaban:


63

Ada pertanyaan yang hampir sama di GitHub setahun yang lalu.

Idenya adalah mengganti nama cabang master:

git branch -m master development
git branch -m published master
git push -f origin master 

Membuat master memiliki apa yang Anda ingin orang gunakan, dan melakukan semua pekerjaan lain di cabang.

(a " git-symbolic-ref HEAD refs/head/published" tidak akan disebarkan ke repo jarak jauh)

Ini mirip dengan " Bagaimana cara saya menghapus origin / master di Git ".


Seperti yang dikatakan di utas ini : (penekanan dari saya)

" git clone" hanya membuat satu cabang lokal.
Untuk melakukan itu, ia melihat ke HEAD refrepo jarak jauh, dan membuat cabang lokal dengan nama yang sama dengan cabang jarak jauh yang dirujuk olehnya.

Jadi untuk menyelesaikannya, Anda memiliki repo A dan mengkloningnya:

  • HEADreferensi refs/heads/masterdan itu ada
    -> Anda mendapatkan cabang lokal yang disebut master, mulai dari origin / master

  • Referensi HEAD refs/heads/anotherBranchdan itu ada
    -> Anda mendapatkan cabang lokal yang dipanggil anotherBranch, mulai dariorigin/anotherBranch

  • Referensi HEAD refs/heads/masterdan itu tidak ada
    -> "git clone" mengeluh

Tidak yakin apakah ada cara untuk langsung mengubah HEADref di repo .

(yang merupakan inti dari pertanyaan Anda, saya tahu;))


Mungkin satu-satunya cara adalah dengan "publikasi untuk orang miskin" , di mana Anda:

 $ git-symbolic-ref HEAD refs/head/published
 $ git-update-server-info
 $ rsync -az .git/* server:/local_path_to/git/myRepo.git/

Tapi itu akan melibatkan akses tulis ke server, yang tidak selalu memungkinkan.


Seperti yang saya jelaskan di " Git: Cara yang benar untuk mengubah Cabang Aktif di repositori kosong? ", Tidak git remote set-headakan mengubah apa pun di repo jarak jauh.

Itu hanya akan mengubah cabang pelacakan jarak jauh yang disimpan secara lokal di repo lokal Anda, di remotes/<name>/HEAD.


Terima kasih, VonC. Saya membacanya sebelum memposting di sini. Tetapi seperti yang Anda lihat, cabang yang disebut "master" tidak diinginkan dalam proyek ini karena alasan teknis dan kebijakan.
JasonSmith

Anda kemudian dapat menegakkan kebijakan itu dengan melarang pembaruan apa pun pada cabang master melalui hook pra-komit.
VonC

Ya, jika ternyata tidak ada cara untuk melakukan apa yang saya inginkan maka saya akan melakukan itu dan menerima jawaban Anda. Terima kasih telah menindaklanjuti!
JasonSmith

Terima kasih atas pembaruannya. Untuk saat ini, saya menggunakan trik "tidak sama-sama-leluhur" untuk membuat cabang master dengan hanya satu komit. (Yaitu: git branch -D master; echo ref: refs / heads / master> .git / HEAD; rm *). Kemudian saya hanya menyentuh file bernama GO_AWAY, dan pesan komit menjelaskan situasinya. Itu akan berhasil untuk saat ini. Saya dapat memeriksa melalui sumber dan melacak di mana sisi penerima menetapkan KEPALA untuk jawaban akhir.
JasonSmith

1
@ctn Itu hanya karena saya lupa opsi -f( --force). Saya telah mengedit jawabannya sesuai dengan itu. Maka jawaban yang Anda rujuk memang menggunakan opsi yang sama.
VonC

42

Pembaruan: Ini hanya bekerja untuk salinan lokal dari repositori ("klien"). Silakan lihat komentar orang lain di bawah ini.

Dengan versi terbaru git (Feb 2014), prosedur yang benar adalah:

git remote set-head $REMOTE_NAME $BRANCH

Jadi misalnya, mengalihkan head pada remote originke cabang developadalah:

git remote set-head origin develop


Apakah fitur ini memerlukan versi terbaru git di server atau apakah cukup jika mesin klien menginstal git terbaru?
Mikko Rantalainen

3
@Totor singkat tapi benar; jawaban ini harus direndahkan. Git memiliki konsep "lokal, cabang default untuk remote" yang agak membingungkan. Ini memungkinkan Anda mengetik "origin" alih-alih "origin / defaultbranch" dan merupakan hal sisi klien murni . Cerita panjang di git-scm.com/docs/git-remote # set-head
MarcH

1
untuk mengonfirmasi apa yang dibicarakan @MarchH: lari git checkout -b default; git push origin HEAD; git remote set-head origin default. Anda kemudian dapat memeriksa perubahan lokal dengan cat .git/refs/remotes/origin/HEAD(seharusnya ref: refs/remotes/origin/default), dan kurangnya perubahan jarak jauh dengan git remote show origin(akan tetap apa pun itu sebelum Anda menambahkan cabang default).
De Novo

37

Karena Anda menyebutkan GitHub, untuk melakukannya di situs mereka cukup masuk ke proyek Anda, lalu ...

admin > Default Branch > (choose something)

Selesai.


1
Luar biasa! Itu adalah bagian terakhir yang hilang.
berkus

Asal / HEAD saya sudah menunjuk ke cabang fitur, bukan master. Saya mencoba mengubah "cabang utama" bolak-balik, tetapi tidak mempengaruhi HEAD ... Ada saran?
Daniil Shevelev

3
Pengaturan> Cabang> Cabang Default
Chun Yang

12

Lihat: http://www.kernel.org/pub/software/scm/git/docs/git-symbolic-ref.html

Ini menetapkan cabang default di repositori git. Anda dapat menjalankan ini di repositori telanjang atau cermin.

Pemakaian:

$ git symbolic-ref HEAD refs/heads/<branch name>

6
$ git symbolic-ref HEAD refs / heads / name-of-branch
Lamy

Saya melakukan ini di repo jarak jauh saya dan itu memperbaiki masalah saya kloning di mana karena alasan tertentu kepala itu adalah nama cabang lain dan oleh karena itu mencoba mengkloning master akan menghasilkan kesalahan saat mencoba menutup master di komposer, ini mungkin sangat spesifik untuk skenario ini , tetapi orang lain mungkin berada dalam posisi itu dan bertanya-tanya apa yang harus dilakukan
Christopher Thomas

10

(Pada dasarnya sudah ada pertanyaan yang sama " buat referensi simbolik git di repositori jarak jauh ", yang tidak menerima jawaban universal.)

Tetapi ada jawaban khusus untuk berbagai git "farms" (di mana banyak pengguna dapat mengelola repo git melalui antarmuka terbatas: melalui http dan ssh): http://Github.com , http://Gitorious.org , http: / /repo.or.cz , Girar ( http://git.altlinux.org ).

Jawaban khusus ini mungkin berguna bagi mereka yang membaca halaman ini dan memikirkan tentang layanan khusus ini.


4
Sekarang mereka memiliki menu drop-down untuk memilih cabang HEAD di repo.or.cz (contoh: repo.or.cz/editproj.cgi?name=for-me-and-for-all_imz.git ) dan gitorious.org juga. Bagus!
imz - Ivan Zakharyaschev

7

Jika Anda memiliki akses ke repo jarak jauh dari shell, cukup masuk ke .git (atau dir utama jika itu adalah repo kosong) dan ubah file HEAD agar mengarah ke head yang benar. Misalnya, secara default selalu berisi 'refs: refs / heads / master', tetapi jika Anda membutuhkan foo sebagai HEAD, cukup edit file HEAD dan ubah isinya menjadi 'refs: refs / heads / foo'.


Saya memiliki hak admin di server Git dan saya melakukan hal yang persis sama. Kami menggunakan Gitolite dan saya pergi ke repositori yang saya buat. Nama direktorinya adalah myrepo.git. Isi file HEAD di direktori yang diberikan diubah dari ref: refs/heads/mastermenjadi ref: refs/heads/mainline. Sekarang, ketika saya mencoba untuk mengkloning repositori di kotak lokal saya, itu masih mengarah ke master. Saya menjalankan git clone ssh://gitolite@git.server/myrepoperintah. Ada ide untuk perilaku seperti itu?
Technext

Versi server Git: git version 1.7.1& Versi klien Git:git version 1.9.4.msysgit.2
Technext

5

Anda dapat membuat cabang master yang terpisah hanya dengan menggunakan perintah porcelain Git:

git init
touch GO_AWAY
git add GO_AWAY
git commit -m "GO AWAY - this branch is detached from reality"

Itu memberi kita cabang utama dengan pesan kasar (Anda mungkin ingin lebih sopan). Sekarang kita membuat cabang "asli" kita (sebut saja trunk untuk menghormati SVN) dan memisahkannya dari master :

git checkout -b trunk
git rm GO_AWAY
git commit --amend --allow-empty -m "initial commit on detached trunk"

Hei, presto! gitk --all akan menampilkan master dan trunk tanpa tautan di antara keduanya.

"Ajaib" di sini adalah --amend menyebabkan git commit untuk membuat komit baru dengan induk yang sama dengan HEAD saat ini, lalu buat HEAD mengarah ke sana. Tetapi HEAD saat ini tidak memiliki induk karena itu adalah komit awal dalam repositori, jadi HEAD baru juga tidak mendapatkannya, membuatnya terlepas satu sama lain.

Komitmen HEAD lama tidak dihapus oleh git-gc karena refs / heads / master masih menunjuk ke sana.

The --allow-kosong bendera hanya diperlukan karena kita melakukan sebuah pohon yang kosong. Jika ada beberapa git add setelah git rm maka itu tidak diperlukan.

Sebenarnya, Anda bisa membuat cabang yang terpisah kapan saja dengan membuat percabangan komit awal di repositori, menghapus pohonnya, menambahkan pohon yang terlepas, lalu melakukan git komit --amend .

Saya tahu ini tidak menjawab pertanyaan tentang bagaimana memodifikasi cabang default pada repositori jarak jauh, tetapi ini memberikan jawaban yang jelas tentang cara membuat cabang yang terpisah.


1
Anda dapat membuat cabang yang terlepas lebih mudah dengan mengambil cabang yang tidak terkait dari repo lain dan memberinya nama. Misalnya, git fetch git:user@example.com:foo remote-branch-name && git checkout -b detached-branch FETCH_HEADakan menambahkan cabang baru detached-branchyang cocok dengan cabang remote-branch-namedi remote git:user@example.com:foo. Tentu saja, "remote" bisa menjadi tempat penyimpanan di sistem file lokal yang telah Anda siapkan sebelumnya.
Mikko Rantalainen

2

Pertama, buat cabang baru yang ingin Anda jadikan default, misalnya:

$>git branch main

Selanjutnya, dorong cabang itu ke asal :

$>git push origin main

Sekarang ketika Anda masuk ke akun GitHub Anda, Anda dapat pergi ke repositori Anda dan memilih Pengaturan> Cabang Default dan pilih " utama ."

Kemudian, jika Anda memilih demikian, Anda dapat menghapus cabang master:

$>git push origin :master


Poin utama yang harus dipahami adalah jika penyedia hosting (GitHub dalam contoh ini) tidak menyediakan metode untuk memodifikasi cabang default, Anda kurang beruntung. Protokol Git tidak menyediakan fitur untuk mengubah cabang default jarak jauh; Anda harus dapat menjalankan git symbolic-refpada shell jarak jauh atau sebaliknya dapat mengubah file teks yang dipanggil HEADdalam direktori root repositori jarak jauh.
Mikko Rantalainen

2

Terkait dengan pertanyaan itu, saya berakhir di sini ketika mencari:

Bagaimana cara membuat repo lokal mengetahui cabang default yang diubah di GitHub

Untuk kelengkapan, menambahkan jawaban:

git remote set-head origin -a

0

Untuk orang-orang gitolite, gitolite mendukung perintah yang disebut - tunggu - symbolic-ref. Ini memungkinkan Anda untuk menjalankan perintah itu dari jarak jauh jika Anda memiliki izin W (tulis) ke repo.


-1

Sederhana, cukup masuk ke akun GitHub Anda dan di sisi paling kanan di menu navigasi pilih Pengaturan , di Tab Pengaturan pilih Cabang Default dan kembali ke halaman utama repositori Anda yang melakukan trik untuk saya.


1
Meskipun ini menunjukkan cabang baru sebagai default di antarmuka GitHub, ketika melakukan git clone [repo], saya tidak mendapatkan cabang itu. yaitu .git / HEAD berisi ref yang salah.
Joseph Sheedy
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.