Там царь Кащей над златом чахнет, или как сохранить все старые репозитории в один включая историю git

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

В 2017-2018 я учился в филиале французской школы 42 и мне приходилось много писать на Си. Было много учебных проектов, начиная от реверс-инжениринга стандартной библиотеки Си, printf, sha/md5/des алгоритмов, заканчивая своими собственными проектами, которые не имели отношения к Школе 42. Был простенький DNS proxy, сниффер сетевых пакетов, реверс-инжениринг игры Сапер. Сейчас я понимаю насколько ужасен тот код, но хочется его сохранить как память о бессонных ночах над сегфолтами, бас ероррами, потерянными указателями, утечках памяти. Два десятка репозиториев воспоминаний.

Мой github давно хотел чистки, и я все откладывал идею сделать полностью автоматический сборщик до более свободных дней. И вот у меня четвертый день кашель и второй день температура 37,5 - спать не получается - настало время доделать "хотелку". Репозиторий для проекта я создал несколько месяцев назад, но руки так и не доходили сделать.

Сбор требований

Скриншот моего архива в Github
Скриншот моего архива в Github
  1. Скрипт должен складывать каждую ветку проекта в отдельную папку

  2. Скрипт должен сохранять историю коммитов

  3. Скрипт должен быть устойчив к мердж конфликтам типа (rename/rename)

  4. Скрипт должен работать через Gihub Actions и запускать вручную

  5. Скрипт должен принимать переменными окружения репозиторий архива, архивируемый репозиторий, основную ветку архива в которую сливать все, а так же токен и имя пользователя github, чтобы запушить новое

  6. Скрипт должен работать без вмешательства через консоль (например с браузера телефона можно добавить в архив новый проект)

  7. Скрипт должен быть максимально простым, чтобы побудить людей поучаствовать в его доработке (<3 open source)

Реализация

Согласно списку требований я решил написать сам скрипт на баше, хотя я в нем и не силен. Логика довольно простая: получаем список веток, копируем содержимое проекта и переносим все в подпапку, коммитимся, повторяем для всех веток, потом добавляем новый удаленный репозиторий, и мерджим все ветки в архив. Но есть один нюанс, если мы переносим все в подпапку, а потом тоже самое делаем с соседней веткой - мы можем получить мердж конфликт типа (rename/rename). Поэтому пришлось добавить коммит в одном месте, который не сработает, если нет мердж конфликта (гит проигнорирует команду, так как нечего коммитить), но если был мердж конфликт (rename/rename) - проблему решит просто git add . && git commit.

По комментарию коммитов видно, что ветка master слилась без проблем, а на ветке fps был конфликт (rename/rename), который разрешился обычным  git add . && git commit.
По комментарию коммитов видно, что ветка master слилась без проблем, а на ветке fps был конфликт (rename/rename), который разрешился обычным git add . && git commit.

Код конфига для Gihub Actions:

name: archivist
on:
  workflow_dispatch:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout Archived Repository
        uses: actions/checkout@v2
        with:
          repository: ${{ secrets.ARCHIVED_REPOSITORY }}
          token: ${{ secrets.WRITE_GITHUB_TOKEN }}
          path: archived
          fetch-depth: 0
      - run: |
          cd ./archived
          git config user.name github-actions
          git config user.email github-actions@github.com
          existBranches=($(git branch -a | grep remotes | awk -F '/' '{ print $3  }'));
          for i in "${existBranches[@]}"; do
               git checkout -- .
               git checkout -b ${i}-move origin/${i} || true
               git reset --hard HEAD
               mkdir -p ../tmp/${{ secrets.ARCHIVED_REPOSITORY }}
               mv ./.git ../tmp/.git
               cd ..
               mv ./archived/ tmp/${{ secrets.ARCHIVED_REPOSITORY }}/${i}/
               cd ./tmp/
               git add .
               git commit -m "Preparing ${{ secrets.ARCHIVED_REPOSITORY }}/${i} for move"
               cd ../
               mv ./tmp/ ./archived/
               cd ./archived
               done;
          git config -l | grep 'http\..*\.extraheader' | cut -d= -f1 | xargs -L1 git config --unset-all
          git remote add archive "https://${{ secrets.GIT_USERNAME }}:${{ secrets.WRITE_GITHUB_TOKEN }}@github.com/${{ secrets.ARCHIVE_REPOSITORY }}"
          git fetch archive
          git checkout -b tmp_${{ secrets.ARCHIVE_REPOSITORY_DEFAULT_BRANCH }} archive/${{ secrets.ARCHIVE_REPOSITORY_DEFAULT_BRANCH }} || true
          for i in "${existBranches[@]}"; do
               git merge ${i}-move --allow-unrelated-histories --no-edit --no-ff > /dev/null 2>&1 || true
               git add .
               git commit -m "resolve conflicts for ${{ secrets.ARCHIVE_REPOSITORY }}/$i" || true
               git push --force --quiet "https://${{ secrets.GIT_USERNAME }}:${{ secrets.WRITE_GITHUB_TOKEN }}@github.com/${{ secrets.ARCHIVE_REPOSITORY }}" tmp_${{ secrets.ARCHIVE_REPOSITORY_DEFAULT_BRANCH }}:${{ secrets.ARCHIVE_REPOSITORY_DEFAULT_BRANCH }}
          done;
          >&2 echo "All done" ;

Итоги

Скрипт я написал за пару часов, и потом еще минут 40 потратил чтобы слить туда более 20 репозиториев (и наконец-то их удалить). Конечно хотелось бы сразу добавить список, но мне подошло и текущее решение. В любой момент можно добавить новый проект в архив.

Ссылка на проект https://github.com/setnemo/bygone

Ссылка на архив https://github.com/setnemo/archive

Источник: https://habr.com/ru/post/570404/


Интересные статьи

Интересные статьи

«Если вы хотите, чтобы другие последовали за вами, научитесь оставаться наедине со своими мыслями». Я сейчас делаю Ontol — это Github для знаний/мудрости. Онтол — это курируемые спис...
Весной 2020 года я впервые попробовал себя в разработке сайтов бэкенд я писал на питоне а на фронте пришлось использовать js и он вызвал у меня отторжение(тут надо уточни...
Приветствую, Хабр! Меня зовут Павел Воропаев, я Software Engineer в компании Exness. Ранее успел поработать в разных российских компаниях в качестве фулстек разработчика, разработчика баз...
Ученые охотятся за одиночеством, чтобы помочь нам лучше понять цену социальной изоляции.Задолго то того, как мир услышал о COVID-19, профессор Кей Тай, нейробиолог, решила ответить ...
Считается, что одним из первых инструментов, который освоили люди, были флейты. Расскажем о тех, что сделали неандертальцы, и тех, что остаются частью культуры отдельных народов. ...