Git 教學

https://git-scm.com/

Git 教學

安裝篇

下載Git

https://git-scm.com/downloads

  1. 安裝過程 next下一步到底。
  2. 安裝完成之後,可以找到 「Git Bash」

檢查是否安裝成功

1
$ git --version

設定篇

建立目錄讓Git管理

1
$ git init

設定ssh key

查看ssh key
1
$ ls -al ~/.ssh

一般預設的公共密鑰文件為下列其中之一:

  • id_dsa.pub
  • id_ecdsa.pub
  • id_ed25519.pub
  • id_rsa.pub
產生ssh key
1
$ ssh-keygen -t rsa -b 4096 -C "GitHub email address"

設定 SSH Key 密碼

複製ssh key
1
$ cat ~/.ssh/id_rsa.pub | pbcopy
測試ssh
1
$ ssh -T git@github.com

使用者設定

設定使用者的名稱與電子信箱,不然每次commit都要輸入一次。

1
2
$ git config --global user.name "UserName"
$ git config --global user.email "UserName@email.com"

查看git config 設定

1
$ git config --list

進階用法:不同的專案設定不同的作者

a.切到該專案目錄

1
2
$ git config --local user.name "UserName"
$ git config --local user.email "UserName@email.com"

c.設定之後這個專案目錄就會跑local的設定檔,離開這個專案還是會跑Global。

更換編輯器: vim -> emacs

1
$ git config --global core.editor emacs

自訂指令:Alias 別名

1
2
$ git config --global alias.l log
$ git config --global alias.lg "log --oneline --graph"

設定之後,輸入 git l 指令就跟 git log 一樣。
設定之後,輸入 git lg 指令就跟 git log --oneline --graph 一樣。

基礎篇

建立 Git 專案

1
$ git init

提交一個 Patch

1
2
3
4
5
$ git status
$ git add <file>
$ git commit
$ git log
$ git show

新增 / 修改檔案

1
2
3
4
5
6
$ git diff
$ git diff <file>
$ git diff --cached
$ git add -A
$ git commit -m <message>
$ git show <commit_id>

刪除檔案

1
2
$ git rm <file>
$ git add -u

搬移檔案

1
$ git mv <file> <directory>

重新命名檔案

1
$ git mv <file> <new_name>

檔案狀態

1
2
3
$ git reset HEAD
$ git reset HEAD <file>
$ git checkout -- <file>

檔案還原

1
2
3
4
$ git checkout -- <file>
$ git reset HEAD
$ git reset HEAD <file>
$ git reset --hard HEAD

忽略檔案 .gitignore

1
$ git add -f <file>

提交空白Patch

1
$ git commit --allow-empty -m "空的"

Patch篇

基本觀念

1
$ git log --pretty=raw

關鍵字 HEAD

1
2
$ git show HEAD^
$ git show HEAD~3

Reset Patch

1
2
3
4
$ git log --oneline
$ git reset HEAD^
$ git reset --hard HEAD^
$ git reset --hard <commit id>

找回消失的 Patch

1
2
$ git reflog
$ git log -g

修改 / 訂正 Patch

1
2
3
4
$ git commit --amend
$ git commit --amend -m <message>
$ git reset --soft HEAD^
$ git reset --soft HEAD@{1}

移除單一個 Patch

1
$ git cherry-pick <commit id>

Rebase 互動模式

1
$ git rebase -i <after this commit>

Cherry-Pick 版本衝突

1
2
$ git cherry-pick --continue
$ git cherry-pick --abort

Rebase 版本衝突

1
2
3
$ git rebase --continue
$ git rebase --skip
$ git rebase --abort

Revert Patch

1
2
3
$ git revert <commit id>
$ git revert --continue
$ git revert --abort

分支篇

查看分支

1
2
$ git branch
$ gitk --all &

建立 / 刪除分支

1
2
3
4
5
6
$ git branch <new branch name>
$ git checkout <branch name>
$ git checkout -b <new branch name>
$ git branch -f <branch name> <commit id>
$ git branch -D <branch name>
$ git log <branch name>

Commit Tree

1
2
$ git checkout <commit id>
$ git checkout -b <new branch name> <commit id>

Rebase 合併分支

1
2
3
4
$ git cherry-pick <commit 1> <commit 2> ...
$ git rebase <new base>
$ git rebase <new base> <branch name>
$ git reset --hard ORIG_HEAD

Merge 合併分支

1
2
$ git merge <branch name>
$ git merge --no-ff <branch name>

遠端篇

新增專案

1
2
ssh-keygen -t rsa
ssh -T git@github.com

設定 Repo URL

1
2
3
4
$ git remote -v
$ git remote add <short name> <repo url>
$ git remote rm <short name>
$ git remote rename <short name> <new name>

上傳分支

1
2
$ git branch -a
$ git push <remote name> <branch name>

設定 Upstream

1
2
3
$ git push -u <remote name> <branch name>
$ git branch -u <remote>/<remote branch>
$ git branch --unset-upstream

複製 / 下載專案

1
2
3
4
$ git clone <repo URL>
$ git clone <repo URL> -b <branch name>
$ git clone <repo URL> <folder name/path>
$ git clone <local project>

同步遠端分支

1
2
3
4
5
$ git fetch <remote name>
$ git fetch --all
$ git remote update
$ git pull
$ git pull --rebase

強制更新遠端分支

1
$ git push -f

刪除遠端分支

1
2
3
4
5
6
$ git push <remote name> :<branch name>
$ git remote show <remote name>
$ git remote prune <remote name>
$ git remote update -p
$ git fetch --all -p
$ git fetch -p

進階篇

檔案暫存

1
2
3
4
5
6
7
$ git stash
$ git stash list
$ git stash pop
$ git stash pop stash@{n}
$ git stash drop
$ git stash drop stash@{n}
$ git stash clear

Add / Checkout 檔案部分內容

1
2
$ git add -p
$ git checkout -p

版本標籤

1
2
3
4
5
6
7
8
9
10
11
$ git tag
$ git tag <tag name> <commit id>
$ git tag -a <tag name> <commit id>
$ git tag -a <tag name> <commit id> -m <msg1> -m <msg2>
$ git tag -a <tag name> <tag name>^{} -f
$ git tag -d <tag name>

$ git push <remote name> <tag name>
$ git push <remote name> --tags
$ git push <remote name> :<tag name>
$ git push -f <remote name> <tag name>

子模組

1
2
3
4
$ git submodule init
$ git submodule update
$ git submodule add <repo url> <project path>
$ git clone --recursive <repo URL>

心得

每次git commit都會產生一個Patch,

git rebase 整理Patch會改變Hush值

git reset https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified.

  • 移動HEAD分支的指向 git reset --soft

    只是移動HEAD

  • 使索引看起來像HEAD git reset --mixed

    移動HEAD,還原Stage區

  • 使工作目錄看起來像索引 git reset --hard

    移動HEAD,….還原工作目錄