廖雪峯Git教程:https://www.liaoxuefeng.com/wiki/896043488029600
1.設置、查詢user name, email
-
設置user name,email
git config --global user.name "user name"
git config --global user.email "email" -
查詢user name,email
git config --global user.name
git config --global user.email
2. 創建版本庫
首先,選擇一個合適的地方,創建一個空目錄;第二步,通過git init
命令把這個目錄變成Git可以管理的倉庫,瞬間Git就把倉庫建好了。
(1)初始化一個Git倉庫,使用git init
命令。
(2)添加文件到Git倉庫,分兩步:
- 使用命令
git add <file>
,注意,可反覆多次使用,添加多個文件; - 使用命令
git commit -m <message>
,完成。
3. 修改與版本回退
3.1 修改文件
提交修改和提交新文件是一樣的兩步。
-
要隨時掌握工作區的狀態,使用
git status
命令。 -
如果
git status
告訴你有文件被修改過,用git diff
可以查看修改內容。
3.2 版本回退
命令:git reset --hard commit_id
回退到上一個版本:首先,Git必須知道當前版本是哪個版本,在Git中,用HEAD
表示當前版本,上一個版本就是HEAD^
,上上一個版本就是HEAD^^
,當然往上100個版本寫100個^
比較容易數不過來,所以寫成HEAD~100
。
$ git reset --hard HEAD^
HEAD is now at e475afc add distributed
$ git reset --hard 1094a
HEAD is now at 83b0afe append GPL
(1)HEAD
指向的版本就是當前版本,因此,Git允許我們在版本的歷史之間穿梭,使用命令git reset --hard commit_id
。
(2)穿梭前,用git log
可以查看提交歷史,以便確定要回退到哪個版本。
git log
命令用於查看歷史記錄,命令顯示從最近到最遠的提交日誌,如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上--pretty=oneline
參數
git log
git log --pretty=oneline
(3)要重返未來,用git reflog
查看命令歷史,以便確定要回到未來的哪個版本。
git reflog
e475afc HEAD@{1}: reset: moving to HEAD^
1094adb (HEAD -> master) HEAD@{2}: commit: append GPL
e475afc HEAD@{3}: commit: add distributed
eaadf4e HEAD@{4}: commit (initial): wrote a readme file
3.3 撤銷修改
場景1:當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file,如:
git checkout -- readme.txt
git checkout -- file
命令中的--
很重要,沒有--
,就變成了“切換到另一個分支”的命令。
場景2:當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD <file>
,就回到了場景1,第二步按場景1操作。
git reset HEAD readme.txt
git checkout -- readme.txt
git reset
命令既可以回退版本,也可以把暫存區的修改回退到工作區。當我們用HEAD
時,表示最新的版本。
場景3:已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考版本回退一節,不過前提是沒有推送到遠程庫。
3.4 刪除文件
一般情況下,你通常直接在文件管理器中把沒用的文件刪了,或者用rm
命令刪了:
$ rm test.txt
這個時候,Git知道你刪除了文件,因此,工作區和版本庫就不一致了,git status
命令會立刻告訴你哪些文件被刪除了。
現在你有兩個選擇:
(1)一是確實要從版本庫中刪除該文件,那就用命令git rm
刪掉,並且git commit
:
$ git rm test.txt
rm 'test.txt'
$ git commit -m "remove test.txt"
[master d46f35e] remove test.txt
1 file changed, 1 deletion(-)
delete mode 100644 test.txt
現在,文件就從版本庫中被刪除了。
(2)二是刪錯了,因爲版本庫裏還有,所以可以很輕鬆地把誤刪的文件恢復到最新版本
$ git checkout -- test.txt
git checkout
其實是用版本庫裏的版本替換工作區的版本,無論工作區是修改還是刪除,都可以“一鍵還原”。
注意:從來沒有被添加到版本庫就被刪除的文件,是無法恢復的!
4.遠程倉庫
註冊GitHub賬號,由於本地Git倉庫和GitHub倉庫之間的傳輸是通過SSH加密的,所以,需要一點設置:
(1)第1步:創建SSH Key。在你電腦用戶主目錄下(C:\Users\10***\.ssh),看看有沒有.ssh目錄,如果有,再看看這個目錄下有沒有id_rsa
和id_rsa.pub
這兩個文件,如果已經有了,可直接跳到下一步。如果沒有,打開Shell(Windows下打開Git Bash),創建SSH Key:
$ ssh-keygen -t rsa -C "[email protected]"
需要把郵件地址換成自己的郵件地址,然後一路回車,使用默認值即可,由於這個Key也不是用於軍事目的,所以也無需設置密碼。
如果一切順利的話,可以在用戶主目錄裏找到.ssh
目錄,裏面有id_rsa
和id_rsa.pub
兩個文件,這兩個就是SSH Key的祕鑰對,id_rsa
是私鑰,不能泄露出去,id_rsa.pub
是公鑰,可以放心地告訴任何人。
(2)第2步:登陸GitHub,打開“Account settings”,“SSH Keys”頁面:
然後,點“Add SSH Key”,填上任意Title,在Key文本框裏粘貼id_rsa.pub
文件的內容,點“Add Key”,你就應該看到已經添加的Key。
爲什麼GitHub需要SSH Key呢?因爲GitHub需要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,所以,GitHub只要知道了你的公鑰,就可以確認只有你自己才能推送。
GitHub允許添加多個Key。假定你有若干電腦,你一會兒在公司提交,一會兒在家裏提交,只要把每臺電腦的Key都添加到GitHub,就可以在每臺電腦上往GitHub推送了。
4.1 添加遠程庫
先有本地庫,後有遠程庫的時候,如何關聯遠程庫?
(1)要關聯一個遠程庫,使用命令:
方式1:git協議
$ git remote add origin [email protected]:your-github-name/repo-name.git
方式2:http協議
$git remote add origin https://github.com/your-github-name/repo-name.git
你也許還注意到,GitHub給出的地址不止一個,還可以用https://github.com/michaelliao/gitskills.git
這樣的地址。實際上,Git支持多種協議,默認的git://
使用ssh,但也可以使用https
等其他協議。
使用https
除了速度慢以外,還有個最大的麻煩是每次推送都必須輸入口令,但是在某些只開放http端口的公司內部就無法使用ssh
協議而只能用https
。
(2)關聯後,第一次推送master分支的所有內容,使用命令:
git push -u origin master
(3)此後,每次本地提交後,只要有必要,就可以使用命令推送最新修改:
git push origin master
分佈式版本系統的最大好處之一是在本地工作完全不需要考慮遠程庫的存在,也就是有沒有聯網都可以正常工作,而SVN在沒有聯網的時候是拒絕幹活的!當有網絡的時候,再把本地提交推送一下就完成了同步,真是太方便了!
4.2 從遠程庫克隆
假設我們從零開發,那麼最好的方式是先創建遠程庫,然後,從遠程庫克隆。
(1)首先,登陸GitHub,創建一個新的倉庫,名字叫gitskills。
勾選Initialize this repository with a README
,這樣GitHub會自動爲我們創建一個README.md
文件。創建完畢後,可以看到README.md
文件。
(2)現在,遠程庫已經準備好了,下一步是用命令git clone
克隆一個本地庫:
$ git clone [email protected]:michaelliao/gitskills.git
注意把Git庫的地址換成你自己的,然後進入gitskills
目錄看看,已經有README.md
文件了:
$ cd gitskills
$ ls
README.md
小結
- 要克隆一個倉庫,首先必須知道倉庫的地址,然後使用
git clone
命令克隆。 - Git支持多種協議,包括
https
,但通過ssh
支持的原生git
協議速度最快。
5.分支管理
5.1 創建與合併分支
Git鼓勵大量使用分支:
- 查看分支:
git branch
- 創建分支:
git branch <name>
- 切換分支:
git checkout <name>
或者git switch <name>
- 創建+切換分支:
git checkout -b <name>
或者git switch -c <name>
- 合併某分支到當前分支:
git merge <name>
“快進模式”:Fast-forward - 刪除分支:
git branch -d <name>
5.2 解決衝突
當master
分支和feature1
分支各自都分別有新的提交,即變成了下圖這樣,這種情況下,Git無法執行“快速合併”,只能試圖把各自的修改合併起來,但這種合併就可能會有衝突。
此時,直接查看readme.txt的內容:
當Git無法自動合併分支時,就必須首先解決衝突。解決衝突後,再提交,合併完成。解決衝突就是把Git合併失敗的文件手動編輯爲我們希望的內容,再提交。
用git log --graph
命令可以看到分支合併圖:
$ git log --graph
$ git log --graph --pretty=oneline --abbrev-commit
5.3 分支管理策略
- 快進模式合併:通常,合併分支時,如果可能,Git會用
Fast forward
模式,但這種模式下,刪除分支後,會丟掉分支信息,看不出來曾經做過合併。 - 普通模式合併:如果要強制禁用
Fast forward
模式,Git就會在merge時生成一個新的commit,這樣,從分支歷史上就可以看出分支信息。
$ git merge --no-ff -m "merge with no-ff" dev
可以看到,不使用Fast forward
模式,merge後就像這樣:
分支策略
在實際開發中,我們應該按照幾個基本原則進行分支管理:
- 首先,
master
分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面幹活; - 那在哪幹活呢?幹活都在
dev
分支上,也就是說,dev
分支是不穩定的,到某個時候,比如1.0版本發佈時,再把dev
分支合併到master
上,在master
分支發佈1.0版本; - 你和你的小夥伴們每個人都在
dev
分支上幹活,每個人都有自己的分支,時不時地往dev
分支上合併就可以了。
所以,團隊合作的分支看起來就像這樣:
5.4 Bug分支
修復bug時,我們會通過創建新的bug分支進行修復,然後合併,最後刪除;
當手頭工作沒有完成時,先把工作現場git stash
一下,然後去修復bug,修復後,再git stash pop
,回到工作現場;
在master分支上修復的bug,想要合併到當前dev分支,可以用git cherry-pick <commit>
命令,把bug提交的修改“複製”到當前分支,避免重複勞動。
5.5 Feature分支
添加一個新功能時,你肯定不希望因爲一些實驗性質的代碼,把主分支搞亂了,所以,每添加一個新功能,最好新建一個feature分支,在上面開發,完成後,合併,最後,刪除該feature分支。
- 開發一個新feature,最好新建一個分支;
- 如果要丟棄一個沒有被合併過的分支,可以通過:
git branch -D <name>
強行刪除。
5.6 多人協作
(1)查看遠程庫的信息
當你從遠程倉庫克隆時,實際上Git自動把本地的master
分支和遠程的master
分支對應起來了,並且,遠程倉庫的默認名稱是origin
。
要查看遠程庫的信息,用git remote
:
$ git remote
origin
用git remote -v顯示更詳細的信息:
$ git remote -v
origin [email protected]:michaelliao/learngit.git (fetch)
origin [email protected]:michaelliao/learngit.git (push)
(2)推送分支
推送分支,就是把該分支上的所有本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上,如果要推送其他分支,比如dev
,就改成:
$ git push origin dev
並不是一定要把本地分支往遠程推送,那麼,哪些分支需要推送,哪些不需要呢?
master
分支:是主分支,因此要時刻與遠程同步;
dev
分支:是開發分支,團隊所有成員都需要在上面工作,所以也需要與遠程同步;bug分支:只用於在本地修復bug,就沒必要推到遠程了,除非老闆要看看你每週到底修復了幾個bug;
feature分支:是否推到遠程,取決於你是否和你的小夥伴合作在上面開發。
(3)抓取分支
多人協作的工作模式通常是這樣:
-
首先,可以試圖用
git push origin <branch-name>
推送自己的修改; -
如果推送失敗,則因爲遠程分支比你的本地更新,需要先用
git pull
試圖合併; -
如果合併有衝突,則解決衝突,並在本地提交;
-
沒有衝突或者解決掉衝突後,再用
git push origin <branch-name>
推送就能成功!
如果git pull
提示no tracking information
,則說明本地分支和遠程分支的鏈接關係沒有創建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>
。
這就是多人協作的工作模式,一旦熟悉了,就非常簡單。
小結
-
查看遠程庫信息,使用
git remote -v
; -
本地新建的分支如果不推送到遠程,對其他人就是不可見的;
-
從本地推送分支,使用
git push origin branch-name
,如果推送失敗,先用git pull
抓取遠程的新提交; -
在本地創建和遠程分支對應的分支,使用
git checkout -b branch-name origin/branch-name
,本地和遠程分支的名稱最好一致; -
建立本地分支和遠程分支的關聯,使用
git branch --set-upstream branch-name origin/branch-name
; -
從遠程抓取分支,使用
git pull
,如果有衝突,要先處理衝突。