GitHub CLIでプルリクエストを出す朝、CIを待つ昼、マージする夕方。ghだけで回す一日

コードを書いているのはエディターとターミナルなのに、プルリクエストを出すときだけブラウザに移る。タブを探し、リポジトリのページを開き、「Compare & pull request」のボタンを押し、タイトルと説明を書き直し、レビューをお願いする相手を選ぶ。一つひとつは数十秒の作業でも、1日に何度も繰り返すと、そのたびに頭の中で組み立てていた続きが途切れてしまう。私が気になっていたのは、時間そのものより、この途切れのほうだった。 GitHub CLI、コマンド名で言えば gh は、GitHub が公式に配布しているコマンドラインの道具だ。git が手元のリポジトリと遠くのリポジトリのあいだで履歴をやり取りする道具だとすれば、gh はその外側にある GitHub 独自の仕組み、つまりプルリクエスト、イシュー、Actions の実行結果、リリースといったものをターミナルから扱うための道具になる。git の代わりではなく、git の隣に置いて使う。 この記事では、朝にブランチを切ってプルリクエストを出し、昼に CI の結果を待ち、午後にレビューをやり取りして、夕方にマージするまでの一日を、gh のコマンドだけでたどっていく。最後に、毎日使うための短縮の設定と、それでもブラウザを開いたほうが早い場面もまとめておく。 準備はインストールとログインの2つだけ エディターの隣にターミナルを置いておけば、プルリクエストの操作もそこで済むPhoto: Wikideas1 / CC0 インストールは、Windows なら winget install --id GitHub.cli、macOS なら brew install gh の1行で終わる。Linux でも主要なディストリビューション向けのパッケージが用意されている。入れ終わったら gh --version で版を確かめておく。gh は数週間おきに新しい版が出るので、手順の説明と手元の動きが違うと感じたら、まず版を新しくするのが近道だと思う。 次にログインする。gh auth login を実行すると、どの GitHub につなぐか、git の通信に HTTPS と SSH のどちらを使うかを順に聞かれる。認証の方法は、ブラウザでの承認を選ぶのが手軽だ。ターミナルに8文字の確認コードが表示され、ブラウザで GitHub の承認画面を開いてそのコードを入れると、ログインが完了する。ブラウザを使うのはこの一度だけで、受け取った認証情報は OS の資格情報の保管場所にしまわれる。 ログインできたかどうかは gh auth status で確かめられる。どのアカウントで、どこに認証情報が置かれているかが表示される。あわせて gh auth setup-git を一度実行しておくと、git の push や pull でも gh の認証情報が使われるようになり、パスワードやトークンを毎回聞かれることがなくなる。サーバーや自動化の仕組みの中で使うときは、ログインの代わりに環境変数 GH_TOKEN にトークンを入れておけば、gh はそれを読んで動く。 ...

2026年10月27日 · 2 分 · 418 文字 · kingsworksub-jpg

Windowsのシンボリックリンクをmklinkで作る、ジャンクションとの違いとrmdirで消す理由

複数のプロジェクトで同じ設定ファイルを使い回したい、容量の大きいキャッシュを別の場所へ逃がしたい。開発をしていると、こういう場面でシンボリックリンクが欲しくなる。LinuxやmacOSならln -sの1行で済む話だが、Windowsではリンクの種類が3つあり、作れるかどうかが権限や設定で変わり、消し方を間違えると元のファイルまで消える。毎回なんとなく調べ直しているので、ここで一度まとめておく。 確かめた環境は、手元のWindows 11(ビルド26300)、標準のWindows PowerShell 5.1(5.1.26100)、Git for Windows 2.55、Node.js 24.19だ。一時フォルダの中に作業用のフォルダを作り、リンクを作る、フォルダごと動かす、消す、Gitで取り出す、という操作を順に試した。結果は最後に表にしている。 Windowsのリンクは3種類、まず何が違うのか ハードリンクは同じボリュームの中でしか作れない。ディスクをまたぐならジャンクションかシンボリックリンクを使うPhoto: Mk2010 / CC BY 4.0 WindowsのNTFSで使えるリンクは、シンボリックリンク、ジャンクション、ハードリンクの3つだ。コマンドプロンプトのmklinkで、オプションを変えるとそれぞれを作り分けられる。何も付けなければファイルのシンボリックリンク、/Dでフォルダのシンボリックリンク、/Jでジャンクション、/Hでハードリンクになる。 シンボリックリンクは、いちばんln -sに近いものだ。ファイルにもフォルダにも使え、行き先を相対パスで書ける。ネットワーク上の共有フォルダを指すこともできる。Windows Vistaから使えるようになった。 ジャンクションは、それより前のWindows 2000の時代からある、フォルダ専用のリンクだ。行き先は同じパソコンの中のドライブに限られ、パスは絶対パスで保存される。権限の面ではいちばん気軽で、一般ユーザーのまま作れる。 ハードリンクは性質がまったく違う。1つのファイルの実体に、名前を2つ付けるしくみで、どちらが本物という区別がない。ファイル専用で、同じボリュームの中でしか作れない。手元でハードリンクの側に1行書き足すと、元のファイルの中身も同じように増えていた。片方の名前を消しても、もう片方の名前が残っていればファイルの中身は消えない。 dirで一覧を出すと、この違いがそのまま見える。シンボリックリンクは<SYMLINK>か<SYMLINKD>、ジャンクションは<JUNCTION>と表示され、角かっこの中に行き先が出る。ハードリンクは普通のファイルと見分けがつかない。 管理者権限が要るのはシンボリックリンクだけ、開発者モードで外せる Windows 10 Mobileの「開発者向け」設定。パソコン版のWindowsにも同じ名前の画面があり、そこで開発者モードをオンにするPhoto: The Microsoft Corporation / Public domain シンボリックリンクを作るには、本来は「シンボリックリンクの作成」という特権が必要で、既定では管理者にしか与えられていない。ジャンクションとハードリンクにはこの制限が無い。開発ツールがフォルダのリンクにジャンクションを好んで使うのは、権限で失敗しないからだと思う。 この制限は、Windows 10のCreators Update(バージョン1703)から緩くなった。設定の「開発者向け」で開発者モードをオンにしておくと、一般ユーザーでもシンボリックリンクを作れる。ただし作る側のプログラムが、API(CreateSymbolicLink)に「特権なしでの作成を許可する」という専用の値(SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE)を渡している場合に限られる。開発者モードをオンにしただけで、どのツールでも作れるようになるわけではない。 手元のパソコンは開発者モードがオンで、作業したユーザーは管理者ではない。この状態で4種類を作り比べた結果が次の表だ。 作り方 種類 結果 mklink / mklink /D シンボリックリンク 作成できた mklink /J / mklink /H ジャンクション・ハードリンク 作成できた PowerShell 5.1のNew-Item -ItemType SymbolicLink シンボリックリンク 「この操作には管理者特権が必要です」で失敗 PowerShell 5.1のNew-Item -ItemType Junction / HardLink ジャンクション・ハードリンク 作成できた Node.jsのfs.symlinkSync(dir・junction・ファイル) 3種とも 作成できた 意外だったのはPowerShell 5.1だ。同じウィンドウのmklinkは通るのに、New-Itemでシンボリックリンクを作ろうとすると、開発者モードがオンでも管理者権限を求められて止まった。5.1しか無い環境でスクリプトからシンボリックリンクを作るなら、cmd /c mklinkを呼ぶのがいちばん確実だった。PowerShell 7は手元に入っていないので、こちらは確かめていない。 ...

2026年10月20日 · 1 分 · 180 文字 · kingsworksub-jpg

git worktreeで作業フォルダをブランチの数だけ持つ、stashと切り替えをやめるための備忘録

新しい機能のブランチで作業している途中に、本番側の小さな不具合を直してほしいと頼まれる。これまでは、書きかけの変更をgit stashで退避し、git switch mainで切り替え、直してコミットし、元のブランチに戻ってgit stash popする、という手順を踏んでいた。そのたびにエディタは開いていたファイルを読み直し、ビルドの成果物は古いブランチの状態のまま残り、退避したことを忘れてstashが溜まっていく。小さな修正のはずが、戻ってきたときに何をしていたか思い出すところから始まるのが嫌だった。 この切り替えそのものをやめられるのがgit worktreeだ。1つのリポジトリに作業フォルダを何本でも足せて、フォルダごとに別のブランチを開いておける。修正を頼まれたら、別のフォルダに移って直すだけで済み、書きかけの作業には指一本触れない。仕組みと使い方、それに後片付けでつまずきやすい点を、手元のWindows 11に入っているGit 2.55.0で一通り試したので、その結果をまとめておく。 worktreeは作業フォルダを増やす機能で、リポジトリは1つのまま mainから枝を切り、作業してmainへ戻す。worktreeを使うと、この枝ごとに別のフォルダを持てるPhoto: TheresNoTime / CC BY-SA 4.0 ふつうのクローンは、.gitフォルダ(履歴やブランチの情報が入っている本体)が1つと、ファイルを編集するための作業フォルダが1つ、という組み合わせになっている。ブランチを切り替えると、この作業フォルダの中身が丸ごと書き換わる。同じリポジトリを2つの場所で開きたければ、もう1回クローンするのがこれまでのやり方だったが、それだと履歴が2倍の容量になり、片方で作ったブランチをもう片方から見るにはpushとfetchを挟む必要がある。 worktreeは、.gitの本体は1つのまま、作業フォルダだけを追加する。最初からある作業フォルダを「メインのワークツリー」、後から足したものを「リンクされたワークツリー」と呼ぶ。追加したフォルダの直下にあるのは.gitフォルダではなく、.gitという名前の小さなテキストファイルで、中身は1行だけだった。 gitdir: C:/Users/norio/AppData/Local/Temp/wtlab/repo/.git/worktrees/repo-feature 指している先は、メインのリポジトリの.git/worktrees/の下に作られた管理用のフォルダだ。ここにそのワークツリー専用のHEAD(今どのブランチを開いているか)とindex(ステージングの状態)が置かれ、commondirというファイルには本体への相対パス../..が、gitdirというファイルには逆向きに作業フォルダ側の.gitファイルの場所が書かれている。行きと帰りの両方向にパスが記録されていることが、後で出てくる「フォルダを動かしたときに壊れる」話の原因になる。 機能としては古く、2015年7月のGit 2.5で入った。当初は追加と掃除くらいしかできず、フォルダを消すremoveと移すmoveが加わったのは2018年のGit 2.17だ。その後も、空のブランチで作業フォルダを作る--orphanがGit 2.42で、パスを相対で記録する--relative-pathsがGit 2.48で足されている。古い解説記事では、フォルダを手で消してpruneで片付ける手順が紹介されていることがあるが、今はremoveで一度に済む。なお、サブモジュールを含むリポジトリでの複数ワークツリーは、公式の説明書きでも対応が不完全とされていて、サブモジュールのあるワークツリーはmoveできない。サブモジュールを多用するリポジトリでは、慎重に試したほうがいい。 基本はadd・list・removeの3つで足りる まずはブランチを1つ、隣のフォルダに開いてみる。リポジトリの中で次のように打つ。 git worktree add ../repo-feature feature # 既存のブランチ feature を開く git worktree add -b hotfix ../repo-hotfix # 新しいブランチ hotfix を作って開く git worktree list listの出力は、フォルダ、開いているコミット、ブランチ名の3列になる。 C:/Users/norio/AppData/Local/Temp/wtlab/repo 008158a [main] C:/Users/norio/AppData/Local/Temp/wtlab/repo-feature 008158a [feature] C:/Users/norio/AppData/Local/Temp/wtlab/repo-hotfix 008158a [hotfix] あとはcd ../repo-hotfixで移って、いつも通り編集・コミット・pushすればよい。コミットは本体の.gitに入るので、メインのフォルダに戻ってgit log hotfixと打てば、もうそこにある。pushもfetchも要らない。 ブランチ名を書かずにgit worktree add ../quickfixとフォルダだけ渡すと、フォルダ名と同じquickfixというブランチが今のコミットから作られた。もう1つ便利だったのは、手元にはまだ無く、リモートにだけあるブランチの名前を渡した場合だ。クローンしたリポジトリでgit worktree add ../clone-topic topicとすると、origin/topicを追いかけるtopicブランチが自動で作られ、branch 'topic' set up to track 'origin/topic'.と表示された。レビューを頼まれたブランチを開くときは、これがいちばん手数が少ない。 ...

2026年10月18日 · 2 分 · 407 文字 · kingsworksub-jpg