モテるGit管理 (gh, ghq, git-cz, lazygit)
この頃海外のエンジニアの環境構築動画を見るのにハマっているため、Mapifyから試してみようと思います。
「ドキュメント読み込み機能が便利だった」にある公式ドキュメントベースで回答を生成してくれるのも便利ですね!
はじめに
コード管理スマートにしたい!カッコつけたい!😎
⭐️愉快なつらみたち⭐️
- GitHubリポジトリを用意するためにターミナルから離れるの...?
- あれ?ディレクトリどこにおいたっけ??
- プロジェクトのディレクトリに移動するために長いパスを打つ苦行
- プレフィックス多すぎておぼえられな〜い
- プロジェクトごとにコミットメッセージのプレフィックスが違う..だと..?
- 絵文字つけ忘れ&コミットメッセージ間違えちゃった😭
-
プロジェクトルートに戻るために
cd ../
を繰り返し続ける人生...
こいつらを!全部!解決してやるぜぇ〜〜!!!💪
学習の初めをスマートに
手始めにこれらを解決しましょう。
- GitHubリポジトリを用意するためにターミナルから離れるの...?
- あれ?ディレクトリどこにおいたっけ??
- プロジェクトのディレクトリに移動するために長いパスを打つ苦行
こんな感じでCLIでGitHubリポジトリとローカルのリポジトリを用意することができるようになります。
具体的には以下の手順を行なっています。
- ghコマンドでGitHubリポジトリを作成し
- ghqコマンドでローカルに clone & git init
- ghqでgit管理しているプロジェクト一覧を取得し、fzfで選択してプロジェクトディレクトリへ移動
# GitHubリポジトリを作成
gh repo create [プロジェクト名] --private
# ローカルにクローン & git init
ghq get [プロジェクト名]
# ^Gでghqで管理しているリポジトリ一覧を取得し、fzfで選択して移動 (^Gはあらかじめ.zshrcに設定)
# 設定していない場合は以下のコマンドで同じことができる
ghq list | fzf | xargs -I{} cd $(ghq root)/{}
それぞれのツールの導入やら使い方やらを解説していきます。
GitHubの操作をCLIで (gh)
GitHubの操作をCLIで行いたい時は GitHub CLI (gh コマンド) を使用します。
導入は以下の記事が参考になります。
リポジトリを作成したい時は
# プライベートリポジトリ
gh repo create [プロジェクト名] --private
# 公開リポジトリ
gh repo create [プロジェクト名] --public
リポジトリを削除したい場合は
gh repo delete [プロジェクト名]
みたいな感じでサクッとできます。
PRやらIssueやらも操作できるので詳しくはgh --help
を確認してみてください。
gh --help (日本語ver.)
GitHubとコマンドラインからシームレスに連携します。
使用法
gh <コマンド> <サブコマンド> [フラグ]
コアコマンド
auth: ghとgitをGitHubに認証する
browse: ブラウザでリポジトリを開く
codespace: コードスペースに接続して管理する
gist: gistを管理する
issue: イシューを管理する
org: 組織を管理する
pr: プルリクエストを管理する
project: GitHubプロジェクトを操作する
release: リリースを管理する
repo: リポジトリを管理する
GitHub Actionsコマンド
cache: GitHub Actionsキャッシュを管理する
run: ワークフロー実行の詳細を表示する
workflow: GitHub Actionsワークフローの詳細を表示する
エイリアスコマンド
co: "pr checkout"のエイリアス
追加コマンド
alias: コマンドショートカットを作成する
api: 認証されたGitHub APIリクエストを行う
attestation: アーティファクトの証明書を操作する
completion: シェル補完スクリプトを生成する
config: ghの設定を管理する
extension: gh拡張機能を管理する
gpg-key: GPGキーを管理する
label: ラベルを管理する
ruleset: リポジトリのルールセット情報を表示する
search: リポジトリ、イシュー、プルリクエストを検索する
secret: GitHubシークレットを管理する
ssh-key: SSHキーを管理する
status: リポジトリ全体の関連イシュー、プルリクエスト、通知に関する情報を表示する
variable: GitHub Actions変数を管理する
ヘルプトピック
actions: GitHub Actionsの操作について学ぶ
environment: ghで使用できる環境変数
exit-codes: ghが使用する終了コード
formatting: ghからエクスポートされたJSONデータのフォーマットオプション
mintty: MinTTYでghを使用する際の情報
reference: すべてのghコマンドの包括的なリファレンス
フラグ
--help コマンドのヘルプを表示する
--version ghのバージョンを表示する
例
$ gh issue create
$ gh repo clone cli/cli
$ gh pr checkout 321
詳細情報
コマンドの詳細については`gh <コマンド> <サブコマンド> --help`を使用してください。
マニュアルはhttps://cli.github.com/manualを参照してください。
終了コードについては`gh help exit-codes`を使用して学んでください。
今いるリポジトリをブラウザで開くコマンドもあり、URLの共有や画面共有の時に便利ですね。
# 今いるリポジトリをブラウザで開く
gh browse
✌️✌️✌️✌️解決✌️✌️✌️✌️
これでターミナルとずっと一緒❤️❤️
- GitHubリポジトリを用意するためにターミナルから離れるの...?
ローカルにあるリポジトリを管理 (ghq)
ghqとは
ghqはローカルにあるリポジトリを管理するためのツールです。
クローンするパスをghqで管理するため、自分が今いるディレクトリを意識せずクローンすることができます。
クローンするためにいちいちディレクトリ移動する必要がなくなるのがいいですね。
以下のコマンドで管理しているリポジトリの一覧を取得できるのも便利です。
# ghqで管理しているリポジトリ一覧
ghq list
ghqの導入
brew install ghq
ghq
で管理するリポジトリのディレクトリのパスは~/.gitconfig
の[ghq] root
で指定します。
[ghq]
root = /Users/username/src
ghqでクローン
自分が管理しているレポジトリはリポジトリ名単体でクローンできます。
ghq get project-name
自分以外のリポジトリをクローンする時はリポジトリの所有者名をつけます。
ghq get user-name/project-name
ghq get
は以下のパスにクローンしたものを配置します。
[.gitconfigで指定したディレクトリ] + [github.com/user-name/project-name]
例えば、mozumasu/dotfilesをクローンした場合は以下のようになります。
/Users/mozumasu/src/github.com/src/mozumasu/dotfiles
ghq --help (日本語ver.)
NAME:
ghq - リモートリポジトリのクローンを管理
USAGE:
ghq [グローバルオプション] コマンド [コマンドオプション]
VERSION:
1.7.1 (rev:5bf53dc)
AUTHORS:
motemen <motemen@gmail.com>
Songmu <y.songmu@gmail.com>
COMMANDS:
get, clone リモートリポジトリのクローン/同期
list ローカルリポジトリの一覧
rm ローカルリポジトリの削除
root リポジトリのルートを表示
create 新しいリポジトリを作成
help, h コマンドの一覧または特定のコマンドのヘルプを表示
GLOBAL OPTIONS:
--help, -h ヘルプを表示
--version, -v バージョンを表示
今いるディレクトリを意識せずに設定したパスにクローンできるのは認知不可が低くて快適ですね。
✌️✌️✌️✌️解決✌️✌️✌️✌️
- あれ?ディレクトリどこにおいたっけ??
プロジェクトディレクトリにサクッと移動(ghq, fzf)
fzfとは
fuzzy finderの一つで、リストから曖昧検索して選択することができるツールです。
使えばわかります。使いましょう。
fzfの導入
インストールは以下のコマンドで行います。
brew install fzf
ghqのパスが長いな〜と感じるかもしれませんが、
aliasを設定して^G
を押すとサクッと移動できるようにしておけば負担になることもありません。
# ghq
function ghq-fzf() {
local src=$(ghq list | fzf --preview "bat --color=always --style=header,grid --line-range :80 $(ghq root)/{}/README.*")
if [ -n "$src" ]; then
BUFFER="cd $(ghq root)/$src"
zle accept-line
fi
zle -R -c
}
zle -N ghq-fzf
bindkey '^g' ghq-fzf
自分はファジーファインダーにfzf, プレビューにbatを使用しています。この部分はお好きなものに書き換えてください。
コードはこちらの記事に載っているものを使用させていただだいています。コードの詳細な解説もあるありがたい記事です。感謝🙏
解決ッ!🎉
- プロジェクトのディレクトリに移動するために長いパスを打つ苦行
コミットをスマートに
続いてのお題はこちら。
- プレフィックス多すぎておぼえられな〜い
- プロジェクトごとにコミットメッセージのプレフィックスが違う..だと..?
- 絵文字つけ忘れ&コミットメッセージ間違えちゃった😭
画像は以下の手順を行なっている様子です。
コミットメッセージを美しく (git-cz)
git-czはConventional Commitsというコミットメッセージの標準規格に従ったコミットメッセージを作成することができます。
要はプレフィックスとフォーマットを強制してコミットメッセージを美しくしてくれるツールです。
以下のように対話形式でプレフィックスを選んでコミットメッセージを作成することができるため、プレフィックスが覚えられない&絵文字つけ忘れ問題もgit-czが解決してくれます。
git-czの導入
npm install -g git-cz
プロジェクトごとにプレフィックスを設定
プロジェクトごとに固有のプレフィックスがある場合はプロジェクトのルートにchangelog.config.js
を設置し、プレフィックスを設定します。
zennのリポジトリの例
module.exports = {
disableEmoji: false,
format: "{type}: {emoji}{subject}",
list: [
"add",
"update",
"publish",
"unpublish",
"delete",
"fix",
"chore",
"docs",
],
maxMessageLength: 64,
minMessageLength: 3,
questions: [
"type",
"scope",
"subject",
"body",
"breaking",
"issues",
"lerna",
],
types: {
add: {
description: "新規記事の追加",
emoji: "🚀",
value: "add",
},
update: {
description: "記事の追記や更新",
emoji: "🎸",
value: "update",
},
publish: {
description: "記事の公開",
emoji: "🔖",
value: "publish",
},
unpublish: {
description: "記事の非公開",
emoji: "🙈",
value: "unpublish",
},
delete: {
description: "記事の削除",
emoji: "🗑",
value: "delete",
},
fix: {
description: "記事の誤字・脱字の修正",
emoji: "🐛",
value: "fix",
},
chore: {
description: "CI/CDの変更やパッケージのアップデートなど",
emoji: "🤖",
value: "chore",
},
fix: {
description: "不具合の修正",
emoji: "🐛",
value: "fix",
},
docs: {
description: "ドキュメントの更新",
emoji: "✏️",
value: "docs",
},
},
messages: {
type: "Select the type of change that you're committing:",
subject: "Write a short, imperative mood description of the change:\n",
body: "Provide a longer description of the change:\n ",
breaking: "List any breaking changes:\n",
issues: "Issues this commit closes, e.g #123:",
},
};
- プレフィックス多すぎておぼえられな〜い
- プロジェクトごとにコミットメッセージのプレフィックスが違う..だと..?
もちろんグローバル設定も用意可能です。
グローバル設定は~chanlog.config.js
に配置します。
~/.chanlog.config.js (グローバル設定)
module.exports = {
disableEmoji: false,
format: "{type}{scope}: {emoji}{subject}",
list: [
"feat",
"test",
"fix",
"chore",
"docs",
"refactor",
"style",
"ci",
"perf",
"package",
"config",
"WIP",
],
maxMessageLength: 64,
minMessageLength: 3,
questions: [
"type",
"scope",
"subject",
"body",
"breaking",
"issues",
"lerna",
],
scopes: [],
types: {
feat: {
description: "新機能",
emoji: "🎸",
value: "feat",
},
chore: {
description: "ビルド関連やライブラリの変更",
emoji: "🤖",
value: "chore",
},
ci: {
description: "CI関連の変更",
emoji: "🎡",
value: "ci",
},
docs: {
description: "ドキュメントの更新",
emoji: "✏️",
value: "docs",
},
fix: {
description: "不具合の修正",
emoji: "🐛",
value: "fix",
},
perf: {
description: "パフォーマンス改善",
emoji: "⚡️",
value: "perf",
},
refactor: {
description: "リファクタリング",
emoji: "💡",
value: "refactor",
},
style: {
description: "コードの処理に影響しない変更(スペースや書式設定など)",
emoji: "💄",
value: "style",
},
test: {
description: "テストコード",
emoji: "💍",
value: "test",
},
//自分用に追加
package: {
description: "パッケージ",
emoji: "📦",
value: "package",
},
config: {
description: "設定ファイル",
emoji: "⚙",
value: "config",
},
WIP: {
description: "作業途中",
emoji: "🚧",
value: "WIP",
},
},
messages: {
type: "プレフィックスを選択:",
subject: "コミットのタイトル(概要)を入力(option):\n",
body: "変更内容の詳細を入力(option):\n",
breaking: "重大な変更を入力(option):\n",
issues: "関連するisuueを入力(option), 例 #123:",
},
};
Git管理を簡単に (Lazygit)
Git管理を簡単にするTUIツールlazygit
を使用します。
コミットを手軽に分けたり、修正したい!みたいな時に重宝します。
?
でキーバインド一覧を表示できます。gitのコマンドはおろか、lazygitの操作なんて覚えられない!って人でも安心ですね。
ターミナルでもNeovimでも使用することができます。
下記のように簡単にファイルをステージング&コミットし、Pushすることができます。
Lazygitの導入
brew install jesseduffield/lazygit/lazygit
lazygitって入力するのが大変なのでaliasを設定しておくと便利です。
abbr -S lg='lazygit' >>/dev/null
LazyGitでよくやる操作
コミット前のファイルを一時退避 (Stash)
-
差分を全てStash
s
-
ステージングだけStash
-
スペースキー
でファイルをステージング - ステージングしたファイルを
S
→s
でStash
-
-
Stashをステージに反映
- Stashウィンドウを選択し、反映させたいStashをスペースで選択
- Stashした内容が反映される
以下のgifではステージングのStashとStashの反映をしている様子です。
コミット漏れを修正 (git commit --amend)
ファイルをステージングした状態でA
コミットメッセージを修正
修正したいコミットメッセージにカーソルを合わせてr
を押すとコミットメッセージを編集することができます。
コミットの内容を変更したい (fixup)
特定のコミットを修正したい場合は、以下の手順で行います。
- コミットに加えたい内容をステージング
- 修正したい対象のコミットにカーソルを合わせて
F
を押す (fixupコミットが作成される) - 修正したい対象のコミットに再度カーソルを合わて
S
を押す (auto squash)
fixupよくわからんって人は以下の記事を参考にしてください。
コミットメッセージの修正もできるようになりました🙌
- 絵文字つけ忘れ&コミットメッセージ間違えちゃった😭
コミットを別ブランチに持っていく (cherry-pick)
私はよくブランチを間違えてコミットしてしまいます😭
別ブランチにコミットしてしまった場合は以下の手順で別ブランチにコミットを持っていくことができます。
- 間違ってコミットしたブランチに
スペースキー
で移動 - 移動したいコミットにカーソルを合わせて
C
- コミットを持っていきたいブランチに
スペースキー
で移動 -
V
でコミットを貼り付ける
Lazygitからgit-czを使う
lazygitの設定ファイルは~/.config/lazygit/config.yml
にあります。
自分は以下のように設定して、C
でgit-czを実行できるようにしています。
# https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md
customCommands:
- command: git cz
context: files
subprocess: true
key: C
gui:
language: "ja"
showIcons: true
# log customize
git:
branchLogCmd: "git log --graph --color=always --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' {{branchName}} --"
allBranchesLogCmd: "git log --graph --color=always --pretty='%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --all"
paging:
colorArg: always
pager: delta --dark --paging=never
プロジェクトルートに戻る時もスマートに
最後にこれを解決しましょう。
- プロジェクトルートに戻るために
cd ../
を繰り返し続ける人生...
プロジェクトルートに戻る
実はgitコマンドにはgit rev-parse --show-toplevel
という便利コマンドがあります。
これを以下のようにaliasに設定しておくとproot
でプロジェクトルートに移動することができます。
abbr -S proot='cd $(git rev-parse --show-toplevel)' >>/dev/null
または
alias proot='cd $(git rev-parse --show-toplevel)'
直前のディレクトリに戻る
cd -
で直前のディレクトリに戻ることができます。
プロジェクトルートから移動した場合はcd -
でもプロジェクトルートに戻ることができます。
通常はcd -
で戻って、cd -
で戻れなかったらproot
にして使い分けてもいいかもしれません。
追加でzshの設定ファイルに以下のオプションを追加しておくとcd
無しでディレクトリ移動ができるようになります。
-
だけで戻れるので楽ですね。
setopt auto_cd
これでもう../
を繰り返す必要はありませんね🎵
- プロジェクトルートに戻るために
cd ../
を繰り返し続ける人生...
git-czとcz-git (12/6追記)
おわりに
少しでも皆様のCLI生活が快適になれば幸いです。
アドベントカレンダー5日目はucanさんの「JavaScriptビルドツールの歴史と進化」という記事です。
ツールオタクとしては目が離せない内容ですね。
明日もぜひお楽しみに🎄
また、コメントやTwitterにてコメントいただきありがとうございました!自身の知識のアップデートできて嬉しい限りです。
Discussion
こんにちは、自分もgit-czを使っていましたが、最近はcz-git(czg) の方を利用しています。
主な機能差分は以下にまとめられています。(実際そこまで大きな差はない気がしていますが)
FYI程度でした。よければ見てみてください。
情報いただきありがとうございます!OSSを見たり試したりするのが好きなので教えていただけて嬉しいです!
👀軽量化されていてプロジェクトへの導入のハードルも下がりますね...!
日曜日くらいに使い倒してみます!
これでabbrの標準出力を出さないようにしてますが、
--quieter
オプションをつけると同じことができるので是非。おお!!この書き方見やすくて最高にクールですね!
自分の設定ファイルが
>>/dev/null
だらけで見づらいな〜と思っていたので助かります😭本文にも追記させていただきます!もし問題等あれば教えていただけますと幸いです。🙏