Примечание: одно из самых больших различий между 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 позволяет вам выполнять ветвление и слияние (выбор вишни или перебазирование), позволяет вам совершать коммиты так часто, как вы хотите, во временной частной ветке (только нажатием в удаленный «резервный» репозиторий), повторяя эти «уродливые коммиты» в общедоступной ветке со всеми необходимыми тестами.