SSD Nodes Learn 🎉 VPS $5.50/月〜
ガイド Matt Connor著者 Matt Connor ・更新日 2026-08-09

GitHubとは?GitとVPSでの違いを解説

Gitは手元のPCやサーバーで動くバージョン管理プログラム、GitHubはGitを使うホスティングサービスです。VPSの設定履歴やデプロイでの違いを、具体例で説明します。

GitHub とは何ですか?

GitHub は、Git リポジトリを保存し、その周囲に Web サイトを構築するホスティングサービスです。Git は、自分のコンピューターやサーバー上で動作するバージョン管理プログラムです。GitHub は Git を基盤とする 1 社の製品であり、2018 年以降は Microsoft が所有しています。Git は毎日使用しながら、GitHub を一度も開かないこともできます。Git なしで GitHub を使用することはできません。

この違いは、VPS(virtual private server)を所有した時点で重要になります。Git は、設定ファイルとデプロイスクリプトの変更履歴を記録します。GitHub は、サーバー上にその履歴がない場合にコピーを保存する場所であり、ビルドやレビューを実行する場所でもあります。このガイドでは、空のフォルダーからサーバーへのデプロイまでを 1 つの例に沿って説明します。また、新しい用語は最初に登場した時点で定義します。

Git が自動的に行うこと

Git はバージョン管理システムです。ディレクトリの状態を時間の経過に沿って記録するため、何が、いつ、なぜ変更されたかを確認できます。Git は Linux カーネルの開発向けに 2005 年に作成されました。Git は 分散型 です。つまり、リポジトリの各コピーが履歴全体を保持します。設計上、中央サーバーはありません。同僚の laptop も、サーバーと同じく完全なコピーです。

Git をインストールし、ユーザー情報を設定します。Git は名前とメールアドレスが設定されていないとコミットを記録しません。どちらもコミット自体に書き込まれるためです。

sudo apt update && sudo apt install -y git
git --version
git config --global user.name "Your Name"
git config --global user.email "you@example.com"

Ubuntu 24.04 では、git --version により git version 2.43.0 が出力されます。ここ数年のリリースであれば、以下の内容はすべて同じように動作します。

例: VPS のデプロイファイル用リポジトリ

リポジトリ(通常は「repo」と略します)は、Git が監視するディレクトリです。git init を実行すると、そこに非表示の .git フォルダーが作成され、リポジトリになります。このフォルダーがリポジトリ本体です。.git を削除すると、履歴のない通常のディレクトリだけが残ります。

mkdir vps-deploy && cd vps-deploy
git init -b main
printf '.env\n*.key\n' > .gitignore

-b main は最初のブランチに main という名前を付けます。これを省略すると、Git はデフォルトブランチ名に関する長いヒントを表示します。.gitignore には、Git が決して追跡してはならないパスを記載します。初日に Secret ファイルをここへ追加してください。一度コミットしたファイルは削除しても履歴に残るため、完全に削除するには、その後に作成されたすべてのコミットを書き換える必要があります。

履歴の単位であるコミット

次にスクリプトを追加して、記録します。

printf '#!/bin/sh\nsudo systemctl restart caddy\n' > restart.sh
git add restart.sh .gitignore
git commit -m "Add restart script and gitignore"
git log --oneline

git addは変更をステージングエリアに移します。ステージングエリアは、次のコミットに含める項目の一覧です。git commitは、その一覧を1つのエントリとして履歴に書き込みます。コミットには、追跡対象であるすべてのファイルのスナップショット、メッセージ、作成者、タイムスタンプ、直前のコミットへのポインターが含まれます。git log --onelineはコミットごとに1行を表示します。各行は、a1b2c3dのような短いハッシュで始まります。このハッシュがコミット名であり、Gitのほぼすべてのコマンドで指定できます。

git addの手順を省略すると、git commitno changes added to commit (use "git add" and/or "git commit -a")と応答します。問題はありません。Gitは、ステージングエリアが空であり、スナップショットを作成する対象がないことを通知しています。git statusは、状況が分からなくなったときに実行するコマンドです。現在のブランチ、ステージング済みの変更、Gitが認識しているものの追跡していないファイルを表示します。

ブランチ: 履歴のもう 1 つの系統

ブランチは、コミットを指す可動ポインターです。main はブランチであり、Git にとって特別なものではありません。ブランチの作成にコストはかかりません。Git はファイルをコピーするのではなく、新しいポインターを書き込むためです。

git switch -c add-backup
printf '#!/bin/sh\nrestic backup /srv\n' > backup.sh
git add backup.sh
git commit -m "Add nightly backup"
git switch main
ls

git switch main の後、一覧から backup.sh がなくなっています。何も削除されていません。そのファイルは add-backup ブランチには存在しますが、main には最初から存在しませんでした。そのため、移動したときに Git が作業ディレクトリから削除しました。これは一度は誰もが戸惑う動作です。git switch add-backup で元に戻せます。

Remotes: GitHub がついに登場する場所

ここまでの操作はすべて、ネットワーク接続なしで 1 台のマシン上で行ってきました。remote は、同じリポジトリの別のコピーを指す名前付き URL です。GitHub は、そのコピーの 1 つをホストします。メインの remote に付ける慣例的な名前は origin です。

GitHub の Web サイトで空のリポジトリを作成し、それに接続します。ここでは HTTPS より SSH を推奨します。SSH key は自分で管理するファイルであり、personal access token のように期限切れにならないためです。

ssh-keygen -t ed25519 -C "vps-deploy"
cat ~/.ssh/id_ed25519.pub
ssh -T git@github.com

表示された public key を GitHub アカウントの SSH keys ページに貼り付け、テストをもう一度実行します。動作する key は Hi yourname! You've successfully authenticated, but GitHub does not provide shell access. と応答します。GitHub は shell を提供しないため、この拒否応答が成功です。git@github.com: Permission denied (publickey). は、key が提供されなかったか、受け入れられなかったことを意味します。.pub ファイルを、その隣にある private key ではなく貼り付けたことを確認してください。

git remote add origin git@github.com:yourname/vps-deploy.git
git push -u origin main

git push はコミットを remote に送信します。-u は、ローカルの main が remote の main を追跡することを記録します。そのため、後からは単に git push と実行するだけで済みます。新しいマシンでの git clone <url> はその逆です。履歴を含むリポジトリ全体をコピーし、origin を自動的に設定します。HTTPS remote も使用できます。Web ページと同じプロトコルで通信するため、外向きの port 22 をブロックするネットワークで役立ちます。この説明を詳しく確認したい場合は、実際の HTTP request の構成要素 で仕組みを説明しています。

プルリクエスト、Issue、Fork:GitHubに固有で、Gitにはない機能

ここまでの内容はすべてGitの機能であり、どのサーバーでも利用できます。以下の3つはGitHubの機能です。他のホスティングサービスもこれらを取り入れていますが、Git自体はこれらを認識しません。

プルリクエスト(PR)は、あるブランチを別のブランチへマージするための依頼であり、ディスカッション用のページが付随します。add-backupをpushして、mainに対するPRを開くと、サイト上でコミットごとの差分を確認できます。特定の行にコメントを付けることもできます。自動チェックは、ブランチに対する成功または失敗を報告します。Mergeをクリックすると、GitHubが独自のコピー上でマージを実行し、その後mainを更新します。この名称は、メンテナーに自分のブランチを自分のブランチへ「pull」してもらう、という元々のワークフローに由来します。

Issueは、バグや作業項目を記録する番号付きのスレッドです。Issueはリポジトリ内ではなく、GitHubのデータベースに保存されます。ホスティングサービスを選ぶ前に、この点を理解しておく必要があります。リポジトリをcloneすればすべてのコミットを取得できますが、Issueは1件も取得できません。Issueを取り出すにはAPIを呼び出します。

Forkは、他者のリポジトリをサーバー側に作成した自分用のコピーです。そのコピーへの書き込み権限を持ち、そこへブランチをpushして、コピーから元のリポジトリへプルリクエストを開きます。メンテナーがあなたを知らないプロジェクトに貢献する場合は、この方法を使います。ForkはGitHub上に保存され、作成元を記録しているcloneです。

ソフトウェアは、ユーザーが利用するものと同じAPIを通じて、これら3つすべてを読み取ります。自分のサーバーで実行するプルリクエストレビューワーエージェントは、新しいPRを監視し、差分を読み取り、行コメントを投稿します。リポジトリのルートにAGENTS.mdファイルを置くといった規約が存在するのは、現在のリポジトリが人だけでなくツールからも読み取られるためです。

VPS 所有者にとって GitHub が実際に行うこと

まず、サーバー外のストレージを用意します。デプロイスクリプトと playbook は、それらを設定するサーバーとは別の場所に置きます。新しいイメージから VPS を再構築し、clone して実行します。リポジトリは非公開にし、サーバーには deploy key を付与します。これはアカウント全体ではなく、1 つのリポジトリに対して登録する SSH key で、read only に設定します。read only の deploy key が漏えいしても、公開されるのは 1 つのリポジトリです。アカウントの key が漏えいすると、push 可能なすべての対象が公開されます。

sudo git clone git@github.com:yourname/vps-deploy.git /srv/vps-deploy
cd /srv/vps-deploy
git pull --ff-only

--ff-only は merge commit の作成を拒否します。変更を取得するだけのサーバーでは、merge は常に意図しない結果です。そのため、この flag によって分かりにくい履歴を、単純なエラー fatal: Not possible to fast-forward, aborting. に変えられます。サーバー上で、本来変更されるべきでないものが変更されています。再度 pull する前に原因を特定してください。

root で clone した後、別のユーザーとして Git を実行すると、fatal: detected dubious ownership in repository at '/srv/vps-deploy' になります。Git は、別のユーザーが所有するリポジトリの読み取りを拒否します。悪意のある .git/config によって、Git がコマンドを実行させられる可能性があるためです。chown で所有者を修正してください。safe.directory の例外を追加する方法は避けます。この例外では、原因を取り除かずにチェックだけを無効化してしまうためです。

GitHub Actions: ビルドとデプロイのパイプライン

Actions は GitHub の CI/CD システム(継続的インテグレーションと継続的デリバリー)です。.github/workflows/ 配下に YAML ファイルをコミットすると、指定したイベントが発生したときに GitHub が実行します。

name: check
on:
  push:
    branches: [main]
jobs:
  shellcheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v7
      - run: sudo apt-get update && sudo apt-get install -y shellcheck
      - run: shellcheck *.sh

このファイルを workflow と呼びます。job は 1 台のマシン上で実行されます。step は 1 つのコマンドまたは公開済みの action です。uses: で別のリポジトリにある action を取り込み、@v7 でそのメジャーバージョンを固定します(2026年8月時点で actions/checkout の現行バージョンは v7 です)。必ず何らかのバージョンを固定してください。固定しない action では、内容を確認していないコードが Secret へのアクセス権を持って実行されるためです。

runs-on: ubuntu-latest では、job の終了時に破棄される新しい仮想マシンを GitHub に要求します。標準 runner はパブリックリポジトリでは無料です。2026年8月時点で、無料プランにはプライベートリポジトリ向けに月 2,000 分の実行時間が含まれます。この数値を予算の前提にする前に、現在の料金ページを確認してください。

Secret はリポジトリ設定に保存され、${{ secrets.DEPLOY_KEY }} として読み取られます。fork からの pull request によって起動された workflow には読み取り専用の token が付与され、Secret へのアクセス権はありません。そうしなければ、第三者が Secret を出力するだけの PR を作成できるためです。

自分の VPS で Actions runner を実行する

runs-on: self-hostedを使用すると、ジョブは代わりに自分が所有するマシンで実行されます。リポジトリの runner 設定ページには、ダウンロード用のコマンド、リポジトリの Web アドレス、1 時間有効な登録トークンが表示されます。最後の2つを REPO_URLRUNNER_TOKEN に指定すれば、セットアップは3つのコマンドで完了します。

./config.sh --url "$REPO_URL" --token "$RUNNER_TOKEN"
sudo ./svc.sh install
sudo ./svc.sh start
./svc.sh status

svc.sh statusを実行すると、サービスが active であり、直近のログ行が表示されることを確認できます。runner は GitHub への送信 HTTPS 接続を開いてジョブを取得するため、runner 用に受信ポートを開く必要はありません。svc.sh installは systemd unit を作成します。ここを省略する人が多いのですが、設定しないと SSH セッションの終了とともに runner も終了します。その結果、後続のジョブが理由を示さずにキューで待機し続けます。VPS での self-hosted runner の完全なセットアップでは、長期間稼働する runner に必要なハードニングとクリーンアップについて説明しています。

この構成では、ジョブがすでにサーバー上で実行されるため、デプロイ時にインターネットから到達可能な受信用 SSH key は不要です。ビルドキャッシュも実行間で保持され、使用時間のカウントもありません。

注意点が1つあります。GitHub の公式ドキュメントでは、self-hosted runner は private repository でのみ使用することを推奨しています。public repository の fork から pull request を作成すると、危険なコードを runner 上で実行できるためです。runner は、そのブランチの workflow ファイルに記述された内容をそのまま実行します。誰が push できるかを管理できる private repository では、リスクは小さいです。public repository では、self-hosted runner を見知らぬ第三者がコードを実行できるマシンとして扱ってください。

GitHub は本当に必要ですか?

いいえ。標準は Git であり、GitHub は利便性を提供するサービスです。Forgejo と Gitea はセルフホスト型の forge です。forge とは、issue と pull request を付加できる Git ホストを指します。どちらも単一の Go バイナリとしてリリースされ、小規模な VPS で動作します。Forgejo は Gitea から 2022 年にフォークされ、現在は Codeberg を支えています。wire protocol は同一であるため、リポジトリは 1 つのコマンドで移行できます。

git remote -v
git remote set-url origin git@git.example.com:you/vps-deploy.git
git push origin main

すべての commit が移行されます。各 clone に完全な履歴がすでに保存されているためです。移行されないのは、GitHub がその上に構築した層、つまり issue と pull request のスレッドです。CI も移行されません。Forgejo には独自の Actions 実装があり、.forgejo/workflows/ から同様の YAML を読み込みます。ただし、ドキュメントには制限が明記されています。GitHub Actions と Forgejo Actions は同一ではなく、すぐには動作しない場合があります。また、専用の runner も必要です。この作業はコピーではなく、移植として計画してください。

多くのプロジェクトが残る本当の理由は、contributor です。公開コードは、すでに利用者がアカウントを持っている場所に置く必要があります。非公開の deploy script はその限りではありません。これは別々の判断であり、それぞれ異なる答えを選べます。

最初に問題になりやすい箇所とエラーメッセージ

プッシュが拒否される場合。 次のメッセージが表示されます。

 ! [rejected]        main -> main (fetch first)
error: failed to push some refs to 'github.com:yourname/vps-deploy.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.

最後に pull してから、誰かがプッシュしています。Web エディターで行った編集であることがよくあります。git pull --rebase を実行して、相手のコミットの上に自分のコミットを適用し直してから、もう一度プッシュします。共有ブランチでは git push --force を避けてください。サーバー上のそのブランチから、他のコミットが削除されるためです。

fatal: refusing to merge unrelated histories ローカルで git init を実行し、さらに GitHub に README 付きのリポジトリを作成させています。2 つの履歴に共通するコミットがないため、Git はどちらを採用すべきか判断できません。確実な方法は、GitHub 側のコピーを新しいフォルダーに clone し、そこへ自分のファイルを移動することです。

error: src refspec main does not match any 指定したブランチが、このリポジトリに存在しません。通常は、リポジトリにまだコミットが 1 つもないか、ブランチ名が master です。git branch --show-current で確認できます。

Secret がコミットに含まれた場合。 直ちに認証情報をローテーションしてください。プッシュされた時点で公開されたものとして扱います。fork、ミラー、キャッシュされた表示にコピーが残っており、自分では削除できないためです。

FAQ

GitHub は Git と同じものですか?

いいえ。Git はマシンにインストールして使用するバージョン管理プログラムで、ネットワーク接続もアカウントも必要ありません。GitHub は、Git リポジトリを保存し、Web インターフェース、Issue、Pull Request、CI などを追加する商用ホスティングサービスです。Git は 2005 年にリリースされ、GitHub はその上に構築される形で 2008 年に開始されました。GitHub がなくても、Git は使い続けられます。GitHub のすべての機能は、その内部で Git に依存しています。

VPS で Git を使うために GitHub アカウントは必要ですか?

いいえ。git initgit commitgit log は、リモートをまったく設定していないサーバーでも動作します。これだけで /etc ファイルの変更を追跡したり、デプロイスクリプトを管理したりできます。アカウントが役立つのは、サーバー障害後も残る履歴のコピーや、別のマシンからクローンできる場所が必要な場合です。Forgejo や Gitea などのセルフホスト型 forge を所有するハードウェア上で運用すれば、同じ用途に対応できます。また、別のマシン上に bare repository を置き、通常の SSH リモートから接続すれば、forge ソフトウェアは必要ありません。

Pull Request とは何ですか?

Pull Request は、あるブランチを別のブランチへマージするための依頼で、議論用のページが付属します。ブランチを push し、main に対する PR を開くと、ホスト上で変更がコミット単位に表示されます。レビュアーは個々の行にコメントでき、自動チェックは成功または失敗を報告できます。これは Git の機能ではなく GitHub の機能であるため、Git 自体にはこのためのコマンドがありません。他のホストも同じ仕組みを実装していますが、merge request と呼ぶ場合があります。

GitHub Actions runner を自分の VPS で実行すべきですか?

プライベートリポジトリであれば、多くの場合は実行してもよいでしょう。ジョブはすでに料金を支払っているハードウェア上で実行されるため、実行時間に応じた料金は発生せず、ビルドキャッシュも維持されます。また、runner は GitHub に外向きに接続してジョブを要求するため、デプロイ用の受信用 SSH key をインターネットに公開する必要もありません。パブリックリポジトリでは、GitHub は自分の runner の使用を推奨していません。誰でもリポジトリを fork し、ワークフローによって自分のマシン上でコードを実行する Pull Request を開けるためです。

後から GitHub からリポジトリを移行できますか?

コードであれば、簡単に移行できます。すべての clone には完全な履歴が含まれているため、git remote set-url origin <new url> の後に push すれば、1 つのコミットに含まれるすべての内容を移行できます。一方、GitHub が管理する層は残りません。Issue、Pull Request の議論、Actions の履歴は、あなたの .git フォルダーではなく GitHub のデータベースに保存されています。移行ツールを使えば、API 経由で Issue をコピーできます。ワークフローファイルは通常、新しいホストの CI に合わせて編集する必要があります。この点を踏まえると、正式なドキュメントを Issue のスレッドではなくリポジトリに置くべき理由が分かります。

#github#git#version-control#ci-cd#developer-tools