Git・GitHub の merge とrebase について
git pull --rebase
Gitでrebaseを行う際、事前にmasterブランチの最新の変更を取り込んでおくことで、コンフリクトの発生を減らすことができます!
まずは、最新 master を pullしてから事項の Rebase作業を始めましょう💪🥺🔥
Rebase作業と完了まで
# Remote の master から Rebase で pullしてくる (localブランチに取り込む)
git pull --rebase origin master
# Conflictを解消して、git add と git commit を実行する
# Conflictなど解消したら、continueする
# まだConflictがある場合は、またConflictを解消して、git add と git commit を実行する
# すべてのConflictを解消すると、Rebaseが完了となる
git rebase --continue
# コンフリクトを解消した後に、注意するのが、pushをする時です!
# 通常の pushができなくなるはずなので、Force Pushすることになります!
# ただし、通常の「git push --force origin ブランチ名」ではなく、
# ローカルで rebase 後にリモートにpushするときは、次のコマンドが安全
git push --force-with-lease --force-if-includes origin ブランチ名
Gitのrebase作業を途中で中止したい場合
git rebase --abort
コミットをまとめたい場合
git rebase -i HEAD~3 # 直近3つのコミットを整理
# または、次のようにもできる
git rebase -i <commit_id> # commit_id より後ろのコミットを整理
コンフリクトの解決選択:「現在の変更」と「入力側の変更」
「現在の変更」:Local Repository
「入力側の変更」:Remote Repository
# コンフリクトを「現在の変更」(Local に合わせる)で解決する場合
git checkout --ours .
# コンフリクトを「入力側の変更」(Remote に合わせる)で解決する場合
git checkout --theirs .
参考・引用
git push --force-with-lease --force-if-includes について
git push --force-with-lease --force-if-includes origin ブランチ名
コマンドは、
Gitでブランチをリモートリポジトリに強制的にプッシュする際のオプションを組み合わせたものです。
それぞれのオプションがどのように機能するかを説明します。
コマンドの各部分
-
git push
: リモートリポジトリに対して、ローカルの変更をプッシュする基本的なコマンドです。 -
--force-with-lease
: このオプションは「安全な強制プッシュ」とも言われます。--force
の代わりに使うことが推奨されており、リモートにあるブランチの現在の状態を確認してからのみ強制的にプッシュします。- 他の人がリモートの同じブランチに変更を加えていない場合は、問題なくプッシュが実行されます。
- 他の人がリモートブランチに変更を加えている場合、競合が発生するため、強制プッシュは行われません。
- つまり、競合を避けつつ、必要なときには強制プッシュを行いたい場合に役立ちます。
-
--force-if-includes
: このオプションは、ローカルの変更がリモートの変更も「包含」している場合にのみ強制的にプッシュします。- つまり、リモートに自分の変更が含まれていることを確認した上でプッシュしたい場合に便利です。
- リモートの変更を巻き戻してしまうリスクを防ぎつつ、ローカルの変更を反映させることができます。
組み合わせて使う目的
- **
--force-with-lease
と--force-if-includes
**を同時に使用することで、より安全に強制プッシュができます。 - 他の開発者の変更をリモートに保持しつつ、自分の変更を適用する際に使用されます。
例:
git push --force-with-lease --force-if-includes origin ブランチ名
このコマンドを使うと、他の人の作業を上書きせずに、リモートブランチに対して自分の変更を反映できるので、チームでの作業の安全性を高めるのに役立ちます。
Git Merge
# 1. masterブランチへ移動
git checkout master
# 2. git pullでmasterを最新に
git pull origin master
# 3. 開発用ブランチへ移動
git checkout 開発用ブランチ
# 4. mergeコマンドでmaserの内容を取り込む
git merge master
# 5. 取り込んだものをリモートにpush
git push origin 開発用ブランチ
git rebase でError
git rebase development
# [ Error内容 ]
It seems that I cannot create a rebase-apply directory, and
I wonder if you are in the middle of patch application or another
rebase. If that is not the case, please
rm -fr ".git/rebase-merge" and run me again.
and run me again. I am stopping in case you still have something
valuable there.
「ours」と「theirs」を理解する
Git では、マージまたはリベース中に競合が発生した場合、「ours」と「theirs」のいずれかを選択して競合を解決することができます。
「ours」と「theirs」が何を指すかを理解することは、競合を効果的に解決するために重要です。
-
ours
: 現在のブランチ (マージまたはリベースを開始する前にチェックアウトしたブランチ) を指します。これは、ローカルの変更を表します。 -
theirs
: 現在のブランチにマージされるブランチを指します。これは、別のブランチ (多くの場合、リモート リポジトリ) から受信した変更を表します。
コマンドの説明
ours
) を維持して競合を解決する
1. ローカルの変更 (git checkout --ours .
説明:
-
目的: このコマンドは、現在のブランチからの変更 (ローカルの変更) を保持することで、現在のすべての競合を解決します。
-
実行内容:
-
作業ディレクトリ内の競合ファイルを、現在のブランチのバージョンに置き換えます。
-
競合を解決済みとしてマークします。
-
使用例: ローカルの変更を信頼し、他のブランチから受信した変更を破棄したい場合に使用します。
theirs
) を受け入れて競合を解決する
2. 受信した変更 (git checkout --theirs .
説明:
-
目的: このコマンドは、マージ先のブランチからの変更 (多くの場合、リモート リポジトリからの受信した変更) を受け入れて、現在のすべての競合を解決します。
-
機能:
-
作業ディレクトリ内の競合ファイルを、マージされるブランチのバージョンに置き換えます。
-
競合を解決済みとしてマークします。
-
使用例: ローカルの変更を破棄して、他のブランチから受信した変更を優先する場合に使用します。
用語に関する重要な注意
提供されたコメントに誤解があるようです:
-
コメント:
-
**「現在の変更」(リモート) の場合:
git checkout --ours .
-
**「受信した変更」(ローカル) の場合:
git checkout --theirs .
-
説明:
-
「現在の変更」(
ours
) は、実際には ローカル ブランチ を指し、リモート ブランチを指しません。 -
「受信した変更」(
theirs
) は、マージされるブランチ を指し、多くの場合、リモート ブランチを指します。
視覚的な表現
master
にいて、feature
を master
にマージしていると仮定します:
-
master
: 現在のブランチ (ours
)。 -
feature
: マージされるブランチ (theirs
)。
競合を解決する手順
- 競合するファイルを識別する:
git status
- 解決戦略を選択する:
- ローカルの変更を保持する:
git checkout --ours .
- 受信した変更を受け入れる:
git checkout --theirs .
- 解決されたファイルを追加する:
git add .
- マージを確定する:
git commit -m "マージ競合を解決しました"
要約
-
git checkout --ours .
: ローカルの変更 (現在のブランチ) を保持し、他のブランチから受信した変更を破棄します。 -
git checkout --theirs .
: 他のブランチから受信した変更を受け入れ、競合ファイル内のローカルの変更を破棄します。
この違いを理解することで、マージ競合時に情報に基づいた決定を下すことができ、プロジェクトに組み込む変更を制御できるようになります。