Gitea レポジトリのアーカイブを保存する

bash scriptを使います

目的は、local ipで長らく使っていたGiteaのサーバー上のアーカイブをまとめてセーブしておきたいということです。流れとしてはメインのサーバーにまとめていき、local ipの方は電源を切りたいということです。最終形は、

#!/bin/bash

# Configuration
GITEA_URL="http://192.168.0.147:3000"
OWNER="nao"
TOKEN="your-original-access-token-here"
IS_ORG=false # Change to true if OWNER is an Organization instead of a personal User

PAGE=1
PER_PAGE=50

# Determine correct endpoint based on account type
if [ "$IS_ORG" = true ]; then
  ENDPOINT="${GITEA_URL}/api/v1/orgs/${OWNER}/repos"
else
  ENDPOINT="${GITEA_URL}/api/v1/users/${OWNER}/repos"
fi

while true; do
  echo "Fetching repositories from page ${PAGE}..."

  # Fetch a page of repositories
  RESPONSE=$(curl -s -X GET "${ENDPOINT}?page=${PAGE}&limit=${PER_PAGE}" \
    -H "Authorization: token ${TOKEN}")

  # Extract repo names and default branches
  # Format: "repo_name:default_branch"
  REPOS=$(echo "$RESPONSE" | grep -o '"name":"[^"]*","full_name"[^}]*' | sed -E 's/.*"name":"([^"]*)".*"default_branch":"([^"]*)".*/\1:\2/')

  # Break the loop if no repositories are returned on this page
  if [ -z "$REPOS" ]; then
    echo "No more repositories found."
    break
  fi

  # Process each repository found on the current page
  echo "$REPOS" | while IFS=: read -r REPO_NAME DEFAULT_BRANCH; do
    # Skip if the repository is completely empty (no default branch found)
    if [ -z "$DEFAULT_BRANCH" ] || [ "$DEFAULT_BRANCH" = "null" ]; then
      echo "Skipping [${REPO_NAME}]: Repository is empty or has no commits."
      continue
    fi

    echo "Processing [${REPO_NAME}] -> Default branch: ${DEFAULT_BRANCH}"
    echo "Downloading archive..."

    curl -s -X GET \
      "${GITEA_URL}/api/v1/repos/${OWNER}/${REPO_NAME}/archive/${DEFAULT_BRANCH}.zip" \
      -H "Authorization: token ${TOKEN}" \
      -o "${REPO_NAME}-${DEFAULT_BRANCH}.zip"

    echo "Saved as ${REPO_NAME}-${DEFAULT_BRANCH}.zip"
    echo "----------------------------------------"
  done

  # Advance to the next page
  ((PAGE++))
done

echo "All downloads completed!"

ほぼGemini君に作ってもらいました。branchがmasterの場合とmainの場合に分かれており、empyなrepositoryでエラーが出ないような工夫を指示しました。実行時の様子は、

nao@ghost:~/gemini$ ./git2.sh
Fetching repositories from page 1...
Processing [648-15-final] -> Default branch: master
Downloading archive...
Saved as 648-15-final-master.zip
----------------------------------------
Processing [alt.embarcadero] -> Default branch: master
Downloading archive...
Saved as alt.embarcadero-master.zip
....<途中略>
----------------------------------------
Processing [exif-handling] -> Default branch: main
Downloading archive...
Saved as exif-handling-main.zip
----------------------------------------
Processing [8led-stripe] -> Default branch: master
Downloading archive...
Saved as 8led-stripe-master.zip
----------------------------------------
Fetching repositories from page 4...
No more repositories found.
All downloads completed!

若干の時間はかかりますが、この場合は、104個のアーカイブが全てセーブできました。repositoryがemptyの場合はエラーで止まらず、サイズが小さいアーカイブとして保存されます。中身は*.zipではありません。

nao@ghost:~/gemini$ cat next-master.zip
Internal Server Error

ファイルサイズが22バイトなので、grep すると。

nao@ghost:~/gemini$ grep " 22" archive.lst
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 other-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 alt-worked-ya-smtpxoauth-pasversion-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 dummy-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 foobartemps-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 yetanotherfoobar-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 proichain-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 cryptopp870-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:12 foobar-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:11 alt-repo-list-delete-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:10 repo-list-delete-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:09 opencv-cameralib-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:09 nextaa-master.zip
-rw-rw-r-- 1 nao nao        22  8月  2 13:09 next-master.zip
nao@ghost:~/gemini$ grep " 22" archive.lst | wc -l
13

104個のrepositoryのうち、13個がemptyでした。多いかね。createしたけど、放っておいたわけですね。

Git for WindowsのBashでも完遂しました。最後だけ、

Processing [which-one] -> Default branch: master
Downloading archive...
Saved as which-one-master.zip
----------------------------------------
Fetching repositories from page 3...
Processing [exif-handling] -> Default branch: main
Downloading archive...
Saved as exif-handling-main.zip
----------------------------------------
Processing [8led-stripe] -> Default branch: master
Downloading archive...
Saved as 8led-stripe-master.zip
----------------------------------------
Fetching repositories from page 4...
No more repositories found.
All downloads completed!

Linuxなマシンがなくても、Git for Windowsが使えれば、このスクリプトは使えます。同様にしてGitHubやGitLab用のスクリプトも作成できると思います。net上を丹念に探すか、探しているとCopilot君やGemini君が口を挟んできますから、そちらに乗っかる手もありますね。もちろんChappy君でも可です。拡散しない範囲で、動くものを使いましょう。動作確認に明け暮れて、実用にならないことは、bash scriptでもありますよね。AIへのお伺いは、あくまで参考程度にとどめましょう。

Gitea->GiteaあるいはGitHub->Gitea、GitLab->Giteaならば拙作のRemote Repository Managerを試して見るのも良いと思います。保証はしませんが。

コメント