git是一個分佈式版本控制系統git
所謂的分佈式管理控制系統就是不存在中央服務器,每個電腦都有一個完整的版本庫,不須要聯網就能夠工做。github
分佈式版本控制系統一般也有一臺充當「中央服務器」的電腦,但這個服務器的做用僅僅是做爲方便你們的修改。沒有他,你們同樣能夠幹活,只不過方便了交換而已安全
下面說下git的版本庫,也能夠說是git的倉庫,英文repository,其實就是一個能夠被git管理起來的目錄而已。每個文件的修改,刪除git均可以追蹤,以便git能夠還原每個歷史的文件服務器
建立一個版本庫很是的簡單,選擇一個合適的地方app
mkdir yangleiPro框架
cd yangleiProssh
pwd分佈式
pwd命令是顯示當前的目錄,經過git init命令,把這個目錄變成git能夠管理的目錄。工具
如上,git倉庫就搞定,能夠看到目錄下面多了一個.git的東東。學習
有了repository,固然須要往咱們的repository裏添加項目文件,能夠新建,也能夠複製到yangleiPro目錄下
用git add命令添加。
若是沒有任何顯示,就表明你添加成功了
添加完了文件,就能夠提交文件了,把文件提交到倉庫中。
用git commit命令。
一般咱們能夠
git commit -m "study git"
-m後面是對本次提交的說明性文件。
學習了建立版本庫,add和commit文件。下面來講下git的操做
status命令和diff命令
git status命令可讓咱們時刻的知道git的狀態,好比一個文件被修改過,或者一個文件沒有提交之類的
git diff命令顧名思義就是查看difference,也就是說git diff能夠查看咱們所修改的內容
版本回退
當咱們提交了不少次文件後,想看看歷史版本都有哪些,咱們能夠運行git log命令
git log命令用於現實從近到遠的提交日誌。
若是嫌輸出的信息太多,能夠用git log --pretty=oneline,此時你看到的一大串相似3628164...882e1e0的是commit id(版本號)。
每次咱們提交一個版本,git就自動把他們串成一個時間線
回到某一個版本
首先git知道當前是哪個版本,在git中用HEAD表示當前版本,上一個版本就是HEAD^,上上個版本就是HEAD^^,固然往上100個版本寫100個^比較容易數不過來,因此寫成HEAD~100。
git reset --hard HEAD^
若是想再從新恢復以前的版本,能夠指定commit的id git log --pretty=oneline能夠看到,
git reset --hard 3628164
ID那麼長,不須要寫全的,git會自動去找。
Git的版本回退速度很是快,由於Git在內部有個指向當前版本的HEAD指針,當你回退版本的時候,Git僅僅是把HEAD從指向append GPL
注意,咱們從這兩節中能夠了解到:
HEAD指向的版本就是當前版本,所以,Git容許咱們在版本的歷史之間穿梭,使用命令git reset --hard commit_id。
穿梭前,用git log能夠查看提交歷史,以便肯定要回退到哪一個版本。
要重返將來,用git reflog查看命令歷史,以便肯定要回到將來的哪一個版本。
下面說下git的基本概念
工做區:這個簡單,其實就是你電腦上的那個目錄
版本庫:工做區終有一個.git的文件,這個不屬於工做去的,而是git的版本庫
暫存區:stage或index,一半存在.git目錄下的index文件中,因此咱們把暫存區也叫作索引index
git的版本庫中有不少東西,其中最重要的稱爲stage,也叫index,暫存區,還有git爲咱們自動建立的第一個分支,master,以及指向第一個分支的指針HEAD。
咱們往git版本庫中添加文件的時候一般分爲兩步
第一步:git add ,其實是把文件添加到暫存區
第二步:git commit 其實是把stage中全部的文件提交到當前的分支上。
由於咱們建立版本庫的時候,git會幫咱們建立一個惟一的分支,因此如今咱們提交到的分支就是git幫咱們建立的master分支上。
固然,咱們能夠這麼理解:須要提交的文件統統的放在stage暫存區中,而後一併提交到分支上。並且一提交後暫存區就沒有任何內容了,而commit的內容也是從工做去中add到的stage中的內容
撤銷修改
git checkout -- file能夠丟棄工做區的修改
git checkout -- readme.txt的意思就是把其在工做去的修改所有撤銷掉
這裏有兩種狀況:
一種是readme.txt自修改後尚未被放到暫存區,如今,撤銷修改就回到和版本庫如出一轍的狀態;
一種是readme.txt已經添加到暫存區後,又做了修改,如今,撤銷修改就回到添加到暫存區後的狀態。
總之,就是讓這個文件回到最近一次git commit或git add時的狀態
刪除文件
在git中刪除其實也是一種對文件的修改
通常狀況下,你一般直接在文件管理器中把沒用的文件刪了,或者用rm命令刪了
rm readme.txt
這個時候git知道你把文件給刪了,由於工做區和版本庫不一致了,用git status會告訴你哪些文件被刪除了
因此如今你有兩條路能夠選擇:
一、肯定刪除這些東西:git rm readme.txt
二、剛剛刪除錯了,須要恢復以前的工做區內容,git checkout -- readme.txt
命令git rm用於刪除一個文件。若是一個文件已經被提交到版本庫,那麼你永遠不用擔憂誤刪,可是要當心,你只能恢復文件到最新版本,你會丟失最近一次提交後你修改的內容。
下面說下git的遠程倉庫,其實所謂的遠程倉庫就是借用Github提供的git倉庫託管服務
關於在Github上創建遠程倉庫這裏就很少說了,百度也都是有不少的,並且通常咱們的項目也是創建好的
簡單介紹下把本地倉庫的東東推送到遠程倉庫的作法吧
本地庫的全部內容推送到遠程庫上
git push -u origin master
把本地庫的內容推送到遠程,用git push命令,其實是把當前分支master推送到遠程
因爲遠程庫是空的,咱們第一次推送master分支時,加上了-u參數,Git不但會把本地的master分支內容推送的遠程新的master分支,還會把本地的master分支和遠程的master分支關聯起來,在之後的推送或者拉取時就能夠簡化命令。
而後用命令git push origin master就能夠了
注意:要關聯一個遠程庫,使用命令git remote add origin git@server-name:path/repo-name.git;關聯後,使用命令git push -u origin master第一次推送master分支的全部內容;此後,每次本地提交後,只要有必要,就可使用命令git push origin master推送最新修改
當你第一次使用Git的clone或者push命令鏈接GitHub時,會獲得一個警告:
The authenticity of host 'github.com (xx.xx.xx.xx)' can't be established.
RSA key fingerprint is xx.xx.xx.xx.xx.
Are you sure you want to continue connecting (yes/no)?
這是由於Git使用SSH鏈接,而SSH鏈接在第一次驗證GitHub服務器的Key時,須要你確認GitHub的Key的指紋信息是否真的來自GitHub的服務器,輸入yes回車便可。
Git會輸出一個警告,告訴你已經把GitHub的Key添加到本機的一個信任列表裏了:
Warning: Permanently added 'github.com' (RSA) to the list of known hosts.
這個警告只會出現一次,後面的操做就不會有任何警告了。
下面說下git的clone,這是咱們如今作項目的第一步,都是從clone下來項目經理已經創建好的項目框架
可是若是你是創建遠程庫的人,從遠程庫克隆,就須要咱們先建立遠程庫,在github建立一個新的gitskills倉庫,咱們勾選Initialize this repository with a README,這樣GitHub會自動爲咱們建立一個README.md文件。建立完畢後,能夠看到README.md文件
真正的clone很簡單,一個命令
git clone http://cloneurl
注意:要克隆一個倉庫,首先必須知道倉庫的地址,而後使用git clone命令克隆。Git支持多種協議,包括https,但經過ssh支持的原生git協議速度最快
下面說下分支的管理,這個多是咱們用的最多的地方了
看到這裏,咱們已經知道,咱們的每一次提交,git都會把它串成一條時間線,這條時間線就是一條分支。目前來講,咱們只說道一個分支,master。
HEADE嚴格來講不是指向提交,而是指向master,master纔是指向提交的,因此HEAD指向的應該是當前的分支。
一開始的時候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能肯定當前分支,以及當前分支的提交點
每次提交,master分支都會向前移動一步,這樣,隨着你不斷提交,master分支的線也愈來愈長,當咱們建立新的分支,例如dev時,Git新建了一個指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當前分支在dev上,接着上面的說法,如今對工做區的修改和提交就是針對dev分支了,好比新提交一次後,dev指針往前移動一步,而master指針不變。假如咱們在dev上的工做完成了,就能夠把dev合併到master上。Git怎麼合併呢?最簡單的方法,就是直接把master指向dev的當前提交,就完成了合併,因此Git合併分支也很快!就改改指針,工做區內容也不變!和新建分支是同樣同樣的。
合併完分支後,甚至能夠刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉後,咱們就剩下了一條master分支
上面說的是指令和git分支管理的原理,下面說下具體的實現和指令:
首先咱們建立一個分支,而後切換到這個分支上:
git branch yangleiDev
git checkout yangleiDev
固然這兩句指令也能夠直接寫成一句:git checkout -b yangleiDev
而後咱們能夠用git branch來查看目前全部的分支,而且能夠看到你如今所在的分支上。
而後咱們能夠在本身的分支上add,commit。。。各類操做
而後咱們切回master分支,查看下內容,我擦!你會發現剛剛的提交什麼的都不在了。。。
莫慌!由於你剛剛提交的是在本身的分支上,yangleiDev,而你如今在的是master分支上,因此這個時候咱們須要作的就是把master指針移到本身新建的分支上,簡單的說,就是分支的合併:git merge yangleiDev
git merge命令用於合併指定分支到當前分支
合併完成後就能夠看到master分支上有了以前咱們提交在yangleiDev分支上的東西了,這個時候就能夠刪了yangleiDev分支了:git branch -d yangleiDev
由於建立、合併和刪除分支很是快,因此Git鼓勵你使用分支完成某個任務,合併後再刪掉分支,這和直接在master分支上工做效果是同樣的,但過程更安全。
命令比較多昂,這裏簡單總結下:
查看分支:git branch
建立分支:git branch <name>
切換分支:git checkout <name>
建立+切換分支:git checkout -b <name>
合併某分支到當前分支:git merge <name>
刪除分支:git branch -d <name>
其實這麼來講,通常操做就搞定了。。。可是!!!通常來講,因爲是多人合做,因此這裏咱們通常都會遇到代碼衝突
所謂的代碼衝突就是不一樣的分支上有了新的提交,致使git沒法執行快速合併
用帶參數的git log也能夠看到分支的合併狀況:
git log --graph --pretty=oneline --abbrev-commit
用git log --graph命令能夠看到分支合併圖。z
若是你有一個bug任務,你想建立一個分支issue-101來修復它,可是你當前正在dev上進行的工做尚未完成而不能提交,bug須要如今修復,因此如今你須要暫停dev上工做,Git提供了一個stash功能,能夠把當前工做現場「儲藏」起來,等之後恢復現場後繼續工做:$ git stash。
Git把stash內容存在某個地方了,可是須要恢復一下,有兩個辦法:
一是用git stash apply恢復,可是恢復後,stash內容並不刪除,你須要用git stash drop來刪除;
另外一種方式是用git stash pop,恢復的同時把stash內容也刪了;
對了,這裏的分支有時候有個地方仍是須要注意下的:
開發一個新feature,最好新建一個分支;若是要丟棄一個沒有被合併過的分支,能夠經過git branch -D <name>強行刪除
下面介紹下關於分支的推送
當你從遠程倉庫克隆時,實際上Git自動把本地的master分支和遠程的master分支對應起來了,而且遠程倉庫的默認名稱是origin
這裏說道的遠程庫,若是須要查看遠程庫的信息,能夠用git remote 活着用 git remote -v 查看更詳細的信息。
推送分支
就是把該分支上的全部本地提交推送到遠程庫。推送時,要指定本地分支,這樣,Git就會把該分支推送到遠程庫對應的遠程分支上
git push origin yourBranchName
master分支是主分支,所以要時刻與遠程同步;
dev分支是開發分支,團隊全部成員都須要在上面工做,因此也須要與遠程同步;
bug分支只用於在本地修復bug,就不必推到遠程了,除非老闆要看看你每週到底修復了幾個bug;
feature分支是否推到遠程,取決於你是否和你的小夥伴合做在上面開發。
在咱們如今的開發中,因爲都是多人合做,因此一半的工做模式應該是這樣子的:
首先,能夠試圖用git push origin branch-name推送本身的修改;
若是推送失敗,則由於遠程分支比你的本地更新,須要先用git pull試圖合併;
若是合併有衝突,則解決衝突,並在本地提交;
沒有衝突或者解決掉衝突後,再用git push origin branch-name推送就能成功!
若是git pull提示「no tracking information」,則說明本地分支和遠程分支的連接關係沒有建立,用命令git branch --set-upstream branch-name origin/branch-name
其實說到這裏就基本知足咱們的工做須要了。
雖然git只是一個工具,可是卻實實在在的寫了一本書,關於git的一些高級的應用,其實我也不是很清楚,後續在研究補充,相似於git的標籤,自定義git等等等操做。
好吧!先記錄到這裏吧~