概要
- ローカルでの作業結果をリモートにpushしようとしたとき、その間に他のユーザーがリモートに変更を加えていると、エラーになりpushできない
- そのようなときは、リモートからpullまたはfetch & mergeで変更内容をローカルにマージし、その結果をpushする
準備
リモートリポジトリーの準備
あらかじめ空のリモートリポジトリーexample
を準備しておく。以降、これに対してローカルで2人のユーザーを想定して変更を加える。
user1の作成とクローン
ローカルでuser1
ディレクトリーを作成し、そこにリモートリポジトリーをクローンして移動。
1 2 3 4 5 6 7 8 9 |
[vagrant@localhost git]$ mkdir user1 && cd user1 [vagrant@localhost user1]$ git clone git@github.com:taustation/example.git Cloning into 'example'... Enter passphrase for key '/home/vagrant/.ssh/id_rsa': remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done. [vagrant@localhost user1]$ cd example/ |
ローカルのログ。
1 2 3 4 5 6 |
[vagrant@localhost example]$ git log commit 2a3e7602dcfe8f83868eb3d85556786de571b043 (HEAD -> main, origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |
同様にuser2ディレクトリーを作成し、そこにもリモートリポジトリーをクローンして移動。
1 2 3 4 5 6 7 8 9 |
[vagrant@localhost git]$ mkdir user2 && cd user2 [vagrant@localhost user2]$ git clone git@github.com:taustation/example.git Cloning into 'example'... Enter passphrase for key '/home/vagrant/.ssh/id_rsa': remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 Receiving objects: 100% (3/3), done. [vagrant@localhost user2]$ cd example/ |
ログはuser1
と同じ内容。
1 2 3 4 5 6 |
[vagrant@localhost example]$ git log commit 2a3e7602dcfe8f83868eb3d85556786de571b043 (HEAD -> main, origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |
user1によるコミット・プッシュ
user1
で新規ファイルを作成してコミット。
1 2 3 4 5 6 7 8 |
[vagrant@localhost example]$ vi user1.txt [vagrant@localhost example]$ cat user1.txt user1による新規追加 [vagrant@localhost example]$ git add . [vagrant@localhost example]$ git commit -m "created user1.txt" [main f515a8a] created user1.txt 1 file changed, 1 insertion(+) create mode 100644 user1.txt |
ローカルのログには新たなコミットが加わっている。
1 2 3 4 5 6 7 8 9 10 11 12 |
[vagrant@localhost example]$ git log commit f515a8ade4ea3d225cff1dd374895acf313ceca1 (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:31:33 2021 +0900 created user1.txt commit 2a3e7602dcfe8f83868eb3d85556786de571b043 (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |
この内容でリモートにプッシュする。リモートには新たなコミットが追加されるが、user1側のローカルには反映されない。
1 2 3 4 5 6 7 8 9 |
[vagrant@localhost example]$ git push Enter passphrase for key '/home/vagrant/.ssh/id_rsa': Enumerating objects: 4, done. Counting objects: 100% (4/4), done. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 304 bytes | 304.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0) To github.com:taustation/example.git 2a3e760..f515a8a main -> main |
user2によるコミット・プッシュ・エラー
現時点でuser2
のローカルリポジトリーの内容がリモートと異なっている状態で、user2
でファイルを作成・コミット。
1 2 3 4 5 6 7 8 |
[vagrant@localhost example]$ vi user2.txt [vagrant@localhost example]$ cat user2.txt user2による新規追加 [vagrant@localhost example]$ git add . [vagrant@localhost example]$ git commit -m "created user2.txt" [main 8ead5ca] created user2.txt 1 file changed, 1 insertion(+) create mode 100644 user2.txt |
user2
のローカルのログでは、user1
のコミットは当然反映されていない。
1 2 3 4 5 6 7 8 9 10 11 12 |
[vagrant@localhost example]$ git log commit 8ead5caf0200c88e2b6fa70ddc2ff9d97d535da8 (HEAD -> main) Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:33:29 2021 +0900 created user2.txt commit 2a3e7602dcfe8f83868eb3d85556786de571b043 (origin/main, origin/HEAD) Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |
この状態でuser2
からコミット結果をプッシュしようとすると、リモートリポジトリーがその後の作業結果を含んでいるので更新できない、とエラーになる。
1 2 3 4 5 6 7 8 9 10 |
[vagrant@localhost example]$ git push Enter passphrase for key '/home/vagrant/.ssh/id_rsa': To github.com:taustation/example.git ! [rejected] main -> main (fetch first) error: failed to push some refs to 'git@github.com:taustation/example.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. |
対応処理
このようなエラーの場合、リモートの内容をgit pullするか、フェッチ後にマージする。ここではfetch & merge
で進める。
フェッチ
まずリモートの内容をフェッチ。
1 2 3 4 5 6 7 8 9 |
[vagrant@localhost example]$ git fetch Enter passphrase for key '/home/vagrant/.ssh/id_rsa': remote: Enumerating objects: 4, done. remote: Counting objects: 100% (4/4), done. remote: Compressing objects: 100% (2/2), done. remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:taustation/example 2a3e760..f515a8a main -> origin/main |
フェッチされたリポジトリーFETCH_HEAD
に移動。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[vagrant@localhost example]$ git checkout FETCH_HEAD Note: switching to 'FETCH_HEAD'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at f515a8a created user1.txt |
フェッチされた内容のログ。user2
クローン後のuser1
による変更が記録されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
[vagrant@localhost example]$ git log commit f515a8ade4ea3d225cff1dd374895acf313ceca1 (HEAD, origin/main, origin/HEAD) Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:31:33 2021 +0900 created user1.txt commit 2a3e7602dcfe8f83868eb3d85556786de571b043 Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit [vagrant@localhost example]$ git branch * (HEAD detached at FETCH_HEAD) main |
マージ
main
ブランチに移動
1 2 3 4 5 6 7 8 9 |
[vagrant@localhost example]$ git branch * (HEAD detached at FETCH_HEAD) main [vagrant@localhost example]$ git checkout main Previous HEAD position was f515a8a created user1.txt Switched to branch 'main' Your branch and 'origin/main' have diverged, and have 1 and 1 different commits each, respectively. (use "git pull" to merge the remote branch into yours) |
作業中のmain
ブランチにフェッチされた内容をマージ。このマージはno-faseet-forwardになるので、エディターが立ち上がる。
1 2 3 4 5 |
[vagrant@localhost example]$ git merge FETCH_HEAD Merge made by the 'recursive' strategy. user1.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 user1.txt |
マージ後のログ。user1
、user2
のコミットが含まれ、マージコミットが加わっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[vagrant@localhost example]$ git log commit 30dc6433f7e4519d8a4c4ff9288812aed1d9bba9 (HEAD -> main) Merge: 8ead5ca f515a8a Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:48:22 2021 +0900 Merge branch 'main' of github.com:taustation/example into main merging user1's work by user2 commit 8ead5caf0200c88e2b6fa70ddc2ff9d97d535da8 Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:33:29 2021 +0900 created user2.txt commit f515a8ade4ea3d225cff1dd374895acf313ceca1 (origin/main, origin/HEAD) Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:31:33 2021 +0900 created user1.txt commit 2a3e7602dcfe8f83868eb3d85556786de571b043 Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |
git log --graph
でも確認。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
* commit 30dc6433f7e4519d8a4c4ff9288812aed1d9bba9 (HEAD -> main, origin/main, origin/HEAD) |\ Merge: 8ead5ca f515a8a | | Author: taustation <taustation@gmail.com> | | Date: Fri Aug 13 09:48:22 2021 +0900 | | | | Merge branch 'main' of github.com:taustation/example into main | | merging user1's work by user2 | | | * commit f515a8ade4ea3d225cff1dd374895acf313ceca1 | | Author: taustation <taustation@gmail.com> | | Date: Fri Aug 13 09:31:33 2021 +0900 | | | | created user1.txt | | * | commit 8ead5caf0200c88e2b6fa70ddc2ff9d97d535da8 |/ Author: taustation <taustation@gmail.com> | Date: Fri Aug 13 09:33:29 2021 +0900 | | created user2.txt | * commit 2a3e7602dcfe8f83868eb3d85556786de571b043 Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |
プッシュ
マージされた内容で、改めてプッシュ。
1 2 3 4 5 6 7 8 9 10 11 |
[vagrant@localhost example]$ git push Enter passphrase for key '/home/vagrant/.ssh/id_rsa': Enter passphrase for key '/home/vagrant/.ssh/id_rsa': Enumerating objects: 7, done. Counting objects: 100% (7/7), done. Compressing objects: 100% (4/4), done. Writing objects: 100% (5/5), 577 bytes | 577.00 KiB/s, done. Total 5 (delta 1), reused 0 (delta 0) remote: Resolving deltas: 100% (1/1), done. To github.com:taustation/example.git f515a8a..30dc643 main -> main |
リモートへの繁栄の確認
プッシュ後のリモートの内容をuser1
でプル。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[vagrant@localhost example]$ git pull Enter passphrase for key '/home/vagrant/.ssh/id_rsa': remote: Enumerating objects: 7, done. remote: Counting objects: 100% (7/7), done. remote: Compressing objects: 100% (3/3), done. Unpacking objects: 100% (5/5), done. remote: Total 5 (delta 1), reused 5 (delta 1), pack-reused 0 From github.com:taustation/example f515a8a..30dc643 main -> origin/main Updating f515a8a..30dc643 Fast-forward user2.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 user2.txt |
user2
のコミットも反映されている。
1 2 3 4 |
[vagrant@localhost example]$ ls README.md user1.txt user2.txt [vagrant@localhost example]$ cat user2.txt user2による新規追加 |
ログも最終状態になっている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
[vagrant@localhost example]$ git log commit 30dc6433f7e4519d8a4c4ff9288812aed1d9bba9 (HEAD -> main, origin/main, origin/HEAD) Merge: 8ead5ca f515a8a Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:48:22 2021 +0900 Merge branch 'main' of github.com:taustation/example into main merging user1's work by user2 commit 8ead5caf0200c88e2b6fa70ddc2ff9d97d535da8 Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:33:29 2021 +0900 created user2.txt commit f515a8ade4ea3d225cff1dd374895acf313ceca1 Author: taustation <taustation@gmail.com> Date: Fri Aug 13 09:31:33 2021 +0900 created user1.txt commit 2a3e7602dcfe8f83868eb3d85556786de571b043 Author: taustation <88479749+taustation@users.noreply.github.com> Date: Fri Aug 13 09:20:42 2021 +0900 Initial commit |