Mercurial → Git. Конспект, грабли.

Oct 29, 2012 02:28

Мирно жил с Mercurial, но Hg-Git при push запорол сначала инфо о ветке, а потом и вовсе потерял коммит, поэтому пришлось все-таки взяться за Git. Ниже приводятся заметки на полях книжки, не всегда следующие ее тексту. Заметки будут потихоньку дополняться по мере чтения.

И полезная табличка: http://mercurial.selenic.com/wiki/GitConcepts


настройка

Глобальные настройки:

HG: vi ~/.hgrc
GIT: vi ~/.gitconfig или git config --global foo.bar quux

Настройки репозитория:

HG: vi .hg/hgrc
GIT: vi .git/config или git config foo.bar quux

add

Mercurial коммитит изменения прямо из рабочего каталога, Git - из промежуточного (staging), поэтому их надо явным образом копировать из рабочего в промежуточный между последней правкой и коммитом.

HG: hg init; echo a > foo.txt; hg add foo.txt; echo b > foo.txt; hg commit -m init

В репозитории будет foo.txt с текстом "b".

GIT: git init; echo a > foo.txt; git add foo.txt; echo b > foo.txt; git commit -m init

В репозитории будет foo.txt с текстом "a".

См. http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository

.gitignore

HG: можно на лету переключать синтаксис между regex и glob.
GIT: только glob.

CLI

HG: понимает достаточный набор букв для идентификации команды + встроенные псевдонимы (commit = com = ci).
GIT: требует, чтобы команду написали полностью (хотя бы и через автодополнение).

status

HG: working → repo
GIT: working → staging → repo

Файл может быть дважды упомянут в разных разделах: "to be committed" (staging vs repo) и "changed but not updated" (working vs staging).

diff

HG: hg diff
GIT: git diff (changed but not yet staged); git diff --staged (staged but not yet committed)

commit

Быстрая фиксация изменений в ранее добавленном файле:

HG: echo a > foo.txt; hg commit
GIT: echo a > foo.txt; git commit -a

Через staging:

HG: -
GIT: echo a > foo.txt; git add foo.txt; git commit

remove

Удалить файл из working, а при коммите и из репозитория:

HG: hg rm foo.txt; hg commit
GIT: git rm foo.txt; git commit

Удалить файл из staging/repo, но не трогать в working:

HG: hg forget foo.txt; [hg commit]
GIT: git rm --cached foo.txt; [git commit]

move

HG: hg mv a b
GIT: git mv a b

Но есть важная разница: Mercurial в момент коммита сохраняет в changeset'е информацию о копировании файла (и переименовании как частном случае, т.е. hg mv a b = hg cp a b; hg rm a), а Git тупо удаляет старый файл и добавляет новый, при этом рвёт историю и угадывает переименование уже post factum (напр., при слиянии веток). Поэтому Git потенциально может доставить больше головной боли.

log

Практически одинаково, включая опции --stat, -p (HG: -p,--patch; GIT: -p). У обоих всякие фишечки, которые я и в Hg не использую (а напрасно). В частности, обе системы дают мощные инструменты фильтрации. По форматированию (см. для Hg):

HG: hg log --template '{node|short} - {author|person}, {date|age} : {desc}\n'
GIT: git log --pretty=format:"%h - %an, %ar : %s"

Ну и, собственно:

HG: hg log --graph --style compact
GIT: git log --graph --pretty=short

Undoing things

В случае ошибки, обнаруженной сразу после коммита, обе системы позволяют удалить последний коммит и добавить новый вместо него. При этом хэш меняется в любом случае.

Исправляем ошибку в описании последнего коммита:

HG: hg commit -m foo; hg commit --amend -m bar
GIT: git commit -m foo; git commit --amend -m bar

Исправляем файл в последнем коммите:

HG: echo a > foo.txt; hg commit; echo b > foo.txt; hg commit --amend
GIT: echo a > foo.txt; git commit -a; echo b > foo.txt; git commit -a --amend (не забыть commit -a / add)

Если файл из working случайно добавлен в staging:

HG: -
GIT: git reset HEAD foo.txt

Сброс локальных изменений в файле до ранее закоммиченного состояния:

HG: hg revert foo.txt
GIT: git checkout -- foo.txt

Remotes

В Git под "remote" подразумевается удаленный репозиторий. Ессно, их может быть много. Информация о каждом хранится в .git/config как отдельная секция ini-файла. В Mercurial они перечисляются в виде название=путь в секции "paths".

HG: hg paths
GIT: git remote -v

Можно посмотреть детальную информацию о конкретном remote (в Mercurial это только путь к нему):

HG: hg paths default
GIT: git remote show origin

При клонировании (hg clone/git clone) исходный репозиторий автоматически запоминается как "default" (в Mercurial) или "origin" (в Git).

Работа с ними одинакова:

HG: hg pull john; hg push default
GIT: git fetch john; git push origin

Управление списком удаленных репозиториев через CLI есть только в Git:

HG: -
GIT: git remote add [shortname] [url]
GIT: git remote rename johnconnor john
GIT: git remote rm john

pull

Получить:

HG: hg pull
GIT: git fetch

Получить и обновить/смержить:

HG: hg pull --update
GIT: git pull

push

HG: hg push
GIT: git push

Конкретный удаленный репозиторий и конкретная ветка:

HG: hg push default -b default
GIT: git push origin master

tags

В Mercurial есть метки (tags) одного типа. Хранятся в текстовом файле .hgtags как пары ревизия/метка. Их можно добавлять туда вручную или через CLI; во втором случае это оформляется как коммит.

В Git есть lightweight tags (хранятся как .git/refs/tags/имя_метки - и хэш ревизии в теле файла), а также annotated tags (хранятся как отдельные объекты). Предполагается работа через CLI. В обоих случаях при добавлении метки коммит не создается. Соответственно, установить источник и время появления "простой" метки невозможно(?).

Список меток:

HG: hg tags
GIT: git tag

Создание метки:

HG: hg tag v0.1
GIT: git tag v0.1
GIT: git tag v0.1 -a -m "tag annotation"

Особенности Git:

1. Поскольку аннотированные метки содержат данные, которые невозможно посмотреть через git tag, следует использовать git show v0.1.
2. Поскольку метки хранятся отдельно от кода, их нужно отправлять в удаленный репозиторий явным образом: git push origin v0.1 (конкретная метка) или git push origin --tags (все метки). При клонировании репозитория все метки оттуда выгребаются в клон автоматически.

Так, ладно, тут адски неудобно конспектировать. Переношу в файлик в ReStructuredText, мб потом где-нибудь выложу результат.

soft.git, soft.hg, dev.scm

Previous post Next post
Up