適宜人群
這是一篇關(guān)于 git 沖突入門級的介紹,以及簡略介紹 git 分支的應(yīng)用,大佬請繞行//手動齜牙
另外還有一篇非常好的最最基礎(chǔ)的git使用命令請參考這篇寫得很好的博客:Git操作詳解
背景
最近在做一個微信小程序,因為不再是自己一個人獨自開發(fā),而是和兩個組員一起開發(fā)小程序前端頁面
那么不能再像在 GitHub 中托管辣雞 demo 一樣,一直一條分支
直接 git pull origin master
然后git push origin master
然后看著 GitHub 又變綠了一點,發(fā)出一聲感嘆:“雖然今天的代碼一個都調(diào)不通,但是還是好累呢!”
剛開始其實三個人也是用的一個分支,即 master 分支,后來頁面數(shù)量多起來,愈發(fā)地混亂,而且小程序頁面注冊,還有全局變量的設(shè)置,都在根目錄下的app.js,app.json...中進行配置,(我重新整理后的)小程序目錄大概如下:

所以項目 git 上傳就一直沖突不斷,基本上傳一次就沖突一次
入坑
當(dāng)項目中的兩個成員同時修改一個文件(不是文件夾),然后分別上傳到遠程 git 倉庫就會產(chǎn)生沖突,一般 git 會整合的時候在發(fā)生沖突的文件中自動生成三方合并標記線(<<<<<<<、=======、>>>>>>>)來標識各個成員的不同修改
Fine,F(xiàn)or example
- 在 GitHub 上創(chuàng)建了一個測試項目來模擬遠程 git 倉庫
- 在電腦本地新建并使用兩個空文件夾
file1,file2模擬真實開發(fā)中的兩個項目成員- 在
file1,file2中分別clone下這個測試項目- 在
file1,file2先后修改clone到本地的測試項目中的同一個文件test.text中的內(nèi)容- 將修改后的
file1,file2先后push到GitHub,你會發(fā)現(xiàn)沖突
具體過程:
在 test.text 文件中, zb是模擬的公共配置項代碼

成員 file1 在公共代碼下面配置了自己的代碼: 甲的修改

成員 file2 在公共代碼下面配置了自己的代碼: 乙的修改

于是他們兩個在互不知情的情況下修改了同一個文件,分別 push 到遠程 git 倉庫
file1 先 pull,然后 push,這時候遠程的 git 倉庫中的 test.text 中的內(nèi)容變成了 file1 修改后的內(nèi)容
這時候 file2 在 pull 的時候就會產(chǎn)生沖突,因為遠程的 git 倉庫 test.text 中的第二行和 file2 本地
git 倉庫 test.text 中的第二行內(nèi)容不一樣,git 本身無法判斷到底保留哪個
所以就會自動處理沖突,全部保留下來,下面圖片就是 git 自動處理沖突后的打印出的信息:

git 并使用標記線標明代碼沖突來源和沖突的內(nèi)容,下圖就是
file2 的 test.text 在 git 自動處理沖突后打開時候的內(nèi)容(頓時感覺自己的代碼被下了毒)
稍稍解釋一哈這個里面的意思:
<<<<<<<HEAD 乙的修改
表示 git 提示這部分產(chǎn)生沖突的來源是HEAD,沖突的內(nèi)容是
乙的修改,這個 HEAD 是一個指針,指向的是file2的最新提交記錄
=======
分隔符,將沖突的內(nèi)容以及來源的不同信息隔開
甲的修改 >>>>>>>a35d5e7617aeb98bf382fa1a1af7579e976f9f4a
表示 git 提示這部分產(chǎn)生沖突來源是哈希值為
a35d5e7617aeb98bf382fa1a1af7579e976f9f4a的提交記錄(每一個提交 commit 都會有一個獨有的哈希值,通過哈希值可以找到這個提交的所有信息),沖突的內(nèi)容是甲的修改,這個提交記錄正是file1的提交
這時候你就要自己手動處理,看看到底保留哪一份代碼,或者還是都保留,然后刪掉這些 git 自己增加的字符,解決沖突后,繼續(xù) push 到遠程 git 倉庫
那么這時候問題來了,如果是一個兩個文件沖突還好,像我自己目前這個小程序包含了大量的項目頁面,配置等文件,每上傳一次,來一次沖突,沖突還是一大片的,這誰頂?shù)米。?/p>
我的微信小程序項目的沖突就是這樣,許多文件許多代碼段出現(xiàn)大量的<<<<<<<、=======、>>>>>>>標記符:

填坑
解決這個坑的思路是這樣的:
- 三個人分別建立自己的分支,每個人在自己的分支上提交記錄,互不干擾
- 將公共的要配置的代碼放在gitignore中不傳到遠程git倉庫中,最后合并分支再統(tǒng)一處理
分支思想
如果是單獨開發(fā),開發(fā)者可以選擇一條分支進行代碼托管
但是項目協(xié)作者一多,單分支就會出現(xiàn)問題:

上圖就是我之前的項目的問題,大家都在同一條分支上進行修改提交,不知不覺就會修改同一個文件,然后產(chǎn)生沖突的問題
所以就將每個人寫的項目獨立成一條分支,然后就在自己的分支上盡情修改,最后再合并成一條,這樣在開發(fā)的時候各個功能開發(fā)一起進行,互不影響,等各自完成后再合并部署,加快了進度和主分支的完整性和可用性

如圖,在
master 分支上第二次提交的節(jié)點上新建branch2分支,甲在 master 上繼續(xù)提交,乙在 branch2 上提交,互不干擾合并分支:

當(dāng)分支上的功能完成,我們可以將
branch2 分支合并到 master 分支上,如上圖所示,最后又合并成一條主分支,然后就可以進行完整功能測試和部署至服務(wù)器了那么問題來了,分支解決了沖突了么?
其實分支的目的就是避免沖突,互不影響,提高效率,如果兩位開發(fā)者在兩條不同的分支修改同一份文件,最后合并的時候還是會有沖突的,git 還是搞不清楚到底保留哪一份代碼,于是又會它自己解決沖突,又會出現(xiàn)那些三方合并標記線
所以項目的模塊劃分,低耦合性很重要,我這個項目的解決方式是將這些公共的經(jīng)常修改的配置文件等都在 .gitignore 中配置好,不傳到遠程 git 倉庫中,最后統(tǒng)一分支的時候手動選擇
相關(guān)命令
git branch
列出本地已經(jīng)存在的分支,并且在當(dāng)前分支的前面加 * 號標記
- git branch -r 列出遠程分支
- git branch -a 列出本地分支和遠程分支
- git branch branch2 創(chuàng)建一個新的叫
branch2的本地分支,但只是創(chuàng)建分支,沒有進行分支切換
git chekout
切換分支
- git checkout master 切換到
master分支 - git checkout -b branch2 新建并且切換到一條名為
branch2的新分支
即這條命令包含了兩個過程:
1.git branch branch2 新建branch2分支
2.git checkout branch2 指針 HEAD 指向切換到branch2分支(也就是目前你都是在branch2分支上修改)
git pull origin master
git push origin master
將本地 git 倉庫的 master 分支 push 到遠程的test分支中,照例還是要先 pull,后push
git log
打印git的提交記錄,后面可以跟參數(shù)
1.git log --oneline 可以使每條日志以簡短的形式一行輸出
2.git log --graph 可以使日志以圖的形式打印
參數(shù)可以連用,即:git log --oneline --graph 功能疊加
舉個例子:創(chuàng)建,合并分支過程
- git init
在空文件下初始化git - 在初始化 git 后的文件夾中創(chuàng)建并編輯相關(guān)代碼文件
- git add .
將自己修改好的代碼添加到暫存區(qū)(add后面有個空格和 . ) -
git commit -m "master第一次提交"
將暫存區(qū)的代碼提交到本地 git 倉庫中
此時的本地 git 倉庫:
- git checkout -b branch2
新建并且切換到branch2新分支
這時候一個節(jié)點就包含了兩個指針,一個master,一個branch2:
- 兩次 git commit
因為兩個指針都包含在一個節(jié)點,所以要分離開兩個指針,使之成為兩條獨立的分支
當(dāng)前 HEAD 指向branch2,所以直接輸入git commit
然后切換至master分支:git checkout master,繼續(xù)輸入:git commit
- 這時候不同開發(fā)者就可以在各個分支上進行修改
假設(shè)master分支上提交了一次,branch2分支上也提交了一次 - git checkout master
如果在其他分支,這時候切換至master分支,準備合并 - git merge branch2
如果在其他分支,先使用git checkout master命令切換至master分支
再使用git merge branch2將branch2合并至master分支 - git commit
再使用commit,使 git 分支樹徹底合并:
10.git log --oneline --graph
之前的圖示都是我自己繪的,如果使用控制臺查看 git 的歷史提交記錄,就是這樣:
如果你也是一步步按照我的步驟,這就是最后打印出來的圖示!
坑外話
其實 git 博大精深,林納斯作為 git 的創(chuàng)造者,畢竟是影響世界 IT 進程的程序員,牛皮不是沒有道理的,我這里也只是小敘一波,有什么錯誤的不清晰的地方請大佬們指教,以后有什么更深入的理解也會持續(xù)更新(撒花)




