【現代軟件工程課件】
源代碼管理 -- 以實踐促進學習
移山軟件學院的學生果凍問老師: 為啥需要源代碼管理? 我自己寫代碼多爽,別人要,就用QQ 傳過去好了。
老師問:原始人怎么建房子?
果凍:或者找一個洞,或者自己挖一個洞,上面搭個棚子擋雨...
老師問:現代人怎么建房子?
果凍:那就要有樓房,當然還要搭腳手架,還要升降機,起重機,等等工具。
老師問:如果原始人穿越到現在,要蓋房,是否可以不要腳手架,大家直接搬磚從一樓砌牆,然后站在一樓砌二樓,然后站在二樓砌三樓... 砌到十樓么?
果凍:這有很多問題:
- 人力搬磚效率底下,人的體力有限,必須有工具幫忙。
- 如果牆砌歪了,沒有人來看,砌到五樓才發現從二樓開始就歪了,怎么辦?
- 現代房屋有各種成型的模塊(門框,窗框,各種預制板,各種管道線路),沒有工具,光憑人力根本搞不定。
老師:對,我們需要腳手架,升降機,起重機,水泥攪拌車,各種檢測工具來保證一個大樓能順利建好。 我們說過,
軟件 = 程序 + 軟件工程
軟件的質量 = 程序的質量 + 軟件工程的質量
軟件工程的質量要靠軟件工具和軟件流程來保證, 大家看過正在建設中的高樓, 半完工的樓頂上矗立着巨大的塔吊。這個塔吊不是用戶需求的一部分 (用戶希望完工的樓房上面沒有塔吊!),但是,這是建築工程上不可缺少的環節,那么怎么把塔吊順利地安裝上,隨着樓房的增高而增高(動畫, 迪拜塔的建設),讓塔吊高質量地工作,怎么做安全檢查,防止它倒下來? 這就是工程的要求。
軟件工程中,也有類似腳手架,塔吊這樣的工程系統,工具和流程。 軟件的源代碼管理工具(source code control system),加上構建系統 (build system), 能保證一個復雜軟件能在多個角色,多個團隊的合作下,按時以合適的質量發布。 如果你寫一個Hello World 程序, 當然不需要這些工具, 就像你用兒童積木搭房子過家家,你自己高興,但這不是建築工程。
源代碼管理的10 個實踐問題:

源代碼管理的重要性無需贅述,但是在實際中, 很多團隊都是小和尚念經 - 有口無心。 嘴上說重要,但是實際上還是通過QQ 傳遞源代碼,或者演示一結束, 源代碼立刻沒有可以工作的版本。 我們請各個團隊舉出例子,說明自己是用什么樣的源代碼系統 (subversion, CVS, github, TFS, etc) ,如何處理團隊開發中可能會遇到的各種問題。如果團隊還是用QQ 傳遞代碼,請說明QQ 如何解決下列的問題。
每個團隊寫一個博客,回答下列問題,(每個回答要加上截屏顯示):
0. 在吹牛之前,先回答這個問題: 如果你的團隊來了一個新隊員,有一台全新的機器, 你們是否有一個文檔,只要設置了相應的權限,她就可以根據文檔,從頭開始搭建環境,並成功地把最新、最穩定版本的軟件編譯出來,並運行必要的單元測試? (在這過程中,不需要和老隊員做任何交流)
1. 你的團隊的源代碼控制在哪里?用的是什么系統?
如何處理文件的鎖定問題?
場景:
程序員果凍正在對幾個文件進行修改,實現一個大的功能, 這時候,
程序員小飛也要改其中一個文件,快速修復一個問題。怎么辦?
一個代碼文件被簽出 (check out) 之后,另一個團隊成員可以簽出這個文件,並修改,然后簽入么?
有幾種設計,各有什么優缺點?
例如,簽出文件后,此文件就加鎖,別人無法簽出; 或者, 所有人都可以自由簽出文件
2. 如何看到這個文件和之前版本的差異? 如何看到代碼修改和工作項 (work item),缺陷修復 (bug fix) 的關系。
場景: 程序員果凍看到某個文件被修改了,他怎么看到這個文件在最近的修改究竟改了哪些地方? (
例子)
場景: 程序員果凍看到某個文件在最新版本被改動了100 多行, 那么和這100多行對應的其他修改在什么文件中呢? 這個修改是為了解決哪些問題而作的呢? 那些問題有工作項 (work item,issue),或者bug 來跟蹤么?
3. 如果某個文件在你簽出之后已經被別人修改,並且簽入了,那么你在簽入你的修改的時候,
如何合並不同的修改(merge)? 你用了什么工具來幫助你?
4. 你有20個文件都是關於同一個功能的修改,你要如何保證這些文件都
同時簽入成功(修改的原子性),或者同時簽入不成功?
場景: 程序員果凍要簽入 20 個文件,他一個一個地簽入, 在簽入完5 個 .h 文件之后, 他發現一些 .cpp 文件和最新的版本有沖突,他正在花時間琢磨如何合並... 這時候, 程序員小飛從客戶端同步了所有最新代碼, 開始編譯, 但是編譯不成功 - 因為有不同步的 .h 文件和 .cpp 文件! 這時候, 別的程序員也來抱怨同樣的問題,果凍應該怎么辦?
5. 你的PC 上有關於三個功能的修改, 但是都沒有完成,有很多文件處於半完工的狀態,這時你要緊急修改一個新的 bug,如何把本地修改放一邊,保證在干凈的環境中修改這個 bug, 並成功地簽入你的修改 ---
changelist management。
6. 規范操作和自動化
你的團隊規定開發者簽入的時候要做這些事情:
- 代碼復審 (要有別的員工的名字)
- 和這次簽入相關的issue 編號, 任務/task, 缺陷/bug 編號,等等, 以備查詢。
請問你的團隊有這樣的自動化工具讓開發者方便地一次性填入所有信息然后提交么? (高級功能, 代碼提交之后, 相關bug 的狀態會改動為 “fixed”, 並且有鏈接指向這次簽入。)
7. 如何給你的源代碼
建立分支?
場景:你們需要做一個演示,所以在演示版本的分支中對各處的代碼做了一個臨時的修改, 同時,主要的分支還保持原來的計划開發。 你們怎么做到的? 在演示之后,演示版本的有些修改應該合並到主分支中,有些則不用,你們是怎么做到的?
場景: 你們的軟件發布了,有很多用戶,一天,一個用戶報告了一個問題,但是他們是用某個老版本,而且沒有條件更新到最新版本。 這時候,你如何在本地構建一個老版本的軟件,並試圖重現那個問題?
8. 一個源文件,如何知道它的
每一行都是什么時候簽入的,為了什么目的簽入的 (解決了哪個任務,或者哪個bug)?
場景: 一個重要的軟件歷經幾年,幾個團隊的開發和維護,忽然出現在某個條件下崩潰的事故,
程序員果凍經過各種debug手段,發現問題是在某一個文件中有一行代碼似乎顯然出了問題, 但是這個模塊被很多其他模塊調用, 這行代碼是什么時候,為了什么目的,經過誰簽入的呢? 如果貿然修改, 會不會導致其他問題呢? 怎么辦?
9. 如何給一個系統的所有源文件都打上
標簽,這樣別人可以同步所有有這個標簽的文件版本?
代碼每天都在變, 有時質量變好,有時變差,我們需要一個 Last Known Good (最后穩定的好版本) 版本, 這樣新員工就可以同步這個版本, 我們如果需要發布,也是從這個版本開始。 那么如何標記這個 Last Known Good 版本呢?
10. 你的項目的
源代碼和測試這些代碼的單元測試,以及其他測試腳本都是放在一起的么? 修改源代碼會確保相應的測試也更新么?你的團隊是否能部署自動構建的任務?
在簽入之前,程序員能否自動在自己的機器上運行自動測試,以保證本地修改不會影響整個軟件的質量?
在程序員提交簽入之后,服務器上是否有自動測試程序, 完成編譯,測試,如果成功,就簽入,否則,就取消簽入?
團隊是否配置了服務器,它自動同步所有文件,自動構建,自動運行相關的單元測試,碰到錯誤能自動發郵件給團隊
作業題,分析比較各種軟件構建環境:
就像一個廚師要分析各種廚房用具,挑選適合自己的工具組合, 一個軟件團隊也要挑選適合自己的源代碼管理和其他配套工具,請選擇至少三種,比較各自的優點缺點,成本:
- github
- https://gitee.com/education
- coding.net
- code.csdn.net
- gitcafe.com
- www.visualstudio.com
- code.taobao.org
- Visual Studio Team Foundation Server
- gitblit, 在Windows系統下構建 git 服務,帶網頁端管理…
- Visual Source Safe (VSS)
- 自己搭建系統