Если я правильно понимаю их (и я далеко не эксперт по каждому из них), у каждого из них есть своя философия. Я впервые использовал ртуть в течение 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 может это делать, и часто люди используют его таким образом, который не применяется. Git картина, если есть такая вещь, может легко выглядеть так
o---o---o---o---o
o---o---o---o
\
o---o
o---o---o---o
На самом деле, в некоторых случаях даже нет смысла показывать ветки в git.
Одна вещь, которая очень сбивает с толку для обсуждения, у git и mercurial есть нечто, называемое «ветвью», но они не являются отдаленно одинаковыми вещами. Ветвь в 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
А теперь в рт с помощью клона
$ 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 clone фактически такой же, как 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 ветви, каждая из которых основана на ветви, называемой master. (Я уверен, что в git есть способ сделать эти 1 строку вместо 2)
Теперь работать над одним я просто делаю
git checkout fix-game-save-bug
и начать работать. Фиксация и т. Д. Переключение между ветками даже в таком большом проекте, как Chrome, происходит практически мгновенно. Я на самом деле не знаю, как это сделать в HG. Это не часть учебников, которые я читал.
Еще одна большая разница. Стадия Гита.
У Git есть эта идея сцены. Вы можете думать об этом как о скрытой папке. Когда вы фиксируете, вы фиксируете только то, что находится на сцене, а не изменения в вашем рабочем дереве. Это может звучать странно. Если вы хотите зафиксировать все изменения в вашем рабочем дереве, вы должны будете 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 даже есть команды, чтобы решить, какие именно строки в одном и том же файле вы хотите скопировать на сцену, чтобы вы также могли разделить эти коммиты по отдельности. Почему вы хотите это сделать? Поскольку в качестве отдельных коммитов другие могут извлекать только те, которые им нужны, или, если возникла проблема, они могут отменить только тот коммит, который имел проблему.