====== Git ====== [[https://git-scm.com/book/ru/v2|Документация]] ===== Общее =====
:!: Сведения **Git** как таковой opensource-софт, вся работа выполняется **непосредственно в нем**, системы типа **github / gitlab** это общедоступные **хранилища**, в которых можно размещать репозитории для внешнего хранения, софт так или иначе работает прежде всего с **локальным репозиторием** и уже отдельным действием отправляет данные на внешку.\\ **master** главная ветка по умолчанию, создается **первым коммитом**\\ :!: Авторизация\\ Непонятная ситуация с авторизацией, вроде ввели новый способ по токенам, по крайней мере в винде только через него получилось, в линуксе по ssh ключу удалось.. (используется id_rsa.pub)\\ Постоянная конфигурация хранится в файле "~/.bash_profile" (в винде по крайней мере)\\ Для хранения токенов можно использовать: * windows - командой "**git config --global credential.helper manager-core**" * linux - "**git config --global credential.helper store**" Минус в том что хранится в открытом виде, есть варианты **store/cache**, второй хранит 15 минут и только в памяти\\ # Установка\\ apt git install\\
# Инициализация проекта cd /'project' && git init # Добавить удаленный репозиторий git remote add (или origin для репы по умолчанию) https://github/uset/repo # например git remote add origin git@github.com:ncily/gh_actions.git # Отправка проекта # Добавление файлов к проекту git add . (file1 file2 ...) # Фиксация изменений (-m коммент, -a применить ко всем либо к указанным файлам) git commit -m "Text comment" -a (or changed-file1) # Отправка на удаленный репозиторий git push [ветка] # Скачивание git pull [origin] git checkout [master] # Проверка ключа ssh -T git@github.com ssh -vT git@github.com # Авторизация по SSH После создания пары ключей SSH вам необходимо добавить открытый ключ на GitHub.com, чтобы включить доступ по SSH для вашей учетной записи В параметрах уч записи в ГХ, добавляем SSH-ключ, саписываем туда содержимое файла ".ssh/id_rsa.pub" нужно учетки После этого, проверяем авторизацию командой "ssh -T git@github.com"
:!: Работа с внешними репами [[https://git-scm.com/book/ru/v2/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D1%83%D0%B4%D0%B0%D0%BB%D1%91%D0%BD%D0%BD%D1%8B%D0%BC%D0%B8-%D1%80%D0%B5%D0%BF%D0%BE%D0%B7%D0%B8%D1%82%D0%BE%D1%80%D0%B8%D1%8F%D0%BC%D0%B8|Дока]] git remote [-v] git remote add (origin для репы по умолчанию) git remote remove/rename git remote show # Отправить изменения git push [branch] # Скачать изменения git pull (или без указания, origin по умолчанию) git fetch
:!: Ветки [[https://git-scm.com/book/ru/v2/%D0%92%D0%B5%D1%82%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B2-Git-%D0%A3%D0%BF%D1%80%D0%B0%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B2%D0%B5%D1%82%D0%BA%D0%B0%D0%BC%D0%B8|Дока]]\\ **Слияние** выполняется из той ветки в которую нужно добавить указанную (переходим в мастер и указываем ветку которую хотим в него добавить)\\ Слияние происходит в точке ответвления, если после ответвления, в источнике, данном месте были изменения, это вызывает конфликт слияния, решать который нужно вручную\\ **Rebase** в целом тоже самое что и слияние, но работает иначе, слияние совмещает последние коммиты веток, а перебазирование вставляет последний коммит в точку ответвления и применяет последовательно всю историю изменений, получается, тем самым делая его обновленной копией последнего коммита в мастере (в которую сливается)\\ [[https://git-scm.com/book/ru/v2/%D0%92%D0%B5%D1%82%D0%B2%D0%BB%D0%B5%D0%BD%D0%B8%D0%B5-%D0%B2-Git-%D0%9F%D0%B5%D1%80%D0%B5%D0%B1%D0%B0%D0%B7%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5|Дока]]\\ git branch [-v] # Слитые [не слитые] ветки git branch --merged [--no-merged] [name] # Удалить (удалится только слитая ветка, -D для удаления не слитых) git branch -d git branch --all # Переключение веток и загрузка их в рабочий каталог git checkout <существующая ветка> git checkout -b <новая ветка> # История коммитов git log <имя ветки> <--all> git log --oneline --decorate --graph --all
:!: Коммиты # Удалить последний коммит (сдвинуть указатель на шаг назад) # Удаленный репозиторий может не принять такой прикол, для пуша добавляем --force git reset --hard HEAD~1 [либо хэш-код] # Слияние с предыдущим коммитом git commit --amend # Разница между текущим состоянием и указанным коммитом git diff # Работа с тегами git push --delete origin refs/heads/ git push --delete origin refs/tags/ git tag -d Коммит это слепок, содержит **blob (большой бинарный) объект**, и хеш сумму каждого файла, в т.ч. дерево каталогов.\\ Каждый коммит содержит **ссылку на предыдущий** так формируется цепочка.\\ **Ветка** это ничто иное как **условный указатель** на последний коммит, который будет указан родителем следующему. **Master** абсолютно обычная ветка, просто умолчательная и по наитию используется как основная\\ {{ :develop:git0.jpg?direct&500 |}} **HEAD** это указатель на текущую, локальную ветку, используемую сейчас, увидеть ее можно в команде **git log**\\ | {{ :develop:git1.jpg?direct&600 |}} | {{ :develop:git2.jpg?direct&600 |}} | При переходе между ветками, **заменяется все содержимое рабочего каталога**, файлы автоматически подменяются\\
:!: Общее/Ошибки/Использование **.gitignore**\\ В файле просто перечисляются файлы/папки или их шаблоны, которые нужно игнорировать для загрузки, может располагаться в корне\\ Ошибка "git submodule update failed with 'fatal: detected dubious ownership in repository at'"\\ git config --global --add safe.directory '*' либо в конфиге [safe] directory = *
:!: Общие примеры # Теги (полный путь для тегов, который не пересекается с ветками- :refs/tags/tagname) git push origin :tagname git push --delete origin tagname git tag --delete tagname // удалить локальный тег # создание тега ./execute_on_all_repos.sh git tag -a "1863.9" -m "1863.9" # запушить вроде так долджно быть ./execute_on_all_repos.sh git push origin "1863.9" # Удаление тегов ./execute_on_all_repos.sh git push --delete origin refs/heads/1830 # Удалить удаленную ветку git push origin --delete 1854_norm ./execute_on_all_repos.sh git push origin --delete 1854_norm # Удалить локальную ветку git branch --delete -D 1854_norm ./execute_on_all_repos.sh git branch --delete -D 1854_norm # Генерирует уникальную строку, на основании последнего тега, с добавлением хеша последнего коммита # В данном случае для мозговой сборки, вида "1862.1-14-g9f97cdb7dc" git describe # Можно задать шаблон для отбора имеющихся тегов, здесь берет мгашный тег, на выходе: "mga.18.0.51129-18-g9f97cdb7dc" git describe "--match=mga*" --abbrev=8 # Эта команда фильтрует по маске и возвращает перечень имеющихся тегов git ls-remote --quiet --tags --refs --sort=-version:refname | grep -oP mga.* git ls-remote --quiet --tags --refs --sort=-version:refname | grep -oP 'refs/tags/\K' git ls-remote --quiet --tags --refs | grep -oP 'refs/tags/\K\d{4}\.\d+' // автосгенерированный либо релизный тег git describe --match=[0-9]* --abbrev=8 | tr -s '\r\n' ' ' | sed 's/ //g'
:!: Интеграция GitHub и Jenkins [[https://www.blazemeter.com/blog/how-to-integrate-your-github-repository-to-your-jenkins-project|Источник]]\\ :!: SCM (Source Control Management) Один из вариантов в проекте ГХ создаем вебхук, с указанием адреса дженкинса, указываем по каким событиям отправлять триггер, в дженкинс.\\ Затем в джобе дженкинса, указываем адрес репозитория, в "Build Trigger", "GitHub hook trigger for GITScm polling" и вроде как все\\ В тоже время есть и другие варианты "Build Trigger", возможно в них можно обойтись без вебхука на стороне ГХ и указания адреса дженкинса\\ Так, чтобы работать из репы, нужно код пайплайна разместить там и выбрать "Pipeline script from SCM"
:!: Экспорт из GitLab в GitHub Работает в т.ч. и как актуализация уже существующего экспорта в GH\\ [[https://stackoverflow.com/questions/22265837/transfer-git-repositories-from-gitlab-to-github-can-we-how-to-and-pitfalls-i|Source]]\\ [[https://github.com/piceaTech/node-gitlab-2-github|Source2]]\\ # from gitLab git clone --mirror git@your-gitlab-site.com:username/repo.git cd repo # to gitHub git push --no-verify --mirror git@github.com:username/repo.git
:!:
:!: Old **Общее** Есть 4 основных элемента: **Рабочий каталог**, **Промежуточная область**, **Локальный репозиторий**, **Удаленный репозиторий**\\ {{:develop:git_0.png?direct&400|}} * **git add** - добавление файла из рабочего каталога в промежуточную область * **git commit** - из промежуточной области в локальный репозиторий * **git push** - загрузка из локального репозитория в удаленный * **git fetch** - скачивание из удаленного репозитория в локальный * **git merge** - перенос из локального репозитория в рабочий каталог * **git pull** - получение удаленного репозитория сразу в рабочий каталог, две предыдущие команды вместе ** Установка ** Нормальный клиент здесь- [[https://gitforwindows.org/]]\\ После установки делаем подпись, в "git bash" пишем: $ git config --global user.name "YourName" $ git config --global user.mail "YourMail" $ git config --global -- list ** Доступ SSH ** Затем настраиваем сертификат, для без парольного доступа.\\ git bash: # Генерация ключевой пары (можно: -t rsa -b 4096 -C) $ ssh-keygen -t ed25519 -C "YourEMail" Вводим имя файла, парольную фразу можно не вводить, чтобы не вводить ее при каждом обращении в git\\ После завершения, файлы будут в домашней директории пользователя, помещаем их в "~/.ssh" \\ закрытый ключ переименовываем в "id_rsa" (тут **неясный момент!**)\\ Содержимое открытого ключа (".pub") копируем при создании ключа в лк git'a, там нужно добавить ключ, с содержанием этого открытого ключа\\ Так же нужно добавить созданных ключ агенту авторизации $ eval "$(ssh-agent -s)" $ ssh-add ~/.ssh/id_ed25519 После пишем: **"$ ssh -T git@github.com"** (можно добавить -vT, для расширенного вывода), для принятия сертификата, в ответе должна фигурировать строка типа: "Hi "YourName"! You've successfully authenticated, but GitHub does not provide shell access", если так, тогда все норм\\ ** Траблы с тортилой ** При установке стоило совершить один неверный шаг и выбрать тортилу как транспорт, п*зда, от нее нет спасения, работать она не работает, с таким подходом во всяком случае, и сменить никак не удавалось долгое время, в итоге заменил переменную окружения **GIT_SSH**, установил путь к стандартной утилите ("C:\Program Files\Git\usr\bin\ssh.exe") и заработало.\\ ** Использование ** Репозитории создаются и далее привязаны к конкретным каталогам, для работы с репозиторием нужно перейти в его каталог.\\ ** Инициализация репозитория ** Переходим в созданный каталог: "**$ git init**"\\ ** Добавление файлов ** Добавление в промежуточную область: "**$ git add .**"\\ Точка добавит все, можно указать конкретные, либо маску\\ Просмотр состояния: "**git status**" ** Фиксация изменений ** Фиксация изменений в файлах: "**$ git commit -m "text-comment"**"\\ Отмена фиксации: "**$ git reset HEAD~1**"\\ ** Удаленный источник ** Добавление: "**$ git remote add origin **"\\ Список доступных: "**$ git remote -v**"\\ ** Дополнительно ** # Изменения в файлах: $ git diff # История фиксаций: $ git diff- ???? # Мержинг если есть конфликты коммитов $ git merge --allow-unrelated-histories
===== Применение =====
:!: Кейсы **Сборка с незасабмиченным топиком из геррита**\\ Переходим в начальную ветку, например мастер, на вкладке геррите ищем по ИД нужный коммит, важно, нужно начинать с последнего коммита в этом топике, в этот репозиторий, можно посмотреть по порядковому номеру, есть в url\\ Находим последний коммит, чекаутимсяв него, после этого, на вкладке гита, уже будут присутствовать все предыдущие коммиты этого топика, в этой репе\\ Если есть коммиты из другой репы, аналогично, находим последний, чекаутимся, проверяем что в гите есть все предыдущие\\ Создаем ветку, пушим ее\\
:!: Пример слияния репозиториев Точнее включение одного репозитория в другой, подпроектом\\ # Клонируем тот репозиторий, который будет мержиться git clone https://github.com/first-repo cd first-repo git remote rm origin # На всякий случай отвязываем репозиторий # Подготавливаем репозиторий: перемещаем всё содержимое репозитория (за исключением папки .git) в отдельную папку, которая и будет подключаться в другой репозиторий mkdir first_repo git mv $(ls -A | grep -v first_repo | grep -v .git) first_repo/ git commit -m "prepare repo for merging in main_repo - move all to new subdir" # Клонируем рядом целевой репозиторий cd .. git clone https://github.com/main_repo cd main_repo/ # Подключаем к нему подготовленный первый репозиторий и вытаскиваем его master в отдельную ветку first-repo git remote add first-repo ../first-repoe/ git fetch first-repo git branch first-repo remotes/first-repo/master # Мержим ветку в локальный master git merge first-repo --allow-unrelated-histories git remote rm first-repo # Проверяем и пушим git log git push
:!: Cмена Remote git remote -v # View existing remotes # origin https://github.com/user/repo.git (fetch) # origin https://github.com/user/repo.git (push) git remote set-url origin https://github.com/user/repo2.git # Change the 'origin' remote's URL git remote -v # Verify new remote URL # origin https://github.com/user/repo2.git (fetch) # origin https://github.com/user/repo2.git (push)
===== =====