Кому нужная новая VCS, когда уже есть Git, Mercurial, SVN, Perforce, Darcs и прочие? Автор проекта Jujutsu считает, что ещё есть куда совершенствоваться. Знакомьтесь — Martin von Zweigbergk из Google работает над проектом Jujutsu, или для краткости jj
.
Плюсы:
Невероятно гибкая работа с коммитами и ветвлением. Основное отличие jj
от Git cостоит в том, что история коммитов представляет из себя последовательность патчей, а не snapshot-ов. Идея взята из Darcs. Такой подход позволяет легко переписывать историю коммитов, rebase становится тривиальным, коммиты (патчи) можно спокойно перемещать между ветками, конфликтов меньше (автоматическое разрешение конфликтов работает лучше, чем в Git или Mercurial).
Например, у вас есть история коммитов, но один коммит «Create file A» не должен быть в истории. Подход jj состоит в том, что все коммиты после «плохого» нужно переместить (rebase) на «Initial commit». Для этого нужно поменять ссылку на родителя командой jj rebase -s yyltlwtl --destination krpsnnrr
.
Если в качестве родительского коммита указать не один, а 2 и более, то jj
смержит эти ветки. Случайно смержили не ту ветку? Ничего страшного. Сделайте rebase, указав только одного родителя, тем самым отменив слияние веток.
Можете переключится на старый коммит, поменять файлы, изменить комментарий, а затем вернуться к самому свежему коммиту. Изменения в истории автоматически подтянутся.
Отмена любого действия. Все изменения в репозитории можно откатить. Есть как простой jj undo
так и полная история ваших действий над репозиторием jj op log
.
Поддерживает чтение и запись в Git remote. Можете попробовать импортировать свой pet-project и поиграться с коммитами
Написан на Rust. Это заметно по скорости работы и простоте установки: скачиваете один бинарник и прописываете его в PATH. Правда из-за этого возникает проблема с GIT+SSH. Об этом ниже.
Консоле-ориентированность. Утилита jj делает работу в консоли приятной. История коммитов выглядит красиво. jj diff
удобно подсвечивает изменения файлов прямо в консоли.
Минусы:
Отсутсвие аналога git stage. Все изменения в файлах рабочей копии автоматически коммитятся. Нельзя закоммитить часть локальных изменений, оставив другие изменения висеть в рабочей копии. Авторы jj
рекомендуют создать отдельную private ветку, запретив её заливать на сервер. Все локальные изменения нужно делать в private ветке, сливая её с последним коммитом, и отменяя merge перед отправкой на сервер.
Непонятно, какой flow использовать. Можно продолжать использовать git flow. Но думаю стоит изобрести новые более гибкие правила для работы с ветками, фичами и релизами в jj
.
Нет поддержки private key авторизации через SSH. Jujutsu не используется OpenSSH, установленный в системе. Вместо этого jj
слинкован с libgit2. Поэтому он игнорирует ~/.ssh/config
. По этому поводу есть issue в Github.
Нет поддержки git submodules. Но у разработчиков есть план, как их добавить.
Jujutsu ещё не добрался до версии 1.0, но уже смог удивить своими идеями и подходом к VCS. Определённо стоит попробовать, хотябы для личного пользования. Основная проблема jj
такая же как у Mercurial, Bazaar и прочих — они не Git. Многие уже подсели на Github/Gitlab и не могут легко переключиться на jj
. Инструменты и инфраструктура вокруг Git делают его стандартом для индустрии.
Комментарии (39)
kresh
30.10.2024 15:55А на Habr писали уже про post-git VCS типа Pijul и Fossil SCM? Как я понял Jujutsu тоже основана на Patch theory но нигде ещё не видел сравнения этих трех VCS.
funny_falcon
30.10.2024 15:55Fossil - это не post-git. Да, это коробочное решение «все-в-одном»: wiki, issue tracker и, собственно, SCM. Да, есть какие-то улучшения благодаря использованию SQLite в качестве стораджа. Но концепция SCM там всё-же очень близка к Git: цепочки снапшотов.
Особенно не приятно, что в Fossil нет ребейзов веток. Ричард Хипп говорит, что в компании (разрабатывающей SQLite3) ребейзы объявлены вредными, и потому в Fossil они не реализованы. Это удерживает меня от экспериментов с Fossil, т.к. на примере некоторых old-school открытых проектов я вижу пользу линейной истории главной ветки.
seyko2
30.10.2024 15:55А в чём эта польза выражается? (не спец, особо пока git не пользовался, в основном копил последовательность патчей, то есть обычные патчи: снизу вверх, а не сверху вниз как вроде бы хранит git.
khajiit
30.10.2024 15:55В линейной истории проще разобраться, чем в многомерной макаронине, множество раз пересекающейся сама с собой.
nuclight
30.10.2024 15:55Натыкался на этот jj весной в поисках идей для своей DVCS. Увы, при том же гите как формате хранения ничего инновационного там архитектурно нет и быть не может - так, только CLI-удобства какие...
Основная проблема
jj
такая же как у Mercurial, Bazaar и прочих — они не Git. Многие уже подсели на Github/Gitlab и не могут легко переключиться наjj
. Инструменты и инфраструктура вокруг Git делают его стандартом для индустрии.И это, собственно, ключевой момент, который не понимает автор статьи - использование чего-то в качестве "стандарта" не отменяет ни других средств, ни исследований в этой области, которые со временем победят, если сумеют предложить что-то действительно новее и лучше. Двадцать лет назад таким "стандартом" для приложений была Windows - всё, нету этого, теперь Web, облака и мобилы. Еще через 20 лет и это перестанет быть стандартом, и т.д.
Panzerschrek
30.10.2024 15:55Интересно, но не практично. git стал отраслевым стандартом, с ним все умеют работать, куча инструментов под него заточено. Лучшие (в теории) альтернативы просто не могут в таких условиях существовать.
KaiKristo
30.10.2024 15:55В истории полно инструментариев позиции которых казались незыблемыми. Помню кто-то мне заливал, что зачем что-то еще, когда есть borland с++ builder
feelamee
30.10.2024 15:55Многие уже подсели на Github/Gitlab и не могут легко переключиться на
jj
. Инструменты и инфраструктура вокруг Git делают его стандартом для индустрии.Вы ведь сами сказали тут:
Поддерживает чтение и запись в Git remote. Можете попробовать импортировать свой pet-project и поиграться с коммитами
что jj может работать с git.
Поэтому это решает проблему зависимости от инфраструктуры git.
netch80
30.10.2024 15:55Кажется, слишком много коней и людей смешались в одной куче.
Основное отличие
jj
от Git состоит в том, что история коммитов представляет из себя последовательность патчей, а не snapshot-ов.В Git получить патч между коммитами-снапшотами не просто, а очень просто. Но любой патч будет содержать контекстно-зависимые данные - например, номера строк. Пусть в ветке v12 перед местом патча добавили 30 строк. Патч для v12 будет начинаться со строки 199, а для v11 начинался со 169. Это один и тот же патч, или разные? А если со 169 другое место для применения с тем же контекстом (патч ложится ровно)?
Идея взята из Darcs. Такой подход позволяет легко переписывать историю коммитов,
Не влияет.
rebase становится тривиальным,
Не становится. Те же проблемы наложения при изменении контекста.
коммиты (патчи) можно спокойно перемещать между ветками,
Не влияет.
конфликтов меньше (автоматическое разрешение конфликтов работает лучше, чем в Git или Mercurial).
Если стало работать лучше, то изменено что-то в этом самом методе автоматического разрешения конфликтов, а не в базе самого движка.
И вот это интересно - может быть применено везде.
event1
30.10.2024 15:55Не вполне понятно какую проблему решает это нововведение. Альтернативная техника хранения изменений — это хорошо, но если не решается никакая проблема пользователей, то зачем это?
leadraven
30.10.2024 15:55Аналогия напрашивается скорее с меркуриалом, и сравнения хотелось бы с ним.
mayorovp
Вообще-то в гите история коммитов логически тоже представляет из себя последовательность патчей. Это только на уровне хранения они снапшоты.
iliazeus
Насколько понял из описания, суть
jj
в том, что если у коммита поменять родителя - то это все еще будет тот же коммит. В отличие отgit
, где это уже новый коммит с новым хешем.Поэтому обычно как раз-таки удобнее считать коммиты в git не патчами, а именно снепшотами. Один хеш - одно состояние кода.
Sap_ru
Но тогда получается Mercurial, который Git, но с хранением метаинформации и неизменным хэшем, со всеми вытекающими плюсами и минусами. И JJ превращается в велосипед.
funca
Что-то подобное было реализовано в Darcs. Но на больших репозиториях он еле шевелился, был весьма прожорливым по памяти и при слияниях часто получалась каша. Если в jj смогли решить проблемы, то это неплохой апгрейд для велосипеда.
fuggy
Не думаю что в Darcs программе использующей теорию патчей за 20 лет развития не смогли решить, а в программе не доросшей до 1.0, не справившейся с банальной ошибкой ssh, вдруг смогли решить.
questpc
При этом для git до сих пор нет полнофункционального бесплатного кроссплатформенного gui клиента, такого как TortoiseHG. Хотя о git знают все, он везде в требованиях а о Mercurial знают единицы.
Misteg
Любая современная IDE подойдет как GUI?
Sap_ru
Разные IDE работают по-разному. А иногда нужно с репозиторем, непривязанным к языку работать. Я сильно не люблю встроенное в IDE. Лень то всё запоминасть. Поэтому пользуюсь или консолью или GitKraken если нужно удобно с историей поработать.
Sap_ru
Ну, как бы есть несколько платных клиентов, которые могут работать бесплатно практически со всем функционалом. Тот же GitKraken это космический корабль на все случаи жизни даже в бесплатной версии. И он вполне кросс-платформанный.
playermet
SmartGit, GitKraken, GitButler, GitHub Desktop, Gittyup, Sourcetree, Gitnuro, и еще кто знает сколько менее известных.
monah_tuk
Sublime merge)
questpc
Открываю сайт первого же из списка SmartGit, да есть под все основные системы, однако вижу Purchase - он не бесплатен. А TortoiseHg полностью бесплатен и ставится из репозиториев в считанные секунды.
playermet
Он бесплатен с полным функционалом для некоммерческого использования. Ставится за считанные секунды и при первом запуске нажимается одна галочка. У GitKraken бесплатный фунционал ограничен, но достаточен для 99% случаев. У SourceTree не помню, сайт alternativeto пишет что бесплатная версия есть. Остальные перечисленные бесплатны полностью и в добавок опенсорсны.
Zukomux
Есть fork. Он условно платный, но на самом деле просто иногда всплывает окно с просьбой задонатить. А в целом, полноценное приложение
sergio_nsk
Это на что ответ, что такое "он"?
mayorovp
fork - это название
sergio_nsk
Спасибо. А тот пост неуча, названия/имена собственные ведь пишутся с большой буквы.
x4x7
В статье очень мало внимания уделено сути. Даже на скриншоте видно что у каждого коммита есть два хеша - один, который слева, не меняется при внесении изменений. Справа - обычный из гита, который меняется. Они имеют разный формат, например нулевой коммит это и zzz и 0000
sheknitrtch Автор
Я не стал в статье погружаться в детали реализации. Есть интересное видео с живыми примерами использования https://www.youtube.com/watch?v=2otjrTzRfVk. Есть отличная документация. Мне было важно пояснить, чем jj лучше или хуже Git.
domix32
Пробовал эту штуку некоторое время. Выглядит как просто чуть более человечный гит - навигация по истории несколько проще, всякая автоматизация из коробки, смена веток и управление рабочим деревом проще, резолв конфликтов при мерже/ребейзе проще из-за этого. При этом работает поверх гита. Самая большая разница в отношении к изменениям. Есть неплохая вводная про то как с этим работает jj (листать к секции obslog)
ixSci
Всё с точностью до наоборот: логически git представляет собой граф снапшотов (деревьев), а вот реализация использует pack files.
mayorovp
pack files не имеют никакого отношения к последовательности патчей, это просто способ сжатия.
В отличии от патчей, на pack files никак не влияют ни настройки LF/CRLF, ни настройки отображения пробельных символов, ни настройки логического сравнения файлов.
ixSci
Ну я вроде обратного и не утверждал? Последовательность патчей это вообще не про git, а pack files я привёл только из-за упоминания патчей в Вашем комментарии. Т. к. они хранят дельту, они ближе всего к понятию патчей, но это всего лишь деталь реализации, связанная с оптимизацией. Можно легко представить git без оптимизации, где вообще дельты не хранятся ни в каком виде.
netch80
То, что вам показывают в формате git log -p или аналога дифф в случае одного родителя - оптимизация усилий на типовой случай. Уже при merge это не показывается, надо явно запрашивать.