Git Branch Подробности - PullRequest
       3

Git Branch Подробности

0 голосов
/ 08 ноября 2019

Подскажите, пожалуйста, как я могу определить следующие детали Git Branch

  • Кто создал ветку
  • Когда была создана ветка
  • , какая ветка новаябыла создана ветка

1 Ответ

0 голосов
/ 08 ноября 2019

Вы слишком верите в идею ветви. Git не заботится о ветвях; Git заботится о коммитах . Но чтобы сказать это, мы должны сначала остановиться и определить слово ответвление . В этом абзаце, что я подразумеваю под «ветвью», является именем ветви , например master или develop или feature/tall. Для Git эти имена имеют только одну функцию: для записи необработанного хеш-идентификатора коммита.

В Git есть другие сущности, которые люди могут и действительно называют "ветвью". См. Что именно мы подразумеваем под "ветвью"?

В любом случае ветвь name в Git содержит хэш-идентификатор одного коммита. Это на самом деле очень полезно: и для нас, людей, для которых идентификаторы хешей в Git выглядят как случайный мусор, и для самого Git. Но это все , которые они держат сами. Важная информация хранится в другом месте, в основном в самих коммитах.

Git действительно заботится о коммитах. Коммиты хранят большую часть данных, которые вы ищете: кто их сделал, когда и из каких других ранее зафиксированных коммитов.

В именах ветвей не хранятся данные, которые вы ищете. У них нет информации об создателе. У них тоже нет собственной истории (но мы увидим кое-что еще через минуту). Для этого есть важная причина.

В отличие от ClearCase, Git представляет собой распределенную систему контроля версий. В ClearCase имеется централизованное управляемое хранилище: база объектов томов или VOB. Отдельные пользователи идут в центральное хранилище и получают из него что-то, а затем возвращают его обратно. Чтобы сделать это, все эти пользователи должны совместно использовать имена VOB для вещей. Так что если VOB хочет называть что-то Брюсом, то все остальные тоже могут называть это Брюсом.

С Git каждый репозиторий независим . У каждого есть свои собственные имена ветвей, независимо от имен ветвей всех остальных. only действительно универсальное имя в Git - это хэш-идентификатор. Каждый согласен с хеш-идентификаторами: коммит, чей хеш-код 08da6496b61341ec45eac36afcc8f94242763468 равен 08da6496b61341ec45eac36afcc8f94242763468 в в каждом репозитории Git. Никакой другой коммит не может иметь ID 08da6496b61341ec45eac36afcc8f94242763468.

Если вы и я планируем соединить наши репозитории вместе, мы могли бы хотеть координировать имена наших веток время от времени, и мы может сделать это. Но мой репозиторий имеет моих названий веток, а ваш - ваших. Вы являетесь создателем всех названий вашей ветви. Я буквально не могу создать имя ветки в вашем хранилище. Все, что я могу сделать, это передать вам коммит - по его большому уродливому хэш-идентификатору - и затем попросить вашего Git создать или обновить какое-то имя. 1

Это большеОбычно все настраивается наоборот: я даю вам только для чтения доступ к моему хранилищу. Вы запускаете git fetch, чтобы ваш Git вызывал мой Git через Интернет. Ваш Git спрашивает мой Git: Эй, другой-Git, какие у вас есть названия веток? Какие универсальные идентификаторы хеша идут вместе с этими именами ветвей? Мой Git дает вам мой список имен и хэш-идентификаторов, и ваш Git работает оттуда:

  • Torek's Gitговорит, что его master a123456.... У меня есть a123456..., так что я в порядке.
  • Git Торека говорит, что его dev составляет b789abc.... Хм, у меня нет есть b789abc.... Возможно, мне следует запросить этот коммит по его хеш-идентификатору.

Это будет продолжаться до тех пор, пока ваш Git не получит всю информацию, которую мой Git передает на этом этапе коммуникации. Затем ваш Git по хеш-идентификатору запрашивает любой коммит, который он хочет. Если родительский коммит этого коммита - другой хеш-идентификатор, сохраненный внутри фактического коммита - представляет собой коммит, которого нет у вашего Git, ваш Git может запросить , что коммит его хэш-идентификатор и т. Д.

Evфактически, ваш Git возвращается к некоторому хеш-идентификатору, который уже есть у вашего Git - в этом случае у вашего Git есть коммит и он вообще не нужен - или у меня заканчиваются коммиты и я говорю «это все, что есть». 2 Затем ваш Git создает в вашем репозитории Git каждый коммит, который я передал.

Последнее, что делает ваш Git в этом процессе, - это создает или обновляет ваш имена для удаленного слежения . Здесь вместо того, чтобы использовать ваши ветви имена - которые ваши, а не мои! - ваш Git меняет все мои имена, простым и удобным в обращении образом. Ваш Git использует псевдоним для моего Git, а не URL. Псевдоним вашего Git, вероятно, origin - хотя вы можете и фактически должны установить другой один для каждого другого Git, который вы собираетесь вызывать вот так. Имя origin - это просто имя по умолчанию для Git, из которого вы сделали свой первоначальный клон.

Итак, давайте предположим, что ваш Git вызывает Git origin. Ваш Git имеет полный список всех ветвей my и соответствующих им (одиночных) хеш-идентификаторов. Таким образом, ваш Git теперь создает или обновляет имя origin/*, соответствующее именам моего Git. Мой Git сказал вашему Git, что my master равно a123456..., поэтому ваш Git создает или обновляет ваш origin/master, чтобы он указывал на коммит a123456.... У вас уже был этот коммит, так что мой не должен был отправлять его вам, или не попросил его, и мой Git отправил его. Мой Git сказал вашему Git, что my dev это b789abc...;ваш Git имеет этот коммит сейчас;ваш Git создает или обновляет ваш origin/dev, чтобы он указывал на b789abc....

Опять же, это коммит , что имеет значение. Коммиты - и хэш-идентификаторы - являются универсальной валютой Git. Чьи-то имена филиалов ... ну, это те, о ком нужно беспокоиться. Мы скопируем их и сохраним как имя для удаленного слежения , но это не имена branch . Мои ветви названы моими;твои названия веток твои. Независимо от того, что Git использует кто-то, его имена ветвей их , а не чьи-либо другие.


1 Для вас может быть хорошей записьюименно я сделал этот запрос на обновление, но сам Git этого не делает. Сам Git не имеет никакой аутентификации или авторизации любого рода. Git полагается на какой-либо другой объект для выполнения любой необходимой аутентификации и / или авторизации. Так как кто-то еще делает это - если это вообще делается - Git также оставляет любую запись такой информации этой другой сущности.

2 Технически мой Git просто передает коммит, который имеет no parent, то есть root commit . Так как у него нет родителя, не существует более раннего коммита, который нужно запросить.


Git хранит некоторые собственные журналы

С учетом вышеизложенного - факт, что ваши ветви называют ваши и вы создаете и обновляете их - мы должны отметить, что Git действительно ведет журналы ваших различных ссылок . Эти журналы также ваши, чтобы делать, как вы хотите. Но каждый раз, когда ваш Git обновляет ссылку, он сохраняет предыдущее значение ссылки в «журнале ссылок».

A ref (или ссылка) в Gitявляется обобщением имен ветвей (например, master), имен тегов (например, v2.1), имен удаленного отслеживания (например, origin/master) и т. д. Каждый вид имени по-прежнему просто хранит один хэш-идентификатор, но «вид» имени определяет, как вы будете его использовать.

Имя ветви - это просто ссылка, полное имя которой начинается с refs/heads/. Так что ваш master на самом деле просто ссылка с именем refs/heads/master. Имя тега - это ссылка, полное имя которой начинается с refs/tags/, поэтому v2.1 - это сокращение от refs/tags/v2.1. Имя удаленного отслеживания начинается с refs/remotes/ и включает имя удаленного - origin - и еще одну косую черту, поэтому ваше имя удаленного отслеживания для origin master равно refs/remotes/origin/master.

Всякий раз, когда твой Gitдатирует любое из этих имен, оно сохраняет значение old в reflog для этого имени. Он помещает новое значение в это имя и помещает текущую дату и время в reflog вместе со старым значением.

Это означает, что если вы хотитеЕсли вы знаете, какой хеш-код был у вашего master вчера, вы можете сделать так, чтобы ваш Git просматривал ваш журнал для вашего master. Если оно было обновлено ранее сегодня, есть запись в этом журнале, и это показывает, что вчера у него был тот хэш-идентификатор, который у него был вчера.

Эти записи журнала в конечном итоге истекают и получаютвыбросил. Это очень отличается от коммитов , которые по большей части живут вечно. 3 Также важно помнить, что ваши reflogs ваши . Вы не можете видеть мое.

В Git есть специальная ссылка, записанная HEAD (заглавными буквами), в которой обычно хранится имя ветви , а не необработанный идентификатор хеша. может хранить необработанный хэш-идентификатор;в этом режиме Git говорит, что у вас есть «отсоединенная ГОЛОВА». Но в основном он запоминает название ветви, на которой вы «находитесь» - например, если git status говорит on branch master, это означает, что HEAD содержит внутри себя имя refs/heads/master. Для HEAD существует журнал, в котором хранится необработанный идентификатор хеша, найденный путем следования через имя к базовому хешу коммита.


3 Технически, коммит живет до тех пор, пока выможет найти это. Это делает концепцию достижимости чрезвычайно важной. Подробнее о достижимости см. Think Like (a) Git .


git push на самом деле здесь нечетный случай

Поток коммитов, который я описал вышедля git fetch. Обратите внимание, что git pull означает run git fetch, затем выполните вторую команду Git . Вторая команда Git запускается только в вашем хранилище: ваш fetch получает доступ только для чтения к другому хранилищу Git, получает от него коммиты (и другие данные), а затем обновляет имена для удаленного отслеживания. Команда second - это команда, которая включает новые коммиты в ваши ветки. Мне нравится откладывать эту вторую команду - обычно я хочу посмотреть, что git fetch на самом деле принес , прежде чем принимать какое-либо решение о принятии или не принятии новых коммитов, поэтому я вообще редко использую git pull.

Между тем, ближайшая вещь, противоположная извлечению, - git push. При этом ваш Git вызывает другой Git - обычно под вашим собственным именем, опять же: git push origin означает, что вы хотите, чтобы ваш Git вызывал Git по URL, который ваш Git сохранил под вашим именем origin. После этого ваш Git не получает коммиты от исходного Git. Вместо этого ваш Git отправляет коммиты (и другие объекты) к ним.

Ваш Git скажет: У меня есть коммит 9876543... для вас, у вас его уже есть? Если нет, ваш Git отправит его вам. Если у 9876543... есть родительский a123456..., ваш Git также удостоверится, что у его Git есть a123456..., и так далее. В конце концов, ваш Git достигает коммита, который уже есть у его Git, и ему не нужно его отправлять, или достигает корневого коммита - такого, у которого нет родителя - так что больше нет коммитов для отправки.

Теперь, когдаваш Git отправил в Git все ваши коммиты, которые им не нужны, которые им понадобятся, ваш Git отправляет Git вежливый запрос: Пожалуйста, если все в порядке, установите для master значение9876543.... Это их Git, принять или отклонить этот запрос. Basic Git - в отличие от более популярных версий для продажи от таких людей, как GitHub, Bitbucket и Gitlab, - здесь очень простые правила (хотя вы можете написать свои собственные причудливые). Провайдеры веб-хостинга также обеспечивают аутентификацию пользователей, ведение журналов и т. Д., И они сами могут предоставить вам более эффективный контроль, если вы являетесь администратором. Встроенная проверка Basic Git просто: если я выполню этот запрос, смогу ли я найти коммит с ответвлением ветки, который уже есть в названии?

Этот тест - смогу ли я найти текущий коммит, если я приму этот новый хэш-идентификатор коммита - это проверка, чтобы определить, является ли операция fast forward . Это, опять же, все о достижимости : начиная с 9876543... и работая в обратном направлении через родительские хеш-идентификаторы, могу ли я получить хеш-идентификатор, который у меня есть в имени сейчас? Если имя new , базовый Git просто принимает запрос, а если вежливый запрос на удаление имени, базовый Git просто принимает запрос.

Вы можете изменить этот вежливый запрос напринудительная команда: установите для master значение 9876543...! Они все еще могут отклонить его, но, опять же, основной Git последует за командой. Тест «это ускоренная перемотка» исчезает.

Правила обновления тегов и других имен более просты (но были разбиты до Git 1.8.2): имена тегов просто не могут бытьобновляется без --force, и большинство других имен используют правило имени ветви («это ускоренная перемотка вперед»).

Когда кто-либо использует git push, именно здесь происходит настоящая аутентификация, авторизация,и регистрация должна происходить на принимающей стороне. Basic Git предполагает, что это делает какая-то другая сущность: если вы преодолели какой-либо механизм, который предоставляет транспорт (https или ssh или любой другой), все должно быть хорошо! Если вы используете хостинг-провайдера, он может предоставить .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...