聲明:由於本人對於Git的學習還處於摸索階段,對有些概念的理解或許只是我斷章取義,有曲解誤導的地方還請見諒指正!
一、分支1.1分支的概念。
對於的分支的理解,我們可以用模組化這個詞來解釋;在日常工作中,一個項目的開發模式往往是模組化,團隊協作式的開發。這樣我們項目的進度可以稱得上多核並髮式的開發了。這種模組化的開發要求我們儘可能的高內聚低耦合以免造成一隻胳膊沒了整個人都廢了的局面。因此在所有的版本控制器對代碼進行管理的時候都引入了分支這個概念。那麼分支是什麼呢?
分支是相對於主幹來說的,或者是相對於主分支來說的,它是用來將特性開發絕緣開來的。我們在建立倉庫的時候,系統會預設建立master分支,也就是我們預設的主幹分支。當我們開發一個項目的時候,在架構搭建完成後,需要開發一個一個模組的功能的時候,我們往往會建立一個一個的分支來進行分別開發,沒跟人都在自己的一畝三分地裡勞作,相互沒有影響,當某一項功能或者模組開發完成通過測試的時候在整合到主架構上,這樣做的好處是,可以避免單個模組的開發工作的缺陷造成整個架構系統無法編譯通過,無法正常運轉。如果你是一個Android開發人員,我們可以用主線程(UI)線程和子線程來理解,比較類似的是當我們建立一個Activity的時候,系統會預設建立一個主線程,也就是我們的UI線程,如果我們在需要訪問網路擷取資料的時候(耗時操作),我們一般的做法就是我們會重新開啟一個子線程進行遠端資料的擷取與解析,當我們完成資料讀取操作後在對UI線程進行更新,以免耗時操作造成UI線程的阻塞(ANR)。
1.2建立分支與分支合并
我們每次執行提交的時候,git都會把它們串成一條時間軸,這條時間軸就是一個分支。經過前一階段的學習,我們知道,在我們的倉庫中只有一個主分支,也就是只有一條時間軸,隨著我們每一次的提交,master分支的時間想也就越長。當我們需要開發一個新的功能的時候,我們可以建立一個分支的時候(dev)來進行該功能模組的開發工作,Git就會同時建立了一個指標(dev),把HEAD指向dev分支,表示當前分支在dev上。那麼對工作區的修改和提交就是在dev分支上了,我們每一次提交後,dev指標就會往前移動一次,不會影響到master分支。當我們在dev分支上的開發工作完成以後,通過測實驗證後,再把dev分支與master進行合并。那麼如何合并呢?我們可以讓master分支指向dev分支(dev分支又指向當前分支下的最後一次提交)的當前提交,也就是把這個dev分支作為master主幹分支的一次修改來進行提交,這樣就完成了合并。合并完成後我們甚至可以刪除被合并的dev分支。
下面我們來進行實際的命令操作:
1.2.1 建立分支
$ git branch dev
!注意:執行上述命令,沒有任何提示!
1.2.2切換分支
$ git checkout devSwitched to branch 'dev'
!注意:
1.2.3建立並切換分支命令
使用git checkout命令加上-b參數表示建立並切換分支,相當於上述兩條命令;
$ git checkout -b dev
1.2.4查看當前分支
$ git branch* dev master
綠色部分為當前分所在的分支。
STAR@STAR-PC ~/learngit (dev)$ git add test.txtSTAR@STAR-PC ~/learngit (dev)$ git commit -m "create new branch"[dev cee7bfc] create new branch 1 file changed, 2 insertions(+), 1 deletion(-)
STAR@STAR-PC ~/learngit (dev)
$ git commit -m "create new branch"
[dev cee7bfc] create new branch
1 file changed, 2 insertions(+), 1 deletion(-)
上述代碼在dev分之下提交修改。
STAR@STAR-PC ~/learngit (dev)$ git checkout masterSwitched to branch 'master'Your branch is ahead of 'origin/master' by 1 commit. (use "git push" to publish your local commits)
上述命令是我們在dev分之下條修改後進行的分支切換操作,此時我們查看工作區,則在dev分支下的修改並不存在。此時若想在master看到我們在dev分支下的修改,則需要合并分支。
$ git merge devUpdating 94bf25d..cee7bfcFast-forward test.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
上述命令的執行完成了整合,此時查看工作區的檔案發現,主分支下的檔案已經能夠看到之前在dev分支下的修改了。
注意!上述命令執行後列印的提示資訊中的“Fast-forward”,告訴我們此次合并為“快進模式”也就是直接讓master指標指向dev的當前提交。
1.2.5刪除分支
由於之前的內容我們提到過,在分支合并後我們可以刪除已經合并的分支,因此我們來刪除dev分支,並查看所有分支。
STAR@STAR-PC ~/learngit (master)$ git branch -d devDeleted branch dev (was cee7bfc).STAR@STAR-PC ~/learngit (master)$ git branch* master
提示資訊告訴我們dev分支已刪除,剩餘分支為master,綠色表示當前分支為master
1.3解決分支合并衝突
你看到這個題目的時候或許心裡會有疑惑?上述的操作不是很順利嗎?怎麼會有衝突呢?
我們回頭看看上述分支合并的操作就會發現,我們在合并分支的時候,建立分支dev有改動,而master分支沒有提交任何修改,但是如果我們在合并分支的時候,master和dev分支均提交了修改呢?這樣一來合并分支會還會一帆風順嗎?我們帶著這個問題來進行接下來的操作。
我們首先建立一個分支dev,然後分別在兩個分支上提交修改。
STAR@STAR-PC ~/learngit (master)$ git checkout -b dev2Switched to a new branch 'dev2'STAR@STAR-PC ~/learngit (dev2)$ git add test.txtSTAR@STAR-PC ~/learngit (dev2)$ git commit -m "create a new brance dev2"[dev2 046661c] create a new brance dev2 1 file changed, 2 insertions(+), 1 deletion(-)STAR@STAR-PC ~/learngit (dev2)$ git switch mastergit: 'switch' is not a git command. See 'git --help'.STAR@STAR-PC ~/learngit (dev2)$ git checkout masterSwitched to branch 'master'Your branch is ahead of 'origin/master' by 2 commits. (use "git push" to publish your local commits)STAR@STAR-PC ~/learngit (master)$ git add test.txtSTAR@STAR-PC ~/learngit (master)$ git commit -m "add a new line for master"[master 835e78c] add a new line for master 1 file changed, 2 insertions(+), 1 deletion(-)
合并分支:
$ git merge dev2Auto-merging test.txtCONFLICT (content): Merge conflict in test.txtAutomatic merge failed; fix conflicts and then commit the result.
根據上述提示資訊我們發現,test.txt檔案發生衝突,合并失敗。我們可以根據git status來查看衝突檔案。
$ git statusOn branch masterYour branch is ahead of 'origin/master' by 3 commits. (use "git push" to publish your local commits)You have unmerged paths. (fix conflicts and run "git commit")Unmerged paths: (use "git add <file>..." to mark resolution) both modified: test.txtno changes added to commit (use "git add" and/or "git commit -a")
或許我們也可以直接查看test.txt的內容:
<<<<<<< HEADadd a new line for master。=======create a new branch dev2.>>>>>>> dev2
git用<<<<<<,======,>>>>>>標記出不同分支的內容,我們可以對檔案進行修改如下;
add a new line for master。create a new branch dev2.
並在master進行提交:
STAR@STAR-PC ~/learngit (master|MERGING)$ git add test.txtSTAR@STAR-PC ~/learngit (master|MERGING)$ git commit -m "fixed"[master 51e165e] fixed
提示資訊告訴我們問題已經解決。接著我們就可以刪除dev2分支了。
$ git branch -d dev2Deleted branch dev2 (was 046661c).
!注意:我們之前的分至合併作業都是快速模式下執行的,但是在這種模式下刪除分支後,會丟失分支資訊。因此我們在合并分支的時候也可以採用no-ff方式,如下,有興趣的朋友可以自己進行測試。
$ git nerge --no-ff -m "merge with no-ff" dev
1.4分支的隱藏與恢複
如果我們在項目的開發過程中,需要暫時擱置當前分支的開發並在其他分之下進行操作,我們可以使用git stash對當前分支進行隱藏。
$ git checkout -b dev3Switched to a new branch 'dev3'STAR@STAR-PC ~/learngit (dev3)$ git add test.txtSTAR@STAR-PC ~/learngit (dev3)$ git commit -m "use stash"[dev3 d358fab] use stash 1 file changed, 2 insertions(+), 1 deletion(-)
查看狀態,並執行git stash命令
$ git statusOn branch dev3Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: test.txtno changes added to commit (use "git add" and/or "git commit -a")STAR@STAR-PC ~/learngit (dev3)$ git stashSaved working directory and index state WIP on dev3: d358fab use stashHEAD is now at d358fab use stash
切換回主分支進行提交修改操作。
$ git statusOn branch masterYour branch is ahead of 'origin/master' by 6 commits. (use "git push" to publish your local commits)Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: test.txtno changes added to commit (use "git add" and/or "git commit -a")STAR@STAR-PC ~/learngit (master)$ git add test.txtSTAR@STAR-PC ~/learngit (master)$ git commit -m "hello"[master 404a601] hello 1 file changed, 2 insertions(+), 1 deletion(-)
切換會dev3分支
STAR@STAR-PC ~/learngit (master)$ git checkout dev3Switched to branch 'dev3'
切換回分支之後,此時我們需要恢複現場。
首先查看隱藏的現場。
STAR@STAR-PC ~/learngit (dev3)$ git stash liststash@{0}: WIP on dev3: d358fab use stash
恢複現場的方式有兩種一種是使用git stash apply [stash@{0}],但是恢複後stash內容並不會刪除,我們需要手動執行git stash drop 來刪除。
第二種執行git stash pop,恢複的同時刪除stash的內容。
$ git stash popOn branch dev3Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: test.txtno changes added to commit (use "git add" and/or "git commit -a")Dropped refs/stash@{0} (6696a348f1e160fa3f234dff50eaad0d59e4d264)
dev3分支下完成修改後,執行合并分支的操作。
!注意:如果我們開發完成一個分支,準備切換到主分支進行合并的時候,卻發現該分支下的修改已經不需要了,這個時候我們如果要刪除該分支我們需要執行git branch -D [分支名]
1.5推送本地分支到遠程分支
一般來說我們都會在本地分支上進行修改和提交,然後與主幹分支進行合并,再刪除無用分支,因此我們向遠程分支進行推送的時候只需要推送主幹分支即可。
$ git push -u origin masterUsername for 'https://github.com': huangyabin001Password for 'https://huangyabin001@github.com':Counting objects: 31, done.Delta compression using up to 4 threads.Compressing objects: 100% (19/19), done.Writing objects: 100% (29/29), 2.23 KiB | 0 bytes/s, done.Total 29 (delta 9), reused 0 (delta 0)To https://github.com/huangyabin001/learngit.git 1cf2aaa..7b69267 master -> masterBranch master set up to track remote branch master from origin.
注意如果輸入git push origin master則會出現一下問題:
$ git push origin master
fatal: unable to access 'https://github.com/huangyabin001/learngit.git/': Empty
reply from server
二、自訂Git2.1用戶端配置2.1.1 core.editor
Git預設會調用你的環境變數editor定義的值作為文字編輯器,如果沒有定義的話,會調用vi來建立和編輯,我們可以使用core.editor改變預設編輯器。
$ git config --global core.editor emacs
2.1.2 help.autocorrect
該配置只在Git1.6.1及以上版本有效,如果你錯打了一條命令,會顯示:
$git com tig:'com' is not a git-command.See 'git --help'. Did you mean this?commit
2.2Git的著色
Git能夠為輸出到你終端的內容著色,以便你可以憑直觀的介面進行快速的分析。
Git會按照你的需要自動為大部分的輸出加上顏色
$git config --global color.ui true