Hello , Git

前言java

因爲最近公司開始中止使用SVN,開始轉向GIT了,利用週末的時間學習實踐了下,分享給你們~git


什麼是Git?程序員

Git的官網是:http://git-scm.com/ ,咱們能夠在上面瞭解到GIT的一些介紹:github


Git is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency.
shell


Git是一個開源的,免費的,分佈式的版本管理系統。apache


咱們知道CVS,SVN,也是經常使用的版本管理系統,他們之間最大的區別在於「分佈式」。bash


另外,咱們還須要注意GIT的一個特性:everything is local  服務器


要知道CSV,SVN,咱們本地安裝的是客戶端,必須經過網絡鏈接到服務器,才能取得代碼,若是斷網,那就OVER了。可是GIT則不一樣,它全部的東西都在本地存放,也就是說在斷網的狀況下,能夠離線運行。網絡


說到GIT,那麼天然要知道一個網站:https://github.com/ 這是一個著名的程序員社交網站,咱們能夠在GITHUB上發佈本身的項目或者參與到別人的項目中。分佈式


GIT是大名鼎鼎的LINUX之父在2005年發佈,通過多年的沉澱,在開源社區使用率很是普遍,能夠說花一點時間學習GIT,將會給咱們帶來巨大的幫助,那麼下面咱們就開始吧!



來,安裝Git!

目前GIT的最新版本是2.6.3,GIT雖然有GUI,可是經過命令行的方式纔是掌握GIT的最佳方式,所以我將使用LINUX GIT來進行實踐。


爲了不安裝GIT的過程當中,涉及到諸多依賴,我已經在LINUX作好YUM源,並安裝了一些經常使用工具包,以下所示。

[root@localhost ~]# yum grouplist install
Loading "rhnplugin" plugin
Loading "security" plugin
Loading "installonlyn" plugin
This system is not registered with RHN.
RHN support will be disabled.
Setting up Group Process
Setting up repositories
Installed Groups:
   Office/Productivity
   MySQL Database
   Development Libraries
   System Tools
   GNOME Desktop Environment
   Network Servers
   X Window System
   Printing Support
   Mail Server
   Server Configuration Tools
   Administration Tools
   Graphical Internet


你們能夠到https://www.kernel.org/pub/software/scm/git/  下載    git-2.6.3.tar.gz

tar -xvf git-2.6.3.tar.gz 
./configure --prefix=/usr/local
make
make install


安裝完畢後,咱們能夠看到:

[root@localhost bin]# pwd
/usr/local/bin
[root@localhost bin]# ll
total 23260
-rwxr-xr-x 116 root root 5817589 Dec  4 18:29 git
-rwxr-xr-x   2 root root  162431 Dec  4 18:29 git-cvsserver
-rwxr-xr-x   1 root root  348074 Dec  4 18:29 gitk
-rwxr-xr-x 116 root root 5817589 Dec  4 18:29 git-receive-pack
-rwxr-xr-x   2 root root 2763905 Dec  4 18:29 git-shell
-rwxr-xr-x 116 root root 5817589 Dec  4 18:29 git-upload-archive
-rwxr-xr-x   2 root root 2998205 Dec  4 18:29 git-upload-pack
[root@localhost /]# git --version
git version 2.6.3
[root@localhost /]#



要使用,就要先配置Git

配置GIT,很簡單!

[root@localhost /]# git config --global user.name zhangfengzhe
[root@localhost /]# git config --global user.email zhangfengzhe1990@163.com
[root@localhost /]# git config --global color.ui true

之因此要配置USERNAME/EMAIL就是說對代碼的改動進行惟一PERSON標示

爲了讓GIT有些色彩,咱們對顏色進行了配置。


列出配置:

[root@localhost /]# git config --list
user.name=zhangfengzhe
user.email=zhangfengzhe1990@163.com
color.ui=true
[root@localhost /]#


說白了,咱們利用git config命令進行的配置操做,其實是對文件的改動,那麼在哪裏呢?

[root@localhost ~]# pwd
/root
[root@localhost ~]# cat .gitconfig 
[user]
name = zhangfengzhe
email = zhangfengzhe1990@163.com
[color]
ui = true


配置文件就在YOUR HOME目錄下,在上面,咱們看到了典型的LINUX分段式配置文件。


所以,咱們能夠直接修改.gitconfig就能夠完成配置。



建立Git Repo

Repo即repository的簡寫,就是倉庫,代碼庫的意思,有點MAVEN的感受,呵呵。


先看下面的例子:

[root@localhost myproject]# pwd
/myproject
[root@localhost myproject]# ll
total 16
drwxr-xr-x 2 root root 4096 Dec  4 19:41 hadoop
drwxr-xr-x 2 root root 4096 Dec  4 19:41 storm
[root@localhost myproject]# cd hadoop
[root@localhost hadoop]# git init 
Initialized empty Git repository in /myproject/hadoop/.git/
[root@localhost hadoop]# ll -al
total 24
drwxr-xr-x 3 root root 4096 Dec  4 19:41 .
drwxr-xr-x 4 root root 4096 Dec  4 19:41 ..
drwxr-xr-x 7 root root 4096 Dec  4 19:41 .git
[root@localhost hadoop]#

咱們常用的SVN,會在本地目錄下生成.svn,GIT也相似。


經過git init命令,咱們能夠建立一個empty repository!


事實上,對於通常的開發人員而言,咱們並不須要create empty repo,咱們開始須要作的實際上是克隆一個repo。


好比,最近阿里巴巴提交給apache的JSTORM項目,咱們來看看如何CLONE它。


首先,咱們經過https://github.com/alibaba/jstorm    COPY HTTPS

[root@localhost myproject]# git clone https://github.com/alibaba/jstorm.git

下載完成後,會出現jstorm目錄,以及在目錄中存在.git隱藏目錄。


經過git clone命令,咱們能夠克隆一個repo到本地。



添加以及提交

[root@localhost hadoop]# pwd
/myproject/hadoop
[root@localhost hadoop]# ll -A
total 12
drwxr-xr-x 7 root root 4096 Dec  5 03:35 .git
-rw-r--r-- 1 root root    0 Dec  5 03:36 HelloWorld.java
[root@localhost hadoop]# git status
On branch master
Initial commit
Untracked files:
  (use "git add <file>..." to include in what will be committed)
HelloWorld.java
nothing added to commit but untracked files present (use "git add" to track)

首先注意到.git目錄,說明已經進行了init。


經過git status命令,咱們能夠查看repo的狀態信息。


注意到Untracked files列表,是在說明HelloWorld.java沒有註冊到Git,所以咱們須要給HelloWorld.java「上戶口」。

[root@localhost hadoop]# git add HelloWorld.java 
You have new mail in /var/spool/mail/root
[root@localhost hadoop]# git status
On branch master
Initial commit
Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
new file:   HelloWorld.java
[root@localhost hadoop]#


經過git add命令,其實是將file推送到Staged Area。


上面再次查看狀態,提示須要提交,HelloWorld.java is new file。


下面咱們來提交:

[root@localhost hadoop]# git commit -m 
"this is the first commit for me and only one file : HelloWorld.java"
[master (root-commit) 815b551] this is the first commit for me and only one file : 
HelloWorld.java
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 HelloWorld.java
[root@localhost hadoop]#


注意了,同SVN同樣,GIT每次提交也會有MESSAGE信息,直接經過-m選項進行指定。


經過git commit -m命令來進行提交到HISTORY區域。


那麼提交後的狀態,又是什麼呢?

[root@localhost hadoop]# git status
On branch master
nothing to commit, working directory clean
[root@localhost hadoop]#

提交後,就乾淨了,你懂的!


那麼經過上面的一些實踐,其實咱們能夠獲得一些初步的認識:

若是有FILE並無ADD到REPO的話,GIT會提示咱們Untracked files

若是git add FILE但沒有COMMIT的話,GIT會提示咱們new files

若是COMMIT後,GIT會提示咱們nothing to commit, working directory clean



初步認識Git的核心原理圖

在上面的例子中,已經說起到working directory,staged area以及history。


其實這三個區域就是GIT的核心,理解他們之間的關係,是掌握GIT的基礎。


wKiom1Zjypag-E2gAAAmWV2aDWk570.png


咱們工做在working dir區域,對文件進行改動、添加、刪除的操做,而這些改動首先應該先到達Staged area區域,而後經過提交在History區域造成最新version。



既然有3個區域,那麼天然,對於一個文件,應該有2部分的狀態信息:


第一,對於working dir和staged area而言,有什麼區別?

第二,對於staged area和history而言,有什麼區別?


事實上,對於git status -s會看到2列狀態標誌位來表達這2部分狀態信息。【後文會有介紹】



對於History有一個HEAD的概念:


wKioL1ZjzXmhK5QwAAAdO6jE4M8858.png


提及head,天然會想到頭部指針,確實是有這麼個意思。


關於HEAD,也會在命令中予以體現!



Git狀態標誌位剖析

[root@localhost hadoop]# git status
On branch master
nothing to commit, working directory clean
[root@localhost hadoop]# ll -a
total 28
drwxr-xr-x 3 root root 4096 Dec  5 03:36 .
drwxr-xr-x 4 root root 4096 Dec  4 20:08 ..
drwxr-xr-x 8 root root 4096 Dec  5 04:01 .git
-rw-r--r-- 1 root root    0 Dec  5 03:36 HelloWorld.java
[root@localhost hadoop]# vi HelloWorld.java 
[root@localhost hadoop]# git status
On branch master
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:   HelloWorld.java
no changes added to commit (use "git add" and/or "git commit -a")
[root@localhost hadoop]# 
[root@localhost hadoop]# git status -s
 M HelloWorld.java
?? love.txt
[root@localhost hadoop]# git add love.txt 
[root@localhost hadoop]# git status -s
 M HelloWorld.java
A  love.txt


注意git status -s會簡明扼要的列出狀態信息,就列出2個標誌位!


仔細觀察上面的信息,love.txt的A,和HelloWorld.java的M並無對齊,這是爲何呢?


實際上,一個文件的git status有2列,第一列表明staging區域信息;第二列表明woring dir信息。也便是說,HelloWorld.java在working dir中修改了,但沒有提交到staging area 。love.txt在staging中添加了,可是在work dir中,沒有改變。


繼續,看下面的操做,來看status的變化:

[root@localhost hadoop]# git commit -m "love.txt" love.txt 
[master f43f700] love.txt
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 love.txt
[root@localhost hadoop]# git status -s
 M HelloWorld.java
[root@localhost hadoop]# git add HelloWorld.java 
[root@localhost hadoop]# git status -s
M  HelloWorld.java
[root@localhost hadoop]#



如何查看文件差異?

其實當咱們利用git status發現文件有差別時,很顯然,咱們須要查看文件的差異在哪裏!


看差別,看什麼和什麼的差別呢?


是working dirPK staged area ?

是staged area PK history ?

仍是working dir PK history ?


git均可以知足你!


working dir PK staged area:

[root@localhost hadoop]# git status -s
MM HelloWorld.java
[root@localhost hadoop]# git diff
diff --git a/HelloWorld.java b/HelloWorld.java
index 2e3abaa..5e6618e 100644
--- a/HelloWorld.java
+++ b/HelloWorld.java
@@ -1 +1,2 @@
 this is not a java file,haha
+abc
[root@localhost hadoop]#


staged area PK history:

[root@localhost hadoop]# git diff --staged


working dir PK history:

[root@localhost hadoop]# git status -s
MM HelloWorld.java
[root@localhost hadoop]# git diff HEAD
diff --git a/HelloWorld.java b/HelloWorld.java
index e69de29..5e6618e 100644
--- a/HelloWorld.java
+++ b/HelloWorld.java
@@ -0,0 +1,2 @@
+this is not a java file,haha
+abc
[root@localhost hadoop]#

git diff/git diff --staged/git diff HEAD 查看文件差別。


git diff列出的信息也是蠻多的,固然能夠像git status -s那樣有簡化版本:


git diff --stat

[root@localhost hadoop]# git diff --stat HEAD
 HelloWorld.java | 2 ++
 1 file changed, 2 insertions(+)
[root@localhost hadoop]#



Git有後悔藥能夠吃!

有一句老話叫 人非聖賢,孰能無過。


那麼在GIT中,如何撤銷錯誤呢?


既然是撤銷錯誤,那麼是從哪裏撤銷到哪裏呢?


在實際開發中,咱們常常遇到的是這樣的狀況,咱們對working dir的FILE進行了修改,而後ADD到了staged area區域,忽然發現有問題,想撤銷這些改動。


SO EASY,咱們只須要將history的內容還原便可。

[root@localhost hadoop]# ll -A
total 20
drwxr-xr-x 8 root root 4096 Dec  5 06:20 .git
-rw-r--r-- 1 root root   33 Dec  5 04:56 HelloWorld.java
-rw-r--r-- 1 root root    0 Dec  5 04:06 love.txt
[root@localhost hadoop]# vi HelloWorld.java 
[root@localhost hadoop]# git status -s
 M HelloWorld.java
[root@localhost hadoop]# git add HelloWorld.java 
[root@localhost hadoop]# git status -s
M  HelloWorld.java
[root@localhost hadoop]# git reset HelloWorld.java 
Unstaged changes after reset:
M  HelloWorld.java
[root@localhost hadoop]# git status -s
 M HelloWorld.java
[root@localhost hadoop]#

能夠發現經過git reset命令將staging area還原至history版本,須要注意是的不影響WORK DIR的改動。其實,就是一個標誌位的還原操做而已。


那若是咱們想把已經修改的WORK DIR的文件也恢復到原來的狀態,怎麼辦呢?

同上,咱們只須要將STAGING AREA的文件覆蓋WORK DIR便可,利用git checkout命令。

[root@localhost hadoop]# more HelloWorld.java 
this is not a java file,haha
abc
woyaogaini
[root@localhost hadoop]# git checkout HelloWorld.java 
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# more HelloWorld.java 
this is not a java file,haha
abc
[root@localhost hadoop]#

注意,git提供了一個簡化命令git checkout HEAD,它等價於下面的操做:

git checkout HEAD = git reset + git checkout

[root@localhost hadoop]# git status -s
[root@localhost hadoop]# ll -A
total 24
drwxr-xr-x 8 root root 4096 Dec  5 06:34 .git
-rw-r--r-- 1 root root   33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root   11 Dec  5 06:34 love.txt
[root@localhost hadoop]# cat love.txt 
i love you
[root@localhost hadoop]# vi love.txt 
[root@localhost hadoop]# cat love.txt 
i love you
do you love me
[root@localhost hadoop]# git status -s
 M love.txt
[root@localhost hadoop]# git add love.txt 
[root@localhost hadoop]# git status -s
M  love.txt
[root@localhost hadoop]# git checkout HEAD love.txt 
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# cat love.txt 
i love you
[root@localhost hadoop]#



移除及重命名文件

[root@localhost hadoop]# ll
total 16
-rw-r--r-- 1 root root 33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# touch delete.log
[root@localhost hadoop]# git add delete.log 
[root@localhost hadoop]# git commit -m "commit"
[master 0eccf50] commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 delete.log
[root@localhost hadoop]# git status
On branch master
nothing to commit, working directory clean
[root@localhost hadoop]# git rm delete.log 
rm 'delete.log'
[root@localhost hadoop]# git status -s
D  delete.log
[root@localhost hadoop]# ll -A
total 24
drwxr-xr-x 8 root root 4096 Dec  5 06:53 .git
-rw-r--r-- 1 root root   33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root   31 Dec  5 06:42 love.txt
[root@localhost hadoop]#

看得出,利用git rm進行刪除後,須要COMMIT!

[root@localhost hadoop]# git status -s
D  delete.log
[root@localhost hadoop]# git commit -m "commit"
[master 415380f] commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 delete.log
[root@localhost hadoop]# git status -s
[root@localhost hadoop]#

默認狀況下,git rm會把working dir以及staged area的文件進行刪除。


若是咱們僅僅想從STAGING AREA中移除FILE,可是保留WORK DIR中的文件的話,能夠這樣操做:


[root@localhost myproject]# ll
total 16
drwxr-xr-x 3 root root 4096 Dec  5 06:53 hadoop
drwxr-xr-x 2 root root 4096 Dec  4 19:41 storm
[root@localhost myproject]# cd hadoop/
[root@localhost hadoop]# ll
total 16
-rw-r--r-- 1 root root 33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# touch delete.log
[root@localhost hadoop]# git status -s
?? delete.log
[root@localhost hadoop]# git add delete.log 
[root@localhost hadoop]# git commit -m "commit"
[master 48b1bad] commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 delete.log
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# ll
total 20
-rw-r--r-- 1 root root  0 Dec  5 17:26 delete.log
-rw-r--r-- 1 root root 33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
[root@localhost hadoop]# git rm -cached delete.log 
error: did you mean `--cached` (with two dashes ?)
[root@localhost hadoop]# git rm --cached delete.log 
rm 'delete.log'
[root@localhost hadoop]# ll
total 20
-rw-r--r-- 1 root root  0 Dec  5 17:26 delete.log
-rw-r--r-- 1 root root 33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
[root@localhost hadoop]# git status -s
D  delete.log
?? delete.log
[root@localhost hadoop]#

git rm --cached的方式:


從最後的狀態能夠看到,delete.log仍然在WORK DIR中,可是並無ADD到STAGING AREA區域,同時STAGING AREA區域的delete.log被刪除。


重命名操做:

[root@localhost hadoop]# ll -A
total 28
-rw-r--r-- 1 root root    0 Dec  5 17:26 delete.log
drwxr-xr-x 8 root root 4096 Dec  5 17:31 .git
-rw-r--r-- 1 root root   33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root   31 Dec  5 06:42 love.txt
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# git mv delete.log delete.me
[root@localhost hadoop]# git status -s
R  delete.log -> delete.me
[root@localhost hadoop]# git commit -m "rename file"
[master 6f26a1b] rename file
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename delete.log => delete.me (100%)
[root@localhost hadoop]# git status -s
[root@localhost hadoop]#

經過git mv便可重命名,須要COMMIT!



保留現場:暫存工做區

什麼叫暫存工做區呢?

好比在實際開發中,咱們常常遇到這樣的場景:

咱們在WORK DIR中進行修改,有時咱們還add了一部分到staging area,此時忽然發現代碼存在BUG,須要修改。固然,咱們能夠利用git reset+git checkout的方式迅速獲得clean code,而後開始修改,可是這樣咱們就丟失了在work dir中的全部改動。


git爲咱們提供了git stash命令,幫助咱們保存現有的工做區,於此同時work dir /staging area的代碼恢復到HISTORY水平。一旦咱們改動完畢,COMMIT到HISTORY後,利用git stash pop進行還原原來的工做區!

[root@localhost hadoop]# git status -s
[root@localhost hadoop]# ll
total 28
-rw-r--r-- 1 root root  7 Dec  5 18:07 delete.me
-rw-r--r-- 1 root root 33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
-rw-r--r-- 1 root root  0 Dec  5 17:40 t1.txt
[root@localhost hadoop]# vi delete.me 
[root@localhost hadoop]# cat delete.me 
hello , world
[root@localhost hadoop]# git status -s
 M delete.me
[root@localhost hadoop]# git add delete.me 
[root@localhost hadoop]# git status -s
M  delete.me
[root@localhost hadoop]# vi delete.me 
[root@localhost hadoop]# git status -s
MM delete.me
[root@localhost hadoop]# git stash
Saved working directory and index state WIP on master: b714e98 commit
HEAD is now at b714e98 commit
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# ll
total 28
-rw-r--r-- 1 root root  7 Dec  5 18:11 delete.me
-rw-r--r-- 1 root root 33 Dec  5 06:26 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
-rw-r--r-- 1 root root  0 Dec  5 17:40 t1.txt
[root@localhost hadoop]# vi HelloWorld.java 
[root@localhost hadoop]# git status -s
 M HelloWorld.java
[root@localhost hadoop]# git add HelloWorld.java 
[root@localhost hadoop]# git commit -m "bug fix"
[master 54cf628] bug fix
 1 file changed, 1 insertion(+)
[root@localhost hadoop]# git status -s
[root@localhost hadoop]# git stash pop
On branch master
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:   delete.me
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (963a3ab0075e09ee63117b6b8b606780aca5d020)
[root@localhost hadoop]# ll
total 28
-rw-r--r-- 1 root root 26 Dec  5 18:12 delete.me
-rw-r--r-- 1 root root 37 Dec  5 18:11 HelloWorld.java
-rw-r--r-- 1 root root 31 Dec  5 06:42 love.txt
-rw-r--r-- 1 root root  0 Dec  5 17:40 t1.txt
[root@localhost hadoop]# cat delete.me 
hello , world
hello , git
[root@localhost hadoop]# git status -s
 M delete.me
[root@localhost hadoop]#



總結


wKiom1Zj2NThbPFIAABNqU95x5E353.png


到這裏就結束了,下篇博客將會繼續介紹GIT的一些深刻知識,好比COMMIT對象、TREE-ISH表達式、建立/刪除/合併分支等。

相關文章
相關標籤/搜索