とほほのGit入門

目次

インストール

# yum -y install git		# CentOS 7
# dnf -y install git		# CentOS 8
# sudo apt install git		# Ubuntu 20.04

Gitの流れ

Gitでファイルを修正するには、下記の手順で行います。

  1. ワーキングツリー(WORK)で実ファイルを修正する
  2. ワーキングツリー(WORK)からステージングエリア(STAGING)、別名インデックス(INDEX)に add する
  3. ステージング(STAGING)からローカルリポジトリ(LOCAL)に commit する
  4. ローカルリポジトリ(LOCAL)からリモートリポジトリ(REMOTE)に push する

コマンド

初期化(init)

init は、新規にリポジトリを作成します。

# 新規にプロジェクトを作成してプッシュする
$ mkdir myapp
$ cd myapp
$ git init
$ vi README.md
$ git add .
$ git commit -m "Start project."
$ git push -u http://gitlab.example.com/yamada/myapp.git main

メインブランチ名には以前は master が使用されていましたが、master / slave などの用語は人権問題的に好ましくないことから main に変更されました。

クローン(clone)

clone は、すでに既存のリポジトリがある状態で、リモートリポジトリをローカルリポジトリに複製します。

# [LOCAL] ←(clone)─ [REMOTE]
$ git clone http://gitlab.example.com/yamada/myapp.git
$ cd myapp

ユーザ名やパスワードを下記の様に指定することもできます。

$ git clone http://username:password@gitlab.example.com/yamada/myapp.git

追加(add)

add は、ワーキングツリーからステージングにファイルやディレクトリを追加します。

# [WORK] ─(add)→ [STAGING]
$ git add .			# カレントフォルダ配下のすべてのワーキングツリーの変更をステージングに加える
$ git add ./sample.py		# 指定したワーキングツリーをステージングに加える

削除(rm)

rm は、ステージングやワーキングツリー上のファイルやディレクトリを削除します。

# [WORK] ─(rm)→ [STAGING]
$ git rm ./sample.py		# ステージングからファイルを削除する

移動(mv)

mv は、ステージングやワーキングツリー上のファイルやディレクトリを移動します。

# [WORK] ─(mv)→ [STAGING]
$ git mv A.txt B.txt		# ステージング上のファイル名を変更する
$ git mv dir1/A.txt dir2	# ステージング上のファイル名を変更する

コミット(commit)

commit は、ステージングの変更をローカルリポジトリに反映させます。

# [STAGING] ─(commit)→ [LOCAL]
$ git commit -m "..."		# ステージングの内容をローカルリポジトリにコミットする
$ git commit -a			# addとcommitをまとめて行う。ただし新規ファイルはaddされない
$ git commit --amend -m "..."	# 直前のコミットのコメントを修正する

プッシュ(push)

push は、ローカルリポジトリの変更をリモートリポジトリに反映させます。

# [LOCAL] ─(push)→ [REMOTE]
$ git push			# ローカルリポジトリの変更をリモートリポジトリにプッシュする

プル(pull)

pull は、リモートリポジトリの変更を、ローカルリポジトリ、ステージング、ワーキングツリーに反映させます。

# [WORK] ← [STAGING] ← [LOCAL] ←(pull)─ [REMOTE]
$ git pull			# リモートリポジトリの変更をローカルリポジトリにプルする

フェッチ(fetch)

fetch は、リモートリポジトリから更新情報のみを取り込みます。

# [LOCAL] ←(fetch)─ [REMOTE]
$ git fetch remote_branch_name	# リモートブランチの更新情報を取り込む
$ git diff origin/main main	# リモートブランチとローカルブランチの差分を表示

マージ(merge)

merge は、他のユーザーが行った変更と、自分の変更をマージします。

$ vi main.c			# main.cを変更する
$ git add ./main.c		# main.cをaddする
$ git commit -m "Change main.c"	# main.cをcommitする
$ git push			# main.cをpushする
error: failed to push some refs to 'http://gitlab.example/foo/myapp.git'	# エラーが出る
$ git fetch			# 他ユーザの変更をフェッチする
$ git merge			# マージしてみる
CONFLICT (content): Merge conflict in main.c	# main.cがコンフリクトしている
$ vi main.c			# main.cの内容を見てみる
// main
int main(int argc, char **argv) {
<<<<<<< HEAD
    printf("HELLO world!\n");	# 自分の変更
=======
    printf("hello WORLD!\n");	# 他ユーザの変更
>>>>>>> refs/remotes/origin/develop/v1.1
}
$ git add ./main.c		# 再度addして
$ git commit -m "..."		# commitして
$ git push			# pushする

差分表示(diff)

diff は、コミットやブランチの差分を表示します。beforeafter も省略した場合はステージングとワーキングツリーの差分、after を省略した場合は、ワーキングツリーとの差分を表示します。ただし、add されていない新規ファイルは比較の対象になりません。HEAD はローカルリポジトリの中の最新コミット、HEAD^ はひとつ前のコミット、origin/main は最後にリモートリポジトリと同期(push, pull, fetch)した時点のコミットを示します。

$ git diff			# [WORK]と[STAGING]の差分
$ git diff --staged		# [STAGING]と[LOCAL(HEAD)]との差分
$ git diff --cached		# [STAGING]と[LOCAL(HEAD)]との差分
$ git diff HEAD			# [WORK]と[HEAD]の差分
$ git diff before		# [WORK]と[LOCAL(before)]の差分
$ git diff before --staged	# [STAGING]と[LOCAL(before)]の差分
$ git diff before..after	# [LOCAL(before)]と[LOCAL(after)]の差分
$ git diff before after		# [LOCAL(before)]と[LOCAL(after)]の差分
$ git diff HEAD^..HEAD		# [ひとつ前のコミット(HEAD^)]と[最新コミット(HEAD)]の差分
$ git diff HEAD^		# [ひとつ前のコミット(HEAD^)]と[WORK]の差分
$ git diff f671fbe 8c2d235	# [コミット(f671fbe)]と[コミット(8c2d235)]の差分
$ git diff f671fbe HEAD		# [コミット(f671fbe)]と[HEAD]の差分
$ git diff f671fbe		# [コミット(f671fbe)]と[WORK]の差分
$ git diff origin/main HEAD	# [origin/main]と[LOCAL(HEAD)]の差分
$ git diff origin/main --staged # [origin/main]と[STAGING]の差分
$ git diff origin/main	        # [origin/main]と[WORK]の差分
$ git diff branchA..branchB	# ブランチ間の差分
$ git diff --name-only		# ファイル名のみ表示

リストア(restore)

restore は、Git 2.23 で checkoutrestoreswitch に分離されてできたコマンドで、ステージング上のファイルをワーキングツリーにリストアします。

# [WORK] ←(restore)─ [STAGING]
$ git restore file.txt		# ステージング上のファイルをワーキングツリーにリストアする

リセット(reset)

reset は、commitadd の取り消しを行います。--hard はステージングもワーキングツリーも戻します。--soft は HEAD のみを変更します。

$ git reset --hard HEAD^	# HEADとSTAGINGとWORKをひとつ前のコミット状態に戻す(commit取り消し)
$ git reset HEAD^		# HEADとSTAGINGをひとつ前のコミット状態に戻す。WORKはそのまま
$ git reset --soft HEAD^	# HEADをひとつ前のコミット状態に戻す。STAGINGとWORKはそのまま
$ git reset --hard HEAD		# STAGINGとWORKを最後のコミット状態に戻す。HEADはそのまま(編集取り消し)
$ git reset			# STAGINGを最後のコミット状態に戻す。WORKとHEADはそのまま(add取り消し)
$ git reset --hard f671fbe	# HEADとSTAGINGとWORKをコミット(f671fbe )状態に戻す
$ git reset file		# 特定のファイルやディレクトリに対してのみリセットする

チェックアウト(checkout)

checkout は、ブランチを作成したり、切り替えたり、ブランチからファイルを取り出したりするのに使用します。仕様が複雑になってきたため、2019年8月リリースの Git 2.23 からは、switchrestore に分離されました。

$ git checkout -b new_branch	# ブランチを作成する(古い書き方)
$ git switch -c new_branch	# ブランチを作成する(新しい書き方)
$ git checkout branch		# ブランチを切り替える(古い書き方)
$ git switch branch		# ブランチを切り替える(新しい書き方)
$ git checkout file		# WORKのファイルをSTAGING状態の内容に戻す(古い書き方)
$ git restore file		# WORKのファイルをSTAGING状態の内容に戻す(新しい書き方)

ブランチ(branch)

branch は、ブランチの一覧を表示します。ブランチの切り替えには switch を使用します。リモートのブランチ名を変更したい時は、一度リモートブランチを削除してから、名前変更後のブランチをプッシュします。

$ git branch new_branch		# ローカルリポジトリにブランチを作成する
$ git switch -c new_branch	# ローカルリポジトリにブランチを作成する(新しい書き方)
$ git checkout -b new_branch	# ローカルリポジトリにブランチを作成する(古い書き方)
$ git push -u origin branch	# 新ブランチをリモートリポジトリにプッシュする
$ git branch			# ブランチの一覧を表示する
$ git switch branch		# ブランチを切り替える(新しい書き方)
$ git checkout branch		# ブランチを切り替える(古い書き方)
$ git branch -d branch		# ローカルブランチを削除する
$ git branch -m old new		# ローカルブランチ名を変更する
$ git push -d origin branch	# リモートブランチを削除する

スイッチ(switch)

switch は、2019年8月リリースの Git 2.23 で、checkoutswitchrestore に分離してできたコマンドです。ブランチを作成したり切り替えたりします。

$ git switch -c new_branch	# ローカルリポジトリに新しいブランチを作成する
$ git switch branch		# 別のブランチに切り替える

タグ(tag)

tag は、ブランチのコミット位置にタグをつけます。正式リリースしたポイントにマーク付けを行う場合などに用いられます。

$ git tag -a tagname -m "msg..."	# 現在のコミット位置にタグをつける
$ git tag -a "v1.1" -m "Ver 1.1"	# 現在のコミット位置に "v1.1" という名前のタグをつける
$ git push origin tagname		# タグ情報をリモートリポジトリにプッシュする
$ git remote add origin url		# pushでoriginが見つからないエラーが出る時はこれを実行

オリジン(orgin)

orgin は、http://gitlab.example.com/foo/myapp.git などの URL につける別名のようなものです。デフォルトの名前として origin が使用されます。

$ git remote -v			# オリジンの一覧を表示する
$ git remote add origin url	# オリジンを作成する

コンフィグ(config)

config は、Git に関する様々なパラメータを設定・参照します。

$ git config --list
$ git config {key} {value}
$ git config --global {key} {value}
$ git config --system {key} {value}
$ git config --global user.name "ユーザ名"	# ユーザ名を設定する
$ git config --global user.email "メールアドレス"	# メールアドレスを設定する
$ git config --global color.ui auto		# カラーリングを有効化する
$ git config --global core.quotepath false	# 日本語ファイル名をそのまま表示する
$ git config --global core.safecrlf true	# 改行コードが混在していても変換しない
$ git config --global core.autocrlf false	# チェックアウト時に改行コードを変更しない
$ git config core.ignorecase false		# ファイル名の大文字・小文字を無視しない
$ git config --global core.editor vi		# コミットする際に使用するエディタを指定する
$ git config --global alias.co checkout		# エイリアス(co=checkout)を設定する
$ git config --global credential.helper cache	# ID/PWを900秒間メモリにキャッシュする
$ git config --global credential.helper store	# ID/PWをファイル($HOME/.git-credentials)にキャッシュする
$ git config --global --add merge.ff false	# merge --no-ffをデフォルトにする

ステータス(status)

status は、Git に関するステータス情報を表示します。

$ git status		# 差分情報などのステータスを表示
$ git status -s		# 簡易形式で表示

簡易形式で表示した場合、先頭に A(addが必要)、D(deleteが必要)、M(modifyが必要)が表示されます。1カラム目はローカルリポジトリ(HEAD)とステージング(STAGING)の差分、2カラム目はステージング(STAGING)とワーキングツリー(WORK)の差分を示します。

A  fileA.txt		# ローカルリポジトリに追加が必要
D  fileB.txt		# ローカルリポジトリから削除が必要
M  fileC.txt		# ローカルリポジトリに変更が必要
 A fileD.txt		# ステージングに追加が必要
 D fileE.txt		# ステージングから削除が必要
 M fileF.txt		# ステージングに変更が必要

ログ(log)

log は、コミット履歴を表示します。

$ git log		# コミット履歴を表示
$ git log -p		# ファイルの修正内容も表示
$ git log -2		# 直近の2件のみ表示
$ git log --oneline	# 1行1履歴で表示
$ git log --follow file	# 特定ファイルのログを見る

ショウ(show)

show は、コミットの詳細を表示します。

$ git show f671fbe			# コミット(f671fbe)の詳細を表示する

スタッシュ(stash)

stash は、現在改造中の変更を中断して一時的に退避し、別の変更をコミットしてから、元の作業に戻りたい場合に使用します。

$ git stash save		# 現在の変更を一時的に退避する
$ git stash list		# 退避したスタッシュの一覧を表示する
$ git stash pop			# 退避していたスタッシュを元に戻す
$ git stash drop		# 退避していたスタッシュを消す
$ git stash apply stash@{0}	# 指定しスタッシュを元に戻す
$ git stash drop stash@{0}	# 指定したスタッシュを消す

ヘルプ(help)

help は、ヘルプやマニュアルを表示します。

$ git --help		# gitのヘルプを表示
$ git help -a		# すべてのサブコマンドを表示
$ git command -h	# コマンドのヘルプを表示
$ git help command	# コマンドのマニュアルを表示

.gitignore

.gitignore ファイルには、Git で無視したいファイルを列挙します。各ディレクトリに配置することができ、file はそのディレクトリ配下すべてのファイルにマッチ、/file は、そのディレクトリ内のファイルにマッチします。

# Gitで管理したくないファイルを列挙
$ vi .gitignore
*.bak		# カレントディレクトリ以下のすべての *.bak を無視
/TODO.txt	# カレントディレクトリの TODO.txt を無視
/tmp/		# カレントディレクトリのtmpフォルダを無視

featureブランチ

本番用ブランチ(main)から、開発用ブランチ(develop)を分岐し、さらに各機能毎の機能ブランチ(feature-xxx)を分岐させて開発することがあります。まず、次のようにして develop ブランチを clone し、さらに feature-xxx ブランチを作成します。

$ git http://gitlab.example.com/foo/myapp.git -b develop
$ cd myapp
$ git branch feature-103		# feature-xxxブランチを作成する
$ git switch feature-103		# feature-xxxブランチに移動する
$ git push -u origin feature-103	# feature-xxxブランチをプッシュする

feature-xxx ブランチの中で改造を行っていきます。

$ vi main.c				# ソースを改修する
$ git add ./main.c			# ソースをaddする
$ git commit -m "..."			# ソースをcommitする
$ git push				# ソースをpushする

完成したら、feature-xxx ブランチを、develop ブランチにマージして、feature-xxx ブランチを削除します。

$ git switch develop			# developブランチに移動する
$ git merge feature-103			# feature-xxxブランチをマージする
$ git pull				# リモートのソースをpullする
$ ...					# コンフリクトが発生していたら修正してadd/commitする
$ git push				# developブランチをプッシュする
$ git branch -d feature-103		# ローカルのfeature-xxxブランチを削除する
$ git push -d origin feature-103	# リモートのfeature-xxxブランチを削除する