Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android Git命令家底兒及Git數據通信原理詳解

android Git命令家底兒及Git數據通信原理詳解

編輯:關於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支持四種數據傳輸協議,那麼我們來深入了解下這四種傳輸協議各自的優勢和不足。

傳輸協議 優勢 缺點 本地傳輸 1. 遠程倉庫部署在本地目錄,Git client-server之間的數據通信類似本地文件的復制剪切,數據的通信速度較快;2. 資源的權限沿用本地操作系統的文件權限和網絡訪問權限,不需要單獨配置。 1. 由於遠程倉庫在本地目錄,資源毀滅性丟失的危險性增大。 ssh協議(安全外殼傳輸協議ssh://) 1. 服務搭建相對較簡單;2. 基於公鑰私鑰對的方式進行加密授權數據傳輸;3. 同時支持數據的讀和寫操作。 1. 不支持匿名訪問,必須通過ssh訪問主機才能讀寫倉庫。 Git協議(git://) 1. 自身攜帶的傳輸協議,傳輸速度最快的協議;2. 使用類似ssh相同的數據傳輸機制,但取消了加密解密的開銷。 沒有授權機制,要麼所有客戶端都可讀,要麼所有客戶端都可寫,不能根據情況選擇性配置讀寫權限;2. 服務搭建相對較復雜。 http/https協議(超文本傳輸協議) 服務搭建相對較簡單,基於Apache等web容器就可以實現;2. 授權機制簡單,能夠訪問Git倉庫所在服務器的web服務的人都可以獲取遠程倉庫資源。 1. 數據通信網絡開銷較大;2. 執行寫操作需要基於ssh協議。

通過上面的對比分析,我們發現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。

圖片描述

 

圖5 生成公鑰私鑰

 

在提示信息的目錄中,我們看到生成兩個文件,id_rsa.pub為公鑰文件,id_rsa為私鑰文件,如圖6。

(在Mac中,切換到.ssh目錄(cd .ssh),執行ssh-keygen –t rsa –C “[email protected]”,生成私鑰和公鑰)

圖片描述

 

圖6 公鑰私鑰文件

 

生成的公鑰和私鑰怎麼使用呢?現在我們使用SourceTree基於ssh協議從github上clone一個項目,會發現圖7 ssh認證失敗提示。

圖片描述

 

圖7 ssh認證失敗

 

為什麼會ssh認證失敗呢?提示信息描述的很清楚,我們需要將自己生成的公鑰加入到github維護的該項目中(這個操作由該項目管理員完成,一個項目可能會被加入多個公鑰),加入之後配合本地的私鑰就可以進行安全的數據通信了,此時客戶端就擁有了該項目的寫權限,然後重新嘗試clone,克隆項目成功。

回過頭來,思考下Git基於http/https通信協議的寫權限是不是也是通過這種方式實現的呢?答案是肯定的。

現在到了可以慶祝的時刻了,你不但可以熟練使用Git命令進行協同工作,還透徹的了解了Git數據通信的內部原理。知其然並知其所以然,將知識運用到實踐中,才是研究技術的最高境界。(送人玫瑰,手留余香)

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved