我是經過看廖雪峯的git教程學習的,真的是極好的,如下是我學習過程當中的總結,記錄下來,方便本身參考以熟悉git和github的使用。linux
除了廖雪峯的教程,還比較推薦在看完廖雪峯的教程以後,再看這樣一篇文章:使用git和github進行協同開發流程,和個人另外一篇git的筆記:使用git和github管理本身的項目---真實開發環境的策略 ,深刻了解github和git怎麼在具體的項目開發中管理項目、有什麼好的規範!git
我這裏記錄git的學習筆記,方便隨時參考,具體的git的原理、github的原理、集中式和分佈式版本控制的區別、版本控制的概念和原理、Git和其餘版本控制工具好比SVN的區別、以及更多的相關概念講解,請本身參見廖雪峯的git教程。github
我強烈推薦先看廖雪峯的git教程來系統化認識和學習git,而後本身整理一份具體的步驟方便平時開發時快速參考,或者直接參考個人。ubuntu
先說一個比較可笑的事:廖雪峯的git教程中,剛開始的部分的瀏覽量有38萬,可是最後一頁教程的網頁的瀏覽量是1萬多。vim
之前由於以爲git、github比較難,因此一直拖着不學,如今去嘗試學習,一夜就OK了segmentfault
重點之一是找到全面的、詳細的、生動的、高質量的教程。廖雪峯的git教程是我目前找到的最好的一個。以前找到的講解git用法的書《pro git》如今看來是沒有必要再看了!安全
重點之二就是本身當即去學,其實沒什麼難的,不要被貌似難的表象、概念唬住。服務器
重點之三是最好能本身作簡單的、系統的整理,方便本身隨時再回來查看、複習、參考,不至於出現這樣的狀況:學完之後過一段時間以後再用,可是這時候發現忘了差很少了!ssh
重點之四就是當即動手去用,不然學完很快就忘了。編輯器
有錢的買mac,沒錢的用ubuntu--或者其餘的linux發行版、被逼無奈的用Windows--可是被逼之餘的自主時間必定要遠離Windows。
如今個人測試環境是ubuntu。
以對一個文件的管理爲例,簡單說明git的使用。另外須要說明的是下面的實驗過程主要是隻針對一個文件、而且修改的次數每每只有一次,而在真正的項目中,每每有大量的文件,也可能屢次修改後才合併,合併時候的衝突可能也不僅一兩個,等等。不過原理都是同樣的,我想說的是,不要侷限在這個教程的示例上,請本身經過教程掌握基本的遠原理以後,本身推廣、去大量的實踐,最重要的是要制定一個好的版本控制的策略(合理分工、安排,仍是儘量的避免衝突爲好),這個能夠參考:使用git和github進行協同開發流程以及個人學習筆記使用git和github管理本身的項目---真實開發環境的策略。
sudo apt-get install git
先安裝git
先建立目錄,做爲倉庫
git init
初始化倉庫,能夠發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄裏面的文件,否則改亂了,就把Git倉庫給破壞了
vim readme.txt
新建一個文本文件,好比往裏面添加簡單的一行字符串
git add readme.txt
添加一個文件,好比readme.txt,若是目錄裏面的全部文件都要添加,能夠git add *
git commit-m "添加一個readme.txt文件"
將文件提交到倉庫,並加上說明(這時候是版本1)
若是是第一次使用git,那麼git commit可能報錯,因此須要你配置一些我的信息
git config --global user.email "you@example.com"
配置郵件
git config --global user.name "Your Name"
配置用戶名
必須配置,不然後面的commit、push到遠程庫都會失敗
而後再次git commit -m "添加一個readme.txt文件"
纔會成功
假如此時第一次修改了readme.txt文件
git status
讓咱們時刻掌握倉庫當前的狀態。這時告訴咱們,readme.txt被修改過了,但尚未準備提交的修改。
git diff readme.txt
查看對readme.txt作了什麼修改
git add readme.txt
提交修改和提交新文件是同樣,先git add
git status
能夠再用git status查看倉庫的當前狀態,告訴咱們,將要被提交的修改包括readme.txt
git commit-m "第一次修改"
而後再git commit,並添加修改的描述(這時候是版本2)
git status
能夠再執行git status看倉庫狀態,由於全部的都提交了,Git告訴咱們當前沒有須要提交的修改,並且,工做目錄是乾淨(working directory clean)的。
你能夠像上面所說的那樣不停的提交新的文件、提交對文件的修改
這時候第二次修改readme.txt文件
git add readme.txt
先git add
git commit -m "第二次修改"
提交第二次修改(這時候是版本3)
git log
顯示從最近到最遠的提交日誌,具體顯示的內容本身試一試看看
git log --pretty=oneline
若是嫌輸出信息太多,看得眼花繚亂,試試加上--pretty=oneline參數
看這篇教程去理解爲何Git的版本號要這麼長,Git的版本號相似:3628164fb26d48395383f8f31179f24e0882e1e0 這樣的特別長的十六進制數。
git reset --hard HEAD^
會回退到上一個版本,也就是從版本3回退到版本2
在Git中,用HEAD表示當前版本,也就是最新的提交3628164...882e1e0(注意個人提交ID和你的確定不同),上一個版本就是HEAD^,上上一個版本就是HEAD^^,固然往上100個版本寫100個^比較容易數不過來,因此寫成HEAD~100
vim readme.txt
能夠看到此時的readme.txt文件就是版本2時候的內容,回退成功!
git log
此時看到版本3的信息沒有了
git reset --hard 3628164
經過命令行上的歷史信息(假如你沒清屏的話),找到版本3 的版本號,不必定要所有的版本號,就像這個命令的例子,只要前面的約七、8位這樣就能夠指定回到版本3
vim readme.txt
看到的是第三版本的readme.txt文件的內容,因此又回來了
Git的版本回退速度很是快,由於Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從指向你要回退的那個版本
git reflog
記錄你的每一次命令,最早顯示的是這個命令執行以後的版本的版本號的前七位,這樣就算你清屏了或者重啓了,也能找到某個版本的版本號,就能夠輕鬆回退到那個版本
工做區:就是你在電腦裏能看到的目錄,好比個人learngit文件夾就是一個工做區。
版本庫:工做區有一個隱藏目錄.git,這個不算工做區,而是Git的版本庫。
暫存區:Git的版本庫裏存了不少東西,其中最重要的就是稱爲stage(或者叫index)的暫存區,還有Git爲咱們自動建立的第一個分支master,以及指向master的一個指針叫HEAD。
前面講了咱們把文件往Git版本庫裏添加的時候,是分兩步執行的:
第一步是用git add把文件添加進去,實際上就是把文件修改添加到暫存區;
第二步是用git commit提交更改,實際上就是把暫存區的全部內容提交到當前分支。
由於咱們建立Git版本庫時,Git自動爲咱們建立了惟一一個master分支,因此,如今,git commit就是往master分支上提交更改。
你能夠簡單理解爲,須要提交的文件修改統統放到暫存區,而後,一次性提交暫存區的全部修改。
詳細知識見這篇教程。必須理解暫存區、工做區、版本庫。這些都是是Git很是重要的概念,弄明白了這些概念,就弄明白了Git的不少操做到底幹了什麼。沒弄明白的話,請反覆看!!
爲何Git比其餘版本控制系統設計得優秀,由於Git跟蹤並管理的是修改,而非文件。
什麼是修改?好比你新增了一行,這就是一個修改,刪除了一行,也是一個修改,更改了某些字符,也是一個修改,刪了一些又加了一些,也是一個修改,甚至建立一個新文件,也算一個修改。
經過實例講解什麼叫跟蹤修改,要想理解,請參考原文結合暫存區的知識理解:
vim readme.txt
編輯文件,好比添加新的一行
git add readme.txt
添加,可是不提交
vim readme.txt
再編輯文件,好比再添加一行
git commit -m "修改兩次,添一次,提交一次"
提交
git status
看到的效果是:只提交了第一次的修改,第二次的修改沒有提交
那怎麼提交第二次修改呢?你能夠繼續git add
再git commit
,也能夠彆着急提交第一次修改,先git add
第二次修改,再git commit
,也就是第一次修改 -> git add -> 第二次修改 -> git add -> git commit
,就至關於把兩次修改合併後一塊提交了。
第一種狀況
修改了readme.txt文件,尚未git add 和git commit
可是在你提交以前發現此次修改有問題。既然錯誤發現得很及時,就能夠很容易地糾正它。你能夠手動把文件恢復到上一個版本的狀態。
git checkout -- readme.txt
也能夠經過命令撤銷修改,這條命令的意思就是,把readme.txt文件在工做區的修改所有撤銷
不管是文件修改後值存在於工做區尚未放到暫存區,仍是已經添加到暫存區,總之這個命令就是讓這個文件回到最近一次git commit或git add時的狀態。
查看文件,內容果真復原了。git checkout -- file命令中的--
很重要,沒有--
,就變成了「切換到另外一個分支」的命令,咱們在後面的分支管理中會再次遇到git checkout命令。
第二種狀況
修改了readme.txt文件,並且執行了git add readme.txt
慶幸的是你在 git commit 以前發現了這個問題
git status
查看一下,修改只是添加到了暫存區,尚未提交
git reset HEAD readme.txt
能夠把暫存區的修改撤銷掉,從新放回工做區。git reset命令既能夠回退版本,也能夠把暫存區的修改回退到工做區。當咱們用HEAD時,表示最新的版本。
git status
查看一下,如今暫存區是乾淨的,工做區有修改
git checkout -- readme.txt
還記得第一種狀況中如何丟棄工做區的修改吧
第三種狀況
如今,假設你不但改錯了東西,還從暫存區提交到了版本庫,怎麼辦呢?還記得版本回退一節嗎?能夠回退到上一個版本。不過,這是有條件的,就是你尚未把本身的本地版本庫推送到遠程。
還記得Git是分佈式版本控制系統嗎?咱們後面會講到遠程版本庫,一旦你把錯誤的修改(若是是影響很大的錯誤)提交推送到遠程版本庫,你就真的慘了……
區別對待本地版本庫和遠程版本庫!
在Git中,刪除也是一個修改操做
添加一個新的文件 test.txt
git add test.txt
git commit test.txt -m "再次新增一個文件"
通常狀況下,你一般會在文件管理器中把沒用的文件刪除,或者直接rm test.txt
git status
這個時候,Git知道你刪除了文件,所以,工做區和版本庫就不一致了,git status命令會馬上告訴你哪些文件被刪除了
如今你有兩個選擇,一是確實從版本庫中刪除該文件,那就git rm test.txt
,而後git commit
文件就從版本庫中刪除了
另外一種狀況是刪除錯了,由於版本庫裏還有,因此能夠輕鬆地將誤刪除的文件恢復到最新版本git checkout -- test.txt
git checkout其實使用版本庫中的版本替換工做區的版本,不管工做區是修改仍是刪除,均可以「一鍵還原」
要想學習這部分的知識,請先參考下面的:a.配置鏈接遠程倉庫Github。
假如如今你已經配置好github,而且在github上添加了learngit
倉庫。
git remote add origin git@github.com:michaelliao/learngit.git
這個命令是在本地的learngit倉庫下執行的,前面經過learngit倉庫爲例咱們已經講過在本地建立和操做git倉庫。這兩個地方的倉庫名不須要相同,由於會經過在本地的倉庫目錄下執行這條命令(命令中包含遠程庫的名字)已經將二者創建了聯繫
請千萬注意,把上面的michaelliao替換成你本身的GitHub帳戶名,不然,你在本地關聯的就是個人遠程庫,關聯沒有問題,可是你之後推送是推不上去的,由於你的SSH Key公鑰不在個人帳戶列表中。
git push -u origin master
把本地庫的全部內容推送到遠程庫上。把本地庫的內容推送到遠程,用git push命令,其實是把當前分支master推送到遠程。因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。
而後去Github對應的遠程庫看看,都已經推送上去了。
此後,每次本地提交後,只要有必要,就可使用命令git push origin master
推送最新修改。
這樣你就能夠在Github上託管你的項目代碼、vim的配置文件和插件、重要的文檔……
如今個人vim的配置文件和插件已經同步到Github上了:https://github.com/xumenger/myVimConfig
另外推薦個人關於vim配置的文章::http://segmentfault.com/a/1190000003722928
假設個人github上面有一個遠程庫,可是本地沒有,須要克隆到本地,遠程庫的名字叫'gitskills'
git clone git@github.com:michaelliao/gitskills.git
克隆一個本地庫
cd gitskills
進入克隆下來的本地庫,默認的名字是和github上的同樣的
ls -al
能夠看到本地的克隆庫裏面是和遠程庫裏面的同樣的
若是有多我的協做開發,那麼每一個人各自從遠程克隆一份就能夠了。
你也許還注意到,GitHub給出的地址不止一個,還能夠用https://github.com/michaelliao/gitskills.git這樣的地址。實際上,Git支持多種協議,默認的git://使用ssh,但也可使用https等其餘協議。
使用https除了速度慢之外,還有個最大的麻煩是每次推送都必須輸入口令,可是在某些只開放http端口的公司內部就沒法使用ssh協議而只能用https。
分支在實際中有什麼用呢?假設你準備開發一個新功能,可是須要兩週才能完成,第一週你寫了50%的代碼,若是馬上提交,因爲代碼還沒寫完,不完整的代碼庫會致使別人不能幹活了。若是等代碼所有寫完再一次提交,又存在丟失天天進度的巨大風險。
如今有了分支,就不用怕了。你建立了一個屬於你本身的分支,別人看不到,還繼續在原來的分支上正常工做,而你在本身的分支上幹活,想提交就提交,直到開發完畢後,再一次性合併到原來的分支上,這樣,既安全,又不影響別人工做。
其餘版本控制系統如SVN等都有分支管理,可是用過以後你會發現,這些版本控制系統建立和切換分支比蝸牛還慢,簡直讓人沒法忍受,結果分支功能成了擺設,你們都不去用。
但Git的分支是不同凡響的,不管建立、切換和刪除分支,Git在1秒鐘以內就能完成!不管你的版本庫是1個文件仍是1萬個文件。
首先教程中會詳細講解分支的原理(分支、指針、工做區……),必定要好好看!!看完以後你才能對你的建立分支和合並分支的操做不僅是會用,更能在用的時候沒有任何疑惑!反正能學到更多的知識,何樂而不爲!
另外推薦這樣的博客:使用git和github進行協同開發流程以及個人學習筆記使用git和github管理本身的項目---真實開發環境的策略。
在版本回退裏,你已經知道,每次提交,Git都把它們串成一條時間線,這條時間線就是一個分支。截止到目前,咱們練習的learngit,只有一條時間線,在Git裏,這個分支叫主分支,即master
分支。HEAD嚴格來講不是指向提交,而是指向master,master纔是指向提交的,因此,HEAD指向的就是當前分支。
開始實戰:
git checkout -b dev
建立一個新的分支:dev,而且會切換到dev分支。因此這條命令有兩個做用。git checkout命令加上-b參數表示建立並切換,至關於如下兩條命令:git branch dev
和 git checkout dev
補充:全部的git管理的項目剛開始時候默認有一條分支:master
git branch
查看當前所在的分支。git branch命令會列出全部分支,當前分支前面會標一個*號。
由於切換到dev分支,因此咱們如今能夠在dev分支上正常提交,好比對readme.txt作一個修改
git add readme.txt
git commit -m "提交到dev分支"
git checkout master
如今,dev分支的工做完成,咱們就能夠切換回master分支
*注意:*切換回master分支後,再查看一個readme.txt文件,剛纔添加的內容不見了!由於那個提交是在dev分支上,而master分支此刻的提交點並無變
git merge dev
這是在master分支上執行的命令,做用是:把dev分支上的工做成果合併到master分支上
git merge命令用於合併指定分支到當前分支。合併後,再查看readme.txt的內容,就能夠看到,和dev分支的最新提交是徹底同樣的。注意到上面的Fast-forward信息,Git告訴咱們,此次合併是「快進模式」,也就是直接把master指向dev的當前提交,因此合併速度很是快。固然,也不是每次合併都能Fast-forward,咱們後面會將其餘方式的合併。
git branch -d dev
合併完成以後,能夠放心的刪除dev分支了
git branch
刪除後,查看branch,只剩下master了
教程中有詳細的圖文說明,很形象,很好!必定要參考!
人生不如意之事十之八九,合併分支每每也不是一路順風的。
git checkout -b feature1
建立新的分支feature1,而且換到這個分支,進行新的實驗
在feature1分支下,假如將readme.txt的最後一行由"test branch" 改成"test feature1"
git add readme.txt
git commit -m "在feature1上修改readme.txt的最後一行"
在feature1分支上提交
git checkout master
切換到master分支。Git還會自動提示咱們當前master分支比遠程的master分支要超前1個提交。
在master分支下,假如將readme.txt的最後一行由"test branch" 改成"test master"由於上面的是在feature1上進行的修改,因此切換回master以後,看到的文件並非在feature1上修改後的文件
git add readme.txt
git commit -m "又在master上修改了readme.txt文件"
在master上也提交修改
如今,master分支和feature1分支各自都分別有新的提交
git merge feature1
在master分支上執行該命令,與feature1分支合併。這種狀況下,Git沒法執行「快速合併」,只能試圖把各自的修改合併起來,但這種合併就可能會有衝突,果真衝突了!Git告訴咱們,readme.txt文件存在衝突,必須手動解決衝突後再提交
git status
git status也能夠告訴咱們衝突的文件
這時候使用vim等編輯器打開readme.txt文件能夠看到已經在readme.txt文件中將衝突的信息已經添加到裏面了,Git用<<<<<<<
,=======
,>>>>>>>
標記出不一樣分支的內容
而後咱們編輯readme.txt文件,處理衝突,將內容改爲咱們想要的樣子
git add readme.txt
git commit -m "解決衝突"
在master上提交
git log --graph --pretty=oneline --abbrev-commit
用帶參數的git log能夠看到分支的合併狀況。用git log --graph
命令能夠看到分支合併圖。
git branch -d feature1
最後刪除feature分支,完成工做。
2015.09.09 今天就學到這裏,實在太晚了,趕忙睡覺,明天還得工做!什麼都沒有身體重要!
明天繼續:分支管理策略
首先看這篇文章瞭解git和SVN的區別,畢竟如今必須在工做中使用的就是SVN,因此仍是弄清楚二者的區別。
Git是分佈式版本控制系統,同一個Git倉庫,能夠分佈到不一樣的機器上。怎麼分佈呢?最先,確定只有一臺機器有一個原始版本庫,此後,別的機器能夠「克隆」這個原始版本庫,並且每臺機器的版本庫其實都是同樣的,並無主次之分。
實際狀況每每是這樣,找一臺電腦充當服務器的角色,天天24小時開機,其餘每一個人都從這個「服務器」倉庫克隆一份到本身的電腦上,而且各自把各自的提交推送到服務器倉庫裏,也從服務器倉庫中拉取別人的提交。
徹底能夠本身搭建一臺運行Git的服務器,不過現階段,爲了學Git先搭個服務器絕對是小題大做。好在這個世界上有個叫GitHub的神奇的網站,從名字就能夠看出,這個網站就是提供Git倉庫託管服務的,因此,只要註冊一個GitHub帳號,就能夠免費得到Git遠程倉庫。
在繼續閱讀後續內容前,請自行註冊GitHub帳號。因爲你的本地Git倉庫和GitHub倉庫之間的傳輸是經過SSH加密的,因此,須要一點設置:
建立SSH Key。在用戶目錄
下,看看有沒有.ssh
目錄,若是有,再看看這個目錄下有沒有id_rsa
和id_rsa.pub
這兩個文件,若是已經有了,可直接跳到下一步。若是沒有,打開Shell(Windows下打開Git Bash),建立SSH Key,輸入命令ssh-keygen -t rsa -C "youremail@example.com"
,你須要把郵件地址換成你本身的郵件地址,而後一路回車,使用默認值便可,因爲這個Key也不是用於軍事目的,因此也無需設置密碼。若是一切順利的話,能夠在用戶主目錄裏找到.ssh
目錄,裏面有id_rsa
和id_rsa.pub
兩個文件,這兩個就是SSH Key的祕鑰對,id_rsa
是私鑰,不能泄露出去,id_rsa.pub
是公鑰,能夠放心地告訴任何人。
登錄GitHub,打開「Account settings」,「SSH Keys」頁面.而後,點「Add SSH Key」,填上任意Title,在Key文本框裏粘貼id_rsa.pub
文件的內容:
點「Add Key」,你就應該看到已經添加的Key:
注意如今的Github的頁面的佈局可能和圖片中顯示有細小的差異,不過相信你能找到對應的操做!
爲何GitHub須要SSH Key呢?由於GitHub須要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,因此,GitHub只要知道了你的公鑰,就能夠確認只有你本身才能推送。
固然,GitHub容許你添加多個Key。假定你有若干電腦,你一下子在公司提交,一下子在家裏提交,只要把每臺電腦的Key都添加到GitHub,就能夠在每臺電腦上往GitHub推送了。
最後友情提示,在GitHub上免費託管的Git倉庫,任何人均可以看到喔(但只有你本身才能改)。因此,不要把敏感信息放進去。
若是你不想讓別人看到Git庫,有兩個辦法,一個是交點保護費,讓GitHub把公開的倉庫變成私有的,這樣別人就看不見了(不可讀更不可寫)。另外一個辦法是本身動手,搭一個Git服務器,由於是你本身的Git服務器,因此別人也是看不見的。這個方法咱們後面會講到的,至關簡單,公司內部開發必備。
如今的情景是,你已經在本地建立了一個Git倉庫後,又想在GitHub建立一個Git倉庫,而且讓這兩個倉庫進行遠程同步,這樣,GitHub上的倉庫既能夠做爲備份,又可讓其餘人經過該倉庫來協做,真是一舉多得。具體能夠見教程。
首先,登錄GitHub,而後,在右上角找到「Create a new repo」按鈕,建立一個新的倉庫:
在Repository name填入learngit
,其餘保持默認設置,點擊「Create repository」按鈕,就成功地建立了一個新的Git倉庫:
目前,在GitHub上的這個learngit倉庫仍是空的,GitHub告訴咱們,能夠從這個倉庫克隆出新的倉庫,也能夠把一個已有的本地倉庫與之關聯,而後,把本地倉庫的內容推送到GitHub倉庫。