git日常使用指南
Git是使用廣泛的分布式版本控制系統(tǒng)印蔗。版本控制宁脊,簡單講就是記錄文件變更歷史。使用Git可以處理很小到很大的項目版本管理剥懒,小到一個文件须肆,大到巨量文件集合的項目匿乃。
我最初使用git來管理自己的筆記和文章。現(xiàn)在GitHub有免費的私有倉庫可以使用豌汇,對一些基本操作熟悉后不比堅果云繁瑣多少幢炸,卻更加掌控全局。
git安裝
Linux一般自帶git拒贱。使用git --version
查看是否安裝宛徊。如果沒有安裝使用Linux發(fā)行版相應(yīng)的包管理器進行安裝佛嬉,比如Debian系:sudo apt install -y git
。
Windows闸天、Mac需要從Git官網(wǎng)下載安裝包暖呕,然后一路默認選項安裝即可。Mac也可以使用homebrew進行安裝苞氮。homebrew類似Debian下的apt湾揽,是Mac下的包管理工具。
安裝好Git葱淳,需要進行一點配置就可以使用钝腺。簡單講就是設(shè)置本臺計算機身份:
git config --global user.name "your name"
git config --global user.email "your email"
此后抛姑,沒有額外設(shè)置的話赞厕,該設(shè)備進行的git操作都會標(biāo)記上面身份信息。
創(chuàng)建版本庫
mkdir gitTest
cd gitTest
git init
以上三個命令分別完成創(chuàng)建gitTest目錄定硝,進入該目錄皿桑,在該目錄下創(chuàng)建版本庫。版本庫存放在.git目錄下蔬啡,是git記錄gitTest目錄所有文件變更的倉庫诲侮。
倉庫添加文件
在gitTest目錄下新建一個本文文件,隨便編輯下箱蟆。
第一步沟绪,添加這個文件到緩存區(qū),git add new.txt
空猜。
第二步绽慈,提交到版本庫并備注,git commit -m 'a new text'
辈毯。
將add 與 commit 分離坝疼,一次commit可以針對多次add。
隨時掌握文件動態(tài)
在gitTest下工作時谆沃,可以隨時使用git status
查看倉庫的狀態(tài)钝凶。該命令可以顯示有哪些文件修改了,需要add唁影、commit耕陷。
git diff fileName
,可以查看該文件修改的具體內(nèi)容据沈。其顯示格式與Linux下diff工具相似哟沫。在add后就不能查詢了。
需要注意的卓舵,是git只跟蹤倉庫里文件變化南用。
版本控制
使用git log
可以查看提交歷史。記錄內(nèi)容有版本號(哈希值表示)、提交者裹虫、提交時間肿嘲、commit信息。
在最新的版本庫狀態(tài)有“(HEAD -> master)”標(biāo)識筑公,HEAD表示文件現(xiàn)在的狀態(tài)雳窟,master表示工作分區(qū),工作分區(qū)一般在master上匣屡,后面再詳細講分區(qū)使用封救。
退回上一個版本,git reset --hard HEAD^
捣作,或者git reset --hard 版本號
誉结。命令中版本號寫前幾位就可以,Git會自動匹配券躁。
如果想前進版本(后悔回退了)惩坑,又不知道版本號,使用git reflog
查看所有變更記錄也拜。
git的區(qū)域
git有三個區(qū)域以舒,當(dāng)前文件所在的目錄是工作區(qū),版本庫.git目錄包含暫存區(qū)(stage)和分支(master)慢哈。
工作區(qū)的文件先被修改蔓钟,通過add命令進入暫存區(qū),暫存區(qū)commit后就保存在當(dāng)前分支卵贱。這三個區(qū)文件狀態(tài)都可以回退滥沫。
- 工作區(qū)修改亂了,想放棄所有修改:
git checkout -- <file>
艰赞,回退到版本庫中最新的狀態(tài)(可能是暫存區(qū)或分支) - 撤銷暫存區(qū)的修改(unstaged):
git reset HEAD <file>
佣谐,即清空暫存區(qū) - commit后,當(dāng)前分支回退:
git reset --hard 版本號
方妖,參考上一節(jié)“版本控制”
add后如果想撤銷工作區(qū)的修改狭魂,必須先清空暫存區(qū),在放棄工作區(qū)修改党觅。
推送到遠程倉庫
可以自建遠程倉庫雌澄,也可以使用第三方倉庫。第三方倉庫比較出名的有g(shù)ithub杯瞻、bitbucket镐牺。之前github免費賬戶只有公開倉庫,被微軟收購后開放了免費私人倉庫魁莉。
本地倉庫連接遠程倉庫睬涧,需要有遠程倉庫賬號募胃、ssh秘鑰對。賬號在github官網(wǎng)上申請畦浓,ssh秘鑰對生成參考ssh-keygen用法痹束。
準(zhǔn)備好上面兩個東西,登陸github賬號讶请,在setting-->SSH and GPG keys中添加生成的ssh公鑰祷嘶。至此,遠程倉庫通過公鑰驗證個人電腦上的私鑰完成身份認證夺溢。
第一次使用github需要建空倉庫论巍,然后把本地倉庫的文件推送到遠程倉庫。在github網(wǎng)站右上角风响,點加號嘉汰,根據(jù)引導(dǎo)新建倉庫。
建完遠程倉庫就可以將本地倉庫與之關(guān)聯(lián)钞诡,在本地倉庫執(zhí)行 git remote add origin https://github.com/lcf33/gitTest.git
郑现。
然后將本地倉庫內(nèi)容推送至遠端,在本地倉庫執(zhí)行 git push -u origin master
荧降。第一次推送加-u參數(shù),會把本地的master分支和遠程的master分支關(guān)聯(lián)起來攒读,在以后的推送或者拉取時就可以簡化命令朵诫。
從遠程倉庫克隆
現(xiàn)在遠程服務(wù)器有一個learngit倉庫,本地電腦沒有薄扁。我們可以使用clone命令將其下載到本地剪返。git clone https://github.com/lcf33/learngit.git
,本地當(dāng)前目錄下就會生成一個目錄,內(nèi)含遠端倉庫所有文件邓梅。
遠端倉庫的地址在github頁面可以找到脱盲,還可以使用git clone git@github.com:lcf33/learngit
。Git支持多種協(xié)議日缨,前者使用https協(xié)議钱反,后者使用使用ssh協(xié)議。
使用https除了速度慢以外匣距,還有個最大的麻煩是每次推送都必須輸入口令面哥,但是在某些只開放http端口的公司內(nèi)部就無法使用ssh協(xié)議而只能用https。
創(chuàng)建分支
版本庫里默認生成的時間線是master分支毅待。master即是分支名尚卫,也可以當(dāng)做標(biāo)簽。git用master標(biāo)簽指向主分支最新提交尸红,用HEAD標(biāo)簽指向master表示當(dāng)前位于master分支吱涉。
使用git checkout -b dev
創(chuàng)建dev分支并轉(zhuǎn)到該分支刹泄。此時HEAD改為指向dev分支,表示當(dāng)前處于dev分支怎爵,之后add循签、commit都針對dev分支。
上面一條命令相當(dāng)于git branch dev
git checkout dev
疙咸,前一條是創(chuàng)建分支县匠,第二條是轉(zhuǎn)換分支。為避免checkout混亂撒轮,新版本git添加了switch命令乞旦。創(chuàng)建并切換分支:git switch -c dev
。
查看當(dāng)前倉庫所處分支git branch
题山,星號標(biāo)注所處分支兰粉。
合并分支
在dev分支某文件最佳了些內(nèi)容,合并前先切回master分支 git switch master
顶瞳。合并指定分支到當(dāng)前分支git merge dev
玖姑。git直接把master指向dev的當(dāng)前提交,合并速度非晨猓快(fast-forward)焰络。
合并之后就可以放行刪除dev分支了,git brance -d dev
符喝。如果要丟棄一個沒有被合并過的分支闪彼,可以通過git branch -D <name>強行刪除。
因為創(chuàng)建协饲、合并和刪除分支非澄吠螅快,所以Git鼓勵你使用分支完成某個任務(wù)茉稠,合并后再刪掉分支描馅,這和直接在master分支上工作效果是一樣的,但過程更安全而线。
但上面合并有個問題铭污,dev分支信息會隨著刪除分支一起刪除。在合并時使用--no-ff參數(shù)吞获,git merge --no-ff -m "merge with no-ff" dev
况凉。合并時創(chuàng)建一個新的commit,所以要加上-m參數(shù)各拷。
解決沖突
如果兩個分支都做了修改刁绒,合并就會產(chǎn)生沖突。git會把兩個分支的不同標(biāo)注在變更文件中烤黍,需要我們手動修改后再次add知市、commit傻盟。
沖突文件中,Git用<<<<<<<嫂丙,=======娘赴,>>>>>>>標(biāo)記出不同分支的內(nèi)容。
再次提交后跟啤,用git log --graph命令可以看到分支合并圖诽表。
分支管理原則
master分支應(yīng)該是非常穩(wěn)定的,也就是僅用來發(fā)布新版本隅肥,平時不能在上面干活竿奏。
干活都在dev分支上,dev分支是不穩(wěn)定的腥放。在需要發(fā)布文檔版本時把dev合并到master上泛啸。
團隊每個人都在dev分支上干活,每個人都有自己的分支秃症,時不時地往dev分支上合并候址。
緊急修改
緊急修改(比如修復(fù)bug),通過創(chuàng)建新的bug分支進行修復(fù)种柑,然后合并岗仑,最后刪除。
當(dāng)手頭工作沒有完成時莹规,先把工作現(xiàn)場git stash一下赔蒲,然后去修復(fù)bug,修復(fù)后良漱,再git stash pop,回到工作現(xiàn)場欢际。用git stash apply恢復(fù)母市,但是恢復(fù)后,stash內(nèi)容并不刪除损趋,你需要用git stash drop來刪除患久。可以多次stash浑槽,恢復(fù)的時候蒋失,先用git stash list查看,然后恢復(fù)指定的stash桐玻,git stash apply stash@{0}
篙挽。
在master分支上修復(fù)的bug,想要合并到當(dāng)前dev分支镊靴,可以用git cherry-pick <commit>命令铣卡,把bug提交的修改“復(fù)制”到當(dāng)前分支链韭,避免重復(fù)勞動。
多人協(xié)作
多人協(xié)作的工作模式通常是這樣:
- 首先煮落,可以試圖用git push origin <branch-name>推送自己的修改敞峭;
- 如果推送失敗,是因為遠程分支比你的本地更新蝉仇,需要先用git pull試圖合并旋讹;
- 如果合并有沖突,則解決沖突轿衔,并在本地提交沉迹;
- 沒有沖突或者解決掉沖突后,再用git push origin <branch-name>推送就能成功呀枢。
如果git pull提示no tracking information胚股,則說明本地分支和遠程分支的鏈接關(guān)系沒有創(chuàng)建,用命令git branch --set-upstream-to <branch-name> origin/<branch-name>裙秋。
從遠程庫clone時琅拌,默認情況下只能看到本地的master分支,要在dev分支上開發(fā)摘刑,就必須創(chuàng)建遠程origin的dev分支到本地进宝,git checkout -b dev origin/dev
。
如果本地已經(jīng)單獨創(chuàng)建dev分支枷恕,可以建立本地分支和遠程分支的關(guān)聯(lián)党晋,使用git branch --set-upstream branch-name origin/branch-name
。
要查看遠程庫的信息徐块,用git remote
未玻,用git remote -v
顯示更詳細的信息。在Git中胡控,分支完全可以留在本地扳剿,是否推送,自己定昼激。一般master庇绽、dev兩個分支要與遠程同步。
如果沒有先git pull橙困,則別人先push的修改就會影響到push瞧掺。解決沖突后提交線也會變得凌亂。使用git rebase
把分叉的提交歷史“整理”成一條直線凡傅,看上去更直觀辟狈。缺點是本地的分叉提交已經(jīng)被修改過了。
標(biāo)簽管理
Git的標(biāo)簽雖然是版本庫的快照像捶,但其實它就是指向某個commit的指針(跟分支很像對不對上陕?但是分支可以移動桩砰,標(biāo)簽不能移動),所以释簿,創(chuàng)建和刪除標(biāo)簽都是瞬間完成的亚隅。
commit是hash值,不好管理庶溶。tag就是一個讓人容易記住的有意義的名字煮纵,它跟某個commit綁在一起。
在Git中打標(biāo)簽非常簡單偏螺,首先切換到需要打標(biāo)簽的分支上行疏,然后git tag v1.0
就打上了“v1.0”的標(biāo)簽。
如果要對之前的commit打標(biāo)簽套像,git log --pretty=oneline --abbrev-commit
找到對應(yīng)的hash值酿联,git tag v0.9 hash_value
。
使用git tag
查看所有標(biāo)簽夺巩。該命令是按字母列出標(biāo)簽贞让。可以用git show <tagname>
查看標(biāo)簽詳細信息柳譬。如果嫌標(biāo)簽太短喳张,可以用-m參數(shù)加上備注。git tag -a v1.0 -m "version 1.0 released"
美澳,用-a指定標(biāo)簽名销部。
如果標(biāo)簽打錯了,也可以刪除git tag -d v0.9
制跟。
創(chuàng)建的標(biāo)簽都只存儲在本地舅桩,不會自動推送到遠程。如果要推送某個標(biāo)簽到遠程雨膨,使用命令git push origin <tagname>
江咳,或者推送全部尚未推送到遠程的本地標(biāo)簽git push origin --tags
。
如果標(biāo)簽已經(jīng)推送到遠程哥放,要刪除遠程標(biāo)簽就麻煩一點,先從本地刪除爹土,然后從遠程刪除甥雕。遠程刪除命令也是push,但是格式如下git push origin :refs/tags/v0.9