Comments 43
Основное отличие jj от Git cостоит в том, что история коммитов представляет из себя последовательность патчей, а не snapshot-ов.
Вообще-то в гите история коммитов логически тоже представляет из себя последовательность патчей. Это только на уровне хранения они снапшоты.
Насколько понял из описания, суть jj
в том, что если у коммита поменять родителя - то это все еще будет тот же коммит. В отличие от git
, где это уже новый коммит с новым хешем.
Поэтому обычно как раз-таки удобнее считать коммиты в git не патчами, а именно снепшотами. Один хеш - одно состояние кода.
Но тогда получается Mercurial, который Git, но с хранением метаинформации и неизменным хэшем, со всеми вытекающими плюсами и минусами. И JJ превращается в велосипед.
Что-то подобное было реализовано в Darcs. Но на больших репозиториях он еле шевелился, был весьма прожорливым по памяти и при слияниях часто получалась каша. Если в jj смогли решить проблемы, то это неплохой апгрейд для велосипеда.
Не думаю что в Darcs программе использующей теорию патчей за 20 лет развития не смогли решить, а в программе не доросшей до 1.0, не справившейся с банальной ошибкой ssh, вдруг смогли решить.
Это как раз не связанные вещи: починить ssh — дело сил и времени, а реализовать алгоритм с меньшей сложностью требует исследований, особенно если оные покажут, что вообще всю модель надо по-другому делать.
Кстати, нижеупомянутый pijul вышел позже darcs и, как говорят разработчики этих систем, он следовал теории чище и из-за этого кое-какие проблемы darcs решаются сами собой.
Естественно, это не касается jj, которая, как мне показалось, ставило во главу угла совместимость с git, а не наличие хорошей подлежащей модели.
При этом для git до сих пор нет полнофункционального бесплатного кроссплатформенного gui клиента, такого как TortoiseHG. Хотя о git знают все, он везде в требованиях а о Mercurial знают единицы.
Любая современная IDE подойдет как GUI?
Ну, как бы есть несколько платных клиентов, которые могут работать бесплатно практически со всем функционалом. Тот же GitKraken это космический корабль на все случаи жизни даже в бесплатной версии. И он вполне кросс-платформанный.
SmartGit, GitKraken, GitButler, GitHub Desktop, Gittyup, Sourcetree, Gitnuro, и еще кто знает сколько менее известных.
Sublime merge)
Открываю сайт первого же из списка SmartGit, да есть под все основные системы, однако вижу Purchase - он не бесплатен. А TortoiseHg полностью бесплатен и ставится из репозиториев в считанные секунды.
однако вижу Purchase - он не бесплатен
Он бесплатен с полным функционалом для некоммерческого использования. Ставится за считанные секунды и при первом запуске нажимается одна галочка. У GitKraken бесплатный фунционал ограничен, но достаточен для 99% случаев. У SourceTree не помню, сайт alternativeto пишет что бесплатная версия есть. Остальные перечисленные бесплатны полностью и в добавок опенсорсны.
Есть fork. Он условно платный, но на самом деле просто иногда всплывает окно с просьбой задонатить. А в целом, полноценное приложение
В статье очень мало внимания уделено сути. Даже на скриншоте видно что у каждого коммита есть два хеша - один, который слева, не меняется при внесении изменений. Справа - обычный из гита, который меняется. Они имеют разный формат, например нулевой коммит это и zzz и 0000
Я не стал в статье погружаться в детали реализации. Есть интересное видео с живыми примерами использования https://www.youtube.com/watch?v=2otjrTzRfVk. Есть отличная документация. Мне было важно пояснить, чем jj лучше или хуже Git.
Пробовал эту штуку некоторое время. Выглядит как просто чуть более человечный гит - навигация по истории несколько проще, всякая автоматизация из коробки, смена веток и управление рабочим деревом проще, резолв конфликтов при мерже/ребейзе проще из-за этого. При этом работает поверх гита. Самая большая разница в отношении к изменениям. Есть неплохая вводная про то как с этим работает jj (листать к секции obslog)
Всё с точностью до наоборот: логически git представляет собой граф снапшотов (деревьев), а вот реализация использует pack files.
pack files не имеют никакого отношения к последовательности патчей, это просто способ сжатия.
В отличии от патчей, на pack files никак не влияют ни настройки LF/CRLF, ни настройки отображения пробельных символов, ни настройки логического сравнения файлов.
Ну я вроде обратного и не утверждал? Последовательность патчей это вообще не про git, а pack files я привёл только из-за упоминания патчей в Вашем комментарии. Т. к. они хранят дельту, они ближе всего к понятию патчей, но это всего лишь деталь реализации, связанная с оптимизацией. Можно легко представить git без оптимизации, где вообще дельты не хранятся ни в каком виде.
То, что вам показывают в формате git log -p или аналога дифф в случае одного родителя - оптимизация усилий на типовой случай. Уже при merge это не показывается, надо явно запрашивать.
А на Habr писали уже про post-git VCS типа Pijul и Fossil SCM? Как я понял Jujutsu тоже основана на Patch theory но нигде ещё не видел сравнения этих трех VCS.
О Pijul https://habr.com/ru/articles/785904/ от @samsergey
Fossil - это не post-git. Да, это коробочное решение «все-в-одном»: wiki, issue tracker и, собственно, SCM. Да, есть какие-то улучшения благодаря использованию SQLite в качестве стораджа. Но концепция SCM там всё-же очень близка к Git: цепочки снапшотов.
Особенно не приятно, что в Fossil нет ребейзов веток. Ричард Хипп говорит, что в компании (разрабатывающей SQLite3) ребейзы объявлены вредными, и потому в Fossil они не реализованы. Это удерживает меня от экспериментов с Fossil, т.к. на примере некоторых old-school открытых проектов я вижу пользу линейной истории главной ветки.
А в чём эта польза выражается? (не спец, особо пока git не пользовался, в основном копил последовательность патчей, то есть обычные патчи: снизу вверх, а не сверху вниз как вроде бы хранит git.
Пользователь: ищет что-то про Jujutsu
Поисковик: Kaisen?
Натыкался на этот jj весной в поисках идей для своей DVCS. Увы, при том же гите как формате хранения ничего инновационного там архитектурно нет и быть не может - так, только CLI-удобства какие...
Основная проблема
jj
такая же как у Mercurial, Bazaar и прочих — они не Git. Многие уже подсели на Github/Gitlab и не могут легко переключиться наjj
. Инструменты и инфраструктура вокруг Git делают его стандартом для индустрии.
И это, собственно, ключевой момент, который не понимает автор статьи - использование чего-то в качестве "стандарта" не отменяет ни других средств, ни исследований в этой области, которые со временем победят, если сумеют предложить что-то действительно новее и лучше. Двадцать лет назад таким "стандартом" для приложений была Windows - всё, нету этого, теперь Web, облака и мобилы. Еще через 20 лет и это перестанет быть стандартом, и т.д.
Интересно, но не практично. git стал отраслевым стандартом, с ним все умеют работать, куча инструментов под него заточено. Лучшие (в теории) альтернативы просто не могут в таких условиях существовать.
Многие уже подсели на Github/Gitlab и не могут легко переключиться на
jj
. Инструменты и инфраструктура вокруг Git делают его стандартом для индустрии.
Вы ведь сами сказали тут:
Поддерживает чтение и запись в Git remote. Можете попробовать импортировать свой pet-project и поиграться с коммитами
что jj может работать с git.
Поэтому это решает проблему зависимости от инфраструктуры git.
Кажется, слишком много коней и людей смешались в одной куче.
Основное отличие
jj
от Git состоит в том, что история коммитов представляет из себя последовательность патчей, а не snapshot-ов.
В Git получить патч между коммитами-снапшотами не просто, а очень просто. Но любой патч будет содержать контекстно-зависимые данные - например, номера строк. Пусть в ветке v12 перед местом патча добавили 30 строк. Патч для v12 будет начинаться со строки 199, а для v11 начинался со 169. Это один и тот же патч, или разные? А если со 169 другое место для применения с тем же контекстом (патч ложится ровно)?
Идея взята из Darcs. Такой подход позволяет легко переписывать историю коммитов,
Не влияет.
rebase становится тривиальным,
Не становится. Те же проблемы наложения при изменении контекста.
коммиты (патчи) можно спокойно перемещать между ветками,
Не влияет.
конфликтов меньше (автоматическое разрешение конфликтов работает лучше, чем в Git или Mercurial).
Если стало работать лучше, то изменено что-то в этом самом методе автоматического разрешения конфликтов, а не в базе самого движка.
И вот это интересно - может быть применено везде.
Edit: не в ту ветку, отвечал на вопрос @event1
Решается две проблемы пользователей:
Редактирование истории в гите довольно запутано. Пользоваться git rebase/git cherry-pick может быть довольно тяжело. Или условно: разделить коммит в середине длинной ветки на два.
Работа со stash и другими грязными изменениями. В гите требуется вручную разобраться со всеми незакоммиченными изменениями, прежде чем выйдет переключиться на другую ветку (например, быстро глянуть, а что там на мастере)
Итого, jj делает редактирование истории более доступным.
Ну и в целом, семантическая модель «коммитов» jj гораздо ближе к представлению большинства пользователей, чем семантическая модель в гите. Чаще всего, люди плохо себе представляют, что происходит с графом коммитов, когда мы, например, удаляем один коммит из середины истории. Многие не понимают (на уровне интуиции), зачем нужен git gc.
Был какой-то симулятор/обучалка гита, в котором была визуализация всего графа коммитов. По опыту, когда люди в ней делали git rebase - они думали, что всё сломалось.
P.S. Рассуждения про семантическую модель основаны на малой выборке, а потому субъективны. Будет интересно соотнести их с опытом других людей.
P.P.S. Две проблемы обозначенные вначале - объективны.
Редактирование истории в гите довольно запутано. Пользоваться git rebase/git cherry-pick может быть довольно тяжело.
Хм, по-моему, оно становится тривиально понятным, если разобраться, что же вообще происходит с историей и почему она редактируется именно в виде последовательности патчей. Дальше начинает влиять собственно объективная сложность процесса - которая тут может быть достаточно заметна и от которой хотят уйти те, кто просто хотят думать по принципу "вот это состояние работает, а дальше мне лень".
Или условно: разделить коммит в середине длинной ветки на два.
То же самое. Да, тут надо наперёд сообразить, где делить, и какой командой затем получить изменения для деления. `git status` помогает найти следующий коммит, в стиле:
Next commands to do (6 remaining commands):
pick f253d4cd Track file times in both subspools
а git restore - применить его изменения без коммита. А затем разобраться, какую именно часть действий вложить в индекс - вот тут можно запутаться, если оно слишком перемешано. Увы.
Работа со stash и другими грязными изменениями. В гите требуется вручную разобраться со всеми незакоммиченными изменениями, прежде чем выйдет переключиться на другую ветку (например, быстро глянуть, а что там на мастере)
Это "вручную разобраться" это одна команда stash (можно добавить -a, чтобы вообще всё вкинуло в сохранение). Ну или коммит всего. И то требуется, если надо получить дерево состояния того же мастера, а не просто список коммитов - для последнего и переключаться не надо. Объективно, два разных файловых дерева не могут лежать в одном каталоге, или вы не согласны? Кстати, не помню названия, но для быстрого переключения всем деревом был плагин с компактными командами.
Многие не понимают (на уровне интуиции), зачем нужен git gc.
Ну так для них есть автомат, который запускает gc через какой-то объём действий.
Чаще всего, люди плохо себе представляют, что происходит с графом коммитов, когда мы, например, удаляем один коммит из середины истории.
Хм, я не очень любитель читать документацию, но, по-моему, там совершенно тривиально. Что именно в этом можно не понять?
Две проблемы обозначенные вначале - объективны.
Если и так, то они минимально связаны конкретно с Git.
Не вполне понятно какую проблему решает это нововведение. Альтернативная техника хранения изменений — это хорошо, но если не решается никакая проблема пользователей, то зачем это?
Аналогия напрашивается скорее с меркуриалом, и сравнения хотелось бы с ним.
Jujutsu — новая система контроля версий