Git命令家底儿及Git数据通信原理详解
聲明:本文為CSDN原創投稿文章,未經許可,禁止任何形式的轉載。
作者:周立偉(花名:華序,ITeye博客),關注分布式、高并發和Java中間件的研究。
責編:錢曙光,關注架構和算法領域,尋求報道或者投稿請發郵件qianshg@csdn.net,另有「CSDN 高級架構師群」,內有諸多知名互聯網公司的大牛架構師,歡迎架構師加微信qshuguang2008申請入群,備注姓名+公司+職位。
Git是一款開源的分布式版本控制系統(VCS),常用的VCS工具還包括SVN、Mercurial等,他們的使命是對資源變化的進行版本管理控制,對資源容災備份,支持多域協同開發。這里的資源不僅僅是系統代碼,還包括圖片、文件、網頁等。本篇文章結合流程圖、詳細的注解、實例操作針對Git的使用、Git數據通信原理進行細致的講解,利用半場足球賽的時間通讀全文后相信你面對Git會自信滿滿、知其所以然,使用起來游刃有余,當然對其他工具的理解也就非常容易了。
Git在各個操作系統的安裝過程就不綴文了,步驟都是固定的,按照步驟一步一步安裝就可以了。在開始講解之前,我們先對Git進行資源版本管理有個整體的了解,如圖1為Git資源狀態流轉過程,理解清楚這個流轉圖對Git命令的操作非常關鍵。
接下來,我們開始夢幻的Git命令之旅,了解下在項目協同工作過程中經常使用的Git命令。以下是我在工作過程中的總結(可以說是我的Git家底兒了),為了更清晰的展示,將命令操作分成了有序的多塊,大家在閱讀過程中可能會感覺到一絲筆記的色彩,沒錯,這就是這篇文章的特點,我相信這種方式會更利于大家理解。
(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協議。
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數據通信的內部原理。知其然并知其所以然,將知識運用到實踐中,才是研究技術的最高境界。(送人玫瑰,手留余香)
心靈雞湯:如果你愛他,就送他去創業公司,因為那里是天堂;如果你恨他,就送他去創業公司,因為那里是地獄。作者投稿:
- 詳解應對平臺高并發的分布式調度框架TBSchedule
- 快速認識和使用瀏覽器跟蹤Http服務及Http服務調試工具
總結
以上是生活随笔為你收集整理的Git命令家底儿及Git数据通信原理详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 给ADAS泼冷水?不,是客观评价
- 下一篇: 球30家厂商角逐自动驾驶汽车 四年后10