1、Git基本工做流程git
git init緩存
git clone服務器
git倉庫分爲兩種狀況:app
第一種是在現有項目或目錄下導入全部文件到 Git 中; 第二種是從一個服務器克隆一個現有的 Git 倉庫學習
git init –bare git 建立一個裸倉庫spa
講述完了git的區域,接下來說解下git文件的狀態,其實git的狀態無外乎兩種:已跟蹤和未跟蹤,已跟蹤的文件說明的是被歸入版本控制的文件,在上一次快照中有它們的記錄,在工做一段時間後,它們的狀態可能處於未修改,已修改或已放入暫存區。 工做目錄中除已跟蹤文件之外的全部其它文件都屬於未跟蹤文件,它們既不存在於上次快照的記錄中,也沒有放入暫存區。 初次克隆某個倉庫的時候,工做目錄中的全部文件都屬於已跟蹤文件,並處於未修改狀態。3d
講解下文件變化週期,好比咱們在項目中添加了一個文件a,這時候文件a處於的狀態則是Untracked未跟蹤狀態,當咱們git add的時候這時候就會將文件放到暫存區中這時候狀態變爲Stage,當咱們commit這個暫存區的文件後這個文件就變成未修改狀態,由於沒有進行修改過了相對於版本控制中的文件,當咱們修改了a文件後這時候從unmodified變成modified(修改狀態),這是再git add的時候就會將修改的文件變成stage,放入暫存區用於等待commit。版本控制
往暫存區裏面添加東西使用以下git指令指針
git addcode
從暫存區提交到歷史記錄使用以下指令
git commit
查看工做區和暫存區之間的區別,來確保提交時咱們所須要的呢?
git status
從暫存區裏面刪除內容
git rm
工做區內重命名文件或者移動文件,而後再把他們添加到暫存區
git mv
確保工做區內裏面不須要的文件不被添加進去添加到暫存區和歷史。
.gitignore
新建一個倉庫
git init git_init
cd git_init
touch a //新建a文件
git add a //將a添加到暫存區
git status會顯示咱們要提交的內容a文件,這時候a兩個文件都是Changes to be committed也就是待commit的狀態。
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: a
git commit -m 「initial commit」//提交a文件到版本控制中。
touch b新建文件b
git add b //將b放入暫存區中
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: b
編輯一下a文件,這時候在調用git status
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: a new file: bb
這時候a文件是出於修改狀態,那麼若是咱們在進行修改a文件時候,在調用下git status會發生什麼奇怪的事呢?let’s go。
$ git status On branch master Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: a new file: bb Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) modified: a
這時候咱們會發現兩個modified a,這是爲何呢?可是兩個文件分別存在暫存區和非暫存區,實際上暫存區內只保存了git add的版本,而最新修改的一份沒有提交到暫存區內還在工做區域中,因此咱們會看到兩個,若是這時候調用git commit的話就只會講已經在暫存區的文件存入到版本控制中,而最新修改的那一次記錄沒有被提交。
固然這裏還提供了跳過暫存區的方法就是git commit –a –m「註釋內容」能夠直接跳過暫存區直接提交到記錄裏面去。
將a移除整個項目
git rm a
清楚緩存中的內容,也就是已經暫存的文件
git rm a –cached
給文件重命名將a文件名換成c
git mv a c
假設工做區裏面有這麼一些文件以下圖所示:
在第一次add都尚未進行的時候,暫存區尚未被建立出來,當咱們add的時候會建立一個暫存區出來(文件分開add產生兩個數據對象),以下圖所示:
.git目錄下面多了一個index的文件,那麼這個index文件就是咱們所說的暫存區的文件,那麼每一條索引都是hash值表示以及它對應的文件名。每一個索引還包含了他的文件模式權限還有status number來表示他的合併狀態、時間戳等。每個索引都是跟對象庫的文件是對應的。好比說file.txt這裏對應的是標號1,那麼file2.txt對應的就是標號2(上圖所示標號),這個index裏面除了維護了索引以外還維護了提早計算好的tree對象的內容,也就是咱們的頂層的目錄tree以及folder的tree對象內容,當咱們提交的時候他能夠迅速的根據咱們已經計算好的內容生成一個tree對象,而後添加到歷史記錄裏面。
當咱們修改了file2.txt的時候,這時候git add到暫存區時,發現對象庫裏面新創了一個對象,那麼暫存區的這條索引就被指向新對象的索引替換掉。這時候git暫存區又重新計算了下頂層目錄tree對象的一個內容。當咱們提交的時候咱們直接使用已經計算好的內容建立好一個新的tree對象,生成一個commit對象將master分支上面的HEAD指針指向當前commit對象上去。以下圖所示:
這裏的標號8指向的就是新生成的commit對象。
1.建立分支git branch
2.給固定的commit作標記 git tag
3.分支之間進行切換 git checkout
4.切換分支以前保存本地修改 git stash
5.合併分支 git merge
例子建立一個分支名字叫test並切換到當前的分支上去。
這時候分支的名稱再也不是master而是改變成爲test分支。編輯下a文件用test分支進行提交
切換到master分支上面咱們看一下a的內容
並無test分支在a中添加的內容這時候咱們切換分支時會使用咱們分支上最新的一個提交來還原咱們的暫存區和工做區內容,那麼可讓咱們在不一樣的分支之間獨立的作本身的工做。
git log –oneline –decorate –graph –all
咱們能夠看到提交的記錄或提交這些提交的引用
給第一個提交加一個名稱tag
git tag 「v0」 f6699b3
在查看下git log –oneline –decorate –graph –all
多了一個tag:v0使用git show v0查看下內容,這是打的tag是一個輕量級的只是一個固定的引用。
而使用git tag –a的方式進行添加時會是一個tag對象,他有tag的屬性,包括提交人時間等信息。
Tag指向了一個提交commit
Tag也可使用checkout進行操做
可是它當前的沒有指向一個分支而是指向了一個commit,這時候就會出現一個問題就是咱們切換分支的時候這一部份內容就有可能被遺棄掉,也就是說head引用直接指向了一個commit而不是一個分支名,checkout提供了針對當前commit新建一個分支的方法並切換到當前分支。
git checkout -b 「ttt_v0」
接下來切換master分支
這時候會用的git stash進行保存工做區,由於咱們切換checkout的時候會覆蓋掉當前的內容因此咱們先將其保存起來。若是想要保存暫存區就可使用-a來保存。
Git stash save -a 「stash1」
這時候咱們來查看下緩存區狀態git status的時候是很乾淨的以下圖:
下面咱們切換到master分之下,在切換會ttt_v0下時咱們要還原stash裏面的內容
會有一個stash的緩存內容存在,下面咱們來恢復stash裏面的內容,並將緩存區內容還原。
git stash pop –index stash@{0} 這裏的標記紅色的表示stash裏面的第0個stash
咱們會發現以前修改的a文件已經在暫存區內貯備提交了
使用git stash apply –index stash@{0}這種方式時git stash list裏面的內容是不會被清理掉的這裏–index是恢復暫存區內容
使用git stash drop stash@{0}清除掉,若是不加stash@{0}引用的話他默認會清楚stash棧最上面的一個。
清楚多個stash的時候使用git stash clear
1.git show
2.git log
3.git diff
輸入git log –oneline –decorate –graph –all查看完整的歷史示意圖。
git log -p經常使用的選項是 -p,用來顯示每次提交的內容差別, 你也能夠加上 -2 來僅顯示最近兩次提交:
咱們能夠根據查看git show f6699b3的信息
最新的一次提交能夠用git show master 或者git show HEAD,也可使用git show master^表示master分支的第一次提交master^2表示第二次提交
一般咱們會用git diff來回答兩個問題:第一個就是當前作了什麼尚未提交暫存區?第二個問題就是當前那些文件已經暫存了等待提交?
git diff 這個命令是查看當前工做區與暫存區快照的差別,也就是那些尚未暫存起來。
圖中顯示的是暫存區和工做區的區別在於a文件被修改了添加了next edit file。請注意,git diff 自己只顯示還沒有暫存的改動,而不是自上次提交以來所作的全部改動。 因此有時候你一會兒暫存了全部更新過的文件後,運行 git diff 後卻什麼也沒有,就是這個緣由。
回顧:
所謂的分支就是一個commit記錄的引用以下圖所示:
在這些分支上工做會產生各自的歷史記錄(commit記錄)所謂的分支切換就是指的Head指針的切換以及暫存區和工做區的一個還原,好比說咱們如今當前Head指向的位置處再建兩個分支以後他們所指向的commit都是同一個以下圖所示:
分支切換後以下圖所示:
而tag指向了一個固定的commit記錄,以下圖所示:
分爲兩種一種是輕量級的一種是標籤對象,主要區別就是輕量級的tag只是一個固定的鏈接,可是標籤對象就是建立標籤的時候會產生一個標籤對象,這個標籤對象存儲在.git/object目錄裏面,tag對象裏面包括對數據對象的指向,以及建立時間數據對象類型和建立人等信息。
舉個例子來講明一下分支切換以及合併:
開始的狀態是這樣的,咱們提交了三次commit後的示意圖以下:
當咱們使用了git branch test的時候,將會在當前位置處新建一個分支,分支的名稱叫test,可是分支並無切換依然是master分支(Head的指向)以下圖所示:
咱們在master分支上面工做會產生master分支上面的commit記錄以下圖所示:
這個時候咱們是用git checkout test的時候HEAD指針就會指向test,而且還原暫存區和工做區內容。以下圖所示:
繼續在test分支上面進行工做,會產生test對應分支上面的commit記錄
咱們來講一下合併,合併分爲兩種一種是fast-farword merge也就是說test所指向的commit記錄他實際上是master所指向的commit所衍生出來的以下圖所示:
藍色部分是master分支,紅色部分是master分支所衍生出來的分支。這時候咱們在master分支上面進行合併git merge test不會產生新的commit記錄出來,master分支指向test分支所指向的commit記錄上去,而後把工做區和暫存區還原成了test的暫存區和工做區內容。以下圖所示:
另一種就是non-fast-farword merge也就是咱們的三方合併。
咱們能夠看到master指向的commit和test只想的commit有一個共同的父節點就是70e4d8這個節點。Master指向的commit和test指向的commit並無一個衍生的關係,這時候咱們在master分支上面git merge test,會生成一個新的commit來承載兩個分支的歷史內容
這篇文章非一天寫完的我也是在學習的過程當中總結,以及參考大嬸們寫的文章加本身的理解寫成的,若是這裏有些錯的或者有雷同的請各位大神指點一二。小丁謝過,寫一篇文章確實不容易,能支持的就支持下不能支持的就當沒看過這篇文章就行了。寫篇文章容易麼?寫完了還被移除首頁,已經發了兩篇了第一篇只是開始被移除了首頁~看看這個給不給我移除首頁吧~