在日常工作中, 經常會用到Git操作。 但是對於新人來講, 剛上來對Git很陌生, 操作起來也很懵逼。 本篇文章主要針對剛開始接觸Git的新人, 理解Git的基本原理, 掌握常用的一些命令。
一、Git工作流程
以上包括一些簡單而常用的命令, 但是先不關心這些, 先來瞭解下面這4個專有名詞。
Workspace:工作區
Index / Stage:暫存區
Repository:倉庫區(或本地倉庫)
Remote:遠端倉庫
工作區
程式師進行開發改動的地方, 是你當前看到的, 也是最新的。
平常我們開發就是拷貝遠端倉庫中的一個分支, 基於該分支進行開發。 在開發過程中就是對工作區的操作。
暫存區
.git目錄下的index檔, 暫存區會記錄git add添加檔的相關資訊(檔案名、大小、timestamp...),
當你完成某個需求或功能後需要提交到遠端倉庫, 那麼第一步就是通過git add先提交到暫存區, 被git管理。
本地倉庫
保存了物件被提交 過的各個版本, 比起工作區和暫存區的內容, 它要更舊一些。
git commit後同步index的目錄樹到本地倉庫, 方便從下一步通過git push同步本地倉庫與遠端倉庫的同步。
遠端倉庫
遠端倉庫的內容可能被分佈在多個地點的處於協作關係的本地倉庫修改, 因此它可能與本地倉庫同步, 也可能不同步, 但是它的內容是最舊的。
小結
任何物件都是在工作區中誕生和被修改;
任何修改都是從進入index區才開始被版本控制;
只有把修改提交到本地倉庫, 該修改才能在倉庫中留下痕跡;
與協作者分享本地的修改, 可以把它們push到遠端倉庫來共用。
下面這幅圖更加直接闡述了四個區域之間的關係, 可能有些命令不太清楚, 沒關係, 下部分會詳細介紹。
二、常用Git命令
網上找了個圖, 別人整理的一張圖, 很全很好, 借來用下。 下面詳細解釋一些常用命令。
HEAD
在掌握具體命令前, 先理解下HEAD。
HEAD, 它始終指向當前所處分支的最新的提交點。 你所處的分支變化了, 或者產生了新的提交點, HEAD就會跟著改變。
add
add相關命令很簡單, 主要實現將工作區修改的內容提交到暫存區, 交由git管理。
git add .添加目前的目錄的所有檔到暫存區git addcommit
commit相關命令也很簡單, 主要實現將暫存區的內容提交到本地倉庫,
branch
涉及到協作, 自然會涉及到分支, 關於分支, 大概有展示分支, 切換分支, 創建分支,刪除分支這四種操作。
git branch列出所有本地分支git branch -r列出所有遠端分支git branch -a列出所有本地分支和遠端分支git branch關於分支的操作雖然比較多,但都比較簡單好記。
merge
merge命令把不同的分支合併起來。如上圖,在實際開放中,我們可能從master分支中切出一個分支,然後進行開發完成需求,中間經過R3,R4,R5的commit記錄,最後開發完成需要合入master中,這便用到了merge。
git fetch一般在merge之後,會出現conflict,需要針對衝突情況,手動解除衝突。主要是因為兩個用戶修改了同一檔的同一塊區域。如下圖所示,需要手動解除。
rebase
rebase又稱為衍合,是合併的另外一種選擇。
在開始階段,我們處於new分支上,執行git rebase dev,那麼new分支上新的commit都在master分支上重演一遍,最後checkout切換回到new分支。這一點與merge是一樣的,合併前後所處的分支並沒有改變。git rebase dev,通俗的解釋就是new分支想站在dev的肩膀上繼續下去。rebase也需要手動解決衝突。
rebase與merge的區別
現在我們有這樣的兩個分支,test和master,提交如下:
D---E test在master執行git merge test,然後會得到如下結果:
D--------E在master執行git rebase test,然後得到如下結果:
A---B---D---E---C'---F' test, master可以看到,merge操作會生成一個新的節點,之前的提交分開顯示。而rebase操作不會生成新的節點,是將兩個分支融合成一個線性的提交。
如果你想要一個乾淨的,沒有merge commit的線性歷史樹,那麼你應該選擇git rebase
如果你想保留完整的歷史記錄,並且想要避免重寫commit history的風險,你應該選擇使用git merge
reset
reset命令把當前分支指向另一個位置,並且相應的變動工作區和暫存區。
git reset —softrevert
git revert用一個新提交來消除一個歷史提交所做的任何修改。
revert與reset的區別
git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit。
在回滾這一操作上看,效果差不多。但是在日後繼續merge以前的老版本時有區別。因為git revert是用一次逆向的commit“中和”之前的提交,因此日後合併老的branch時,導致這部分改變不會再次出現,減少衝突。但是git reset是之間把某些commit在某個branch上刪除,因而和老的branch再次merge時,這些被回滾的commit應該還會被引入,產生很多衝突。關於這一點,不太理解的可以看這篇文章。
git reset 是把HEAD向後移動了一下,而git revert是HEAD繼續前進,只是新的commit的內容和要revert的內容正好相反,能夠抵消要被revert的內容。
push
上傳本地倉庫分支到遠端倉庫分支,實現同步。
git push其他命令
git status顯示有變更的檔git log顯示當前分支的版本歷史git diff顯示暫存區和工作區的差異git diff HEAD顯示工作區與當前分支最新commit之間的差異git cherry-pick以上就是關於Git的一些常用命令及詳細闡述,相信能對Git有一個初步的認識。
創建分支,刪除分支這四種操作。git branch列出所有本地分支git branch -r列出所有遠端分支git branch -a列出所有本地分支和遠端分支git branch關於分支的操作雖然比較多,但都比較簡單好記。
merge
merge命令把不同的分支合併起來。如上圖,在實際開放中,我們可能從master分支中切出一個分支,然後進行開發完成需求,中間經過R3,R4,R5的commit記錄,最後開發完成需要合入master中,這便用到了merge。
git fetch一般在merge之後,會出現conflict,需要針對衝突情況,手動解除衝突。主要是因為兩個用戶修改了同一檔的同一塊區域。如下圖所示,需要手動解除。
rebase
rebase又稱為衍合,是合併的另外一種選擇。
在開始階段,我們處於new分支上,執行git rebase dev,那麼new分支上新的commit都在master分支上重演一遍,最後checkout切換回到new分支。這一點與merge是一樣的,合併前後所處的分支並沒有改變。git rebase dev,通俗的解釋就是new分支想站在dev的肩膀上繼續下去。rebase也需要手動解決衝突。
rebase與merge的區別
現在我們有這樣的兩個分支,test和master,提交如下:
D---E test在master執行git merge test,然後會得到如下結果:
D--------E在master執行git rebase test,然後得到如下結果:
A---B---D---E---C'---F' test, master可以看到,merge操作會生成一個新的節點,之前的提交分開顯示。而rebase操作不會生成新的節點,是將兩個分支融合成一個線性的提交。
如果你想要一個乾淨的,沒有merge commit的線性歷史樹,那麼你應該選擇git rebase
如果你想保留完整的歷史記錄,並且想要避免重寫commit history的風險,你應該選擇使用git merge
reset
reset命令把當前分支指向另一個位置,並且相應的變動工作區和暫存區。
git reset —softrevert
git revert用一個新提交來消除一個歷史提交所做的任何修改。
revert與reset的區別
git revert是用一次新的commit來回滾之前的commit,git reset是直接刪除指定的commit。
在回滾這一操作上看,效果差不多。但是在日後繼續merge以前的老版本時有區別。因為git revert是用一次逆向的commit“中和”之前的提交,因此日後合併老的branch時,導致這部分改變不會再次出現,減少衝突。但是git reset是之間把某些commit在某個branch上刪除,因而和老的branch再次merge時,這些被回滾的commit應該還會被引入,產生很多衝突。關於這一點,不太理解的可以看這篇文章。
git reset 是把HEAD向後移動了一下,而git revert是HEAD繼續前進,只是新的commit的內容和要revert的內容正好相反,能夠抵消要被revert的內容。
push
上傳本地倉庫分支到遠端倉庫分支,實現同步。
git push其他命令
git status顯示有變更的檔git log顯示當前分支的版本歷史git diff顯示暫存區和工作區的差異git diff HEAD顯示工作區與當前分支最新commit之間的差異git cherry-pick以上就是關於Git的一些常用命令及詳細闡述,相信能對Git有一個初步的認識。