git 工作原理
Workspace工作區(qū)
程序員進行開發(fā)改動的地方晶伦,是你當(dāng)前看到的聪黎,也是最新的。
平常我們開發(fā)就是拷貝遠程倉庫中的一個分支胳岂,基于該分支進行開發(fā)。在開發(fā)過程中就是對工作區(qū)的操作舔稀。
Index / Stage 暫存區(qū)
.git目錄下的index文件, 暫存區(qū)會記錄git add添加文件的相關(guān)信息(文件名乳丰、大小、timestamp...)内贮,不保存文件實體, 通過id指向每個文件實體产园。可以使用git status查看暫存區(qū)的狀態(tài)夜郁。暫存區(qū)標(biāo)記了你當(dāng)前工作區(qū)中什燕,哪些內(nèi)容是被git管理的。
當(dāng)你完成某個需求或功能后需要提交到遠程倉庫竞端,那么第一步就是通過git add先提交到暫存區(qū)屎即,被git管理。
Repository 本地倉庫
保存了對象被提交 過的各個版本事富,比起工作區(qū)和暫存區(qū)的內(nèi)容技俐,它要更舊一些。
git commit后同步index的目錄樹到本地倉庫统台,方便從下一步通過git push同步本地倉庫與遠程倉庫的同步雕擂。
遠程倉庫
遠程倉庫的內(nèi)容可能被分布在多個地點的處于協(xié)作關(guān)系的本地倉庫修改,因此它可能與本地倉庫同步贱勃,也可能不同步井赌,但是它的內(nèi)容是最舊的。
1.任何對象都是在工作區(qū)
中誕生和被修改募寨;
2.任何修改都是從進入index區(qū)
才開始被版本控制族展;
3.只有把修改提交到本地倉庫
,該修改才能在倉庫中留下痕跡拔鹰;
4.與協(xié)作者分享本地的修改仪缸,可以把它們push
到遠程倉庫來共享。
四個區(qū)域之間的關(guān)系
branch 分支
分支策略
在實際開發(fā)中列肢,應(yīng)該按照幾個基本原則進行分支管理:
(1).master分支
應(yīng)該是非常穩(wěn)定的恰画,僅用來發(fā)布新版本;
(2).開發(fā)都在dev分支
,比如1.0版本發(fā)布時瓷马,再把dev分支
合并到master
上拴还,在master
分支發(fā)布1.0版本;
(3).每個人都在dev
分支上干活欧聘,每個人都有自己的特性分支片林,時不時地往dev
分支上合并就可以了。
merge
操作會生成一個新的節(jié)點,之前的提交分開顯示
D---E test branch
/
A---B---C---F master branch
在master
執(zhí)行git merge test
,然后會得到如下結(jié)果:
D--------E
/ \
A---B---C---F----G master branch
在我們遇到:
1.自己本地add 并commit 但是還沒有 push 到遠端時,發(fā)現(xiàn)代碼有問題,
2.改完代碼匆忙提交,上線發(fā)現(xiàn)有問題,怎么辦?
3.改完代碼測試也沒有問題,但是上線發(fā)現(xiàn)你的修改影響了之前運行正常的代碼報錯,必須回滾.
處理上面的問題我們分 A.沒有push 使用 reset 和B.已經(jīng)push 使用 revert 兩種方式處理方式
1.沒有push 時 : 用到 reset (重置)
git reset [ --soft | --mixed | --hard ] [提交版本號]
(a) --soft
(溫柔的)保留源碼,只回退到commit
信息到某個版本.不涉及index
的回退,如果還需要提交,直接commit
即可.
(b) --mixed
(混合):會保留源碼,只是將git commit
和index
信息回退到了某個版本.
為默認(rèn)方式
git reset --mixed 等價于 git reset
(c) --hard
(牢固地) 源碼也會回退到某個版本,commit
和index
都會回退到某個版本.(注意,這種方式是改變本地代碼倉庫源碼)
注意
:當(dāng)在push代碼以后,也使用 git reset --hard <commit...>
回退代碼到某個版本之前,這樣會有一個問題,你線上的代碼沒有變,線上commit,index都沒有變,當(dāng)你把本地代碼修改完強制提交的時候可能會存在沖突
2.已經(jīng)push 需要使用 git revert (恢復(fù)原狀)
git revert [提交版本號]
git revert
用于反轉(zhuǎn)提交,執(zhí)行revert命令時要求工作樹必須是干凈的.git revert
用一個新提交來消除一個歷史提交所做的任何修改.revert 之后你的本地代碼會回滾到指定的歷史版本,這時你再 git push 既可以把線上的代碼更新.
git reset 與 git revert 區(qū)別
區(qū)別 git revert
是用一次新的commit
來回滾之前的commit
费封,git reset
是直接刪除指定的commit
看似達到的效果是一樣的,其實完全不同.
第一:上面我們說的如果你已經(jīng)push到線上代碼庫, reset
刪除指定commit
以后,你git push
可能導(dǎo)致一大堆沖突,如果落后于線上的版本提交時需要 使用 git push -f
force強制提交.但是revert
并不會.
第二:reset
是在正常的commit
歷史中,刪除了指定的commit
,這時 HEAD 是向后移動了,而 revert
是在正常的commit
歷史中再commit
一次,只不過是反向提交,他的 HEAD 是一直向前的.
問題
A:push 文件1.txt
B:push 文件1.txt(顯然沖突)焕妙,所以先pull,然后手工合并弓摘,假如合并過程中焚鹊,A又push 文件1.txt了。等B合并完韧献,push 文件1.txt時末患,又沖突掉了。