Git の使い方

2017.01.30

Gitに慣れるには,実践あるのみです.実際に,あなたのアカウントで testレポジトリを作成して,Gitコマンドを自らの手で召喚すべし.

あなたのPCに這いよるGit

まず,WindowsでGitを使うとか拷問でしか無いのでLinuxを入れるかMacを買います.

次に,端末を開きます.GUIでもいいかどうかは判断が別れますが,個人的にはCLIの ほうがいいよ.

次に,ユーザ名などを設定する

git config --global user.name "username"
git config --global user.email "username@users.noreply.github.com"
git config --global core.autocrlf false

設定ファイル(~/.gitconfig)を直接いじっていいです. 詳しくはdotfiles/.gitconfig at master · noyuno/dotfilesを参照のこと.

基本的な流れ

Gitが使えない人は,大抵の場合,流れを押さえていないことが多いです. 流れをつかめば息をするように操れます.

  1. cloneまたはfetchまたはpull: リモートサーバから履歴を取得.
  2. checkout name : ワーキングブランチを切り替える.
  3. merge master : masterブランチをワーキングブランチに取り込む.
  4. ファイルを編集する.
  5. add : 変更されたファイルをStageに追加する.
  6. commit : Stageされたファイルをコミットして,履歴を作成する.
  7. push : リモートサーバに履歴を送る.

各コマンドについては,上のリンク先の文書を参照のこと. これより下は,上のコマンド以外で重要なコマンドや動作を紹介します.

現在の状態を知るには

間違ってコミットしないためにも,現在どんな状態かを知る必要があります.

  • status : ワーキングブランチの状態を出力
[noyuno@ld ~/_posts] $ git status
On branch master # ブランチ名
Your branch is up-to-date with 'origin/master'. # このブランチは'origin/master'と比べて何コミット異なるか
Untracked files: # Stageされていないファイル
  (use "git add <file>..." to include in what will be committed)

        2017-01-30-git.md

nothing added to commit but untracked files present (use "git add" to track)
  • remote -v : リモートサーバのアドレスを出力
origin  git@github.com:noyuno/blog.git (fetch)
origin  git@github.com:noyuno/blog.git (push)
  • branch : 現在のブランチ名と他のブランチ名を取得
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/kramdown-and-rouge
  remotes/origin/master
  • diff : Stageされたファイルが既にコミットされていれば,それらの間の差分を出力

履歴を見る

  • log --graph --date=short --decorate=short --pretty=format:'%Cgreen%h %Creset%cd %Cblue%cn %Cred%d %Creset%s': 視覚的に見る
* 9553b9d 2016-12-09 noyuno  Update
* 8b0af42 2016-06-08 Erin Grand  Update _svg-icons.scss
*   6b52dbb 2016-04-10 Erin Grand  Merge pull request #478 from nscyclone/a-typo-fix-in-readme
|\
| * 53140f1 2016-04-06 nscyclone  Fixed a typo in 'README.md'.
|/
* fc5731a 2016-03-07 Barry Clark  Jekyll 3 message at top of readme :sparkles:
* da13f8d 2016-03-07 barryclark  (tag: v1.2.0) Tagging v1.2.0 :sparkles:
*   8970045 2016-03-06 Barry Clark  Merge pull request #373 from yzyzsun/patch-1
|\
| * 895b2fd 2016-01-04 Sun Yaozhu  Add .jekyll-metadata to .gitignore

間違えたとき

  • 間違えて編集しちゃった:git checkout .
  • ブランチを切り替えずに変更しちゃった:
    • HEADが同じ:git checkout <branch>でそのまま,編集した後で git checkout master && git checkout .
    • HEADが異なる:
git stash
git checkout <branch>
git stash pop
  • 間違えてaddしちゃった:reset
  • 間違えてcommitしちゃった:
    • 直前にしたコミットをやり直す:ファイルを編集後commit --amend
[noyuno@ld ~/test] $ git status
On branch master

最初のコミット

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        a

nothing added to commit but untracked files present (use "git add" to track)
[noyuno@ld ~/test] $ git add .
[noyuno@ld ~/test] $  git commit -m a
[master (root-commit) 0f1eec8] a
 1 file changed, 1 insertion(+)
 create mode 100644 a
[noyuno@ld ~/test] $ vi a
[noyuno@ld ~/test] $ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   a

no changes added to commit (use "git add" and/or "git commit -a")
[noyuno@ld ~/test] $ git add .
[noyuno@ld ~/test] $ git commit --amend
[master 6a62240] ab
 Date: Mon Jan 30 13:44:13 2017 +0900
 1 file changed, 2 insertions(+)
 create mode 100644 a
[noyuno@ld ~/test] $ git logcommit 6a62240df1e63360cc2395030744a377c2647b69
Author: noyuno <noyuno@users.noreply.github.com>
Date:   Mon Jan 30 13:44:13 2017 +0900

    ab
  • コミット自体を取り消す:git reset --soft
[noyuno@ld ~/test] $ git log # 初期状態
commit 6a62240df1e63360cc2395030744a377c2647b69
Author: noyuno <noyuno@users.noreply.github.com>
Date:   Mon Jan 30 13:44:13 2017 +0900

    ab
[noyuno@ld ~/test] $ vi a # 編集
[noyuno@ld ~/test] $ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   a

[noyuno@ld ~/test] $ git add .
[noyuno@ld ~/test] $ git commit -m c # コミット(このあとこれを取り消す)
[master fada7dc] c
 1 file changed, 1 insertion(+)
[noyuno@ld ~/test] $ git log
commit fada7dc209225246a89ea7cf59e64ce5af62a0bc
Author: noyuno <noyuno@users.noreply.github.com>
Date:   Mon Jan 30 13:49:25 2017 +0900

    c

commit 6a62240df1e63360cc2395030744a377c2647b69
Author: noyuno <noyuno@users.noreply.github.com>
Date:   Mon Jan 30 13:44:13 2017 +0900

    ab
[noyuno@ld ~/test] $ git reset --soft 'HEAD^' # 最新のコミットを取り消す
[noyuno@ld ~/test] $ git log # 履歴を見ると取り消されたことがわかる
commit 6a62240df1e63360cc2395030744a377c2647b69
Author: noyuno <noyuno@users.noreply.github.com>
Date:   Mon Jan 30 13:44:13 2017 +0900

    ab
[noyuno@ld ~/test] $ git status # 変更がStagedに入る
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   a
  • 間違えてpushしちゃった:他の人が既に参照した可能性があるため,履歴の修正はしないほうが良い

その他

.gitignoreを使う

.gitignoreを使えば,履歴に含めたくないファイルを設定できます. 例:dotfiles/.gitignore at master · noyuno/dotfiles

バイナルファイルはGitに入れるのに適さない(大量に入れると各種コマンドが重くなるのと 圧縮できず,履歴のサイズが大きくなる)ため, 履歴に含まないほうが賢明です.(Git LFSを使う手もある)

既にコミットされたファイルは,.gitignoreに追加しただけでは意味がないので, git rm --cached <name>を使ってファイル削除の事実を作成します.

hub を使う

hubコマンド github/hub: hub helps you win at git. でGitHubのブラウザでの操作をCLIで実現できる.

  • hub pull-request: pushしたこのブランチからPull requestできる,

発展

Linuxの開発のために生まれたバージョン履歴ツールGitは,テキストファイルの編集において,様々な場面で効率的な開発が可能です.

Git を使えば,TeXで作成したレポートを保存したり,他のパソコンから参照したりすることができます. さらにGit LFSでPDFなどのバイナリファイルをかっこ良く扱えます.

また,GitHub Pagesで静的サイトやブログを作ることもできます.このブログがそうです.

また,dein対応のVim/Neovimプラグインを簡単に作成できます.

そして,Unix Likeの設定ファイル(通称dotfiles)をリポジトリにまとめておけば, 複数のパソコンの間で同期をすることができます.

Git のalternativesとしてMercurialがあります.興味があれば調べてみてはいかがでしょうか?


新しい記事: IntelliJ IDEA/EclipseでGit 2017.02.01
古い記事: 電光掲示板を再現する 2017.01.01