git pull実行時にローカルで未コミットの変更を保持する方法
こんにちは、CX事業本部の若槻です。
git pull
を実行する際に、ローカルで未コミットの変更をリモートに反映させずローカルでだけ保持したい場合があります。
例えば、以下のようにhoge.txt
の変更がローカルで行われていますが、この変更はリモートには反映したくないため、未コミットとしています。
$ cat hoge.txt
ローカルでの変更
$ git fetch
$ git diff remotes/origin/master
diff --git a/hoge.txt b/hoge.txt
index 48ee78d..e3130ae 100644
--- a/hoge.txt
+++ b/hoge.txt
@@ -1 +1 @@
-リモートでの変更
+ローカルでの変更
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hoge.txt
no changes added to commit (use "git add" and/or "git commit -a")
しかし、この状態でgit pull
をすると以下のようにエラーとなり、プル操作が行えません。
$ git pull origin master
From https://github.com/account/test
* branch master -> FETCH_HEAD
Updating 017abaf..c79d59e
error: Your local changes to the following files would be overwritten by merge:
hoge.txt
Please commit your changes or stash them before you merge.
Aborting
対処方法
以下の2通りの対処方法をご紹介します。
- リモートの変更で上書きせず、ローカルでの変更を保持したい場合
- やっぱりリモートの変更で上書きしたくなった場合
リモートの変更で上書きせず、ローカルでの変更を保持したい場合
事前に、ローカルでだけ保持したい変更以外の変更をすべてコミットしておきます。
ローカルでだけ保持したい変更をgit stash
で退避させ、ローカルをクリーンな状態にします。
$ git stash save
Saved working directory and index state WIP on master: 017abaf Create hoge.txt
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
この状態でgit pull
をします。ローカルのhoge.txt
がリモートでの変更で上書きされます。
$ git pull origin master
From https://github.com/r-wakatsuki/test
* branch master -> FETCH_HEAD
Updating 017abaf..c79d59e
Fast-forward
hoge.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ cat hoge.txt
リモートでの変更
退避させた変更をstashから戻します。このときhoge.txt
は競合状態となります。
$ git stash apply stash@{0}
Auto-merging hoge.txt
CONFLICT (content): Merge conflict in hoge.txt
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: hoge.txt
no changes added to commit (use "git add" and/or "git commit -a")
$ cat hoge.txt
<<<<<<< Updated upstream
リモートでの変更
=======
ローカルでの変更
>>>>>>> Stashed changes
競合した変更のうちstashから戻した方の変更を適用します。状態としてはhoge.txt
はまだ競合状態にあります。
$ git checkout --theirs .
$ cat hoge.txt
ローカルでの変更
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: hoge.txt
no changes added to commit (use "git add" and/or "git commit -a")
hoge.txt
を一旦ステージングして競合状態を解消します。
$ git add .
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: hoge.txt
hoge.txt
のステージングを取り消します。これでローカルで未コミットの変更を保持したままgit pull
を行うことができました。
$ git reset HEAD
Unstaged changes after reset:
M hoge.txt
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: hoge.txt
no changes added to commit (use "git add" and/or "git commit -a")
リモートの変更で上書きして良い場合
ローカルで未コミットのまま作業してきた変更を、git pull
時に「やっぱりリモートの変更で上書きしてもいいや」となった場合の対処方法です。
変更を未コミットとしているhoge.txt
に対してチェックアウトを行い、ローカルでの最後のコミット内容を適用してローカルをクリーンにします。
$ git checkout hoge.txt
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
git pull
を実行してリモートの変更で上書きします。
$ git pull origin master
From https://github.com/account/test
* branch master -> FETCH_HEAD
Updating c79d59e..37b80c5
Fast-forward
hoge.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
$ cat hoge.txt
リモートでの変更
おわりに
git pull
を実行する際に、ローカルで未コミットの変更に対して
- リモートの変更で上書きせず、ローカルでの変更を保持したい場合
- やっぱりリモートの変更で上書きしたくなった場合
の対処方法についてご紹介しました。
リポジトリに含まれている構成ファイルなどを作業のためにローカルでだけ変更することはよくあるので、覚えておくと役に立ちそうです。どなたかの参考になれば幸いです。
以上