編輯:關於Android編程
現在大部分使用的都是SVN,也有一部分遷移了Git,雖然挺好的,不過還有其它很多版本控制的工具,並沒有誰最好用,最重要的是適合自己的公司與團隊,效率和團隊是成正比了,重要的不是武器,雖然武器也挺重要的,不過最重要的還是配“劍“者,不過要是對Git沒接觸過或者認識不夠的話,我想,這篇“華序”寫的文章足以讓你對Git有所認識了,不過了解下就可以了,凡事不要太執著了,下面,就讓我們進入正文吧。
正文:
Git是一款開源的分布式版本控制系統(VCS),常用的VCS工具還包括SVN、Mercurial等,他們的使命是對資源變化的進行版本管理控制,對資源容災備份,支持多域協同開發。這裡的資源不僅僅是系統代碼,還包括圖片、文件、網頁等。本篇文章結合流程圖、詳細的注解、實例操作針對Git的使用、Git數據通信原理進行細致的講解,利用半場足球賽的時間通讀全文後相信你面對Git會自信滿滿、知其所以然,使用起來游刃有余,當然對其他工具的理解也就非常容易了。
Git在各個操作系統的安裝過程就不綴文了,步驟都是固定的,按照步驟一步一步安裝就可以了。在開始講解之前,我們先對Git進行資源版本管理有個整體的了解,如圖1為Git資源狀態流轉過程,理解清楚這個流轉圖對Git命令的操作非常關鍵。
vcq9u+G4/MD709q087zSwO294qGjPC9wPg0KPHByZSBjbGFzcz0="brush:java;">
(PS:下文中【】的內容為對命令的注解)
git init 【初始化本地倉庫 ,將當前項目目錄加入git管理】
git add 【將新文件加入版本控制,Git會對目標文件進行跟蹤,納入版本控制管理。(這是個多功能命令,根據目標文件的狀態不同,此命令的效果也不同:可以用它開始跟蹤新文件,或者把已跟蹤的文件放到暫存區,還能用於合並時把有沖突的文件標記為已解決狀態等)】
git add . 【將當前目錄所有文件加入到版本控制】
git commit -m 'commit comment' 【提交變動,將修改的文件轉移到暫存區】
git commit -a 'commit comment' 【將add和commit操作合並】
git commit --amend 【重新commit,將之前commit合並為一個(add上次commit漏掉的文件或者重寫comment)】
Example: git commit -m 'commit comment'
git add filename
git commit –amend
此例子只會產生一次commit log,第二個commit會覆蓋第一個commit。
取消已暫存到暫存域的文件或者修改未提交的文件,可以通過git status命令查看取消到命令方案。
<–clone start–>
如果我們想加入一個現有項目的協同開發,可以通過clone命令將遠程reposity的項目克隆鏡像到本地,此鏡像(此處可以聯想下操作系統的鏡像)包含項目所有歷史變更,所有歷史版本,所有分支信息等等,是遠程reposity的一個完整副本。Git支持多種數據傳輸協議,本地傳輸、git協議、ssh協議、http協議。
git clone source. zhouliwei.com/app/zhouliwei.git 【本地倉庫clone】
git clone git+ssh://[email protected]/zhouliwei.git 【遠程倉庫clone(ssh協議)】
git clone http://[email protected]/app/ zhouliwei.git 【遠程倉庫clone(http協議)】
git clone -l /home/zhouliwei/test 【拷貝本地資源庫到當前目錄】
git clone -b 分支名 http://gitusername@source. zhouliwei.com/app/test.git 【clone指定分支(類似checkout)】
git clone -s 遠程地址 【作為共享倉庫】
<–clone end–>
git status 【查看當前版本狀態。
該命令有幾個信息塊:
on branch branchname:本地資源庫在branchname分支
changes not staged for commit:本地資源庫做了哪些修改,還未commit到暫存域
new file:還沒有加入版本控制的新文件
modified:有改動的文件
deleted:被執行刪除的文件 git rm filename
unmerged:出現沖突的文件】
在協同開發的過程中,可能會對資源進行多次修改,多次提交,在一些場景下對提交歷史的回顧極為重要,我們可以借助log命令完成此工作。
git log 【顯示所有歷史提交日志,最近的在第一行】
git log -1 【顯示最近一行】
git log --stat 【顯示提交日志及相關變動文件,增改行統計】
git log -p -1 【詳細顯示每次提交的內容差異】
git log -p -m
git clean --df 【是從工作目錄中移除沒有track的文件】
git rm –cached 【將文件或者路徑從遠程reposity、本地暫存域中刪除,在本地工作空間中保留,主要針對和項目本身無關的不小心提交到服務器的文件】
vim filename 【查看、編輯資源文件】
接下來我們了解下Git branch,分支可以說是一個非常具有魅力的創造,他將協作的成員工作獨立起來,互不影響,各自沿著自己的主線向前推進,他們以master分支作為共同的資源集散地,所有分支生成於master,最終又回歸到master。圖2為Git 的分支模型。
<–branch start–>
每次commit都會在暫存域中生成一個快照對象,生成一個新的版本,分支就是指向快照對象的可變指針。可以通過HEAD定位到當前在哪個分支工作,HEAD是一個指向正在工作本地分支的特殊指針,可以通過checkout將HEAD切換成目標分支。HEAD會隨著當前分支的commit而移動,其他分支不受影響。
git branch 【列出本地所有分支(已檢出)】
git branch -a 【列出本地+遠程所有分支】
git branch -v 【可以看見每一個分支的最後一次提交】
git branch -av
git branch -r 【列出所有原創分支(origin/.)】
git branch branchname 【創建一個新分支】
git branch -d 分支名 【刪除一個分支】
git branch -m oldbranch newbranch 【本地分支改名】
git branch --contains 字符串 【顯示包含目標字符串的分支】
git branch --merged 【顯示所有已合並到當前分支的分支】
git branch --no-merged 【顯示所有未合並到當前分支的分支】
git branch --set-upstream 分支名 origin/分支名 【本地分支關聯到遠程路徑】
<–branch end–>
<–checkout start–>
從遠程reposity checkout的下來的本地分支稱為跟蹤分支,跟蹤分支是一個和某個遠程分支映射的本地分支。clone之後本地會自動創建一個跟蹤分支master,映射到遠程的分支origin/master。
git checkout branchname 【切換到新分支】
git checkout -b branchname 【創建並切換到新的分支,如果本地已經有此分支則使用上個命令】
git checkout -b branchname origin/branchname 【在本地創建新分支,從遠程拉取新分支代碼】
git checkout filename 【替換本地改動,會從服務器下載最新的文件(HEAD 中最新的內容)覆蓋工作目錄中的文件(add、commit的文件不受影響),次這個操作是不可逆】
<–checkout end–>
<–merge start–>
在協同項目工作的過程中,如果多個人同時修改一個文件的相同地方,leader在master上進行合並時難免會出現代碼沖突的情況,此時的merge會合並失敗,需要將沖突進行處理,我們可以采取下面方式進行處理。
git merge branchname || origin/branchname 【合並目標分支到當前分支,合並之後會生成一個新的快照對象】
如果出現沖突,通過git status查看沖突位置(標記為unmerged為重讀文件)。我們可以通過手動修改成想要的代碼, 解決沖突的時候可以用到git diff ,處理完之後用git add
git reset --hard HEAD 【將當前版本重置為HEAD(通常用於merge失敗回退)】
丟棄所有的本地改動與提交:
git fetch origin 【1.從服務器拉取最新版本】
git reset --hard origin/master 【2.將你本地主分支指向到遠程分支】
<–merge end–>
<–fetch start–>
git fetch --all 【 從遠處資源庫拉取所有分支(merge之後才會更新本地分支),可以進行diff、log
git fetch origin 【將從遠程拉取上次克隆後的master分支所有變化,即獲取master分支最新代碼】
通過fetch命令合並代碼過程:
git fetch origin branchname1 【1. <遠程主機名> <分支名> 設置當前的fetch_head為分支branchname(fetch_head為每個分支在服務器上的最新狀態)】
git fetch origin branchname1: branchname2 【2. 拉取遠程branchname1到本地新分支branchname2(branchname2是一個臨時分支) 】
git fetch diff branchname2 【3. 將當前分支和新建的臨時分支branchname2進行比較】
git fetch merge branchname2 【 4. 將當前分支和新建的臨時分支branchname2進行合並,此時branchname1為最新代碼】
git fetch -d branchname2 【5.刪除臨時分支branchname2】
git pull == git fetch + merge 【從遠程拉取最新版本,合並】
git pull origin branchname1 【拉取並合並branchname1】
使用git fetch操作性更好些(和pull對比),我們可以進行diff、log,再merge,更利於開發者根據當前情況進行針對性操作。
<–fetch end–>
<–push start–>
通過push命令將自己的分支資源和協同小組的其他人員進行共享,前提條件是Git賬戶必須擁有遠程reposity的寫權限。
git pull <遠程主機名> <遠程分支名>:<本地分支名>
git push <遠程主機名> <本地分支名>:<遠程分支名> 【將本地分支推送到遠程分支】
1) git push origin <本地分支名> 【遠程分支名為空,將本地分支推送到遠程與其有對映關系的分支】
2) git push origin :<遠程分支名> 【本地分支名為空,將本地空分支推送到遠程分支,即刪除遠程分支】
3) git push origin 【將本地當前分支推送到遠程與其有對映關系的分支】
<–push end–>
<–remote start–>
參與項目的協作開發,本地資源來源於遠程倉庫,所以需要對遠程倉庫的管理,比如遠程倉庫的創建、查看、刪除、client-server資源映射等等。
git remote 【列出遠程所有alias別名,自己權限范圍內的遠程reposity】
git remote -v 【可以看見每一個別名對應的實際url】
git remote add [alias] [url] 【給遠程url添加別名||把url添加為遠程倉庫】
git remote add myRepo /home/zhouliwei/test.git 【添加本地倉庫作為遠程倉庫,共享目錄】
git remote rm [alias] 【刪除一個別名】
git remote rename [old-alias] [new-alias] 【重命名】
git remote set-url [alias] [url] 【更新url. 可以加上—push和fetch參數,為同一個別名set不同的存取地址. 】
git remote add origin 【將本地倉庫連接到遠程倉庫 git remote add origin http://[email protected]/app/test.git 然後可以通過git push origin branchname將branchname推送到相應遠程分支;創建遠程倉庫】
git remote show origin 【顯示遠程信息】
<–remote end–>
將本地工作空間上傳到遠程新建倉庫操作:
首先在本地空間生成用於ssh加密傳輸的公鑰和私鑰,將公鑰維護到遠程倉庫的SSH key(後面會詳細介紹如何操作)。
git init
git add .
git commit –m ‘initial commit’
git remote add origin http://[email protected]/app/test.git
git push orgin master
<–rebase start–>
可以通過rebase命令(衍合)以補丁的方式將某個分支的改動在其他分支上再打一遍(合並到其他分支),可以簡化分支的歷史操作記錄,流程看起來更清晰(和merge對比)。
git checkout branchname
git rebase master
將branchname分支代碼的改動衍合到master,相當於是在master上復制了branchname分支的改動,只在master分支上生成操作歷史。
<–rebase end–>
至此我們已經完成了常用Git命令的講解,包括本地倉庫的創建初始化、克隆遠程資源,本地倉庫資源的修改、提交、推送,分支的管理,遠程倉庫資源的檢出,沖突處理,遠程倉庫管理、協同開發等等。每個命令模塊講解過程中的注解已經非常詳細了,並且為了便於更好的理解列舉了相應的示例,對於使用Git進行項目協同開發的人員來說,上面的內容可以說是綽綽有余了。
接下來,我們順著Git的夢幻之旅繼續往下走。項目協作的各個成員是如何與Git服務端進行數據通信的呢?之前我們有提到Git支持四種數據傳輸協議,那麼我們來深入了解下這四種傳輸協議各自的優勢和不足。
通過上面的對比分析,我們發現http/https是最簡單最流行的一種協議方式,ssh是最安全的一種協議方式,特別是在互聯網領域這一點尤為重要,並且http/https的寫操作也是基於ssh協議完成的,那麼我們繼續深入的了解下ssh通信協議。
ssh數據通信協議也稱作安全外殼協議,從他的名字就可以看出他使命就是確保安全數據傳輸,並且傳輸的數據會進行壓縮,降低網絡傳輸消耗,提高數據傳輸速度。ssh協議是基於公鑰私鑰對的方式進行加密授權數據傳輸的,下面我們通過兩個加密算法來理解公鑰私鑰——對稱加密算法和非對稱加密算法。
圖3為對稱加密算法流程圖,數據的發送方sender和接收方receiver通過相同的密鑰key對數據進行加密解密操作。秘鑰用於確保數據在公共通道傳輸過程中的安全性,即使密文數據在傳輸過程中被外部竊取,如果沒有密鑰也不能獲取其中的內容。
圖4為非對稱加密算法流程圖,數據的發送方sender和接收方receiver通過不同的密鑰key對數據進行加密解密操作。sender通過公鑰key1對明文數據進行加密,receiver通過私鑰key2對密文數據進行解密。公鑰和私鑰一定是成對出現的,如果一個文件用公鑰進行加密,則可以通過私鑰進行解密;如果一個文件用私鑰進行加密,則可以通過公鑰進行解密。比如,我們在互聯網環境中和其他合作方進行數據通信,我們的私鑰是保密的,只有自己知道,公鑰可以分發給合作方1,合作方2等等,這些合作方可以通過公鑰對數據進行加密傳送給我們,然後我們通過自己的私鑰進行解密,並且在這個過程中合作方之間是獨立的數據安全的,不會看到其他其他合作方的數據,這也是非對稱加密的一個優勢。
接著,我們來看下如果生成屬於自己的公鑰和私鑰。
在Git窗口輸入ssh-keygen –t rsa –C “[email protected]”命令,回車,如圖5。
在提示信息的目錄中,我們看到生成兩個文件,id_rsa.pub為公鑰文件,id_rsa為私鑰文件,如圖6。
(在Mac中,切換到.ssh目錄(cd .ssh),執行ssh-keygen –t rsa –C “[email protected]”,生成私鑰和公鑰)
生成的公鑰和私鑰怎麼使用呢?現在我們使用SourceTree基於ssh協議從github上clone一個項目,會發現圖7 ssh認證失敗提示。
為什麼會ssh認證失敗呢?提示信息描述的很清楚,我們需要將自己生成的公鑰加入到github維護的該項目中(這個操作由該項目管理員完成,一個項目可能會被加入多個公鑰),加入之後配合本地的私鑰就可以進行安全的數據通信了,此時客戶端就擁有了該項目的寫權限,然後重新嘗試clone,克隆項目成功。
回過頭來,思考下Git基於http/https通信協議的寫權限是不是也是通過這種方式實現的呢?答案是肯定的。
現在到了可以慶祝的時刻了,你不但可以熟練使用Git命令進行協同工作,還透徹的了解了Git數據通信的內部原理。知其然並知其所以然,將知識運用到實踐中,才是研究技術的最高境界。(送人玫瑰,手留余香)
Android L: 昨天凌晨Google剛剛確認Android L就是Android Lollipop(5.0)
引言Google I/O 2015 推出的 Android Design Support Library令人非常激動。Material Design的推出確實振奮了不少
概念應用的開發離不開存儲,存儲分為網絡、內存、SDCard文件存儲以及外部SDCard2文件存儲,開發中一定要注意好內存管理以免oom、卡頓等不好的用戶體驗,同時還要注意
1、View和ViewRootViewRoot從名稱上來理解似乎是“View樹的根”,這很容易讓人產生誤解。因為ViewRoot並不屬於View樹