Примечание: одно из самых больших различий между Git и Mercurial - это явное наличие индекса или промежуточной области .
Из Mercurial для пользователя Git :
Git - единственный DistributedSCM который раскрывает концепцию индекса или промежуточной области. Другие могут реализовать и скрыть это, но ни в каком другом случае пользователь не знает и не должен иметь с этим дело.
Примерный эквивалент Mercurial - это DirState
, который контролирует информацию о состоянии рабочей копии, чтобы определить файлы, которые будут включены в следующую фиксацию. Но в любом случае этот файл обрабатывается автоматически.
Кроме того, можно быть более избирательным во время фиксации, указав файлы, которые вы хотите зафиксировать, в командной строке или используя расширение RecordExtension
.
Если вам неудобно работать с индексом, вы переходите к лучшему ;-)
Хитрость в том, что вам действительно нужно понимать индекс, чтобы полностью использовать Git. Как напоминает нам эта статья от мая 2006 года (и это актуально и сейчас):
«Если вы отрицаете Индекс, вы действительно отрицаете сам git».
Теперь эта статья содержит много команд, которые теперь проще использовать (так что не слишком полагайтесь на ее содержание;)), но общая идея остается:
Вы работаете над новой функцией и начинаете вносить незначительные изменения в файл.
# working, add a few lines
$ git add myFile
# working, another minor modification
$ git add myFile
На этом этапе ваша следующая фиксация внесет 2 незначительных изменения в текущую ветку.
# working, making major modification for the new features
# ... damn! I cannot commit all this in the current branch: nothing would work
$ git commit
Записывает только изменения, добавленные в промежуточную область (индекс) на этом этапе, но не основные изменения, видимые в настоящее время в вашем рабочем каталоге.
$ git branch newFeature_Branch
$ git add myFile
Следующая фиксация запишет все другие важные изменения в новую ветку newFrature_Branch.
Теперь интерактивное добавление или даже разделение коммита - это функции, доступные в Mercurial с помощью команды ' hg record
' или других расширений: вам нужно будет установить RecordExtension
или CrecordExtension
.
Но это не часть обычного рабочего процесса Mercurial.
Git рассматривает фиксацию как серию « изменений содержимого файла » и позволяет вам добавлять эти изменения по одному.
Вы должны изучить эту функцию и ее последствия: Большинство Гит власти (например , возможность легко восстановить слияние (или разрез`ать проблему, или вернуть коммита) , в отличие от Mercurial ) происходит от этого «содержимое файла» парадигмы.
tonfa (в профиле: "Hg dev, pythonist": цифры ...) вмешался, в комментариях:
В индексе нет ничего принципиально "мерзкого", hg могла бы использовать индекс, если бы он был признан ценным, на самом деле mq
или shelve
уже был частью этого.
О, парень. Это снова мы.
Во-первых, я здесь не для того, чтобы один инструмент выглядел лучше другого. Я считаю Hg отличным, очень интуитивно понятным, с хорошей поддержкой (особенно в Windows, моей основной платформе, хотя я также работаю с Linux и Solaris8 или 10).
Индекс фактически является передним и центральным в том, как Линус Торвальдс работает с VCS :
Git использовал явные обновления индекса с первого дня, даже до первого слияния. Я просто так работал всегда. У меня есть грязные деревья с каким-то случайным патчем в моем дереве, который я не хочу фиксировать, потому что это просто обновление Makefile для следующей версии
Теперь комбинация индекса (которое встречается не только в Git) и парадигмы «контент - король» делает его довольно уникальным и «мерзким» :
git - это средство отслеживания содержимого , и имя файла не имеет значения, если оно не связано с его содержимым. Следовательно, единственное разумное поведение для git add filename - добавить содержимое файла, а также его имя в индекс.
Примечание: «содержание» здесь определяется следующим образом :
Индекс Git в основном определяется как
- достаточно, чтобы содержать полное « содержимое » дерева (а это включает все метаданные: имя файла, режим и содержимое файла - все это части «содержимого», и все они сами по себе бессмысленны! )
- дополнительная информация "stat", чтобы позволить очевидную и тривиальную (но чрезвычайно важную!) оптимизацию сравнения файловых систем.
Таким образом , вы действительно должны увидеть индекс , как быть содержанием .
Контент - это не «имя файла» или «содержимое файла» как отдельные части. Вы действительно не можете разделить их .
Сами по себе имена файлов не имеют смысла (у них тоже должно быть содержимое файла), а содержимое файла само по себе также бессмысленно (вы должны знать, как его получить).
Я пытаюсь сказать, что git принципиально не позволяет вам видеть имя файла без его содержимого. Вся эта идея безумна и неверна. Это не имеет отношения к «реальности».
Из FAQ основными преимуществами являются:
- совершить с высокой степенью детализации
- помочь вам сохранить незавершенную модификацию в вашем дереве в течение достаточно длительного времени
- выполните несколько небольших шагов для одной фиксации, проверяя, что вы сделали
git diff
, и подтверждая каждый маленький шаг с помощью git add
или git add -u
.
- позволяет отличное управление конфликтов слияния:
git diff --base
, git diff --ours
, git diff --theirs
.
- позволяет
git commit --amend
изменять только сообщение журнала, если индекс не был изменен за это время
Я лично считаю, что это поведение не должно быть по умолчанию, вы хотите, чтобы люди совершали что-то протестированное или, по крайней мере, скомпилированное.
Хотя в целом вы правы (насчет «протестированной или скомпилированной» части), способ, которым Git позволяет вам выполнять ветвление и слияние (выбор вишни или перебазирование), позволяет вам совершать коммиты так часто, как вы хотите, во временной частной ветке (только нажатием в удаленный «резервный» репозиторий), повторяя эти «уродливые коммиты» в общедоступной ветке со всеми необходимыми тестами.