書きかけですし、未検証です。ご了承ください。
gitとは
プログラムソースのバージョン管理システムのこと。
gitの用語で大事なのは、
- 作業ディレクトリ
- ステージングエリア
- リポジトリ
の3つ。
リポジトリがGitのキモで、変更履歴を管理する登録簿みたいなものになる。
インストール方法
まずGitというソフトが必要なのでPCにインストールする(MacにはGitが最初からインストールされているので不要)
gitはhttps://git-scm.comからダウンロードする。ダウンロードしたらexeを実行する。
インストール先をきいてくるが、基本的にデフォルトのまま次へ次へでOK。
以下すべての操作はWindowsではコマンドプロンプト、Macではターミナルで行う。
インストールされているGitのバージョンを確認する
下記コマンドのどちらかで確認できる。Macの場合もちゃんと入っているか確認したい場合はバージョンを確認するといい。
git version git --version
初期設定
変更履歴をとるのに「誰が」という情報が必要なので、名前とEメールを記載することになっている。まずその設定をしておく。
git config --global user.name "hogehoge" git config --global user.email "hogehoge@gmail.com" git config --global init.defaultBranch main git config --global color.ui true git config --global core.autoCRLF false
上記を順に打っていけばいい。名前とEmailはそれぞれ自分のものを入力する。共同開発をすることもあるので、解りやすいものにした方がいいかも。
color.uiはメッセージの色分けをしてくれる設定。これをtrueでオンにする。
autoCRLFは自動でgit addかgit commitをしたときに、自動でCRLFに直してくれる機能。これをfalseでオフにする。
どっちみち本番サーバはLinuxなので、勝手にLFをCRLFに直されても困る。ちなみに、別件でこれをオフらずにやったことがあり、確かにWarningで「LFになってるので、CRLFに直しますよ」よというメッセージが出た。そのまま進んだら本当にCRLFに変更されていた。
設定確認
ちゃんと設定がされているか、もしくは現在の設定を見るコマンド
git config -l
Gitリポジトリを作成する
HTMLでもJavaScriptでもPHPでもいいのだが、実際に開発するときは何かフォルダに入れるはず。
そのフォルダが作業ディレクトリ。その中にリポジトリを設置する形で作成する。その作成コマンド。
作成手順は、コマンドからそのディレクトリに移動し、
git init
これを打つことで.gitというフォルダが作成される。このフォルダがリポジトリ。
このリポジトリの中が前述したコードの差分などを管理するための記録簿になっている。
このフォルダの隣にはもちろん開発中のコードがある。
ゆえに、
- 作業ディレクトリ = 開発コード群を入れているフォルダ
- リポジトリ = 開発コード群を入れているフォルダに設置された変更管理簿(.gitフォルダ)
- プログラム = 冒頭にインストールしたGitプログラム
が必要となる。ステージングエリアは後述。
ステージングする
作業ディレクトリからステージングエリアに上げるコマンド
作業ディレクトリにあるファイル名を指定してステージングする
git add index.html
作業ディレクトリにあり、変更があったものを全てaddする。カレント以下全て。
git add .
ステージングから戻す
ステージングに上げたファイルを戻す。
ステージングした全てのファイルを戻す
git reset
ステージングしたファイルをファイル名を指定して戻す
git reset ファイル名
コミットする
ステージングエリアからリポジトリに上げる操作。
基本コマンド
git commit
ステージングにある全てのファイルをコミットする。
コミットされる前に、エディタが立上がってメッセージを入れる画面になる。
操作はvimです。vimの説明は必要最低限だけ下記の別記事にまとめてあります。vimを知らないと出られなくなります。
git addとcommitをまとめて
慣れてくるとまとめて行いたいときがある。ただし、untracked filesには使えない。
git commit -a -m "addとcommit" もしくはまとめて git commit -am "addとcommit" でも可能
コミットメッセージのお作法
gitでは標準的に
1行目: コミットでの変更内容の要約 2行目: 空行 3行目: 変更した理由
となる。コメントメッセージは、他の人がコミットの変更内容を調べる場合や、自分で後から履歴を見直す際に大切な情報となるので、変更内容の解りやすいコメントを心がける。
ファイル名を指定
ファイル名を指定するとそのファイルだけコミット対象になる
git commit ファイル名
-mオプション
コメントも同時に入れてコミットするオプション。
git commit -m "ライン2を追加"
-vオプション
変更箇所を確認しながらcommitするオプション
git -v
現在の作業ディレクトリの状態を確認する
基本コマンド
git status
gitは3つの状態で管理をしていくので、長く作業をしているとどのファイルをどの場所に置いたかわからなくなるので、そういう時に使う。
用語
On branch main
今いるブランチがマスターだよ
Your branch is ahead of ‘origin/main’ by 4 commits(use “git push” to publish your local comits)
リモートのorigin/mainより先に4つ進んでいるよ。あなたのローカルのコミットを発行するためにgit pushを使ってね。
nothing to commit, working tree clean
コミットするものは何も無いよ、ワーキングツリー(作業ディレクトリ)はキレイだよ
initial commit
まだ何も登録されていない
untracked files
このファイルはステージングエリアに仮登録されいません
modified(changes to be comitted)
ファイルが変更されているよ。コミットすべき変更があるよ
modified: index.htmlとあれば、index.htmlが変更されたよという意味。
Changes not staged for commit とあれば、ステージにもコミットにも来ていないという意味。
(use “git add <file> … ” to update what will be commited)・・アドしてステージにあげるか、
(use “git checkout — <file> … ” to discard changes in working directory)・・戻しなさい。
という次にやることを丁寧に教えてくれる。
コミット履歴の確認
commitをするたびにリポジトリに登録されていくが、それを一覧で見ることができる。いつ、誰が、何のファイルを更新したのか、その履歴。
基本コマンド
git log
全てのコミット履歴を表示する。git log中の移動はVimと同じ。
内容は、commit時に自動で割り当てられたIDと、投稿者、メールアドレス、日時、コメント3行など。
ファイル名を指定する
ファイル名を指定すると、そのファイルだけの履歴を全件表示してくれる。
git log filename
–onelineオプション
commitの状態を1行で確認する
git log --oneline
1コミットを1行で表示してくれる。IDとファイル名とコメント1行だけ。投稿者やメールアドレスも表示されない。
–graphオプション
ブランチの状態がグラフィカルで見ることができ、わかりやすい。
git log --oneline --graph
–all オプション
全てのブランチのコミットの状態を確認できる。
–pretty=shortオプション
commitの状態を1行コメント+αで表示する。
git log --pretty=short
git logのコメント1行版のようなもの。メールや投稿者は表示される。
-nオプション
最新のコミットn件見たい場合に使う。単にgit logとすると大量のログが表示されてしまうので、通常は-nか–onelineで絞る。
git log -n 3
-pオプション
commitの状態を変更された場所も見たいときに使う。
git log -p
git logのコミット情報に加えて、ファイルの差分も表示する。緑色で示された箇所が変更された箇所。
–statオプション
commitの状態をどこが変更されたではなく、どのファイルが何カ所変わったかを見る。沢山のファイルを扱っている場合に効果的。
git log --stat
-p と -n 1の組みあわせ
dotinstallでやってた。最新のコミット1件をnで、-pは変更の状態を確認する。
git log -p -n 1
削除する方法
gitで管理しているディレクトリからファイルやディレクトリを消す場合は、gitで管理をしている以上、勝手に消したら、管理しているgitからすると一体全体どこにいっちゃったんだ?となってしまう。消す場合は、下記コマンドを実行すること。
リポジトリ上のファイル(作業ディレクトリ含む)を消したい
git rm index.html git commit filename -m "index.html deleted"
git rmだけでは、作業ディレクトリのファイルが消えて、ステージングエリアに上がるだけなので、さらにcommitしてあげないといけない。
.gitignoreを忘れてGit管理の対象に入って間違ってコミットしてしまったファイルを、git rmコマンドで、コミットしたファイルをGitの管理から削除できる。
先走ってコマンドを使用せずに、deleteキー等で消しちゃった。
git add index.html git commit index.html -m "index.html deleted"
その場合は、git statusでdeleted: index.htmlと赤字で表示される。なので、これをgit add / commitすればよい。削除という変更をリポジトリに上げればよい。
リポジトリ上のファイルだけを消したい
ローカルにファイルは残してGitの管理だけを外したい。
git rm --cache filename
リポジトリ上のディレクトリを消したい
ファイルごとGit管理から削除、ディレクトリも一緒に削除
git rm -r dirname
戻すときは、git checkout
git checkout -- index.html
とする。
checkout で過去に戻る
任意のコミットに戻る。
コミットハッシュを確認 git log --oneline git checkout コミットハッシュ
checkoutで戻った後に、元に戻す
git switch -
変更されたファイルの差分表示
作業ディレクトリとステージングエリアとの差分
git diff
diffとはdifferenceの略。git addやgit commitする前に、本当に変更に間違えがないかを念のために確認するときに使う。
作業ディレクトリがクリーンな状態では何も表示されない。
ファイルに修正を加えた状態でgit diffをすると変更を示してくれる。差分は緑で表示。
さらにgit add .をして、git diffをしても何も表示されない。これはステージングに上げているから。
ステージングと最新コミットとの差分は下のgit diff HEADを使う。
ステージングとコミットとの差分
HEADをつけるとステージングとコミットとの差分になる。
git diff HEAD
ステージした後の差分
git diff --staged
ステージングエリアとローカルリポジトリとの差分
git diff --cached
ステージングにあるファイルの変更箇所を見たい場合は、とする。作業フォルダ・ステージングどちらにあるかでコマンドが違う。
ブランチについて
ブランチとは別々のバージョンを並行して開発したい場合に使用する。ちょっとした機能を試したいときに、さっとブランチを作って、そこで作業してうまくいったらmainにどんどん取り込んでいくように開発を進めればよい。
ブランチの一覧を見る
何もない状態なら、*mainと表示される。これは最初に作られるブランチで、米印 * が今自分がそこにいるということを示す。
ブランチの一覧を見る
git branch
リモート追跡ブランチも見る場合は-aオプションをつける
git branch -a
リモート追跡ブランチを指定して見る
git branch origin/main
ブランチを作る
git branch hoge
このコマンドはブランチを作るだけで移動はしない。この状態でgit branch(一覧を見る)をすると、hoge *mainの両方が表示され、変わらず*がmainについていることがわかる。
ブランチを移動する
最近はcheckout ではなく switchでやるらしい。
git switch hoge
これでhogeに移動でき、git branchで見ると、hogeに * がついていることがわかる。ここでファイルを作成してcommitしてもmainには影響を及ぼさない。ためしにmyscript.jsをhogeで作成して、git add . とgit commit – m “myscript added”を行いコミットして、git checkout mainに戻ったら、作業ディレクトリにはmyscriptは存在しなかった。そして、git checkout hogeに戻ると、myscriptがあった。完全に別になる。
ブランチを作成しつつ、そのブランチに移動する
git switch -c hoge
ブランチをマージする。
git merge hoge
今回はhogeで作ったものをmainに組み入れるマージ。その場合は、上記コマンドをmainに移動してから入力する。するとmainにも同じファイルができる。
マージコミットを作るマージ
git merge hoge --no-ff コミットメッセージを書く git merge hoge --no-ff -m "hogeをマージしました" 自動でメッセージを書いてくれる (merge branch 'hoge') git merge hoge --no-ff --no-edit
ブランチを削除する
git branch -d hoge
これでhogeブランチを削除できる。その後git branchで確認しても、残っていない。
ブランチを作ってそのブランチにチェックアウトする。
git checkout -b hogehoge
ブランチの名前を変更する
ブランチを作ってswitchする(ブランチ名を間違えた) git switch -c add-0333 -mはmoveの意味。これで変更できる。 git branch -m add-0333 add-03 masterをmainにするのも同様 git branch -m master main
ブランチでコミットした後に削除する
add-03ブランチを作ってコミットした後、この変更がいまいちだったとき、このブランチごと変更を消したい場合、とりあえずadd-03ブランチにいたら削除できなさそうなので、一旦mainブランチに移動してからadd-03をgit branch -dで消すのが普通のように見えるが、それでは消せない。
エラーメッセージはadd-03はマージしていないので削除できませんよ。
大文字のDで実行すれば消せる。 git branch -D add-03
マージで衝突(コンフリクト)が起きた場合
hogehogeでindex.htmlを替えて、git add . git commit -m “comment” をして、mainでindex.htmlを替えて、git add . / git commit -m “comment”をした。そして、main側にhogehogeの内容をmergeしようとした場合、Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result.と表示される。そして、git statusで見ると、both modified: index.html(両方で変更されてるよ)と表示される。
index.htmlを開くと、下記のようになっている。HEADだと1stなのに、hogehogeだとfirstだよ。
<<<<<<<< HEAD line 1st ======== line first >>>>>>>> hogehoge
line 1st
これは上記のように変更して。git add . / git commit -m “conflict fixed”などとすればよい。その後、git logで見てみると、Mergeをしたとログに残っている。
マージを中断する
コンフリクトが発生したとき、一旦マージ前に戻す。コンフリクトが起きたときビックリするので一旦戻すこともよし。戻すことで落ち着いて考えることもできる。
git merge --abort
ブランチの分岐元を変える rebase
中上級者向け。例えばmain担当とadd-03担当がいて、add-03を進めている間にも当然main側も進んでいるとして、コンフリクトが起きたとき、mergeするmain担当が直さないといけないことになる。add-03担当側でコンフリクトを直した状態にしておく配慮のため、最新mainに付け替える方法がrebaseとなる。
まずブランチ側に移動 git switch add-03 add-03の分岐元をmainの最新にもっていく git rebase main コンフリクト発生 ステージング&コミット git commit -a --no-edit 指定されたコマンドを実行し付け替え完了 git rebase --continue main側からmerge git switch main git merge add-03 --no-ff --no-edit 以上、あとはブランチの削除をお忘れなく
タグをつける
主なコミットに別名をつけること。よくある使い方は、「バージョン1はこのコミットだよ」という具合です。git showやgit resetでもこのタグ名を指定することができる。
直前のコミットにタグをつける
git tag v1.0
これでgit logで見ても、commit 02c4d0651442**** (HEAD -> main , tag: v1.0)となっている。
コミットを指定してタグをつける
git tag v0.9 05c769a73459
のように、ID名十分な桁数を後ろにつけること。
タグの一覧を見る
git tag
これでv1.0表示される。
タグの削除方法
git tag -d v0.9
-dオプションを使うこと。
エイリアスをつける
エイリアスとは、gitの色々な命令に短縮名をつけるもの。タグはcommitIDにつける別名。たとえば、git checkout とか結構打つの面倒だけど、それを短く登録する。
checkoutをcoで登録する
git config --global alias.co checkout
これでcoでcheckoutが使える。
エイリアス使用例
git config --global alias.co checkout git config --global alias.st status git config --global alias.br branch git config --global alias.ci commit
エイリアスなどの設定を一覧表示する。
git config -l
注意事項
gitで管理している場合は、rmやmvで削除や移動をしてはいけない。一体全体どこにいっちゃったんだ?ということになる。削除や移動をする場合は、下記のようにする。
git rm index.html git rm index.html index2.html
管理対象外とする
error.logのようにサイズが大きくなったり、そもそもバージョン管理する必要がないファイルはgitの管理下から外す方法がある。同じフォルダ内に、.gitignoreというファイルを作り、その中にログ系のファイルなら、*.logと入力する。logというフォルダなら、/log/とする。windowsでドットから始まるファイルを作るには、.gitignore.のように前後にドットをつけるとうまくいく。この設定を行えば、git statusで見ても、バージョン管理にはerror.logは反映されない。まt.gitignoreファイルの適用範囲は、置いたディレクトリ下位のファイルに反映される。
macで自動生成されるファイルや、パスワードが記載されているファイルは対象外にする。
#と書くと#から始まる行はコメント
指定したファイルを書くとそのファイルが除外 index.html
ルートディレクトリを指定 /root.html
ディレクトリ以下を全て除外 dir/
Q&A
直前のcommitを変更する(に含める)
コミットをした後に、これもコミットに含めたかったということがよくある。そのとき、直前にコミットに追加する方法が–amendでできる。コミットメッセージを変更しない場合は–no-edit
ファイルを追加で変更して・・ git add . git commit --amend コミットメッセージを変更しない場合は git commti --amend --no-edit とする
つまり、直前のcommitに含めてしまおうというときに使う。
直前のコミットのコメントを変更する
さっきのコミットメッセージを変えたいということはよくある。
git add . git commit -m "0444を追加" git commit --amend -m "04を追加"
直前よりもっと前を変更したいこともあるが、それは複数人でGitをやっていると混乱するので、やらないほうがいい。変更したいのなら、変更して新たにコミットすべき。
戻すとき
git reset [option] [hash]
harf コミットは失われて、ワーキングやステージングから変更履歴は失われる
soft コミットは失われるが、ワーキングやステージングに変更履歴はキープされる
mixed コミットは失われて、ワーキングディレクトリのみ変更履歴がキープされる
何も指定しなければmixedになる。
直前のcommitまで戻したい。
git reset HEAD
この場合は、commitが戻るだけ。作業ディレクトリまでは戻らない。つまり元ファイルは戻らない。
直前のcommitまで作業ディレクトリ(元ファイル)ごと戻りたい。
git reset --hard HEAD
直前より前のcommitまで戻りたい。
git reset --hard HEAD^
More?と聞かれるので、^で答えること。これで直前の1つ前まで戻れる。–hardは必要に応じて。
comitIDを指定して戻りたい
git reset --hard 05c769a
05c769aは実際は戻りたい箇所のcommitID。最低7ケタ。–hardは作業ディレクトリごと戻す。
前回取り消されたところに戻りたい
git reset --hard ORIG_HEAD
今回例ではgit reset –hard 05c769aで一番最初のcommitに戻ったが、やっぱりその上のcommitだった。と言う場合、最初のcommitに戻ってしまうのは、初期に戻ってしまうということだから、後の祭りになる。しかし、ORIG_HEADには前回取り消されたHEADの情報が1個だけ入っている。ここに戻れる。
特定のファイルだけ前の状態に戻したい
git checkout ad9772b1b readme.txt
id aaa readme.txt line1 added
id bbb index.html line1 added
id ccc readme.txt line2 added
id ddd index.html line2 added
git reset –hard bbb
これをすると、bbbのindex.htmlがline1の状態に戻るだけでなく、readme.txtもline1の状態に戻ってしまう。これではcommitを分けるメリットが無い。何でもかんでも変更を一切合切今日一日ご苦労さんで、1commitにしてしまうと、ある特定のファイルだけ戻すことができない。なので、普通commitはコメントで判断できるくらいに細分化して分けることが推奨される。しかし、resetで戻ると時系列で戻ってしまうので、あれ?と思って調べたらcheckoutを使うようだった。
共有リポジトリ
フォルダを共有リポジトリとして登録する
git init --bare
共有リポジトリにしたいフォルダまでcdして、上記コマンドを使う。共有リポジトリのディレクトリ名は、ourweb.gitなどと、.gitにするのがお作法。
リモートリポジトリに登録する
git remote add origin https://github.com/koujiha0365/intro_git
git pushでリモートリポジトリにあげる場合、リモートリポジトリに登録する必要がある。git remote addでローカルリポジトリをリモートリポジトリに登録できる。名前はよく使われるのがoriginなので、originで登録する。
リモートのoriginがどこにあるのか確認する
git config -l git remote -v
のどちらかで確認できる。
共有リポジトリを削除する
git remote rm origin
これで削除できる。
mainの内容をoriginに突っ込む
git push origin main
これでourweb.gitの中に意味不明なファイルが出来ている。
同じ内容をcloneする。
git clone ../ourweb.git myweb2
userbをデスクトップに作ったので、そこから../でourweb.gitディレクトリを指定。myweb2という中身で保存する。(userbを作る作業は実際は不要。デスクトップからgit clone ourweb.git myweb2でOK。
USERBから共有リポジトリourweb.gitにプッシュする
myweb2にあるindex.htmlを編集し、git add . / git commit -m “line 3 added”とし、
git push origin main
とする。ここで重要なのは、リモートの情報も引き継がれるので、git push origin mainが使える。
またhtdocs7側でmyweb2で行って変更をpullで引く
git pull origin main
共有時のトラブルについて
今回、htdocs7を作って作業していた。そして共有リポジトリをデスクトップにourweb.gitで作成した。そしてhtdocs7からgit push origin mainでプッシュした。さらにデスクトップからgit clone ourweb.git myweb2で、myweb2を複製する。次にhtdocs7で内容を変更し、git commit -amを行い、git push origin mainで共有リポジトリに突っ込んだ。そして、デスクトップのmyweb2で内容を変更し、git commit -amを行い、git push origin mainでこちらも共有リポジトリに突っ込もうとすると、エラーになる。まずアナタは、pullしなさいと。なので、git pull origin mainを行い、いったん引っ張ることにする。そしたら、編集したindex.htmlがマージの衝突(コンフリクト)と同じ状態になるので、同様にファイルを修正して、またgit commit -amを行い、git push origin mainで共有リポジトリに突っ込んで解決する。
要するに、同時にローカルを修正し合ってリポジトリに放り込もうとすると、後で突っ込む方が先にpullして下さいよとなる。
リモート
フェッチする
リモートの変更履歴をローカルのリモート追跡ブランチに取り込む
git fetch
リモート追跡ブランチの変更をmainにマージする
git merge origin/main
git log --oneline
プルリクエスト
GitHub のサイト上で、マージする前にコンフリクトがあるかどうか確認できたり、コードの差分を確認できたり、必要だったらコードにコメントをつけて修正をうながしたり、修正がすべて終わったらボタン一発でマージすることができる。
ブランチを作って移動する
git switch -c add-04
コードを修正してコミットする(ローカルのadd-04ブランチで)
git commit -am "04を追加"
*mainにmergeする前にプルリクエストする
一旦リモートリポジトリにadd-04ブランチをpush、初めての場合は-uオプション
git push -u origin add-04
compare & pull requestボタンをクリック
add descriptionに「04を追加したので後でチェック」と入力
create pull requestボタンをクリック
merge pull requestをクリック、confirm mergeをクリック
delete branchをクリックして終了
vscodeに切り替え
git branch -a
remotes/origin/add-04はgithub上で削除したので無い。
–pruneでフェッチする
リモートリポジトリに存在するブランチの内容は取り込みつつ、リモートリポジトリに存在しないブランチの追跡ブランチは削除してくれる。
git fetch --prune
mainにmergeする
mainブランチに切り替える
git switch main
リモート追跡ブランチ、origin/mainをマージする
git merge origin/main
ブランチを削除する
git branch -d add-04
クローン
クローンする場合はgithubのアドレスをコピーする。githubのアドレスは
https://github.com/{ユーザ名}/{リポジトリ名}.git
ディレクトリを作成しつつクローンする
コマンドを実行したディレクトリの場所に、新たにディレクトリを作成しつつクローンする
カレントディレクトリに、リポジトリ名のディレクトリができ、その中にコードが展開される
git clone [クローンしたいURL]
カレントディレクトリに、指定した名前のディレクトリができ、その中にコードが展開される
git clone [クローンしたいURL] [ディレクトリ名]
既存のディレクトリにクローンする
あらかじめローカル側で作ったディレクトリの中にソースを展開する場合
git initをしてローカルリポジトリを作らないとgit remoteなどのコマンドは使えません。
cd [既存のディレクトリ]
git init
git remote add origin [コピーしたURL]
git pull origin main
色んな場所から
githubにある変更を取り込む(fetch/merge)
githubにあるmainブランチの変更が先に進んでいる
変更をローカルのリモート追跡ブランチに取り込む
git fetch
一応ブランチを確認する(-aで全てのブランチ)
git branch -a
変更を確認する
git log origin/main --oneline
マージする
git merge origin/main
githubにある変更を取り込む(pull)
同じくgithubにあるmainブランチの変更が先に進んでいる状態。pullはorigin/mainからリモート追跡ブランチに取り込むfetchと、リモート追跡ブランチからローカルのmainに取り込むmergeの両方を行うコマンドということ。
git pull origin main
ローカルからブランチを作ってpush
add-08ブランチを作成しつつ、add-08ブランチに移動
git switch -c add-8
コミット
git commit -am "08を追加"
ちなみにこのままリモートブランチのmainにpushしようとしたらエラーになる。
git push origin main
なぜなら開発はadd-08ブランチで行っており、mainは何も変えていないので差分が無いから。
正しくは
git push origin add-08
コメント