Git 本地倉庫(Repository)詳解

大綱:

一、前言

二、概述

三、在Windows上安裝Git

四、創建本地倉庫

五、本地倉庫管理詳解

六、總結

注,測試機 CentOS 5.5 x86_64,Git 服務器版本:git version 1.8.2.1,客戶端版本:git version 1.9.2.msysgit.0。所有軟件請到這裏下載:http://msysgit.github.io/


一、前言

本來呢,其實呢。我以爲Git也就幾個命令,沒什麼難的。於是就到網上找了些文章看看,發現這些文章難得不知道該說什麼好。不是簡單的寫幾個命令,就是直接複製粘貼手冊中的內容,沒有一點連續感,不知道從何學起。總之呢,我想寫一個什麼都不會的朋友能看懂的、初學朋友能看懂的、運維能看懂的、開發也能看懂的,看完就能幹活的教程。


二、概述

這個教程呢,有幾個部分先和大家說一下:

  • Git 本地倉庫詳解

  • Git 遠程倉庫詳解

  • Git 分支管理詳解

  • Git 標籤管理詳解

  • GitHub 使用詳解

  • Git 全局配置詳解

  • Git與GitHub總結

注,本教程呢,只能讓你會使用Git幹活,至於你呢想深入瞭解Git,或者想成爲Git領域的專家喲,我想說這只是個起步。還有我想說Git只是個工具嘛,目的只是爲了提高我們的工作效率,我們沒有必要去,也不需要學浪費時間在研究工具上,只要我們會用就好,嘿嘿!也許有博友不同意啊,只是個人見解啊,勿噴啊!


三、在Windows上安裝Git

注,大家請到這裏下載:http://msysgit.github.io/。具體的安裝過程我就不演示了,直接雙擊安裝即可。安裝完成後桌面上會生成一個Git bash圖標,雙擊打開會彈出一個類似命令行窗口的東西,大家請看下圖:

git bash

好了,到這裏我們的Git就安裝完成了,嘿嘿!下面我們來進行基本配置:

git config

$ git config --global user.name "Your Name"
$ git config --global user.email “[email protected]

注,我這裏根據我的情況設置如下(如上圖):

$ git config --global user.name "chenmingqian"
$ git config --global user.email “[email protected]

我們在上一篇文章說過Git是分佈式控制系統,所以,每個客戶端都必須設置:你的名字和郵箱。這樣才容易區分是哪個用戶提交的Git版本,嘿嘿!大家可以看到git config 後面接的是--global參數,這表示你的機器上所有的Git倉庫都會使用這個配置,但你也可以對不同的倉庫指定不同的用戶名和郵箱。這個我們會在後面的文章中講解,這裏不作說明,嘿嘿!有興趣的博友可以先提前google一下。


四、創建本地倉庫

1.版本庫又稱倉庫

版本庫或者是倉庫,英文名Repository,其實啊說白了就是一個目錄而且,這個目錄中的所以文件都被git管理而且,不管你做什麼操作都會被記錄,包括:增加、刪除、修改文件等,都會被記錄下來,以便後來跟蹤與修改相關記錄,甚至被還原。好了,下面我們就在我們客戶端(我這裏演示的是Windows客戶端,其它客戶端操作一樣)中創建一個版本庫:

mkdir

大家可以看到我們在/c/Users/root/下創建一個空目錄pro即可project簡寫。還有一點需要說明的在Windows系統中目錄名稱不要使用中文,不然會出現神馬問題,我不負責。嘿嘿^_^……


2.目錄變成倉庫

git init

執行git init命令,即可Initialized empty Git repository in c:/Users/root/pro/.git/,初始化一個空目錄,路徑爲c:/Users/root/pro/.git/。大家可以看到pro目錄中生成了一個隱藏目錄 .git目錄,進入目錄中大家可以看到裏面有很多文件,沒事不要修改或者改動裏機的文件,這裏面的文件就是控制和管理版本庫的,嘿嘿。至於裏文件的具體作用我們會在後面的文章中講解,想提前瞭解的朋友可以先google一下。


3.向本地倉庫中增加文件

下面我們向版本庫中增加文件,需要注意的是,在版本庫中只能跟蹤和管理文本文件,比txt文件、js文件、php文件、java文件等,所有的程序代碼都可以的。但是像視頻、圖片等這些二進制文件,雖然能由git管理,但是隻能記錄大小,無法跟蹤具體修改了什麼,嘿嘿。大家懂了吧。好了,下面我們來增加一個readme.txt文件,其內容如下:

This is git test.
Git is a version of the best controller.
……

readme

注意,新建的readme.txt文件,一定要在pro目錄,不然git無法管理這裏文件哦,嘿嘿!下面我們把個文件放到版本庫中。

git add

1).git status 命令

我們先用git status命令查看一下,如上圖。大家可以看到git記錄我們新增加一個文件readme.txt,並且提示這個文件還沒有被提交。下面我們用git add命令提交一下。

2).git add 命令

git add 命令是告訴git,我們要把什麼文件提交到倉庫中去,大家可以看我們執行git add readme.txt命令後,沒有任何提示。那就說明我們提交完成了。下面我們通過git commit命令,將readme.txt文件提交到版本庫中。

3).git commit 命令

$ git commit -m "add readme.txt"
[master (root-commit) e5d662b] add readme. 
1 file changed, 3 insertions(+) 
create mode 100644 readme.txt

大家可以看到我們用git commit命令提交readme.txt文件,給出的提示是  1 file changed, 3 insertions(+),一個文件改變,插入了三行內容。與我們上面增加三行內容一致。嘿嘿!下面我們簡單的說明一下git commit命令,其中的參數-m後面輸入的是本次提交的版本說明,可以輸入任意內容,但需要說明的是,最好寫有意義的說明,便於以後查看。

4).git status 命令

最後我們再用git status命令查看一下版本庫的狀態,提示沒有任何內容需要提交說明我們向版本庫增加文件成功了,嘿嘿。


4.總結

1).初始化一個Git倉庫,使用git init命令

2).添加文件到本地Git倉中,分爲兩步:

  • 使用git add命令,注意,可以多次使用,添加多個文件

  • 使用git commit命令,完成添加。

爲什麼Git添加文件需要兩步呢?一步add,一步commit。嘿嘿,因爲commit命令可以一次提交多個文件,所以你可以多次使用add命令呢。下面是個案例:(我們也經常這麼用)

$ git add file1.php
$ git add file2.php
$ git add file3.php
$ git commit –m “add file1.php file2.php file3.php”

好了,到這裏我們創建本地git倉庫和向倉庫中增加文件的內容就講解完成了,下面我們來詳細講解一下Git本地倉庫的管理,內容有點多請大家慢慢看,嘿嘿!


五、本地倉庫管理詳解

1.查看工作區的狀態(git status)

在上面的文章中我們成功的增加了一個readme.txt文件,並用git status命令查看了狀態,在這節中我們就詳細的說一下git status命令。我們修改一下readme.txt中的內容如下:

This is git test. 
Git is a version of the best conntroller.

我們刪除了最後一行,現在我們再用git status命令查看一下狀態:

git status

從上圖中我們可以看到,我們用git status命令查看一下,我們得知readme.txt文件被修改過了,但是還沒有提交這個修改。但是有博友會問了,git提示我們這個readme.txt這個文件被修改了,但我們想看看具體修改了什麼內容怎麼辦呢?這個時候我們需要git diff命令出場了,如下圖:

git diff

大家可以從上面圖片中可以看到,我們刪除了最後一行的……省略號。嘿嘿,用紅顏色標出來的。好了知道修改了什麼,下面我們就提交修改吧,提交修改和提交新文件一致,也是兩步,先add,再commit。如下圖:

git add readme

大家可以看到我們執行git add命令,同樣沒人輸出。但是,我們可以用git status命令查看一下。下面我們用git commit命令提交到本地版本庫,如下圖:

git commit read

同樣的我們使用git status命令查看一下狀得知我們修改的readme.txt文件已提交。好了,到這裏我們的git status命令就講解完成了,同時我們也講解一個git diff命令,可以查看我們修改了哪些內容。下面我們來講解一下版本回滾。


2.版本回滾

在上面一個章節中我們演示修改文件並提交文件,再用git status命令查看狀態,下我們再修幾個版本並提交:

git a free

git a dis

好了,就這樣我們不斷的修改並提交到本地的版本庫中。一會你測試的時候發現前修改的版本有問題想回滾到前面的版本,或者你誤刪除了一些文件,想回到上一個commit中去,然後繼續工作。我們應該怎麼辦呢?在Git版本控制中,我們所有的操作都是有歷史記錄的,我們用git log命令查看一下(如下圖):

git log

大家可以看到,用git log命令可以查看最近幾次提交的版本。如果你發現內容太多,可以用這個命令查看(如下圖):

git log oneline

上面你看到的一大串數字,其實是commit id(即,版本號),和svn不一樣,Git的commit id不是1,2,3……這樣的遞數字,而是一相SHA1計算出來的哈希數,用16進製表示。有博友會問了,爲什麼Git的commit id不是1,2,3……這樣的遞增數字,而是用SHA1算出來的哈希數來表示呢?大家應該知道Git是分佈式管理系統,我們會有多個人同時開發,如果大家都用1,2,3……這樣的遞增數字,作爲版本號,那不就衝突了嘛,嘿嘿。好了,下面我們來說版本回滾,準備把readme.txt回滾到“add readme.txt“的那個版本,我們應該怎麼做?


我們先來說一下,Git的當前是在哪個版本,在Git中我們用HEAD表示當前版本,也就是我們最新提交的”749f84ccb87……ff2q6ad“,上一個版本就應該這麼表示”HEAD^“,再上一個版本就這樣表示”HEAD^^“,當然如果有幾十個版本或者1000個版本,我們還要寫1000個^,這是不可能的,所以喲。我們寫成這樣HEAD~1000。好了,現在我們就用git reset命令,將我們的版本回退到”add readme.txt“中吧,如下圖:

git reset add

大家可以看到,我們回到了”add readme.txt“版本中了,下面我們再來查看一下git log,如下圖:

git log2

有個問題哦,有沒有發現我們最後提交的那個版本不見了,如上圖。現在只有三個版本了,這說明什麼問題呢?舉個簡單的例子說明一下,就好比你從現在回到了18世界,想再回到21世界已經回不去了,那應該怎麼辦呢?只要我們找到最新版本的commit id,我這裏新版本的commit id是”749f84ccb87……ff2q6ad“,於是就可以回到未來的某個版本,就好比我們知道現在的時間,就能回到現在。下面我們來演示一下(如下圖):

git reset 2

好了,大家可以看到我們又回到最新版本,嘿嘿。現在你回退到某個版本中,已經關掉了Git bash。但是呢,你又後悔了,想恢復到新版本中,但是呢?你又找不到commit id了,那又該怎麼辦呢?在Git中,我們當時用$ git reset --hard HEAD^^^,回退到“add readme.txt”版本時,再想恢復到最新版的 “add a line distributed” 中,必須有commit id才行,這時我們已經關閉了Git bash。在Git中提供了一個git reflog命令,是用來記錄你每一次執行的命令,下面我們來演示一下(如下圖):

git reflog

嘿嘿,現在我們又可以回去最新版了。好了,到這裏我們的回滾版本就講解完成了。下面我們來說一下,工作區、提交區/暫存區(stage/index)、版本庫。


3.工作區、提交區/暫存區(stage/index)、版本庫

work

其實呢,工作區、提交區/暫存區(stage/index)、版本庫的概念問題,從上圖中就能看的很清楚,本來不想細講的,但想想還是說一下。Git與其他版本版本控制器其中之一的不同之處就在於有提交區/暫存區(stage/index)的概念。下面我們先來看一下工作區:

workdir

gitworkdir

其實呢,工作區就是我們開發目錄了,在電腦中是可能看到的,比如我們這裏的pro目錄,就是一個工作區。大家再來看一下,下面的兩張圖:

git .git

git .git2

大家可以看到,工作區中有個隱藏的目錄“.git”,這個不是工作區哦,這個就是Git的版本庫。大家再看下面兩張圖:

git index1

git index2

大家可以看到,在“.git”目錄中有很多文件,其中一個重要的文件index,就是我們說的提交區/暫存區(stage/index)。暫存區(stage, index)是 Git 最重要的概念之一,理解了這個概念很多 Git 命令就不再那麼神祕了。對於 Git 暫存區(stage) ,不知道您的感想如何?

  • “被眼花繚亂的 Git 魔法徹底搞糊塗了?”

  • “Git 爲什麼這麼折磨人,修改的文件直接提交不就完了麼?”

  • “看不出 Git 這麼做有什麼好處?”


我認爲 Git 暫存區(stage或稱爲 index)的設計是 Git 最成功的設計之一,也是最難理解的一個設計。 在版本庫(.git)目錄下,有一個 index 文件,相信大家在上圖中已經看到了。下面我們好好說一說他們之間關係,同樣的我們先看一張圖:

git-stage

在上圖中,我們可以看到部分 Git 命令是如何影響工作區和暫存區(stage/index)的。

  • 圖中左側爲工作區,右側爲版本庫。在版本庫中標記爲 "index" 的區域是暫存區(stage/index),標記爲 "master" 的是 master 分支所代表的目錄樹(關於分支問題在下面的文章中會詳解)。

  • 圖中我們可以看出此時 "HEAD" 實際是指向 master 分支的一個“指針”。所以,圖示的命令中出現 HEAD 的地方可以用 master 來替換(HEAD的概念我們在後面的文章中也會詳解)。

  • 圖中的 objects 標識的區域爲 Git 的對象庫,實際位於 ".git/objects" 目錄下,我們會在後面的文章中將重點介紹,嘿嘿!。

  • 當對工作區新增或修改的文件執行 "git add" 命令時,暫存區的目錄樹被更新,同時工作區新增或修改的文件內容被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區的文件索引中。(如上圖)

  • 當執行提交操作 "git commit" 時,暫存區的目錄樹寫到版本庫的對象庫(objects)中,master 分支會做相應的更新。即 master 指向的目錄樹就是提交時暫存區的目錄樹。(如上圖)

  • 當執行 "git reset HEAD" 命令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。 當執行 "git rm --cached <file>" 命令時,會直接從暫存區刪除文件,工作區則不做出改變。

  • 當執行 "git checkout ." 或者 "git checkout -- <file>" 命令時,會用暫存區全部或指定的文件替換工作區的文件。這個操作很危險,會清除工作區中未添加到暫存區的改動。

  • 當執行 "git checkout HEAD ." 或者 "git checkout HEAD <file>" 命令時,會用 HEAD 指向的 master 分支中的全部或者部分文件替換暫存區和以及工作區中的文件。這個命令也是極具危險性的,因爲不但會清除工作區中未提交的改動,也會清除暫存區中未提交的改動。

好了,到這裏我們的工作區、暫存區、版本庫就講解到這裏了,由於本人能力有限有什麼不正確的地方歡迎大家指出。好了,下面我們繼續講解……


4.修改管理

1).關於修改

在上面的文章中我們講解了工作區、暫存區和版本庫的概念,有了這些概念有理解。下面我們說一說爲什麼Git比其它版本控制軟件優秀?嘿嘿,是因爲Git跟蹤管理的是我們每一次的修改(或操作),而不是文件。比如你新增了一行,這就是一個修改,刪除了一行,也是一個修改,更改了某些字符,也是一個修改,刪了一些又加了一些,也是一個修改,甚至創建一個新文件,也算一個修改。下面我們來簡單演示一下:我們先查看一下readme.txt文件,如下圖:

modify1

下面我們修改一下readme.txt內容,增加一行:Git rest 1.如下圖:

modify2

下面我們用 git add 命令提交一下,如下圖:

modify3

下面我們再修改一下readme.txt文件,如下圖:

modify4

我們又增加一行 Git test 2. 如下圖:

modify5

modify6

下面我們提交一下,如下圖:

modify7

下面我們再查看一下狀態,如下圖:

modify8

大家可以看到我們第二次沒有被提交,怎麼會這樣呢?細心的博友可以看到我們第二次修改後,直接執行 git commit了。沒有執行 git add 命令,前面我們說了,當你用“git add”命令後,在工作區的第一次修改被放入暫存區,準備提交。但是,在工作區的第二次修改並沒有放入暫存區,所以,“git commit”只負責把暫存區的修改提交了,也就是第一次的修改被提交了,第二次的修改不會被提交。下面我們用 git diff 命令查看一下工作區與版本庫裏面的區別:

modify9

大家可以從圖上看到,我們增加 Git test 2. 還沒有提交,嘿嘿!那麼第二次修改怎麼提交呢?其實我們再add再commit,就可以了。如下圖:

modify10

好了,現在,你又理解了Git是如何跟蹤修改的,每次修改,如果不add到暫存區,那就不會加入到commit中。那麼我們想取消修改的版本,又該怎麼取消呢?下面我們繼續……


2).取消(撤消)修改

下面我們來講解怎麼撤消修改,一般情況下我們是不會出錯的,但是項目比較緊,老是有人在催你(這個你懂的),突然出錯了,我們想取消修改那又怎麼辦呢?如下圖:

modify11

在你要提交之前,你發現在有錯誤了,應該是101。既然錯誤發現得很及時,就可以很容易地糾正它。你可以刪掉最後一行,手動把文件恢復到上一個版本的狀態。我信先用git status查看一下,如下圖:

modify12

如上圖,Git會告訴你有你個文件被修改,你有兩個選擇,一個用 git add 提交到暫存區,另一個是用git checkout可以丟棄工作區的修改。命令git checkout -- readme.txt意思就是,把readme.txt文件在工作區的修改全部撤銷,這裏有兩種情況:

  • 一種是readme.txt自修改後還沒有被放到暫存區,現在撤銷修改就回到和版本庫一模一樣的狀態;

  • 另一種是readme.txt已經添加到暫存區後,又作了修改,現在撤銷修改就回到添加到暫存區後的狀態。

總之,就是讓這個文件回到最近一次git commit或git add時的狀態。下面我們來演示一下,如下圖:

modify13

大家可以看一下 readme.txt 文件果然還原到上一個版本了,嘿嘿!大家注意哦,git checkout -- file命令中的“--”很重要,沒有“--”,就變成了“創建一個新分支”的命令,我們在後面的文章中將詳細講解分支管理。真是禍不單行啊,我們不但程序寫錯了,還 git add 到暫存區了,如下圖:

modify14

不管怎麼樣,我們先查看一下狀態吧,如下圖:

modify15

大家可以看到Git告訴我們,用 git reset HEAD file 可以把暫存區中的修改撤消掉,重新放回工作區,如下圖:

modify16

git reset命令既可以回退版本,也可以把工作區的某些文件替換爲版本庫中的文件。當我們用HEAD時,表示最新的版本。我們再用 git status 查看一下發現,現在的暫存區是乾淨的,工作區有修改。

那說明我們撤消成功,嘿嘿!下面我們再執行 git checkout命令撤消工作區修改,如下圖:

modify17

好了,到這裏我們終於撤消回來了,嘿嘿。現在,假設你不但改錯了東西,還從暫存區提交到了版本庫,怎麼辦呢?還記得版本回退一節嗎?可以回退到上一個版本。不過,這是有條件的,就是你還沒有把自己的本地版本庫推送到遠程。還記得Git是分佈式版本控制系統嗎?我們後面會講到遠程版本庫,一旦你把錯誤提交推送到遠程版本庫,你就真的慘了……大家小心就好,哈哈……好了,下面我們來總結一下:

  • 當你改亂了工作區某個文件的內容,想直接丟棄工作區的修改時,用命令git checkout -- file。

  • 當你不但改亂了工作區某個文件的內容,還添加到了暫存區時,想丟棄修改,分兩步,第一步用命令git reset HEAD file,就回到了第1步,第二步按第1步進行操作,就是執行一下git checkout -- file。

  • 已經提交了不合適的修改到版本庫時,想要撤銷本次提交,參考我們前面講解的版本回退,不過前提是沒有推送到遠程庫。嘿嘿,祝你回退成功。

好了,撤消管理我們已經講了很多了,下面我們來說一下文件刪除的問題,終於快通關了。嘿嘿……


5.文件刪除

刪除文件就比較簡單了,我們快速的過一下了,嘿嘿!下面我們新增加一個文件並提交到Git版本庫中,如下圖:

add index

一般我們直接在目錄中把沒用的文件刪了,或者用rm命令刪了,下面我們來演示一下:

git rm

大家可以看到,我們用 git status 查看一下狀態,現在我們有兩個選擇,一個是從版本庫中刪除該文件,就 git rm 命令刪除掉並用 git commit提交,另一種情況刪錯了,因爲版本庫裏還有所以可以很容易的恢復。下面我們來演示一下情況1:

git delete

好了,下面我們來看一下情況2:

git check

git rm 命令用於刪除一個文件。如果一個文件已經被提交到版本庫,那麼你永遠不用擔心誤刪,但是要小心,你只能恢復文件到最新版本,你會丟失最近一次提交後你修改的內容。好了,到這裏我們刪除文件就講解完成,嘿嘿。


六、總結

在一篇博客中我們講解了Git 本地版本庫的講解,在下一篇博客中我們主要講解Git 遠程倉庫詳解,好了到這裏這篇博客到這裏就全部完成。本人能力有限,有任何問題歡迎大家提出並討論。最後,希望大家有所收穫^_^……


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章