====== 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 # копировать репозиторий В своих обычных операциях Git [[https://git-scm.com/book/ru/v2/%D0%98%D0%BD%D1%81%D1%82%D1%80%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D1%8B-Git-%D0%A0%D0%B0%D1%81%D0%BA%D1%80%D1%8B%D1%82%D0%B8%D0%B5-%D1%82%D0%B0%D0%B9%D0%BD-reset|управляет тремя деревьями]] (разделами): - 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 # обновить область подготовленных файлов новой версией файла/папки 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 # добавить удалённый репозиторий с заданным именем git remote remove git remote rename git remote set-url # новый адрес git remote show # инфо о репозитории git fetch # получить данные ветки, но не сливать изменения git pull # слить данные ветки git push # отправить изменения в ветку # Если локальная ветка уже отслеживает удалённую, то можно просто git push git pull Перенастроить локальный репозиторий с одного удалённого на другой git remote show # показать название удалённого репозитория origin git remote get-url origin # показать ссылку git remote set-url origin # установить новую ===== Коммиты ===== Коммит - это некий снапшот ФС и отсылки на предыдущие снапшоты. Содержит контрольную сумму, которую 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 коммита назад. Перенос коммита, например, если он был отправлен не в ту ветку, можно сделать командой ''[[https://www.atlassian.com/git/tutorials/cherry-pick|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! С откатыванием коммитов слияния сложнее. [[https://www.youtube.com/watch?v=_O6uANApwH0|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 {{:service:pasted:20220721-132004.png}} Если обе ветки меняют одну и ту же часть кода, то возникает конфликт, т. к. git не знает, что нужно оставить, необходимо ручное вмешательство. Конфликтующие файлы выводятся командой ''git status''. В этих файлах будут маркеры с цитатами из обоих веток, нужно оставить там то, что нужно. После разрешения конфликтов можно коммитить -''git commit''. Rebase - копирует коммиты тематической ветки в основную, как если бы они там и были.\\ {{:service:pasted:20220721-134136.png}} # копировать изменения ветки 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= --no-merges # коммиты определённого автора без коммитов слияния веток git log main..test # каких коммитов из test нет в main git log --left-right main..test # показать уникальные коммиты для обеих веток, где они расположены git log -L,: # история изменений набора строк в файле 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 ===== Схема ===== {{:service:pasted:20240529-093727.png?800}} **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 # or git checkout -b **Add and Commit** To make additions to your branch, you will use the following commands: # Stage the file git add # 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 # 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-сертификат ==== [[https://ru.stackoverflow.com/questions/458822/%D0%9F%D1%80%D0%BE%D0%B1%D0%BB%D0%B5%D0%BC%D0%B0-%D1%81-ssl-%D0%BF%D1%80%D0%B8-%D0%BA%D0%BB%D0%BE%D0%BD%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B8-%D1%85%D1%80%D0%B0%D0%BD%D0%B8%D0%BB%D0%B8%D1%89%D0%B0|Варианты решения]]: - Использовать SSH при работе с git - Отключить проверку ssl сертификата при клонировании GIT_SSL_NO_VERIFY=true git clone /path/to/repo - Отключить проверку ssl сертификата глобально git config --global http.sslVerify false - Если сертификат самоподписанный - найти инструкцию по добавлению самоподписанного сертификата в доверенные ===== Литература ===== [[https://www.youtube.com/watch?v=9oDNBuive-g|Let's git started together!]] (Youtube) - review the Git concepts, explained by one of the GitLab's Developer Evangelist\\ https://dangitgit.com/ru - варианты исправления/отката ошибок\\