Gitと向き合うための、Gitでよく使うコマンドノート
Gitを使って開発、バージョン管理していますが、Sourcetreeだけでは解決できない場合があります。そんな時、実際にトラブルに合ったケースとともに解決方法を記録しておきました。また、よく使う、知っておくと便利なGitコマンドもご紹介いたします。
▼ この記事で書ききれなかった機能をこちらにまとめてます。あわせてご参考ください。
Githubでリポジトリ作ったらローカルリポジトリで最初にやる設定
Githubで空のリポジトリを作っておく。ただし、Github側ではREADMEも.gitignoreも作らないこと!
プロジェクト配下で以下実行。
git init
touch .gitignore # 内容は適宜編集しておく
git add .
git commit -m "first commit"
git remote add origin https://github.com/ユーザー名/リモートリポジトリ名.git
git push -u origin main
これでローカルリポジトリがリモートリポジトリへ反映されます。あとはゴリゴリ開発していきましょう!
git branchでブランチ操作
現在いるブランチを確認する
git branch
新しいブランチを作成する
git branch feature/⚪︎⚪︎機能の開発
ブランチを切り替える
git checkout feature/⚪︎⚪︎機能の開発
もしもブランチが切り替えられないケースに合ったら、とりあえずターミナルを再起動すればおkです。
ブランチを削除する
git branch -d feature/⚪︎⚪︎機能の開発
ただし、削除対象となるブランチ以外のブランチにチェックアウトする必要があります。
ブランチを強制削除する
たまに、上記コマンドでブランチの削除が行えないケースに合いました。そんな時は強制削除を試しましょう。強制削除はオプションの「D」を大文字にするだけです。
git branch -D feature/⚪︎⚪︎機能の開発
コンフリクトを解消する
コンフリクトが起きたら、とにかく慌てないことが大事です。慌ててあれこれコマンド実行してしまうと、さらに面倒なことになりかねません。まずはお茶でも飲みながら落ち着いてから問題に取り組みましょう。
コンフリクトが発生していることを確認する
git status
コンフリクトの発生を確認したら、対象となるファイルを開きます。とくにVS Codeを使って開くのが、わかりやすくておすすめです。
コンフリクト部分を探す
コンフリクト部分には、以下のようなマーカーが書かれているはずです。
<<<<<<< HEAD
(あなたの変更内容)
=======
(他のブランチやマージされた内容)
>>>>>>> branch-name
どちらを保持するか判断したら、手作で内容を修正します。この時 <<<<<<< HEAD や >>>>>>> のマークも削除してください。コンフリクトといっても、単にファイルにマーカーが記述されているだけなので、落ち着いて見れば大したことはありません。 VS Codeであれば、コンフリクト部分にボタンが表示されているはずなので、それを利用しましょう。
コンフリクトを修正したら、変更内容をステージングする
git add [修正したファイル名]
全てのコンフリクトを解決したら、新しいコミットを作成する
git commit
この時、エディタが開きます。マージメッセージを編集できるのですが、デフォルトのメッセージが提供されているので、そのままエディタを閉じてもらって大丈夫です。
リモートリポジトリの設定
設定されているリモートリポジトリを確認する
$ git remote -v
origin https://github.com/aragig/ChainableMark2Html.git (fetch)
origin https://github.com/aragig/ChainableMark2Html.git (push)
リモートリポジトリのURLを削除する
git remote remove origin
新しいリモートリポジトリのURLを登録する
git remote add origin リモートリポジトリのURL
gitignoreが反映されない
git add . でステージングしても .gitignore の設定が無視される場合があります。そんな時は、一度キャッシュを削除すると効果的です。git rm -r --cached .
ローカルでのみ追跡をさせないようにする
次の設定を行うことで、セキュリティ情報や個人的な設定などの変更を追跡せずにすみます。
追跡から除外する
git update-index --skip-worktree path/to/file
追跡除外対象から解除する
git update-index --no-skip-worktree path/to/file
追跡除外対象のファイルを確認する
git ls-files -v | grep ^S
または、
git ls-files --others --ignored --exclude-standard
過去のコミットに戻りたい(チェックアウト)
$ git logを実行して、日付やコミットメッセージの内容を手がかりに、戻りたい地点を探します。戻りたいコミットが見つかったら、commitのハッシュをコピーし、$ git checkout [ハッシュ]でチェックアウトします。
最後のコミットを取り消す
まだ、リモートリポジトリへプッシュしていない場合、比較的簡単に最後のコミットを取り消すことが可能です。
変更内容は保持して最後のコミットだけ取り消す
git reset --soft HEAD^
変更内容を破棄して最後のコミットだけ取り消す
git reset --hard HEAD^
誤ってプッシュしたコミットを取り消す
誤ったコミットをリモートリポジトリへプッシュしてしまった場合の取り消し方法です。共同開発の場合は、他の開発者へ影響が出ますので、事前確認の上、慎重に行なってください。
強制プッシュで取り消す(履歴なし)
共同作業でなければ以下の方法が有効です。履歴も残りません。
- git resetなどのコマンドを使って、ローカルリポジトリのコミットを取り消しておく
- git push origin <branch-name> --force で、ローカルリポジトリをリモートリポジトリへ強制的に反映さセル
リバートを使って取り消す(履歴あり)
リバートを使えば、共同作業の場合でも安全に取り消すことができます。ただし履歴は残ります。
- git log で取り消したいコミットのハッシュを特定する
- git revert <commit-hash> で取り消したいコミットをリバートする
- コミットメッセージを残して、リモートリポジトリにプッシュする
GitでHEADが"宙ぶらりん"になり、変更内容が見えなくなった
まずは落ち着いて、以下の手順を試してみてください。
1. 失われたコミットを見つける
失われたコミットを見つけるには、git reflogを使います。このコマンドは、ローカルリポジトリのHEADが過去に指していたコミットを表示します。コミットを行った後に何らかの理由でHEADが変更された場合でも、ここに記録が残ります。
git reflog
2. コミットの内容を確認する
git reflogで表示されたコミットの中から、失われたと思われるコミットを見つけ出し、そのコミットの内容を確認します。コミットID(例:a1b2c3d)を使用して、以下のコマンドを実行します。git show a1b2c3d
このコマンドにより、コミットに含まれる変更内容を確認できます。
3. 失われたコミットを復元する
失われたコミットを正しいブランチに復元するには、次のコマンドを使用します。ここで、<branch>は復元したいブランチ名(例えばmaster)、<commit-id>は復元したいコミットIDです。
git checkout <branch>
git cherry-pick <commit-id>
または、コミットIDを直接ブランチにマージすることもできます。
git merge <commit-id>
スタッシュで一時退避
開発中に、コミットはせずに別のブランチへ移動したい場合があります。そんな時に、変更内容を一時的に退避させるのがスタッシュです。
変更内容を一時退避させる
git stash
これでエラーや警告なく、ブランチやコミットを切り替えられるようになります。
スタッシュしたリストを確認する
git stash list
一時退避させた内容を戻す
元のブランチに戻ってきて、作業を再開したい場合は保存したスタッシュを戻す必要があります。
git stash pop
コミットメッセージを意味のあるものにする
コミットメッセージを何も考えなしに自由に書いてしまうと、人はおろか、自分でさえ変更内容がわからなくなってコミットを遡れなくなってしまいます。そこでアイデアとして Conventional Commits でコミットメッセージの構造を標準化する方法があります。Conventional Commits とは、単なる仕様にすぎません。仕様に従うことで、コミットログから直接バージョン番号やリリースノートを生成することが容易になります。
基本的なフォーマット
type: コミットの種類を示す
- feat: (新機能)
- fix: バグ修正
- docs: ドキュメントの変更
- style: コードのスタイルやフォーマットに関する変更
- refactor: リファクタリング
- test: テストの追加や修正
- chore: その他の変更
scope (オプション) : コミットが影響を与える範囲
例えば、特定のコンポーネントやファイル名などがこれに該当する。
description: コミットの簡潔な説明
何を変更したのか、なぜその変更が必要だったのかを明確にするべき。
body (オプション) : 詳細な説明
変更の動機や、どのように変更したのかの詳細を記載。
footer (オプション): issueトラッカーのID関連付け
例:
- Fixes #123
- Closes #456
実際の例
Conventional Commitsを使用することで、コミットログはより情報豊かで読みやすくなり、自動化ツールとの連携も容易になります。
とはいえ、Conventional Commitsに従って、すべての内容を書くのは面倒なので、私の場合は<description>と<description>オプションだけを仕様に従って記述するようにしています。これだけでもコミット履歴を見たときに、変更内容が分かりやすくなります。
特定のファイルの差分を表示する
git diff [ファイルパス]
コミットツリーを見やすく表示する
git log --graph --date=short でコミットツリーを表示できますが、お世辞にも見やすいとは言えません。そこで、オプションを追加してツリーを整形して見やすくする設定を紹介いたします。 こちらのstackoverflow で紹介されているものになります。git config --global --edit で 以下エイリアスを追記します。...
[alias]
lg1 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold green)(%ar)%C(reset) %C(white)%s%C(reset) %C(dim white)- %an%C(reset)%C(auto)%d%C(reset)' --all
lg2 = log --graph --abbrev-commit --decorate --format=format:'%C(bold blue)%h%C(reset) - %C(bold cyan)%aD%C(reset) %C(bold green)(%ar)%C(reset)%C(auto)%d%C(reset)%n'' %C(white)%s%C(reset) %C(dim white)- %an%C(reset)'
lg = lg1
コミットメッセージを変更したい
まだリモートリポジトリへプッシュしている前でしたら、コミットメッセージを修正・変更可能です。
git commit --amend
このコマンドを実行するとVimエディタが開かれるので、適宜内容を書き換えます。
▼ この記事で書ききれなかった機能をこちらにまとめてます。あわせてご参考ください。