&開發過程中離不開源代碼的管理,
目地:為了解決在軟件開發過程中,由源代碼引發的各種蛋疼、繁瑣的問題。
目前開發使用較廣的版本控制系統「Git & SVN」,后續會單開一篇總結正在使用的【強大的 Git 客戶端:SourceTree】。
本篇文章主要從使用者角度【Git & SVN 詳解使用】學習總結。
在「時間 & 知識 」有限內,總結的文章難免有「未全、不足 」的地方,還望各位好友指出
目錄:
源代碼管理認知
源代碼管理 SVN 詳解使用
SVN 基礎知識概念
2.SVN 客戶端實用命令
3.SVN 客戶端實用示例
4.「SVN–>branch & tag」分支和標簽
5.SVN ST 顯示的文件狀態
源代碼管理 Git 詳解使用
1.Git基礎知識概念
2.Git 幾個核心概念
3.Git 工作原理 / 流程
4.Git 客戶端實用命令
5.「Git–>branch & tag & remote」分支、標簽和遠程
6.Git 客戶端實用示例
SVN & Git 兩者比較
碼農們踩過的坑整理(持續~)
下面簡單幾點總結,來給初學者快速對源代碼管理有個認知;
為什么會出現源代碼管理工具 ?
為了解決在軟件開發過程中,由源代碼引發的各種蛋疼、繁瑣的問題。
源代碼會引發哪些問題 ?
無法后悔:做錯了一個操作后,某些情況下無法返回,沒有后悔藥可以吃。
版本備份:費空間、費時間。
版本混亂:因版本備份過多造成混亂,難于找回正確的想要的版本。
代碼沖突:多人操作同一個文件(團隊開發中的常見問題)。
權限控制:無法對源代碼進行精確的權限控制。
追究責任:出現了嚴重的 BUG,無法定位到負責人,容易耍賴。
源代碼管理工具的作用是 ?
能追蹤一個項目從誕生一直到定案的過程。
記錄一個項目的所有內容變化。
方便地查閱特定版本的修訂情況。
溫馨提示:
如果是團隊開發,使用源代碼管理工具是強制性的!
如果是單人開發,也強烈建議現在就開始使用源代碼管理工具。
SVN是集中式控制系統,需要一個中央服務器。
Repository代碼倉庫,保存代碼的倉庫。
Server服務器,保存所有版本的代碼倉庫。
Client客戶端,只保存當前用戶的代碼倉庫。
用戶名&密碼訪問代碼倉庫需要使用自己的 “用戶名和密碼”,從而可以區分出不同的人對代碼做的修改。
svn checkout「簡寫svn co」:將服務器上最新的代碼倉庫下載到本地(只需要做一次)。
svn update「簡寫svn up」:從服務器上將其他人所做的修改下載到本地 (每天上班必須要做的事情)。
svn commit「簡寫svn ci」:將改動的文件提交到服務器(每天下班之前至少做一次)。
svn add:向本地的版本控制庫中添加新文件。
svn delete、svn remove「簡寫svn del、svn rm」:從本地的版本控制庫中刪除文件。
svn move:移動文件或者目錄或文件更名
svn mkdir:創建納入版本控制下的新目錄
svn revert:撤銷之前的一切修改
svn merge:將兩個版本之間的差異合并到當前文件
svn info:查看文件的詳細信息。
svn diff:查看不同版本的區別。
svn log:查看日志信息。
svn list:列出版本庫下的文件和目錄列表。
svn status「簡寫svn st」:查看文件狀態。
svn help:獲取幫助信息(比如 svn help ci)。
svn lock:加鎖。
svn unlock:解鎖。
檢出:
去到公司的第一天,將項目檢出(下載)至本地。
svn checkout URL[PATH]
svn co URL[PATH]
注意:
這里的中括號[ ]代表可選(可以省略)。
URL:代碼倉庫的遠程地址。
[PATH]:將代碼下載到本地的哪個路徑(如果省略本地的路徑,就下載到命令行當前所在的路徑)。
提交:
將改動過的舊文件提交至服務器。
svn commit-m "注釋"[PATH]
svn ci-m "注釋"[PATH]
注意:
一定要養成寫注釋的良好習慣。
“注釋”:”修改了User.m文件”。
[PATH]:代表是 提交哪個文件到服務器(如果省略路徑,就將命令行所在路徑中所有改動過的文件提交到服務器)。
添加:
提交一個新建的文件到服務器,需要2個步驟。
添加新建的文件到本地的版本控制庫中:svn add。
提交剛才的添加操作到服務器:svn commit。
將文件添加到本地的版本控制庫。
svn add PATH
PATH:代表是 添加哪個文件到版本控制庫中。
刪除:
刪除服務器上的某個舊文件,需要做2個步驟。
將文件從本地的版本控制庫中移除:svn delete、svn remove。
提交剛才的刪除操作到服務器:svn commit。
將文件從本地的版本控制庫中移除。
svn delete PATH
PATH:代表是 將哪個文件從版本控制庫中移除。
更新:
將服務器上其他同事提交的,最新代碼更新到本地。
svn update [PATH]
PATH:代表是 更新哪個文件的內容(如果省略路徑,就更新命令行所在路徑的所有內容)。
回滾:
改動沒有被提交。
這種情況下,使用svn revert就能取消之前的修改。當為單個文件時,直接svn revert 文件就行了;當為目錄時,需要加上參數-r (Recursive,遞歸),否則只會將改文件這個目錄的改動。
改動已經被提交。
這種情況下,用svn merge命令來進行回滾。先運行svn up保證拿到最新的版本,然后svn log查看并找到要回滾的版本號,如果想要更詳細的了解情況,可以使用svn diff -r HEAD:2500 [文件](回滾到版本號2500),此處的[ ]可以是文件、目錄或整個項目。
SVN官方推薦在一個版本庫的根目錄下先建立trunk、branches、tags這三個文件夾,其中trunk是開發主干,存放日常開發的內容;branches存放各分支的內容,比如為不同客戶定制的不同版本;tags存放某個版本狀態的標簽。
branhces和tags本質沒有區別,都是通過svn copy方式建立的,差異在于通常branches中的內容是需要繼續修改或開發的,tags中的內容是存放不再修改的,這一般通過權限設置來解決,tags通常只給管理員開放寫權限。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
171.新建分支
svncopymaster_repository_url branch_repository_url -m"your comments"
2.新建空白分支
svn mkdir branch_repository_url
3.刪除分支
svn rm branch_repository_url -m"your comments"
4.新建tag
svncopymaster_repository_url tag_repository_url -m"your comments"
5.刪除tag
svn rm tag_repository_url -m"your comments"
6.查看branches
svn ls ^/branches --verbose
分支與主干的合并:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20# 分支合到主干 cd trunk
svn merge -r : svn://branch/path
# 分支當前版本為4847,想把4825到4847間的改動merge到主干
# cd trunk
svn merge -r4825:4847svn://branch/path
svn ci -m"merge branch changes r4835:4847 into trunk"
# 主干合到分支 cd branch
# 在r23創建了一個分支,trunk版本號更新到了25,想把23-25之間的改動merge到分支
svn merge -r23:25svn://trunk/path
svn ci -m"merge trunk changes r23:25 into my branch"
# cd trunk
# 查看當前Branch中已經有那些改動已經被合并到Trunk中
svn mergeinfo svn://branch/path
# cd trunk
# 查看Branch中那些改動還未合并
svn merginfo svn://branch/path --show-revs eligible
merge分支B到分支A
1
2
3
4
5step1: Checkout URL A
# cd branch A
step2: merge URL B to your workingcopyof A
svn merge -r10:HEAD http://branch-b .
step3: Commit A
沖突提示
1
2
3
4
5
6(p) postpone? ? ? ? ? 暫時推后處理,我可能要和那個和我沖突的家伙商量一番
(df) diff-full? ? ? ? 把所有的修改列出來,比比看
(e) edit? ? ? ? ? ? ? 直接編輯沖突的文件
(mc) mine-conflict? ? 如果你很有自信可以只用你的修改,把別人的修改干掉
(tc) theirs-conflict? 底氣不足,還是用別人修改的吧
(s) show all options? 顯示其他可用的命令
' '沒有修改。
A被添加到本地代碼倉庫。
C沖突。
D被刪除。
I被忽略。
M被修改。
R被替換。
X外部定義創建的版本目錄。
?文件沒有被添加到本地版本庫內。
!文件丟失或者不完整(不是通過svn命令刪除的文件)。
~受控文件被其他文件阻隔。
U服務器收到文件更新了
G本地文件以及服務器文件都已更新,而且成功的合并了
git是一款開源的分布式版本控制工具。
在世界上所有的分布式版本控制工具中,git是最快、最簡單、最流行的。
作者是Linux之父:Linus Benedict Torvalds。
當初開發git僅僅是為了輔助Linux內核的開發(管理源代碼)。
工作區(Working Directory):倉庫文件夾里除.git目錄以外的內容。
版本庫(Repository):.git目錄,用于存儲記錄版本信息。
暫存區(stage)
分支(master):git自動創建的第一個分支。
HEAD指針:用于指向當前分支。
git add:將工作區文件修改添加到暫存區。
git commit:將暫存區的所有內容提交到當前分支(提交區)。
git push:將提交區內容 推送到服務器上。
git pull:從服務器上更新文件。
1.git clone:從服務器上克隆(下載)最新的代碼到本地。
2.git init:初始化本地倉庫(在當前目錄新建代碼庫),也可以git init Desktop/GitCode(在指定位置創建代碼庫) ,如果使用了git clone不用使用此命令。
3.git config:配置用戶名和郵箱。
1
2
3
4
5
6
7
8
9
10git config --global user.name"GO_ln"
git config --global user.email"xxx @xx.com"
```
-4.`add`:將工作區的文件提交到暫存區。
```objc
// 添加指定文件
git add GitTest/GitTest/ViewController.m
// 添加本地庫所有文件
git add .
5.git commit:提交信息。
1
2
3
4
5
6
7
81.git commit -m 將暫存區的內容提交到提交區
// 提交所有
git commit -m"日志"
// 提交某一個文件
git commit GitTest/GitTest/ViewController.m -m"修改VC"
2.把工作區中的內容提交到暫存區并從暫存區中提交到提交區
git commit -am “提交信息”
6.git status:查看當前 git 的狀態。
7.git push:將提交區內容 推送到服務器上。
8.checkout:撤銷某次提交的某個文件。
1
git checkout8989920311bacb3f4e3ced7f82ab75ca47c318c7 GitTest/GitTest/ViewController.m
9.revert:撤銷某一次提交。
1
git revert8989920311bacb3f4e3ced7f82ab75ca47c318c7
10.checkout HEAD:放棄本地某一文件的修改。
1
git checkout HEAD GitTest/GitTest/ViewController.m
11.git reset:回退到某個版本并保存未追蹤的改動。(通過log來查詢)
1
git reset8989920311bacb3f4e3ced7f82ab75ca47c318c7
12.git reset --hard HEAD:放棄本地全部修改。
13.git reset --keep:回退到某個版本并保存未提交的改動。
1
git reset --keep8989920311bacb3f4e3ced7f82ab75ca47c318c7
14.log:查看提交日志。
15.git show:查看每次提交的具體內容。
16.diff:查看追蹤文件的差異。
1
2
3
4// 查看追蹤文件的差異
git diff
// 查看某一文件的差異
git diff GitTest/GitTest/ViewController.m
17.rm:刪除文件。
1
git rm GitTest/GitTest/ViewController.m
18.mv:修改某一個文件的名字。
1
2// 注意,路徑要對應,否則會自動移動
git mv GitTest/GitTest/ViewController.m GitTest/GitTest/View.m
19.blame:查看文件被誰修改。
1
git blame GitTest/GitTest/ViewController.m
「Git–>branch & tag & remote」分支、標簽和遠程
branch:分支。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31// 查看本地分支
git branch
// 查看遠程分支
git branch -r
// 查看遠程和本地分支
git branch -a
// 創建本地分支,但是不切換
git branch branch1
// 新建一個分支并切換
git checkout -b branch2
// 新建一個分支,指向指定commit
git branch branch38989920311bacb3f4e3ced7f82ab75ca47c318c7
// 新建一個分支,與指定的遠程分支建立追蹤關系
git branch --track branch4 origin/master
// 切換到指定分支,并更新工作區
git checkout branch4
// 切換到上一個分支
git checkout -
// 建立追蹤關系,在現有分支與指定的遠程分支之間
git branch --set-upstream branch3 origin/master
// 合并指定分支到當前分支
git merge branch2
// 選擇一個commit,合并進當前分支
git cherry-pick8989920311bacb3f4e3ced7f82ab75ca47c318c7
// 刪除分支
git branch -d branch1
// 刪除遠程分支
git push origin --delete branch1
git branch -dr branch1
// 將當前分支push到指定遠程分支
git push origin HEAD:branch1
tag:標簽。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16// 列出所有tag
git tag
// 新建一個tag在當前commit
git tag1
// 新建一個tag在指定commit
git tag28989920311bacb3f4e3ced7f82ab75ca47c318c7
// 刪除本地tag
git tag -d1
// 查看tag信息
git show2
// 提交所有tag
git push --tags
// 刪除遠程tag
git push origin --delete tag2
// 新建一個分支,指向某個tag
git checkout -b [branch] [tag]
remote:遠程。
1
2
3
4
5
6
7
8
9
10
11
12// 查看遠程庫的地址列表
git remote -v
// 查看這個遠程庫的信息
git remote show origin
// 從遠程庫更新所有的信息到本地,但是不合并
git fetch origin
// 從遠程庫更新所有的信息到本地,但是不合并并清理已刪除的遠程分支
git fetch -p origin
// 從遠程庫更新數據并立即合并數據
git pull origin branch1
// 將本地數據同步到遠程庫中
git push origin? branch1
1、示例:將本地代碼提交到 GitHub 上。
前期準備:
cd Desktop/git(桌面文件夾)
git clone https://github.com/CustomPBWaters/liunDemo.git(倉庫的URL)
cd liunDemo(github上建的文件夾) 把要上傳的Demo放到建的桌面 git 文件夾里。
ls -a會提示下步操作。
git commit -am CoreDataDemo,這里的CoreDataDemo是我本地的Demo。
1
2git add CoreDataDemo? 把工作區的內容提交到暫存區
git commit -m CoreDataDemo? 把暫存區中的內容提交到提交區
git status查看提交狀態。
這時第一次提交,會讓輸入GitHub用戶名密碼。
git push將文件推送到服務器上。
注意:要傳得Demo項目中,有的含隱藏文件.git,需要刪除 rm -rf .git,再上傳就可以了。
2、示例:解決沖突(手動解決)。
打開沖突文件,刪除<<<<<<< HEAD ======= >>>>>>> branch1這三行
再修改成想要的,添加,提交即可。
SVN & Git特點
結構(最主要的區別)
SVN是集中式管理,Git是分布式管理
速度
在很多情況下,git的速度遠遠比SVN快
難度
SVN功能簡單,指令簡單,入門容易。Git功能完善,指令復雜,入門簡單掌握難
其他
SVN使用分支比較笨拙,git可以輕松擁有無限個分支
SVN必須聯網才能正常工作,git支持本地版本控制工作
舊版本的SVN會在每一個目錄置放一個.svn,git只會在根目錄擁有一個.git
補充
集中式版本控制
在分布式下開發者可以本地提交。
每個開發者機器上都有一個服務器的數據庫。
從穩定可靠的角度來看,分布式肯定是更好的選擇。
這兩個版本控制一直持續到現在,兩者都有其優點和缺點。
個人認為兩者沒有絕對的優勢,能夠取代另一方。
但是從功能上來講,Git 擁有SVN大致所有的功能,還擁有更多可靠,便捷,個性化的指令方便操作。
就剩最后一句話了,沒錯,想要復雜的功能,就要承受學習的代價