github使用說明

github使用說明

前言

什麼是github,github能作什麼?它是一個代碼倉庫,可是你能夠把它當作一個遠程硬盤(雲盤、網盤)。和通常網盤的區別在於,它經過一個叫作git的軟件進行同步,上傳或下載操做,這個軟件有很是強大的同步功能,甚至能夠創建不一樣的存儲分支,讓同步的文件有多個不一樣的版本(這對代碼開發來講是頗有意義的)。可是,若是你不想要,不須要這個功能,也能夠把它當作純粹的免費網盤使用。github

如今就有不少人,經過github來存放我的筆記,日記,博客等文檔資料,在不一樣電腦上,只要同步一下,就能繼續編輯,很是方便。這個甚至比通常的網盤要來得輕鬆,由於git對版本的控制更好,數據傳輸量更少。同步更加智能化,版本管理更加方便。安全

多說無益,本文介紹git的原理和使用方法,你親自看一下是否對你有用。bash

1、git原理

1.1 分佈式儲存

git是一個分佈式同步工具,簡單來講,它不要求你創建一個特定的服務器,你能夠在任何地方創建本身的存儲倉庫,不一樣的倉庫沒有地位的差別,都是平等的,這就去中心化了,因此叫分佈式。服務器

這有什麼好處,好比你不須要依賴某個網盤提供商,若是它不當心倒閉了,只要你把倉庫搬到另外一個提供商就能夠,甚至,你直接弄一臺電腦放倉庫也是能夠的。這個理念我認爲是很是有居安思危精神的。千萬別過於相信網絡,要給數據一個備份。網絡

若是是傳統的網盤,你須要用它的軟件,下載文件到你的電腦,而後用另外一家的軟件,上傳到另外一個網盤備份,不用兩天你就受不了。若是你不跟蹤備份,可能網盤沒通知你就把你的學習資料刪除了,那你是怎麼也要不回來的。相信經歷過的朋友都知道。而只需用git,就能統一的管理各個倉庫,輕鬆進行復雜的同步。編輯器

1.2 版本庫 repository

也就是儲存倉庫,可是這個倉庫不但能夠放文件,還對文件的修改、刪除等歷史記錄做跟蹤,讓你能夠回溯到某個歷史時期。這是git 最強大的功能。分佈式

爲了利用好版本管理功能,要求文件類型是文本類型,最好是UTF-8編碼的。工具

git init #在當前目錄下創建倉庫,將新建一個.git文件夾來存儲倉庫數據

1.3 添加到倉庫

在當前目錄新建文件,而後加入倉庫,git便可維護該文件的同步管理。性能

git add file.txt #將當file.txt文件加入git倉庫

1.4 提交到倉庫

添加並不會馬上提交,也不會自動同步,這個交給用戶本身判斷恰當的提交時機。

git commit -m "這裏寫備註" #提交數據

每次提交,都要求你寫一個備註,來記錄你此次提交作了什麼,這是個良好的習慣,由於這樣你回溯歷史的時候,才知道哪一個版本是你的目標版本。

1.4.1 顯示文件變化

當前被跟蹤的文件,和倉庫版本有什麼差別,能夠用git status 列出哪些文件改動了的文件。

若是你還想知道具體修改了什麼地方,能夠用git diff xxx來查看xxx文件的改動狀況。

1.5 變動到不一樣的歷史版本

這個是比較高級的功能,也許你用得上,也許用不上。首先,git reflog會顯示你提交文檔的版本:

#樣例輸出
f9adcba (HEAD -> master) HEAD@{0}: reset: moving to f9adc
9a75fd8 HEAD@{1}: reset: moving to HEAD~1
f9adcba (HEAD -> master) HEAD@{2}: commit: 測試回退功能
9a75fd8 HEAD@{3}: commit: 加了一點
781b0ad HEAD@{4}: commit: 有加了一點
55227c1 HEAD@{5}: commit: git文檔修改
f2d5850 HEAD@{6}: commit (amend): ss2
ff6877d HEAD@{7}: commit (initial): ss

要跳到那個版本,使用git reset --hard f9ad,其中f9ad用具體的版本號替換。在以上樣例的第一列,只須要給出幾位,git就會尋找到對應版本。

當跳轉到該版本,相應的文檔數據會當即修改。

1.6 工做區和版本庫的區別

當你在某個目錄下面,建立倉庫git init,該目錄就是你的工做區,而具體的倉庫的一些配置信息,是放在.git目錄下的(可能被隱藏)。

工做區的做用就是你要同步的文件,應該放在這個目錄下面,你只須要修改對應的文件,git負責其他的一切。你不須要刻意的去修改或者理會.git目錄下面的內容,而應該使用git軟件來輸入命令。

1.7 暫存區 stage

當用git add xxx添加文件,實際上就是把文件放入暫存區。當git commit就會把暫存區的內容正式提交到某個分支(之後解釋分支),並清空暫存區。

若是要撤銷工做區的修改,能夠用git checkout -- xxx;若是要撤銷暫存區的修改,能夠用git reset HEAD xxx

1.8 遠程倉庫

還記的我說過git是分佈式的麼?若是隻是在本身電腦目錄建立一個倉庫,那就沒什麼意思了,如今學習怎麼添加遠端的倉庫。

首先,申請github.com網站的帳戶,並申請一個倉庫的使用權,而後獲得一個倉庫的連接地址,而後:

git remote add 倉庫別名 連接 #添加遠端倉庫
git push -u 倉庫別名 master #將本地分支master提交到倉庫。-u表示關聯對應分支
git remote -v #顯示遠程倉庫狀況
git pull #從遠程倉庫拉取最新版本

1.9 分支

git容許創建不一樣分支,所謂的分支,就是另外一條修改文件的路線。git記錄每一條路線不一樣的修改內容,當合並的時候會要求你對有衝突的修改內容進行選擇。

git branch git #建立名爲git的分支
git checkout git #切換到git分支
git branch #查看當前分支狀況
git merge git #將git合併到當前分支
git branch -d git #刪除git分支

建立分支後,所作任何修改,隻影響當前分支,當切換分支,文件會瞬間回到另外一個分支的狀態下。

雖然git分支這個功能看上去很強大,又很複雜,但實際上運做很是高效,它總能按照你指望的方式去運做。所以,推薦多使用,用來劃分不一樣的關注點也是挺好的。

一個合理的使用分支的方法是:

  1. 保持主分支不變,其餘分支修改
  2. 而後將當前主分支合併到某個分支,解決衝突
  3. 最後用主分支合併該分支,更新主分區

這樣就算再多人一塊兒合做編輯,也能保證主分支是穩定可靠的。

不過,最好仍是不要隨便跳轉分支,由於跳轉分支容易致使當前數據丟失,而後還會致使不少不少的誤操做。(本博客就是這樣丟失了一些歷史信息,╮(╯▽╰)╭!)q

1.10 儲藏

特別要注意,切換分支是一個高度危險的操做!由於它會毀掉當前工做區的狀態。切換分支以前,應該先提交當前修改內容到倉庫。可是,若是佔時沒法提交,能夠藉助儲藏功能,把當前工做區保存在一個棧表裏面。

git stash #保存並清空當前工做區修改狀態
git stash pop #回彈當前工做區上一個狀態。
git stash list #顯示儲藏棧表

1.11 標籤

標籤對應了commit 提交版本,由於這個版本號太複雜,所以用標籤名來代替,更加容易識別。也做爲一個發行版本號來使用。

git tag v0.9 #當前版本命名爲標籤v0.9
git tag #查看當前標籤
git tag -d v0.9 #刪除對應標籤
git push origin v0.9 #提交標籤到遠程倉庫

2、實踐

2.1 流程總結

縱觀理論知識,咱們能夠得出一些結論:

  1. git是分佈式,多倉庫的,其中最直接的倉庫就在當前工做目錄下的.git文件,還能添加遠程倉庫。
  2. 工做流程是: 初始化並配置git本地倉庫--》在工做區編輯文件--》提交到暫存區--》本地倉庫--》遠程倉庫。
  3. 有回退的機制:遠程倉庫——pull或clone—》本地倉庫--版本回溯--》當前版本工做區。
  4. 有儲藏現場機制: 工做區、暫存區--stash--》儲藏堆棧; 儲藏堆棧--stash pop--》恢復當前工做區、暫存區。
  5. 有版本控制: 每次commit提交,就會產生一個版本記錄,任什麼時候候,只要有這個記錄就能回退到該版本的狀態。所以,commit以後的操做至少能夠保證該版本的數據是安全的。
  6. 有分支能力: 分支對團隊來講是最重要的支持能力,恰當使用分支,能夠多人同時編輯,而不會產生太多數據衝突。
  7. 有些操做是危險的:若是沒有提交到倉庫,就切換分支,當前工做內容就可能丟失,由於切換分支並不懂得自動保存當前工做區的狀態。只要是會對當前工做區產生影響的操做,都有可能影響到數據安全(若是當前工做區沒有提交,有修改狀態),好比拉取,同步,切換分支,版本跳轉,所以這些操做以前特別要注意查看當前工做區狀態,先提交,或者儲藏現場。

  8. 工做區和暫存區,都是不安全的,能夠視爲臨時數據,他們之間造成一個小型的臨時版本控制機制。工做區的內容能夠放到暫存區,暫存區的內容也可能回退到工做區。

2.2 配置git

2.2.1 安裝git

git 官網在http://git-scm.com,下面以deepin系統爲例:

apt install git #安裝git
git --version #版本號2.17

2.2.2 建立本地倉庫

cd ~
mkdir gittest
cd gittest
git init    #在gittest目錄下建立倉庫,當前工做區便是gittest

git help #查看使用說明

2.2.3 克隆遠程倉庫

非新項目,能夠從遠程倉庫克隆建立。

git clone https://github.com/Anduin2017/HSharp.git cloneProj #從已有的遠程倉庫克隆建立名爲cloneProj的本地倉庫。該遠程連接能夠在github任意一個公開項目中獲取。

2.2.4 配置本地倉庫信息

git倉庫的配置信息,能夠存在三個地方:

  1. system 影響全部用戶,文件位於/etc/gitconfig
  2. global 影響當前用戶,~/.gitconfig
  3. local 影響當前倉庫,.git/config
#添加用戶名和郵箱信息,必備,由於每一次提交倉庫都要記錄當前提交人的這些信息
git config --local user.name "myname" #添加user.name的記錄爲myname,其中--local爲默認值,能夠省略
git config user.email myname@163.com #添加user.email爲myname@163.com

git config --list #列出當前已經配置的內容
git config user.name #列出某項的值,即myname

2.2.5 忽略某些文件 .gitignore

若是不想某些文件被加入倉庫,能夠用.gitignore文件指定,內容例如:

#忽略.cpp文件和~符號結尾的文件
*.cpp
*~

2.3 檢查工做區和暫存區狀態

應該常用這個命令確認文件狀態。

注意: 若是你使用編輯器來編輯,要注意當前編輯狀態和當前文件狀態是不一樣的。git是針對文件而不能知道你有沒有正在編輯。若是你正在編輯,又經過git命令修改了文件,你的編輯器就會提示你原始文件已經被修改,你沒法保存等異常狀態。所以,你在使用git命令前,應該先把編輯狀態下的文件,用編輯器保存一下。

git status #查詢狀態

2.4 正式進入工做

2.4.1 工做區和暫存區交互

  1. 編輯工做區上的文件,而後放到暫存區,繼續編輯
  2. 若是編輯後不滿意,用暫存區的內容恢復到工做區
  3. 若是滿意,繼續放進暫存區
#建立一個新文件,並在末尾輸入內容「hello world!」
cat >>myfile.txt
hello world!
^C
#將該文件放入暫存區
git add myfile.txt
#繼續編輯,並在末尾添加「hello.」
cat >>myfile.txt
hello.
^C
# 這時,就存在兩個不一樣的版本,一個是修改前放進暫存區的"hello word!"版本,一個是工做區內的「hello word!hello."版本。
git status #遇事不決,先用這個確認狀態。能夠發現同一個文件,有兩種狀態。一種是放在暫存區的,提示讓你提交;另外一種是在工做區的,提示讓你暫存變動。
git diff myfile.txt #確認一下文件內容的差異。顯示工做區和暫存區兩個同名文件的對比,若是你會看diff輸出格式,就能發現差異是添加"hello."

#選擇1,放棄當前修改,返回上次暫存內容
git checkout -- myfile.txt
#選擇2,確認修改,放入暫存
git add myfile.txt
#git status的提示很豐富,提示上面有以上指令的使用格式

#刪除文件
#若是某個文件被刪除,這在git中也是一個特殊的修改
git rm xxx #刪除xxx,並把刪除狀況告知暫存區

git rm --staged yyy #從暫存區刪除yyy文件,但不影響工做區

2.4.2 暫存區和本地倉庫交互

暫存區的內容並不會產生一個穩定的版本,最終要正式加入倉庫,須要commit提交。

提交會要讓你輸入每次提交的備註,命令行下面的編輯器由git config core.editor選項控制。

git commit #向本地倉庫提交暫存區的內容
git reset HEAD myfile.txt #取消暫存區內容。

git diff --staged #比較暫存區和倉庫版本的不一樣

git commit -a -m 」備註「 #把工做區的改動所有暫存起來,而後直接提交。-a參數將縮減提交的步驟。

git log -2 #觀察最近兩條提交記錄
git log  --pretty="%h %an,%ar:%s" #按指定格式顯示記錄
git log --pretty=oneline --graph #顯示按分支提交結構圖

apt install gitk #安裝圖形化顯示記錄的工具

2.4.3 遠程倉庫

git remote -v #查看遠程倉庫列表
git remote add remotegit https://github.com/Anduin2017/HSharp.git #添加一個遠程倉庫,命名爲remotegit

git fetch remotegit #下載遠程倉庫remotegit的對象和引用

git remote show remotegit #顯示遠程倉庫關聯信息
git remote rename remotegit newname #把遠程倉庫命名進行修改
git remote rm newname #刪除遠程倉庫的關聯

git clone https://github.com/Anduin2017/HSharp.git clonegit #克隆生成一個徹底同樣的本地倉庫,建立工做目錄爲clonegit
2.4.3.1 遠程分支

遠程倉庫上面的分支,稱爲遠程分支。

git remote -v #查看遠端倉庫狀況
git remote add gitbak file:///home/user/git #加入本地另外一處倉庫

git fetch gitbak #下載倉庫信息
git branch -av #查看全部分支,包括遠端倉庫
git branch --set-upstream-to=gitbak/master #當前分支關聯gitbak/master分支
git pull gitbak master --allow-unrelated-histories #合併不關聯的歷史數據

git push cloneProj HEAD:master #提交本地分支到遠端倉庫

#注意:應該儘可能保持本地分支名稱和遠程一致。

2.4.4 儲藏

這個功能比較簡單。

git stash #儲藏當前工做區和暫存區變更
git stash pop #恢復

2.4.5 版本

每一次提交,都會產生一個版本,任什麼時候候均可以跳轉到該版本,可是版本標識是一個字符串哈希序列(sha-1 40字符哈希),不方便對外公佈。

git tag #顯示現有標籤
git tag v1.0 #爲當前版本命名標籤
git show #顯示HEAD關聯提交對象信息
git show v1.0 #顯示特定版本信息
git push origin v1.0 #向遠程倉庫提交標籤

git commit -am"備註" #建立一個新提交"commit"對象,並改變HEAD指針指向新對象,若是頭指針指向某個分支,先改變該分支指向新對象,再用HEAD指針指向該分支。簡而言之,建立新版本

git reset 2341a --hard #HEAD指針調到散列爲2341a開始的commit對象,即跳到該版本,--hard參數重置當先工做區和暫存區

2.4.6 分支

git中的分支,相似一個指針,一個提交(commit)相似鏈表中的一個節點。commit保存了父節點,和整個目錄樹結構,所以當分支(指針)指向某個commit,內容天然就是該節點的狀態。理解這點很重要。也許你會擔憂每次提交都產生一個當前文件目錄的快照,會不會致使存儲量變得很大,實質上是不須要擔憂的。git以一種高效的方式進行相關記錄,無論是性能仍是空間,都容許你瞬間執行提交,產生新的快照。

一開始有個master的分支,有個HEAD指針,它指向master,而master指向具體的commit節點,每次提交,master都會更新到新的節點上。若是你使用某種命令移動這個指向,天然就會變動到不一樣的版本,這就是實現版本管理的基礎。

git branch -va #顯示分支狀況,-a表示全部分支,包括遠程分支,這個命令常用,由於它會顯示分支的狀況,相似git status顯示文件狀況。

git branch testbranch #基於當前分支建立一個新分支,實質不過是複製一個指針而已,效率很是高

#當你想切換到其餘分支
#1. 保存正在編輯的文件
#2. 儲藏現場git stash push -m "備註"
#2.2 或者提交git commit
#3. 切換分支
#爲何?由於切換分支會清空現場,你將丟失掉工做區和暫存區的改動數據
git checkout testbranch #切換到testbranch,它和此前分支上一次提交版本如出一轍

git commit -m 「備註」 #每次提交,都會移動當前分支,指向最新的commit對象

#分支的成果最終要合併起來
git merge master #將master分支合併到當前分支
#合併過程可能會出現數據衝突,參考提示,手工選擇後合併成功
git checkout master
git merge testbranch #更新master分支,通常這個分支做爲默認的主分支
git branch -d testbranch #刪除分支
#若是該分支新增的內容沒有被合併到其餘分支,就會提示讓你先合併,善用git status,根據提示來操做便可。

git mergetool #調用圖形界面來解決內容衝突

分支的功能並不算太複雜,可是如何設計適合本身須要的分支系統,就是一門值得思考的功課。建議master做爲集成主分支,有若干分支負責實際編輯,編輯完畢合併到主分支。而後每一個細分支有里程碑(用標籤標註),發佈版本應該選擇恰當的里程碑組合,進度稍微比主分支慢。

另外,若是須要修補,能夠選擇在里程碑新建一個補丁分支,它須要和主分支合併,也須要和發佈分支合併。

  1. master分支,負責最新版本的持續集成
  2. publish分支,負責里程碑版本的特定集成
  3. featureX分支,負責各項具體內容,並在特定版本打下里程碑標籤
  4. patch分支,負責修補漏洞,選擇要修復的版本,並打上修訂號。由於集成是一件比較費勁的事情,因此能夠選擇只對特定版本進行修復。

可能用到的技術包括:

  1. 建立分支: git branch 分支名 提交對象
  2. 跳轉到該分支: git checkout 分支名
  3. 編輯,保存,提交
  4. 跳轉到集成分支:git checkout xxx
  5. 集成:git merge x1
  6. 打標籤:git tag v1.0.0.f1
  7. 分離頭指針: git checkout --detach
  8. 跳轉版本:git reset --hard commit對象

集成merge的基本邏輯是:

  1. 尋找共同祖先,計算出各自不一樣點
  2. 讓用戶選擇合併那些內容

所以應該採起的策略:每一個分支應該儘可能尋求共同祖先。那麼共同祖先是怎麼來的?實質之前某個merge節點(或者是分裂的初始點),不然分支怎麼會有共同祖先?所以解決集成merge衝突複雜化的辦法,實際是分紅屢次集成,也就是持續集成的意義所在。

其餘使用技巧

  1. 若是顯示的中文文件名變成了\344\275\277\347\224\250相似的編碼格式,能夠用:
    git config --global core.quotepath false
相關文章
相關標籤/搜索