水底

ScalaとかC#とかネットワークとか

Gitで気をつけるべき設定

大体デフォルトで問題ないが, 気をつける必要がある設定がいくつかあるのでメモ.

f:id:amaya382:20170326024520p:plain

.gitconfig > .core

autocrlf

改行コードにまつわる設定. 設定によっては「リポジトリ上だけLF」といったことができる, が, 複数人が利用する以上色々混じる可能性は払拭できず, コレ!と断言できる設定がない.

周辺設定項目として safecrlfeol がある.

詳細は↓とか参照

qiita.com

ignorecase

ファイル名の大文字小文字を区別するかどうかの設定. デフォルトが true なので, false にしてやらないと大文字小文字のリネームで面倒なことになる. この設定は常に false で良いと思う.

filemode

ファイルのパーミッションを扱うかどうかの設定. 基本はデフォルトの true で問題ないが, Windows環境が混じると厄介. Windowsの場合のみ false にして, 権限を弄りたい場合 (+x とか) のみ手動で git update-index --add --chmod=... するのが無難かな?

タイムスタンプ周り

あまりお目にかかる機会がないかもしれないがGitのCommitに記録されているタイムスタンプは2種類ある (git log --pretty=fuller で確認できる). 一つは AuthorDate という基本的には不変のタイムスタンプで, 例えば git commit --amend しても変わらない. もう一つが CommitDate でCommit内容が変更されると常に更新される. この2つの違いが厄介で, 何気なく git commit --amend などをしてしまうと, タイムスタンプの乖離が発生する. これに起因するよくある問題として, 実際のコミットの前後関係とタイムスタンプ情報が一致せず, Gitのネットワーク図が意図しない形になる場合がある. 「それじゃあ最初からタイムスタンプは一つでいいじゃん!」と思うかもしれないが, Author(作成者) と Commit(編集者) には意味があり, 例えばGitHub上でのMergeの A committed with B といった部分は Author(A) と Commit(B) を利用して実現されている.

解決のための設定

git commit --amend

git commit --amend --date=now とする. これで CommitDateAuthorDate の両方がamend時のタイムスタンプに更新される.

git rebase

  • AuthorDate維持したい 場合
    git rebase を使う目的は「過去の特定コミットメッセージを修正したい」や「一部のコミットをまとめたい」といったものであることが多く, つまりは オリジナルのタイムスタンプを変更したくない 場合が多いだろう. そのような場合は以下の手順でオリジナルのタイムスタンプ (AuthorDate) にする.
  1. 普通に git rebase ... を行う. interactiveでもそうでなくても.
  2. git rebase --committer-date-is-author-date ${遡るCommit, HEAD~1とか}

1.で一旦は CommitDateAuthorDate がズレるものの, 2.で CommitDateAuthorDate に修正される. なお, rootのCommitだけはこの方法で修正できないため, 別途以下の手順を踏む.

  1. git rebase -i --root でrootのCommitのみを edit(e) にする
  2. rootのCommitの AuthorDate を手動で取得してきて GIT_COMMITTER_DATE='ここにAuthorDate' git commit --amend を実行
  3. 最後に git rebase --continue
  • AuthorDate捨てて良い 場合 あまり使う場面がないと思われるが, git rebase --ignore-date ... とすることで AuthorDateCommitDate に追従させることができる.