設定
使用 git 第一步是設定你的 user name 跟 user email
$ git config --global user.name "nyo"
$ git config --global user.email "nyo@mail.com"
設定檔會在 ~/.gitconfig
或者可以下指令看
$ git config -l
設定顯示顏色
$ git config --global color.diff auto
$ git config --global color.status auto
$ git config --global color.branch auto
$ git config --global color.log auto
# 自訂 log 格式到 lg,當然你也可以定義其他 alias
$ git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)%Creset' --abbrev-commit --date=relative"
設定 commit 時,使用的編輯器
預設是用系統預設的編輯器或者是 vi
$ git config --global core.editor vim
設定你想用於處理 conflict 的 tools
$ git config --global merge.tool gvimdiff
為專案建立 Repository
假設專案的資料夾為 project
$ cd project/
$ git init
git 會建立一個 .git 的資料夾,所有 repository 所需要的資料都在裡面
接著將要讓 git 追蹤的檔案加入
$ git add .
(. 指目前所在的目錄,當然也可以指定檔案)
最後輸入 commit 指令,把資料 commit
$ git commit
輸入指令後會進入編輯器,為目前的資料變動加上說明
存檔後此次 commit 的資料就會加入 repository 中
複製一份 Repository
以 git clone 的指令把其他地方的 repository 複製到你目前的工作目錄下
可以用 git://, http(s)://, ssh:// 從網路複製,或直接從電腦中的其他資料夾複製
$ git clone ssh://username@url/<路徑>
$ git clone <資料路徑>
clone 完成後,來源的網址會存到 config 中的 remote origin 中
建立新的 branch,編輯,然後送回原位子
開一個新的 branch newBranch
$ git branch newBranch
$ git branch newBranch v2.5 # newBranch based at v2.5
如果你是跑
$ git branch
會看目前你擁有的 branch ,有*的是目前所在的 branch
其他 branch 參數
$ git branch -d <branch> #刪除 branch
$ git branch -r #列出所有的 remote branch
$ git branch -a #列出所有的 branch
切換到新的 branch
$ git checkout newBranch
現在在新的 branch 上做任何修改都不會動到原本 master 上的資料了
修改創作完成後,就是要把修改的內容 commit 到 repository
# 加入新增的檔案(如果有的話)
$ git add <檔案>
# commit 全部修改的資料
$ git commit -a
或者是
$ git add -u #stage 修改的資料
$ git commit
切換到 master
$ git checkout master
再來要把資料 merge 並送回 origin,但是在那之前要先確定有沒有其他人 push 資料上去
$ git pull [origin] [remote branch name]
事實上 pull 等於 fetch 新的資料並 merge 進local branch
更新完 master 後,將 master 和 newBranch merge 起來
$ git merge newBranch
merge 時如果有 conflict 時,conflict 的部份會有<<<< ==== >>>>
只要將 conflict 的部份修改再 commit 即可完成 merge 動作
最後將 master push 到 remote repository 工作就告一段落了
# push all branch
$ git push origin
$ git push <remote>
$ git push <remote> <local branch>:<remote branch>
沒辦法 push master?
修改 remote 的 git config
$ git config receive.denyCurrentBranch=ignore
關於 Commit
自動 stage 已修改或刪除的檔案,但是對新增的檔案沒有作用
$ git commit -a
直接使用 "message" 當 commit message
$ git commit -m "message"
commit 指定的 file,已 stage 的資料不會被 commit 依舊是 staged
$ git commit <file>
修改當前 branch 最近一次的 commit
$ git commit --amend
想要只 commit 部份的變動,可用以下指令,進入 Interactive mode
$ git add -i
關於 Reset
working tree: 當前的工作資料 (unstage)
HEAD: 目前所在的 commit (staging area)
index: 儲存的 commit 資料 (repository)
reset 後,原本的 HEAD 會存到 ORIG_HEAD
reset HEAD 跟 index 到指定的 commit 而 working tree 不會變動
$ git reset HEAD
reset HEAD 到指定的 commit
$ git reset --soft HEAD
$ git reset --soft HEAD^ # HEAD 的前一個 commit
$ git reset --soft HEAD~3 # HEAD 的前三個 commit
reset HEAD, index, working tree 到指定的 commit
$ git reset --hard HEAD
關於 Cherry-pick
要將已存在的 commit 拿來使用
$ git cherry-pick <commit>
$ git cherry-pick -n <commit> #只套用該 commit 的變動,不會 commit 出去
關於 Tag
commit 的編碼都很亂,加個 tag 很方便
$ git tag <tagname> #為目前的 commit 加上 tag
$ git tag <tagname> <commit> #為指定的 commit 加上 tag
$ git tag -d <tagname> #刪除 tag
關於 Merge
假設當下所在的 branch 是 master
A---B---C topic / D---E---F---G master
$ git merge topic
topic 裡從 master 分支出來後的 commit(A, B, C) 會合到 master 並用一個新的 commit 加以記錄
A---B---C topic / \ D---E---F---G---H master
merge 時如果有 conflict 時,conflict 的部份會有<<<< ==== >>>>
只要將 conflict 的部份修改再 commit 即可完成 merge 動作
加上 --no-commit 執行 merge 不會自動 commit ,你可以在 commmit 前修改 merge 結果
$ git merge --no-commit <commit>
關於 Rebase
rebase 的基本用法:
假設當下所在的 branch 是 topic
A---B---C topic / D---E---F---G master
用以下指令:
$ get rebase master
$ git rebase master topic
A'--B'--C' topic / D---E---F---G master
rebase --onto 的用法:
假設目前的 commit tree 是:
o---o---o---o---o master \ o---o---o---o---o next \ o---o---o topic
想要把 topic 跟 master merge 但是又不要有 next 的資料
$ git rebase --onto master next topic
o---o---o---o---o master | \ | o'--o'--o' topic \ o---o---o---o---o next
rebase 還可以移除 commit
E---F---G---H---I---J topicA
$ git rebase --onto topicA~5 topicA~3 topicA
F 跟 G 就被刪掉了
E---H'---I'---J' topicA
rebase 的時候遇到 conflict 時,
git rebase 會停在第一個有問題的 commit 並在 working tree 裡 mark conflict
修正完 coflict 後再以 git-add 告知 git conflict 解除了
再下指令繼續 rebase
$ git rebase --continue
或者想要取消 rebase 動作
$ git rebase --abort
關於 Stash
當你程式改到一半,還不打算 commit 修改的資料,但是又想要對 repository 有所動作時,就是用 stash 了
將修改的資料先暫存起來,並回復到 HEAD 的狀態
$ git stash
取出一筆記錄,並從 stash list 中移除,不指定 stash 的話預設會是 stash@{0}
$ git stash pop [<stash>]
取出一筆記錄,但不移除
$ git stash apply [<stash>]
顯示該筆 stash 的修改記錄
$ git stash show [-p] [<stash>]
列出暫存區裡的所有資料
$ git stash list
清空 stash list
$ git stash clear
從指定的 stash 所在的 commit 建立並切換到一個新的 branch,並將 stash 的記錄套用到新的 working tree。
成功執行後,該 stash 資料將被 drop
$ git stash branch <branchname> [<stash>]