Open6

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 .

参考・引用

https://zenn.dev/mikaneko/articles/0fe1daf2e8a987

https://zenn.dev/owayo/articles/a009820118060f

https://gist.github.com/d-kuro/08ec0964107ae4c8bc074ed8162b63cc

https://qiita.com/ucan-lab/items/0a128bb14528e4e52fd2#git-rebase-コマンドの解説

https://qiita.com/KaitoMuraoka/items/880a2022adb06dca89f0

https://qiita.com/Hashimoto-Noriaki/items/6e183f738289cf288b23

https://qiita.com/asosori2/items/bf5405978ac7409d0557

https://qiita.com/dys/items/c062b1be0d0287352e37

https://sakaishun.com/2022/09/23/git-pull-rebase/

https://kray.jp/blog/git-pull-rebase/

ピン留めされたアイテム
まさぴょんまさぴょん

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 ブランチ名

このコマンドを使うと、他の人の作業を上書きせずに、リモートブランチに対して自分の変更を反映できるので、チームでの作業の安全性を高めるのに役立ちます。

https://zenn.dev/mary_pp/articles/eaac544eaf600a

まさぴょんまさぴょん

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 開発用ブランチ

https://qiita.com/ksygu/items/7ca1e72c6c079d3a25c1

https://qiita.com/kuramoto30/items/6924a92b512dc073f058

https://qiita.com/chihiro/items/5dd671aa6f1c332986a7

https://zenn.dev/tana0102/articles/475d8952933af6

https://www-creators.com/archives/2111

https://qiita.com/chihiro/items/2fa827d0eac98109e7ee

https://codelikes.com/git-merge/

まさぴょんまさぴょん

「ours」と「theirs」を理解する

Git では、マージまたはリベース中に競合が発生した場合、「ours」と「theirs」のいずれかを選択して競合を解決することができます。
「ours」と「theirs」が何を指すかを理解することは、競合を効果的に解決するために重要です。

  • ours: 現在のブランチ (マージまたはリベースを開始する前にチェックアウトしたブランチ) を指します。これは、ローカルの変更を表します。

  • theirs: 現在のブランチにマージされるブランチを指します。これは、別のブランチ (多くの場合、リモート リポジトリ) から受信した変更を表します。

コマンドの説明

1. ローカルの変更 (ours) を維持して競合を解決する

git checkout --ours .

説明:

  • 目的: このコマンドは、現在のブランチからの変更 (ローカルの変更) を保持することで、現在のすべての競合を解決します。

  • 実行内容:

  • 作業ディレクトリ内の競合ファイルを、現在のブランチのバージョンに置き換えます。

  • 競合を解決済みとしてマークします。

  • 使用例: ローカルの変更を信頼し、他のブランチから受信した変更を破棄したい場合に使用します。

2. 受信した変更 (theirs) を受け入れて競合を解決する

git checkout --theirs .

説明:

  • 目的: このコマンドは、マージ先のブランチからの変更 (多くの場合、リモート リポジトリからの受信した変更) を受け入れて、現在のすべての競合を解決します。

  • 機能:

  • 作業ディレクトリ内の競合ファイルを、マージされるブランチのバージョンに置き換えます。

  • 競合を解決済みとしてマークします。

  • 使用例: ローカルの変更を破棄して、他のブランチから受信した変更を優先する場合に使用します。

用語に関する重要な注意

提供されたコメントに誤解があるようです:

  • コメント:

  • **「現在の変更」(リモート) の場合: git checkout --ours .

  • **「受信した変更」(ローカル) の場合: git checkout --theirs .

  • 説明:

  • 「現在の変更」(ours) は、実際には ローカル ブランチ を指し、リモート ブランチを指しません。

  • 「受信した変更」(theirs) は、マージされるブランチ を指し、多くの場合、リモート ブランチを指します。

視覚的な表現

master にいて、featuremaster にマージしていると仮定します:

  • master: 現在のブランチ (ours)。

  • feature: マージされるブランチ (theirs)。

競合を解決する手順

  1. 競合するファイルを識別する:
git status
  1. 解決戦略を選択する:
  • ローカルの変更を保持する:
git checkout --ours .
  • 受信した変更を受け入れる:
git checkout --theirs .
  1. 解決されたファイルを追加する:
git add .
  1. マージを確定する:
git commit -m "マージ競合を解決しました"

要約

  • git checkout --ours .: ローカルの変更 (現在のブランチ) を保持し、他のブランチから受信した変更を破棄します。

  • git checkout --theirs .: 他のブランチから受信した変更を受け入れ、競合ファイル内のローカルの変更を破棄します。

この違いを理解することで、マージ競合時に情報に基づいた決定を下すことができ、プロジェクトに組み込む変更を制御できるようになります。