Yakstは、海外の役立つブログ記事などを人力で翻訳して公開するプロジェクトです。
3ヶ月前投稿 修正あり

よりよいGitの設定

.gitconfigファイルに記入するオプションをカスタマイズすれば、Gitをより上手に、便利に使うことができる。著者のGit設定の紹介と、便利な設定の解説。

原文
Better Git configuration | Scott Nonnenberg (English)
翻訳者
D98ee74ffe0fafbdc83b23907dda3665 doublemarket
翻訳レビュアー
B5aa4f809000b9147289650532e83932 taka-h


私はGitが大好きで、いつでもGitを使っています。私は時々、何かについて深く調べてみたり、ドキュメントを一通り読んでみたり、設定を見直してみたりするのですが、今回はGitについてそれをやってみました。私の書いた4番目の技術スタックの改善に関する記事にようこそ!

Gitのすべて

私がコーディングを始めたのは、ただのファイルシステム上でコピーしていたあの辛い日々、そしてチェックアウトに排他的ロックが必要だったVisual SourceSafeを使っていた時でした。それでもその時、ソース管理のコンセプトは私にとって素晴らしいものに思えましたし、家でコーディングする時にはそういったものにアクセスできたらな、と思っていました。

その後カリフォルニアポリテクニック州立大学(Cal Poly)で、グループプロジェクトに関わる中でConcurrent Versions System (CVS)に出会いました。限られたグループプロジェクトしかなかったので、あまり得意になったわけではありませんでした。

マイクロソフトで働いている間、プロダクトが出荷できるものか確認するためにVisual Studioの開発者でない人間が丸々1週間を使ってドッグフーディングすると言う「App Week」と呼ばれる期間中、ソース管理のためにTeam Foundation Serverを使いました。しかし、その間に個人的なプログラミングの全てはSubversionと共にありました。無料で、しかも簡単にローカルで動かせたからです。ローカルでの変更の全てを記録するのに使っていました。

それが変わったのは、2010年の秋のことでした。サイドプロジェクトを開発するためにRuby on Railsを学習し、私が読んだその総合的なチュートリアルは、Herokuと新しいバージョン管理システムである Git を取り上げていました。Gitを使えば、ローカルにホストしているように扱いつつも、同時に他の人ともやり取りできるという点で、素晴らしいものでした。排他的ロックもないし、オフラインでも生産性が落ちないし、賢いマージをしてくれる。私はGitに夢中になりました。

それからGitはまさに人気を得ています。オープンソースにとっては事実上の標準です。主要などのクラウドソースコードホスティングサービスにもサポートされています。専用のソース管理ツールからコードエディターまで、多くのGUIツールにもサポートされています。

Gitは、知っておくべき、そしてちゃんと知っておくべきものなのです。

グローバル設定

知っているかどうかに関わらず、あなたはもうグローバルなGitの設定を使っています。それは、ホームディレクトリの .gitconfig ファイルです。ほとんどの .gitconfig には、よくある「Gitを始める」チュートリアルで作られた通り、あなたの名前とメールアドレスが書かれているでしょう。しかし、このファイルにはとてもたくさんの設定が使えるのです!

私の グローバルな .gitconfig の中身はコメント付きで全てgistに置いてあります。直接このファイルを見てみてもよいですが、ここではもう少し詳しくそれぞれのセクションについて取り上げてみたいと思います。

エイリアス

.gitconfig を特別仕様にするのになくてはならないのが、独自のコマンドを作れてしまう [alias]セクションです。何か機能が不足していると思いますか?ここに追加してしまいましょう!いまいち使いたいように動いてくれない機能がある?ここに自分専用バージョンを追加しましょう!

  • prune = fetch --prune - 他の人がメインリポジトリーにブランチをプッシュするプロジェクトで仕事している時は、たくさんの色々なローカルブランチに遭遇することになります。 pruneは、リモートで削除済みのローカルブランチを全て削除します。ここに追加するのは、私がいつもこれを忘れてしまうからです。
  • undo = reset --soft HEAD^ - コミットで間違いをしてしまった時には、このコマンドがコミット前の状態を復元してくれます。ただし、通常私はこのような場合、既にしてしまったコミットをamend(修正)します。これはコミットメッセージを残してくれるからです。
  • stash-all = stash save --include-untracked - Stashは、他のブランチで作業中にも関わらず誰かがあちこちのブランチをチェックアウトしてくれと依頼してくるような時にとても便利です。このコマンドを使うと、stashした時、まだ git add でトラックしていない新しいファイルも一緒にstashしてくれます。
  • glog = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' - デフォルトの git logコマンドで表示されるコミット履歴はスペースの効率が悪く、重要な情報に焦点が当たっていません。このコマンドのカラフルでグラフィカルな表示は、ブランチが複雑な時などにもパースしやすくなっています。

マージ

ff = only は、すべてのマージがfast-forwardでない限りエラーを出してくれるようにするものです。マージコミットを作らず、2つの履歴をひとつにすることもなく、コミットからコミットへスムーズに進んで行くようにします。

これでどうやって仕事を進めるのか疑問に思った人もいるでしょう!その答えは、コミットツリーの分岐を持ってきて違う場所に付け替え、新しい「ベース」を作ってくれる git rebase です。これは非常に便利なツールです。

これが、 master とコンフリクトが起きた時にプルリクエストを更新する場合の私のやり方です。これはつまり、他の人が変更を加えた未来の世界に、自分のコミット全部を適用するチャンスを得たということです。最新の master を自分のブランチにマージする時の「他人の変更を自分の変更にマージする」という比喩よりもこちらの方が私はいいと考えています。

このオプションは素晴らしくて、これでうっかりマージコミットを作ってしまうということがなくなります。マージコミットを意図的に作りたいなら、 git merge --ff を明示的に指定して強制的に作ることが可能です。

conflictstyle = diff3 は、マージのコンフリクトが発生した時に少し多めの情報が得られます。通常は、「左から」の変更と「右から」の変更という2つのセクションが表示されます。しかしこのオプションを使うと、「左」と「右」が変更しようとする前の元々の状態を表示する3番目のセクションが表示されます。

コミット

gpgSign = true は、全てのコミットがGPGキーで署名されるようにしてくれます。 .gitconfig ファイルの中にあるユーザー情報は何の証明もされておらず、あなたのものに見えるコミットが、他の誰かのプルリクエストに現れると行ったことが簡単に起こり得てしまうので、このような設定をするのはよい考えです。

私は一度、アカウントやマシンの準備に時間がかかりすぎるという理由で、他の人の認証情報を使わなくてはならないことがありました。私のプルリクエストは他の人のアカウントから作られたのですが、そこに含まれるコミットの全ては、私の本名が書かれていたというわけです。パブリックなGPGキーをGitHubアカウントに登録することで、コミットがどこからきたものなのかに対する疑問を消し去ることができます。署名されたコミットには、小さな"Verified"バッジが付きます

注意 :

  • 複数のGPGキーを持っている場合は、 user.signingKey オプションでどれを使うかを指定できます。
  • GUIアプリケーションを使っているときには、コミットに署名するのにこのオプション群を使う必要はありません。アプリケーションのオプションを調べてみましょう。
  • gpg-agent で、パスフレーズを入力する時間を節約できるので、作業がちょっと楽になります。使いましょう!

プッシュ

default = simple は、もう既に設定済みのオプションかもしれません。これで、ローカルブランチをリモートの同名のブランチにプッシュするのが簡単になります。

followTags = true もとても簡単です。新しいタグを --follow-tags を付けて手動でプッシュする代わりに、 git push すると一緒にローカルのタグを送ってしまえるのです。あなたはどうか分かりませんが、私はローカルで作ったタグがあったら、プッシュする時に全部含まれてて欲しいんです。

ステータス

showUntrackedFiles = all 普通、新しいディレクトリーを追加したけれどもまだ git add していない時には、 git status は単にディレクトリー名だけを表示するはずです。たくさんのファイルを含む新しいディレクトリを作ったのに1行しか表示されなくて、私はこれで失敗したことが何度かあります。このオプションは、このような新しいディレクトリーは以下のファイル全てを git status コマンドで表示するようにします。

注意 : 非常に大きいディレクトリーの場合、これによって動作が遅くなる可能性があります。

転送

fsckobjects = true は、変更の受信あるいは送信の際に追加のチェックを行いたいということをGitに伝えるためのものです。どうして追加チェックが必要なのでしょうか?データの破損を、あとではなく近いうちに警告されたいと思うのではないでしょうか?

注意 : これにより転送が少し遅くなる可能性があります。

diffツール : icdiff

ビルトインの git diff コマンドに加えて、Gitではdiffをビジュアライズしてくれる外部ツールを使えるようになっています。以下の一連の設定は、リポジトリー内の2つの状態の違いを表示する icdiff を設定するものです。

[diff]
  tool = icdiff
[difftool]
  prompt = false
[difftool "icdiff"]
  cmd = /usr/local/bin/icdiff --line-numbers $LOCAL $REMOTE

これで、普通通り git difftool master branch で使えます。

icdiff は、カラフルでGitHub風の分割型のdiffを、コンソール上に再現しようとするのが面白いところです。通常のチャンクベースのdiffの表示よりも、ちょっと読みやすいでしょう。

注意 : - icdiff のインストールがちょっと難しいかもしれません。ラッキーなことに、簡単な回避策があります。 - git diff は残したままにしておきましょう。 icdiff は、 /dev/null との比較は扱えないようです。例えば、新しいファイルをステージした後に git difftool --cached してみましょう。

ボーナス : もっとリビジョンを!

いつも git checkout master 実行してますよね?このコマンドでは、 masterリビジョンの一例であり、特に master ブランチの最新のコミットを指す完結表現です。よくあるリビジョン表現があります。

# ブランチのチェックアウト
git checkout branchname

# リモートブランチのチェックアウト
git checkout remotes/origin/branchname

# 特定のコミットのチェックアウト
git checkout 158e4ef8409a7f115250309e1234567a44341404

# 現在のブランチの最新コミットのチェックアウト
git checkout HEAD

しかしここで、リビジョンを指定する完全な表現があることに気づきます。それぞれの記号は、上の例の目的語部分に対応します。

# ^ は「最初の親コミット」なので、これはmasterブランチの2番目に新しいコミット
git checkout master^

# これが2つ以上の親を持つマージコミットなら、これは2番目の親を取得
git checkout master^2

# 3回 ^ を繰り返すのと同じ。「最初の親」を3回さかのぼる
git checkout master~3

# 1日前の最初のコミット
git checkout master@{yesterday}

# 5分前の最初のコミット
git checkout master@{5.minutes.ago}

サポートされているリビジョンのフォーマット全部の一覧はここにあります https://git-scm.com/docs/gitrevisions なんと広範囲に渡るのかと驚きました!

多くのGitコマンドでリビジョンが使えることを覚えておきましょう。例えば git log master@{10.days.ago}..master を試してみましょう。

使ってみよう!

私の .gitconfig から始めるか、あるいはそれを自分のカスタマイズの手がかりに使ってみましょう。私がやったようにディーブダイブすることもできます。コマンドリストオプション一覧はとてもためになります。

Gitが最大限便利になるようにしましょう。Gitをゆるく使うと、辛いバグや現実のマージコンフリクトの余地を残してしまいます。さあ調べてみましょう!


その他の参考になる資料 :

次の記事
MySQL 8.0 : クエリーキャッシュのサポート終了
前の記事
MySQL 8.0のGROUPING関数(MySQL Server Blogより)

Feed small 記事フィード