Git Pull時のトラブルシューティング
発生した問題
最近、同じGitHubリポジトリで作業しているチームメンバーと私のGit間で、Pull Requestの「Files Changed」タブに表示される内容に違いが発生しました。
チームメンバーは作業ブランチ→PR間では作業した分のファイル数のみ表示されています。
しかし、私のPRではマージされたdevelopブランチのファイルチェンジ(自身以外の他メンバーのファイルもすべて表示)に表示されるようになりました。そのため、ファイルチェンジ数が100を超えるなど(もっと前に気付けよと自分にツッコミをいれました)とんでもないことになりました、、、、、
問題の詳細
同じ手順を踏んでいるにもかかわらず、異なる結果になっていました:
- 自分の作業ブランチAに移動
-
git pull origin develop
を実行 -
git push origin ブランチA
を実行
これにより、GitHub上のPull Request(PR)の「Files Changed」タブに表示される内容が:
- チームメイト: 作業ブランチAで修正したファイルのみが表示される
- 私: 作業ブランチAで修正したファイルと、developブランチで修正されたファイルも表示される
原因
問題の原因は、git pull
コマンドの動作の違いでした。
- チームメイト: マージ方式(デフォルト)を使用
- 私: リベース方式を使用
調査の結果、私のグローバル設定ファイル(.gitconfig
)に以下の設定があることがわかりました:
[pull]
rebase = true
一方、チームメイトの設定ファイルには、この設定がありませんでした。
(.gitconfigファイルの[pull]セクションの設定を書き換えた記憶は全くありません、、、、)
マージ方式とリベース方式の違い
merge方式
git pull origin develop (--no-rebase オプション付きまたはpull.rebase = false)
特徴
- 履歴がそのまま保持され、マージコミットが作成される
- ブランチが分岐して再度合流する「ダイヤモンド型」の履歴になる
- GitHub上のPRには、作業ブランチで行った変更のみが表示される
- コンフリクトをマージ時に一度だけ解決
図解
A1 -- A2 -- A3 -- A4 -- M (ブランチA)
\ /
D1 -- D2 -- D3 (Developブランチ)
M = マージコミット
rebase方式
git pull --rebase origin develop (または pull.rebase = true)
特徴
- 作業ブランチのコミットが退避され、対象ブランチの上に再適用される
- 直線的な履歴になる
- GitHub上のPRには、developからブランチAまでの全ての変更が表示される
- 各コミットを再適用する時点でそれぞれコンフリクト解決が必要になる場合がある
図解
D1 -- D2 -- D3 -- A1' -- A2' -- A3' -- A4' (ブランチA)
A1', A2'... = リベースにより再適用されたコミット
解決方法
問題を解決するには、以下のいずれかの方法で設定を変更します:
グローバル設定を変更(すべてのリポジトリに適用)
git config --global pull.rebase false
または .gitconfig
ファイル内の[pull]セクションを直接編集もしくは[pull]セクションを削除
[user]
name = JohnDoe
email = john.doe@example.com
~~~~~(一部省略)~~~~~
[pull]
rebase = false
プロジェクト固有の設定を変更(現在のリポジトリのみ適用)
git config pull.rebase false
これにより、.git/config
ファイルに以下の設定が追加されます:
[pull]
rebase = false
macOSにおけるGitの設定階層
設定ファイルの優先順位(下に行くほど優先される)
- システム全体の設定 (
/etc/gitconfig
) - グローバル設定 (
~/.gitconfig
) - プロジェクト固有の設定 (
.git/config
) - コマンドラインオプション (
--rebase
など)
プロジェクト固有の設定がない場合は、グローバル設定が適用されます。これが今回の問題の原因でした。
チームでの統一
チーム内での一貫性を確保するには:
- チームで標準的な設定を決める(マージ方式かリベース方式か)
- 新しいメンバーがチームに参加した際に設定を確認する
- 必要に応じてプロジェクト固有の設定を
.git/config
に含める
補足:Homebrew でより新しいバージョンのGitを使用する方法
macOSにはデフォルトでGitがインストールされていますが、より新しいバージョンを使いたい場合は:
# Homebrewのインストール
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Gitのインストール
brew install git
Homebrewでインストールしたgitを優先するには:
# zshの場合
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
# bashの場合
echo 'export PATH="/opt/homebrew/bin:$PATH"' >> ~/.bash_profile
source ~/.bash_profile
Intel Macの場合は /opt/homebrew/bin
の代わりに /usr/local/bin
を使用します。
いや、想定外すぎる挙動すぎて最初は焦りました、、、、、
チーム開発では、このような設定の違いが予期せぬ問題を引き起こすことがあるため、設定を統一することが重要と痛感した機会でした。
Discussion