LoginSignup
1
0

More than 3 years have passed since last update.

GitとGit Hub 入門(3/3)

Last updated at Posted at 2019-10-13

前の記事はこちら

GitとGit Hub 入門(1/3)
GitとGit Hub 入門(2/3)

こんな時どうする?

仕事中によくあるシーンをまとめたので、一緒に練習してみましょう。

ステージングへの追加を取り消す

勢い余ってステージングにファイルを追加してしまったけど、次のコミットにはやっぱり含めたくない!という場合です。

試しに、ファイル「test2」をステージングに追加します。

$ git add test2
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   test2

答えが表示されていますね。
(use "git reset HEAD <file>..." to unstage)

案内の通りに、ステージングからtest2を元に戻します。

$ git reset HEAD test2
$ git status
On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)

    test2

nothing added to commit but untracked files present (use "git add" to track)

ステージングに追加する前に元に戻りましたね。
ここで、新しい言葉が出てきました。HEADって何でしょう。

HEADとは

HEADは、今作業しているブランチの最新のコミットのことです。
git logでコミットログを確認してみましょう。

$ git log
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master, origin/master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date:   Sat Oct 12 22:15:23 2019 +0900

    Create README.md

commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date:   Sat Oct 12 19:13:31 2019 +0900

    first commit

今、HEADは一番上のREADMEを追加した時のコミットになっています。
git show HEADで最新のコミットの内容を見ることができます。

$ git show HEAD
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master, origin/master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date:   Sat Oct 12 22:15:23 2019 +0900

    Create README.md

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bab6eaf
--- /dev/null
+++ b/README.md
@@ -0,0 +1,2 @@
+# sample
+sample for remote repository

ついでに、最新のコミットの1つ前のコミットはHEAD^になります。
前のコミットになるほど、^が増えていきます。

最新のコミットの1つ前のコミットは一番最初のコミットになりますね。

$ git show HEAD^
commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date:   Sat Oct 12 19:13:31 2019 +0900

    first commit

diff --git a/test1 b/test1
new file mode 100644
index 0000000..e69de29

つまり、git reset HEAD test2HEADの状態まで元に戻す、ということになります。
commit の後にある f733bfe11003832f28f4803481cbe086e1903e4aはコミットIDで、HEADの代わりにこれを入力しても同じになります。

コミットした時のコメントを修正する

直前のコミット
のコメントを修正したい場合です。

まず、ファイル「test2」をステージングに追加し、コミットまで行いましょう。
コメントは"add hoge"にします。

$ git add test2
$ git commit -m "add hoge"
[master c26d97e] add hoge
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test2

git logでコミットされたことを確認します。

$ git log
commit c26d97e9a6c9460a0b9790f3040b12beca1750f0 (HEAD -> master)
Author: hoge <hoge@gmail.com>
Date:   Sun Oct 13 15:11:59 2019 +0900

    add hoge

コメントを"add test2"に修正します。

$ git commit --amend -m "add test2"

コミットログのコメントが修正されていることを確認しましょう。

$ git log
commit 255795fc007dc6c5e64cc4acd2a54ca1e62f64c4 (HEAD -> master)
Author: hoge <hoge@gmail.com>
Date:   Sun Oct 13 15:11:59 2019 +0900

    add test2

コメントが修正できましたね。

コミットを取り消す

間違えてコミットしてしまったけど、変更箇所が漏れてた時など、コミットを無かったことにしたい場合です。

これも、git resetを使います。

$ git reset --soft HEAD^

HEAD^は、最新のコミットの1つ前を指しますから、最新のコミットの1つ前まで戻す、という意味です。
--softをつけると、コミットの操作のみが取り消されて、ステージングに追加された状態まで戻ります。

コミットログを見てみましょう。
先ほどの、add test2のコミットがなくなりましたね。

$ git log
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master, origin/master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date:   Sat Oct 12 22:15:23 2019 +0900

    Create README.md

commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date:   Sat Oct 12 19:13:31 2019 +0900

    first commit

git statusでステージングの状態を見てみましょう。
test2のファイルが追加されていますね。

$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    new file:   test2

ちなみに、--softを付けないと、ステージングに追加した操作も一緒に取り消されます。
また、--hardとすると、作業中のファイルの状態もHEAD^の状態(最新のコミットの1つ前の状態)になります。つまり、test2のファイルが削除されます。(気をつけて。。)

プッシュしたファイルを元に戻す

間違えてプッシュしちゃった・・・という時プッシュを取り消すことができます。
この作業は複数人で同じリモートリポジトリを見ながら作業している場合、少し危険です。ちゃんとプッシュを取り消すことを周知しておきましょう。

無かったことにする

まず、ファイル「test2」をコミットし、リモートリポジトリにプッシュします。

$ git commit -m "add test2"
[master 72225df] add test2
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 test2

$ git push origin master
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 4 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 264 bytes | 264.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0)
To https://github.com/hoge/sample.git
   7022b44..72225df  master -> master

リモートリポジトリにtest2が追加されました。
sample_for_remote_repository.png

コミットログも追加されていますね。

$ git log
commit 72225dfff26c3e09114614739f584b5b6c9701af (HEAD -> master, origin/master)
Author: hoge <hoge@gmail.com>
Date:   Sun Oct 13 16:54:55 2019 +0900

    add test2

commit 7022b44cb174e7d1d932a950d052fcdec9b36408
Author: hoge <53826023+hoge@users.noreply.github.com>
Date:   Sat Oct 12 22:15:23 2019 +0900

    Create README.md

commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date:   Sat Oct 12 19:13:31 2019 +0900

    first commit

まず、先ほど説明した方法でコミットを取り消します。

$ git reset --soft HEAD^
$ git log
commit 7022b44cb174e7d1d932a950d052fcdec9b36408 (HEAD -> master)
Author: hoge <53826023+hoge@users.noreply.github.com>
Date:   Sat Oct 12 22:15:23 2019 +0900

    Create README.md

commit f733bfe11003832f28f4803481cbe086e1903e4a
Author: hoge <hoge@gmail.com>
Date:   Sat Oct 12 19:13:31 2019 +0900

    first commit

add test2のコミットが消えましたね。

この状態で、プッシュし直します。

$ git push origin mastser
error: src refspec mastser does not match any.
error: failed to push some refs to 'https://github.com/hoge/sample.git'

おっと、エラーになりましたね。
リモートリポジトリで記録されたコミットログと、プッシュされたコミットログに乖離があったからです。
具体的には、リモートリポジトリにはadd test2というログがまだ残っているのに、新たにプッシュされたコミットログにはadd test2が無くなっているからです。

あまりお行儀はよくありませんが、-fを付けて強制的にプッシュします。

$ git push -f origin master
Total 0 (delta 0), reused 0 (delta 0)
To https://github.com/hoge/sample.git
 + 72225df...7022b44 master -> master (forced update)

エラーが出ず、プッシュできましたね。

リモートリポジトリからもtest2が削除されています。
sample_for_remote_repository2.png

コンフリクトを修正する

リモートリポジトリとローカルリポジトリで同じところに更新が入った場合、ローカルリポジトリからリモートリポジトリにプッシュするとエラーが出てプッシュできません。この状態をコンフリクトしていると言います。
複数人で同じリモートリポジトリを更新していたら、こんなことも起こる可能性があります。

簡単に試してみましょう。まず、リモートリポジトリ側でREADMEの内容を全て削除して、「modify comment」と入力します。
sample_for_remote_repository3.png

次に、ローカルリポジトリでもREADMEの内容を修正します。
viコマンドで、READMEの内容を全て削除して、「test」と入力しましょう。

そして、ステージングに追加し、コミット・プッシュまで一気にやってみましょう。

$ vi README.md
$ git add README.md
$ git commit -m "mod README"
$ git push origin master
To https://github.com/maru-e/sample.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://github.com/hoge/sample.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 fetchでリモートリポジトリの変更内容をローカルリポジトリに取得することができます。

$ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From https://github.com/hoge/sample
   7022b44..7beb0cd  master     -> origin/master

そして、ローカルリポジトリmasterブランチの最新のコミットHEADとリモートリポジトリ(origin)のmasterブランチとの差分を次のコマンドで確認できます。

$ git diff HEAD origin/master
diff --git a/README.md b/README.md
index 9daeafb..a099415 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-test
+modify comment

README.mdファイルが修正されていて、ファイルの中身がローカルリポジトリでは「test」、リモートリポジトリでは「modify comment」となっているのがわかります。

もしローカルリポジトリの内容をリモートリポジトリに上書きして良いのであれば、git push -f origin masterで強制的にプッシュします。

リモートリポジトリの内容をローカルリポジトリに上書きしたい場合は、git pull origin masterで上書きされます。

差分を見て、どちらかの方法で内容を修正しましょう。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0