git初基本用法總結
來自: http://my.oschina.net/u/2491705/blog/618123
git是一個分布式版本控制系統
所謂的分布式管理控制系統就是不存在中央服務器,每一個電腦都有一個完整的版本庫,不需要聯網就可以工作。
分布式版本控制系統通常也有一臺充當“中央服務器”的電腦,但這個服務器的作用僅僅是作為方便大家的修改。沒有他,大家一樣可以干活,只不過方便了交換而已
下面說下git的版本庫,也可以說是git的倉庫,英文repository,其實就是一個可以被git管理起來的目錄而已。每一個文件的修改,刪除git都可以追蹤,以便git可以還原每一個歷史的文件
創建一個版本庫非常的簡單,選擇一個合適的地方
mkdir yangleiPro
cd yangleiPro
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會告訴你哪些文件被刪除了
所以現在你有兩條路可以選擇:
1、確定刪除這些東西:git rm readme.txt
2、剛剛刪除錯了,需要恢復之前的工作區內容,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等等等操作。
好吧!先記錄到這里吧~