Edit

なぜこれを書いているか

僕はGitあまり深くやっていないので、勉強用にこの記事を書いてます

この記事の対象者

  • git add, git commit, git pushくらいしかやったことない人
  • ただぼんやりとしかGitしたことない人
  • mergeってなんぞや…って人

注意

この記事の内容は「Githubありき」という感じです

Linus Torvaldsさんごめんなさい

登場するgitコマンド

コマンド 操作
git init ディレクトリをGitで使う宣言
git add <file or folder> ファイル、フォルダをステージングエリアに置く
git status ステージングエリアにあるファイル、フォルダの確認
git diff --cached ステージングエリアにあるファイルの前のバージョンとの変更点を表示
git commit ステージングエリアにあるファイル、フォルダをリポジトリに移動させてバージョンを確定する
git commit -m <message> エディタを開かずにコミットメッセージを引数として書き、git commitを実行
git commit --amend 直前のコミットを修正する
git log コミットの履歴を表示
git log --oneline コミットのログを1行だけのコンパクトな形で表示する
git log -p commitしたときの前のバージョンとの差分(変更点)を表示する
git log --stat コミットごとに変更されたファイル名を列挙して表示する
git remote add <name> <url> ローカルのリポジトリをリモートリポジトリに登録する
git config -l リモートリポジトリの場所を確認する
git push ローカルリポジトリのコミットをリモートリポジトリに反映させる
git reset HEAD <file or directory> git add したファイルを取り消す
git reset --hard <commit id> 指定されたコミットのバージョンへ戻す
git reset --hard HEAD 直前のコミットへ戻る
git reset --hard HEAD^ 前々回のコミットへ戻る
git reset --hard ORIG_HEAD git resetによってキャンセルされたコミットへ戻る
git branch ブランチの一覧の表示
git branch <branch name> <branch name>という名前のbranchを作る
git branch -d <branch name> 指定されたブランチを消す
git checkout <branch name> 指定されたのブランチへ移動
git checkout -b <branch name> 新しいブランチを作って移動する
git merge <branch name> 現在のブランチへ指定されたブランチにあるファイル、フォルダを反映する

まずはGitで登場する領域から

ここでステージングエリアを含む、4つの重要な領域について勉強しましょう

領域 概念
作業ディレクトリ ファイルの作成、修正を行う場所
ステージングエリア リポジトリに確定する予定のファイルの置き場所
リポジトリ(ローカル) バージョンが確定したファイルの置き場
リモートリポジトリ ネットワーク上にあるリポジトリ

図にするとこんな感じ

1.png

Gitで扱う領域について視覚的に理解できたら実際に手を動かしてみましょう

git init

ディレクトリを作って、移動

$ mkdir test
$ cd test 

そしたら、ここでgit init!!

$ git init

これは 「testっていうディレクトリをGitで使うよ」って宣言みたいな感じ

Initialized empty Git repository in /Users/foo/bar/test/.git/

みたいのが出ればオッケー

git add

$ echo "hoge 1" > hoge.txt

で文字列hoge 1を一行目に含むhoge.txtを作成

そして、このファイルを作業ディレクトリからステージングエリアに置くためにgit addというコマンドを使います

$ git add hoge.txt

また、「このファイル、新しく生成したり、編集したりしたけど、ステージングエリアにgit addして置いたっけ…」ってなることがあると思いますが

$ git status

とすることで、addしたファイル、addがまだされてないファイルの一覧が出ます

作業ディレクトリのファイルを全部addしたいと思うことがあると思います、そんな時は

$ git add .

でファイル全部をaddすることができます

git add .したらgit statusで確認することも忘れずに!

そして、ファイルがステージングエリアにある状態でdiff --cachedコマンドを叩くと

$ git diff --cached

addしたファイルの前のバージョンとの変更点が出力されます

ここまでの作業で、下の図の様にhoge.txt作業ディレクトリからステージングエリアに置くことができました

2.png

git commit

では次は、ステージングエリアからローカルのリポジトリaddしたファイルをcommitしてみましょう

$ git commit

上記のコマンドを実行したら下のようにVimが立ち上がります

3.png

commitするたびに、作業の内容(追加/削除したファイル、編集したファイルの内容などの変更点)をそこに書きます

なので、立ち上がったVimでiinsert modeに入って1st commitと打ってください

4.png

そしたらescを押して:wqでVimから抜けてください

 1 file changed, 1 insertion(+)
 create mode 100644 hoge.txt

こんなログが残されていると思います

ちなみにVimでいちいちメッセージを書くのが面倒だったら

git commit -m "1st commit"

-mのオプションを付けてcommitしてもいいです

そしたらcommitした履歴をgit logコマンドで確認してみましょう

$ git log

このコマンドを打つと下のように出力されるはずです

commit c91ff94f6664388c5032a6466f64e00dac908c50 (HEAD -> master)
Author: hoge hoge <hoo@bar>
Date:   Fri May 14 22:27:40 2021 +0900

    1st commit

git logには色々なオプションがあるので、機能と一緒に羅列していきます

オプション 機能
git log --oneline コミットのログを1行だけのコンパクトな形で表示する
git log -p commitしたときの前のバージョンとの差分(変更点)を表示する
git log --stat コミットごとに変更されたファイル名を列挙して表示する

ここまでの作業で下の図まで進めることができました

5.png

git push

ローカルのリポジトリcommitしたら、リモートリポジトリpushする段階に入ります

ではまずは、リモートリポジトリを用意しましょう

6.png

上のスクリーンショットのように自分のGithubのリポジトリ閲覧ページへ行って、右上のNewボタンをクリック

7.png

リポジトリの名前を書く、書いたらスクロールダウン

8.png

Create repositoryボタンをクリック

9.png

リポジトリが作られたら、この画面に飛びます

ローカルのリポジトリを作られたリモートリポジトリに登録するには、git remoteコマンドを使います

下線部をコピペしてターミナルに貼って実行してください

$ git remote add origin git@github.com:<Githubのユーザネーム>/test.git

↑のoriginというところはどんな文字列でもいいです

リモートリポジトリの場所を確認したい場合はgit config -lと叩きましょう

$ git config -l

いろいろ表示されますが

remote.origin.url=git@github.com:e205723/test.git

↑こんな行があると思います、これでリモートリポジトリの場所を確認する感じです

そして念願のgit pushです

リモートリポジトリの登録をしてから、1回目のpush-u origin masterを添えて実行してください

$ git push -u origin master

実行に成功すると以下の様なログが出力されます

Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 224 bytes | 224.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
To github.com:e205723/test.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.

ここまでの作業で下の図まで進めることができました

10.png

.gitignore

git add .を乱用してgit statusを怠っているとaddしてはいけないファイルをaddしてしまうこともあります

こういうときに.gitignoreファイルを作成するとgit add .しても特定のファイルがaddされないようにすることができて便利です

実際に.gitignoreファイルを作ってみましょう

$ vim .gitignore

.DS_Storeファイル、log拡張子のファイルなどはpushしないほうがいいですので

.DS_Store

*.log

という風に書いて保存してみましょう

そうしたらgit add .してもaddされないようになります

git commit –amend

直前のコミットに間違いがあって、新たにcommitするほどでもない間違いのとき、commit --amendを使いましょう

hoge.txtの中身を

hoge 1
hoge 2

としましょう

そして、以下のコマンドを実行します

$ git add hoge.txt
$ git commit -m "add hoge2"

このとき、hoge.txtの中身を

hoge 1
hoge 3

にしてcommitしたかったことに気がついたとします

実際に、hoge.txtの中身を上記のように書き換えて、add hoge.txtとした後にcommit --amendを実行してみましょう

$ git add hoge.txt
$ git commit --amend

実行すると以下の様な画面になります

11.png

add hoge2add hoge3にしてから保存して抜けてください

ここで

$ git log

とすると

commit 7272df0450d989f5403cd234c191609bb50265b5 (HEAD -> master)
Author: hoge hoge <hoo@bar> 
Date:   Sat May 15 19:29:58 2021 +0900

    add hoge3

commit c91ff94f6664388c5032a6466f64e00dac908c50 (origin/master, origin/HEAD)
Author: hoge hoge <hoo@bar>
Date:   Fri May 14 22:27:40 2021 +0900

    1st commit

上のようにコミットのログが出力されます

これで無駄にコミットの履歴を増やすことなく、編集したファイルをローカルのリポジトリに置くことができました

git reset

コミットのログから、任意のバージョンへ戻す方法を紹介します

まず、hoge.txtの中身を

hoge 1
hoge 2
hoge 3

にします、ここで

$ git add hoge.txt

とします、ここで「あー、hoge.txtの中身は前のままでよかったな…」ってなったら

$ git reset --hard HEAD

とすることで、作業ディレクトリが前回のコミットの状態に戻ってステージングエリアも綺麗になります

ここで、hoge.txtの中身を確認してみると

hoge 1
hoge 3

となって前回のコミットの状態に戻っていることが確認できます

前々回のコミットに戻すときは

$ git reset --hard HEAD^

と打ちます、代わりにgit logから取得したidをコピペしていくのでもありです

git logを実行した結果

commit 7272df0450d989f5403cd234c191609bb50265b5 (HEAD -> master)
Author: hoge hoge <hoo@bar>
Date:   Sat May 15 19:29:58 2021 +0900

    add hoge3

commit c91ff94f6664388c5032a6466f64e00dac908c50 (origin/master, origin/HEAD)
Author: hoge hoge <hoo@bar>
Date:   Fri May 14 22:27:40 2021 +0900

    1st commit

前々回のコミットはメッセージが「1st commit」です

そのコミットのidは例では

c91ff94f6664388c5032a6466f64e00dac908c50

となっていますが先頭の数桁(最低7桁以上)から一意に定まればいいでの先頭7桁だけ取ってgit reset --hardに添えて実行します

$ git reset --hard c91ff94

と実行してください

ここで、hoge.txtを実行すると

hoge 1

となり、最初のコミットのバージョンに戻ります

また、「git resetコマンドでバージョン戻したけど、もともとのバージョンが実は良かった」なんてときは、git resetによってキャンセルされたコミットがORIG_HEADに1つだけ入っているので

$ git reset --hard ORIG_HEAD

と実行すると、バージョンが戻ります

git branch

branchの概念を勉強します

ブランチというのは「分岐」や「枝分かれ」などの意味を持ち、別々のバージョンを並行して開発するときに使います

12.png

さっそくgit branchコマンドを実行してみましょう

$ git branch

実行すると、現在あるブランチの一覧がでます

* master

*がついているブランチは現在のブランチです

ブランチがmasterしかないので、hogeという名前の新しいブランチを作成します

$ git branch hoge

git branchを実行してブランチ確認した結果が↓

  hoge
* master

*がついているmasterが現在のブランチです

git checkoutコマンドでブランチhogeに移動してみましょう

$ git checkout hoge

git branchでブランチ確認した結果が↓

* hoge
  master

ここで、touch hoge2.txtとしてls

hoge.txt   hoge2.txt

ここでgit addgit commitを実行

$ git add hoge2.txt
$ git commit -m "add hoge2.txt"

ここでgit logを実行します

commit f960b5a75e603759a2dbd9931288d778a509cea9 (HEAD -> hoge)
Author: Yoshiaki Sano <hoo@bar>
Date:   Fri May 21 01:02:41 2021 +0900

    add hoge2.txt

commit 7272df0450d989f5403cd234c191609bb50265b5 (master)
Author: Yoshiaki Sano <hoo@bar>
Date:   Sat May 15 19:29:58 2021 +0900

    add hoge3

commit c91ff94f6664388c5032a6466f64e00dac908c50 (origin/master, origin/HEAD)
Author: Yoshiaki Sano <hoo@bar>
Date:   Fri May 14 22:27:40 2021 +0900

    1st commit

というふうに表示されます

メッセージがadd hoge3であるコミット(masterブランチ)からhogeブランチへ分岐しているのでこのような結果になります

ここまでの作業で下の図まで進めることができました

13.png

masterブランチで作業したくなったら

$ git checkout master

上記のコマンドでブランチをmasterに変えてください

そうするとgit logの結果もlsの結果もhogeブランチに分岐する前のmasterブランチの状態に戻ります

git merge

あるブランチで作成/編集したファイルを別のブランチにも反映させたいときにgit mergeコマンドを使います

git checkoutコマンドで、反映対象のブランチに移動します

hogeにあるファイルをmasterブランチにも存在するようにしたいので

現在のブランチがmasterでなかったらgit checkout masterを実行します

$ git checkout master

そしたらhogeブランチを対象にgit mergeコマンドを実行してみましょう

$ git merge hoge

実行すると、hogeにあるファイル、コミットがmasterに反映されます

lsを実行すると

hoge.txt   hoge2.txt

となります

git logでコミットログを確認してみると

commit f960b5a75e603759a2dbd9931288d778a509cea9 (HEAD -> master, hoge)
Author: Yoshiaki Sano <hoo@bar>
Date:   Fri May 21 01:02:41 2021 +0900

    add hoge2.txt

commit 7272df0450d989f5403cd234c191609bb50265b5
Author: Yoshiaki Sano <hoo@bar>
Date:   Sat May 15 19:29:58 2021 +0900

    add hoge3

commit c91ff94f6664388c5032a6466f64e00dac908c50 (origin/master, origin/HEAD)
Author: Yoshiaki Sano <hoo@bar>
Date:   Fri May 14 22:27:40 2021 +0900

    1st commit

という感じで、hoge2.txtが追加されたコミットがmasterにも反映されました

ここまでの作業で下の図まで進めることができました

14.png

また、hogeブランチを二度と使わないことになって消去したくなったらgit branch -dコマンドを使いましょう

$ git branch -d hoge

と実行するとhogeブランチが消えます、下は実行結果の出力です

Deleted branch hoge (was f960b5a).

今回のケースでは、この後にgit branchとしてもmasterブランチしか表示されなくなります

コンフリクトとその解消

hogehogeという名前のブランチを新しく作って、そのブランチに移動しましょう

$ git branch hogehoge
$ git checkout hogehoge

としても良いのですが

$ git checkout -b hogehoge

として一気にブランチの生成と移動を行うことができます

上のコマンドを実行したあとにgit branchを実行した結果が↓

* hogehoge
  master

hogehogeブランチでhoge.txtを編集しましょう

hoge 1
hoge 3

から

hoge 1
hoge 2
hoge 3

にして保存してください

そうしたら

$ git add hoge.txt
$ git commit -m "add hoge2"

として、hogehogeブランチでgit addgit commitしてください

ここで、一旦masterブランチへ移動しましょう

$ git checkout master

そしてmasterブランチのhoge.txtを編集しましょう

hoge 1
hoge 3

から

hoge one
hoge two
hoge three

にして保存してください

そしたら

$ git add hoge.txt
$ git commit -m "change the numerical notation"

として、hogehogeブランチでgit addgit commitしてください

ここまでの作業で下の図まで進めることができました

15.png

ここからmasterブランチにhogehogeブランチをmergeしてみましょう

masterブランチにて

$ git merge hogehoge

とすると

Auto-merging hoge.txt
CONFLICT (content): Merge conflict in hoge.txt
Automatic merge failed; fix conflicts and then commit the result.

このようにコンフリクトが起きたという旨のメッセージが出力されます

コンフリクトとは、mergeにより結合する際に、それぞれのブランチで同じファイルの重複する部分が変更されていると発生する衝突のことを意味します

ここからはコンフリクトの解消方法について勉強していきます

現在の状況でgit statusを実行したときの出力の中に

Unmerged paths:
  (use "git add <file>..." to mark resolution)
	both modified:   hoge.txt

というメッセージがあります

これは両方のブランチでhoge.txtが編集されているという意味です

コンフリクトはこのhoge.txtを編集することで解決することができます

$ vim hoge.txt

とすると

<<<<<<< HEAD
hoge one
hoge two
hoge three
=======
hoge 1
hoge 2
hoge 3
>>>>>>> hogehoge

hoge.txtの中身が↑のようになっていることが確認できます

<<<<<<< HEAD=======の間は、masterブランチのhoge.txtの内容です

=======>>>>>>> hogehogeの間は、hogehogeブランチのhoge.txtの内容です

コンフリクトは<<<<<<< HEAD=======>>>>>>> hogehogeを消して、masterブランチのhoge.txtの内容とhogehogeブランチのhoge.txtの内容を参考にして、hoge.txtの中身を修正することで解消されます

hoge.txtの中身をmasterブランチの1,3行目、hogehogeブランチの2行目を参考にして以下のように修正してください

hoge one
hoge 2
hoge three

修正したら保存して

$ git add hoge.txt
$ git commit -m "fix conflict"

としてコンフリクトを解消したhoge.txtgit addgit commitしてください

これでコンフリクトが解消されました

comments powered by Disqus