マニュアル: Git

投稿日: 更新日:

最新版のインストール方法(RHEL, CentOS)

IUSの提供するリポジトリを使うのが早いです。

CentOS 6の場合は以下のようになります。

yum install https://centos6.iuscommunity.org/ius-release.rpm
yum install git2u

古いバージョンのGitが入っている場合は、以下のようにコンフリクトします。

Error: git2u conflicts with git-1.7.1-9.el6_9.x86_64 Error: git2u-perl-Git conflicts with perl-Git-1.7.1-9.el6_9.noarch Error: git2u-core conflicts with git-1.7.1-9.el6_9.x86_64

この場合は、エラーが出たパッケージを削除してからインストールしてください。

rpm -e git perl-Git
yum install git2u

入れておくとよい設定

会社とプライベートで分ける

v2.13.0から有効なようです。

名前、メールアドレスの設定

メールアドレスがプロジェクトによって違う場合は、 名前だけでも構いません。

git config --global user.name "Hideki Ikemoto"
git config --global user.email "ikemo333@gmail.com"

カラー表示

git config --global color.ui auto

日本語ファイル名をそのまま表示したい

core.quotepathを設定する。

git config --global core.quotepath false

エディタの設定(CentOS)

CentOS 7では、デフォルトでviがエディタとして使われている。

git var GIT_EDITOR

通常viコマンドを打つとvimが起動するが、 この定義はaliasにすぎないため、 デフォルトだと/usr/bin/vi(Small版1])が起動する。

vim-enhanced(Huge版)を有効にするためには、以下のように設定する。

git config --global core.editor vim

bash

パスは環境による。

# 補完設定。
source /usr/local/etc/bash_completion.d/git-completion.bash

# プロンプト設定
source /usr/local/etc/bash_completion.d/git-prompt.sh

# 変更されたファイルの表示(`*`: unstaged、`+`: staged)
GIT_PS1_SHOWDIRTYSTATE=true

# アップストリームとの違い(`=`: 同じ、`>`: ahead, `<`: behind, `<>`: diverged)
GIT_PS1_SHOWUPSTREAM=true

# 新規ファイルの存在(`%`で表示)
GIT_PS1_SHOWUNTRACKEDFILES=true

# スタッシュの存在(`$`で表示)
GIT_PS1_SHOWSTASHSTATE=true

# 色付きで表示(要調査・・・)
GIT_PS1_SHOWCOLORHINTS

基本的な流れ

masterからdevelブランチを切って作業する場合の大まかな手順です。

  1. ブランチを作成&移動: git checkout -b devel
  2. ブランチで作業
  3. 必要ならsquash
  4. masterにマージ
    1. git checkout master
    2. git merge devel
      • --no-ffを付けない場合、可能ならばfast-forwardを使います。

クローン(git clone)

git clone <URL>

最新の履歴だけ取得するには、 git clone --depth 1 <URL> のようにする。

取得(git fetch / git pull)

  • リモートで消されたブランチを削除する: git fetch --prune

コミット(git commit)

コミットメッセージ

この記事が参考になります。

ただ、参照しているAngularJSは1.xのもので、Angular (2.x以上のことを指す)の方が良さそうです。

<type>(<scope>): <subject>

<body>

<footer>
  • type:
    • build: ビルドシステムや外部ライブラリの変更
      • .gitignoreもこのtypeが使われている模様。
    • ci: CI設定やスクリプトの変更
    • docs: ドキュメントのみの修正
    • feat: 機能追加
    • fix: バグ修正
    • perf: パフォーマンスの改善
    • refactor: リファクタリング(機能追加でもバグ修正でもない)
    • release: リリース(Angularのドキュメントには記載がないが、logより)
    • style: コードに影響しない変更
    • test: テストの追加修正
  • scope: 影響範囲(オプション)
    • これはプロジェクトによるが、Angularではnpmのパッケージ名を使用している。
    • 例外は以下の通り。
      • packaging: package.json, d.tsなど全てのパッケージに影響するもの
      • changelog: CHANGELOG.md
      • docs-infra: ドキュメント作成ツール(静的サイトジェネレータ)に関連するもの
      • ivy: 新レンダリングエンジンIvyに関するもの
      • ngcc: Angular Compatibility Compilerに関するもの
      • なし: 全てのパッケージで行われるスタイル、テスト、リファクタリング、特定のパッケージに関連しないドキュメントの変更
  • subject
    • 現在形、命令形を使用
    • 最初の文字を大文字にしない。
    • .で終わらない
  • body
    • subjectと同じく、現在形、命令形を使用
    • 詳細を書く(変更のモチベーションなど)
  • footer: 以下のものを書く
    • クローズするチケットの番号
    • BREAKING CHANGE:(破壊的な変更、互換性に影響があるもの)

実行権限の追加(update-index)

git update-index --chmod=+x

クリーン(git clean)

必ず-i, -n, -fのいずれかのオプションが必要。 gitの他の多くのコマンドと違って、取り返しがつかなくなるから。

  • -n: 何が起きるかの表示のみ(dry-run)
  • -f: 削除の実行
  • -i: インタラクティブモード

その他オプション。-xと-Xの違いはまだ良くわかってません。。。

  • -d: ディレクトリも削除
  • -x: .gitignoreなどのファイルを無視。つまり、無視されているファイルも削除対象。
  • -X: Gitが無視しているファイルのみ削除。

リセット(git reset)

  • soft: コミットのみ取り消し
  • mixed: インデックスへの登録を取り消し
  • hard: 作業ツリーも取り消し

softはあまり使わないかも。mixed(デフォルト)か、hardがほとんどか。

リモートに強制的に合わせたい場合

リモートが正しいので強制的に合わせたいとき。 --hardなので当然ローカルの変更は破棄されるのに注意。 あとコメントも書いてますが、当然master以外の場合は変更する。

git fetch

# masterの場合
git reset --hard origin/master

チェックアウト(git checkout)

  • ブランチの切り替え2: git checkout <ブランチ名>
    • 自動的に追跡ブランチが作成されることもあります3
  • ブランチを作成しつつ切り替え: git checkout -b <ブランチ名>

ブランチ(git branch)

  • 上流ブランチ(upstream branch)を表示: git branch -vv(vを2つ並べる)
  • リモート追跡ブランチ(remote-tracking branches)を表示: git branch -r
  • ブランチを削除: git branch -d <ブランチ名>

1ファイルだけ別のブランチから取得

Git 1ファイルだけ別のブランチから持ってくる - Qiita

以下のようにする。

git show ブランチ名:ファイル名

つまみ食い(git cherry-pick)

特定のコミットのみ適用する機能。

マージが入るとそのままではうまくいかない。 以下のようにする必要がある。

タグ(git tag)

タグの削除

git tag delete タグ名
git push origin :refs/tags/タグ名

差分(git diff)

ブランチ間のファイルの差分を表示するときは以下のようにする。 ワークスペースのファイルを指定するときはブランチ名をつけない。

git diff ブランチ名:ファイル名 ブランチ名:ファイル名

ログ(git log)

特定のコミットのみ出力するには以下のようにする。

HASH=xxxx
git log ${HASH}
  • 表示オプション
    • --graph: ツリーをグラフ表示
    • --decorate: ブランチ名、タグ名などを表示
    • --oneline: 1コミット1行表示
    • --stat: 変更行数の表示(人間に読める形式)
    • --numstat: 変更行数の表示(プログラム処理用)
      • 表示形式は「追加行数」「削除行数」「ファイル名」の順
    • --date=フォーマット: 日時の表示形式を変更(strftime形式)
      • 例: --date=format-local:'%Y-%m-%d %H:%M:%S' : ローカルタイムゾーンで YYYY-MM-DD hh:mm:ss 形式で表示される。
      • 常に設定する場合は git config log.date フォーマット のようにする。
  • パッチ形式で出力: git log -p
  • 差分を検索4: git log -S<検索文字列>

リモート(git remote)

  • リモートリポジトリの変更: git remote set-url <name> <newurl>
    • 通常<name>はoriginになる。

リベース(git rebase)

  • Git - リベース

  • Git - git-rebase Documentation

  • experimentブランチを、masterの先頭に適用したい場合

    1. 変更したいブランチをチェックアウト(例: git checkout experiment)
    2. 元となるブランチにリベース(例: git rebase master)
      • 単にgit rebase master experimentで良いみたいです。
  • serverブランチから派生したclientブランチの変更点を、masterの先頭に適用したい場合

    • git rebase --onto master server client

一時退避(git stash)

  • 追加: git stash
    • git stash push または git stash save も同じ。
    • git stash push は古いバージョンで使えないことがある(1.8.3.1ではなかった)。
    • git stash save は現在は非推奨になっている(2.16.2で確認)。
    • -u: 未追跡のファイルも対象とする。
    • -a: 全てのファイルも対象とする(ignore対象のものも)。
  • 一覧: git stash list
  • 詳細表示: git stash show
  • 適用: git stash apply
  • 適用 & 削除: git stash pop
  • 削除: git stash drop

検索(git grep)

Git - git-grep Documentation

  • -e: 基本正規表現
  • -E: 拡張正規表現(+などが使える)

制御コードを検索

例: キャリッジリターンを検索したい場合

git grep -n $'\r' *.yaml

サブモジュール(git submodule)

追加

git submodule add <repository> <path>

内部でやっていると思われること。

  1. リポジトリをclone
  2. リポジトリの情報を.gitsubmoduleに書き込む。
  3. リポジトリのハッシュをどこかに書き込む。

cloneはちょっとだけ特殊です。

  • cloneしたリポジトリ以下の.gitはただのファイルっぽい
    • 中身を見ると、本物の.gitのパスが書き込まれている。
    • そのパスは、git submoduleコマンドを実行した親リポジトリの、.git/module/<path>に書き込まれるようです。
    • .git/module/<path>/configを見ると、core.worktreeに指定があります。

更新

以下のコマンドが簡単です。 --remote--rebaseがついているのがポイント。

git submodule update --remote --rebase

付け忘れたり、コンフリクトした場合は、サブモジュールのディレクトリに行って、 rebaseなりmergeなりすればいいです。

一括作業

以下のように、 git submodule foreach のあとに実行したいコマンドを記入します。

git submodule foreach git status

削除

git submodule deinit path/to/submodule
git rm path/to/submodule # -f必要かも

.git/modules 以下には残るため、手動で削除が必要そうです。

複数の作業ディレクトリ(git worktree)

git worktree add <path> <branch>

.gitignore

git config --global core.excludesfile ~/.gitignore_global
vi ~/.gitignore_global

除外設定は以下の場所から取得するのが良い。

gibo

基本的にはgiboで自動生成が良いようです。

インストールはHomebrewの場合は以下のようにします。

brew install gibo

例えば、Javaの場合は以下のようにします。

git Java >> .gitignore

対応している言語・ツールはgibo -lで表示できますが、 (自分が)よく使うものは以下になります。

  • Ansible
  • Gradle
  • Java
  • JetBrains
  • Node
  • Ruby
  • Vagrant

グローバルで書く vs リポジトリに格納

基本は以下の判断基準でいいと思います。

gitignore に書くべきでないものは gitignore_global へ - Qiita

github/gitignore にあるか github/gitignore - Global にあるかで判断

github/gitignoreによると、 だいたい以下のように分かれているようです。

  • グローバル
    • OS(macOS, Windows, Linuxなど)
    • IDE(Eclipse, JetBrains, NetBeans, JDeveloper, Xcodeなど)
    • エディタ(Vim, Emacs, Kateなど)
    • オフィス(Microsoft Office, LibreOfficeなど)
  • それ以外(リポジトリにコミットすべきもの)
    • プログラミング言語
    • ビルドツール(Gradle, Mavenなど)
    • フレームワーク(Railsなど)

ただ、Visual Studioはグローバルではありません。 ツールの性質によるのか、他の理由なのかは謎です。

また、必ずしもこれを守らないといけないわけではないです(のはず)。 例えば、IDEの設定はリポジトリにあってもいいと思います。

属性(gitattributes)


  • 設定する場所は以下のどちらか(複数形)。
    • .git/info/attributes
    • .gitattributes
  • チェックアウト/チェックイン時に影響
    • text: テキストとして扱う。
      • EOFの扱いが制御できる。例: *.c text
      • デフォルトはcore.eol, core.autocrlfに影響
      • 値にautoを付けると、Gitがテキストファイルだと認識したものに対し、LFに変換します。しかし、CRLFでコミットされたら、変換しません。。。と書かれてますが意味が分かりません(結局テキストファイルでCRLFでコミットしたらどうなるのか。最初にコミットしたときの状況次第か?)。
    • eol: 改行コード
      • いろいろありますが意味がわからんので後で調査。
    • ident: $Id: をオブジェクト名に変換
    • filter
      • clean: チェックイン時のコマンド
      • smudge: チェックアウト時のコマンド
        • ちなみにsmudgeは「汚す」という意味です。cleanの逆ですね。

暗号化

ツール

ghqは別ページにまとめました。

git-open

git open でGitHubなどを開くツール。

インストールは npm install --global git-open とする。 Homebrewにあるのは別物(未調査)。

Subversion連携

独立した記事にしました。

Git: Subversion連携


  1. Vim参照。 ↩︎

  2. Subversionだとsvn switchなので慣れないときはよく忘れました。 ↩︎

  3. Git - リモートブランチに『チェックアウトしたいブランチ名が(a)まだローカルに存在せず、(b)存在するリモートは1つだけ、の場合、Gitは自動的に追跡ブランチを作ってくれるのです。』と書かれています。 ↩︎

  4. git logでコミットの差分の中身で絞り込む - Qiita ↩︎

公式サイト

外部サイト

逆引きマニュアル