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

聲明:本文爲CSDN原創投稿文章,未經許可,禁止任何形式的轉載。 php

      如今大部分使用的都是SVN,也有一部分遷移了Git,雖然挺好的,不過還有其它不少版本控制的工具,並無誰最好用,最重要的是適合本身的公司與團隊,效率和團隊是成正比了,重要的不是武器,雖然武器也挺重要的,不過最重要的仍是配「劍「者,不過要是對Git沒接觸過或者認識不夠的話,我想,這篇「華序」寫的文章足以讓你對Git有所認識了,不過了解下就能夠了,凡事不要太執着了,下面,就讓咱們進入正文吧。git


正文:github

Git是一款開源的分佈式版本控制系統(VCS),經常使用的VCS工具還包括SVN、Mercurial等,他們的使命是對資源變化的進行版本管理控制,對資源容災備份,支持多域協同開發。這裏的資源不只僅是系統代碼,還包括圖片、文件、網頁等。本篇文章結合流程圖、詳細的註解、實例操做針對Git的使用、Git數據通訊原理進行細緻的講解,利用半場足球賽的時間通讀全文後相信你面對Git會自信滿滿、知其因此然,使用起來遊刃有餘,固然對其餘工具的理解也就很是容易了。
web

Git在各個操做系統的安裝過程就不綴文了,步驟都是固定的,按照步驟一步一步安裝就能夠了。在開始講解以前,咱們先對Git進行資源版本管理有個總體的瞭解,如圖1爲Git資源狀態流轉過程,理解清楚這個流轉圖對Git命令的操做很是關鍵。算法

圖片描述

接下來,咱們開始夢幻的Git命令之旅,瞭解下在項目協同工做過程當中常用的Git命令。如下是我在工做過程當中的總結(能夠說是個人Git家底兒了),爲了更清晰的展現,將命令操做分紅了有序的多塊,你們在閱讀過程當中可能會感受到一絲筆記的色彩,沒錯,這就是這篇文章的特色,我相信這種方式會更利於你們理解。vim

(PS:下文中【】的內容爲對命令的註解)
git init                       【初始化本地倉庫 ,將當前項目目錄加入git管理】
git add <filename||path>         【將新文件加入版本控制,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協議。app

git clone source. zhouliwei.com/app/zhouliwei.git            【本地倉庫clone】 
git clone git+ssh://gitusername@192.168.0.1/zhouliwei.git 【遠程倉庫clone(ssh協議)】 
git clone http://gitusername@source.zhouliwei.com/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  <filename||path> 【將文件或者路徑從遠程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 <server> 【將本地倉庫鏈接到遠程倉庫   git remote add origin http://gitusername@source.zhouliwei.com/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://gitusername@source.zhouliwei.com/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 「zhouliwei555@163.com」命令,回車,如圖5。

圖片描述

圖5 生成公鑰私鑰

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

(在Mac中,切換到.ssh目錄(cd .ssh),執行ssh-keygen –t rsa –C 「zhouliwei555@163.com」,生成私鑰和公鑰)

圖片描述

圖6 公鑰私鑰文件

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

圖片描述

圖7 ssh認證失敗

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

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

如今到了能夠慶祝的時刻了,你不但能夠熟練使用Git命令進行協同工做,還透徹的瞭解了Git數據通訊的內部原理。知其然並知其因此然,將知識運用到實踐中,纔是研究技術的最高境界。(送人玫瑰,手留餘香)

相關文章
相關標籤/搜索