目錄
- 前言
- 本地倉庫 (使用Sourcetree)
- 遠程倉庫 (使用GitHub)
前言
本文僅簡單討論代碼的版本控制, 包括版本提交、分支、遠程倉庫的拉取/推送、版本回退等, 不探討Git指令, 不涉及多人協作, 更多的是客戶端使用過程的記錄.
分別使用Sourcetree和GitHub客戶端實現對代碼的版本控制, 兩者操作起來都差不多, 故分別用于演示管理本地倉庫和遠程倉庫. 遠程倉庫需要服務器來儲存項目代碼, 自從微軟收購GitHub后, 對私有項目也開放免費了, 所以遠程客倉庫的拉取/推送操作將使用GitHub客戶端來演示.
所謂倉庫, 可以理解成一個項目, 或者是這個項目對應的文件夾.
本地倉庫 (使用Sourcetree)
Sourcetree客戶端下載地址https://www.sourcetreeapp.com/
1. 創建本地倉庫
新建一個文件夾LocalRepository, 裝入一個文件README.md, 隨便填入初版信息:
打開Sourcetree客戶端, 創建本地倉庫
指定剛才創建的文件夾
成功創建倉庫, 右邊數字代表修改量
雙擊進入主界面
勾選待定的文件(表示放入暫存區), 填入版本記錄信息, 然后提交, 這時歷史版本中就有版本記錄了.
2. 新增版本
我們回到剛才的README.md文件, 新增一行信息:
然后我們看到Sourcetree中文件狀態里新增了未保存的修改:
勾選文件, 填入版本記錄信息"下雨了", 然后提交:
可以看到歷史中有了版本記錄:
討論
至此, 我們已經完成了第一次版本迭代. 但是有個問題, 本次修改版本是直接在主分支master上面進行的, 而master應該用于儲存可發布的穩定版本, 不應直接供給開發階段使用.
實際開發中, 我們應先分離出一個分支進行開發, 調試無誤后再合并到master進而發布. 這樣即可以防止多人協作同時對master進行操作造成沖突, 同時又可以分出多個分支進行多功能"并行"開發.
假設這樣一種情況:
當我們在master上直接開發新功能, 開發到一半的時候發現原來的代碼有bug, 這時候我們只有兩種選擇: 要么寫完另一半功能再去調試bug, 要么遺棄現有的一半功能代碼去調試bug. 這種做法好比是"線程阻塞式"的, 似乎不符合我們的需求. 那么, 此時分支可以閃亮登場了. 創建一個分支去開發這個新功能, 此時我們會有兩個分支: master和新功能分支. 當我們在功能分支上開發到一半的時候發現原來代碼有bug, 我們可以切換到master分支去, 另創建一個臨時分支用于修復bug, bug修復后將臨時分支合并到master用于發布更新, 功能分支調試無誤后也合并到master, 最后形成穩定的代碼版本.
我們之所以能在各分支之間隨意切換, 是因為分支之間的版本管理是相互獨立的, 詳見下節.
3. 分支
這個例子的流程如下:
當發布"下雨了"這個版本后, 我們新建一個買菜分支去買魚和豆腐, 買完魚后才想起家里沒有關窗 (代碼有bug). 這時我們可以切換到master, 把窗關上(bug修復), 然后重新切回買菜分支, 繼續買豆腐, 然后回到家里 (稱為合并).
新建分支
點擊"分支"按鈕, 或者直接在指定版本上右擊選擇分支...
選擇指定節點, 起名買菜
然后我們看到分支那里, 多了"買菜"這個分支:
這時候當前分支已經切換到買菜這里了, 以后的修改將只對當前分支有效. 要想切換分支, 雙擊分支中的分支名即可.
返回我們的工程項目文件夾LocalRepository, 新增一個買菜文件:
然后看到文件狀態那里有更新, 我們將這個提交一個版本, 備注買魚, 提交到"買菜"分支 (此時我們正處于這個分支上):
然后點擊歷史, 查看版本記錄:
切換分支
此時, 買菜分支比master超前了一個版本(買魚版本).
我們可以驗證下, 在分支中雙擊master切換到主分支, 此時我們的項目文件夾LocalRepository下買菜文件沒有了:
而切換回買菜分支, 又出現了買菜這個文件:
現在我們切換回master, 新建一個temp分支去修復bug (關窗), 過程和新建買菜差不多, 就只貼關鍵步驟了. 在temp分支里關窗:
然后temp和買菜分支各有一版不同的修改, 且都超前于master: temp多了"關窗"版本, 而買菜分支則多了"買魚"版本:
合并分支
現在bug修復了, 我們將temp合并到master里去.
我們要將某個源分支合并到某個目標分支上, 需要到目標分支上進行操作. 比如我們要把temp的關窗版本合并到master, 需要切換到master中, 然后右擊關窗版本選擇合并:
刪除分支
已經生成穩定版本了, 現在可以把temp分支刪除了:
好的, bug修復了, 我們切換回買菜分支, 繼續買豆腐:
OK, 現在可以回家了. 將買菜分支合并到master.
過程不再重復, 直接看結果:
4. 版本回退
我們在master上疊加兩個新版本進行測試:
如果我們想回退到天晴了這個版本, 可以右鍵選擇重置到這次提交:
然后有三種重置方式供我們選擇:
軟合并和混合合并都不會刪除開窗版本的內容, 都是變成天晴了版本提交之后開窗版本提交之前的狀態. 不同的是, 軟合并會將這些修改添加到已暫存區, 而混合合并則還在未暫存區.
強行合并則是丟棄整個開窗版本, 項目文件夾內容變成天晴了這個版本.
暫存文件
我們提交的時候, 只會將暫存文件的內容進行提交記錄. 所以我們修改了內容之后, 要確保想要提交的內容放到已暫存文件, 否則提交的時候不會記錄該修改內容.
軟合并
不會刪除開窗版本的內容, 只是將開窗版本的修改置為未提交狀態
修改的內容被默認添加到已暫存文件區:
混合合并
和軟合并唯一不同點是, 修改的內容還在為暫存文件區. 這時如果我們點擊選中未暫存文件, 則會被添加到已暫存文件, 這就和軟合并一樣了.
強行合并
丟棄開窗版本, 內容變成天晴了版本內容:
5. Sourcetree&Git部分名詞解釋
摘自https://www.cnblogs.com/fisherbook/p/11397168.html
克隆(clone):從遠程倉庫URL加載創建一個與遠程倉庫一樣的本地倉庫
提交(commit):將暫存文件上傳到本地倉庫(我們在Finder中對本地倉庫做修改后一般都得先提交一次,再推送)
檢出(checkout):切換不同分支
添加(add):添加文件到緩存區
移除(remove):移除文件至緩存區
暫存(git stash):保存工作現場
重置(reset):回到最近添加(add)/提交(commit)狀態
合并(merge):將多個同名文件合并為一個文件,該文件包含多個同名文件的所有內容,相同內容抵消
抓取(fetch):從遠程倉庫獲取信息并同步至本地倉庫
拉取(pull):從遠程倉庫獲取信息并同步至本地倉庫,并且自動執行合并(merge)操作,即 pull=fetch+merge
推送(push):將本地倉庫同步至遠程倉庫,一般推送(push)前先拉取(pull)一次,確保一致
分支(branch):創建/修改/刪除分枝
標簽(tag):給項目增添標簽
工作流(Git Flow):團隊工作時,每個人創建屬于自己的分枝(branch),確定無誤后提交到master分枝
終端(terminal):可以輸入git命令行
遠程倉庫 (使用GitHub)
如果只需要上傳代碼到GitHub而不涉及后續修改迭代, 那么使用網頁就夠了.
1. 上傳 (Push)
注冊GitHub賬號, 在右上角點擊+號創建遠程倉庫 (保存在GitHub):
選擇public表示公開, 任何人可見; 選擇private則自己可見, 也可設置成指定人可見. 一般項目都會帶有一個自述文件(README.md)用于描述項目以及使用方法等.
點擊Upload files以上傳代碼文件:
直接拖動文件到窗口或者點擊選擇上傳:
例子中文件內容為一個HelloWord文件夾, 然后里面有個版本記錄的文本文件:
因為初版內容相對于原始空內容來說也是一種修改, 所以上傳完成后GitHub會提示我們提交這個修改:
然后返回項目首頁, 發現這個文件夾已經上傳成功了:
2. 下載 (Pull)
點擊克隆或者下載按鈕, 可以直接下載壓縮文件ZIP:
解壓后就會看到我們的HelloWord文件以及README文件:
3. GitHub客戶端
如果要克隆遠程倉庫到本地, 在本地修改內容后push同步到遠程倉庫, 那么最佳方案就是下載GitHub客戶端.
下載地址: https://desktop.github.com/
克隆遠程倉庫到本地
克隆遠程倉庫到本地. 點擊克隆和下載按鈕, 選擇Open in Desktop進行克隆:
克隆完成后就在我們指定的本地文件夾看到HelloWord文件夾和README文件了:
push
我們在本地修改README文件:
然后GitHub客戶端有提示有新的修改:
我們提交這個修改, 備注等外賣. 注意, 此次提交僅記錄在本地, 如果需要同步到遠程倉庫, 需要進行push推送操作.
點擊History版本記錄, 將指定版本push到遠端. 點擊上傳箭頭:
然后我們查看網頁端, HelloWord項目已經有更新了:
pull
相反地, 我們在GitHub網頁 (遠程倉庫) 修改內容, 然后拉取同步到本地.
然后打開GitHub客戶端, 刷新一下:
然后我們看到遠端有一個新版本:
點擊Pull origin拉取之. 然后History就多了個版本記錄:
同時本地文件也被更新了: