Git ветвление: мастер против источника / мастер против удаленных / источник / мастер

Я думаю, что я на правильном пути, чтобы понять основные концепции Git.

Я уже настроил и клонировал удаленный репозиторий. Я также создал пустой репозиторий на стороне сервера и связал с ним свой локальный репозиторий.

Моя проблема в том, что я не понимаю разницу между:

  • Происхождение / мастер против удаленных / происхождение / мастер

Насколько я понял, master - это локальная ветвь, а remotes / origin / master - удаленная.

Но что такое происхождение / мастер?

7 ответов

Решение

Возьмите клон удаленного репозитория и запустите 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,

Краткий ответ для таких чайников, как я (украденный у Торека):

  • origin / master - это "где мастер был там в прошлый раз, когда я проверял"
  • мастер "где мастер здесь на основе того, что я делал"

Технически на самом деле нет никаких "удаленных" вещей 1 в вашем репозитории Git, есть только локальные имена, которые должны соответствовать именам в другом, другом репо. Названные origin/whatever Первоначально будет совпадать с теми, которые находятся в репо, с которого вы клонировали:

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

делает локальную копию другого репо. По пути он отмечает все ветви, которые были там, и фиксирует те, на которые ссылаются, и вставляет их в локальный репозиторий под именами. refs/remotes/origin/,

В зависимости от того, как долго вы идете, прежде чем git fetch или эквивалентно обновлению "моей копии what. some.where.out.there", они могут менять свои ветви вокруг, создавать новые и удалять некоторые. Когда вы делаете свой 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 на "где мастер там", как необходимо.


Предостережение: в версиях 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 это то, что Git называет "удаленным". Это просто краткое имя для URL, который вы использовали, когда делали клон. Это также, где origin в origin/master происходит от. Имя origin/master называется ветвью удаленного отслеживания, которая иногда сокращается до "удаленной ветви", особенно в более старой или более неформальной документации.

Я бы постарался сделать ответ @ErichBSchulz более простым для начинающих:

  • origin / master - это состояние ветки master в удаленном хранилище.
  • master - состояние ветки master в локальном хранилище
  1. origin - это пользовательское и наиболее распространенное имя, указывающее на удаленное.

$ git remote add origin https://github.com/git/git.git --- Вы запустите эту команду, чтобы связать ваш проект github с origin. Здесь происхождение определяется пользователем. Вы можете переименовать его $ git remote rename old-name new-name


  1. master - в Git по умолчанию используется имя ветки master. Для удаленного и локального компьютера.

  1. origin / master - это просто указатель для ссылки на главную ветку в удаленном репо. Помните, я сказал, что происхождение указывает на удаленный.

$ git fetch origin - Загружает объекты и ссылки из удаленного хранилища на локальный компьютер [origin/master]. Это означает, что это не повлияет на вашу локальную главную ветвь, если вы не объедините их, используя $ git merge origin/master, Не забудьте оформить правильную ветвь, где вам нужно объединиться, прежде чем запускать эту команду

Примечание. Извлеченное содержимое представляется в виде удаленной ветви. Fetch дает вам возможность просмотреть изменения, прежде чем интегрировать их в вашу копию проекта. Чтобы показать изменения между вашим и удаленным $git diff master..origin/master

Я думаю, что это примечание git slash, вероятно, лучше понять, если заглянуть внутрь .git папка.


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

В линуксе sudo apt-get install tree Это полезно для просмотра.
В винде думаю 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 / head содержит нашего местного мастера.

  • .git / refs / remotes может содержать несколько пультов, хотя на данный момент мы имеем только источник.

  • .git / refs / tags (обсуждается в другом месте).

Происхождение, таким образом, является нашим единственным и отдаленным. Это держит происхождение / мастер.


Мы находим, что у нас есть 2 HEADS (указатели на текущие ветви), один локальный и один удаленный:

$ 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 ". Те, что показаны здесь, предназначены для удаленного именованного источника.

  • Таким образом, вторая строка является указателем текущей ветви источника. Remotes/origin: HEAD - указывает на -> мастер. Это показывает, что в удаленном репозитории текущая ветвь является их ветвью с именем master (не путать с нашей локальной веткой с именем master).

  • Остальные ветви не найдены в вашем.git/refs/ tree, но вы найдете их в .git/packed-refs,

Когда мы выполняем git fetch, мы загружаем изменения из удаленного репозитория в наш удаленный репозиторий отслеживания.

Когда мы выполняем git merge, мы объединяем изменения в этом локальном удаленном репозитории отслеживания с нашей рабочей локальной ветвью или ветвями, в данном случае с нашей главной ветвью.

(Когда мы выполняем git pull, мы выполняем оба эти шага за одну операцию.)


Также интересно отметить, что эти локальные и удаленные UUID для master в настоящее время указывают на один и тот же узел (он же "commit"):

$ 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
....

Без сомнения, это оставляет больше вопросов, чем ответов, но я думаю, что это может помочь вам ответить на ваши собственные вопросы о том, что к чему.

Одно уточнение (и момент, который меня смутил):

"remotes / origin / HEAD является веткой по умолчанию" не совсем правильно.

remotes / origin / master был веткой по умолчанию в удаленном хранилище (когда вы последний раз проверяли). ГОЛОВА не ветвь, она просто указывает на ветвь.

Думайте о ГОЛОВЕ как о вашей рабочей зоне. Когда вы думаете об этом таким образом, тогда "git checkout branchname" имеет смысл изменить файлы рабочей области на файлы конкретной ветви. Вы "извлекаете" файлы веток в свою рабочую зону. Голова для всех практических целей - это то, что вы видите в своей рабочей зоне.

Другие вопросы по тегам