Git設定問題のトラブルシューティング:一般的な修正とベストプラクティス

設定の出所を追跡し、ID、エイリアス、フック、改行コード、プル、認証情報の問題を解決して、Git設定の問題を修正します。

Git設定問題のトラブルシューティング:一般的な修正とベストプラクティス

ほとんどのGit設定問題は、見た目よりも奇妙です。Gitは通常、設定ファイルのいずれかが指示したことを正確に実行しています。難しいのは、どのファイルかを特定することです。設定は、リポジトリ、ユーザー設定、システム設定、インクルードファイル、または特定のディレクトリ下でのみ適用される条件付きインクルードに存在する可能性があるからです。

私が最初に使うコマンドはこれです:

git config --list --show-origin --show-scope

Gitのバージョンが --show-scope をサポートしていない場合は、次を使用します:

git config --list --show-origin

originは、各値を提供したファイルを示します。これは値単独よりも重要です。[email protected] と表示されるだけでは不十分で、それが .git/config~/.gitconfig/etc/gitconfig、またはインクルードされたワークプロファイルのいずれから来たのかを知る必要があります。

Git設定には優先順位があります。ローカルリポジトリ設定は通常、グローバルユーザー設定より優先され、グローバル設定はシステム設定より優先されます。コマンドラインオプションと環境変数は、1つのコマンドに対してこれらすべてを上書きできます。条件付きインクルードはさらに別のレイヤーを追加します。グローバルファイルは「このディレクトリ内にいるときは、この他の設定も読み込む」と指示できます。

1つの設定をそのソースとともに検査できます:

git config --show-origin --get user.email
git config --show-origin --get core.autocrlf
git config --show-origin --get-regexp '^alias\.'

この習慣は、多くの無駄な編集を防ぎます。リポジトリに user.email がローカル設定されている場合、git config --global user.email を変更しても、そのリポジトリのコミットには影響しません。

コミットの名前やメールが間違っている

症状は単純です:コミットに誤った作者が表示されます。これは、同じラップトップを仕事と個人のプロジェクトで使用している場合や、仕事用メールを設定する前に会社のリポジトリをクローンした場合によく発生します。

現在のリポジトリでGitが使用するものを確認します:

git config user.name
git config user.email
git config --show-origin --get user.email

デフォルトのIDをグローバルに設定します:

git config --global user.name "Your Name"
git config --global user.email "[email protected]"

1つのリポジトリに対しては、ローカルに設定します:

git config --local user.name "Your Name"
git config --local user.email "[email protected]"

IDが明示的に設定されていない場合にGitがコミットを拒否するようにしたい場合は、次を使用します:

git config --global user.useConfigOnly true

この設定は、IDを切り替える人に便利です。Gitがシステムのユーザー名やホスト名から推測するのを停止するため、初心者には煩わしいかもしれません。間違ったアドレスでコミットを作成するよりもコミットを失敗させたい場合に使用します。

よりクリーンな仕事/個人の分割には、条件付きインクルードを使用します:

# ~/.gitconfig
[user]
    name = Your Name
    email = [email protected]

[includeIf "gitdir:~/work/"]
    path = ~/.gitconfig-work

次に、これを ~/.gitconfig-work に配置します:

[user]
    email = [email protected]

gitdir:~/work/ の末尾のスラッシュは重要です。これはそのディレクトリ下のリポジトリを意味するからです。トリガーされない場合は、ワークリポジトリ内から git config --list --show-origin を実行し、インクルードされたファイルが表示されるか確認します。

すでに間違ったメールでコミットを作成してしまった場合、設定を変更しても将来のコミットのみが修正されます。未公開のコミットの場合は、修正またはリベースできます。すでに共有ブランチにプッシュされたコミットの場合は、履歴を書き換える前に確認を取ってください。

機能しないエイリアス

Gitエイリアスは alias.* の下に保存されます。次のようにリストします:

git config --get-regexp '^alias\.'

通常のエイリアスはGitサブコマンドに展開されます:

git config --global alias.st 'status -sb'
git st

エイリアスがシェルパイプライン、変数展開、cd、または他の非Gitコマンドを必要とする場合は、! で始める必要があります:

git config --global alias.recent '!git for-each-ref --sort=-committerdate --count=10 --format="%(refname:short)" refs/heads/'

! がない場合、Gitは最初の単語をGitコマンドとして扱おうとします。ls -la は「ls という名前のGitコマンドを実行する」となり、意図したものではありません。

引用符はもう1つの一般的な失敗原因です。シェルからエイリアスを定義する場合は、可能な限りエイリアス全体をシングルクォートで囲み、必要に応じて内部でダブルクォートを使用します。シェルによって引用符の扱いが異なります。特にPowerShellと cmd.exe です。複雑なエイリアスが頻繁に壊れる場合は、設定ファイルを直接編集します:

git config --global --edit

実用的なデバッグのコツは、Gitの外部でコマンドを開始することです。動作したら、それをエイリアスに貼り付けます。シェルエイリアスの場合は、先頭に ! を付けて再度テストします。

また、メンタルモデルを隠すエイリアスにも注意してください。pullmerge という名前のエイリアスは、Gitの動作を驚かせる可能性があります。Gitはエイリアスが組み込みコマンドを直接上書きすることを許可しませんが、シェルエイリアスやラッパースクリプトは可能です。git pull が奇妙に動作する場合は、シェル設定も確認します:

type git
alias | grep git

決して実行されないフック

フックが失敗する理由は3つあります:Gitが異なるフックディレクトリを探している、ファイルが実行可能でない、またはスクリプトが想定する環境がないことです。

設定されたフックパスを確認します:

git config --show-origin --get core.hooksPath

これが .githooks と表示された場合、Gitは .githooks/pre-commit を使用し、.git/hooks/pre-commit は使用しません。何も表示されない場合、Gitは .git/hooks を使用します。

macOSとLinuxでは、パーミッションを確認します:

ls -l .git/hooks/pre-commit .githooks/pre-commit 2>/dev/null
chmod +x .githooks/pre-commit

ゼロ以外のステータスで終了するフックは、Git操作をブロックします。一時的なトレースを先頭に追加します:

#!/usr/bin/env bash
set -x
pwd
env | sort

共有フックにノイズの多いトレースを残さないでください。すぐに読みにくくなります。

パスの問題はGUIクライアントで一般的です。ターミナルで動作するフックがIDEで失敗するのは、IDEがシェルプロファイルを読み込まないためです。可能な限りプロジェクトローカルのコマンドを優先します:

./node_modules/.bin/eslint .

または、コマンドを確認して有用なメッセージを表示します:

if ! command -v npm >/dev/null 2>&1; then
  echo "npm is required for this hook but was not found in PATH."
  exit 1
fi

改行コードが変わり続ける

改行コードの問題は、チェックアウト直後にファイルが変更されたように見える、すべての行が変更された大きな差分、またはWindowsで編集した後にLinuxでスクリプトが失敗するなどの形で現れます。

設定を確認します:

git config --show-origin --get core.autocrlf
git config --show-origin --get core.eol

一般的な選択肢は次のとおりです:

# Windowsフレンドリーなチェックアウト、リポジトリ内はLF
git config --global core.autocrlf true

# macOS/Linuxフレンドリー:コミット時のみCRLFをLFに変換
git config --global core.autocrlf input

# 自動変換なし
git config --global core.autocrlf false

チームにとっては、.gitattributes の方がすべての開発者にグローバル設定を正しく設定させるよりも信頼性が高いです。プロジェクトルールをリポジトリに配置します:

* text=auto
*.sh text eol=lf
*.bat text eol=crlf
*.png binary
*.jpg binary
*.pdf binary

.gitattributes を追加または変更した後は、ファイルを意図的に正規化します:

git add --renormalize .
git status

その差分を注意深く確認します。多くのファイルに影響を与える可能性があり、改行コードの正規化と機能作業を混在させたくありません。

プル、プッシュ、マージが間違ったデフォルトを使用する

場合によっては、設定の問題はIDや改行コードではありません。Gitが予期しないプル戦略を選択することです。

プル関連の設定を確認します:

git config --show-origin --get pull.rebase
git config --show-origin --get pull.ff
git config --show-origin --get branch.main.rebase

git pull がマージを期待しているのにリベースを続ける場合、pull.rebase またはブランチ固有の設定が有効になっている可能性があります。非ファストフォワードプルを拒否する場合、pull.ff=only が設定されている可能性があります。これらの設定自体は間違っていません。チームのワークフローに一致している必要があるだけです。

警告や驚きを避けるために、明示的なデフォルトを設定します:

# プル時にマージ
git config --global pull.rebase false

# プル時にリベース
git config --global pull.rebase true

# ファストフォワードプルのみ許可
git config --global pull.ff only

1つのブランチに対して:

git config branch.main.rebase true

認証情報ヘルパーの混乱

認証の問題は、多くの場合リモートの問題のように見えますが、ローカル設定から発生します。Gitは古いトークンをキャッシュした認証情報ヘルパーを使用している可能性があります。

ヘルパーを確認します:

git config --show-origin --get-all credential.helper

osxkeychainmanagermanager-corestorecache などが表示される場合があります。複数のヘルパーが存在する可能性があります。Gitが間違った認証情報を送信し続ける場合は、ランダムなリモートURLを変更するのではなく、OSキーチェーンまたは認証情報マネージャーから削除します。

また、リモートを確認します:

git remote -v

SSHとHTTPSは異なる認証パスを使用します。1つのリポジトリが [email protected]:org/repo.git を使用し、別のリポジトリが https://github.com/org/repo.git を使用する場合、必ずしも同じ認証情報を使用するとは限りません。

信頼性の高いデバッグルーティン

Git設定に一貫性がないと感じた場合は、推測する代わりにルーティンを使用します:

  1. リポジトリルートから失敗するコマンドを実行します。
  2. git config --show-origin --get <name> で正確な設定を検査します。
  3. git config --list --show-origin --show-scope で関連設定をリストします。
  4. グローバル設定を変更する前に、.git/config のローカル設定を確認します。
  5. 問題が1つのディレクトリ下でのみ発生する場合は、条件付きインクルードを確認します。
  6. 最小の設定変更を行い、元のコマンドを再実行します。

Git設定はレイヤー化できるため強力です。それが混乱の原因でもあります。修正方法は、レイヤーを可視化し、実際に勝っているレイヤーを変更することです。

IDE内で設定が異なる場合

混乱を招くGit問題のクラスは、エディターまたはGUI内でのみ発生します。ターミナルは1つのIDを使用しますが、IDEは別のIDでコミットします。フックはシェルで成功しますが、コミットパネルからは失敗します。認証情報プロンプトがターミナルに表示される一方、GUIは古いトークンで静かに再試行します。

理由は通常、環境です。インタラクティブシェルは .bashrc.zshrc、SDKマネージャー、言語バージョンマネージャー、カスタム PATH エントリを読み込む場合があります。デスクトップから起動されたGUIは、それらのいずれも読み込まない場合があります。Git自体は同じ設定ファイルを読み取りますが、フックや認証情報ヘルパーは異なる世界を見る可能性があります。

デバッグするには、環境をローカルファイルに出力する一時的なフックを作成します:

#!/usr/bin/env bash
{
  date
  pwd
  git --version
  git config --list --show-origin
  env | sort
} > /tmp/git-hook-debug.log
exit 1

IDEからGitアクションを実行し、/tmp/git-hook-debug.log を確認します。その後、フックを削除します。これにより、ターミナルで見えるものではなく、Gitとフックが実際に何を見たかがわかります。

GUIクライアントでのID問題については、ツールに独自のGit設定があるかどうかを確認します。一部のクライアントはシステムGitを使用します。他のクライアントはGitをバンドルするか、ユーザーIDをアプリケーション設定に保存します。クライアントがGitを介してコミットしている場合、git log --format=fuller -1 で結果の作者とコミッターが表示されます。これにより、「Git設定が間違っていた」と「GUIが独自の設定を使用した」を区別するのに役立ちます。

疑わしい場合は、重要なプロジェクトに対してリポジトリローカル設定を明示的にします:

git config --local user.email "[email protected]"
git config --local core.hooksPath .githooks

ローカル設定は、そのマシン上のリポジトリメタデータとともに移動するため、驚きを減らします。それでもコミットされないため、共有ルールは .gitattributes.editorconfig、フックスクリプト、プロジェクトドキュメントなどの追跡ファイルに保存する必要があります。

既知の良好なベースラインを維持する

設定問題が繰り返し発生する場合は、自分のマシン用に小さな既知の良好なベースラインを保存します。派手である必要はありません。コメント付きの ~/.gitconfig に、ID、エディター、デフォルトブランチ動作、認証情報ヘルパー、インクルードを含めれば十分です。新しいラップトップが異なる動作をした場合、すべての設定を再発見する代わりに比較できます。

有用なベースラインチェックには以下が含まれます:

git config --global --list --show-origin
git config --global --get core.editor
git config --global --get init.defaultBranch
git config --global --get-all credential.helper

インターネットや同僚から設定をコピーする際は注意してください。エイリアスは、あなたが持っていないツールを想定している場合があります。認証情報ヘルパーはプラットフォーム固有です。改行コード設定は、相手のOSには正しくても、あなたのOSには間違っている場合があります。Git設定はシェル設定と同様に扱います。アイデアを借りるが、各行を理解してから保持します。

プロジェクトメンテナーにとって、最善の修正は共有の期待を個人設定から移動することです。改行コードを .gitattributes に、フォーマットをフォーマッター設定に、無視するファイルを .gitignore に、必要なチェックをCIに配置します。プロジェクトが目に見えないグローバル設定に依存するほど、設定チケットは少なくなります。

問題を修正するために設定を変更した場合は、それがローカルかグローバルかを書き留めてください。多くの将来のGitの謎は、6か月後に誰も覚えていない良い一時的なローカル修正から始まります。