概要 #
git・ghは使う頻度が高いのに、いざ打とうとすると「あれ、これどうやるんだっけ」と手が止まることがあります。特に「変更を戻したいが、どこまで戻るのが正しいか」「PRを作った後の後片付けはどうするか」あたりは、使うたびに調べ直しがちです。
自分が実際に繰り返し使っているコマンドを、実行結果とセットでまとめます。次に忘れたときにこのページを見れば手が止まらないようにするのが目的です。
git cloneやgit commitは使ったことがあり、ブランチを切ってPRを出す流れも一度は経験している人を想定しています。gitやGitHubをこれから始める人向けの入門ではありません。
コマンドラインでの実用に絞ります。gitの内部構造(オブジェクトモデル、reflogの仕組み)やGUIクライアントの操作は扱いません。
検証環境 #
- git 2.34.1
- gh 2.89.0
出力例は、動作確認用に作った小さなリポジトリと、このブログのリポジトリで実際に実行した結果です。
基本のワークフロー #
日々いちばん使う流れです。ブランチを切り、変更をコミットし、PRを作ってマージし、後片付けをします。
# 1. 最新のmainから始める
git switch main
git pull
# 2. 作業用ブランチを作る
git switch -c feature/some-topic
# 3. 変更をステージ(ファイルを個別に指定する)
git add path/to/file.md
# 4. コミット
git commit -m "説明"
# 5. リモートへpush(初回は -u で上流ブランチを設定)
git push -u origin feature/some-topic
# 6. PRを作る
gh pr create --title "タイトル" --body "本文"
# 7. マージし、ブランチも消す
gh pr merge <PR番号> --squash --delete-branch
# 8. ローカルの後片付け
git switch main
git pull
git fetch --prune origin
git add .やgit add -Aではなく、ファイルを個別に指定するのを習慣にしています。意図しないファイル(一時ファイル、認証情報、ローカル設定など)を巻き込む事故を防げます。
状態を見る #
今どうなっているか #
git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: file.txt
no changes added to commit (use "git add" and/or "git commit -a")
git status --short(-s)にすると1行1ファイルの簡潔な表示になります。左の記号はステージ済み、右は未ステージの状態です。
M file.txt
差分を見る #
git diff # 未ステージの変更
git diff --staged # ステージ済みの変更(--cachedも同じ)
diff --git a/file.txt b/file.txt
index 83db48f..d4d604f 100644
--- a/file.txt
+++ b/file.txt
@@ -1,3 +1,4 @@
line1
line2
line3
+modified line
git addした後にgit diffが空になるのは、既定では未ステージの変更だけを見るためです。ステージした内容を確認したいときは--stagedを付けます。
履歴を見る #
git log --oneline # 1コミット1行
git log --oneline --all --graph # 全ブランチをグラフで
* dfefad9 fourth commit on main
* 403e14a third commit
* 26b211d second commit
* a93c0e4 first commit
ブランチを操作する #
git switch -c feature/demo # 作成して切り替え
git switch main # 切り替え
git branch -a # 一覧(-a はリモート追跡ブランチも)
git branch --show-current # 今いるブランチ名だけ
git branch -d feature/demo # 削除(マージ済みのみ)
git branch -D feature/demo # 強制削除
feature/demo
* feature/demo2
main
git switchはgit 2.23で追加されたコマンドです。以前はgit checkoutがブランチ切り替えとファイル復元を兼ねていましたが、役割ごとにswitch(ブランチ)とrestore(ファイル)に分かれました。git checkout -bも今も動きますが、目的が読み取りやすいのはswitch -cのほうです。
削除時の-dはマージ済みのブランチだけを消します。未マージのブランチを消そうとすると止めてくれるので、まず-dを試し、本当に捨ててよいと分かってから-Dにするのが安全です。
変更を戻す #
いちばん忘れやすく、間違えると痛いところです。「どこまで戻すか」で使うコマンドが変わります。
まだコミットしていない変更 #
git restore file.txt # 作業ツリーの変更を捨てる
git restore --staged file.txt # ステージから降ろす(変更は残る)
git restore file.txtは変更を完全に捨てます。復元できません。捨ててよいか迷うときは、後述のgit stashで退避するほうが安全です。
コミット済みの変更 #
git reset --soft HEAD~1 # コミットだけ取り消し、変更はステージに残る
git reset HEAD~1 # コミット取り消し、変更は未ステージに(--mixed、既定)
git reset --hard HEAD~1 # コミットも変更も破棄
--softの後の状態です。変更はM(ステージ済み)として残っています。
M file.txt
--mixed(オプション省略時)の後は、未ステージに降りています。
M file.txt
--hardは変更を完全に破棄します。 また、resetは履歴を書き換えるため、すでにpush済みのコミットに使うと、他の人の手元と食い違います。
push済みのコミットを取り消す #
git revert <コミットハッシュ>
revertは「打ち消すコミットを新しく積む」ため、履歴を書き換えません。共有ブランチではこちらを使います。
b20ee55 Revert "feature: add feature line"
d44f4e2 feature: add feature line
7f150f6 fifth commit on main (conflicting edit)
元のコミットが残り、その上にRevert "..."が積まれています。
作業を一時退避する #
git stash # 変更を退避
git stash list # 退避一覧
git stash pop # 最新を戻して退避を削除
git stash apply # 戻すが退避は残す
git stash push -m "メモ" path/to/file # ファイル指定・メモ付き
$ git stash
Saved working directory and index state WIP on main: 403e14a third commit
$ git stash list
stash@{0}: WIP on main: 403e14a third commit
$ git stash pop
(変更が戻る)
Dropped refs/stash@{0} (8d243cc5aa163ecc045ecab81b2c940967c285ce)
「作業途中だが別のブランチで急ぎの修正をしたい」ときに使います。ファイルを指定して部分的に退避することもできます。
履歴を整える #
rebase:ブランチの起点を最新にする #
git switch feature/demo
git rebase main
Successfully rebased and updated refs/heads/feature/demo.
mainが進んだ後、自分のブランチをその先端に付け替えます。マージコミットが増えず、履歴が直線になります。
コンフリクトすると途中で止まります。
CONFLICT (content): Merge conflict in file.txt
error: could not apply 64c4e72... feature: add feature line
hint: Resolve all conflicts manually, mark them as resolved with
hint: "git add/rm <conflicted_files>", then run "git rebase --continue".
hint: You can instead skip this commit: run "git rebase --skip".
hint: To abort and get back to the state before "git rebase", run "git rebase --abort".
このときのgit statusは、いま何をしている途中かを教えてくれます。
interactive rebase in progress; onto 7f150f6
Last command done (1 command done):
pick 64c4e72 feature: add feature line
You are currently rebasing branch 'feature/demo' on '7f150f6'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)
Unmerged paths:
both modified: file.txt
対処は3択です。
# 解決して続ける
git add file.txt
git rebase --continue
# このコミットを飛ばす
git rebase --skip
# rebase自体をやめて元に戻す
git rebase --abort
迷ったら--abortで元の状態に戻せます。
cherry-pick:特定のコミットだけ取り込む #
git switch main
git cherry-pick <コミットハッシュ>
[main 50a646f] feature: add feature line
1 file changed, 2 insertions(+)
「別ブランチのあの修正だけ先に取り込みたい」ときに使います。
gh:PRを操作する #
gh pr create --title "タイトル" --body "本文"
gh pr create --fill # コミットメッセージからタイトル・本文を作る
gh pr list # 一覧
gh pr list --state merged --limit 5
gh pr view <番号> # 詳細
gh pr view <番号> --web # ブラウザで開く
gh pr diff <番号> # 差分
gh pr checkout <番号> # そのPRのブランチに切り替え
gh pr merge <番号> --squash --delete-branch
gh pr listの出力です。
125 docs/HANDOVER.md: #8(routes-based + ip-masq-agent)完了を反映 docs/handover-item8-complete MERGED 2026-09-02T10:02:07Z
124 Add article: VPC Peering越しのGKE Pod→VM通信をip-masq-agentで復旧させる feature/30-gke-routes-based-ip-masq MERGED 2026-09-02T10:00:51Z
--jsonで必要な項目だけ取り出せます。スクリプトから使うときに便利です。
gh pr view 124 --json number,title,state,mergedAt,url
{"mergedAt":"2026-09-02T10:00:57Z","number":124,"state":"MERGED","title":"Add article: ...","url":"https://github.com/tech-0222/hugo-blog/pull/124"}
マージ方式 #
gh pr mergeのヘルプに書かれている主なフラグです。
-d, --delete-branch Delete the local and remote branch after merge
-m, --merge Merge the commits with the base branch
-r, --rebase Rebase the commits onto the base branch
-s, --squash Squash the commits into one commit and merge
--squashはPR内のコミットを1つにまとめてマージするフラグです。作業途中の細かいコミットが本流の履歴に残らないので、普段はこれを使っています。--delete-branchを付ければ、リモートとローカルのブランチも一緒に消えます。
gh:Issueを操作する #
gh issue create --title "タイトル" --body "本文" --label article
gh issue list # 一覧
gh issue list --state closed --limit 5
gh issue view <番号>
gh issue comment <番号> --body "コメント"
gh issue close <番号> --comment "対応しました"
123 CLOSED [記事] VPC Peering越しのGKE Pod→VM通信をip-masq-agentで解決する article 2026-09-02T10:00:58Z
120 CLOSED [記事] GKEのPod/ServiceセカンダリIPレンジをどう設計するか article 2026-09-02T03:37:14Z
コミットメッセージやPR本文にCloses #123と書いておくと、マージ時にIssueが自動でクローズされます。手動でgh issue closeする必要はありません。
gh:その他 #
CIの実行結果を見る #
gh run list # 実行一覧
gh run list --branch main --limit 5
gh run view <run ID> # 詳細
gh run view <run ID> --log # ログ全体
gh run view <run ID> --log-failed # 失敗したステップのログだけ
completed success fix: 2記事に欠落していた... Check Terraform GCP blog main push 33694093914 44s 2026-09-02T23:13:38Z
completed success fix: 2記事に欠落していた... Check blog main push 33694093968 49s 2026-09-02T23:13:38Z
PRをマージした後、gh run listでCIが通っているかを確認する習慣をつけておくと、mainが壊れたまま放置される事故を防げます。実際にこの記事を書いている最中、過去のPRでCIが失敗したまま気づいていなかったことをgh run listで見つけました。
APIを直接呼び出す #
gh api repos/OWNER/REPO
gh api repos/OWNER/REPO --jq '{full_name, default_branch, open_issues_count}'
{"default_branch":"main","full_name":"tech-0222/hugo-blog","open_issues_count":1}
ghのサブコマンドに無い情報が欲しいときは、gh apiでGitHub APIを直接叩けます。認証はgh auth loginのものが使われるので、トークンを自分で用意する必要はありません。
認証状態を確認する #
gh auth status
github.com
✓ Logged in to github.com account tech-0222
- Active account: true
- Git operations protocol: https
- Token: gho_************************************
- Token scopes: 'gist', 'project', 'read:org', 'repo', 'workflow'
ghの動作がおかしいときは、まずここでログイン状態とトークンのスコープを確認します。
つまずいたときの確認先 #
| やりたいこと | コマンド |
|---|---|
| 今どうなっているか分からない | git status |
| 直前のコミットを取り消したい(変更は残す) | git reset --soft HEAD~1 |
| push済みのコミットを取り消したい | git revert <ハッシュ> |
| 作業を中断して別ブランチへ行きたい | git stash → git stash pop |
| rebaseの途中で分からなくなった | git status → git rebase --abort |
| ブランチを消したい | git branch -d(危なければ止まる) |
| PRのCIが通ったか見たい | gh run list |
| ghの調子が悪い | gh auth status |
まとめ #
git addはファイルを個別に指定する。意図しないファイルを巻き込む事故を防げる- 変更を戻すときは「どこまで戻すか」でコマンドが変わる。
restore(未コミット)、reset(コミット済み・履歴を書き換える)、revert(push済み・履歴を残す) rebaseの途中で迷ったらgit statusが今の状況と選択肢を教えてくれる。--abortでいつでも戻せる- PRマージ後は
gh run listでCIを確認する。マージした時点では通っていても、mainで別のチェックが落ちることがある