Содержание
Git
# Для начала надо настроить имя и email для авторизации. git config --global --edit # либо vi ~/.gitconfig # либо способом <поле> <значение> git config --global user.name ivanpetrov git config --global user.email i.petrov@example.com # Некоторые поля для настройки # core.editor - редактор сообщений коммитов # commit.template - шаблон, используемый при каждом коммите # alias - псевдоним, например, после git config --global alias.st "status -s" # можно будет писать git st # вместо git status -s # Прокси git config --global http.proxy http://proxy.example.com:3128 git config --global https.proxy http://proxy.example.com:3128 # именно http://, иначе будет ошибка "An unexpected TLS packet was received" # Вывести все поля с их значениями git config --list git init # создать репозиторий git clone <repo address> # копировать репозиторий
В своих обычных операциях Git управляет тремя деревьями (разделами):
- HEAD - Последний коммит в репозитории
- Индекс - Снимок следующего намеченного коммита (staging area, подготовленные файлы)
- Рабочий каталог - локальная рабочая папка
git status
показывает файлы и их статус (с ключом -s
- сокр. тип вывода):
- Untracked - левый файл, git о нём не знает (с ключом
-s
- ??). - Modified - изменён, но не находится на очереди для коммита (с ключом
-s
- красный). - Staged - готов к коммиту (с ключом
-s
- зелёный). - Unmodified - изменений нет, актуальная версия.
Изменения/сравнения
git diff # сравнение рабочего каталога с индексом (область подготовленных файлов) git diff --staged # сравнить индекс с HEAD (непроиндексированные изменения показаны не будут) git diff folder/ # показать изменения только для указанной папки
Обновление/коммит
git add <file/folder> # обновить область подготовленных файлов новой версией файла/папки git commit # обновить HEAD
Игнорирование
Файлы с паролями и т. п. - файл .gitignore
.
# ignores all .txt files JUST in the current folder *.txt # ignores all .txt recursive from the current folder **.txt # ignores all .txt in subdirectories recursive from the current # folder (does not include the current folder) **/*.txt # ignore files only in the directory with the .gitignore file - leading “/” /*.txt # A .gitignore file in the root directory with these contents: /content/*.txt # will ignore all .txt files in the content directory. It will not ignore .txt files in the subdirectories of the content directory.
https://www.quora.com/Does-gitignore-file-only-work-on-current-folder
https://www.atlassian.com/ru/git/tutorials/saving-changes/gitignore
Удалённые репозитории
git remote -v # список удалённых репозиториев с заданными именами git remote add <name> <url> # добавить удалённый репозиторий с заданным именем git remote remove <name> git remote rename <old name> <new name> git remote set-url <name> <url> # новый адрес git remote show <name> # инфо о репозитории git fetch <name> <branch> # получить данные ветки, но не сливать изменения git pull <name> <branch> # слить данные ветки git push <name> <branch> # отправить изменения в ветку # Если локальная ветка уже отслеживает удалённую, то можно просто git push git pull
Перенастроить локальный репозиторий с одного удалённого на другой
git remote show # показать название удалённого репозитория origin git remote get-url origin # показать ссылку git remote set-url origin <url> # установить новую
Коммиты
Коммит - это некий снапшот ФС и отсылки на предыдущие снапшоты. Содержит контрольную сумму, которую git использует для ссылки на него.
git commit # открыть редактор для сообщения в коммите git commit -m "Bug fixed" # можно и без редактора git commit -a # Коммитить модифицированные файлы напрямую, минуя стадию stage (git add в этом случае не нужен) git commit -amend # заменить последний коммит - на случай, если коммит ошибочен git revert # создать новый коммит, откатывающий изменения последнего (история сохраняется) git reset # откатить коммит с перемещением указателя HEAD (без сохранения истории). # Опции: --mixed (по умолчанию) - изменения станут неиндексированными, --soft - индексированными, --hard - полная отмена изменений. # бесследный откат последнего коммита git reset --hard HEAD~1 # --force - для того, чтобы игнорировать предупреждение о том, # что удалённый репозиторий новее git push --force
https://proglib.io/p/sravnenie-5-komand-git-revert-checkout-reset-merge-i-rebase-2020-05-25
На коммит можно ссылаться как через контрольную сумму, так и на позицию относительно HEAD, например, HEAD~3
- 3 коммита назад.
Перенос коммита, например, если он был отправлен не в ту ветку, можно сделать командой git cherry-pick
. Список коммитов можно получить с помощью git log master..test
.
git log master..foo
will show the commits that are on foo and not on master. Helpful for seeing what commits you've added since branching!
С откатыванием коммитов слияния сложнее. 2 Ways to Undo Merge Commits
Куча мелких коммитов делает историю проекта замусоренной, что важно при слиянии веток. Их можно объединить в один.
# интерактивное сжатие git cherry -v main # показать сделанные коммиты в сравнении с веткой main git rebase -i HEAD~3 # -i - интерактивно, объединить последние 3 коммита # pick - первый коммит # squash - коммиты, которые будут слиты с первым # сжатие при слиянии веток - коммиты из feature будут объединены и слиты с текущей веткой git merge --squash feature
Ветки
Ветки - версии проекта. По умолчанию - master или main. Лучше называть понятно в соответствии с предназначением - release, dev, test и т. д. Переключение между ветками - это перемещение указателя HEAD в HEAD соответствующей ветки.
git branch dev # создать новую ветку dev git checkout dev # переключиться на ветку dev git checkout -b dev # создать ветку и переключиться на неё git branch -d dev # удалить
Когда отслеживается удалённый репозиторий, то отслеживается удалённая ветка. Команда git clone
привязывает локальную ветку master к ветке origin/master удалённого репозитория.
git branch -u origin/serverfix # привязать текущую ветку к удалённой ветке serverfix репозитория origin git checkout --track origin/serverfix # то же самое git checkout -b serverfix origin/serverfix # создать локальную ветку и отслеживать удалённую git branch -vv # показать локальные и отслеживаемые удалённые ветки git checkout origin/serverfix # создать одноимённую локальную ветку и отслеживать удалённую
git checkout
меняет место указания HEAD по аналогии с git reset
, который его перемещает.
Слияние веток (merge) - создание коммита, указывающего HEADs как предков из двух предыдущих веток - основной и тематической. Для слияния нужно
# Переключиться на основную ветку main git checkout main # и выполнить слияние с веткой feature git merge feature
Если обе ветки меняют одну и ту же часть кода, то возникает конфликт, т. к. git не знает, что нужно оставить, необходимо ручное вмешательство. Конфликтующие файлы выводятся командой git status
. В этих файлах будут маркеры с цитатами из обоих веток, нужно оставить там то, что нужно. После разрешения конфликтов можно коммитить -git commit
.
Rebase - копирует коммиты тематической ветки в основную, как если бы они там и были.
# копировать изменения ветки feature на ветку main git rebase main feature
Merge создаёт некий хаос в логах истории. Rebase в этом плане более последователен, но копированные коммиты всё равно будут другими, хотя и идентичными по содержанию.
Изменить ссылку на удалённый репозиторий (для переезда на другой сервер)
git remote show # показать имя удалённого репозитория git remote get-url origin # показать ссылку git remote set-url origin git@example.com:username/repo.git # установить новую ссылку git push # отправить данные в новый удалённый репозиторий
Создать ветку локально и затем создать её на удалённом сервере
git checkout -b new-branch git branch -u origin/new-branch git push
Просмотр изменений
git log -p # показать изменения в каждом коммите git log -stat # вывести краткую статистику для коммитов - изм. файлы, кол-во изм. строк git log -7 # 7 посл. коммитов git log -since="2022-01-01" # коммиты в 1 янв 2022. Также есть -until= git log -pretty=format:"%h %s" # тонкая настройка формата логов git log -grep string # поиск добавления/удаления строки в сообщениях и строках кода (также параметр -S) git log --author=<name> --no-merges # коммиты определённого автора без коммитов слияния веток git log main..test # каких коммитов из test нет в main git log --left-right main..test # показать уникальные коммиты для обеих веток, где они расположены git log -L<start>,<end>:<file> # история изменений набора строк в файле git blame -L 1,5 README.md # Кто вносил изменения в диапазон указанных строк git grep # поиск по регулярке по всем файлам в истории коммитов -n - показать номер строки, -c - кол-во совпадений
https://git-scm.com/docs/git-log/2.21.0#Documentation/git-log.txt
Схема
Clone and Checkout
In order to start making changes, you must first clone and checkout the repository, and then create a branch to begin your edits.
On your local terminal, the commands or these actions are:
git clone <clone with ssh> # or <clone with https> git checkout -b <branchname>
Add and Commit
To make additions to your branch, you will use the following commands:
# Stage the file git add <file> # Run git status git status # Commit the file git commit -m "commit message" # Run git status git status # Push the commit to the remote git push origin <your_new_branch> # and for an initial push to branch git push -u origin... # Run git status git status # View the git log git log
Советы
- Одно изменение - один коммит. Так проще откатиться.
- Сообщение коммита - заголовок меньше 50 символов, в повелительном наклонении «add a new feature». Сообщение должно объяснять, почему коммит был сделан.
- При разработке делать небольшие коммиты, а при добавлении в репозиторий объединять их в один.
Ошибки/проблемы
Ругань на SSL-сертификат
- Использовать SSH при работе с git
- Отключить проверку ssl сертификата при клонировании
GIT_SSL_NO_VERIFY=true git clone /path/to/repo
- Отключить проверку ssl сертификата глобально
git config --global http.sslVerify false
- Если сертификат самоподписанный - найти инструкцию по добавлению самоподписанного сертификата в доверенные
Литература
Let's git started together! (Youtube) - review the Git concepts, explained by one of the GitLab's Developer Evangelist
https://dangitgit.com/ru - варианты исправления/отката ошибок