Files
lpra/docs/gitlab-migration.md
T

145 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Перенос проекта с GitHub на GitLab с сохранением истории и дат
Инструкция для локального репозитория, когда GitHub недоступен (аккаунт заблокирован) и
переносить приходится из своей копии. Так был перенесён `lpra`: 195 коммитов, 8 тегов,
3 релиза - хэши и даты совпали.
## Что сохраняется, а что нет
| Что | Сохраняется? |
|---|---|
| Даты коммитов (автора и коммита) | **Да, точно.** Они хранятся внутри коммита; push той же истории не меняет ни одного хэша |
| Ветки и теги | Да, если они есть локально (см. шаг 2) |
| Дата создания проекта | **Нет.** На gitlab.com она всегда - день создания проекта, задним числом не ставится. Начало проекта видно по первому коммиту |
| Релизы | Создаются заново, **с исходной датой** (`--released-at`); файлы релизов - заново собрать или взять свои копии |
| Issues, PR, звёзды, Actions | Нет: при заблокированном GitHub их не выгрузить |
**Нельзя:** `rebase`, `squash`, `filter-branch`, `filter-repo`, `commit --amend` по старым
коммитам, «Import from GitHub» с чужой копии - всё это переписывает коммиты и их даты.
## 0. Один раз: вход в GitLab
```sh
brew install glab
glab auth login --hostname gitlab.com --web --git-protocol https
```
Вход через браузер даёт права и на push, и на релизы. Git берёт пароль у glab - для каждого
репозитория это настраивается в шаге 4 (или один раз для всех:
`git config --global credential.https://gitlab.com.helper '!glab auth git-credential'`).
SSH-ключ тоже подойдёт, но в GitLab у ключа должен быть **Usage type: Authentication & Signing**
(с типом «Signing» по SSH не пускает).
## 1. Пустой проект в GitLab
https://gitlab.com/projects/new → **Create blank project** → имя, владелец `itzRedTea`.
**Снять галочку «Initialize repository with a README»** - иначе в проекте появится свой первый
коммит, и историю придётся склеивать.
Или из терминала:
```sh
glab repo create itzRedTea/ИМЯ --public # или --private; README не создаётся
```
## 2. Проверить, что всё есть локально
```sh
cd ~/CodeRepos/ИМЯ
git status # незакоммиченное закоммитить или убрать
git branch -a # ветки: свои и remotes/origin/*
git tag -l # теги
```
- Ветки, которых нет локально, но есть `remotes/origin/X`, тоже переносятся (шаг 3).
- **Теги, созданные на GitHub при публикации релиза, могут не быть локально** - если их не
делали `git fetch --tags`. Такой тег создаётся заново на нужном коммите (шаг 5). Коммит
ищется по дате публикации релиза: последний коммит перед ней
(`git log --format='%h %cd %s' --date=iso --until='ДАТА'`).
Снимок до переноса - для сверки:
```sh
git log --branches --remotes=origin --tags --format='%H %aI %cI' | sort > /tmp/before.txt
git show-ref --tags | sort > /tmp/tags-before.txt
```
## 3. Отправить историю
```sh
git remote rename origin github # GitHub остаётся под своим именем
git remote add origin https://gitlab.com/itzRedTea/ИМЯ.git
H='!glab auth git-credential'
git -c credential.helper= -c "credential.helper=$H" push origin --all # все локальные ветки
git -c credential.helper= -c "credential.helper=$H" push origin 'refs/remotes/github/*:refs/heads/*' # ветки, что были только на GitHub
git -c credential.helper= -c "credential.helper=$H" push origin --tags
```
Вторая команда push может сказать про `HEAD` - это не ветка, сообщение можно не смотреть.
## 4. Сверить и переключиться
Сверка - по свежей копии из GitLab:
```sh
rm -rf /tmp/check && git clone -q https://gitlab.com/itzRedTea/ИМЯ.git /tmp/check
cd /tmp/check && git log --remotes=origin --tags --format='%H %aI %cI' | sort > /tmp/after.txt
git show-ref --tags | sort > /tmp/tags-after.txt
diff /tmp/before.txt /tmp/after.txt && echo "коммиты и даты совпали"
diff /tmp/tags-before.txt /tmp/tags-after.txt && echo "теги совпали"
```
Пустой `diff` - история перенесена один в один. Дальше работать с GitLab:
```sh
cd ~/CodeRepos/ИМЯ
git config --local credential.https://gitlab.com.helper '!glab auth git-credential'
git fetch origin && git branch -u origin/main main
```
## 5. Релизы с исходными датами
Дата - время публикации релиза на GitHub (UTC). Файлы - свои копии или сборка из коммита
релиза во временной папке:
```sh
git worktree add --detach /tmp/rel-1.2.0 1.2.0 # тег или хэш коммита релиза
cd /tmp/rel-1.2.0 && ./build.sh # как проект собирается
glab release create 1.2.0 bin/файл1 bin/файл2 \
-R itzRedTea/ИМЯ --name "Release 1.2.0" \
--released-at "2026-10-15T16:34:53Z" \
--notes "Перенесено с GitHub, дата публикации исходная."
# тега нет (его делал GitHub) - добавить: --ref <полный хэш коммита>
git worktree remove /tmp/rel-1.2.0
```
Создавать по порядку, от старых к новым. Последним GitLab считает релиз с самой поздней
датой. Ссылки на файлы:
- конкретный релиз: `https://gitlab.com/itzRedTea/ИМЯ/-/releases/ТЕГ/downloads/ФАЙЛ`
- последний: `https://gitlab.com/itzRedTea/ИМЯ/-/releases/permalink/latest/downloads/ФАЙЛ`
## 6. Ссылки в самом проекте
Найти и заменить всё, что смотрит на GitHub:
```sh
grep -rn "github.com\|githubusercontent" --exclude-dir=.git .
```
| GitHub | GitLab |
|---|---|
| `https://raw.githubusercontent.com/USER/ИМЯ/main/ПУТЬ` | `https://gitlab.com/itzRedTea/ИМЯ/-/raw/main/ПУТЬ` |
| `https://github.com/USER/ИМЯ/releases/latest/download/ФАЙЛ` | `https://gitlab.com/itzRedTea/ИМЯ/-/releases/permalink/latest/downloads/ФАЙЛ` |
| `https://api.github.com/repos/USER/ИМЯ/releases/latest` (`tag_name`) | `https://gitlab.com/api/v4/projects/itzRedTea%2FИМЯ/releases/permalink/latest` (`tag_name`) |
| `https://api.github.com/repos/USER/ИМЯ/contents/ПАПКА?ref=main` | `https://gitlab.com/api/v4/projects/itzRedTea%2FИМЯ/repository/tree?path=ПАПКА&ref=main` (поле `path`) |
| картинки `github.com/user-attachments/...` | скачать, пока открываются, в `docs/` и ссылаться на файлы |
Путь Go-модуля (`module github.com/...` в `go.mod`) можно не трогать: это только имя.
## 7. После переноса
- Описание проекта в GitLab: «Перенесён с GitHub, начат ДД.ММ.ГГГГ» - раз дата создания новая.
- Токены, которые светились в чатах и логах, - отозвать и выпустить новые.