Базовое использование

Четыре команды выше копируют файлы между рабочим каталогом, каталогом промежуточной подготовки (также называемым индексом) и репозиторием.
git add filesПоместите текущий файл в область индексации.git commitСоздайте снимок области индексации и выполните коммит.git reset -- filesИспользуется для отмены последнегоgit add files, также можно использоватьgit resetчтобы отменить все файлы в области индексации.git checkout -- filesСкопируйте файлы из области индексации в рабочий каталог, чтобы отменить локальные изменения.
Вы можете использоватьgit reset -p, git checkout -p, или git add -pчтобы войти в интерактивный режим.
Вы также можете пропустить область индексации и напрямую получить файлы из репозитория или напрямую закоммитить код.

git commit -aЭквивалентно выполнениюgit addдобавлению всех файлов в текущем каталоге в область индексации и последующему выполнению.git commit.git commit filesСоздайте коммит, который включает последний коммит плюс снимок файлов в рабочем каталоге. При этом файлы добавляются в область индексации.git checkout HEAD -- filesОткатитесь к копии последнего коммита.
Соглашения
В дальнейшем используются изображения следующего вида.

Зелёные 5-символьные строки представляют идентификаторы коммитов, указывая соответственно на их родительские узлы. Ветки показаны оранжевым, каждая указывает на конкретный коммит. Текущая ветка обозначается идентификаторомHEAD. На этом рисунке показаны последние 5 коммитов,ed489— это последний коммит. Веткаmasterуказывает на этот коммит, другая веткаmaintуказывает на узел прародительского коммита.
Подробности команды
Различия
Существует множество способов просмотреть различия между двумя коммитами. Ниже приведены некоторые примеры.

Коммит
При создании коммита git использует файлы из индекса для создания нового коммита и устанавливает текущий узел в качестве родительского. Затем он направляет текущую ветку на новый узел коммита. На рисунке ниже текущая ветка —master. Перед выполнением команды,masterуказывает наed489, после коммитаmasterуказывает на новый узелf0cecи используетed489в качестве родительского узла.

Даже если текущая ветка является прародителем коммита, git поступает так же. На рисунке ниже, вmasterузле прародителя ветки,maintна ветке создаётся коммит, порождая1800b. Таким образом,maint— ветка больше не является узлом-прародителем веткиmaster. На этом этапе необходимо слияние (или перебазирование).

Если вы хотите изменить коммит, используйтеgit commit --amend. git создаст новый коммит с тем же родительским узлом, что и текущий коммит, а старый коммит будет отменён.
Другой пример — коммит detached HEAD, о котором речь пойдёт позже.
Checkout
Команда checkout используется для копирования файлов из исторического коммита (или области подготовки) в рабочий каталог, а также может использоваться для переключения веток.
Когда указано имя файла (или включена опция -p, или одновременно указано имя файла и включена опция -p), git копирует файлы из указанного коммита в область подготовки и рабочий каталог. Например,git checkout HEAD~ foo.cскопирует из узла коммитаHEAD~(то есть родительского узла текущего узла коммита),foo.cскопирует файл в рабочий каталог и добавит его в область подготовки. (Если в команде не указан узел коммита, содержимое копируется из области подготовки.) Обратите внимание, что текущая ветка не меняется.

Когда имя файла не указано, но указана (локальная) ветка, тогда идентификаторHEADперемещается на эту ветку (то есть мы «переключаемся» на эту ветку), и затем содержимое области подготовки и рабочего каталога будетHEADсогласовано с соответствующим узлом коммита. Все файлы в новом узле коммита (a47c3 на рисунке ниже) будут скопированы (в область подготовки и рабочий каталог); файлы, которые существуют только в старом узле коммита (ed489), будут удалены; файлы, не относящиеся ни к одному из вышеперечисленных, будут проигнорированы и останутся без изменений.

Если не указано ни имя файла, ни имя ветки, а вместо этого указан тег, удалённая ветка, значение SHA-1 или нечто подобноеmaster~3, вы получаете анонимную ветку, называемуюdetached HEAD(detachedHEADидентификатор). Это позволяет удобно переключаться между историческими версиями. Например, если вы хотите скомпилировать версию git 1.6.6.1, можно выполнитьgit checkout v1.6.6.1(это тег, а не имя ветки), скомпилировать, установить и затем переключиться обратно на другую ветку, напримерgit checkout master. Однако, когда операция коммита затрагивает "отсоединённый HEAD", её поведение немного отличается; подробности см. ниже.

Операции коммита, когда идентификатор HEAD находится в отсоединённом состоянии
КогдаHEADнаходится в отсоединённом состоянии (не привязан ни к какой ветке), операции коммита могут выполняться нормально, но ни одна именованная ветка не обновляется. (Можно думать об этом как об обновлении анонимной ветки.)

Как только вы позже переключитесь на другую ветку, напримерmaster, этот коммит-узел может больше никогда не использоваться, и будет отброшен. Обратите внимание, что после этой команды ничто не будет ссылаться на2eecb。

Но если вы хотите сохранить это состояние, вы можете использовать командуgit checkout -b nameчтобы создать новую ветку.

Сброс
Команда reset указывает текущей ветке на другое место и выборочно изменяет рабочий каталог и индекс. Она также используется для копирования файлов из исторического репозитория в индекс без изменения рабочего каталога.
Если не указана ни одна опция, текущая ветка указывает на этот коммит. Если--hardопция используется, рабочий каталог также обновляется; если--softопция используется, ничего не изменяется.

--hardопция используется, рабочий каталог также тот же.
Если задано имя файла (или-pопция), эффект аналогичен checkout с именем файла, за исключением того, что индекс обновляется.
Слиянием
Команда merge объединяет разные ветки. Перед слиянием индекс должен совпадать с текущим коммитом. Если другая ветка является предком текущего коммита, команда merge ничего не сделает. Другой случай — если текущий коммит является предком другой ветки, что приводит кfast-forwardслиянию. Указатель просто перемещается и не создаёт новый коммит.
В противном случае это настоящее слияние. По умолчанию текущий коммит (ed489как показано ниже) и другой коммит (33104) и их общий узел-предок (b325c) выполняюттрёхстороннее слияние.. В результате текущий каталог и индекс сначала сохраняются, а затем вместе с родительским узлом33104создаётся новый коммит.
Cherry Pick
Команда cherry-pick «копирует» узел коммита и создаёт идентичный новый коммит в текущей ветке.

Rebase
Перебазирование — альтернатива команде merge. Merge объединяет две родительские ветки в один коммит, и история коммитов не является линейной. Перебазирование воспроизводит историю другой ветки на текущей ветке, делая историю коммитов линейной. По сути, это автоматический cherry-pick, который линеаризует историю.

Все вышеперечисленные команды выполняются в веткеtopic, а не в веткеmaster; в веткеmasterветка, они воспроизводятся, и ветка указывает на новый узел. Обратите внимание, что старые коммиты не имеют ссылок и будут удалены сборщиком мусора.
Чтобы ограничить диапазон отката, используйте--ontoопция. Следующая команда в веткеmasterвоспроизводит текущую ветку начиная с169a6последних коммитов, то есть2c33a。

Также естьgit rebase --interactiveчтобы вам было удобнее выполнять некоторые сложные операции, такие как отбрасывание, переупорядочивание, изменение и слияние коммитов. Здесь нет иллюстраций, показывающих их; подробнее см. здесь:git-rebase(1)
Технические заметки
Содержимое файлов на самом деле не хранится в индексе (.git/index) или в объектах коммитов, а хранится отдельно в базе данных в виде blob-объектов (.git/objects) и проверяется с помощью значений SHA-1. Файл индекса использует идентификационные коды для перечисления соответствующих blob-файлов и других данных. Что касается коммитов, они хранятся в виде дерева (tree-форме, также идентифицируемой соответствующим значением хеша. Деревья соответствуют папкам в рабочем каталоге, а деревья или blob-объекты, содержащиеся в дереве, соответствуют соответствующим подкаталогам и файлам. Каждый коммит хранит идентификационный код своего родительского дерева.
Если вы делаете коммит с отсоединённым HEAD, последний коммит будет указан в reflog для HEAD. Но через некоторое время он становится недействительным и в конечном итоге удаляется сборщиком мусора, подобноgit commit --amendилиgit rebaseпо своей природе.
Оригинальная ссылка: http://marklodato.github.io/visual-git-guide/index-zh-cn.html