При работе с git в команде, использующей ветви функций, мне часто трудно понять структуру ветвей в истории.
Пример:
Допустим, была ветка Feature / Make-Coffee , и исправление ошибок продолжалось на master параллельно с веткой Feature.
История может выглядеть так:
* merge feature/make-coffee
|\
| * small bugfix
| |
* | fix bug #1234
| |
| * add milk and sugar
| |
* | improve comments
| |
* | fix bug #9434
| |
| * make coffe (without milk or sugar)
| |
* | improve comments
|/
*
проблема
На первый взгляд, мне трудно сказать, с какой стороны находится ветвь функции. Мне обычно нужно просмотреть несколько комментариев с обеих сторон, чтобы понять, что есть что. Это становится более сложным, если есть несколько ветвей объектов параллельно (особенно если они предназначены для тесно связанных объектов), или если произошло объединение в обоих направлениях между ветвью объекта и мастером.
В отличие от этого, в Subversion это значительно проще, потому что имя ветки является частью истории, поэтому я могу сразу сказать, что изначально была сделана фиксация на «feature / make-coffee».
Git может упростить эту задачу, включив имя текущей ветви в метаданные коммита при создании коммита (вместе с автором, датой и т. Д.). Однако git этого не делает.
Есть ли какая-то фундаментальная причина, почему это не сделано? Или это просто, что никто не хотел эту функцию? Если это последнее, есть ли другие способы понять цель исторических ветвей, не видя названия?
Ответы:
Возможно, потому что имена ветвей имеют смысл только в одном хранилище. Если я в
make-coffee
команде и отправляю все свои изменения через привратник, мояmaster
ветвь может быть перетащена в ветвь привратникаmake-coffee-gui
, которую он объединит со своейmake-coffee-backend
ветвью, прежде чем перейти кmake-coffee
ветке, которая объединится с центральнойmaster
ветвью.Даже в одном репозитории имена ветвей могут изменяться и изменяться по мере развития вашего рабочего процесса.
master
может позже изменитьсяdevelopment
, например, на вызов .Как отмечал CodeGnome, у git есть сильная философия дизайна, заключающаяся в том, чтобы не запекать что-либо в данные, если это не нужно. Ожидается, что пользователи будут использовать параметры
git log
иgit diff
выводить данные по своему усмотрению после факта. Я рекомендую попробовать, пока вы не найдете формат, который работает лучше для вас.git log --first-parent
Например, не будет отображать коммиты из ветки, в которой происходит слияние.источник
Отслеживание истории веток с помощью
--no-ff
В Git коммит имеет предков, но «ветвь» на самом деле является просто текущим руководителем некоторой линии разработки. Другими словами, коммит является моментальным снимком рабочего дерева в определенный момент времени и может принадлежать любому количеству ветвей одновременно. Это часть того, что делает ветвление Git таким легким по сравнению с другими DVCS.
Коммиты Git не несут информацию о ветвях, потому что они не нужны для истории Git. Тем не менее, слияния, которые не являются ускоренными, могут, безусловно, содержать дополнительную информацию о том, какая ветвь была объединена. Вы можете убедиться, что ваша история содержит эту информацию, всегда передавая
--no-ff
флаг вашим слияниям. git-merge (1) говорит:Как правило, это создает сообщение о слиянии, подобное тому
Merge branch 'foo'
, что вы можете найти информацию о «ветвях предков» со строкой, подобной следующей:источник
git log --merges
.Самый простой ответ заключается в том, что названия ветвей эфемерны. Что если вы скажете переименовать ветку (
git branch -m <oldname> <newname>
)? Что будет со всеми коммитами против этой ветки? Или что, если два человека имеют филиалы с одинаковыми именами в разных локальных репозиториях?Единственное, что имеет значение в git - это контрольная сумма самого коммита. Это основная единица отслеживания.
Информация есть, вы просто не просите об этом, и его не совсем там.
Git хранит контрольную сумму главы каждого филиала в
.git/refs/heads
. Например:(да, я коплю свои контрольные суммы мерзавцев, они не особенные, но они являются частными репозиториями, на которые я смотрю в тот момент, когда не нужно ничего случайно сообщать).
Просматривая это и отслеживая каждый коммит, который имеет это как родитель, или родительский родитель или родительский родитель ... вы можете узнать, в каких ветвях находится данный коммит. Это просто большой график для рендеринга.
Хранение, где конкретно имя ветви (которая может измениться, как упомянуто выше) в коммите, находится в самом коммите, это дополнительные издержки на коммите, которые ему не помогают. Сохраните родительский (ые) коммит и его товар.
Вы можете увидеть ветви, выполнив команду git log с соответствующим флагом.
Есть много разных способов выбрать то, что вы хотите для этого - посмотрите документацию git log -
-all
раздел и несколько опций, которые следуют.Эти 'test', 'test1' и 'test2' являются ветвями, которым они были посвящены.
Обратите внимание, что документация журнала git огромна, и вполне возможно получить из нее практически все, что вы захотите.
источник
Почему коммиты git не содержат название ветки, на которой они были созданы?
Просто дизайнерское решение. Если вам нужна эта информация, вы можете добавить ловушку prepare-commit-msg или commit-msg, чтобы применить ее к одному репозиторию.
После аварии на BitKeeper Линус Торвальдс разработал git, соответствующий процессу разработки ядра Linux. Там, пока патч не принят, он пересматривается, редактируется, полируется несколько раз (все через Mail), подписывается (= редактирование коммита), выбирается вишня, бродит по ветвям лейтенанта, может быть, часто перебазируется, больше правок, вишня -выборы и так далее, пока они окончательно не слились вверх по течению от Линуса.
В таком рабочем процессе может не быть определенного источника коммита, и часто коммит просто создается в какой-то временной ветке отладки в каком-то неважном частном случайном репозитории с забавными именами ветвей, когда распространяется git.
Возможно, это дизайнерское решение произошло случайно, но оно точно соответствует процессу разработки ядра Linux.
источник
Потому что в Git коммиты типа "сделать кофе" считаются частью обеих ветвей, когда ветка функции объединяется. Есть даже команда, чтобы проверить это:
Кроме того, филиалы дешевые, местные и эфирные; их можно легко добавлять, удалять, переименовывать, отправлять и удалять с сервера.
Git следует принципу все можно сделать, поэтому вы можете легко удалить ветку с удаленного сервера и переписать историю.
Допустим, я был в ветке «master» и сделал два коммита: «сделай кофе» и «добавь молоко и сахар», затем я решил использовать для этого новую ветку, поэтому я вернул «master» обратно в «origin» /мастер'. Не проблема, вся история по-прежнему чиста: «варить кофе» и «добавлять молоко и сахар» не являются частью мастера, только функция / приготовление кофе.
Mercurial - это противоположность; он не хочет ничего менять. Ветви постоянны, история переписывания осуждается, вы не можете просто удалить ветку с сервера.
Вкратце: Git позволяет вам делать все, Mercurial хочет упростить задачу (и делает действительно трудным позволить вам делать то, что вы хотите).
источник