一.Git簡介
Git是目前世界上最先進(jìn)的分布式版本控制系統(tǒng)力九。它就沒有中央服務(wù)器的卦睹,每個(gè)人的電腦就是一個(gè)完整的版本庫金句,這樣,工作的時(shí)候就不需要聯(lián)網(wǎng)了搬卒,因?yàn)榘姹径际窃谧约旱碾娔X上瑟俭。
完成開發(fā)以后再將各自的修改推送給對方,就可以互相看到對方的修改了(為了便于項(xiàng)目中的所有開發(fā)者分享代碼秀睛,我們將代碼存放遠(yuǎn)程 Git 倉庫例如github)尔当。與此對應(yīng)的是SVN是集中式版本控制系統(tǒng),
版本庫是集中放在中央服務(wù)器的蹂安,而干活的時(shí)候,用的都是自己的電腦锐帜,所以首先要從中央服務(wù)器哪里得到最新的版本田盈,然后干活,干完后缴阎,需要把自己做完的活推送到中央服務(wù)器允瞧。而且集中式版本控制系統(tǒng)是必須聯(lián)網(wǎng)才能工作。
二.Git文件狀態(tài)
-
Untracked: 未跟蹤, 此文件在文件夾中, 但并沒有加入到git庫, 不參與版本控制. 通過
git add
狀態(tài)變?yōu)?code>Staged -
Unmodify: 文件已經(jīng)入庫, 未修改, 即版本庫中的文件快照內(nèi)容與文件夾中完全一致. 這種類型的文件有兩種去處, 如果它被修改, 而變?yōu)?code>Modified. 如果使用
git rm
移出版本庫, 則成為Untracked
文件 -
Modified: 文件已修改, 僅僅是修改, 并沒有進(jìn)行其他的操作. 這個(gè)文件也有兩個(gè)去處, 通過
git add
可進(jìn)入暫存staged
狀態(tài), 使用git checkout
則丟棄修改過, 返回到unmodify
狀態(tài), 這個(gè)git checkout
即從庫中取出文件, 覆蓋當(dāng)前修改 -
Staged: 暫存狀態(tài). 執(zhí)行
git commit
則將修改同步到庫中, 這時(shí)庫中的文件和本地文件又變?yōu)橐恢? 文件為Unmodify
狀態(tài). 執(zhí)行git reset HEAD filename
取消暫存, 文件狀態(tài)為Modified
三.Git常見命令
1.設(shè)置相關(guān)
-
git config --list
查看配置 -
git config user.name
查看用戶名 -
git config user.email
查看郵箱 -
git config --global user.name "nameVal"
配置全局用戶名 -
git config --global user.email "eamil@qq.com"
配置全局郵箱 -
git config --global credential.helper store
全局緩存登錄憑證 -
git config user.name “xxxx”
配置單個(gè)項(xiàng)目用戶名(需進(jìn)入到項(xiàng)目文件夾根目錄里面) -
git config user.email "xxxx@xx.com"
配置單個(gè)項(xiàng)目郵箱(需進(jìn)入到項(xiàng)目文件夾根目錄里面) -
git config –global credential.helper cache
設(shè)置記住密碼(默認(rèn)15分鐘) -
git config credential.helper ‘cache –timeout=3600’
設(shè)置記住密碼自定義過期時(shí)間(這里設(shè)置一個(gè)小時(shí)之后失效) -
git config –global credential.helper store
設(shè)置記住密碼長期存儲(chǔ) -
git config --global credential.helper wincred
清除緩存登錄憑證 -
git credential-manager uninstall
清除緩存在git中的用戶名和密碼 -
git version
查看git軟件的版本號(hào)蛮拔。
2.創(chuàng)建
-
git init
初始化 -
git clone git@git... .git
克隆項(xiàng)目(git:// 協(xié)議) -
git clone http://... .git
克隆項(xiàng)目(http(s)://) -
git clone http://郵箱(或用戶名):密碼@倉庫地址
指定郵箱或者用戶名克隆項(xiàng)目,如果用戶名或者郵箱及密碼中包含了@符號(hào)述暂,所以需要把@轉(zhuǎn)碼一下代替:@-->%40 -
git clone -b 要clone的分支名 倉庫地址
克隆指定分支的項(xiàng)目.
3.添加到暫存區(qū)及提交
-
git add readme.txt
將文件提交到暫存區(qū) -
git add .
把工作區(qū)域內(nèi)的所有變化提交到暫存區(qū),包括文件內(nèi)容修改(modified)以及新文件(new)建炫,但不包括被刪除的文件畦韭。 -
git add -u
僅監(jiān)控已經(jīng)被add的文件(即tracked file)將被修改的文件提交到暫存區(qū)。add -u 不會(huì)提交新文件(untracked file)肛跌。(git add --update的縮寫) -
git add -A
是上面兩個(gè)的合集,提交所有變化艺配。(git add --all的縮寫) -
git commit -m "first"
提交到版本庫 -
git status
狀態(tài)查看(查看工作目錄中的狀態(tài)例如:有沒有沒被提交的文件之類的)
4.刪除
-
git rm 我的文件
在本地倉庫刪除文件 -
git rm -r 我的文件夾/
在本地倉庫刪除文件夾 此處-r表示遞歸所有子目錄,如果你要?jiǎng)h除的衍慎,是空的文件夾转唉,此處可以不用帶上-r。
刪除的文件可以通過 git reset head file 和git checkout file恢復(fù).
5.branch(分支)
-
git branch [branch-name]
新建一個(gè)分支稳捆,但依然停留在當(dāng)前分支 -
git checkout -b [branch-name]
新建一個(gè)分支赠法,并切換到該分支 -
git branch
列出所有的分支(所有本地分支) -
git branch -r
列出所有的分支(所有遠(yuǎn)程分支) -
git branch -a
列出所有的分支(所有本地和遠(yuǎn)程分支) -
git checkout [branchname]
切換到指定分支,并更新工作區(qū) -
git branch -d [branchname]
刪除本地分支 -
git push origin --delete [branchName]
刪除遠(yuǎn)程分支 -
git branch -m [oldname] [newName]
分支重命名 -
git reflog --date=local | grep nikeglass
查看當(dāng)前分支的父分支 -
git merge [branchname]
將branchname分支上的修改合并到當(dāng)前分支上 -
git rebase [branchname]
對當(dāng)前分支基于branchname進(jìn)行變基操作
6.遠(yuǎn)程分支.
git checkout -b [分支名] [遠(yuǎn)程名]/[分支名]
在本地建立分支并和遠(yuǎn)程分支同步git remote add origin [遠(yuǎn)程git地址]本地項(xiàng)目關(guān)聯(lián)遠(yuǎn)程倉庫(origin 是默認(rèn)的遠(yuǎn)程版本庫名稱,添加多個(gè)不同的遠(yuǎn)端需要不同的標(biāo)識(shí))
git remote
列出所有關(guān)聯(lián)的遠(yuǎn)端倉庫.git remote update origin --prune
更新遠(yuǎn)程分支列表git remote -v
列出所有關(guān)聯(lián)的遠(yuǎn)端倉庫(詳細(xì)信息).git remote rm origin:origin(遠(yuǎn)程關(guān)聯(lián)倉庫的別稱)
刪除關(guān)聯(lián)的遠(yuǎn)程倉庫乔夯。-
fetch+merge
拉取遠(yuǎn)程倉庫與本地倉庫進(jìn)行合并(git fetch 相當(dāng)于是從遠(yuǎn)程獲取最新到本地砖织,不會(huì)自動(dòng)merge)git fetch origin master //將遠(yuǎn)程倉庫的master分支下載到本地當(dāng)前branch中 git log -p master...origin/master //比較本地的master分支和origin/master分支的差別 git merge origin/master //進(jìn)行合并
git pull origin master
相當(dāng)于是從遠(yuǎn)程獲取最新版本并merge到本地款侵。git push <遠(yuǎn)程主機(jī)名> <本地分支名>:<遠(yuǎn)程分支名>
推送到遠(yuǎn)程倉庫.如果當(dāng)前分支只有一個(gè)追蹤分支,那么主機(jī)名和后面都都可以省略:git push
镶苞。
如果當(dāng)前分支與多個(gè)主機(jī)存在追蹤關(guān)系喳坠,那么這個(gè)時(shí)候-u選項(xiàng)會(huì)指定一個(gè)默認(rèn)主機(jī),這樣后面就可以不加任何參數(shù)使用git push:git push -u origin(遠(yuǎn)程主機(jī)名) master:master(本地分支名:遠(yuǎn)程分支名)
茂蚓。git pull origin master --allow-unrelated-histories
分支進(jìn)行強(qiáng)行合并
git fetch和git pull 區(qū)別: fetch 和 pull 的不同: fetch 相當(dāng)于是從遠(yuǎn)程獲取最新版本到本地壕鹉,不會(huì)自動(dòng)merge,所以本地倉庫的代碼還未被更新聋涨,
然后比較本地分支和遠(yuǎn)程分支的差別,最后通過 git merge origin/master 來合并這兩個(gè)版本晾浴,可以把它理解為合并分支一樣的。
pull 相當(dāng)于是從遠(yuǎn)程獲取最新版本并merge到本地(相當(dāng)于git fetch 和 git merge)牍白。如果想要更加可控一點(diǎn)的話推薦使用fetch + merge,因?yàn)?br> git fetch更安全一些,在merge前脊凰,我們可以查看更新情況,然后再?zèng)Q定是否合并
7.標(biāo)簽
-
git tag
列出所有tag -
git show [tag]
查看tag信息 -
git tag [tagname]
打輕量標(biāo)簽 -
git tag -a [tagname] -m [message]
打標(biāo)簽并附注標(biāo)簽(例如茂腥,打v1.0標(biāo)簽git tag -a v1.0 -m 'v1.0 release'
) -
git tag -a [tagname] [commit_id]
對過去的提交打標(biāo)簽 -
git tag -d [tagname]
刪除本地tag -
git push origin --delete tag <tagname>
刪除遠(yuǎn)程tag -
git push [remote] [tag]
提交指定tag(例如狸涌,將v1.0標(biāo)簽推送到遠(yuǎn)程服務(wù)器上git push origin v1.0
) -
git push [remote] --tags
提交所有tag -
git checkout [tagname]
切換到對應(yīng)標(biāo)簽狀態(tài)(這時(shí)候 git 可能會(huì)提示你當(dāng)前處于一個(gè)“detached HEAD" 狀態(tài)。 因?yàn)?tag 相當(dāng)于是一個(gè)快照最岗,是不能更改它的代碼的帕胆。如果要在 tag 代碼的基礎(chǔ)上做修改,你需要一個(gè)分支:git checkout -b [branchname] [tagname]
)
8.日志
-
git log
每一次操作記錄 -
git reflog
可以查看所有分支的所有操作記錄(包括(包括commit和reset的操作)般渡,包括已經(jīng)被刪除的commit記錄懒豹,git log則不能察看已經(jīng)刪除了的commit記錄,而且跟進(jìn)結(jié)果可以回退到某一個(gè)修改驯用。 -
git log --oneline --graph
查看歷史中什么時(shí)候出現(xiàn)了分支脸秽、合并 -
git diff
比較工作區(qū)和暫存區(qū)的所有文件差異變化 -
git diff <file name>
比較工作區(qū)和暫存區(qū)的指定文件的差異 -
git diff --stat
比較工作區(qū)和暫存區(qū)的所有文件變化列表 -
git shortlog -n-
按每位作者的提交次數(shù)排序分組輸出。 -
git show commit_id
查看某個(gè)提交的詳細(xì)
8.撤銷修改版本回溯
-
git checkout -- file
丟棄工作區(qū)內(nèi)文件的修改(例如:git checkout -- readme.md) -
git checkout .
放棄對工作區(qū)內(nèi)所有的文件修改
命令
git checkout -- readme.txt
意思就是蝴乔,把readme.txt
文件在工作區(qū)的修改全部撤銷记餐,這里有兩種情況:一種是readme.txt
自修改后還沒有被add到暫存區(qū),現(xiàn)在淘这,撤銷修改就回到和之前版本庫一模一樣的狀態(tài)剥扣;
一種是readme.txt
已經(jīng)添加add到暫存區(qū)后,又作了修改铝穷,現(xiàn)在钠怯,撤銷修改就回到添加到暫存區(qū)后的狀態(tài)∈锬簦總之晦炊,就是讓這個(gè)文件回到最近一次git commit
或git add
時(shí)的狀態(tài)。
-
git reset HEAD <file>
撤銷已經(jīng)add到暫存區(qū)的文件. -
git reset HEAD .
撤銷所有的已經(jīng)add到暫存區(qū)的文件.
如果文件已經(jīng)被add到暫存區(qū),再使用git checkout是沒有用的.此時(shí)應(yīng)該使用git reset HEAD將文件撤銷添加到暫存區(qū)的操作,然后再使用git checkout操作讓文件恢復(fù)到最近一次commit.
-
git reset --hard HEAD^
回退到上個(gè)版本 -
git reset --hard commit_id
退到/進(jìn)到 指定commit_id
撤銷修改分為三種情況
情況一:未使用 git add 緩存代碼時(shí):
放棄單個(gè)文件修改git checkout -- filepathname
,注意不要忘記中間的"--",不寫就成了檢出分支了! 放棄所有的文件修改git checkout .
情況二:已經(jīng)使用了 git add 緩存了代碼:
可以使用 git reset HEAD filepathname
(比如: git reset HEAD readme.md
)來放棄指定文件的緩存,放棄所有的緩存可以使用 git reset HEAD .
**`` 命令断国。此命令用來清除 git對于文件修改的緩存贤姆。相當(dāng)于撤銷 git add 命令所在的工作。
情況三:已經(jīng)用 git commit 提交了代碼:
可以使用 git reset --hard HEAD^
來回退到上一次commit的狀態(tài)稳衬。此命令可以用來回退到任意版本:git reset --hard commitid
三.Git忽略
1.使用.gitignore文件
在git中如果想忽略掉某個(gè)文件霞捡,不讓這個(gè)文件提交到版本庫中,可以使用修改根目錄中 .gitignore 文件的方法(如無薄疚,則需自己手工建立此文件)碧信。
創(chuàng)建.gitignore
touch .gitignore
打開 Git Bash->導(dǎo)航到 Git 倉庫的位置->為倉庫創(chuàng)建.gitignore文件
.gitignore匹配規(guī)則
# 此為注釋 – 將被 Git 忽略
*.a # 忽略所有 .a 結(jié)尾的文件
!lib.a# 但 lib.a 除外
/TODO # 僅僅忽略項(xiàng)目根目錄下的 TODO 文件,不包括 subdir/TODO
build/# 忽略 build/ 目錄下的所有文件
doc/*.txt # 會(huì)忽略 doc/notes.txt 但不包括 doc/server/arch.txt
.gitignore不生效問題
把某些目錄或文件加入忽略規(guī)則街夭,按照上述方法定義后發(fā)現(xiàn)并未生效砰碴,原因是.gitignore只能忽略那些原來沒有被追蹤的文件靠欢,如果某些文件已經(jīng)被納入了版本管理中犬绒,僅修改.gitignore是無效的。
所以如果需要忽略的文件已經(jīng)提交到本地倉庫堪侯,則需要從本地倉庫中刪除掉該文件埃碱,如果已經(jīng)提交到遠(yuǎn)端倉庫猖辫,則需要從遠(yuǎn)端倉庫中刪除該文件,.gitignore文件才能實(shí)際生效砚殿。
解決方法就是先把本地緩存刪除(改變成未被追蹤狀態(tài))住册,然后再提交(push),這樣就不會(huì)出現(xiàn)忽略的文件了瓮具。git
清除本地緩存命令如下:
git rm -r --cached . 去掉已經(jīng)托管的所有文件
git add . 添加文件
git commit -m '本地提交的comment' 提交
2.忽略本地修改
- 本地開發(fā)中需要用的文件,不能提交到遠(yuǎn)程凡人,但是還不能寫入.gitignore文件名党。
- 遠(yuǎn)程倉庫里已存在的文件,在本地進(jìn)行修改了.但是不想提交到遠(yuǎn)程倉庫里面去(例如一些編輯器的配置文件,不同版本的編輯器配置文件可能不同.但是初始化倉庫時(shí)沒有做好.gitignore的配置導(dǎo)致配置文件被添加到版本庫里面了
此時(shí),要么在.gitignore里面添加忽略規(guī)則再把緩存修改)。
git update-index --assume-unchanged /XX/XX/XXX.file
本地忽略單個(gè)文件
git ls-files -z | xargs -0 git update-index --assume-unchanged
進(jìn)入文件夾中(忽略文件夾中所有的文件)
git ls-files -v | grep '^h\ '
找出所有被忽略的文件
git ls-files -v | grep '^h\ ' | awk '{print $2}'
找出所有被忽略的文件路徑
git update-index –no-assume-unchanged –path /XX/XX/XXX.file
取消單個(gè)忽略文件
git ls-files -v | grep '^h' | awk '{print $2}' |xargs git update-index --no-assume-unchanged
取消所有被忽略的文件
注意: 這種方式也有一個(gè)副作用挠轴,如果本地被忽略的該文件在本地被修改了传睹,遠(yuǎn)程的該文件也被其他人修改了。那在拉取遠(yuǎn)程分支時(shí)岸晦,由于本地和遠(yuǎn)程文件存在不一致的更新欧啤,會(huì)導(dǎo)致拉取不成功的問題。此時(shí)應(yīng)該先取消文件忽略启上,再進(jìn)行拉取操作邢隧。
四.Git分支合并
merge兩種模式
merge一般有兩種模式:
- Fast forward模式
通常,合并分支時(shí)冈在,如果沒有分歧解決倒慧,就會(huì)直接移動(dòng)文件指針,這就是Fast forward模式,也是merge默認(rèn)的模式纫谅。
舉例來說炫贤,開發(fā)一直在master分支進(jìn)行,但忽然有一個(gè)新的想法付秕,于是新建了一個(gè)dev的分支兰珍,并在其上進(jìn)行一系列提交,完成時(shí)询吴,回到master分支掠河,
此時(shí),master分支在創(chuàng)建dev分支之后并未產(chǎn)生任何新的commit汰寓。master分支合并dev分支并不會(huì)產(chǎn)生新的commit. 以后當(dāng)合并分支被刪除時(shí)口柳,也就不知道對應(yīng)的提交是來自于哪個(gè)分支。
此時(shí)的合并就叫fast forward有滑。如果想在這樣的的情況下也自動(dòng)生成一個(gè)commit跃闹,記錄此次合并就可以用:git merge --no-ff模式。
- --no-ff模式
git merge --no-ff -m "merge with no-ff" dev
因?yàn)楸敬魏喜⒁獎(jiǎng)?chuàng)建一個(gè)新的commit毛好,所以加上-m參數(shù)望艺,把commit描述寫入。
總結(jié):fast forward能夠保證不會(huì)強(qiáng)制覆蓋別人的代碼肌访,確保了多人協(xié)同開發(fā)找默。盡量不要使用non fast forward方法提交代碼。
merge沖突問題
git沖突的場景:
- 情景一:多個(gè)分支代碼合并到一個(gè)分支時(shí)吼驶;
- 情景二:多個(gè)分支向同一個(gè)遠(yuǎn)端分支推送代碼時(shí)惩激;
實(shí)際上,push操作即是將本地代碼merge到遠(yuǎn)端庫分支上蟹演。push和pull其實(shí)就分別是用本地分支合并到遠(yuǎn)程分支 和 將遠(yuǎn)程分支合并到本地分支 所以這兩個(gè)過程中也可能存在沖突风钻。
git的合并中產(chǎn)生沖突的具體情況:
- 兩個(gè)分支中修改了同一個(gè)文件(不管什么地方)
- 兩個(gè)分支中修改了同一個(gè)文件的名稱
兩個(gè)分支中分別修改了不同文件中的部分,不會(huì)產(chǎn)生沖突酒请,可以直接將兩部分合并骡技。
merge解決沖突
- 先本地直接提交代碼:git push origin master
- 如果別人在自己之前提交了修改,git會(huì)提示push失敗羞反,需要先pull遠(yuǎn)程代碼:git pull origin/master
- (拉取遠(yuǎn)程倉庫進(jìn)行自動(dòng)合并) 如果能自動(dòng)合并布朦,git會(huì)提示auto merge成功,這時(shí)可以直接git push origin master如果不能自動(dòng)merge昼窗,git會(huì)提示auto merge失敗是趴,
- 需要手動(dòng)解決沖突:git status 查看沖突情況修改沖突git status 查看沖突解決情況git add .git commit -m '解決沖突的注釋說明'git push origin master
避免產(chǎn)生沖突
現(xiàn)代軟件開發(fā)項(xiàng)目中,代碼沖突是不可避免的膏秫,但我們應(yīng)該盡量減少?zèng)_突的產(chǎn)生右遭,避免不必要的沖突做盅。下面列舉一下實(shí)踐經(jīng)驗(yàn):
- 工作在不同的分支上,并經(jīng)常性的同步主代碼窘哈,如果由于項(xiàng)目要求吹榴,比如長期開發(fā)一個(gè)功能使得該功能代碼在開發(fā)完成之前合并到主分支,此時(shí)我們雖然沒有辦法經(jīng)常合并代碼到主分支滚婉,也至少需要經(jīng)常性的同步主分支代碼到開發(fā)分支上
图筹,避免在最終合并到主分支上時(shí)產(chǎn)生過多沖突。 - 盡量使用短生命周期分支而非長期分支让腹。
- 除了技術(shù)層面的手段远剩,也可以通過項(xiàng)目管理上的手段來盡量避免,例如:不要同時(shí)將相同組件開發(fā)的不同任務(wù)分給不同的開發(fā)者骇窍,否則在合并代碼時(shí)該組件將會(huì)產(chǎn)生過多的沖突瓜晤。
各組件開發(fā)小組之間經(jīng)常性的溝通,互相了解各自的開發(fā)狀態(tài)腹纳,在可能產(chǎn)生沖突的時(shí)候及時(shí)采取手段痢掠。
merge和rebase(變基)
merge 會(huì)把公共分支和你當(dāng)前的commit 合并在一起,形成一個(gè)新的 commit 提交:
rebase會(huì)把你當(dāng)前分支的 commit 放到公共分支的最后面,所以叫變基嘲恍。就好像你從公共分支又重新拉出來這個(gè)分支一樣足画。
舉例:如果你從 master 拉了個(gè)feature分支出來,然后你提交了幾個(gè) commit,這個(gè)時(shí)候剛好有人把他開發(fā)的東西合并到 master 了,
這個(gè)時(shí)候 master 就比你拉分支的時(shí)候多了幾個(gè) commit,如果這個(gè)時(shí)候你 rebase master 的話,就會(huì)把你當(dāng)前的幾個(gè) commit佃牛,放到那個(gè)人 commit 的后面淹辞。此時(shí)切換到master分支再用merge進(jìn)行合并即可.
優(yōu)點(diǎn)
- rebase最大的好處是你的項(xiàng)目歷史會(huì)非常整潔
- rebase 導(dǎo)致最后的項(xiàng)目歷史呈現(xiàn)出完美的線性——你可以從項(xiàng)目終點(diǎn)到起點(diǎn)瀏覽而不需要任何的 fork。這讓你更容易使用 git log俘侠、git bisect 和 gitk 來查看項(xiàng)目歷史
缺點(diǎn) - 安全性象缀,如果你違反了 rebase 黃金法則,重寫項(xiàng)目歷史可能會(huì)給你的協(xié)作工作流帶來災(zāi)難性的影響
-
可跟蹤性爷速,rebase 不會(huì)有合并提交中附帶的信息——你看不到 feature 分支中并入了上游的哪些更改
- 可以看出merge結(jié)果能夠體現(xiàn)出時(shí)間線攻冷,但是rebase會(huì)打亂時(shí)間線。
- 而rebase看起來簡潔遍希,但是merge看起來不太簡潔。
- 最終結(jié)果是都把代碼合起來了里烦,所以具體怎么使用這兩個(gè)命令看項(xiàng)目需要凿蒜。
注意:
- 不要在公共分支使用rebase
- 本地和遠(yuǎn)端對應(yīng)同一條分支,優(yōu)先使用rebase,而不是merge
五.Git暫存與恢復(fù)
git stash命令作用
- 當(dāng)正在dev分支上開發(fā)某個(gè)項(xiàng)目,這時(shí)項(xiàng)目中出現(xiàn)一個(gè)bug胁黑,需要緊急修復(fù)废封,但是正在開發(fā)的內(nèi)容只是完成一半,還不想提交丧蘸,這時(shí)可以用git stash命令將修改的內(nèi)容保存至堆棧區(qū)漂洋,
然后順利切換到hotfix分支進(jìn)行bug修復(fù),修復(fù)完成后,再次切回到dev分支刽漂,從堆棧中恢復(fù)剛剛保存的內(nèi)容演训。 - 由于疏忽,本應(yīng)該在dev分支開發(fā)的內(nèi)容贝咙,卻在master上進(jìn)行了開發(fā)样悟,需要重新切回到dev分支上進(jìn)行開發(fā),可以用git stash將內(nèi)容保存至堆棧中庭猩,切回到dev分支后窟她,再次恢復(fù)內(nèi)容即可。
git stash命令的作用就是將目前還不想提交的但是已經(jīng)修改的內(nèi)容進(jìn)行保存至堆棧中蔼水,后續(xù)可以在某個(gè)分支上恢復(fù)出堆棧中的內(nèi)容震糖。這也就是說,stash中的內(nèi)容不僅僅可以恢復(fù)到原先開發(fā)的分支趴腋,也可以恢復(fù)到其他任意指定的分支上吊说。
git stash作用的范圍包括工作區(qū)和暫存區(qū)中的內(nèi)容,也就是說沒有提交的內(nèi)容都會(huì)保存至堆棧中于样。
-
git stash
能夠?qū)⑺形刺峤坏男薷模üぷ鲄^(qū)和暫存區(qū))保存至堆棧中疏叨,用于后續(xù)恢復(fù)當(dāng)前工作目錄。 -
git stash save "notes"
作用等同于git stash穿剖,區(qū)別是可以加一些注釋 -
git stash list
查看當(dāng)前stash中的內(nèi)容 -
git stash pop id
將當(dāng)前stash中的內(nèi)容彈出蚤蔓,并應(yīng)用到當(dāng)前分支對應(yīng)的工作目錄上,id是可選項(xiàng),默認(rèn)時(shí)上一次暫存,通過git stash list可查看具體值糊余。只能恢復(fù)一次. -
git stash apply id
將堆棧中的內(nèi)容應(yīng)用到當(dāng)前目錄秀又,不同于git stash pop,該命令不會(huì)將內(nèi)容從堆棧中刪除贬芥,可以恢復(fù)多次.也就說該命令能夠?qū)⒍褩5膬?nèi)容多次應(yīng)用到工作目錄中吐辙,適應(yīng)于多個(gè)分支的情況。 -
git stash drop stash id
刪除某個(gè)保存蘸劈,id是可選項(xiàng)昏苏,通過git stash list可查看具體值 -
git stash clear
刪除所有保存的快照
六.Git去除大文件
- 首先找出git中前五大的文件:
或者:git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
或者:git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
git rev-list --all | xargs -rL1 git ls-tree -r --long | sort -uk3 | sort -rnk4 | head -10
- 用第一步文件的id找出文件名:
git rev-list --objects --all | grep fileId
- 刪除文件提交記錄
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <your-file-name>' rm -rf .git/refs/original/ git reflog expire --expire=now --all git fsck --full --unreachable git repack -A -d git gc --aggressive --prune=now git push --force
七.Git Flow(版本管理工作流)
Git 作為一個(gè)源碼管理系統(tǒng),不可避免涉及到多人協(xié)作威沫。為了避免協(xié)作過程中產(chǎn)生混亂贤惯,必須有一個(gè)規(guī)范的工作流程,讓大家有效地合作棒掠,使得項(xiàng)目井井有條地發(fā)展下去孵构。Gitflow是基于Git的強(qiáng)大分支能力所構(gòu)建的一套軟件開發(fā)工作流,這些流程應(yīng)被視作為指導(dǎo)方針烟很,而非“鐵律”颈墅。Gitflow使用多個(gè)分支來記錄項(xiàng)目開發(fā)的歷史蜡镶,而不是使用單一的master分支。
1.主要分支
主要分支包括Master和Develop恤筛,前者用于正式發(fā)布官还,后者用于日常開發(fā)。常設(shè)分支只需要這兩條就夠了叹俏,不需要其他的了妻枕。
Master分支(主):
Git主分支的名字,默認(rèn)叫做Master粘驰。該分支上的代碼隨時(shí)可以部署到生產(chǎn)環(huán)境屡谐, 這個(gè)分支只能從其他分支合并,并且不能在這個(gè)分支做任何直接修改蝌数。每次版本封版后由主程序員合并release
分支代碼進(jìn)來愕掏,發(fā)布完成以后打上tag,開發(fā)人員不可以隨意操作顶伞。
develop分支(開發(fā)):
用來開發(fā)的分支饵撑,通常可以直接在其上進(jìn)行開發(fā)唆貌,在每次發(fā)布版本(release)和線上緊急bug(hotfix)修復(fù)后滑潘,需要同步到其上。理論上此版本只在開發(fā)階段使用锨咙,提測時(shí)不可以直接修改语卤,而在測試結(jié)束后由release
分支合并到其上。如果想正式對外發(fā)布酪刀,就在Master分支上粹舵,對Develop分支進(jìn)行"合并"(merge)。
2.臨時(shí)性分支
除了常設(shè)分支以外骂倘,還有一些臨時(shí)性分支眼滤,用于應(yīng)對一些特定目的的版本開發(fā)。臨時(shí)性分支主要有三種:功能分支 (feature)历涝,預(yù)發(fā)布分支 (release)诅需,修補(bǔ)bug分支 (fixbug),這三種分支都屬于臨時(shí)性需要荧库,使用完以后诱担,應(yīng)該刪除,使得代碼庫的常設(shè)分支始終只有Master和Develop电爹。
release分支(預(yù)發(fā)布):
在發(fā)布正式版本之前(即develop合并到Master分支之前),我們可能需要有一個(gè)預(yù)發(fā)布的版本進(jìn)行測試料睛。預(yù)發(fā)布分支是從Develop分支上面分出來的丐箩,所有測試階段的bug全部在此分支修復(fù)摇邦,測試結(jié)束后,必須合并進(jìn)Develop和Master分支屎勘。它的命名施籍,可以采用release-xx的形式。
feature分支(功能):
為了開發(fā)某種特定功能概漱,從Develop分支上面分出來的丑慎。開發(fā)完成后,要再并入Develop瓤摧。功能分支的名字竿裂,可以采用feature-XX的形式命名。如果在團(tuán)隊(duì)開發(fā)時(shí)照弥,有一個(gè)功能的開發(fā)周期要長過本次版本開發(fā)周期腻异,建議開啟一個(gè) feature
進(jìn)行單獨(dú)開發(fā),當(dāng)需要此功能的時(shí)候这揣,只需要將 feature
合并入 develop
分支悔常,下次一并提測即可。這樣設(shè)計(jì)可以避免這個(gè)功能在尚未開發(fā)完成或者通過測試的時(shí)候混入發(fā)布的版本给赞,而導(dǎo)致不可預(yù)知的不穩(wěn)定机打。當(dāng)然也可以同時(shí)開啟多個(gè) feature
分支進(jìn)行不同新功能開發(fā),在合適的時(shí)候合并提測即可片迅。
hotfix分支(bug修復(fù)):
軟件正式發(fā)布以后残邀,難免會(huì)出現(xiàn)bug。這時(shí)就需要?jiǎng)?chuàng)建一個(gè)分支障涯,進(jìn)行bug修補(bǔ)罐旗。修補(bǔ)bug分支是從Master分支上面分出來的。修補(bǔ)結(jié)束以后唯蝶,再合并進(jìn)Master和Develop分支九秀。它的命名,可以采用fixbug-XX的形式粘我。線上bug修復(fù)的熱補(bǔ)丁分支鼓蜒,應(yīng)由 master
拉出,并在修復(fù)完成后合并入 master
和 develop
保證兩分支的bug已修復(fù)征字。
3.新功能開發(fā)中都弹,各角色的工作流程
(1.)前置階段(新功能啟動(dòng))
開發(fā)主管--》基于master主干創(chuàng)建一個(gè)develop分支。
現(xiàn)有主干分支: master匙姜、develop
(2.)開發(fā)階段(開始開發(fā))
功能開發(fā)人員--》基于develop分支創(chuàng)建一個(gè)feature_XX分支
功能開發(fā)人員--》在feature_XX分支上開發(fā)新功能
功能開發(fā)人員--》新功能開發(fā)完成以后畅厢,在git上發(fā)起Pull request把代碼合并到到develop分支上
開發(fā)主管--》確認(rèn)代碼沒問題,通過該合并請求
現(xiàn)有主干分支: master氮昧、develop框杜、feature_XX
(3.)測試階段(開發(fā)完畢)
開發(fā)主管--》基于develop分支創(chuàng)建一個(gè)分支名為release-1.0.0的預(yù)發(fā)布版本
測試人員--》對release-1.0.0分支的代碼進(jìn)行測試浦楣,測試通過在git發(fā)起Pull request把release-1.0.0代碼合并到到master分支上。
現(xiàn)有主干分支: master咪辱、develop振劳、feature_XX、release-1.0.0
(4.)發(fā)布階段(測試通過)
開發(fā)主管--》基于master分支創(chuàng)建一個(gè)里程碑版本(tag)名為1.0.0-Release
刪除完成使命的其他分支:feature_login油狂、release-1.0.0
現(xiàn)有主干分支: master历恐、develop、1.0.0-Release(tag)
4.線上代碼出現(xiàn)bug時(shí)专筷,各角色的工作流程
(1)前置階段(提交bug)
測試人員--》發(fā)下問題弱贼,基于1.0.0-Release里程碑版本在git上新建一個(gè)issue
現(xiàn)有主干分支: master、develop仁堪、1.0.0-Release(tag)
(2)修復(fù)階段(開始修復(fù)bug)
功能開發(fā)人員--》基于1.0.0-Releasetag創(chuàng)建一個(gè)hotfix_XX(該issue序號(hào))分支哮洽,在hotfix_XX分支上修復(fù)bug,修復(fù)完成后弦聂,在git上發(fā)起Pull request把代碼合并到到master主干上
開發(fā)主管--》確認(rèn)代碼沒問題鸟辅,通過該合并請求
現(xiàn)有主干分支: master、develop莺葫、1.0.0-Release(tag)匪凉、hotfix_0001
(3)測試階段(bug修復(fù)完畢)
測試人員--》對master分支的代碼進(jìn)行測試
現(xiàn)有主干分支: master、develop捺檬、1.0.0-Release(tag)再层、hotfix_0001
(4)發(fā)布階段(測試通過)
開發(fā)主管--》基于master分支創(chuàng)建一個(gè)里程碑修復(fù)版本(tag)名為1.0.1-Release,刪除完成使命的其他分支:hotfix_XX
現(xiàn)有主干分支: master堡纬、develop聂受、1.0.0-Release(tag)、1.0.1-Release(tag)
八.常見問題.
第一次輸入錯(cuò)誤的gitlab用戶名和密碼烤镐,第二次clone不彈框提示輸入用戶名和密碼的解決方案蛋济。
git clone remote: HTTP Basic: Access denied
方式一:在控制面板里面將憑證刪除.
方式二:使用git命令重置憑證.
git config --system --unset credential.helper
git config --global credential.helper store