Skip to content

Основные понятия и начало использования GIT

Следующая статья


Команды из статьи

  • git config --global user.name "{Your GitHub/Gitlab username}"
  • git config --global user.email yourmail@example.com
  • git config --list --show-origin
  • git init
  • git status
  • git add .
  • git commit -m "Comment"
  • git log
  • git log --pretty=oneline
  • git log --graph
  • git checkout <hash>
  • git checkout master
  • git commit --amend
  • git reset HEAD <file> [<file2> ...]git restore --staged <file> [<file2> ...]
  • git checkout -- <file> [<file2> ...]git restore <file> [<file2> ...]+

То, что GIT - вещь нужная и полезная, что особо расписывать не имеет смысла. Данные заметки призваны структурировать знания по этой системе и закрепить набор устоявшихся практик её использования.

Основное

GIT - это распределённая система контроля версий. То есть наличие какого-то удалённого репозитория, ветки master (или как сейчас её богомерзки называют main) не означает, что у нас есть 'сверх-ветка', без которой вся работа над проектом неизбежно развалится. Централизации если и стараются придерживаться, то только по организационнным соображениям. Однако из каждого снимка, который обозначает текущее состояние проекта можно продолжить работу над ним. В любой момент можно легко и непринуждённо сделать fork, то есть обособить под своё владение чужой проект и вносить свои правки на свой вкус. Нет сложностей в том, чтобы потом сделать запрос на слияние (pull request) с основным проектом и, возможно, внести свой вклад в развитие какого-то очень важного ПО. Сделать это можно из CLI. Но можно воспользоваться функционалом, который предоставляют различные платформы (GitHub, Gitlab, Gitea, Bitbucket) в графическом режиме через веб-интерфейс.

Если развернуть утверждение о распределённости системы техническим языком, то вместо номеров ревизий (как это делалось в централизованных СКВ), кажждый коммит идентифицируется при помощи хэш-суммы (SHA-1). Безусловно, коммиты хранят данные о том, кто сделал изменения, когда и какие (иначе зачем они были бы нужны). Но при этом все эти изменения являются равнозначными, что позволяет чётко и ясно составить список конфликтов и наглядно сравнив варианты, принять один из них или разрешить (resolv) по своему.

К тому же, вышеперечисленные платформы интегрируются с различными системами, которые позволяют автоматически тестировать изменения кода, сообщать о результатах тестов по электронной почте, автоматически деплоить код на сервера. Это не является уникальным признаком данного вида СКВ, но очень важно в современной работе администратора. То есть СКВ сейчас - это основа подхода непрерывной интеграции и доставки (CI/CD).

Первоначальная настройка

Устанавливается система просто как в Windows так и в Linux - останавливаться на этом не вижу смысла.

Единственное, что нужно будет сделать - это внести данные в глобальные переменные GIT:

git config --global user.name "{Your GitHub/Gitlab username}"
git config --global user.email yourmail@example.com

В противном случае каждый коммит, а затем пуш, система будет требовать от нас эти данные. Полный список всех настроек можно посмотреть так git config --list --show-origin

Основные понятия

Репозиторий - собственно какталог, в кором содержится код проекта И! каталог .git/ в котором находятся файлы с информацией о коммитах, текущем состоянии, URL удалённого репозитория, различные ключи, секреты и прочее связанное с контролем версий. Именно наличие этой папки делает репозиторий репозиторием. Репозиторий, в котором находится только директория .git/ называется пустым, но, тем не менее, это уже Репозиторий и с ним можно делать всё, что мы дальше распишем.

Инициализируется репозиторий командой git init либо можно склонировать имеющийся репозиторий с удалённого сервера, но о работе с ним поговорим отдельно.

Рабочая копия - это все файлы репозитория, за исключением директории .git/.

Три состояния - это очень важная вещь в понимании работы системы: + изменённые файлы; + индексированные файлы; + зафиксированные файлы.

Есть ещё файлы, которые могут находиться в проекте и которые мы по соображениям здравого смысла и безопасности не хотим вносить в систему (фотографии, данные пользователей, ключи в открытом виде и т. п.), для чего создаём в корне репозитория файлик .gitignore и в каждой строчке прописываем относительно корня репозитория пути до этих фалов и каталогов. НО! Если мы в этот файлик внесём путь до этого же файлика, то система перестанет его читать и толку от него не будет. Поэтому состояние игнора мы не рассматриваем как одно из основных.

Изменённые файлы (modified) - это те файлы, которые мы, как ни странно, изменили, но ещё не успели добавить в список для создания снимка (коммита). Соответственно, в IDS-ах или графических программах для работы с GIT такие файлы помечают буквой 'M' (misterion :-) )

misterion

Их список можно посмотреть командой git status

Индексированные файлы (staged) - когда изменённый файл добавлен в список (индекс) для следующего коммита. Происходит это при помощи команды git add [здесь список файлов для внесения в индекс], но чаще всего вносят все файлы, которые были изменены говоря об этом точкой . или такой конструкцией ./*. В графических программах напротив таких файлов появляется буква A

Зафиксированные файлы (committed) - это те, которые, собственно находятся в системе и ... короче, никуда они уже запросто так не денуться. В графических программах они отображаться вместе с остальными в простом дереве файлов и никак специально не выделяются. Коммит происходит командой git commit -m "Краткое описание изменений"

HEAD - в простейшем случае можно считать, что это указатель коммит. Ну а если более развёрнуто, то он определяет состояние находится рабочая копия. И в дальнейшем, когда мы будем говорить о ветвлении, мы упомянем, что как раз смена ветки технически обозначает куда будет переставлен этот указатель.

Вопрос: "Зачем файлы разделены на изменённые и индексированные, если всё равно чаще всего проблему добавления решают командой git add .?" Всё это сделано для того, чтобы в репозиторий попадали только те файлы, которые по нашему мнению действительно нужны проекту. Поэтому, как говорят англоманы, best practic является использование команды git status перед и добавлением в индекс, и, тем более, коммитом. По списку можно будет понять, что система "увидела" медиафайлы, которые не являются частью разрабатываемого приложения, какие-нибудь "мусорные" или конфиденциальная файлы и катклоги, так и как данные IDE или пакеты зависимостей. Увидев это всё, мы быстренько внесём изменения в .gitignore и избежим сложной процедуры удаления нежелательных данных из репозитория.

Собственно, на этом можно считать, что GIT для индивидуального локального пользования в самом примитивном виде освоен и в рамках локальной машины уже можно не волноваться, что проект куда-то денется. Однако, если вспомнить, что этот некультурный финн по гражданству и швед по национальности...

FuNVIDIA

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

Перемещение между коммитами

GIT позволяет посмотреть список предыдущих снимков и перейти к определённому. Происходит это при помощи команды git log. Её вывод выглядит примерно так:

$ git log
commit 25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master)
Author: boyko1989 <hunwiss89@gmail.com>
Date:   Wed Aug 31 21:38:45 2022 +0400

    Test for GitHub

commit 11503cc98ebfff24850453709c88054b7842d8b0
Author: boyko1989 <hunwiss89@gmail.com>
Date:   Wed Aug 31 14:50:36 2022 +0400

    Играемся

commit d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4
Author: Pavel <hunwiss89@gmail.com>
Date:   Wed Aug 31 13:52:22 2022 +0400

    GIT INIT

Сверху располагается самый последний коммит. Его хэш в полном виде - это верхняя строка. Также текущий коммит обозначен указателем HEAD. Также видим, что стрелочкой указано имя ветки, а также имя подключения. В информации о каждом коммите указан автор и дата. Внутри системы, конечно она хранится в формате UNIX-time, однако заботливый GIT показывает это в привычном виде. Ну и отдельно представлен комментарий.

Много всего - нужно покороче. И такая возможность есть у нас:

$ git log --pretty=oneline
25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master) Test for GitHub
11503cc98ebfff24850453709c88054b7842d8b0 Играемся
d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4 GIT INIT

Как видно в таком симпатичном (pretty) формате в одну строку (one line) гораздо проще быстренько пробежаться глазами по истории. Однако можно ещё интереснее представить - в виде графа.

$ git log --graph
* commit 25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master)
| Author: boyko1989 <hunwiss89@gmail.com>
| Date:   Wed Aug 31 21:38:45 2022 +0400
|
|     Test for GitHub
|
* commit 11503cc98ebfff24850453709c88054b7842d8b0
| Author: boyko1989 <hunwiss89@gmail.com>
| Date:   Wed Aug 31 14:50:36 2022 +0400
|
|     Играемся
|
* commit d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4
  Author: Pavel <hunwiss89@gmail.com>
  Date:   Wed Aug 31 13:52:22 2022 +0400

      GIT INIT

Ну или git log --pretty=oneline --graph Однако в таком виде в нащем случае будет просто набор отмеченных звёздочкой строчек. Всю силу данного варианта можно будет понять, когда мы познакомимся с ветками.

Что касается перемещения между коммитами, то делается это очень просто, но не нужно. Поясню. Допустим мы переместимся на коммит:

$ git checkout 11503cc98ebfff
Note: switching to '11503cc98ebfff'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 11503cc Играемся

Как видим, не обязательно вводить полный хэш - хотя бы такую часть, которую система точно определит как тот или иной коммит (от 6 первых символов хэша). Здесь мы видим уточнение про какой-то 'detached HEAD' - это означает, что мы переместились на определённый коммит, а не на ветку. При этом данный коммит не присоединён ни к одной ветке. И команда git log --pretty=oneline покажет нам следующее:

$ git log --pretty=oneline
11503cc98ebfff24850453709c88054b7842d8b0 (HEAD) Играемся
d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4 GIT INIT

Ради эксперимента изменим что-нибудь в тексте и посмотрим, что будет: добавили строку в файл, добавим файл в индекс, закоммитим. Он уведомляет, что мы работаем с 'detached HEAD', но коммит делает. Теперь пытаемся вернуться обратно на изначальную "верхушку" репозитория:

$ git checkout master
Warning: you are leaving 2 commits behind, not connected to
any of your branches:

  98f9af3 Эксперимент
  ccc36af экс

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> 98f9af3

Switched to branch 'master'
Your branch is up to date with 'gitlab/master'.

И логи:

$ git log --pretty=oneline
25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master) Test for GitHub
11503cc98ebfff24850453709c88054b7842d8b0 Играемся
d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4 GIT INIT

У нас было два коммита и мы их потеряли, так как они были "leaving 2 commits behind, not connected to any of your branches", то есть неприсоединены ни к одной ветке. Так что намного лучше, если мы при переходе на конкретный коммит создаём ветку и работаем с ней, а потом всё сливаем в мастер. Но об этом позже.

Операции отмены

Если "хорошая мысля" пришла после того, как коммит был сделан и нужно изменить буквально одну опечатку или забыли добавить какой-то файл, то можно воспользоваться командой git commit --amend после добавления исправленного файла в индекс. Получится единый коммит - такой, каким он должен был быть. Старый при этом заменяется нынешним.

Возможно мы поспешно добавили какой-то файл в индекс. В таком случае, чтобы удалить его из списка подготовленных файлов, нужно воспользоваться командой git reset HEAD <file> [<file2> ...]

Также мы можем решить, что в изменённом файле мы сделали всё не так, и нам хотелось бы отменить правки. Для этого: git checkout -- <file> [<file2> ...]. Все изменения пропадут, поэтому важно не перестараться с удалением чего-то лишнего.

Команда git restore заменяет git reset и git checkout -- <file> [<file2> ...]. Для удаления из индекса можно воспользоваться командой git restore --staged <file> [<file2> ...]. Также спомощью этой команды можно сделать отменение изменённого файла: git restore <file> [<file2> ...]. Но, опять же, при использовании этой команды нужно быть внимательным - информация исчезает без возможности восстановления.

Проблемы

Самая смешная проблема - это когда посде добавления файлов в индекс перед коммитом, система выдаёт такое предупреждение:

git add .
warning: in the working copy of 'example', LF will be replaced by CRLF the next time Git touches it

Это предупреждение вызвано тем, что в Linux и Windows немного по разному формляется конец строки.

Следующая статья


Источники:

  • Git - Book - официальный сайт системы

Основные понятия и начало использования GIT

Следующая статья


Команды из статьи

  • git config --global user.name "{Your GitHub/Gitlab username}"
  • git config --global user.email yourmail@example.com
  • git config --list --show-origin
  • git init
  • git status
  • git add .
  • git commit -m "Comment"
  • git log
  • git log --pretty=oneline
  • git log --graph
  • git checkout <hash>
  • git checkout master
  • git commit --amend
  • git reset HEAD <file> [<file2> ...]git restore --staged <file> [<file2> ...]
  • git checkout -- <file> [<file2> ...]git restore <file> [<file2> ...]+

То, что GIT - вещь нужная и полезная, что особо расписывать не имеет смысла. Данные заметки призваны структурировать знания по этой системе и закрепить набор устоявшихся практик её использования.

Основное

GIT - это распределённая система контроля версий. То есть наличие какого-то удалённого репозитория, ветки master (или как сейчас её богомерзки называют main) не означает, что у нас есть 'сверх-ветка', без которой вся работа над проектом неизбежно развалится. Централизации если и стараются придерживаться, то только по организационнным соображениям. Однако из каждого снимка, который обозначает текущее состояние проекта можно продолжить работу над ним. В любой момент можно легко и непринуждённо сделать fork, то есть обособить под своё владение чужой проект и вносить свои правки на свой вкус. Нет сложностей в том, чтобы потом сделать запрос на слияние (pull request) с основным проектом и, возможно, внести свой вклад в развитие какого-то очень важного ПО. Сделать это можно из CLI. Но можно воспользоваться функционалом, который предоставляют различные платформы (GitHub, Gitlab, Gitea, Bitbucket) в графическом режиме через веб-интерфейс.

Если развернуть утверждение о распределённости системы техническим языком, то вместо номеров ревизий (как это делалось в централизованных СКВ), кажждый коммит идентифицируется при помощи хэш-суммы (SHA-1). Безусловно, коммиты хранят данные о том, кто сделал изменения, когда и какие (иначе зачем они были бы нужны). Но при этом все эти изменения являются равнозначными, что позволяет чётко и ясно составить список конфликтов и наглядно сравнив варианты, принять один из них или разрешить (resolv) по своему.

К тому же, вышеперечисленные платформы интегрируются с различными системами, которые позволяют автоматически тестировать изменения кода, сообщать о результатах тестов по электронной почте, автоматически деплоить код на сервера. Это не является уникальным признаком данного вида СКВ, но очень важно в современной работе администратора. То есть СКВ сейчас - это основа подхода непрерывной интеграции и доставки (CI/CD).

Первоначальная настройка

Устанавливается система просто как в Windows так и в Linux - останавливаться на этом не вижу смысла.

Единственное, что нужно будет сделать - это внести данные в глобальные переменные GIT:

git config --global user.name "{Your GitHub/Gitlab username}"
git config --global user.email yourmail@example.com

В противном случае каждый коммит, а затем пуш, система будет требовать от нас эти данные. Полный список всех настроек можно посмотреть так git config --list --show-origin

Основные понятия

Репозиторий - собственно какталог, в кором содержится код проекта И! каталог .git/ в котором находятся файлы с информацией о коммитах, текущем состоянии, URL удалённого репозитория, различные ключи, секреты и прочее связанное с контролем версий. Именно наличие этой папки делает репозиторий репозиторием. Репозиторий, в котором находится только директория .git/ называется пустым, но, тем не менее, это уже Репозиторий и с ним можно делать всё, что мы дальше распишем.

Инициализируется репозиторий командой git init либо можно склонировать имеющийся репозиторий с удалённого сервера, но о работе с ним поговорим отдельно.

Рабочая копия - это все файлы репозитория, за исключением директории .git/.

Три состояния - это очень важная вещь в понимании работы системы: + изменённые файлы; + индексированные файлы; + зафиксированные файлы.

Есть ещё файлы, которые могут находиться в проекте и которые мы по соображениям здравого смысла и безопасности не хотим вносить в систему (фотографии, данные пользователей, ключи в открытом виде и т. п.), для чего создаём в корне репозитория файлик .gitignore и в каждой строчке прописываем относительно корня репозитория пути до этих фалов и каталогов. НО! Если мы в этот файлик внесём путь до этого же файлика, то система перестанет его читать и толку от него не будет. Поэтому состояние игнора мы не рассматриваем как одно из основных.

Изменённые файлы (modified) - это те файлы, которые мы, как ни странно, изменили, но ещё не успели добавить в список для создания снимка (коммита). Соответственно, в IDS-ах или графических программах для работы с GIT такие файлы помечают буквой 'M' (misterion :-) )

misterion

Их список можно посмотреть командой git status

Индексированные файлы (staged) - когда изменённый файл добавлен в список (индекс) для следующего коммита. Происходит это при помощи команды git add [здесь список файлов для внесения в индекс], но чаще всего вносят все файлы, которые были изменены говоря об этом точкой . или такой конструкцией ./*. В графических программах напротив таких файлов появляется буква A

Зафиксированные файлы (committed) - это те, которые, собственно находятся в системе и ... короче, никуда они уже запросто так не денуться. В графических программах они отображаться вместе с остальными в простом дереве файлов и никак специально не выделяются. Коммит происходит командой git commit -m "Краткое описание изменений"

Типы объектов GIT : BLUB(файл), TREE(папка), COMMIT(коммит), ANNOTATED TAG(аннотированный тэг)

HEAD - в простейшем случае можно считать, что это указатель коммит. Ну а если более развёрнуто, то он определяет состояние где находится рабочая копия. И в дальнейшем, когда мы будем говорить о ветвлении, мы упомянем, что как раз смена ветки технически обозначает куда будет переставлен этот указатель.

Вопрос: "Зачем файлы разделены на изменённые и индексированные, если всё равно чаще всего проблему добавления решают командой git add .?" Всё это сделано для того, чтобы в репозиторий попадали только те файлы, которые по нашему мнению действительно нужны проекту. Поэтому, как говорят англоманы, best practic является использование команды git status перед и добавлением в индекс, и, тем более, коммитом. По списку можно будет понять, что система "увидела" медиафайлы, которые не являются частью разрабатываемого приложения, какие-нибудь "мусорные" или конфиденциальная файлы и катклоги, так и как данные IDE или пакеты зависимостей. Увидев это всё, мы быстренько внесём изменения в .gitignore и избежим сложной процедуры удаления нежелательных данных из репозитория.

Собственно, на этом можно считать, что GIT для индивидуального локального пользования в самом примитивном виде освоен и в рамках локальной машины уже можно не волноваться, что проект куда-то денется. Однако, если вспомнить, что этот некультурный финн по гражданству и швед по национальности...

FuNVIDIA

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

Перемещение между коммитами

GIT позволяет посмотреть список предыдущих снимков и перейти к определённому. Происходит это при помощи команды git log. Её вывод выглядит примерно так:

$ git log
commit 25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master)
Author: boyko1989 <hunwiss89@gmail.com>
Date:   Wed Aug 31 21:38:45 2022 +0400

    Test for GitHub

commit 11503cc98ebfff24850453709c88054b7842d8b0
Author: boyko1989 <hunwiss89@gmail.com>
Date:   Wed Aug 31 14:50:36 2022 +0400

    Играемся

commit d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4
Author: Pavel <hunwiss89@gmail.com>
Date:   Wed Aug 31 13:52:22 2022 +0400

    GIT INIT

Сверху располагается самый последний коммит. Его хэш в полном виде - это верхняя строка. Также текущий коммит обозначен указателем HEAD. Также видим, что стрелочкой указано имя ветки, а также имя подключения. В информации о каждом коммите указан автор и дата. Внутри системы, конечно она хранится в формате UNIX-time, однако заботливый GIT показывает это в привычном виде. Ну и отдельно представлен комментарий.

Много всего - нужно покороче. И такая возможность есть у нас:

$ git log --pretty=oneline
25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master) Test for GitHub
11503cc98ebfff24850453709c88054b7842d8b0 Играемся
d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4 GIT INIT

Как видно в таком симпатичном (pretty) формате в одну строку (one line) гораздо проще быстренько пробежаться глазами по истории. Однако можно ещё интереснее представить - в виде графа.

$ git log --graph
* commit 25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master)
| Author: boyko1989 <hunwiss89@gmail.com>
| Date:   Wed Aug 31 21:38:45 2022 +0400
|
|     Test for GitHub
|
* commit 11503cc98ebfff24850453709c88054b7842d8b0
| Author: boyko1989 <hunwiss89@gmail.com>
| Date:   Wed Aug 31 14:50:36 2022 +0400
|
|     Играемся
|
* commit d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4
  Author: Pavel <hunwiss89@gmail.com>
  Date:   Wed Aug 31 13:52:22 2022 +0400

      GIT INIT

Ну или git log --pretty=oneline --graph Однако в таком виде в нащем случае будет просто набор отмеченных звёздочкой строчек. Всю силу данного варианта можно будет понять, когда мы познакомимся с ветками.

Что касается перемещения между коммитами, то делается это очень просто, но не нужно. Поясню. Допустим мы переместимся на коммит:

$ git checkout 11503cc98ebfff
Note: switching to '11503cc98ebfff'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 11503cc Играемся

Как видим, не обязательно вводить полный хэш - хотя бы такую часть, которую система точно определит как тот или иной коммит (от 6 первых символов хэша). Здесь мы видим уточнение про какой-то 'detached HEAD' - это означает, что мы переместились на определённый коммит, а не на ветку. При этом данный коммит не присоединён ни к одной ветке. И команда git log --pretty=oneline покажет нам следующее:

$ git log --pretty=oneline
11503cc98ebfff24850453709c88054b7842d8b0 (HEAD) Играемся
d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4 GIT INIT

Ради эксперимента изменим что-нибудь в тексте и посмотрим, что будет: добавили строку в файл, добавим файл в индекс, закоммитим. Он уведомляет, что мы работаем с 'detached HEAD', но коммит делает. Теперь пытаемся вернуться обратно на изначальную "верхушку" репозитория:

$ git checkout master
Warning: you are leaving 2 commits behind, not connected to
any of your branches:

  98f9af3 Эксперимент
  ccc36af экс

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> 98f9af3

Switched to branch 'master'
Your branch is up to date with 'gitlab/master'.

И логи:

$ git log --pretty=oneline
25d1be668b5cdac4c603686df2a29e40c4b7993f (HEAD -> master, origin/master, gitlab/master) Test for GitHub
11503cc98ebfff24850453709c88054b7842d8b0 Играемся
d4f453b85a6934490d6e29ecef3c66b8dc2c1fe4 GIT INIT

У нас было два коммита и мы их потеряли, так как они были "leaving 2 commits behind, not connected to any of your branches", то есть неприсоединены ни к одной ветке. Так что намного лучше, если мы при переходе на конкретный коммит создаём ветку и работаем с ней, а потом всё сливаем в мастер. Но об этом позже.

Операции отмены

Если "хорошая мысля" пришла после того, как коммит был сделан и нужно изменить буквально одну опечатку или забыли добавить какой-то файл, то можно воспользоваться командой git commit --amend после добавления исправленного файла в индекс. Получится единый коммит - такой, каким он должен был быть. Старый при этом заменяется нынешним.

Возможно мы поспешно добавили какой-то файл в индекс. В таком случае, чтобы удалить его из списка подготовленных файлов, нужно воспользоваться командой git reset HEAD <file> [<file2> ...]

Также мы можем решить, что в изменённом файле мы сделали всё не так, и нам хотелось бы отменить правки. Для этого: git checkout -- <file> [<file2> ...]. Все изменения пропадут, поэтому важно не перестараться с удалением чего-то лишнего.

Команда git restore заменяет git reset и git checkout -- <file> [<file2> ...]. Для удаления из индекса можно воспользоваться командой git restore --staged <file> [<file2> ...]. Также спомощью этой команды можно сделать отменение изменённого файла: git restore <file> [<file2> ...]. Но, опять же, при использовании этой команды нужно быть внимательным - информация исчезает без возможности восстановления.

Проблемы

Самая смешная проблема - это когда посде добавления файлов в индекс перед коммитом, система выдаёт такое предупреждение:

git add .
warning: in the working copy of 'example', LF will be replaced by CRLF the next time Git touches it

Это предупреждение вызвано тем, что в Linux и Windows немного по разному формляется конец строки.

Следующая статья


Источники:

  • Git - Book - официальный сайт системы