剛更新完Xcode9,發(fā)現(xiàn)自帶的Git功能的用戶體驗比之前版本都有很大的提升。網(wǎng)上搜索了一篇使用文檔做一下翻譯,原文地址:https://www.raywenderlich.com/153084/use-git-source-control-xcode-9
原創(chuàng)翻譯,轉(zhuǎn)載請說明。

無論你是獨立開發(fā)者還是團隊開發(fā),項目如果不使用代碼控制的話你懂得。代碼控制可以幫助你還原舊版本代碼、在不會影響正在運作的應(yīng)用的同時增加新的功能、清楚地知道你的代碼在每個階段的改變、增加團隊協(xié)作效率,簡直鵝妹子嚶。Xcode自帶的Git就是一個十分優(yōu)秀的代碼控制系統(tǒng)(嘖,Xocde8的Git真是問題多多,不過Xcode9的Git確實體驗不錯,推薦)
Linus Torvalds開發(fā)了一款主要運行在Lunx內(nèi)核上的分布式版本控制系統(tǒng)Git。使用Git有一件很開心的事是Git并不需要任何核心倉庫的支持,那就意味著每個人都可以擁有自己的倉庫。(個人認為這也是比SVN好用的其中一個大原因,Git的誕生其實和SVN有一定的關(guān)系,其中的趣事可以百度一下)
在這篇文章中,你將會了解到Git以及如何使用Xcode自帶Git。
Gitting Started
這里我們不討論Git的內(nèi)部原理,而是去試試如何使用。先創(chuàng)建一個Xcode項目,然后嘗試一下通過Git版本控制的常用功能。
打開Xcode ,創(chuàng)建一個Single View Application?project.

補充模板中的配置項(其實這一步比較無所謂,按照具體項目操作):
Product Name: GitUseExample
Team: Your Apple Developer team if you have one, or None
Organization Name: Your name
Organization identifier: As the name indicates, it’s your organization’s identifier, if you have one. Otherwise, type whatever.
Language: Swift
Device family: iPhone
Use Core Data, Include Unit Tests, and Include UI Tests: not checked
然后點擊Next. 選項卡會讓你選擇把項目保存在哪里. 確保版本控制選項打勾,如下圖。

注: 如果沒發(fā)現(xiàn)這個選項的話點擊Options按鈕.
Xcode會幫你在創(chuàng)建新的項目的同時創(chuàng)建好一個新的Git倉庫。
所有版本控制系統(tǒng)包括Git在內(nèi)會把數(shù)據(jù)存入一個倉庫中,這樣Git就可以實現(xiàn)管理你的項目版本和時刻追蹤開發(fā)周期中的每一次代碼變動??梢园褌}庫看做是存儲各版本各種信息的數(shù)據(jù)庫。

你項目中的所有操作:添加文件、修改代碼、修改的次數(shù)等都會被記錄。
當項目發(fā)生修改并且修改完自己覺得沒問題的時候,就可以把這些更改放入倉庫。之后你可以隨時將代碼切換。
那當前按照項目模板創(chuàng)建的代碼將會如何呢?
剛創(chuàng)建的項目中只包含了這些配置文件。除了Xocde幫你自動配置的這些以外還沒有任何內(nèi)容可以提交。
點圖中左側(cè)標紅按鈕,打開版本控制導(dǎo)航(快捷鍵:cmd+2)。同時讓右側(cè)的版本控制檢測欄也開著(快捷鍵:cmd+Option+3)。在左側(cè)面板中點擊三角形可以顯示出在存儲庫中配置的所有分支、標記和遠程操作。點擊master分支,然后在編輯窗口點擊Initialcommit就可以看到Xcode自動提交的詳細信息。

Now, make some changes to your project. OpenAppDelegate.swiftand change the methodapplication(_:didFinishLaunchingWithOptions:)to the following:
現(xiàn)在來試試寫一點代碼。打開AppDelegate.swift將_:didFinishLaunchingWithOptions:方法中的實現(xiàn)部分改成以下內(nèi)容。
funcapplication(_application: UIApplication,? ? ? ? didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?)->Bool{print("Application did finish launching")returntrue}
保存后你會注意到AppDelegate.swift邊上會有一個“M”標識:

“M”代表“發(fā)生更改”,意思是你對這個文件進行了修改但是還沒有提交此次的變化到你的本地Git倉庫中。
接下來打開ViewController.swift在viewDidLoad():方法后添加以下代碼:
@IBActionfuncbuttonClicked(_sender: UIButton){print("This is a Git tutorial")}
打開Main.storyboard,拖一個button進去,再更改以下button的顯示文本。

最后要把button的點擊事件和代碼綁定。。。。(啊不想細說這部分了,iOS的入門可以自行某度吧)

修改完成后你會發(fā)現(xiàn)你有進行修改過的文件右側(cè)都出現(xiàn)了“M”。

Run一下試試。。。

好了這就意味著當前代碼是沒問題的,就可以提交啦。
Xcode頂部菜單欄中點擊Source Contro->Commit

點完就會出現(xiàn)一個新的界面,就像下面這樣的:

主界面被分成兩部分。左側(cè)窗口顯示的內(nèi)容是最新的代碼。如果你是第一次提交,那左側(cè)顯示的就是從創(chuàng)建項目開始的所有開發(fā)代碼。右側(cè)窗口顯示的是修改前的代碼。

左側(cè)面板1:未提交修改的文件列表。默認為所有未提交的文件全部選中。不過不想提交的話手動取消勾選。通過對比具體代碼內(nèi)容窗口,可以對文件中的修改內(nèi)容進行是否需要提交的選擇。代碼內(nèi)容窗口中藍色高亮部分為發(fā)生變化的代碼區(qū)域,就算你增加或者刪除了一個空格的改動也會被標注高亮。

內(nèi)容窗口中間區(qū)域2:列舉當前文件中所有更改的內(nèi)容。每個更改默認都是選中狀態(tài),同樣可以根據(jù)實際情況手動不勾選。例如change3比較無所謂,取消勾選后就這段修改就不會被提交。


底部輸入框2:在你提交之前,Xcode會要求你填寫提交信息。此處填寫的信息能幫助你更容易理解每一次的提交內(nèi)容和目的(個人認為盡量多花點時間在寫每次提交的信息上,當開發(fā)團隊逐漸擴大、代碼量上去之后,提交次數(shù)會越來越多,如果想花更少的時間去尋找或者了解每次提交的版本的內(nèi)容的話最快捷的辦法就是通過這些信息)

點擊Commit。完成提交后就會看到以下內(nèi)容。

Branching Out
Code自帶Git支持提交修改內(nèi)容到指定分支。先解釋什么是分支:一個分支可以看做提交內(nèi)容的集合。在不同分支中操作可以降低修改代碼內(nèi)容帶來的可能會影響項目原先功能的風(fēng)險。
倉庫創(chuàng)建的時候Git會自動創(chuàng)建一個叫做“mater”的分支,以上的操作其實都是在這個分支中進行的。master分支一般用作保存項目穩(wěn)定代碼,其它的分支用作日常開發(fā)。(Git和SVN同樣有命名規(guī)范但也不是硬性的要求,所有開發(fā)人員都遵循一套標準方便對代碼進行管理。例如:master:線上版本分支;developer:測試版本;其它分支:項目中每個開發(fā)人員獨立分支用作日常開發(fā))
舉個例子:如果準備在開發(fā)版本中添加一個新的文件,就像下圖中新增了MapForItinerary類。

MapForItinerary.swift文件邊上會出現(xiàn)“A”的標示,意思是這個新增文件還未被提交到倉庫。同樣的道理進行提交操作:

如果你選中帶“A”標示的文件,你會發(fā)現(xiàn)Xcode并不會顯示先前版本的信息進行比較。新文件當然沒有咯。
添加新功能勢必會對原代碼造成很大變動。使用新分支能幫助你杜絕因此造成的各種風(fēng)險。點擊左下角的齒輪按鈕,選擇Branch from “master”

填寫新分支的名稱,點擊Create:

Xcode就會幫你創(chuàng)建一個新的分支,初始選中。當前分支的邊上會顯示(current)

再次提交:

提交完成后,有進行提交過的文件邊上的標示將會消失:

Backing Out
一天你在項目的最新版本中加一個很酷的功能,吃了個下午茶后發(fā)現(xiàn)可能有更好的實現(xiàn)方式,這時候你想回到最新版本的初始狀態(tài)重新開發(fā)。

使用Git就能很容易地實現(xiàn) :]
(以下又是一頓操作)

如果你不希望保留這些的修改操作,可以在Xcode的導(dǎo)航欄中選擇selectSource Control\Discard Changes

Xcode會與你確認是否要做此操作(畢竟不小心discard還是有一定風(fēng)險,原本寫了好幾天的代碼說沒就沒了,而且是再也找不回來的那種)

不僅可以放棄一個文件的整體更改,還可以像提交那樣選擇文件中的部分內(nèi)容放棄。

好了,你之前的修改都沒了,也沒有內(nèi)容可以提交了。既然已經(jīng)嘗試過放棄更改,您可能會想知道這兩者之間的區(qū)別是什么,以及您之前選擇的不提交選項。雖然這兩種選擇都導(dǎo)致了存儲庫中沒有記錄的更改,但是有一個很大的區(qū)別:如果在commit時選擇忽略某個修改內(nèi)容,那么這個修改將不會被提交,但是本地源碼中還是會有修改記錄。discard不僅忽略修改內(nèi)容,還會將本地源碼還原。
Time Travel
如果想恢復(fù)代碼,Discarding changes是一種比較節(jié)省成本的做法。但是有些情況下使用可能會帶來一些麻煩。Git提供項目可以保存多個版本的功能。所有內(nèi)容將會保存在倉庫里,通過Git可以對其進行管理。如果你選擇discard changes一個文件,Git會把這個文件恢復(fù)成最后一次提交的版本中這個文件的內(nèi)容。這就是限制所在。
隨著項目的更新迭代,你的項目倉庫中的版本會越來越多。如果你想回到第一個或者第二個版本的話,通過discarding changes就沒辦法做到。但是Xcode和Git還有其它功能能很容易實現(xiàn)這個需求。
選擇ViewController.swift. 選擇View\Version Editor\Show Comparison View. 在Xocde的右上角切換到第三個按鈕。

就會像下圖一樣出現(xiàn)版本編輯:

你可以比較兩個版本內(nèi)容。默認狀態(tài)下當前內(nèi)容顯示在左側(cè),Git倉庫中存儲的最新版本內(nèi)容顯示在右側(cè)。如果想與倉庫中更早版本進行比較,點擊右下角的??按鈕就可以選擇你想要的版本。

如果想恢復(fù)到具體版本,只需單擊比較窗格中的更改號旁邊的箭頭,然后選擇Discard Change

Once you finish reverting to an earlier version, you will need to commit this “new” version of the file as the most recent. Go ahead and do that now.
一旦恢復(fù)成之前的版本,就相當于當前又是一個新的版本,所以同樣需要提交。
如何分辨哪個提交是你希望切換的呢?按住版本編輯按鈕,選擇Log?;蛘咴诓藛螜谥羞x擇View\Version Editor\Show Log View。

Xcode會羅列出當前文件的所有提交內(nèi)容。每次提交都會有一個唯一標識符。

這些標識符與之前使用的更改歷史列表中所示的標識符匹配.

同樣可以通過點擊Show modified files顯示詳細內(nèi)容。
另一個實用功能為Blame。在這個界面中你可以看到文件中在每次提交時的變化。
按住版本編輯按鈕并選擇Blame. 或者從菜單欄中選擇View\Version Editor\Show Blame View.


如果想看提交更改的詳細內(nèi)容,點擊日期邊上的??按鈕。

Merging Branches
You learned earlier that Git allows you to work on multiple streams of revisions known as branches. You also learned that it is good practice to do all of your development on a branch other than the master branch. What, then, are you to do when you finish development of a feature and want to release it? Simple! You merge your development branch into your master branch.
在前面了解到Git允許在多個被稱為分支的修訂流中工作;在master分支之外的分支上執(zhí)行所有的開發(fā)是一種很好的體驗。當完成一個新功能的開發(fā)并想要發(fā)布它時,就需要把當前分支合并到mater分支中。
新功能還沒有完成,但產(chǎn)品經(jīng)理明確需要在主界面中添加另一個文本。要實現(xiàn)這一點,需要暫時離開開發(fā)新功能的這個分支,并從穩(wěn)定的主分支中再創(chuàng)建一個新的分支。
具體操作如下:


創(chuàng)建完成后當前選中分支并沒有發(fā)生變化,右鍵點擊新創(chuàng)建的分支,選擇Checkout

Xcode問你確不確定,當然確定咯。

這樣新的分支就會變成剛才創(chuàng)建的分支,分支名右側(cè)多了(current)

現(xiàn)在就可以根據(jù)產(chǎn)品經(jīng)理的新的要求進行一頓操作。

功能開發(fā)完畢并Run了沒問題后提交。與上面操作一樣,先切換到master分支。右鍵點擊剛才發(fā)生修改的分支,選擇Merge “new_label” into “master”

Xcode又問你確不確定,你說確定合并。

合并窗口將出現(xiàn)用于控制合并的過程。合并源(the “merge from” branch)將出現(xiàn)在右邊。您當前的代碼,也就是合并后的代碼將出現(xiàn)在左邊。使用屏幕底部的按鈕來控制合并的方向。對于一個簡單的合并,比如這個,使用Xcode的默認設(shè)置即可。

最后點擊Merge按鈕開始合并。
If all goes well, you should see the changes (theUILabel) from the new branch appear in the user interface when you click onMain.storyboardor when you run your application. Now your changes are in the master branch because of the merge! Use one of the methods of viewing your commit history that you learned to verify that this change appears in the history.

Ignoring generated files
在第一次提交的時候可以發(fā)現(xiàn),除了代碼文件之外,Git還跟蹤Xcode的各種文件。因為這些文件對于項目來說和代碼文件同樣重要。你需要這些來與團隊成員共同完成應(yīng)用開發(fā)工作。但是App的每次build都會使Xcode生成新的文件。Xcode會自動地重新生成這些文件,所以保存這些內(nèi)容并沒有實際意義。不僅沒有意義,還可能讓你在提交歷史中查找修改內(nèi)容增加了難度。Git提供了一種機制來忽略這些文件:.gitignorefile。macOS會把它當作一個隱藏的文件,所以當你在Xcode或Finder中查看你的項目內(nèi)容時是不會看到這個文件的。但是不要怕,Git就能找到它。
不需要自己做,可以從gitignore.io上下載到此文件。
打開Terminal,輸入以下代碼。這些操作只要做一次,不需要在每次開發(fā)新項目的時候重復(fù)操作。
$git config --global alias.ignore'!gi() { curl -L -s https://www.gitignore.io/api/$@ ;}; gi'
Now, for any project using Git, do the following in aTerminalwindow:
cd
git ignore swift,macos >.gitignore
git add .gitignore
git commit -m "Add .gitignore file"
接下來就開始下載最近在macOS上用Swift開發(fā)的常用.gitignore配置文件。Terminal大概會顯示下面這些內(nèi)容:

.gitignore文件作為項目的一部分,Git同樣會追蹤文件的新增和更改內(nèi)容。
注意:最好在項目開發(fā)之前完成.gitignore文件的添加。
Xcode and GitHub
至此所做的所有工作都是使用存儲在計算機上的本地倉庫中。GitHub提供遠程倉庫讓開發(fā)者將自己的項目發(fā)布在上面。這個功能給團隊開發(fā)帶來許多便捷。(GitHub的私有倉庫是收費的,不過現(xiàn)在的互聯(lián)網(wǎng)公司應(yīng)該都會創(chuàng)建內(nèi)部私有庫,如果沒有的話推薦使用:某云)
如果還沒有GitHub賬號,那就先去GitHub注冊一個。完了之后你需要在Xcode中授權(quán)GitHub。打開Xcode的Preference并選擇Accounts。點擊左下角的?按鈕,選擇GitHub。

如果在你的GitHub賬戶上啟用了雙重身份驗證,Xcode需要你輸入驗證碼。

Xcode會顯示添加成功的GitHub賬戶配置。如果已經(jīng)配置了SSH密鑰,可以隨意切換到SSH進行克隆。

在代碼控制導(dǎo)航欄中右鍵點擊左上角項目名稱,并選擇Create “GitUseExample” Remote on GitHub

Xcode會幫你設(shè)置好默認配置,點擊Create。在代碼控制導(dǎo)航欄中就會看到Xcode已經(jīng)添加了一個名字叫做origin的遠程倉庫,倉庫中也有一個master分支。

如果要將項目內(nèi)容推送到遠程倉庫中的對應(yīng)分支中,選擇Source Control\Push


右鍵點擊遠程倉庫中的某個分支,選擇selectView on GitHub,就可以看到GitHub中的該分支的具體內(nèi)容。


如果每次更改都要推送到遠程分支中,那么修改后Run沒問題的話,點擊Source Control\Commit,再點擊Source Control\Push。


Success! :]