Розгалуження Git: майстер проти походження / master проти віддалених / походження / master


201

Я думаю, що я на вірному шляху, щоб зрозуміти основні поняття git.

Я вже створив і клонував віддалене сховище. Я також створив порожнє сховище на сервері та пов’язав з ним своє місцеве сховище.

Моя проблема полягає в тому, що я не розумію різниці між:

  • походження / майстер проти віддалених / походження / майстер

Наскільки я зрозумів, master - це локальна гілка, а віддалений / походження / master - віддалений.

Але що саме походження / господар ?


1
@ChristopherWallace: Ви спровокували два запитання щодо мета за допомогою своєї редакції: " Нам дійсно потрібен тег [походження]? " Та " Що таке справжній [Master]? ".
Дедуплікатор

@Deduplicator Це проблема?
nbro

@ChristopherWallace: Ну, здається, багато хто вважає, що обидва теги (той, який ви створили, і той, який ви тільки що додали) погані. Я випадково погоджуюся, але, можливо, у вас є що додати до дискусії, яка не розглядалася. Якщо ні, то, здається, так.
Дедуплікатор


Подальше запитання: навіщо .git/refs/origin/masterколи-небудь дрейфувати .git/refs/remotes/origin/master? Це зараз у мене відбувається, і мене відкидають.
Павло

Відповіді:


219

Візьміть клон віддаленого сховища та запустіть git branch -a(щоб показати всі гілки, про які знає git). Це, мабуть, буде виглядати приблизно так:

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

Тут masterзнаходиться відділення в локальному сховищі. remotes/origin/master- це гілка, названа masterна віддаленому імені origin. Ви можете посилатися на це як на origin/master, як у:

git diff origin/master..master

Ви також можете посилатися на це як remotes/origin/master:

git diff remotes/origin/master..master

Це лише два різні способи посилання на одне й те саме (до речі, обидві ці команди означають «покажіть мені зміни між віддаленою masterгілкою та моєю masterгілкою).

remotes/origin/HEADє default branchдля віддаленого імені origin. Це дозволяє вам просто сказати originзамість цього origin/master.


5
Хороша відповідь. Я думаю, що git branch -aпоказ віддаленої гілки як remotes/origin/masterчастково тому, що базовий номер зберігається в .git/refs/remotes/origin(якщо він не був упакований). На мою думку, результат роботи git branch -aможе бути набагато чіткішим, можливо, відокремлюючи назву віддаленого від назви гілки чимось іншим, ніж косою рисою.
Метт Херн

14
Також зауважте git branch -r, що для відображення лише віддалених гілок буде показано гілку як тільки origin/masterтому, що remotes/префікс не потрібен.
Метт Херн

3
@misterbiscuit: це правда. Вихід є більш заплутаним, ніж уточнюючим. Велике спасибі, чудова відповідь на моє запитання, яке дало мені правильні підказки
Джон Румпель

Якщо я дивлюсь, git logя бачу commit fa9sd8jasdf98 (HEAD -> master), що це означає? Що таке HEAD в цьому випадку? Я думав, що в даний час я "господар" і збираюся origin/master. Я думаю, що я щось переплутав, може хтось допоможе прояснитись? РЕДАКТУВАННЯ ОНОВЛЕННЯ: Я думаю, що я це зрозумів, чи правильно вважати, що HEAD в даний час вказує на головну гілку, це означає, що я зараз перебуваю в процесі прийому на майстер?
Себастьян Нільсен

@SebastianNielsen так, ви праві, HEAD -> майстер-частина означає, що ви зараз перебуваєте на головній гілці.
iRestMyCaseYourHonor

108

Коротка відповідь для манекенів, як я (вкрадено з Торека):

  • origin / master - це "там, де майстер був там останній раз, коли я перевіряв"
  • майстер - "там, де господар тут, на основі того, що я робив"

9
origin / master = резервне копіювання віддаленої машини, оновлене востаннє, коли ви перевіряли master = ваша копія походження / master
sakurashinken

40

Технічно є на самому ділі не якісь - або «дистанційний» речі на всіх 1 в вашому Git репо, є тільки локальні імена , які повинні відповідати іменам на іншому, різні репо. Названі origin/whateverспочатку співпадуть з тими, хто на репо, з якого ви клонували:

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

робить локальну копію іншого репо. По дорозі він зазначає всі гілки, які там були, і виконує посилання на них, і вкладає їх у ваше місцеве репо під назвами refs/remotes/origin/.

Залежно від того, скільки часу ви переходите до вас git fetchабо еквівалент, щоб оновити "мою копію того, що є деяким. Десь там. Тут", вони можуть змінити свої гілки, створити нові та видалити деякі. Коли ви зробите свою git fetch(або git pullяка насправді витяг плюс злиття), ваше репо зробить копії своєї нової роботи та змінить усі refs/remotes/origin/<name>записи за потребою. Саме цей момент fetchінгібує, що все узгоджується (ну, що, і початковий клон, і деякі випадки pushінженерії - в основному, коли Git отримує можливість перевірити - але дивіться застереження нижче).

У Git зазвичай ви посилаєтесь на власні refs/heads/<name>як на справедливі <name>, а на віддалені - як origin/<name>, і все це працює, тому що очевидно, який з них є. Іноді можливо створити власні назви гілок, які роблять це не очевидним, але не хвилюйтеся про це, поки це не станеться. :-) Просто дайте Git найкоротше ім'я, яке робить це очевидним, і воно піде звідти: origin/masterце "там, де майстер був там останній раз, коли я перевірив", і master"де господар тут, на основі того, що я робив" . Запустіть, git fetchщоб оновити Git на "там, де господар там," за потребою.


Caveat: у версіях Git, старших 1.8.4, git fetchє деякі режими, які не оновлюються "там, де майстер там" (точніше, режими, які не оновлюють жодної гілки віддаленого відстеження). Біг git fetch origin, або git fetch --all, або навіть просто git fetch, робить оновлення. Біг git fetch origin master не робить . На жаль, цей режим "не оновлюється" спрацьовує звичайним git pull. (Це в основному лише незначне роздратування і фіксується в Git 1.8.4 і пізніших версіях.)


1 Ну, є одна річ, яку називають "дистанційною". Але це теж місцево! Назва origin- це те, що Гіт називає "дистанційним". Це в основному лише коротка назва URL-адреси, яку ви використовували, коли робили клон. Це також , де originв origin/masterприходить. Назва origin/masterназивається відділенням віддаленого відстеження , яке іноді скорочується до "віддаленого відділення", особливо в старій чи більш неофіційній документації.


2
Відмінний опис для такого новачка, як я, дякую! Уточнив, чому вона поставила origin/masterнаклейку на localграфік репо, а не на remoteодин (я від усієї душі рекомендую презентацію Джесіки Кер "Git Happens" для людей, які не знайшлиgit : vimeo.com/46010208 . Я чухав голову між 30:00 - 30: 19.)
старший старший

11

Я б спробував зробити відповідь @ ErichBSchulz простішим для початківців:

  • origin / master - це стан головного відділення у віддаленому сховищі
  • master - стан головного відділення в локальному сховищі

1
добре спробуйте, але IMHO без виходу last time I've checkedвтрачає важливий момент
Олексій Мартьянов

6
  1. походження - Це звичайне і найпоширеніше ім’я, яке слід вказувати на віддалений.

$ git remote add origin https://github.com/git/git.git--- Ви виконаєте цю команду, щоб прив'язати ваш проект github до походження. Тут походження визначено користувачем. Ви можете перейменувати його за$ git remote rename old-name new-name


  1. master - Назва гілки за замовчуванням у Git - це master. Як для віддаленого, так і для локального комп'ютера.

  1. origin / master - Це лише вказівник на посилання на головну гілку у віддаленому репо. Пам'ятайте, я сказав, що походження вказує на віддалений

$ git fetch origin- Завантажує об’єкти та реферати з віддаленого сховища на локальний комп'ютер [походження / майстер]. Це означає, що це не вплине на вашу локальну галузь, якщо ви не зробите їх з використанням $ git merge origin/master. Не забудьте перевірити правильну гілку, де потрібно об'єднатись, перш ніж запустити цю команду

Примітка: Вибраний вміст представлений як віддалена гілка. Fetch дає вам можливість переглянути зміни, перш ніж інтегрувати їх у свою копію проекту. Показати зміни між вашими та віддаленими$git diff master..origin/master


5

Одне уточнення (і пункт, який мене бентежив):

"Remotes / origin / HEAD - це гілка за замовчуванням" насправді не вірна.

Remotes / origin / master була гілкою за замовчуванням у віддаленому сховищі (востаннє ви перевіряли). HEAD - це не галузь, вона просто вказує на гілку.

Подумайте про голову як про свою робочу зону. Якщо ви думаєте про це таким чином, тоді "git checkoutname name" має сенс щодо зміни файлів вашої робочої області, щоб бути файлом певної гілки. Ви "оформляєте" гілки файлів у свою робочу зону. ГОЛОВНА для всіх практичних цілей - це те, що вам видно у вашій робочій зоні.


Точніше, HEADце "вказівник на гілку" (власне файл у вашому локальному репо часто містить рядок ref: refs/heads/master, наприклад ..., крім випадків, коли він "від'єднаний", що зовсім інша річ). Тим не менш, існує різновид помилок у тому, як cloneінтерпретується "віддалений HEAD": протоколи передачі взагалі не можуть надсилати непряму гілку, а лише сирий SHA-1, тому git має хитрості, завдяки чому це "в основному працює". Кожен час від часу хтось натрапляє на дивний випадок. Я свого роду бажання git взагалі не створював remotes/origin/HEAD, особливо коли він виходить неправильним ...
torek

2

Я думаю, що це позначення косої риси, мабуть, найкраще зрозуміти, заглянувши всередину вашої .gitпапки.


Наприклад, ось дещо скорочене дерево мого .git для вихідної бази LibreOffice.

Для Linux sudo apt-get install tree це корисно для перегляду.
У Windows я думаю, що treeкоманда все ще може працювати.

Прокрутіть униз і подивіться реф. (Також "посилання") внизу:

$ 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

Це може бути менш заплутано, якби воно було викладено так, але це не так:

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

У нас є три основні типи посилань: голови , пульти та теги .

  • .git / refs / heads тримає нашого місцевого майстра .

  • .git / посилання / пультів ДУ може містити кілька пультів дистанційного керування, хоча на даний момент ми маємо тільки походження в ньому.

  • .git / refs / tags (обговорюється в іншому місці).

Походження, таким чином, є нашим єдиним та віддаленим. Він має походження / головного .


Ми виявляємо, що у нас є 2 ГОЛОВИ (вказівники на поточні гілки), одна локальна та одна віддалена:

$ 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

Якщо ви перелічите свої філії :

$ 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
  ...
  • Перша перелічена ( ведуча ) гілка є єдиною, яка не є віддаленою. Тож у цьому випадку ми маємо одне місцеве відділення. Ось з чого ми почнемо свою власну роботу, для власних нових відділень та подальших зобов’язань.

Далі у вас може бути багато відділень віддаленого відстеження, і ми тут. Ви знаєте, що це віддалені гілки відстеження, оскільки вони мають префікс " Remotes / ". Тут показано віддалене походження.

  • Отже, другий рядок є поточним вказівником гілки origin . Віддалення / походження: HEAD --точки до -> master. Це показує, що у віддаленому сховищі поточна гілка є їхньою гілкою з ім'ям master (не плутати її з нашою локальною гілкою з іменем master ).

  • Решта гілок не знайдено у вашому .git / refs / tree, а скоріше ви їх знайдете .git/packed-refs.

Коли ми git fetch, ми завантажуємо зміни з віддаленого сховища, у наше сховище віддаленого відстеження.

Коли ми git злиття, ми об'єднуємо зміни цього локального сховища віддаленого відстеження у нашу працюючу локальну філію або гілки, в даному випадку в нашу головну гілку.

(Коли ми git pull, ми робимо обидва ці кроки в одній операції.)


Також цікаво відзначити, що ці локальні та віддалені UUID- майстри для головного в даний час вказують на той самий вузол (він же "фіксувати"):

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

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

Тож наш місцевий майстер вказує на те саме місце, що і майстер походження дистанційного керування:

[local] master = [remote] origin master

Нарешті, я думаю, що також корисно поглянути .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
....

Без сумніву, це залишає більше питань, ніж відповідей, але я думаю, що це може почати допомагати вам відповідати на власні запитання про те, що робити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.