Git Cheat Sheet
問題の背景
チームで開発する際、よくあるパターンとして、
- developブランチから、featureブランチAを切って実装、PullRequestを作成し、レビュー待ち
- その間に、featureブランチAにfeatureブランチBを切って、新しい機能を実装します
- featureブランチAのレビューを経て承認され、スカッシュマージによってdevelopブランチへ統合され
- この時、featureブランチBのコミットがfeatureブランチAの元のコミットに含まれてしまうことがあって、developブランチと多くのマージコンフリクトが発生してしまいました。
問題発生の原因
- スカッシュマージによって個々のコミットがまとめられたため、ブランチBには依然としてブランチAの個々の変更が残っていること
- その結果、developブランチに既に存在するスカッシュコミットとブランチBの変更が重複して適用され、コンフリクトが発生したこと
解決策:リベースによる解決
ブランチBをブランチA由来のコミットを取り除いて、developブランチ上のスカッシュコミットに合わせてリベースすることで、効率よく解決できます。
具体的には、以下の手順で行います:
git checkout feature/branch-b
git rebase --onto develop HASH_BASE feature/branch-b
このコマンドは、ブランチ B の中で HASH_BASE より後のコミットだけを、develop ブランチ上に再適用します。 HASH_BASEは、ブランチ A が develop から分岐した時点のコミットハッシュにすると、元ブランチ A のコミットがブランチ B に含まれなくなります。
リベース中にコンフリクトが発生した場合、各コンフリクト箇所で適切に修正し、 以下のコマンドでリベースを続行します。
git add <修正済みファイル>
git rebase --continue
リベースが正常に完了したら、ブランチ B の変更を develop ブランチへPRを作成してマージしましょう。
この方法により、履歴がクリーンになり、将来的なマージやデバッグ作業が大幅に楽になります。
Remote ブランチにコミットしました
問題の背景
リモートブランチをLocalにFetchせずに、チェックアウトし、
git checkout origin/branch-a
をすると、そのまま作業し、コミットしたら、プッシュできない。下記のエラーメッセージ表示されました:
error: src refspec feature/branch does not match any
error: failed to push some refs to 'github.com:organization/project.git'
問題発生の原因
Fetchが忘れて、RemoteブランチをCheckoutするとき、実際のHEADはそのブランチではなく、detached HEADの状態です。 すると、ブランチに所属せず、特定のコミットを指している状態です。
git checkout origin/main
# または
git checkout <コミットID>
HEAD → origin/main の最新コミットを直接指す(ローカルブランチではない)
ブランチは指していない
→ この状態でコミットすると、その履歴はどのブランチにも属しません。
そのまま作業して、コミットできるか、そのコミットはブランチ属していない、浮いた状態です。
git log
, git reflog
で確認できますが、後で消える可能性がある
あくまで一時的な作業や、過去のコミットを試す時に使うモード
解決策
- ブランチからそのコミットハッシュをcherry-pickしたら解決
git log
# copy the コミット hash abc1234
git checkout branch
git cherry-pick abc1234
git push origin branch
- このコミットから新しいブランチを作成で解決
git branch feature/tmp abc1234
リベースの後で--force-with-lease
でプッシュ
git rebaseの後、--force でプッシュが必要でしょう。 このとき、--force-with-leaseでプッシュするとより安全にプッシュできます。
git push --force-with-lease
すべてのCommitを一つにする
GitHubで他の人が作ったボイラープレートをクローンして、自分のプロジェクトを始めることはよくあります。しかし、元のコミット履歴は不要なので、削除したほうがよいでしょう。 以下の手順でクリーンなリポジトリを作成できます:
方法1: 履歴のない新しいブランチを作成
# Navigate to your repository
cd your-repo
# Create a new orphan branch (no commit history)
git checkout --orphan clean-master
# Add all files
git add -A
# Create the first commit
git commit -m "Initial commit"
# Delete the old master branch
git branch -D master
# Rename the current branch to master
git branch -m master
# Force push to your remote repository
git push -f origin master
方法2: .gitフォルダを削除して再初期化
# Navigate to your repository
cd your-repo
# Remove the .git folder (this deletes all history)
rm -rf .git
# Initialize a new repository
git init
# Add all files
git add -A
# Create the first commit
git commit -m "Initial commit"
# Add your remote repository
git remote add origin https://github.com/yourusername/your-repo.git
# Push to your repository
git push -u origin master