2013-09-01 3 views
1

Я этоКак правильно Кассовые ветви из удаленного хранилища

[email protected]:~/project1/wh-app-ios$ git branch -a -v -v 
    * master     1d35af1 [origin/master: ahead 2] Adding 123 to hello 
     remotes/gitb/gh-pages e3dad9d boom 
     remotes/gitb/integration 1d3fcd5 Adding 55_Glossary chapter 
     remotes/gitb/master  86d1d30 Merge remote-tracking branch 'origin/master' 
     remotes/gitb/pt_BR  dc9d991 Revisions at 03, 07, 08, 09, 10, 11 and 50 
     remotes/origin/HEAD  -> origin/master 
     remotes/origin/master 1ae426b Update README.md 

я

[email protected]:~/project1/wh-app-ios$ git checkout gitb/master 
    Note: checking out 'gitb/master'. 

    You are in 'detached HEAD' state. You can look around, make experimental 
    changes and commit them, and you can discard any commits you make in this 
    state without impacting any branches by performing another checkout. 

    If you want to create a new branch to retain commits you create, you may 
    do so (now or later) by using -b with the checkout command again. Example: 

     git checkout -b new_branch_name 

    HEAD is now at 86d1d30... Merge remote-tracking branch 'origin/master' 

Затем, глядя на предостерегающие сообщения выше я делаю

[email protected]:~/project1/wh-app-ios$ git checkout -b mastergitb 
    Switched to a new branch 'mastergitb' 

Теперь я на

[email protected]:~/project1/wh-app-ios$ git branch -a -v -v 
     master     1d35af1 [origin/master: ahead 2] Adding 123 to hello 
    * mastergitb    86d1d30 Merge remote-tracking branch 'origin/master' 
     remotes/gitb/gh-pages e3dad9d boom 
     remotes/gitb/integration 1d3fcd5 Adding 55_Glossary chapter 
     remotes/gitb/master  86d1d30 Merge remote-tracking branch 'origin/master' 
     remotes/gitb/pt_BR  dc9d991 Revisions at 03, 07, 08, 09, 10, 11 and 50 
     remotes/origin/HEAD  -> origin/master 
     remotes/origin/master 1ae426b Update README.md 
    [email protected]:~/project1/wh-app-ios$ 

Вопрос:

  1. Но ясно mastergitb не отслеживает gitb/мастер. Почему это ?

  2. Я только что создал локальную ветвь с именем mastergitb, которая является просто копией gitb/master, но не имеет никакого отношения к ней?

+0

BTW, что такое «gitb»? Просто опечатка для «git»? – sleske

+0

@sleske no, это имя удаленного репо. – VonC

+0

@VonC: Ах, я вижу. Я редактировал заголовок. – sleske

ответ

4

Есть странная вещь о «удаленной ветке», так как git называет их, что отличает их от «местных» ветвей. Я иногда думаю, что это может иметь смысл для людей, если git использует другое имя, хотя на самом деле у меня нет лучшего имени. Таким образом, по отношению к вопросу 2:

ли я просто создать локальную ветку с именем mastergitb, что это просто копия gitb/master, но не имеет никакого другого отношения с ним?

Да, но фраза «копия» немного вводит в заблуждение. Скажем, вместо этого, что вы создали локальную ветвь, то заканчивается с той же фиксацией, что и удаленной.

Вещь в отношении ветвей git заключается в том, что каждое название ветки - это всего лишь метка для фиксации. То, что делает локальное название филиала особенно особенным (и полезным), заключается в том, что это , перемещающий метку, и автоматически перемещает . (Сравните с тегом «tag», который также является ярлыком для определенного коммита, но теги не перемещаются автоматически, и люди обычно ожидают, что они останутся на месте. Вы должны предупредить других, которые делятся или копируют из вашего репо, если вы перемещаете тег.)

Когда вы находитесь на «ветке», против того, чтобы иметь «отдельную ГОЛОВКУ», которая, как заметил кто-то, является отвратительной - и вы делаете новую фиксацию, ярлык ветви автоматически переходит к новому совершить. То есть, когда HEAD является именем ветки bran, git commitgit merge и другими различными способами добавления коммитов), добавьте новый фиксатор с родительским указателем, указывающим на предыдущий ответ, и затем переместите ветку :

C5 -- C6 -- C7 <-- HEAD=bran 

становится:

C5 -- C6 -- C7 -- C8 <-- HEAD=bran 

Но "удаленные филиалы" не работают, как это. Фактически, вы не можете даже быть «на» удаленной ветви, как вы обнаружили: если вы git checkout origin/master, git помещает вас в состояние «отдельно стоящего HEAD».

Другая забавная вещь, тем не менее, заключается в том, что «удаленные ветви» могут и не двигаться. Они не двигаются, когда вы добавьте фиксацию, потому что вы никогда не «на» их. Вы проверяете их, и голова гильотинирована сразу. :-) Затем вы можете создать локальную ветвь с git checkout -b, как и вы. Эта локальная ветвь настроена так, чтобы указывать на то, что имена HEAD, которые являются тем же самым сообщением, что и имя удаленной ветви. Это не совсем копия чего-либо, потому что это просто стрелка , указывающая на фиксация.

В виде диаграммы, это может выглядеть немного, как это (если вы на местном master, что «отслеживание» origin/master):

 C2  <-- origin/xyz 
    /
C0--C1   <-- origin/foo 
     \ 
     C3--C4 <-- origin/bar 
     \ 
      C5  <-- origin/master, HEAD=master 

Если вы git checkout origin/foo, мерзавец сотрет HEAD= из внизу (оставляя origin/master и master оба указывающие на фиксацию C5), и установите HEAD в хэш-код SHA-1 для фиксации C1. Он не устанавливает HEAD=origin/foo (что помещает вас в «удаленную ветку»), а скорее непосредственно на хеш фиксации (состояние «отсоединенной головки»).

Затем, когда вы git checkout -b localfoo, мерзавец создает новое имя ветви localfoo, устанавливает его, чтобы указать на совершение C1, и устанавливает HEAD=localfoo. Теперь вы «на ветке»!

Примечание: «ФИО» местного отделения bran - refs/heads/bran. «Полное имя» удаленной ветви rmt/bran - refs/remotes/rmt/bran. То есть, локальная ветка всегда находится в refs/heads/, а удаленной - никогда. Обычно вы оставляете все материалы переднего конца и просто ссылаетесь на bran и origin/bran, но иногда это имеет значение, и это делает некоторые из приведенных ниже текстов более разумными.

Помимо создания localfoo «дорожка» origin/foo (уже ответили), есть еще один пункт, чтобы объяснить, и это: как, точно, «удаленные ветви» перемещаются? Ответ: они перемещаются на git fetch (или git remote update, который в основном такой же, как fetch). Когда вы извлекаете (или обновляете) с удаленного, git связывается с пультом дистанционного управления и находит его имена ветвей. Используя эти имена, он находит коммиты, на которые они указывают. Затем он находит своих родителей, родителей родителей и так далее. Всякий раз, когда у вас нет этих коммитов, он их переносит и заправляет в ваше репо, чтобы вы «догнали» до пульта.Затем он записывает новые имена ссылок в категории «удаленные ветви», которые контролируются файлом .git/config.

Если заглянуть в .git/config вы увидите что-то вроде этого:

[remote "origin"] 
     fetch = +refs/heads/*:refs/remotes/origin/* 
     url = ssh://some.where.out.there/some/path/to/repo.git 

Это fetch линия является ключом к получению «удаленных филиалов». В нем говорится, что для всего пульта есть то, что соответствует refs/heads/* -все его местных филиалов - заменить refs/heads/ с refs/remotes/origin/ (сохраняя остальную часть названия филиала), а затем обновить эти ссылки (насильно, из-за знака +). Таким образом, после того, как кто-то контролирует удаленные обновления URL-адресов, которые репо, а затем вы получаете fetch, вы получаете их обновления, и ваш git перемещает ваши ярлыки «удаленной ветви» в соответствии с ними.

Это зависит от вас, когда и когда нужно переместить местных ярлыки отраслевых ярлыков в соответствии с автоматически перемещаемыми ярлыками «удаленной ветви». Легкий способ сделать это - использовать «git merge», а простой способ автоматизации - сделать локальную ветвь «ветвью отслеживания». После того, как вы разметили местное отделение L в качестве отслеживания удаленных филиалов RMT/R, git status сообщит вам, если это позади, git pull будет знать, как вызвать git merge и git merge можно сказать для автоматического обновления (см merge.defaultToUpstream в раздел КОНФИГУРАЦИЯ git-merge documentation).

6

Я не знаю, почему сообщение не относится к этому, но вы можете написать

git checkout -t origin/branchname 

создать локальную ветку с именем branchname, который отслеживает origin/branchname (-t коротка для --track) , Или вы можете написать

git checkout -b localname -t origin/branchname 

создать локальную ветку с именем localname, который отслеживает origin/branchname, так что в вашем примере:

git checkout -b mastergitb -t gitb/master 

Да, создавая неотслеживающую ветку именно то, что вы сделали. Вы можете исправить это, удалив ветвь и следуя этим инструкциям, или запустив git branch --set-upstream mastergitb gitb/master, чтобы установить восходящий поток для существующей ветки.

Смежные вопросы