前言
Git是目前世界上最先進的分佈式版本控制系統。本文從頭詳細地介紹了Git的各種用法。
配置本機用戶和郵箱
λ git config --global user.name 名字
λ git config --global user.email 郵箱
注意:git config
的--global
參數代表本機上所有git倉庫都用這個配置。
若想爲某個倉庫配置其它的用戶名和郵箱:
λ git config -user.name 名字
λ git config ser.email 郵箱
查看全局用戶名和郵箱:
λ git config --global user.name
λ git config --global user.email
查看某倉庫用戶名和郵箱同理,上述語句去掉--global
就可以。
創建倉庫
將當前目錄編程Git可以管理的倉庫:
λ git init
Initialized empty Git repository in C:/Users/hwx/Desktop/learngit/.git/
C:/Users/hwx/Desktop/learngit
是我的目錄,.git
目錄用來跟蹤管理版本庫,不用管它。
將文件添加到版本庫
注意:所有版本控制系統只能跟蹤文本文件的改動,可以告訴你每次改動的細節。但是不能跟蹤圖片、視頻這些二進制文件的變化,只能知道文件大小的變化。
下面我們添加一個readme.txt到倉庫,分兩步:
1.用命令git add
將文件添加到暫存區:
λ git add readme.txt
該命令執行成功不會有任何顯示,可以同時add多個文件,中間用空格隔開。
2.用命令git commit
將文件從暫存區提交到倉庫:
λ git commit -m "add a readme text"
[master (root-commit) 6fd4dfc] add a readme text
1 file changed, 2 insertions(+)
create mode 100644 readme.txt
-m
後面是本次提交的說明。
注意:git commit
只會提交暫存區中的修改,沒放進暫存區的不會提交。
git status
查看倉庫狀態。
1.倉庫中有文件沒add
λ git status
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
.1.txt.swp
nothing added to commit but untracked files present (use "git add" to track)
2.倉庫中有文件修改過了,但是沒add
λ 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: readme.txt
no changes added to commit (use "git add" and/or "git commit -a")
3.倉庫中有文件add了,但是沒有commit
λ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: readme.txt
4.倉庫該add的都add了,該commit的都commit了
λ git status
On branch master
nothing to commit, working tree clean
git diff
工作區是目錄,倉庫是版本庫。
git diff
比較的是工作區文件與暫存區文件(上次git add 的內容)的區別
git diff --cached
比較的是暫存區的文件與倉庫文件(上次git commit 的內容)的區別
git diff HEAD --
比較的是工作區文件和倉庫文件
git log
查看倉庫歷史:
λ git log
commit e1f285812d2202a32fed025f309fb6e7a68fde49 (HEAD -> master)
Author: Wenxing Hu <[email protected]>
Date: Sat Dec 22 14:22:32 2018 +0800
readme add forth line
commit 859c43221f414215c34c95004ab3930c407caee6
Author: Wenxing Hu <[email protected]>
Date: Sat Dec 22 14:14:04 2018 +0800
readme add 3 line
commit 6fd4dfc32c1ba2bec1fe5e61b85b721c5ed62d2c
Author: Wenxing Hu <[email protected]>
Date: Sat Dec 22 13:57:17 2018 +0800
add a readme text
從下到上是按照時間排序的每次commit的信息。
信息太多了?加上--pretty=oneline
參數:
λ git log --pretty=oneline
e1f285812d2202a32fed025f309fb6e7a68fde49 (HEAD -> master) readme add forth line
859c43221f414215c34c95004ab3930c407caee6 readme add 3 line
6fd4dfc32c1ba2bec1fe5e61b85b721c5ed62d2c add a readme text
每行前面的一大串是commit id。git log --oneline
可以只顯示前7位id。
git reset
回退到某一個版本
HEAD
是個指針,代表當前的版本。上個版本是HEAD^
,上上個是HEAD^^
,往上n個版本可以寫成HEAD~n
。
λ git reset --hard HEAD~
HEAD is now at 859c432 readme add 3 line
注意:執行git reset --hard HEAD^
可能會出來個more?
這是因爲命令行中^是換行符,所以還是用HEAD~1
吧。
也可以根據commit id來進行版本變換:
git reset --hard e1f2
HEAD is now at e1f2858 readme add forth line
這裏commit id輸入四個字符就可以了。
注意:git log
只能看到HEAD指向的版本及之前的版本。
版本變換多了,弄暈了,不要緊,命令git log --reflog
用來查看所有版本。還有命令git reflog
可以查看每次執行的命令。
撤銷修改
1.工作區的文件弄壞了,git checkout -- 文件名
這條命令可以使它回到最新的add或commit時的狀態,俗稱一鍵還原。
2.工作區的文件弄壞了,還add到了暫存區,用命令git reset HEAD 文件名
,可以將其方會工作區,這樣就回到了1的情況,再執行1就可以了。
刪除文件
先git rm 文件名
,再git commit
。
λ git rm test.txt
rm 'test.txt'
λ git commit -m "delete test.txt"
[master ee28494] delete test.txt
1 file changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 test.txt
遠程倉庫
遠程倉庫這裏以GayHub爲例,當然你也可以自己搭建一個服務器運行Git。
1.將本地倉庫和遠程倉庫通過SSH連接。
λ ssh-keygen -t rsa -C "你的郵箱"
然後根據提示一路回車。。。
運行成功後,可以在用戶主目錄裏找到.ssh目錄,裏面有id_rsa
和id_rsa.pub
兩個文件,這兩個就是SSHKey的祕鑰對,id_rsa
是私鑰,不能泄露出去,id_rsa.pub
是公鑰,可以放心地告訴任何人。
然後在GitHub中添加SSH key,把公鑰添加進去就ok了。
2.關聯本地倉庫和遠程倉庫
首先在GitHub中新建一個倉庫(Repository):
按它的提示,在本地倉庫執行命令:
git remote add [email protected]:649453932/git-test.git
將本地倉庫推送到遠程倉庫的命令:
git push -u origin master
其中-u
只在第一次推送時加,origin代表遠程倉庫,注意本地倉庫只有commit了的文件纔會推送到遠程倉庫。
之後每次推送時**git push origin 分支名
**,你可以推送本地的mastet到遠程倉庫,當然也可以選擇本地的其他分支推送。注意:遠程倉庫也可以有好多分支。
移除關聯的遠程倉庫:
git remote rm origin
3.從遠程倉庫克隆
git clone [email protected]:649453932/git-test.git
可以隨便從GitHub中clone倉庫,clone回來就成了你的一個本地庫,但保留了該倉庫之前的各種記錄。
分支管理
剛開始,只有一個分支,名爲master,可以再創建分支,分支之間平時互不影響,可以並行開發。
查看所有分支:git branch
,當前分支前會有個*
創建分支:git branch 名字
切換到分支:git checkout 名字
創建並切換到分支:git checkout -b 名字
合併指定分支到當前分支:git merge 名字
刪除分支:git branch -d 名字
衝突處理
若master分支和另外一個分支同時對一個文件做了修改,那就不能merge了。
這就需要我們手動解決了:
λ cat readme.txt
This is a readme text.
This is second line.
This is third line.
forth
fifth
sixth
seventh
eighth_master_dev1
<<<<<<< HEAD
master !!!
=======
dev2 !!!
>>>>>>> dev2
Git用<<<<<<<
,=======
,>>>>>>>
標記出不同分支的內容我們把這些符號刪掉,改成我們想要的內容。再在master分支上add和commit,主分支就改好了,另外一個分支現在就可以merge了。
圖形化分支合併情況
git log --graph
命令可以查看分支合併情況:
λ git log --graph --pretty=oneline --abbrev-commit
* 99fdeac (HEAD -> dev2, master) conflict fixed!
|\
| * 47c854e ADD eighth
* | 53ba977 ADD eighth_maser
|/
* e555cd8 branch test
* ee28494 (origin/master) delete test.txt
* 0ec907e add test.txt
* cd95b35 fidth line
* 6fd4dfc add a readme text
分支merge技巧
通常,合併分支merge
時,如果可能,Git會用Fast forward
模式,但這種模式下,刪除分支後,會丟掉分支信息。
使用--no-ff
可以禁用Fast forward
,merge時會生成新的commit,就可以從log看到分支。
git merge --no-ff -m "merge with no-ff" 要merge的分支名
λ git merge --no-ff -m "merge noff" dev7
Merge made by the 'recursive' strategy.
readme.txt | 1 +
1 file changed, 1 insertion(+)
然後我們看log,dev6是 Fast forwar 模式進行merge的,而dev7是--no-ff模式進行merge的:
λ git log --graph --pretty=oneline --abbrev-commit
* 5571146 (HEAD -> master) merge noff
|\
| * dbc506e (dev7) dev7
|/
* 2122b61 (dev6) dev6
|
...
git stash
該命令可以將工作現場
存儲起來,之後可以再恢復。用於臨時處理其它分支的事務,處理完再回來將自己存儲的工作現場恢復。
λ git stash
Saved working directory and index state WIP on dev6: 2122b61 dev6
用git stash
可以查看存儲的工作現場。
git stash apply
恢復現場,但是之後還需要用git stash drop
來刪除存儲的。可以直接用git stash pop
來恢復現場並刪除存儲。
注意:只有被add過的文件纔會被git stash存儲,注意是add 過,只要曾經add過就行。
刪除分支
git branch -d dev1
λ git branch -d dev1
error: The branch 'dev1' is not fully merged.
If you are sure you want to delete it, run 'git branch -D dev1'.
若該分支沒有被合併,刪除就會丟失該分支上的修改,強制刪除命令:git branch -D 分支名
。
多人協作
git remote -v
:顯示詳細信息
λ git remote -v
origin [email protected]:649453932/learngit.git (fetch)
origin [email protected]:649453932/learngit.git (push)
上面顯示了可以抓取和推送的origin的地址。如果沒有推送權限,就看不到push的地址。
從本地推送時用下面的命令,將本地分支推送到遠程倉庫的分支:
git push origin 分支名
若兩個人同時處理一個遠程分支,一個人推送了,另外一個人再推送就會失敗,得先用git pull
將最新的提交從origin/分支名
抓下來與本地合併,再推送。
也有可能兩人修改了同一個文件,pull下來有衝突,需要手動解決,解決方式見前面的衝突處理。
忽略特殊文件
建一個.gitignore文件。
裏面這樣寫:
# 這是註釋
這裏是你想忽略的文件
*可以代指任何字符串
...
這樣每次git status
就不會提示這些文件了。