Git - DmitryGontarenko/usefultricks GitHub Wiki

Работа в консоли

touch [file_name] - создавать файл
ls - показать все файл в текущем разделе
mkdir [dir_name] - создать директорию
mkdir -p [folder1/folder2] - создать директорию с вложенной структурой clear - очистить консоль
sudo rm -r -f database/ - удалить директорию. -r recursive, говорит о том что будут удалены все папки и под-папки; -f force

Общие понятия

Указатель на файлы: file.txt - конкретный файл
*.txt - все файлы с выбранным расширением
/. - директория полностью

git status -s - сокращенный вывод статуса.
git diff - можно увидеть, что мы изменили, но еще не проиндексировали

git clean -f - удаление всех неотслеживаемых файлов в рабочей директории, которые не входят в файл .gitignore. Флаг -f служит для подтверждения удаления, а с помощью еще одного флага - -n, можно посмотреть на список того, что будет удалено.

Коммит

git commit -m [commit_name] - создание нового коммита (создание записи изменений), который включает в себя все проиндексированные изменения, текущий коммит становится родителем для нового. После создания указатель (HEAD) перемещается на новый коммит.
git commit --amend - изменение последнего коммита. Эта команда создаёт новый коммит, родителем которого будет родитель ошибочного коммита. Старый коммит будет отброшен. С помощью дополнительного ключа --amend -m [new_commit_name] можно быстро изменить название коммита.

_Если отправлена команда git commit без параметров, выйти из открывшегося окна можно командой: _ Escape :wq Enter

Просмотр истории коммитов

git log - просмотр истории коммитов (не рекомендуется использовать без ограничений)
git log -5 - просмотр истории коммитов с ограничением по количеству
git log -p -5 - флаг -p показывает изменения, внесенные в коммит

Если вы запустили команду git log, которая содержит большое количество коммитов и "застряли" в ней, нажмите Q + Enter для выхода.

Форматирование вывода:
git log --pretty=format:"%h - %an, %ar : %s" - с помощью флага --pretty можно задать собственный формат вывода логов, в данном случае результат вывода будет такой: ab9285b - Гонтаренко Дмитрий, 5 weeks ago : Добавлена csv таблица
git log --oneline --graph --decorate --all -10 - еще один вариант форматирования вывода, в этом случае истори коммитов будет выведена в виде графов.

Источник. Можно ознакомиться со всеми дополнительными опциями

Отмена коммита

git reset --soft HEAD^1 - откатить коммит на 1 назад (все измененные/добавленные файлы ранее сохранятся).
git reset --hard HEAD^1 - откатить коммит на 1 назад с удалением всех внесенных изменений и файлов.
В том случае, если надо откатиться только на один коммит, команда HEAD^ будет работать аналогично представленным выше.

git checkout -- [file_name] - откатить все изменения в уже отслеживаемом файле (до добавления add)
git reset [file_name] - исключение файла из трекинга (после его добавления add)

Работа с удалёнными репозиториями

git remote -v - выводит название доступных удаленных репозиториев. Ключ -v позволяет увидеть адреса для чтения и записи. Команда clone автоматически добавляет имя "origin" для склонированного репозитория.
git fetch [remote_name] - обновление/добавление веток из удаленного репозитория. Все загруженные данные будут находиться в локальном репозитории, но не будут автоматически слиты с текущей работой.
git pull [remote_name] - извлекает (fetch) данные с сервера, с которого вы изначально склонировали, и автоматически пытается слить (merge) их с кодом, над которым вы в данный момент работаете. Если в кратце, то git pull = git fetch + git merge.
git push [remote_name] [branch_name] - отправление своих наработок (commits) на удаленный сервер. Если кто-то другой залил свои изменения в ту же ветку раньше вас, т.е. ваши данные уже не актуальны, с начало потребуется забрать эти изменения (pull). Обычно это выглядит так: git push origin HEAD, где HEAD - ссылка на текущую ветку.

Использование ключа -u связывает локальную ветку с удаленным репозиторием, что позволяет после команды git push -u origin HEAD использовать, например, команду git pull без указания удаленного репозитория.
Использование ключа --force позволяет подливать изменения (дополнять коммит) в уже существующую ветку на удаленном репозитории, например: git push --force origin HEAD.
Обычно это можно использовать после изменения коммита с помощью ключа --amend или команды rebase.

Работа с ветками

git branch - просмотр всех существующих веток в репозитории (текущая ветка будет помечена)
git branch -v - просмотр существующих веток и их последние коммиты

git branch [branch_name] - создание новой ветки
git chekcout [branch_name] - переключиться на существующую ветку

git branch -d [branch_name] - удалить локальную ветку
git push origin :[branchName] - удалить ветку на сервере
git branch -m "new_branch_name" - переименовать ветку (локально!)

Переименование удаленной (находящейся на сервере) ветки:
https://multiplestates.wordpress.com/2015/02/05/rename-a-local-and-remote-branch-in-git/ git branch -m [old_name] [new_name] - переименовываем локальную ветку
git push origin :[old_name] [new_name] - используя : удаляем ветку на сервере и загружаем изменения

git checkout -b [branch_name] origin/[exist_branch] - создать новую ветку, переключиться на нее и подтянуть изменения из уже существующей ветки

Stash

git stash - помещение проиндексированных изменений/файлов в стеш («отложить» текущие изменения). Помещаются такие изменения во временное хранилище по принципу FILO, это надо учитывать при восстановлении изменений.
git stash apply - восстанавливает последний стеш (при этом эти изменения остаются в хранилище)

git stash list -2 - просмотр всех отложенных изменений/хранилищ (с флагом ограничения по количеству)
git stash apply stash@{n} - восстановить конкретное изменение по номеру
git stash pop stash@{n} - восстановление изменений и удаление их из стеша
git stash drop stash@{n} - удаляет выбранное хранилище.
git stash show -p stash@{n} - просмотр изменений в хранилище, ключ -p используется что бы увидеть сами изменения.

git stash clear - удаляет все хранилища.
git stash --all - помещение всех неотслеживаемых и отслеживаемых (но еще не закомиченных) изменений и файлов в хранилище.

git stash save -m "message" - сохранение изменений с вашим сообщением.
git stash save -u - сохранение в хранилище всех изменений, включая непроиндексированные. Флаг -u это сокращение от --include-untracked.

git stash branch [branch_name] stash@{n} - создает новую ветку, которая будет включать в себя содержимое (изменения) выбранного хранилища. При этом изменения удаляются из списка (pop).

Во всех примерах выше, параметр stash@{n} опциональный и служит для указания на конкретный элемент списка, при его отсутствии будет использовано последние значение, помещенное в хранилище.
Хранилище stash расположено локально и поэтому не относится к какой-то конкретной ветке.

Источник
Документация

Объединение коммитов

cherry-pick:
git cherry-pick [hash-commit] - данная команда позволяет забрать один коммит из другой ветки и вставить его в текущую. В качестве параметра передаётся идентификатор (хеш) коммита в другой ветке.
Пример: git cherry-pick 4c0e9ffc34f38396a69fb3eba989ef87e5774d97.
Мы берем один коммит с идентификатором 4c0e9ffc34f3 из той ветки, в которой он был сделан, и изменения этого коммита будут добавлены в текущую ветку как новый коммит.

rebase:
git rebase — один из двух способов объединить изменения, сделанные в одной ветке, с другой веткой.
git rebase --interactive (rebase -i) - возможность изменения более ранних коммитов вручную, рассмотрим какие команды для этого существуют:

  • pick - использовать коммит "как есть".
  • edit - изменить коммит. Необходимо зафиксировать изменения командой git add и нажать/ввести сontinue
  • skip - пропустит коммит (он будет удален).
  • squash - объеденяет выбранные коммиты. Необходимо будет задать имя для нового объединенного коммита.
    Работа в Intellij Idea - для объединения нынешнего коммита с предыдущим, для предыдущего коммита нужно определить команду squash (эту комманду нельзя определить для самого первого коммита). Но при необходимости порядок коммитов можно менять.
  • reword - переименовать коммит.
  • fixup - объединяет выбранные коммиты. Эта команда аналогична squah, но при использовании fixup будет сохранено исходное сообщение коммита (с кем объединялись другие).

После внесения необходимых изменений сделайте push --force.
При работе на Windows операции с rebase -i удобнее всего проделывать в Intellij Idea, при работе в Linux - в IDE или консоли.

merge:
git merge [branch_name] - позволяет выполнить слияние с другой веткой. Например, в ветку developer нужно влить исправление ошибок, для этого, переключившись на нужную ветку, выполним команду - git merge bugfix-115.
Если исправления затрагивают уже существующие данные, git не сможет выполнить объединение автоматически, он добавит во все конфликтующие файлы пометки разрешения конфликтов, что бы дать возможность вручную решить конфликт. После разрешение конфликта нужно добавить файл (git add), что бы отметить конфликт как решенный.

вставить пример разрешения конфликта вручную Основы ветвления и слияния
Intellij Idea. Edit Project History

gitignore

В системе Git можно настроить возможность автоматического игнорирования файлов, т.е. такие файлы не будут отслеживаться. Для этого необходимо создать файл .gitignore.
Этот файл будет иметь примерно такое содержание:

### IntelliJ IDEA ###
.idea
*.iws
out/
target/

К шаблонам в файле .gitignore применяются следующие правила:

  • пустые строки, а также строки, начинающиеся с #, игнорируются;
  • можно инвертировать шаблон, использовав восклицательный знак ! в качестве первого символа;
  • можно использовать стандартные glob шаблоны - упрощенные регулярные выражения.
    • символ * - соответствует 0 или более символам;
    • [abc] - любая последовательность символов из указанных в скобках;
    • ? - один сивол;
    • [0-9] - соответствует любому символу из интервала (в данном случае от 0 до 9).

Если файл .gitignore создан до того, как файлы были проиндексированы, то можно убрать их из версионного контроля командой:
git rm --cached readme.txt - для файла
git rm --cached target\* - для директории

Источник:
Синтаксис gitignore

git config

Файл .gitconfig позволяет настраивать алисасы, учетные записи, внешний вид и т.д.

Если 3 уровня git config:

  1. системный - системные конфигурации доступны для всех проектов и пользователей, хранятся в /etc/gitconfig. Изменяется с помощью команды git config --system
  2. глобальный - глобальные конфигурации для всех проектов для текущего пользователя, хранятся в ~/.gitconfig. Изменяется с помощью команды git config --global
  3. проектный - конфигурации проекта доступны только для текущего проекта и хранятся в каталоге проекта .git/config. По умолчанию команда git config будет изменять именно этот файл.

Настройки на каждом следующем уровне подменяют настройки предыдущих уровней, то есть значения в .git/config перекроют соответствующие значения в /etc/gitconfig.

Пример:

[alias]
	tree = log --graph --decorate --pretty=oneline --abbrev-commit
	poh = push origin HEAD

Источники:
Документаци. Первоначальная настройка Git
Документаци. Git-config
Пример готовой конфигурации

Сценарии

В коммит случайно был добавлен лишний файл:
git reset --soft HEAD^ - отменяет коммит с сохранением файлов
git reset [file_name] - исключаем файл из трекинга
Коммит был сделан не в ту ветку:
Создаем вторую ветку на основе текущей и переходим в нее.
Откатываем изменения в первой ветке reset --hard HEAD^1

Источники:

Git: наглядная справка

Проверить: git checkout [commit_number] - переключиться существующий коммит по его номеру (HEAD переместится, от него можно создать новую ветку)
git revert -n [hash_commit] - удалить выбранный коммит из ветки (-n не коммитить) - проверить, как это повлияет на удаленный репозиторий
git reset [hash_commits] - откатить изменения на выбранные коммиты
3

Version Control Systems

Для разработки качественного программного обеспечения нам необходимо иметь возможность отслеживать все изменения и при необходимости отменять их. Системы контроля версий (VCS) выполняют эту роль, отслеживая историю проекта и помогая объединять изменения, внесенные несколькими людьми. Они значительно ускоряют работу и дают нам возможность легче находить ошибки.
В настоящее время самой популярной системой контроля версий является Git и две распространенных моделей ветвления - Gitflow и Trunk-based development.

Модели ветвления