Якщо я правильно їх розумію (і я далеко не експерт по кожному), вони принципово мають різну філософію. Я вперше застосував ртутний 9 місяців. Зараз я використав git для 6.
hg - це програмне забезпечення для управління версіями. Головною метою є відстеження версій програмного забезпечення.
git - файлова система, заснована на часі. Його мета - додати ще один вимір до файлової системи. Більшість мають файли та папки, git додає часу. Те, що трапляється чудово працювати як VCS, є побічним продуктом його дизайну.
У hg є історія всього проекту, яку завжди намагаються підтримувати. За замовчуванням я вважаю, що hg бажає всіх змін усіх об'єктів усіма користувачами при натисканні та потягуванні.
У git є лише пул об’єктів і ці файли відстеження (гілки / голови), які визначають, який набір цих об'єктів представляє дерево файлів у певному стані. Під час натискання чи витягування git надсилає лише ті предмети, необхідні для конкретних гілок, які ви штовхаєте чи тягнете, що є невеликим підмножиною всіх об'єктів.
Що стосується git, то немає "1 проекту". У вас може бути 50 проектів, все в тому ж репо, і git не хвилює. Кожним з них можна було керувати окремо в одному репо і жити чудово.
Концепція гілок Hg - це відгалуження основного проекту або відгалуження гілок тощо. У Git немає такої концепції. Гілка в git - це лише стан дерева, все - гілка в git. Яка галузь є офіційною, нинішньою чи новітньою, не має значення у git.
Я не знаю, чи це мало сенс. Якби я міг намалювати картинки, hg може виглядати приблизно так, де кожен фільтр - цеo
o---o---o
/
o---o---o---o---o---o---o---o
\ /
o---o---o
Дерево з єдиним коренем і гілками, що відходять від нього. Хоча git може це зробити, і часто люди використовують це таким чином, який не застосовується. Гіт-картина, якщо є така річ, може легко виглядати так
o---o---o---o---o
o---o---o---o
\
o---o
o---o---o---o
Насправді в чомусь навіть не має сенсу показувати гілки в git.
Одне, що дуже заплутано для обговорення, git та mercurial мають щось, що називається "гілка", але вони віддалено не є одними і тими ж речами. Відділення в меркуріалі виникає, коли між різними репостами виникають конфлікти. Гілка в git, схоже, на клон у hg. Але клон, хоча це може дати подібну поведінку, безумовно, не той самий. Подумайте, я пробую це в git vs hg, використовуючи хромовий репо, який досить великий.
$ time git checkout -b some-new-branch
Switched to new branch 'some-new-branch'
real 0m1.759s
user 0m1.596s
sys 0m0.144s
А тепер у hg, використовуючи клон
$ time hg clone project/ some-clone/
updating to branch default
29387 files updated, 0 files merged, 0 files removed, 0 files unresolved.
real 0m58.196s
user 0m19.901s
sys 0m8.957
І те, і інше - гарячі прогони. Тобто я пробіг їх двічі, і це вже другий пробіг. hg клон насправді те саме, що git-new-workdir. Обидва з них роблять абсолютно новий робочий режим майже так, як ніби ви набрали cp -r project project-clone
. Це не те саме, що зробити нову гілку в git. Це набагато більша вага. Якщо є справжній еквівалент розгалуження git в hg, я не знаю, що це таке.
Я розумію, на деякому рівні hg і git можуть зробити подібні речі. Якщо так, то все ще існує величезна різниця в робочому процесі, до якого вони ведуть вас. У git типовим робочим процесом є створення гілки для кожної функції.
git checkout master
git checkout -b add-2nd-joypad-support
git checkout master
git checkout -b fix-game-save-bug
git checkout master
git checkout -b add-a-star-support
Щойно створили 3 гілки, кожна заснована на гілці, званій майстер. (Я впевнений, що в git є спосіб зробити ці 1 рядок замість 2)
Тепер працювати над одним, що я просто роблю
git checkout fix-game-save-bug
і почати працювати. Здійснюйте завдання тощо. Перемикання між гілками навіть у проекті такого великого, як хром, майже миттєве. Я насправді не знаю, як це зробити в hg. Це не частина навчальних посібників, які я читав.
Ще одна велика різниця. Етап Гіта.
У Гіта є ця ідея сцени. Ви можете думати про це як про приховану папку. Виконуючи зобов'язання, ви здійснюєте лише те, що на сцені, а не зміни у вашому робочому дереві. Це може здатися дивним. Якщо ви хочете здійснити всі зміни у вашому робочому дереві, ви зробите це, git commit -a
яке додає всі змінені файли до етапу, а потім виконує їх.
У чому сенс сцени? Ви можете легко розділити свої комісії. Уявіть, що ви редагували joypad.cpp та gamesave.cpp, і ви хочете зробити їх окремо
git add joypad.cpp // copies to stage
git commit -m "added 2nd joypad support"
git add gamesave.cpp // copies to stage
git commit -m "fixed game save bug"
У Git навіть є команди, щоб визначити, які саме рядки в одному файлі ви хочете скопіювати на етап, щоб ви також могли розділити ці комісії окремо. Чому б ти хотів це зробити? Оскільки в якості окремих комісій інші можуть тягнути лише те, що вони хочуть, або якщо виникла проблема, вони можуть скасувати лише зобов'язання, які мали проблему.