Gitのトラブルシューティング
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
Gitを使用中、予期したとおりに動作しないことがあります。Gitのトラブルシューティングと問題の解決に関するヒントを以下に示します。
デバッグ
Gitに関する問題をトラブルシューティングする際は、次のデバッグ手法を試してください。
GitコマンドにカスタムSSHキーを使用する
GIT_SSH_COMMAND="ssh -i ~/.ssh/gitlabadmin" git <command>クローン作成に関する問題をデバッグする
SSH経由のGitの場合:
GIT_SSH_COMMAND="ssh -vvv" git clone <git@url>HTTPS経由のGitの場合:
GIT_TRACE_PACKET=1 GIT_TRACE=2 GIT_CURL_VERBOSE=1 git clone <url>トレースでGitをデバッグする
Gitには、Gitコマンドをデバッグするためのトレースの完全なセットが含まれています。次に例を示します:
GIT_TRACE_PERFORMANCE=1:gitの各呼び出しにかかる時間を示す、パフォーマンスデータのトレーシングを有効にします。GIT_TRACE_SETUP=1:gitがやり取りしているリポジトリと環境について検出された内容のトレーシングを有効にします。GIT_TRACE_PACKET=1: ネットワーク操作に対するパケットレベルのトレーシングを有効にします。GIT_CURL_VERBOSE=1:curlの冗長な出力を有効にします。これには認証情報が含まれる場合があります。
Broken pipeエラー(git push時)
Broken pipeエラーは、リモートリポジトリにプッシュしようとしたときに発生する可能性があります。通常、プッシュする時に次のエラーが表示されます:
Write failed: Broken pipe
fatal: The remote end hung up unexpectedlyこの問題を修正するための解決策は以下のとおりです。
GitでPOSTバッファサイズを大きくする
HTTPS経由でGitを使用して大きなリポジトリをプッシュしようとしたときに、次のようなエラーメッセージが表示されることがあります:
fatal: pack has bad object at offset XXXXXXXXX: inflate returned -5この問題を解決するには、以下を実行します:
ローカルGit設定のhttp.postBufferの値を大きくします。デフォルト値は1 MBです。たとえば、500 MBのリポジトリをクローンするときに
git cloneが失敗する場合は、以下を実行します:ターミナルまたはコマンドプロンプトを開きます。
http.postBufferの値を大きくします:# Set the http.postBuffer size in bytes git config http.postBuffer 524288000
ローカル設定で問題が解決しない場合は、サーバー設定の変更が必要になることがあります。これは、サーバーへのアクセス権がある場合に限り、慎重に行う必要があります。
サーバー側で
http.postBufferを大きくします:ターミナルまたはコマンドプロンプトを開きます。
以下のように、GitLabインスタンスの
gitlab.rbファイルを変更します:gitaly['configuration'] = { # ... git: { # ... config: [ # Set the http.postBuffer size, in bytes {key: "http.postBuffer", value: "524288000"}, ], }, }設定の変更を適用します:
sudo gitlab-ctl reconfigure
エラー: stream 0 was not closed cleanly
このエラーが表示される場合、インターネット接続が遅いことが原因となっていることがあります:
RPC failed; curl 92 HTTP/2 stream 0 was not closed cleanly: INTERNAL_ERROR (err 2)SSH経由ではなく、HTTP経由でGitを使用する場合は、次のいずれかの修正を試してください:
git config http.postBuffer 52428800を使用して、Git設定でPOSTバッファサイズを大きくする。git config http.version HTTP/1.1を使用して、HTTP/1.1プロトコルに切り替える。
どちらの方法でもエラーが修正されない場合は、別のインターネットサービスプロバイダーが必要になることがあります。
SSH設定を確認する
SSH経由でプッシュする場合、はじめにSSH設定を確認してください。「壊れたパイプ」エラーは、認証などのSSHの根本的な問題が原因で発生することがあります。SSHのトラブルシューティングドキュメントの手順に従って、SSHが正しく設定されていることを確認します。
サーバーアクセス権を持つGitLab管理者の場合は、クライアントまたはサーバーでSSH keep-aliveを設定して、セッションタイムアウトを防ぐこともできます。
クライアントとサーバーの両方を設定する必要はありません。
クライアント側でSSHを設定するには:
UNIXで、
~/.ssh/configを編集し(ファイルが存在しない場合は作成します)、以下を追加または編集します:Host your-gitlab-instance-url.com ServerAliveInterval 60 ServerAliveCountMax 5WindowsでPuTTYを使用している場合は、セッションのプロパティに移動し、接続に移動し、Sending of null packets to keep session active(セッションをアクティブに保つためにnullパケットを送信) で、
Seconds between keepalives (0 to turn off)を60に設定します。
サーバー側でSSHを設定するには、/etc/ssh/sshd_configを編集して以下を追加します:
ClientAliveInterval 60
ClientAliveCountMax 5git repackを実行する
‘pack-objects’タイプのエラーも表示される場合は、リモートリポジトリへのプッシュを再試行する前に、git repackを実行してみてください:
git repack
git pushGitクライアントをアップグレードする
古いバージョンのGit(2.9未満)を実行している場合は、2.9以上にアップグレードすることを検討してください(Gitリポジトリにプッシュしたときの壊れたパイプを参照してください)。
ssh_exchange_identificationエラー
GitをSSH経由でプッシュまたはプルしようとすると、次のエラーが発生することがあります:
Please make sure you have the correct access rights
and the repository exists.
...
ssh_exchange_identification: read: Connection reset by peer
fatal: Could not read from remote repository.または
ssh_exchange_identification: Connection closed by remote host
fatal: The remote end hung up unexpectedlyまたは
kex_exchange_identification: Connection closed by remote host
Connection closed by x.x.x.x port 22このエラーは通常、SSHデーモンのMaxStartups値がSSH接続をスロットリングしていることを示します。この設定では、SSHデーモンへの認証されていない同時接続の最大数を指定します。すべての接続は最初は「未認証」であるため、これにより適切な認証情報(SSHキー)を持つユーザーが影響を受けます。デフォルト値は10です。
これは、ホストのsshdログを調べることで確認できます。Debianファミリーのシステムの場合は/var/log/auth.logを参照し、RHELの派生物の場合は、/var/log/secureで次のエラーを確認してください:
sshd[17242]: error: beginning MaxStartups throttling
sshd[17242]: drop connection #1 from [CLIENT_IP]:52114 on [CLIENT_IP]:22 past MaxStartupsこのエラーが存在しない場合、SSHデーモンが接続を制限していないことを示しており、根本的な問題はネットワーキングに関連している可能性があります。
認証されていない同時SSH接続の数を増やす
/etc/ssh/sshd_configで値を追加または変更して、GitLabサーバーのMaxStartupsを増やします:
MaxStartups 100:30:200100:30:200は、最大100個のSSHセッションが無制限に許可され、次に接続の30%が削除されて、絶対最大値である200に達することを意味します。
MaxStartupsの値を変更したら、設定にエラーがないことを確認します。
sudo sshd -t -f /etc/ssh/sshd_config設定のチェックをエラーなしで実行できた場合は、変更を有効にするためSSHデーモンを安全に再起動できます。
# Debian/Ubuntu
sudo systemctl restart ssh
# CentOS/RHEL
sudo service sshd restartgit push/git pull実行中のタイムアウト
リポジトリとの間でプル/プッシュに50秒以上かかる場合は、タイムアウトが発生します。以下の例のように、これには実行された操作の数と、それぞれのタイミングのログが含まれます:
remote: Running checks for branch: master
remote: Scanning for LFS objects... (153ms)
remote: Calculating new repository size... (canceled after 729ms)これを使用して、どの操作のパフォーマンスが低下しているかをさらに調査し、サービスを改善する方法に関する詳細情報をGitLabに提供できます。
エラー: Operation timed out
Gitの使用中にこのエラーが発生した場合、通常はネットワークに問題があることを示します:
ssh: connect to host gitlab.com port 22: Operation timed out
fatal: Could not read from remote repository根本的な問題を特定するには、以下を実行します:
- 別のネットワーク経由で接続します(たとえば、Wi-Fiから携帯電話のデータに切り替えて、ローカルネットワークまたはファイアウォールの問題を排除します)。
- 以下のBashコマンドを実行して、
tracerouteとpingの情報を収集します:mtr -T -P 22 <gitlab_server>.com。MTRとその出力の読み取り方法については、Cloudflareの記事What is My Traceroute (MTR)?(My Traceroute (MTR)とは?)を参照してください。
エラー: transfer closed with outstanding read data remaining
古いリポジトリまたは大きなリポジトリをクローンする場合、HTTP経由でgit cloneを実行すると、次のエラーが表示されることがあります:
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failedこの問題は、Gitそのものが大容量ファイルや大量のファイルを処理できない場合にたびたび発生します。この問題を回避するため、Git LFSが作成されましたが、それでも制限事項があります。これは通常、次のいずれかの理由によるものです:
- リポジトリ内のファイルの数。
- 履歴内のリビジョンの数。
- リポジトリに大容量ファイルが存在。
大きなリポジトリをクローンするときにこのエラーが発生した場合は、1の値にクローンの深さを減らすとよいでしょう。次に例を示します:
このアプローチでは根本的な原因は解決できませんが、リポジトリを正常にクローンすることはできます。クローンの深さを1に減らすには、以下を実行します:
variables:
GIT_DEPTH: 1Your password expiredエラー(LDAPユーザーのSSHを使用したGitフェッチ時)
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
GitLab Self-Managedでgit fetchがこのHTTP 403 Forbiddenエラーを返す場合、GitLabデータベース内のこのユーザーのパスワードの有効期限(users.password_expires_at)が過去の日付になっています:
Your password expired. Please access GitLab from a web browser to update your password.SSOアカウントで実行されたリクエストで、password_expires_atがnullでない場合に、このエラーが返されます:
"403 Forbidden - Your password expired. Please access GitLab from a web browser to update your password."この問題を解決するには、以下のいずれかの方法でパスワードの有効期限を更新します:
GitLab Railsコンソールを使用して、ユーザーデータを確認および更新します:
user = User.find_by_username('<USERNAME>') user.password_expired? user.password_expires_at user.update!(password_expires_at: nil)gitlab-psqlを使用します:# gitlab-psql UPDATE users SET password_expires_at = null WHERE username='<USERNAME>';
このバグはこちらのイシューでレポートされました。
Gitフェッチでのエラー: HTTP Basic: Access Denied
HTTP(S)経由でGitを使用しているときにHTTP Basic: Access deniedエラーが発生した場合は、2要素認証のトラブルシューティングガイドを参照してください。
このエラーは、Git for Windows 2.46.0以降でも発生する可能性があります。トークンで認証する場合、ユーザー名は任意の値にできますが、値が空の場合は認証エラーをトリガーする可能性があります。
これを解決するには、ユーザー名の文字列を指定します。以下のいずれかの方法を使用し、<USERNAME>をのユーザー名に置き換えてください:
リポジトリを複製します:
git clone https://<USERNAME>@gitlab.com/path/to/a/project.git既存のリモートURLを更新します:
git remote set-url origin https://<USERNAME>@gitlab.com/path/to/a/project.git特定のホストに対して常にユーザー名を使用するようにGitを設定します:
git config --global url."https://<USERNAME>@gitlab.com/".insteadOf "https://gitlab.com/"
正常なgit clone中に記録された401エラー
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
HTTPでリポジトリをクローンする場合、production_json.logファイルには最初401(未認証)のステータスが表示され、その直後に200が表示されることがあります。
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":401,
"time":"2023-04-18T22:55:15.371Z",
"remote_ip":"x.x.x.x",
"ua":"git/2.39.2",
"correlation_id":"01GYB98MBM28T981DJDGAD98WZ",
"duration_s":0.03585
}
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":200,
"time":"2023-04-18T22:55:15.714Z",
"remote_ip":"x.x.x.x",
"user_id":1,
"username":"root",
"ua":"git/2.39.2",
"correlation_id":"01GYB98MJ0CA3G9K8WDH7HWMQX",
"duration_s":0.17111
}HTTP基本認証の動作が原因で、HTTP経由で実行されるGitの各操作でこの初期401ログエントリが発生することが考えられます。
Gitクライアントがクローン作成を開始するとき、GitLabに送信される最初のリクエストでは、認証の詳細は提供されません。GitLabは、そのリクエストに対して401 Unauthorizedの結果を返します。数ミリ秒後、Gitクライアントは認証の詳細を含むフォローアップリクエストを送信します。この2番目のリクエストは成功し、200 OKログエントリが生成されます。
401ログエントリに、対応する200ログエントリがない場合、Gitクライアントは次のいずれかを使用している可能性があります:
- 不正なパスワード。
- 有効期限が切れた、または失効したトークン。
これを修正しないと、代わりに403(Forbidden)エラーが発生する可能性があります。
HTTP経由でGitオペレーションを実行する際の403エラー
HTTP経由でGitオペレーションを実行している場合、403(Forbidden)エラーは、認証の失敗によるBANが原因でIPアドレスがブロックされたことを示します:
fatal: unable to access 'https://gitlab.com/group/project.git/': The requested URL returned error: 403認証の失敗によるBANの制限は、GitLab Self-ManagedまたはGitLab SaaSのどちらを使用しているかによって異なります。
失敗した認証のログを確認する
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab Self-Managed
403については、production_json.logで確認してください:
{
"method":"GET",
"path":"/group/project.git/info/refs",
"format":"*/*",
"controller":"Repositories::GitHttpController",
"action":"info_refs",
"status":403,
"time":"2023-04-19T22:14:25.894Z",
"remote_ip":"x.x.x.x",
"user_id":1,
"username":"root",
"ua":"git/2.39.2",
"correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
"duration_s":0.00875
}IPアドレスがブロックされている場合は、対応するログエントリがauth_json.logに存在します:
{
"severity":"ERROR",
"time":"2023-04-19T22:14:25.893Z",
"correlation_id":"01GYDSAKAN2SPZPAMJNRWW5H8S",
"message":"Rack_Attack",
"env":"blocklist",
"remote_ip":"x.x.x.x",
"request_method":"GET",
"path":"/group/project.git/info/refs?service=git-upload-pack"}