Percabangan Git: master vs origin / master vs remote / origin / master

201

Saya pikir saya berada di jalur yang benar untuk memahami konsep dasar git.

Saya sudah menyiapkan dan mengkloning repositori jarak jauh. Saya juga membuat repositori kosong di sisi server, dan menautkan repositori lokal saya dengannya.

Masalah saya adalah saya tidak mengerti perbedaan antara:

  • origin / master vs. remote / origin / master

Sejauh yang saya mengerti, master adalah cabang lokal, dan remote / asal / master adalah yang jauh.

Tapi apa sebenarnya asal / master ?

John Rumpel
sumber
1
@ChristopherWallace: Anda memprovokasi dua pertanyaan tentang meta dengan suntingan Anda: " Apakah kita benar-benar membutuhkan tag [asal]? " Dan " Apa [Master] yang sebenarnya? ".
Deduplicator
@Duplikator Apakah itu masalah?
nbro
@ChristopherWallace: Ya, banyak yang berpikir bahwa kedua tag (yang Anda buat dan yang Anda tambahkan) buruk. Saya kebetulan setuju, tetapi mungkin Anda memiliki sesuatu untuk ditambahkan ke tautan tertaut yang tidak dipertimbangkan. Jika tidak, sepertinya begitu.
Deduplicator
Pertanyaan tindak lanjut: Mengapa .git/refs/origin/mastersaya harus pindah .git/refs/remotes/origin/master? Ini terjadi pada saya sekarang dan saya terlempar.
Paul

Jawaban:

219

Ambil klon repositori jarak jauh dan jalankan git branch -a(untuk menampilkan semua cabang yang diketahui git). Mungkin akan terlihat seperti ini:

* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Di sini, masteradalah cabang di repositori lokal. remotes/origin/masteradalah cabang bernama masterpada remote bernama origin. Anda dapat merujuk ini sebagai origin/master, seperti pada:

git diff origin/master..master

Anda juga dapat menyebutnya sebagai remotes/origin/master:

git diff remotes/origin/master..master

Ini hanya dua cara berbeda untuk merujuk ke hal yang sama (kebetulan, kedua perintah ini berarti "tunjukkan perubahan antara mastercabang jarak jauh dan mastercabang saya ).

remotes/origin/HEADadalah default branchuntuk remote bernama origin. Ini memungkinkan Anda mengatakan originsebaliknya origin/master.

larsks
sumber
5
Jawaban yang bagus. Saya pikir git branch -amenunjukkan cabang jarak jauh remotes/origin/mastersebagian karena ref yang mendasarinya disimpan .git/refs/remotes/origin(jika belum dikemas). Menurut pendapat saya, output dari git branch -abisa jauh lebih jelas, mungkin dengan memisahkan nama remote dari nama cabang dengan sesuatu selain garis miring.
Matt Hurne
14
Perhatikan juga git branch -r, yang hanya menampilkan cabang jarak jauh, akan menampilkan cabang hanya origin/masterkarena remotes/awalan tidak diperlukan.
Matt Hurne
3
@ misterbiscuit: itu benar. Hasilnya lebih membingungkan daripada mengklarifikasi. Terima kasih banyak, jawaban yang bagus untuk pertanyaan saya yang memberi saya petunjuk yang tepat
John Rumpel
Jika saya melihat git logsaya melihat commit fa9sd8jasdf98 (HEAD -> master), apa artinya ini? Apa itu KEPALA dalam hal ini? Saya pikir saya saat ini "master" dan berkomitmen untuk origin/master. Saya pikir saya memiliki sesuatu yang membingungkan, dapatkah seseorang membantu menenangkan? EDIT UPDATE: Saya pikir saya mengerti, apakah benar untuk menganggap bahwa HEAD saat ini menunjuk ke cabang master, artinya saya sedang dalam proses komit untuk menguasai?
Sebastian Nielsen
@SebastianNielsen ya Anda benar, bagian HEAD -> master berarti bahwa Anda saat ini berada di cabang master.
iRestMyCaseYourHonor
108

Jawaban singkat untuk boneka seperti saya (dicuri dari Torek):

  • asal / master adalah "di mana master ada di sana terakhir kali aku memeriksa"
  • master adalah "di mana master ada di sini berdasarkan apa yang telah saya lakukan"
ErichBSchulz
sumber
9
origin / master = cadangan mesin jarak jauh, diperbarui terakhir kali Anda memeriksa master = salinan asal / master Anda
sakurashinken
40

Secara teknis sebenarnya tidak ada hal-hal "jauh" sama sekali 1 di repo Git Anda, hanya ada nama-nama lokal yang harus sesuai dengan nama-nama pada repo lain yang berbeda. Yang bernama origin/whateverawalnya akan cocok dengan yang ada di repo yang Anda kloning-dari:

git clone ssh://some.where.out.there/some/path/to/repo # or git://some.where...

membuat salinan lokal dari repo lainnya. Sepanjang jalan itu mencatat semua cabang yang ada di sana, dan melakukan yang merujuk, dan menempelkan itu ke repo lokal Anda di bawah namarefs/remotes/origin/ .

Bergantung pada berapa lama Anda pergi sebelum Anda git fetchatau yang setara untuk memperbarui "salinan saya dari apa yang some.where.out.there", mereka dapat mengubah cabang mereka di sekitar, membuat yang baru, dan menghapus beberapa. Ketika Anda melakukan git fetch(atau git pullyang benar-benar mengambil plus penggabungan), repo Anda akan membuat salinan dari karya baru mereka dan mengubah semua refs/remotes/origin/<name>entri sesuai kebutuhan. Momen fetchyang membuat semuanya cocok (well, itu, dan klon awal, dan beberapa kasus pushjuga - pada dasarnya setiap kali Git mendapat kesempatan untuk memeriksa - tetapi lihat peringatan di bawah).

Git biasanya membuat Anda menyebut milik Anda sendiri refs/heads/<name>sebagai adil <name>, dan yang jauh sebagai origin/<name>, dan itu semua hanya bekerja karena sudah jelas mana yang mana. Kadang-kadang mungkin untuk membuat nama cabang Anda sendiri yang membuatnya tidak jelas, tetapi jangan khawatir tentang hal itu sampai itu terjadi. :-) Beri saja Git nama terpendek yang membuatnya jelas, dan itu akan pergi dari sana: origin/masteradalah "di mana master ada di sana terakhir kali saya memeriksa", dan master"di mana master ada di sini berdasarkan apa yang telah saya lakukan" . Jalankan git fetchuntuk memperbarui Git pada "di mana master ada di sana" sesuai kebutuhan.


Peringatan: dalam versi Git yang lebih tua dari 1.8.4, git fetchmemiliki beberapa mode yang tidak memperbarui "di mana master ada di sana" (lebih tepatnya, mode yang tidak memperbarui cabang pelacakan jarak jauh). Larigit fetch origin , atau git fetch --all, atau bahkan hanya git fetch, tidak pembaruan. Berlari git fetch origin master tidak . Sayangnya, mode "tidak diperbarui" ini dipicu oleh mode biasa git pull. (Ini terutama hanya gangguan kecil dan diperbaiki di Git 1.8.4 dan yang lebih baru.)


1 Nah, ada satu hal yang disebut "remote". Tapi itu juga lokal! Nama originadalah hal yang disebut Git "remote". Itu pada dasarnya hanya nama pendek untuk URL yang Anda gunakan ketika Anda melakukan klon. Itu juga tempat origindiorigin/master berasal dari. Nama origin/masterini disebut cabang pelacakan jarak jauh , yang kadang disingkat menjadi "cabang jarak jauh", terutama dalam dokumentasi yang lebih lama atau lebih informal.

torek
sumber
2
Deskripsi yang bagus untuk pemula seperti saya, terima kasih! Mengklarifikasi mengapa dia meletakkan origin/masterstiker pada localgrafik repo, dan bukan pada stiker itu remote(saya dengan sepenuh hati merekomendasikan presentasi "Kerit Terjadi" dari Jessica Kerr untuk orang-orang yang baru mengenalgit : vimeo.com/46010208 . Saya menggaruk-garuk kepala saya antara pukul 30: 30-30: 19.)
penatua
11

Saya akan mencoba membuat jawaban @ ErichBSchulz lebih sederhana untuk pemula:

  • origin / master adalah keadaan cabang master pada repositori jarak jauh
  • master adalah keadaan cabang master pada repositori lokal
MKJ
sumber
1
Selamat mencoba tapi IMHO tanpa last time I've checkeditu kehilangan poin penting
Alexei Martianov
6
  1. asal - Ini adalah nama khusus dan paling umum untuk menunjuk ke remote.

$ git remote add origin https://github.com/git/git.git--- Anda akan menjalankan perintah ini untuk menautkan proyek github Anda ke asal. Di sini asal ditentukan oleh pengguna. Anda dapat mengganti nama dengan$ git remote rename old-name new-name


  1. master - Nama cabang default di Git adalah master. Untuk komputer jarak jauh dan lokal.

  1. origin / master - Ini hanya pointer untuk merujuk cabang master di repo jarak jauh. Ingat saya katakan titik asal ke remote.

$ git fetch origin- Mengunduh objek dan referensi dari repositori jarak jauh ke komputer [asal / master] Anda. Itu berarti itu tidak akan mempengaruhi cabang master lokal Anda kecuali Anda menggabungkannya menggunakan$ git merge origin/master . Ingatlah untuk checkout cabang yang benar di mana Anda harus menggabungkan sebelum menjalankan perintah ini

Catatan: Konten yang diambil direpresentasikan sebagai cabang jarak jauh. Ambil memberi Anda kesempatan untuk meninjau perubahan sebelum mengintegrasikannya ke dalam salinan proyek Anda. Untuk menampilkan perubahan antara Anda dan jarak jauh$git diff master..origin/master

Gnanasekar S
sumber
5

Satu klarifikasi (dan poin yang membingungkan saya):

"remote / origin / HEAD adalah cabang default" tidak sepenuhnya benar.

remote / origin / master adalah cabang default di repositori jarak jauh (terakhir kali Anda memeriksa). KEPALA bukan cabang, itu hanya menunjuk ke cabang.

Pikirkan HEAD sebagai area kerja Anda. Ketika Anda memikirkannya seperti ini maka 'git checkout branchname' masuk akal sehubungan dengan mengubah file area kerja Anda menjadi cabang tertentu. Anda "checkout" file cabang ke area kerja Anda. KEPALA untuk semua tujuan praktis adalah apa yang terlihat oleh Anda di wilayah kerja Anda.

Rick
sumber
Lebih tepatnya, HEADadalah "penunjuk ke cabang" (file aktual di repo lokal Anda sering berisi string ref: refs/heads/master, misalnya ... kecuali "terpisah", yang merupakan hal lain sama sekali). Namun, ada semacam bug dalam cara clonemengartikan "HEAD jarak jauh": protokol transfer tidak dapat mengirim cabang tidak langsung sama sekali, hanya SHA-1 mentah, jadi git memiliki kludge yang membuat ini "sebagian besar berfungsi". Namun sesekali seseorang menemukan kasus aneh. Saya agak berharap git tidak menciptakan remotes/origin/HEADsama sekali, terutama ketika itu keluar salah ...
torek
2

Saya pikir notasi git slash ini mungkin paling baik dipahami dengan melihat ke dalam .gitfolder Anda .


Sebagai contoh, ini adalah pohon .git saya yang agak disingkat untuk basis sumber LibreOffice.

Di linux sudo apt-get install tree bermanfaat untuk melihatnya.
Di Windows saya pikir treeperintah itu mungkin masih berfungsi.

Gulir ke bawah dan lihat referensi (alias 'referensi') di dekat bagian bawah:

$ tree  
.  
├── branches  
├── config  
├── description  
├── FETCH_HEAD  
├── gitk.cache  
├── HEAD  
├── hooks  
│   ├── applypatch-msg.sample  
    ...
├── index  
├── info  
│   └── exclude  
├── logs  
│   ├── HEAD  
│   └── refs  
│       ├── heads  
│       │   ├── master  
│       │   └── remotes  
│       │       └── origin  
│       └── remotes  
│           └── origin  
│               ├── distro  
│               │   ├── cib  
│               │   │   └── libreoffice-6-0  
│               │   ├── collabora  
│               │   │   └── cp-6.0  
│               │   └── lhm  
│               │       └── libreoffice-5-2+backports  
│               ├── HEAD  
│               ├── libreoffice-6-2  
│               ├── master  
│               └── private  
│                   └── mst  
│                       └── sw_redlinehide_4a  
├── objects  
│   ├── info  
│   └── pack  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.idx  
│       ├── pack-b80087dc57e2b3315f449ca0f1aaa91987bf0c5e.pack  
│       ├── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.idx  
│       └── pack-eb4e6808029e712d8d9c2671accbbd98aaeb9a04.pack  
├── ORIG_HEAD  
├── packed-refs  
└── refs  
    ├── heads  
    │   ├── master  
    │   └── remotes  
    │       └── origin  
    ├── remotes  
    │   └── origin  
    │       ├── distro  
    │       │   ├── cib  
    │       │   │   └── libreoffice-6-0  
    │       │   ├── collabora  
    │       │   │   └── cp-6.0  
    │       │   └── lhm  
    │       │       └── libreoffice-5-2+backports  
    │       ├── HEAD  
    │       ├── libreoffice-6-2  
    │       ├── master  
    │       └── private  
    │           └── mst  
    │               └── sw_redlinehide_4a  
    └── tags  
        └── libreoffice-6-2-branch-point  

32 directories, 45 files

Mungkin kurang membingungkan jika ditata seperti ini, tetapi tidak:

repositories (i.e. independent trees)
├──local
│  └──master
│
└──origin1
│  └──master
└──origin2
   └──master

Kami memiliki tiga jenis referensi dasar: kepala , jarak jauh , dan tag .

  • .git / refs / kepala memegang master lokal kami .

  • .git / refs / remote dapat menampung sejumlah remote, meskipun saat ini kami hanya memiliki asal di dalamnya.

  • .git / refs / tag (dibahas di tempat lain).

asal demikian, adalah satu-satunya kita dan jauh. Itu memegang asal / master .


Kami menemukan bahwa kami memiliki 2 HEADS (pointer ke cabang saat ini), satu lokal, dan satu remote:

$ cat .git/HEAD                        #         local:  HEAD -> master
ref: refs/heads/master

$ cat .git/refs/remotes/origin/HEAD    # remote origin:  HEAD -> master
ref: refs/remotes/origin/master

Jika Anda daftar cabang Anda :

$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/aoo/aw080
  remotes/origin/aoo/trunk
  remotes/origin/distro/capgemini/cg-4.1
  remotes/origin/distro/cib/libreoffice-5-0
  remotes/origin/distro/cib/libreoffice-5-1
  remotes/origin/distro/cib/libreoffice-5-2
  ...
  • Cabang pertama yang terdaftar ( master ) adalah satu-satunya yang bukan remote. Jadi dalam hal ini kami memiliki satu cabang lokal. Di sinilah kami akan memulai pekerjaan kami sendiri, untuk cabang-cabang baru kami dan komitmen selanjutnya.

Selanjutnya, Anda mungkin memiliki banyak cabang pelacakan jarak jauh, dan kami lakukan di sini. Anda tahu ini adalah cabang pelacakan jarak jauh karena mereka diawali dengan ' remote / '. Yang ditampilkan di sini adalah untuk asal bernama remote.

  • Jadi baris kedua adalah pointer cabang saat ini asal . Remote / asal: HEAD --points to -> master. Ini menunjukkan bahwa dalam repositori jarak jauh, cabang saat ini adalah cabang mereka yang bernama master , (jangan bingung dengan cabang lokal kami yang bernama master ).

  • Cabang yang tersisa tidak ditemukan di .git / refs / tree Anda, tetapi Anda akan menemukannya di .git/packed-refs.

Ketika kita git fetch kita download perubahan dari repositori jauh, ke dalam repositori pelacakan jarak jauh kami.

Ketika kita git menggabungkan kita menggabungkan perubahan di repositori pelacakan lokal, jauh ini ke cabang lokal kami atau cabang, dalam hal ini ke dalam cabang utama kami.

(Ketika kita git pull, kita melakukan kedua langkah ini dalam satu operasi.)


Ini juga menarik untuk dicatat lokal ini UUID dan jarak jauh ini untuk master yang saat ini mengarah ke simpul yang sama (alias 'komit'):

$ cat refs/heads/master                   # local         master
1ca409292272632f443733450313de5a82c54a9c

$ cat refs/remotes/origin/master          # remote origin master
1ca409292272632f443733450313de5a82c54a9c

Jadi master lokal kami menunjuk ke tempat yang sama dengan master asal remote:

[local] master = [remote] origin master

Akhirnya, saya pikir ini juga berguna untuk melihatnya .git/packed-refs

$ cat packed-refs 
# pack-refs with: peeled fully-peeled 
3c1d4742e649fe9c8aed8c2817fe3e1f3364f298 refs/remotes/origin/aoo/aw080
e87c8b7922e9a73e0abb7f9a7a47c9ac3374a826 refs/remotes/origin/aoo/trunk
b70fdffb041c12f124dcc0822b61bf3450e53137 refs/remotes/origin/distro/capgemini/cg-4.1
5dbc3f1754809b9489faaf380b1a4bdbcfbb6205 refs/remotes/origin/distro/cib/libreoffice-5-0
cfdbc96ca47d68d6785fd21829a8d61f49d6e591 refs/remotes/origin/distro/cib/libreoffice-5-1
5189c8c47461ef09739086e55512fc6a10245273 refs/remotes/origin/distro/cib/libreoffice-5-2
3bee5917569ca8e6ee3b086458f5b1a917b88ca1 refs/remotes/origin/distro/cib/libreoffice-5-3
92fbe703f9ca480d3a2b8610d87e991c729edf77 refs/remotes/origin/distro/cib/libreoffice-5-4
05c0a5df66cc69d75280f05b804cf82f3387d42b refs/remotes/origin/distro/cib/libreoffice-6-0
7fe193e759b24b90852e6e327115b77114d7b119 refs/remotes/origin/distro/cib/libreoffice-6-1
8187f7aa413e7ef7b377eea2b057d336bf256867 refs/remotes/origin/distro/collabora/cd-5.3
7a6b608591e21ef61dc05cff9fc58da531035755 refs/remotes/origin/distro/collabora/cd-5.3-3.1
....

Tidak diragukan lagi ini menyisakan lebih banyak pertanyaan daripada jawaban, tetapi saya pikir ini dapat mulai membantu Anda menjawab pertanyaan Anda sendiri tentang apa itu.

Pandangan elips
sumber