【図解】git mergeとgit rebaseの違いを実例で解説(マージとリベースは何が違うのか?)|ブランチを統合する方法(初心者向け、わかりやすい)

git-prograshi(プロぐらし)-kv git/github
記事内に広告が含まれていることがあります。


git mergeとgit rebaseの違い

git merge

git mergeは元のブランチとトピックブランチ(分岐したブランチ)を統合した新しいコミットを作成します。

git rebaseとの違いは、トピックブランチ(分岐したブランチ)のコミットをとってこないことです。

このため、git merge後に生成されるコミットは1つのみです。

Githubを使ったプロジェクトでプルリクしそれが承認されたときに実行されるのが、git mergeです。


git mergeのイメージ図

例えば以下の図で、masterブランチの最新のコミットがC4だとします。そして、masterから分岐したブランチiss53の最新のコミットがC5だとします。

この状態で、iss53ブランチのコミットをmasterブランチにマージすると以下のようになります。

$ git merge iss53
point

mergeしたiss53ブランチの「C3」と「C5」のコミットはmasterブランチのコミットログに移動していないことに注目してください。

masterブランチでは「C4」のコミットの後に、iss53ブランチのコミット内容を統合した「C6」という新しいコミットを1つだけ作成しています。


git rebase

git rebaseはマージではなく、コミット履歴を移動したり修正、削除したりするコマンドです。

マージ前にコミット履歴をきれいにする目的で使用するのが一般的です。(例えば、git rebaseをしてから、プルリクを出すなど)

ただし、他のブランチから分岐した以降のコミットをとってくることができるので、マージと似たような処理をすることになります。

git rebaseをすると、分岐している他のブランチのコミットを分岐した時点からとってきて、自分のコミットの前に付け足すことができます。

枝分かれの枝を根本からポッキっと追って、本流にくっつけるイメージです。

注意点

git rebaseをすると、分岐した時点からのコミット内容をとってきて、自分の変更後のコミットをその先端に移動します。

取得してきたコミット番号は変わりませんが、自分ブランチのコミットは変更になります。(過去のコミット履歴が変わるため)


git rebaseのイメージ図

例えば以下のようにmasterブランチと、分岐したserverブランチがあるとします。

rebase後のコミット履歴のイメージ(git公式ページより)

ここで、serverブランチよりもmasterブランチのコミットがだいぶ先に進んでいます。

serverブランチgit rebaseを使うと、masterから分岐したC2以降のコミット(C5~C9’)を取り込むことができます。

git rebase master

serverブランチのコミット履歴の前に「C5~C9’」までが取り込まれました。そして、serverブランチのコミットがその先端にくっついています。

point

serverブランチの元のコミット「C3」「C4」「C10」が「C3’」「C4’」「C10’」になっていることに注目してください。

コミットは過去の履歴に全て紐づいています。このため過去の履歴が変わると、コミット番号も新たに変更されます。

serverブランチのC3以前のもともとのコミット履歴は「C1→C2」だったのが、「C1→C2→C5→C6→C8’→C9’」になっています。

masterブランチはserverブランチよりも遅れることになるので、masterブランチにserverブランチの内容を取り込むためには、git rebaseを行うか、mergeが必要です。

通常はserverブランチからmasterブランチにプルリクを出して、git mergeします。


(補足)トピックブランチとは?

派生(枝分かれ)したブランチのことです。

トピックブランチから枝分かれしたブランチをサブトピックブランチと呼んだりもします。

------------- master 
   \_________ topic
        \____ subtopic


git mergeの使い方

git mergeを使う場合は、mergeしたいブランチを指定します。

git merge <ブランチ名>

実行すると、マージ後のコミットには「Merge branch ‘指定したブランチ名’ into 実行したブランチ名」というコミットメッセージが入ります。

実例

例えば、testブランチでaaブランチの内容を取り込みたい場合は次のようにします。

#testブランチに移動
git checkout test

#aaブランチの内容をマージ
$ git merge aa
Merge made by the 'recursive' strategy.
 app/controllers/api/pj1/clients_controller.rb    |  49 +++++++++--
 app/javascript/app.vue                           |  62 +++++++++----
 app/javascript/components/Modal.vue              | 106 +++++++++++++++++++++++
(省略)
 17 files changed, 550 insertions(+), 36 deletions(-)
 create mode 100644 app/javascript/components/Modal.vue
 create mode 100644 app/javascript/components/Top.vue

すると、git mergeの下に処理内容が表示されgit mergeが実行されます。

ログ履歴を確認すると、分岐したブランチが統合されているのがわかります。

$ git log --oneline --graph
*   3eefcfb (HEAD -> test) Merge branch 'aa' into test
|\
| * 0701d9d (tag: v3.0, origin/aa, aa) [U]docker-compose add webpack port 3035
| * a90d4ef (tag: v2.0) [U]content-security-policy(CSP) enable webpack-dev-server

マージ後の新しいコミット「3eefcfb」が一つだけ生成されて、「Merge branch ‘aa’ into test」というコミットメッセージが入力されています。

合わせて読みたい

git log --oneline --graphが何をしているかについては下記をご参考ください。

【Git】git logを一行かつグラフで表示するオプション「–-oneline –-graph」で表示される内容を実例で解説


git mergeでオリジナルのコミットメッセージを作成する方法

git mergeを使った場合に、デフォルトの状態だと「Merge branch ‘指定したブランチ名’ into 実行したブランチ名」といったメッセージが自動で入ります。

-mオプションを使えば、これをオリジナルのコミットメッセージにすることもできます。

git merge <ブランチ名> -m "コミットメッセージの内容"

なお-mは--messageのショートオプションです。


実例

例えば、testブランチでaaブランチの内容を独自のコミットメッセージを付けて取り込みたい場合は次のようにします。

#testブランチに移動
git checkout test

#aaブランチの内容をマージ
$ git merge -m "オリジナルのコミットメッセージ" aa
Merge made by the 'recursive' strategy.
 app/controllers/api/pj1/clients_controller.rb    |  49 +++++++++--
 app/javascript/app.vue                           |  62 +++++++++----
 app/javascript/components/Modal.vue              | 106 +++++++++++++++++++++++
(省略)
 17 files changed, 550 insertions(+), 36 deletions(-)
 create mode 100644 app/javascript/components/Modal.vue
 create mode 100644 app/javascript/components/Top.vue

qgit mergeの下に処理内容が表示されgit mergeが実行されます。

ログ履歴を確認すると、分岐したブランチが統合され指定したコミットメッセージになっていることがわかります。

$ git log --oneline --graph
*   0341d3c (HEAD -> test) オリジナルのコミットメッセージ
|\
| * 0701d9d (tag: v3.0, origin/aa, aa) [U]docker-compose add webpack port 3035
| * a90d4ef (tag: v2.0) [U]content-security-policy(CSP) enable webpack-dev-server



git rebaseの使い方

rebaseとは土台を完全に移行するという意味です。このため元のブランチの内容を根っこから、指定したブランチのコミットログの先端にとりつけます。

git rebaseを使ってコミットをとってくる

git rebase <とってきたいコミットを持つブランチ名>

例えば以下のようなコミット履歴があるとします。

          A test
         /
    D---E---F---G aa

testブランチにはaaブランチのコミット「F」と「G」が取り込まれていません。

testブランチでgit rebase aaを実行すると、 aaブランチのコミット「F」と「G」をとってきて、自分の分岐後のコミット「A」を「A’」としてその先頭につけます。

                  test
    D---E---F---G---A'
                aa


実例

aaブランチから分岐したtestブランチのコミット履歴が以下のようになっているとします。

$ git log --oneline --graph
* 1a097d6 (HEAD -> test) [F]add div
* 6adca49 [A]destroyメソッド & Modal追加
* 61d3b4b [A]ClientEdit.vue

[F]add divというコミットメッセージの最新のコミットが「1a097d6」であることに注目してください。

aaをrebaseすると以下のようになります。

$ git rebase aa
Successfully rebased and updated refs/heads/test.

▼git logでコミット履歴を確認。

$ git log --oneline --graph
* 46fc789 (HEAD -> test) [F]add div
* 0701d9d (origin/aa, aa) [U]docker-compose add webpack port 3035
* a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server
* 6adca49 [A]destroyメソッド & Modal追加
* 61d3b4b [A]ClientEdit.vue

コミット履歴を確認すると、aaブランチの最新のコミット「0701d9d」の上にコミットメッセージ「[F]add div」のコミットがきています。

コミット履歴が変わったことで、コミット番号が「1a097d6」から「46fc789」に変わっていることがポイントです。


git rebaseを使ってコミット履歴を綺麗にしてから統合する

git rebaseではコミット履歴を取り込んだにすぎず、現在のブランチの内容をマージしたわけではありません。git rebaseを使ってコミット履歴を綺麗にしてから統合する手順は以下のようになります。

(1) トピックブランチに移動する。
(2) rebaseして本流ブランチ(masterやmain)の内容を取り込む。
(3) プルリクを出す or 本流ブランチに移動する
(4) プルリクを承認する or 本流ブランチでトピックブランチをmergeする。

rebaseしてからmergeするイメージ

まずは以下のように分岐したトピックブランチと本流のmasterブランチがあるとします。

          A---B---C topic
         /
    D---E---F---G master

topicブランチでmasterをrebaseすると以下のようになります。

                             topic
    D---E---F---G---A'---B'---C' 
              master 

最後に、masterでmergeを実行すれば、コミットを指すポインタが「C’」に移動します。

    D---E---F---G---A'---B'---C' 
                            master
                            topic



実例

rebase前のtopicブランチの履歴は下記のようになっているとします。topicブランチの履歴の中にmasterブランチはありません(分岐しているため)。

$ git log --graph --oneline

* 51328ce (HEAD -> topic) create main.js
* 0547564 edit css
* 3915358 add h5



rebaseを実行するとtopicブランチがmasterブランチの前に移動します。

#rebase実行
$ git rebase master

First, rewinding head to replay your work on top of it...
Applying: create main.js


#ログ確認
$ git log --graph --oneline

* 84df830 (HEAD -> topic) create main.js
* f35df23 (master) edit css
* 0547564 edit css
* 3915358 add h5



mergeで統合すると、masterブランチがtopicブランチの位置に移動します。分岐がないため、綺麗なコミット履歴にすることができます。

#mergeを実行するためmasterブランチに移動
$ git checkout master
Switched to branch 'master'

#merge実行
$ git merge -m "merge rabased branch" topic

Updating f35df23..84df830
Fast-forward (no commit created; -m option ignored)
 main.js | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 main.js

#ログを確認
$ git log --graph --oneline

* 84df830 (HEAD -> master, topic) create main.js
* f35df23 edit css
* 0547564 edit css
* 3915358 add h5



仕上げに不要になったtopicブランチを削除して完了です。

$ git branch -d topic
Deleted branch topic (was 84df830).


git rebaseでサブトピックブランチの統合 (rebase --onto)

rebaseの応用編として、サブトピックブランチのみを本流のブランチに統合することもできます。

サブトピックブランチとは、枝分かれから更に枝分かれしたブランチです。これのみを本流に移行する作業です。

--ontoオプションを使って3つのブランチを以下のように指定します。

git rebase --onto <統合先のブランチ名> <トピックブランチ名> <サブトピックブランチ名>


git rebase --ontoのイメージ

git rebase --ontoによる処理のイメージは以下のようになります。

まず、rebase前のコミット履歴は以下のようになっているとします。

                            H---I---J subtopic
                           /
                  E---F---G  topic
                 /
    A---B---C---D  master

rebase --ontoを使って、サブトピックブランチをmasterの先端にrebaseすると以下のようになります。

                  E---F---G  topic
                 /
    A---B---C---D---H'---I'---J'
              master        subtopic


--ontoの処理内容

git rebase --onto master topic subtopicコマンドを実行したときの裏側の処理は以下のようになっています。

  1. topicとsubtopicの共通祖先(G)までのコミットを一時保存。
  2. 保存したコミット(H-I-J)を、順にmasterに付け替える。

付け替えるとき、中身は同じでも、過去のコミット履歴の流れが変わるので、新たなコミットが付与されます(ハッシュ値が変わります)。


git rebaseでコミット履歴やメッセージを変更・削除する

git rebaseでコミット履歴やメッセージを変更・削除する方法

git rebaseでは「-i」(または「--interactive」)オプションを使うと、コミット履歴やメッセージを対話型で変更することができます。

interactiveとは対話形モードのことです。

git rebase -i <コミット>
注意点

指定したコミット以降の新しいコメントを表示します。指定したコミットは含みません。


実例

以下のようなログのコメントを変更する場合の例を紹介します。

$ git log --oneline --graph
* 46fc789 (HEAD -> test) [F]add div
* 0701d9d (origin/aa, aa) [U]docker-compose add webpack port 3035
* a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server
* 6adca49 [A]destroyメソッド & Modal追加
* 61d3b4b [A]ClientEdit.vue
* 00093d1 [F]ClientNewからClientForm.vueを切り出し
* a84cfc5 (tag: v2.1) [A]ClientNew.vue


タグ名「v2.1」が付いているコミットより後で作成したコミットを編集したい場合は、以下のコマンドを実行します。(※タグ名ではなく、a84cfc5や@^^^^^^を指定した場合も同じ処理になります)

#-iオプションでコミットを指定
$ git rebase -i v2.1
(参考)タグって何?
(参考)@^^^^って何?


するとvimエディタが立ち上がり、以下のような内容が表示されます。(VSCodeを使っている場合は、新しいファイルが表示されます)

pick 00093d1 [F]ClientNewからClientForm.vueを切り出し
pick 61d3b4b [A]ClientEdit.vue
pick 6adca49 [A]destroyメソッド & Modal追加
pick a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server
pick 0701d9d [U]docker-compose add webpack port 3035
pick 46fc789 [F]add div

# Rebase a84cfc5..46fc789 onto a84cfc5 (6 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
#                    commit's log message, unless -C is used, in which case
#                    keep only this commit's message; -c is same as -C but
#                    opens the editor
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
# .       create a merge commit using the original merge commit's
# .       message (or the oneline, if no original merge commit was
# .       specified); use -c <commit> to reword the commit message
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#

上に表示され、ハッシュ値とコミットメッセージがある部分の左側に「pick」という文字が表示されているのに注目してください。

これが現在採用しているコミットメッセージという意味です。

これらの内容に対して、コメントアウト(#)がある行以降で表示されているオプションの中から実行したい処理を選びます。

rebase -iのオプション一覧

オプション省略表記内容
pickp現在のまま(変更なし)
rewordrコミットメッセージを編集
edite指定したコミットまで残す(以降を消す)
squachs直前のコミットに統合する
fixedf直前のコミットに統合する。その際このコミットメッセージを消す
execxshellでコマンドを実行する
breakb処理を中断する
dropdコミットを削除する



例えば、コミットメッセージを変更する場合は「pick」を「r(reword)」にし、コミットメッセージを編集します。コミットを削q除する場合はd(drop)に書き換えます。

ここでは最新のコミットを編集する指定にして、2つ目と3つ目のコミットを削除します。

pick 00093d1 [F]ClientNewからClientForm.vueを切り出し
pick 61d3b4b [A]ClientEdit.vue
pick 6adca49 [A]destroyメソッド & Modal追加
d a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server
d 0701d9d [U]docker-compose add webpack port 3035
r 46fc789 [F]add div

保存してエディタを閉じます。

すると、「r」に変更したコミットを編集するためのエディタが起動します。(「r」なしで「d」のみの場合はこの処理はありません。)

[F]add div

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date:      Wed Jan 26 15:54:37 2022 +0900
#
# interactive rebase in progress; onto a84cfc5
# Last commands done (4 commands done):
#    pick 6adca49 [A]destroyメソッド & Modal追加
#    reword d1f95ff コミットを変更しました。
# No commands remaining.
# You are currently editing a commit while rebasing branch 'test' on 'a84cfc5'.
#
# Changes to be committed:
#	modified:   app/javascript/components/Header.vue
#
# Untracked files:
#	debug.log
#

以下のコメントアウト(#)より上の部分のメッセージを編集します。

コミットを編集しました。

# Please enter the commit message for your changes. Lines starting
(省略)

保存してエディタを閉じます。

以下のように表示されれば完了です。

$ git rebase -i v2.1
[detached HEAD 9e5ebb1] コミットを編集しました。
 Date: Wed Jan 26 15:54:37 2022 +0900
 1 file changed, 1 insertion(+)
Successfully rebased and updated refs/heads/test.

ログを確認すると以下のようになっています。

9e5ebb1 (HEAD -> test) コミットを編集しました。
6adca49 [A]destroyメソッド & Modal追加
61d3b4b [A]ClientEdit.vue
00093d1 [F]ClientNewからClientForm.vueを切り出し
a84cfc5 (tag: v2.1) [A]ClientNew.vue

最新のコミットのコミットメッセージが指定した内容に変更され、2番目と3番目のコミット「a90d4ef [U]content-security-policy(CSP) enable webpack-dev-server」と「0701d9d [U]docker-compose add webpack port 3035」が削除されていることがわかります。

また、過去のコミット履歴が変わっているので、最新のコミット番号も「46fc789」から「9e5ebb1」に変更されている点もポイントです。


困った時の対処法(--abort)

git mergeやrebaseでコンフリクトが発生したり、rebase -iのコミット履歴変更を元に戻したい場合は、--abortオプションをつけて実行します。

abortは進行中の作業を強制中断する意味です。

git merge --abort
git rebase --abort


git conflictが発生した場合の対処法

git rebaseやmergeなど他のブランチの情報を取り込む際にコンフリクト(conflict)が発生して処理を実行できない場合があります。

例えば次のようなエラーが発生します。

エラーの内容

git rebaseでエラーが発生した場合次のようなエラーが内容されます。

$ git rebase origin/master
First, rewinding head to replay your work on top of it...
Applying: [A]article show
Using index info to reconstruct a base tree...
M       db/schema.rb
Falling back to patching base and 3-way merge...
Auto-merging db/schema.rb
CONFLICT (content): Merge conflict in db/schema.rb
error: Failed to merge in the changes.
Patch failed at 0001 [A]article show
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

エラーの内容はやたらと長くて複雑に見えますが、重要な部分は次の2つです。

CONFLICT (content): Merge conflict in db/schema.rb
error: Failed to merge in the changes.

マージする際に、db/schema.rbというファイルでコンフリクトが発生したという内容です。

Merge conflict in <ファイル名> のファイル名に注目してください。


次に重要なのは最後の4行です。ここにコンフリクトの解決方法が3つ記されています。

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

詳しくは次の章で解説します。

point

hint: Use で定時されている ‘git am --show-current-patch‘ は現在のローカルのステージングの変更内容を表示します。コンフリクトの解決にはあまり役に立ちません。


コンフリクトの3つの対処方法

上記3つの対処方法は何をするかによって変わります。

  1. 自分でコードをいじってコンフリクトを解決する。
  2. 今回のリベースをスキップする。
  3. 今回のリベースをキャンセルする。


自分でコードを編集してコンフリクトを解決する

最も王道の解決方法は「自分でコードを編集してコンフリクトを解決する」ことです。

Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".

実行手順

手順は次の3ステップです。

  1. コンフリクトが発生しているファイルの内容を修正する。
  2. git add <ファイル名> で対象のファイルをステージングする。
  3. git rebase --continue を実行する。


対象ファイルの修正

まずはコンフリクトが発生しているファイルを開きます。VSCodeを使っている場合はわかりやすくカラーで何が衝突しているかを教えてくれます。

<<<<<<と====と>>>>>>の間に囲まれている部分がポイントです。

<<<<<<<< HEAD (Current Change)
現在取り込もうとしている内容
=====
自分の変更内容
>>>>>>>> <コミットメッセージ> (Incoming Change)

上側のCurrent Changeの部分が取り込もうとしている内容です。自分のローカルとは違ってレポジトリの内容になるためCurrent Change(現在の変更内容)と言われています。

下側が自分のコミットです。新たに入れ込もうとしているのでIncomming Changeとなっています。

Current Changeの方が正しければ、下側や<<<<<<<といった不要な記号を消して、Current Changeの内容にします。Incomming Changeの場合はCurrent Changeを消します。

両方とも必要な場合はどちらも残します。

要は、編集を加えて最終形にすればOKです

上記の例ではレポジトリの内容(上側)が正しいので、Current Changeを残して他を削除します。


VSCodeの便利オプション

VSCodeではコンフリクトが発生した時に便利なオプションが用意されています。

コンフリクトしている内容の上に表示されているオプションを選択すると、コードを自動編集してくれます。

オプション内容
Accept Current ChangeCurrent Changeの内容を残す(Incomming Changeや余計な記号は消す)
Accept Incoming ChangeIncomming Changeの内容を残す(Current Changeや余計な記号は消す)
Accept Both Change両方の内容を残す(余計な記号は消す)
Compare Changes左右のウィンドウで変更点を比較する

それぞれ選択すると次のようになります。

コンフリクト中のコード

<<<<<<< HEAD
ActiveRecord::Schema.define(version: 2021_15_08_103381) do
=======
ActiveRecord::Schema.define(version: 2021_15_08_103372) do
>>>>>>> [A]article events


Accept Current Change

ActiveRecord::Schema.define(version: 2021_15_08_103381) do


Accept Incomming Change

ActiveRecord::Schema.define(version: 2021_15_08_103372) do


Accept Incomming Change

ActiveRecord::Schema.define(version: 2021_15_08_103381) do
ActiveRecord::Schema.define(version: 2021_15_08_103372) do


Comapre Changes

右側のウィンドウを閉じると、元のコンフリクト状態の画面に戻ります。


変更後のファイルをステージングする

ファイルの内容が正しく修正できたら、git add <ファイルパス> を行います。

$ git add db/schema.rb


この状態でgit status で状態を確認するとrebaseが進行中であることが表示されます。

$ git st
rebase in progress; onto a170a57c2
You are currently rebasing branch 'test' on 'a170a57c2'.
  (all conflicts fixed: run "git rebase --continue")

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
  
  ステージングしたファイルの一覧がずらっと並ぶ


git rebase --continue を実行する

最後にgit rebase --continue を実行して完了となります。

$ git rebase --continue
Applying: [A]article events
Applying: [WIP]article yearly pv
Applying: [F]article_years model and job

git log でログを確認すれば、まだ取り込んでいなかったコミットが追加されていることが確認できます。

リモートレポジトリにプッシュできない場合

コンフリクトを修正した後に、リモートレポジトリにプッシュしようとすると、エラーメッセージが表示されてpushできない場合があります。

▼エラーメッセージの例

$ git push origin test
To github.com:xxx/yyy.git
 ! [rejected]            test -> test (non-fast-forward)
error: failed to push some refs to 'git@github.com:xxx/yyy.git'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

これは既にリモートレポジトリに過去のファイルをプッシュしてしまった場合に発生します。

※基本的にコンフリクトを注意されるのは、リモートレポジトリにプッシュした後なので、上記のメッセージがでます。


対処法は、現在ローカルで行った修正内容が正しいので -f オプションを使って強制的にプッシュします。

$ git push origin test -f
Enumerating objects: 65, done.
Counting objects: 100% (65/65), done.
Delta compression using up to 12 threads
Compressing objects: 100% (50/50), done.
Writing objects: 100% (50/50), 7.32 KiB | 1.46 MiB/s, done.
Total 50 (delta 41), reused 0 (delta 0)
remote: Resolving deltas: 100% (41/41), completed with 15 local objects.
To github.com:xxx/yyy.git
 + 69751d9b1...6e98e6c92 test -> test (forced update)

以上で完了です。

最後にgit log --onelineでコミットログを確認すると、自分のローカルとリモートレポジトリが、取り込もうとしていたブランチ(以下では origin/master)より上に来ていることがわかります。

$ git log --oneline
6e98e6c92 (HEAD -> test, origin/test) [F]article_years model and job
8dbb9dcb5 [WIP]article year pv
11ee776ea [A]article events
a170a57c2 (origin/master) Merge pull request #1422 from xxxx/zzz


今回のリベースをスキップする

コンフリクトした際に表示される2つ目のオプションはgit rebase --skipです。

これを使うとコミットをスキップできます。

You can instead skip this commit: run "git rebase --skip".

あまり使うことがないオプションかなと思います。


今回のリベースをキャンセルする

コンフリクトした際に表示される3つ目のオプションはgit rebase --abortです。

git rebase自体を無かったことにできる便利コマンドです。コンフリクトの内容や修正方法がわからない場合はとりあえずgit rebase --abortをしておくと、無難にコンフリクトなしの状態に戻せます。

To abort and get back to the state before "git rebase", run "git rebase --abort".

比較的よく使うオプションです。


タイトルとURLをコピーしました