Как стать автором
Обновить

Комментарии 64

Возможно я что-то не так понял в статье, но я считал что git ( в отличии от например svn) хранит не файлы, а изменения сделанные в файле. А если следовать написанному в статье, то получается что он хранит копию каждого состояния файла.
Насколько я могу судить, все таки архивированные объекты.
githowto.com/ru/git_internals_git_directory
Цитата — Смотрим в один из каталогов с именем из 2 букв. Вы увидите файлы с именами из 38 символов. Это файлы, содержащие объекты, хранящиеся в git. Они сжаты и закодированы, поэтому просмотр их содержимого нам мало чем поможет.
Ну я подозреваю что в данном случае под объектом подразумевается набор изменений в файле.
Интересно. Я думал он как и mercurial хранит изменения.

Теперь возникает вопрос: почему git победил svn?
Потому что популярнее. Мне кажется, это единственное что решило. Хотя hg более продуманный как по внутреннему устройству, так и по интерфейсу работы. Вот забавная статья про коаны git.

На мой взгляд потому что нет зависимости от сервера. Недавно узнал что можно клонировать и пушить не только на сервер но и в дирректорию на диске.

Потому что позволяет редактировать данные задним числом, как в 1С.

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


ИМХО git победил svn за счет гениальной организации и отличной и продуманной работы с ветками (до которой далеко тому же hg). Данная статья не описывает даже десятой части того насколько красиво внутри все устроено

git победил svn за счет гениальной организации и отличной и продуманной работы с ветками (до которой далеко тому же hg)
Вот бы еще git научился безболезненно закрывать ветки не удаляя их, как hg, вообще ништяк было бы.

Что в вашем понимании безболезненно закрывать?
git merge позволяет смерджить ветку куда либо и не удаляет ее… это равно закрыть ветку?
Если вы хотите избавится от возможности создавать в ветке новые комиты — создайте тег с тем же именем и удалите ветку. останется зафиксированный тег. ИМХО у вас какой то странный запрос.

Что в вашем понимании безболезненно закрывать?
Чтобы ветка оставалась собой, просто не отображалась в списке текущих, и без всякого шума. А в идеале еще чтобы в нее нельзя было закоммитить без переоткрытия, и чтобы в логе можно было фильтровать отображение промежуточных коммитов закрытых веток.
создайте тег с тем же именем и удалите ветку. останется зафиксированный тег
Я в курсе про такой способ, им и перебиваюсь, но будем честны это просто костыль. Большинство разработчиков используют теги для версионирования, а мелькающие среди версий огрызки веток выглядят ужасно и кустарно.

Если вы не следуете gitflow или похожему подходу, когда одна задача = одна ветка, то скорее всего у вас просто не возникнет такой проблемы.
ИМХО у вас какой то странный запрос.
Настолько странный, что о нем писали сотни раз до меня. В hg это дефолтный способ работы с ветками.
будем честны это просто костыль.

Механизм тегов решает именно ту задачу о которой вы пишете:
1) не отображаются в основном списке веток
2) нельзя комитить в него без явного переоткрытия (создания новой ветки на основе тега)


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

Ничего не мешает создать некий префикс для имен таких тегов и фильтровать по нему. Даже с использованием тегов только для версионирования очень быстро их становятся сотни а значит глазами их никто не читает. Обычный вариант как я пользуюсь командой:


git tag | grep v
Механизм тегов решает именно ту задачу о которой вы пишете
Он решает ее криво (ветка не просто скрыта, ее вообще нет), с побочками в виде мусорных тегов, и это просто неудобно. При этом в истории все равно образуются холмы (пример из интернета) из коммитов «закрытых» веток.
нельзя комитить в него без явного переоткрытия
Почему нельзя? Чекаут по имени тега, внес изменения, закоммитил. Фактически все работает, просто наш тег выполняющий роль головы ветки не двигается на новый коммит, как раз потому что он тег, а не голова ветки. Т.е. мы просто поломали функционал ветки, а не реализовали ее закрытие.
Ничего не мешает создать некий префикс для имен таких тегов и фильтровать по нему.
И как это сделать скажем в гитхабе/битбакките, чтобы посетитель репозитория зайдя в раздел релизов не видел там дохлых веток?
Он решает ее криво, с побочками в виде мусорных тегов, и это просто неудобно.

Чем мусорная закрытая ветка отличается от мусорного тега?


И как это сделать скажем в гитхабе/битбакките, чтобы посетитель репозитория зайдя в раздел релизов не видел там дохлых веток?

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

Чем мусорная закрытая ветка отличается от мусорного тега?
Тем что она не мусорная. Ее не видно там, где ее не должно быть видно, но при этом видно там, где мы ожидаем ее увидеть.
Ну это уже вопрос собственно к гитхабу и битбакету, если они не реализовали подобный функционал значит спрос на него небольшой
А совсем не потому что гит на это не рассчитан, и теги нужны именно для тегов, да. Наверное оно со всеми фичами так, если еще нет — значит и не надо.

Тег это просто метка и постоянный указатель на коммит. За годы развития гита было множество вариантов их использовать. Наиболее популярный из тех что есть сейчас — это использовать теги для версионирования. Но при этом в самом гите на этот счет ничего не сказано и вы имеете все возможности использовать их так как вам удобно. Например в одном из наших workflow мы ставим несколько тегов на один коммит — один тег помечает комит как версию, а еще 2 тега на тот же коммит подписаны людьми ответственными за выпуск релиза и соответственно удостоверяют подписью их согласие на выпуск. Соответственно деплой prod окружения происходит при наличии 3-х тегов а не одного. Соответственно мы используем этот механизм так как это удобно нам. Поэтому я не понимаю почему вы считает что для хранения легаси веток их нельзя использовать только потому что Github не дает вам удобной UI для их просмотра

чтобы ветка не отображалась и нельзя было в нее коммитить, удалите её локально, но оставьте на сервере.
Потомучто github ;)
Сравнимого по функционалу бесплатного хостинга для чего угодно другого нет, КМК.
Это не объясняет почему он github, а не svnhub или даже hghub.
Что первично, курица или яйцо ;)
Так то hg значительно проще в использовании, чем git. И многим его с головой бы хватило. И при наличии бесплатного (для личного пользования) hghub с вебмордой — многи предпочли бы его.
я думаю, что просто «исторически так сложилось». Как показывает практика, далеко не всегда выживает лучший продукт. Достаточно вспомнить историю развития операционных систем )
И при наличии бесплатного (для личного пользования) hghub с вебмордой — многи предпочли бы его.
Был же Bitbucket, аж с 2008 года. Но в 2011 он добавил поддержку git, а в этом году выпилит поддержку самого меркуриала.
Был же Bitbucket, аж с 2008 года


В 2016 году, судя по ссылкам из википедии, в Bitbucket пользователей (hg + git) было в 4 раза меньше, чем у github (git only).
Что-то пошло не так.
Чем-то напоминает delphi
И тем не менее, сама возможность бесплатного юза была, причем с большинством важных фич которые были у гитхаба. Я даже большу скажу, в битбакките можно было бесплатно иметь приватные репозитории, а в гитхабе они тогда были платными. Ну и «четверть от овердофига» это все еще «дофига».
НЛО прилетело и опубликовало эту надпись здесь
Теперь возникает вопрос: почему git победил svn?
думаю основная причина — децентрализация и не зависимость от сервера. Не знаю как сейчас, но в svn до версии 1.7 включительно, без доступа к серверу ты не мог ничего сохранить (закомитить). Т.е. едишь ты в поезде или где то на даче без инета — и все, приехали.

Даже более того, в случае git можно синхронизироваться вообще без сетевого соединения, через git bundle.

Лично я понял как — деревья используются для хранения данные об файлах их иерархическом положении в древе абстрактной файловой системы для корректного воссоздания структуры.
А по факту при коммите формируется, и храниться дельта изменений.
В противном случаи каждый коммит в файл исходного кода, размером в 1 Мб, должен будет порождать его копию (пусть даже и архивную). Чисто эмперическим путем можно увидеть:


  • при первичном коммите файла в 1Мб = коммит имеет большой размер (более 1 Мб), т.к. коммит содержит дельту от "ничего" до 1Мб
  • при следующем коммите (при изменении всего одного символа) мы получаем объем хранимых данных близкий по объему изменений.

"Ох как часто мы принимаем науку за магию" — я сам.
Был не прав в своем понимании.
Действительно хранятся "слепки" файлов. а небольшие изменения в размерах вызваны просто их "архивацией".

В этой статье содержится еще меньше информации, чем в сотне других.

можно хотя бы 2-3, в которых описываются "кишки"?

Автор не увидит ваш комментарий здесь.
От меня: https://git-scm.com/doc

Там ещё упакованный формат хранения в директории objects/pack есть.

Было бы интересно, если бы кто-нибудь написал статью про алгоритм совместной работы нескольких человек над одним проектом в git. Это всем кажется очевидным, но я так толком и не понял, как это делается правильно, чтобы не получился конфликт написанного разными людьми. Им договариваться не трогать модули друг-друга или как? А то Вася впишет в модуль своё, Юра поменяет его идеологию и что тогда получится? Вот как?
Тогда при попытке слияния коммитов Васи и Юры возникнет конфликт слияния (мерж конфликт) и гит попросит решить, что из двух вариантов изменений файла нужно оставить, а что удалить (или же оставить всё).
Разрешение конфликтов слияния — очень частая операция при работе даже двоих людей над одним и тем же кодом.
Когда ситуация разрастается до десятков и больше человек — как вариант решения, назначается ответственный за прием кода в мастер-ветку, он же и решает мерж-конфликты. Хотя это не единственный возможный сценарий решения этой проблемы.
Тогда при попытке слияния коммитов Васи и Юры возникнет конфликт слияния (мерж конфликт) и гит попросит решить, что из двух вариантов изменений файла нужно оставить, а что удалить (или же оставить всё).


Правильно. И получится нерабочий код. Юра трогал не только общий модуль. Вася поступил так же. И арбитр замучается выяснять, что можно слить, а чего нельзя. Это-то и беспокоит.

В большинстве случаев слияние тривиально.


В меньшинстве случаев либо Вася, либо Юра берут обновлёный код и делают те же самые изменения, которые делали ранее.


Ну и проверку получившегося кода никто не отменял.

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

https://m.habr.com/ru/post/75990/ — как-то так. Информацию по настройке можете пропустить.

О, спасибо! То, что нужно.
> договариваться не трогать модули друг-друга
в точку.
Это же как раз одна из фич git — возможность нормальной работы нескольких человек над одним файлом. Насколько помню, в svn и SourceSafe при чекауте просто лочился файл и привет — жди, пока отпустят.

Это в SourceSafe было. В svn изменения в текстовых файлах тоже сливаются.

С таким переводом xkcd — спасибо, не надо. Почему "запомни", а не "запомнил"?

Кол-во файлов в 255 раз меньше? Как так?

они же по папкам раскладываются от 00 до ff

От разкладывания по 255 папкам кол-во файлов уменьшается в 255 раз? Серьёзно?

В среднем в одной директории становится в 256 раз меньше файлов. Кстати, если файлов будет слишком много, то возможно дальнейшее распихивание по директориям: objects/aa/bb/... и т.д.


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

да все верно, отличный комментарий!
Я не спрашивал про цель, она очевидна. Я усомнился в конкретном утверждении: «Этот маленький трюк в 255 раз уменьшает количество файлов в папке /objects». Вы увидели тут слова «в среднем в одной директории», а я почему-то увидел «в папке /objects». Так может, лучше просто признать косяк?
Я не вижу здесь косяка, но я поменял текст чтобы было меньше разночтений.

Это очевидный косяк, потому что в папке /objects кол-во файлов не изменилось вообще, а лишь добавились промежуточные директории. И разночтений тут быть не может.

От разкладывания по 255 папкам кол-во файлов уменьшается в 255 раз? Серьёзно?

файлы раскладываются по папкам — в каждой папке меньше файлов чем было бы если бы не раскладывали. Серьезно.
«Этот маленький трюк в 255 раз уменьшает количество файлов в папке /objects» — вы считаете, что «папка /objects» это недостаточно чёткое определение?

Вопрос трактовки.
"количество файлов в папке" может означать количество файлов в папке как с учетом файлов во вложенных папках, так и без учета.
Регулярно встречаю как первое, так и второе в интерфейсе программ, всяких руководствах и книгах.
Если имеется ввиду первое, то оспариваемое утверждение неверно, если второе, то верно.

Если второе, то в папке objects нет ни одного файла и от 1 до 255 других папок 00-ff. То есть, оспариваемое утверждение неверно никогда.

"Этот маленький трюк", о последствиях которого спор, уменьшает количество файлов в папке /objects до количества вложенных папок (каждая из которых тоже файл). Если бы не трюк, то все файлы из подпапок валялись бы непосредственно в папке /objects.
Кстати, уменьшение количества файлов начинается не сразу. На начальном этапе в каждой подпапке получается по одному файлу, а потому никакого выигрыша нет.

Вот именно, что до количества вложенных папок, а не в 255 раз. То есть, в первоначальном тексте был явный косяк, о чем я и написал. И был прав.

Ссылка вроде бы годная, но мне кажется, что за 15 лет в обоих программах много чего могло поменяться в плане производительности и алгоритмов компрессии.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий