日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

分布式版本控制系统Git的安装与使用

發(fā)布時(shí)間:2024/1/17 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 分布式版本控制系统Git的安装与使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

作業(yè)要求

1.(本次作業(yè)要求來自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2103

2.? 我的Github遠(yuǎn)程倉庫地址: https://github.com/llgeill/llg-centos-git--test

3.? 我的Github遠(yuǎn)程倉庫地址截圖

作業(yè)內(nèi)容

1.Git的由來

很多人都知道,Linus在1991年創(chuàng)建了開源的Linux,從此,Linux系統(tǒng)不斷發(fā)展,已經(jīng)成為最大的服務(wù)器系統(tǒng)軟件了。

Linus雖然創(chuàng)建了Linux,但Linux的壯大是靠全世界熱心的志愿者參與的,這么多人在世界各地為Linux編寫代碼,那Linux的代碼是如何管理的呢?

事實(shí)是,在2002年以前,世界各地的志愿者把源代碼文件通過diff的方式發(fā)給Linus,然后由Linus本人通過手工方式合并代碼!

你也許會(huì)想,為什么Linus不把Linux代碼放到版本控制系統(tǒng)里呢?不是有CVS、SVN這些免費(fèi)的版本控制系統(tǒng)嗎?因?yàn)長inus堅(jiān)定地反對(duì)CVS和SVN,這些集中式的版本控制系統(tǒng)不但速度慢,而且必須聯(lián)網(wǎng)才能使用。有一些商用的版本控制系統(tǒng),雖然比CVS、SVN好用,但那是付費(fèi)的,和Linux的開源精神不符。

不過,到了2002年,Linux系統(tǒng)已經(jīng)發(fā)展了十年了,代碼庫之大讓Linus很難繼續(xù)通過手工方式管理了,社區(qū)的弟兄們也對(duì)這種方式表達(dá)了強(qiáng)烈不滿,于是Linus選擇了一個(gè)商業(yè)的版本控制系統(tǒng)BitKeeper,BitKeeper的東家BitMover公司出于人道主義精神,授權(quán)Linux社區(qū)免費(fèi)使用這個(gè)版本控制系統(tǒng)。

安定團(tuán)結(jié)的大好局面在2005年就被打破了,原因是Linux社區(qū)牛人聚集,不免沾染了一些梁山好漢的江湖習(xí)氣。開發(fā)Samba的Andrew試圖破解BitKeeper的協(xié)議(這么干的其實(shí)也不只他一個(gè)),被BitMover公司發(fā)現(xiàn)了(監(jiān)控工作做得不錯(cuò)!),于是BitMover公司怒了,要收回Linux社區(qū)的免費(fèi)使用權(quán)。

Linus可以向BitMover公司道個(gè)歉,保證以后嚴(yán)格管教弟兄們,嗯,這是不可能的。實(shí)際情況是這樣的:

Linus花了兩周時(shí)間自己用C寫了一個(gè)分布式版本控制系統(tǒng),這就是Git!一個(gè)月之內(nèi),Linux系統(tǒng)的源碼已經(jīng)由Git管理了!牛是怎么定義的呢?大家可以體會(huì)一下。

Git迅速成為最流行的分布式版本控制系統(tǒng),尤其是2008年,GitHub網(wǎng)站上線了,它為開源項(xiàng)目免費(fèi)提供Git存儲(chǔ),無數(shù)開源項(xiàng)目開始遷移至GitHub,包括jQuery,PHP,Ruby等等。

歷史就是這么偶然,如果不是當(dāng)年BitMover公司威脅Linux社區(qū),可能現(xiàn)在我們就沒有免費(fèi)而超級(jí)好用的Git了。

2.什么是Git

  • 從定義上來說Git就是一個(gè)分布式版本控制系統(tǒng)
  • 從作用上來說Git就是管理一些文本或者代碼的版本更新,例如內(nèi)容的改動(dòng)
  • 從管理的對(duì)象來說,所有的版本控制都只能針對(duì)文本內(nèi)容,像word這樣的二進(jìn)制內(nèi)容,所謂版本,就是文件快照,不能比較差異,只能算帶備份的網(wǎng)盤

3.為什么git叫做分布式版本控制系統(tǒng)

如果要想了解分布式是什么意思,那么我們得先去了解它的對(duì)立面集中式

集中式版本控制系統(tǒng)

  • 工具:CVS及SVN都是集中式的版本控制系統(tǒng)
  • 內(nèi)容:集中式版本控制系統(tǒng)集中存放在中央服務(wù)器的,而干活的時(shí)候,用的都是自己的電腦,所以要先從中央服務(wù)器取得最新的版本,然后開始干活,干完活了,再把自己的活推送給中央服務(wù)器。中央服務(wù)器就好比是一個(gè)圖書館,你要改一本書,必須先從圖書館借出來,然后回到家自己改,改完了,再放回圖書館。
  • 缺點(diǎn):集中式版本控制系統(tǒng)最大的毛病就是必須聯(lián)網(wǎng)才能工作,如果在局域網(wǎng)內(nèi)還好,帶寬夠大,速度夠快,可如果在互聯(lián)網(wǎng)上,遇到網(wǎng)速慢的話,可能提交一個(gè)10M的文件就需要5分鐘,這還不得把人給憋死啊。

?

分布式版本控制系統(tǒng)

工具:git

內(nèi)容:布式版本控制系統(tǒng)沒有“中央服務(wù)器”,每個(gè)人的電腦上都是一個(gè)完整的版本庫,這樣,你工作的時(shí)候,就不需要聯(lián)網(wǎng)了,因?yàn)榘姹編炀驮谀阕约旱碾娔X上。既然每個(gè)人電腦上都有一個(gè)完整的版本庫,那多個(gè)人如何協(xié)作呢?比方說你在自己電腦上改了文件A,你的同事也在他的電腦上改了文件A,這時(shí),你們倆之間只需把各自的修改推送給對(duì)方,就可以互相看到對(duì)方的修改了。

優(yōu)點(diǎn):和集中式版本控制系統(tǒng)相比,分布式版本控制系統(tǒng)的安全性要高很多,因?yàn)槊總€(gè)人電腦里都有完整的版本庫,某一個(gè)人的電腦壞掉了不要緊,隨便從其他人那里復(fù)制一個(gè)就可以了。而集中式版本控制系統(tǒng)的中央服務(wù)器要是出了問題,所有人都沒法干活了。在實(shí)際使用分布式版本控制系統(tǒng)的時(shí)候,其實(shí)很少在兩人之間的電腦上推送版本庫的修改,因?yàn)榭赡苣銈儌z不在一個(gè)局域網(wǎng)內(nèi),兩臺(tái)電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機(jī)。因此,分布式版本控制系統(tǒng)通常也有一臺(tái)充當(dāng)“中央服務(wù)器”的電腦,但這個(gè)服務(wù)器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活,只是交換修改不方便而已。當(dāng)然,Git的優(yōu)勢不單是不必聯(lián)網(wǎng)這么簡單,后面我們還會(huì)看到Git極其強(qiáng)大的分支管理,把SVN等遠(yuǎn)遠(yuǎn)拋在了后面(svn其實(shí)也有分支功能,不過是在服務(wù)器上的分支)

?

集中式與分布式的差異性

  • 分布式在每一個(gè)用戶上都有一個(gè)版本控制而集中式?jīng)]有
  • 由于每一個(gè)用戶都有自己的版本控制工具,所以服務(wù)器壓力幾乎沒有,而集中式版本工具的壓力全在服務(wù)器上,所以在協(xié)作人數(shù)上面分布式版本工具更勝一籌
  • 4.開始安裝Git

    Git安裝

    可以直接從官網(wǎng)下載相應(yīng)操作系統(tǒng)的Git然后進(jìn)行安裝,當(dāng)然也可以使用命令行的方式

    • 例如在使用Centos操作系統(tǒng)的時(shí)候,可以使用如下命令快速安裝
    • yum install -y git
    • 或著不想使用命令行方式就直接去官網(wǎng)下載壓縮包
    https://git-scm.com/

    Git bash配置

    用戶名和郵箱地址的作用

  • 用戶名和郵箱地址是本地git客戶端的一個(gè)變量,不隨git庫而改變。
  • 每次commit都會(huì)用用戶名和郵箱紀(jì)錄。
  • github的contributions統(tǒng)計(jì)就是按郵箱來統(tǒng)計(jì)的。
  • 修改用戶名和郵箱地址

    • $?git?config?--global user.name "username"
    • $?git?config?--global?user.email??"email"

    查看用戶名和郵箱地址

    • $?git?config?user.name
    • $?git?config?user.email

    5.開始使用Git(版本庫)

    以下所有操作都在centos上操作完成

    什么是版本庫

    版本庫又名倉庫,英文名repository,你可以簡單理解成一個(gè)文件夾,這個(gè)文件夾里面的所有文件都可以被Git管理起來,每個(gè)文件的修改、刪除,Git都能跟蹤,以便任何時(shí)刻都可以追蹤歷史,或者在將來某個(gè)時(shí)刻可以“還原”。所以,創(chuàng)建一個(gè)版本庫非常簡單。

    開始創(chuàng)建版本庫

    首先,選擇一個(gè)合適的地方,創(chuàng)建一個(gè)空目錄

    #創(chuàng)建一個(gè)文件件 [llg@localhost 桌面]$ mkdir llg-test-git #進(jìn)入文件夾目錄 [llg@localhost 桌面]$ cd llg-test-git/ #顯示當(dāng)前文件夾路徑 [llg@localhost llg-test-git]$ pwd

    接著,最重要的一步 通過git init?的命令將當(dāng)前文件夾變成一個(gè)版本庫

    [llg@localhost llg-test-git]$ git init 初始化空的 Git 版本庫于 /home/llg/桌面/llg-test-git/.git/ [llg@localhost llg-test-git]$

    最后,通過ls -al 命令,發(fā)現(xiàn)多了個(gè)git文件夾。這個(gè)目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動(dòng)修改這個(gè)目錄里面的文件,不然改亂了,就把Git倉庫給破壞了。

    [llg@localhost llg-test-git]$ ls -al 總用量 4 drwxrwsr-x 3 llg llg 18 9月 14 19:48 . drwsrwsrwt. 13 llg llg 4096 9月 14 19:44 .. drwxrwsr-x 7 llg llg 119 9月 14 19:48 .git [llg@localhost llg-test-git]$

    ?

    開始添加文件到版本庫

    首先需要注意的是版本管理的受眾范圍

    • 首先這里再明確一下,所有的版本控制系統(tǒng),其實(shí)只能跟蹤文本文件的改動(dòng),比如TXT文件,網(wǎng)頁,所有的程序代碼等等,Git也不例外。版本控制系統(tǒng)可以告訴你每次的改動(dòng),比如在第5行加了一個(gè)單詞“Linux”,在第8行刪了一個(gè)單詞“Windows”。而圖片、視頻這些二進(jìn)制文件,雖然也能由版本控制系統(tǒng)管理,但沒法跟蹤文件的變化,只能把二進(jìn)制文件每次改動(dòng)串起來,也就是只知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統(tǒng)不知道,也沒法知道。
    • 不幸的是,Microsoft的Word格式是二進(jìn)制格式,因此,版本控制系統(tǒng)是沒法跟蹤Word文件的改動(dòng)的,前面我們舉的例子只是為了演示,如果要真正使用版本控制系統(tǒng),就要以純文本方式編寫文件。
    • 因?yàn)槲谋臼怯芯幋a的,比如中文有常用的GBK編碼,日文有Shift_JIS編碼,如果沒有歷史遺留問題,強(qiáng)烈建議使用標(biāo)準(zhǔn)的UTF-8編碼,所有語言使用同一種編碼,既沒有沖突,又被所有平臺(tái)所支持。
    • 使用Windows的童鞋要特別注意:千萬不要使用Windows自帶的記事本編輯任何文本文件。原因是Microsoft開發(fā)記事本的團(tuán)隊(duì)使用了一個(gè)非常弱智的行為來保存UTF-8編碼的文件,他們自作聰明地在每個(gè)文件開頭添加了0xefbbbf(十六進(jìn)制)的字符,你會(huì)遇到很多不可思議的問題,比如,網(wǎng)頁第一行可能會(huì)顯示一個(gè)“?”,明明正確的程序一編譯就報(bào)語法錯(cuò)誤,等等,都是由記事本的弱智行為帶來的。建議你下載Notepad++代替記事本,不但功能強(qiáng)大,而且免費(fèi)!記得把Notepad++的默認(rèn)編碼設(shè)置為UTF-8 without BOM即可:

    首先,使用vi創(chuàng)建一個(gè)文件并且添加一些內(nèi)容。確保此文件必須在這個(gè)版本倉庫里面也就是我們惡毒llg-test-git文件夾,不然放在其他地方是不能被版本控制的。

    [llg@localhost llg-test-git]$ vi llg.txt [llg@localhost llg-test-git]$

    接著,將文件顯示的通過git add命令添加到版本庫里面,不過在這之前我們使用git status 來查看一下還沒使用git add命令時(shí)候的狀態(tài)和使用git add之后的狀態(tài),比較一下不同。通過比較,我們發(fā)現(xiàn)了當(dāng)使用git add 命令的時(shí)候其實(shí)是建立起了文件跟蹤的功能,之后使用git status 就可以看到有一個(gè)新文件

    [llg@localhost llg-test-git]$ git status # 位于分支 master # # 初始提交 # # 未跟蹤的文件: # (使用 "git add <file>..." 以包含要提交的內(nèi)容) # # llg.txt 提交為空,但是存在尚未跟蹤的文件(使用 "git add" 建立跟蹤) [llg@localhost llg-test-git]$ [llg@localhost llg-test-git]$ git add llg.txt [llg@localhost llg-test-git]$ git status # 位于分支 master # # 初始提交 # # 要提交的變更: # (使用 "git rm --cached <file>..." 撤出暫存區(qū)) # # 新文件: llg.txt # [llg@localhost llg-test-git]$

    ?

    最后,使用git commit -m告訴Git,把文件提交到倉庫。-m是提交的一些說明信息,必須要寫,可以方便自己和他人了解這次提交了什么東西。

    ?

    ?

    [llg@localhost llg-test-git]$ git commit -m "git練習(xí)測試" [master(根提交) abde635] git練習(xí)測試 1 file changed, 1 insertion(+) create mode 100644 llg.txt [llg@localhost llg-test-git]$

    ?

    疑問:為什么Git添加文件需要add,commit一共兩步呢?

    因?yàn)閏ommit可以一次提交很多文件,所以你可以多次add不同的文件,比如下圖,可以跟蹤多個(gè)文件然后全部一次性提交到版本庫里面.

    [llg@localhost llg-test-git]$ vi one.txt [llg@localhost llg-test-git]$ vi two.txt [llg@localhost llg-test-git]$ vi three.txt [llg@localhost llg-test-git]$ git add one.txt [llg@localhost llg-test-git]$ git add two.txt [llg@localhost llg-test-git]$ git add three.txt [llg@localhost llg-test-git]$ git commit -m "這次測試一次提交三個(gè)文件" [master 44449dc] 這次測試一次提交三個(gè)文件 3 files changed, 4 insertions(+) create mode 100644 one.txt create mode 100644 three.txt create mode 100644 two.txt [llg@localhost llg-test-git]$ [llg@localhost llg-test-git]$ git status # 位于分支 master 無文件要提交,干凈的工作區(qū) [llg@localhost llg-test-git]$

    ?

    6.Git版本回退

    在學(xué)習(xí)版本回退之前我們線來了解下兩個(gè)常用的命令git status和git diff

    git status

    剛剛在創(chuàng)建版本庫的時(shí)候我們已經(jīng)使用了,用來查看git的狀態(tài),一般可以拿來查看我們做的某些操作之后的狀態(tài),例如修改文件,添加文件等等

    例如我們修改一個(gè)文件然后使用git status查看,發(fā)現(xiàn)了提示llg.txt是修改過的文件

    ?


    [llg@localhost llg-test-git]$ vi llg.txt [llg@localhost llg-test-git]$ git status # 位于分支 master # 尚未暫存以備提交的變更: # (使用 "git add <file>..." 更新要提交的內(nèi)容) # (使用 "git checkout -- <file>..." 丟棄工作區(qū)的改動(dòng)) # # 修改: llg.txt # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a") [llg@localhost llg-test-git]$

    ?

    ?

    git sdiff

    由于文件修改過后,我們有時(shí)候可能想知道具體修改了什么內(nèi)容,位置在那里,區(qū)別是什么等等。,所以我們需要git sdiff命令來獲得這個(gè)修改前后的對(duì)照信息

    [llg@localhost llg-test-git]$ git diff diff --git a/llg.txt b/llg.txt index f77faef..2f3d837 100644 --- a/llg.txt +++ b/llg.txt @@ -1 +1 @@ -my name is liliguang +My name is liliguang.I created three files a moment ago. [llg@localhost llg-test-git]$

    ?

    之后繼續(xù)測試,修改其他兩個(gè)文件內(nèi)容 [llg@localhost llg-test-git]$ vi one.txt [llg@localhost llg-test-git]$ vi two.txt [llg@localhost llg-test-git]$ git diff diff --git a/llg.txt b/llg.txt index f77faef..2f3d837 100644 --- a/llg.txt +++ b/llg.txt @@ -1 +1 @@ -my name is liliguang +My name is liliguang.I created three files a moment ago. diff --git a/one.txt b/one.txt index 25ab921..34144e1 100644 --- a/one.txt +++ b/one.txt @@ -1 +1,2 @@ this is one +llg diff --git a/two.txt b/two.txt index 42b3fbc..0f62931 100644 --- a/two.txt +++ b/two.txt @@ -1,2 +1,2 @@ this is two - +llg [llg@localhost llg-test-git]$

    ?

    [llg@localhost llg-test-git]$ vi two.txt [llg@localhost llg-test-git]$ git diff diff --git a/llg.txt b/llg.txt index f77faef..2f3d837 100644 --- a/llg.txt +++ b/llg.txt @@ -1 +1 @@ -my name is liliguang +My name is liliguang.I created three files a moment ago. diff --git a/one.txt b/one.txt index 25ab921..34144e1 100644 --- a/one.txt +++ b/one.txt @@ -1 +1,2 @@ this is one +llg diff --git a/two.txt b/two.txt index 42b3fbc..e730358 100644 --- a/two.txt +++ b/two.txt @@ -1,2 +1,6 @@ this is two - +llg +sss +aaa +bbb +wef [llg@localhost llg-test-git]$

    ?

    ?

    開始使用版本回退的前提

    版本回退的意思就是回退到某一次commit那里,這優(yōu)點(diǎn)類似與打通關(guān)游戲,你可以在任意通過的關(guān)卡中來往穿梭

    git log

    首先,我們需要使用git log 命令來找出我們之前的commit信息。從下圖可以看到提交順序是按照最新日期排序的,最新的在最頂部,commit 后面的就是commit ID?了,后面的版本回退都靠它

    ?

    [llg@localhost llg-test-git]$ git log commit 3956cc36e1017c14e79d9de0944bb9baa6d2ff51 Author: llg <903857227@qq.com> Date: Fri Sep 14 20:35:26 2018 +0800測試兩個(gè)文件提交留一個(gè)文件不提交commit 44449dc5261b8a66bac14ce302519f26895d0163 Author: llg <903857227@qq.com> Date: Fri Sep 14 20:11:22 2018 +0800這次測試一次提交三個(gè)文件commit abde635c93434ac4172caa4e0c6383e9dfc3d522 Author: llg <903857227@qq.com> Date: Fri Sep 14 20:07:31 2018 +0800git練習(xí)測試[llg@localhost llg-test-git]$

    ?

    如果嫌輸出信息太多,看得眼花繚亂的,可以試試加上--pretty=oneline參數(shù)

    ?

    ?

    [llg@localhost llg-test-git]$ git log --pretty=oneline 3956cc36e1017c14e79d9de0944bb9baa6d2ff51 測試兩個(gè)文件提交留一個(gè)文件不提交 44449dc5261b8a66bac14ce302519f26895d0163 這次測試一次提交三個(gè)文件 abde635c93434ac4172caa4e0c6383e9dfc3d522 git練習(xí)測試 [llg@localhost llg-test-git]$

    ?

    ?

    開始使用版本回退

    首先,Git必須知道當(dāng)前版本是哪個(gè)版本,在Git中,用HEAD表示當(dāng)前版本,也就是最新的提交3956cc...(注意我的提交ID和你的肯定不一樣),上一個(gè)版本就是HEAD^,上上一個(gè)版本就是HEAD^^,當(dāng)然往上100個(gè)版本寫100個(gè)^比較容易數(shù)不過來,所以寫成HEAD~100。

    git reset

    我們要把當(dāng)前版本<測試兩個(gè)文件提交留一個(gè)文件不提交>回退到上一個(gè)版本<這次測試一次提交三個(gè)文件>,就可以使用git reset命令:

    從下圖我們可以分析出,其實(shí)HEAD代表的是頭指針,畢竟這個(gè)git使用c語言寫的,我們對(duì)C應(yīng)該也是不陌生的,所以這是一個(gè)雙向鏈表,可以向前也可以向后,只要我們知道commit ID。

    ?

    [llg@localhost llg-test-git]$ git reset --hard HEAD HEAD 現(xiàn)在位于 3956cc3 測試兩個(gè)文件提交留一個(gè)文件不提交 [llg@localhost llg-test-git]$ git reset --hard HEAD^ HEAD 現(xiàn)在位于 44449dc 這次測試一次提交三個(gè)文件 [llg@localhost llg-test-git]$ git reset --hard HEAD^ HEAD 現(xiàn)在位于 abde635 git練習(xí)測試 [llg@localhost llg-test-git]$

    ?

    ?

    當(dāng)我們跳的比較遠(yuǎn)的時(shí)候,也可以直接指定commit ID 來跳轉(zhuǎn)?

    ?

    [llg@localhost llg-test-git]$ git reset --hard 3956cc3 HEAD 現(xiàn)在位于 3956cc3 測試兩個(gè)文件提交留一個(gè)文件不提交 [llg@localhost llg-test-git]$

    ?

    當(dāng)我們想要回到之前最新的版本的時(shí)候,我們會(huì)想到用git log,但是很不幸我們發(fā)現(xiàn)之前的版本信息都沒有了。所以我們還有一個(gè)命令用來找回之前的commit ID ,就是git reflog命令了。

    ?

    [llg@localhost llg-test-git]$ git log commit abde635c93434ac4172caa4e0c6383e9dfc3d522 Author: llg <903857227@qq.com> Date: Fri Sep 14 20:07:31 2018 +0800 git練習(xí)測試 [llg@localhost llg-test-git]$

    ?

    ?

    ?

    ?

    git reflog

    可以拿到所有的操作記錄

    從下面我們可以找到帶有commit字樣的就是我們之前創(chuàng)建的版本,但是只提供了ID的七為數(shù),但是沒關(guān)系,git會(huì)自動(dòng)識(shí)別出來

    ?

    [llg@localhost llg-test-git]$ git reflog abde635 HEAD@{0}: reset: moving to HEAD^ 44449dc HEAD@{1}: reset: moving to HEAD^ 3956cc3 HEAD@{2}: commit: 測試兩個(gè)文件提交留一個(gè)文件不提交 44449dc HEAD@{3}: commit: 這次測試一次提交三個(gè)文件 abde635 HEAD@{4}: commit (initial): git練習(xí)測試 [llg@localhost llg-test-git]$ git reset --hard 3956cc3 HEAD 現(xiàn)在位于 3956cc3 測試兩個(gè)文件提交留一個(gè)文件不提交 [llg@localhost llg-test-git]$

    ?

    ?

    ?

    ?

    ?

    7.git的工作區(qū)和暫存區(qū)

    首先是官圖解釋,從下圖可以看出如果我們想直接提交文件到master分支上,那么直接使用 git commit -a即可

    接著再看看其余大佬繪制的圖

    版本庫(Repository)

    工作區(qū)有一個(gè)隱藏目錄.git,這個(gè)不算工作區(qū),而是Git的版本庫。

    Git的版本庫里存了很多東西,其中最重要的就是稱為stage(或者叫index)的暫存區(qū),還有Git為我們自動(dòng)創(chuàng)建的第一個(gè)分支master,以及指向master的一個(gè)指針叫HEAD。

    ?

    假如我們?cè)赾ommit之后沒有任何操作,那么我們暫存區(qū)就是空的

    當(dāng)我們添加了文件或者修改了文件,并且使用了add命令那么暫存區(qū)stage就又有了文件

    ?

    當(dāng)我們使用commit提交之后,那么早存區(qū)又變成了空

    ?

    關(guān)于git diff 與暫存區(qū)的關(guān)系

    • git diff 比較的是工作區(qū)文件與暫存區(qū)文件的區(qū)別(上次git add 的內(nèi)容)
    • git diff --cached 比較的是暫存區(qū)的文件與倉庫分支里(上次git commit 后的內(nèi)容)的區(qū)別

    8.Git如何撤回修改的操作

    場景1:當(dāng)你改亂了工作區(qū)某個(gè)文件的內(nèi)容,想直接丟棄工作區(qū)的修改時(shí),用命令git checkout -- file。

    首先修改工作區(qū)的文件,不執(zhí)行add操作

    檢查git狀態(tài),發(fā)現(xiàn)提示使用git checkout -- file 命令撤回操作 ,執(zhí)行之后發(fā)現(xiàn)已經(jīng)成功撤回

    [llg@localhost llg-test-git]$ git status # 位于分支 master # 尚未暫存以備提交的變更: # (使用 "git add <file>..." 更新要提交的內(nèi)容) # (使用 "git checkout -- <file>..." 丟棄工作區(qū)的改動(dòng)) # # 修改: one.txt # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a") [llg@localhost llg-test-git]$ [llg@localhost llg-test-git]$ git checkout -- one.txt [llg@localhost llg-test-git]$

    ?

    ?

    ?

    ?

    ?

    ?

    場景2:當(dāng)你不但改亂了工作區(qū)某個(gè)文件的內(nèi)容,還添加到了暫存區(qū)時(shí),想丟棄修改,分兩步,第一步用命令git reset HEAD <file>,就回到了場景1,第二步按場景1操作。

    首先修改文件并且通過add放到暫存區(qū)?

    ?

    [llg@localhost llg-test-git]$ git status # 位于分支 master # 要提交的變更: # (使用 "git reset HEAD <file>..." 撤出暫存區(qū)) # # 修改: one.txt # [llg@localhost llg-test-git]$

    ?

    ?

    ?

    ?

    根據(jù)提示使用git reset HEAD <file> 撤出暫存區(qū),執(zhí)行成功?

    ?

    [llg@localhost llg-test-git]$ git status # 位于分支 master # 要提交的變更: # (使用 "git reset HEAD <file>..." 撤出暫存區(qū)) # # 修改: one.txt # [llg@localhost llg-test-git]$ git reset HEAD one.txt 重置后撤出暫存區(qū)的變更: M one.txt [llg@localhost llg-test-git]$ git status # 位于分支 master # 尚未暫存以備提交的變更: # (使用 "git add <file>..." 更新要提交的內(nèi)容) # (使用 "git checkout -- <file>..." 丟棄工作區(qū)的改動(dòng)) # # 修改: one.txt # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a") [llg@localhost llg-test-git]$

    ?

    場景3:已經(jīng)提交了不合適的修改到版本庫時(shí),想要撤銷本次提交,參考版本回退一節(jié),不過前提是沒有推送到遠(yuǎn)程庫。

    9.Git如何刪除文件

    此處的刪除文件是指當(dāng)一個(gè)文件提交到版本庫后,也就是master分支。如果在工作區(qū)刪除這個(gè)文件,那么將會(huì)使工作區(qū)文件與版本庫文件不對(duì)應(yīng),在這里需要分清兩種使用情況。

    工作區(qū)刪除了文件并且確實(shí)要從版本庫中也刪除該文件

    那么就應(yīng)該使用git rm 命令

    [llg@localhost llg-test-git]$ rm delete.txt [llg@localhost llg-test-git]$ git rm -- delete.txt rm 'delete.txt' [llg@localhost llg-test-git]$ git status # 位于分支 master # 要提交的變更: # (使用 "git reset HEAD <file>..." 撤出暫存區(qū)) # # 刪除: delete.txt # [llg@localhost llg-test-git]$

    ?

    ?

    ?

    當(dāng)然我們通過git status 命令可以看出這一操作只是保留在了暫存區(qū),所以我們還需要commit命令提交這一更改,其實(shí)可以把這一命令想象成修改的命令

    ?

    [llg@localhost llg-test-git]$ git commit -m "正式從版本庫中刪除該文件" [master ad66495] 正式從版本庫中刪除該文件 1 file changed, 1 deletion(-) delete mode 100644 delete.txt [llg@localhost llg-test-git]$ git status # 位于分支 master 無文件要提交,干凈的工作區(qū) [llg@localhost llg-test-git]$

    ?

    ?

    工作區(qū)誤刪了某些文件,需要從版本庫中重新弄回來

    根據(jù)git status 提示的方法,我們可以從版本庫中checkout中某些文件

    [llg@localhost llg-test-git]$ git checkout -- delete.txt

    另外一個(gè)一個(gè)簡單的方法就是重新把版本庫更新回來,但是這個(gè)前提是你得保證只有這么一個(gè)刪除文件,如果有其他文件修改了并且未放到暫存區(qū),那么就非常可怕了。

    ?

    [llg@localhost llg-test-git]$ git reset --hard HEAD^ HEAD 現(xiàn)在位于 eda17f9 這是一個(gè)將要被刪除的文件 [llg@localhost llg-test-git]$ ls -al 總用量 24 drwxrwsr-x 3 llg llg 98 9月 15 19:56 . drwsrwsrwt. 13 llg llg 4096 9月 14 19:44 .. -rw-rw-r-- 1 llg llg 34 9月 15 19:56 delete.txt drwxrwsr-x 8 llg llg 183 9月 15 19:56 .git -rw-rw-r-- 1 llg llg 57 9月 14 21:06 llg.txt -rw-rw-r-- 1 llg llg 16 9月 14 22:05 one.txt -rw-rw-r-- 1 llg llg 14 9月 14 21:06 three.txt -rw-rw-r-- 1 llg llg 13 9月 14 21:06 two.txt [llg@localhost llg-test-git]$

    ?

    10.初識(shí)遠(yuǎn)程倉庫

    既然git的其中一個(gè)目的就是為了協(xié)作開發(fā),那么遠(yuǎn)程倉庫就是為了這一個(gè)目的的。通過將倉庫放在一個(gè)遠(yuǎn)程的服務(wù)器上,讓所有人都可以訪問這個(gè)倉庫,可以一起更新和提交。

    實(shí)際情況往往是這樣,找一臺(tái)電腦充當(dāng)服務(wù)器的角色,每天24小時(shí)開機(jī),其他每個(gè)人都從這個(gè)“服務(wù)器”倉庫克隆一份到自己的電腦上,并且各自把各自的提交推送到服務(wù)器倉庫里,也從服務(wù)器倉庫中拉取別人的提交。

    完全可以自己搭建一臺(tái)運(yùn)行Git的服務(wù)器,不過現(xiàn)階段,為了學(xué)Git先搭個(gè)服務(wù)器絕對(duì)是小題大作。好在這個(gè)世界上有個(gè)叫GitHub的神奇的網(wǎng)站,從名字就可以看出,這個(gè)網(wǎng)站就是提供Git倉庫托管服務(wù)的,所以,只要注冊(cè)一個(gè)GitHub賬號(hào),就可以免費(fèi)獲得Git遠(yuǎn)程倉庫。

    在繼續(xù)閱讀后續(xù)內(nèi)容前,請(qǐng)自行注冊(cè)GitHub賬號(hào)。由于你的本地Git倉庫和GitHub倉庫之間的傳輸是通過SSH加密的,所以,需要一點(diǎn)設(shè)置:

    第1步:創(chuàng)建SSH Key。在用戶主目錄下,看看有沒有.ssh目錄,如果有,再看看這個(gè)目錄下有沒有id_rsa和id_rsa.pub這兩個(gè)文件,如果已經(jīng)有了,可直接跳到下一步。如果沒有,打開Shell(Windows下打開Git Bash),創(chuàng)建SSH Key:

    [llg@localhost ~]$ ssh-keygen -t rsa -C "903857227@qq.com"

    如果一切順利的話,可以在用戶主目錄里找到.ssh目錄,里面有id_rsa和id_rsa.pub兩個(gè)文件,這兩個(gè)就是SSH Key的秘鑰對(duì),id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,可以放心地告訴任何人。

    第2步:登陸GitHub,打開“Account settings”,“SSH Keys”頁面:

    然后,點(diǎn)“Add SSH Key”,填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內(nèi)容:

    [llg@localhost ~]$ cd .ssh/

    ?

    [llg@localhost .ssh]$ ls -al 總用量 16 drwsrwsrwt. 2 llg llg 57 9月 15 20:28 . drwsrwsrwt. 39 llg llg 4096 9月 15 19:59 .. -rw------- 1 llg llg 1679 9月 15 20:29 id_rsa -rw-r--r-- 1 llg llg 398 9月 15 20:29 id_rsa.pub -rw-r--r-- 1 llg llg 175 4月 27 20:05 known_hosts [llg@localhost .ssh]$ vi id_rsa.pub

    ?

    為什么GitHub需要SSH Key呢?因?yàn)镚itHub需要識(shí)別出你推送的提交確實(shí)是你推送的,而不是別人冒充的,而Git支持SSH協(xié)議,所以,GitHub只要知道了你的公鑰,就可以確認(rèn)只有你自己才能推送。

    當(dāng)然,GitHub允許你添加多個(gè)Key。假定你有若干電腦,你一會(huì)兒在公司提交,一會(huì)兒在家里提交,只要把每臺(tái)電腦的Key都添加到GitHub,就可以在每臺(tái)電腦上往GitHub推送了。

    最后友情提示,在GitHub上免費(fèi)托管的Git倉庫,任何人都可以看到喔(但只有你自己才能改)。所以,不要把敏感信息放進(jìn)去。

    如果你不想讓別人看到Git庫,有兩個(gè)辦法,一個(gè)是交點(diǎn)保護(hù)費(fèi),讓GitHub把公開的倉庫變成私有的,這樣別人就看不見了(不可讀更不可寫)。另一個(gè)辦法是自己動(dòng)手,搭一個(gè)Git服務(wù)器,因?yàn)槭悄阕约旱腉it服務(wù)器,所以別人也是看不見的。這個(gè)方法我們后面會(huì)講到的,相當(dāng)簡單,公司內(nèi)部開發(fā)必備。

    確保你擁有一個(gè)GitHub賬號(hào)后,我們就即將開始遠(yuǎn)程倉庫的學(xué)習(xí)。

    11.從github上添加一個(gè)遠(yuǎn)程倉庫

    首先我們github上登陸自己帳號(hào)后創(chuàng)建一個(gè)倉庫

    接著我們可以看到創(chuàng)建完倉庫后給我們的提示

    從本地的已有倉庫直接推送到遠(yuǎn)程倉庫上

    根據(jù)上邊提示輸入命令

    ?

    [llg@localhost llg-test-git]$ git remote add origin https://github.com/llgeill/llg-centos-git--test.git [llg@localhost llg-test-git]$ git push -u origin master Username for 'https://github.com': 903857227@qq.com Password for 'https://903857227@qq.com@github.com': Counting objects: 12, done. Delta compression using up to 4 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (12/12), 1.01 KiB | 0 bytes/s, done. Total 12 (delta 0), reused 0 (delta 0) remote: remote: Create a pull request for 'master' on GitHub by visiting: remote: https://github.com/llgeill/llg-centos-git--test/pull/new/master remote: To https://github.com/llgeill/llg-centos-git--test.git * [new branch] master -> master 分支 master 設(shè)置為跟蹤來自 origin 的遠(yuǎn)程分支 master。

    ?

    ?

    發(fā)現(xiàn)文件已經(jīng)推送完畢?

    ?

    Git遠(yuǎn)程倉庫的優(yōu)點(diǎn)?

    • 要關(guān)聯(lián)一個(gè)遠(yuǎn)程庫,使用命令git remote add origin git@server-name:path/repo-name.git;
    • 關(guān)聯(lián)后,使用命令git push -u origin master第一次推送master分支的所有內(nèi)容;
    • 此后,每次本地提交后,只要有必要,就可以使用命令git push origin master推送最新修改;
    • 分布式版本系統(tǒng)的最大好處之一是在本地工作完全不需要考慮遠(yuǎn)程庫的存在,也就是有沒有聯(lián)網(wǎng)都可以正常工作,而SVN在沒有聯(lián)網(wǎng)的時(shí)候是拒絕干活的!當(dāng)有網(wǎng)絡(luò)的時(shí)候,再把本地提交推送一下就完成了同步,真是太方便了!

    12.從遠(yuǎn)程倉庫克隆一個(gè)已有倉庫

    首先我們從github上創(chuàng)建一個(gè)遠(yuǎn)程倉庫

    首先在github上找到可以克隆的地址

    下一步是用命令git clone克隆一個(gè)本地庫,我們可以發(fā)現(xiàn)項(xiàng)目已經(jīng)克隆下來

    ?

    [llg@localhost 桌面]$ git clone git@github.com:llgeill/llg-centos-git-test-1.git 正克隆到 'llg-centos-git-test-1'... The authenticity of host 'github.com (192.30.253.112)' can't be established. RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8. RSA key fingerprint is MD5:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'github.com,192.30.253.112' (RSA) to the list of known hosts. remote: Counting objects: 3, done. remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 接收對(duì)象中: 100% (3/3), done. [llg@localhost 桌面]$ ls -al 總用量 40 drwsrwsrwt. 14 llg llg 4096 9月 15 21:10 . drwsrwsrwt. 39 llg llg 4096 9月 15 20:39 .. drwxr-xr-x 11 llg llg 196 9月 2 17:11 1-Brixton版教程示例 drwxr-xr-x 34 llg llg 4096 9月 2 15:57 2-Dalston版教程示例 -rw-r--r-- 1 root root 12288 4月 23 20:58 .android-studio.desktop.swp drwxrwxr-x 10 llg llg 302 9月 13 22:23 dist -rwsrwsrwt 1 llg llg 1968 5月 2 08:27 .keystore drwxrwsr-x 5 llg llg 118 9月 14 08:38 llg drwxrwsr-x 3 llg llg 35 9月 15 21:10 llg-centos-git-test-1 drwxrwsr-x 3 llg llg 80 9月 15 20:01 llg-test-git drwxrwsr-x 5 llg llg 131 9月 7 20:13 llg-user-gateway drwxrwsr-x 6 llg llg 151 9月 14 08:51 llg-web-springboot-class drwxr-xr-x 39 llg llg 4096 9月 2 19:41 SpringCloudBook-master drwx------ 14 llg llg 315 9月 3 07:46 spring-cloud-llg drwxrwsr-x 5 llg llg 61 9月 5 18:53 untitled drwxr-xr-x 12 llg llg 4096 6月 29 2016 計(jì)算機(jī)組成原理201407

    ?

    測試從本地倉庫推送回遠(yuǎn)程倉庫

    [llg@localhost llg-centos-git-test-1]$ vi llg.txt [llg@localhost llg-centos-git-test-1]$ git add llg.txt [llg@localhost llg-centos-git-test-1]$ git commit -m "測試" [master 4bdb6c4] 測試 1 file changed, 1 insertion(+) create mode 100644 llg.txt [llg@localhost llg-centos-git-test-1]$ git status # 位于分支 master # 您的分支領(lǐng)先 'origin/master'1 個(gè)提交。 # (使用 "git push" 來發(fā)布您的本地提交) # 無文件要提交,干凈的工作區(qū) [llg@localhost llg-centos-git-test-1]$ git push -u origin masterWarning: Permanently added the RSA host key for IP address '192.30.253.113' to the list of known hosts. Counting objects: 4, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 274 bytes | 0 bytes/s, done. Total 3 (delta 0), reused 0 (delta 0) To git@github.com:llgeill/llg-centos-git-test-1.git 07b4bcc..4bdb6c4 master -> master 分支 master 設(shè)置為跟蹤來自 origin 的遠(yuǎn)程分支 master。

    ?

    13.Git的分支管理

    分支就是科幻電影里面的平行宇宙,當(dāng)你正在電腦前努力學(xué)習(xí)Git的時(shí)候,另一個(gè)你正在另一個(gè)平行宇宙里努力學(xué)習(xí)SVN。

    如果兩個(gè)平行宇宙互不干擾,那對(duì)現(xiàn)在的你也沒啥影響。不過,在某個(gè)時(shí)間點(diǎn),兩個(gè)平行宇宙合并了,結(jié)果,你既學(xué)會(huì)了Git又學(xué)會(huì)了SVN!

    分支在實(shí)際中有什么用呢?假設(shè)你準(zhǔn)備開發(fā)一個(gè)新功能,但是需要兩周才能完成,第一周你寫了50%的代碼,如果立刻提交,由于代碼還沒寫完,不完整的代碼庫會(huì)導(dǎo)致別人不能干活了。如果等代碼全部寫完再一次提交,又存在丟失每天進(jìn)度的巨大風(fēng)險(xiǎn)。

    現(xiàn)在有了分支,就不用怕了。你創(chuàng)建了一個(gè)屬于你自己的分支,別人看不到,還繼續(xù)在原來的分支上正常工作,而你在自己的分支上干活,想提交就提交,直到開發(fā)完畢后,再一次性合并到原來的分支上,這樣,既安全,又不影響別人工作。

    其他版本控制系統(tǒng)如SVN等都有分支管理,但是用過之后你會(huì)發(fā)現(xiàn),這些版本控制系統(tǒng)創(chuàng)建和切換分支比蝸牛還慢,簡直讓人無法忍受,結(jié)果分支功能成了擺設(shè),大家都不去用。

    但Git的分支是與眾不同的,無論創(chuàng)建、切換和刪除分支,Git在1秒鐘之內(nèi)就能完成!無論你的版本庫是1個(gè)文件還是1萬個(gè)文件。

    14.創(chuàng)建與合并分支管理

    在版本回退里,每次提交,Git都把它們串成一條時(shí)間線,這條時(shí)間線就是一個(gè)分支。截止到目前,只有一條時(shí)間線,在Git里,這個(gè)分支叫主分支,即master分支。HEAD嚴(yán)格來說不是指向提交,而是指向master,master才是指向提交的,所以,HEAD指向的就是當(dāng)前分支。

    原理解析

    一開始的時(shí)候,master分支是一條線,Git用master指向最新的提交,再用HEAD指向master,就能確定當(dāng)前分支,以及當(dāng)前分支的提交點(diǎn):

    ?

    創(chuàng)建新分支?

    當(dāng)我們創(chuàng)建新的分支,例如dev時(shí),Git新建了一個(gè)指針叫dev,指向master相同的提交,再把HEAD指向dev,就表示當(dāng)前分支在dev上

    git checkout命令加上-b參數(shù)表示創(chuàng)建分支并切換分支

    ?

    [llg@localhost llg-test-git]$ git checkout -b dev 切換到一個(gè)新分支 'dev' [llg@localhost llg-test-git]$

    ?

    上面的命令等價(jià)與下面兩條命令的結(jié)合

    ?

    [llg@localhost llg-test-git]$ git branch dev [llg@localhost llg-test-git]$ git checkout dev 切換到分支 'dev'

    ?

    我們可以使用git branch 查看當(dāng)前分支的情況?

    ?

    [llg@localhost llg-test-git]$ git branch * dev master

    ?

    ?你看,Git創(chuàng)建一個(gè)分支很快,因?yàn)槌嗽黾右粋€(gè)dev指針,改改HEAD的指向,工作區(qū)的文件都沒有任何變化!

    新分支上提交版本庫

    不過,從現(xiàn)在開始,對(duì)工作區(qū)的修改和提交就是針對(duì)dev分支了,比如新提交一次后,dev指針往前移動(dòng)一步,而master指針不變

    ?

    [llg@localhost llg-test-git]$ vi one.txt [llg@localhost llg-test-git]$ git add one.txt [llg@localhost llg-test-git]$ git commit -m "在分支上提交版本信息" [dev 8c8117b] 在分支上提交版本信息 1 file changed, 2 insertions(+) [llg@localhost llg-test-git]$ git status # 位于分支 dev 無文件要提交,干凈的工作區(qū) [llg@localhost llg-test-git]$

    ?

    當(dāng)我們重新切換到master分支時(shí)候發(fā)現(xiàn)one.txt根本沒有變化,因?yàn)槲覀僣ommit的是dev分支

    ?

    [llg@localhost llg-test-git]$ git checkout master 切換到分支 'master' [llg@localhost llg-test-git]$ vi one.txt [llg@localhost llg-test-git]$ git checkout dev 切換到分支 'dev' [llg@localhost llg-test-git]$ vi one.txt

    ?

    合并分支

    假如我們?cè)赿ev上的工作完成了,就可以把dev合并到master上。Git怎么合并呢?最簡單的方法,就是直接把master指向dev的當(dāng)前提交,就完成了合并?。注意下面的Fast-forwar 信息,Git告訴我們這次合并是“快進(jìn)模式”,也就是直接把master指向dev的當(dāng)前提交,所以合并速度非???。當(dāng)然,也不是每次合并都能Fast-forward,我們后面會(huì)講其他方式的合并。

    ?

    [llg@localhost llg-test-git]$ git checkout master 切換到分支 'master' [llg@localhost llg-test-git]$ git merge dev 更新 3956cc3..8c8117b Fast-forward one.txt | 2 ++ 1 file changed, 2 insertions(+)

    ?

    刪除分支

    合并完分支后,甚至可以刪除dev分支。刪除dev分支就是把dev指針給刪掉,刪掉后,我們就剩下了一條master分支

    ?

    [llg@localhost llg-test-git]$ git branch dev * master [llg@localhost llg-test-git]$ vi one.txt [llg@localhost llg-test-git]$ git branch -d dev 已刪除分支 dev(曾為 8c8117b)。 [llg@localhost llg-test-git]$ git branch * master

    ?

    ?小結(jié)

    因?yàn)閯?chuàng)建、合并和刪除分支非???#xff0c;所以Git鼓勵(lì)你使用分支完成某個(gè)任務(wù),合并后再刪掉分支,這和直接在master分支上工作效果是一樣的,但過程更安全。

    • 查看分支:git branch
    • 創(chuàng)建分支:git branch <name>
    • 切換分支:git checkout <name>
    • 創(chuàng)建+切換分支:git checkout -b <name>
    • 合并某分支到當(dāng)前分支:git merge <name>
    • 刪除分支:git branch -d <name>

    ?

    15.解決分支的沖突問題

    首先創(chuàng)建一個(gè)分支并且提交了一次版本倉庫,主分支也提交了一次版本倉庫,如圖所示

    這種情況下,Git無法執(zhí)行“快速合并”,只能試圖把各自的修改合并起來,但這種合并就可能會(huì)有沖突

    ?

    [llg@localhost llg-test-git]$ git merge fantasy 自動(dòng)合并 dele 沖突(內(nèi)容):合并沖突于 dele 自動(dòng)合并失敗,修正沖突然后提交修正的結(jié)果。

    ?

    果然沖突了!Git告訴我們,readme.txt文件存在沖突,必須手動(dòng)解決沖突后再提交。git status也可以告訴我們沖突的文件

    ?

    [llg@localhost llg-test-git]$ git status # 位于分支 master # 您的分支領(lǐng)先 'origin/master'7 個(gè)提交。 # (使用 "git push" 來發(fā)布您的本地提交) # # 您有尚未合并的路徑。 # (解決沖突并運(yùn)行 "git commit") # # 未合并的路徑: # (使用 "git add <file>..." 標(biāo)記解決方案) # # 雙方修改: dele # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

    ?

    手工修改沖突?

    我們可以直接查看dele的內(nèi)容,Git用<<<<<<<,=======,>>>>>>>標(biāo)記出不同分支的內(nèi)容

    我們手動(dòng)修改沖突位置,之后提交文件到暫存區(qū)并且commit

    ?

    [llg@localhost llg-test-git]$ git add dele [llg@localhost llg-test-git]$ git commit -m "cscs" [master b1dd3cc] cscs

    ?

    現(xiàn)在,master分支和feature1分支變成了下圖所示

    查看分支合并情況?

    用帶參數(shù)的git log --graph?也可以看到分支的合并情況

    ?

    * commit b1dd3cc1e90369e4fe2fc93f5a75b46a8918973f |\ Merge: 478f0bc 43149ab | | Author: llg <903857227@qq.com> | | Date: Sun Sep 16 15:10:03 2018 +0800 | | | | cscs | | | * commit 43149abf7f5724e74f64b394521778ceaded39b1 | | Author: llg <903857227@qq.com> | | Date: Sun Sep 16 15:01:24 2018 +0800 | | | | ccc | | * | commit 478f0bc2b144ac6fce457e05c9e596e314bd1f11 | | Author: llg <903857227@qq.com> | | Date: Sun Sep 16 15:02:12 2018 +0800 | | | | ss | | * | commit a22d668c065ad42c38232850fad8082250aa63a2 |\ \ Merge: 57e8b85 1575642 | |/ Author: llg <903857227@qq.com> | | Date: Sun Sep 16 14:55:13 2018 +0800 | | | | Merge branch 'fantasy' | | | | ceshi | |

    ?

    ?

    16.分支管理策略

    通常,合并分支時(shí),如果可能,Git會(huì)用Fast forward模式,但這種模式下,刪除分支后,會(huì)丟掉分支信息。

    如果要強(qiáng)制禁用Fast forward模式,Git就會(huì)在merge時(shí)生成一個(gè)新的commit,這樣,從分支歷史上就可以看出分支信息。

    下面我們實(shí)戰(zhàn)一下--no-ff(禁用Fast forward)方式的git merge,一些前提條件略過??

    ?

    [llg@localhost llg-test-git]$ git merge --no-ff -m "merge with no-ff" dev Merge made by the 'recursive' strategy. dele | 1 + 1 file changed, 1 insertion(+) 合并分支時(shí),加上--no-ff參數(shù)就可以用普通模式合并,合并后的歷史有分支,能看出來曾經(jīng)做過合并,而fast forward合并就看不出來曾經(jīng)做過合并。 [llg@localhost llg-test-git]$ git log --graph --pretty=oneline --abbrev-commit * 3a5456c merge with no-ff |\ | * b68ba37 add merge |/ * 0ed0fe3 測試 * b1dd3cc cscs |\ | * 43149ab ccc * | 478f0bc ss * | a22d668 Merge branch 'fantasy' |\ \ | |/ | * 1575642 xx * | 57e8b85 Merge branch 'fantasy' |\ \ | |/ | * 87bc5d7 ss * | 709521d 版本沖突 * | 8c8117b 在分支上提交版本信息 |/ * 3956cc3 測試兩個(gè)文件提交留一個(gè)文件不提交 * 44449dc 這次測試一次提交三個(gè)文件 * abde635 git練習(xí)測試

    ?

    我們來看看不適用no-ff下的策略,發(fā)現(xiàn)會(huì)直接合并,分支信息不能再找到

    ?

    [llg@localhost llg-test-git]$ git log --graph --pretty=oneline --abbrev-commit * 8699b49 dele * 3a5456c merge with no-ff |\ | * b68ba37 add merge |/ * 0ed0fe3 測試 * b1dd3cc cscs |\ | * 43149ab ccc * | 478f0bc ss * | a22d668 Merge branch 'fantasy' |\ \ | |/ | * 1575642 xx * | 57e8b85 Merge branch 'fantasy' |\ \ | |/ | * 87bc5d7 ss * | 709521d 版本沖突 * | 8c8117b 在分支上提交版本信息 |/ * 3956cc3 測試兩個(gè)文件提交留一個(gè)文件不提交 * 44449dc 這次測試一次提交三個(gè)文件 * abde635 git練習(xí)測試
    ? 可以看到,不使用Fast forward模式,merge后就像這樣。

    ?

    分支策略

    在實(shí)際開發(fā)中,我們應(yīng)該按照幾個(gè)基本原則進(jìn)行分支管理:

    首先,master分支應(yīng)該是非常穩(wěn)定的,也就是僅用來發(fā)布新版本,平時(shí)不能在上面干活;

    那在哪干活呢?干活都在dev分支上,也就是說,dev分支是不穩(wěn)定的,到某個(gè)時(shí)候,比如1.0版本發(fā)布時(shí),再把dev分支合并到master上,在master分支發(fā)布1.0版本;

    你和你的小伙伴們每個(gè)人都在dev分支上干活,每個(gè)人都有自己的分支,時(shí)不時(shí)地往dev分支上合并就可以了。

    所以,團(tuán)隊(duì)合作的分支看起來就像這樣:

    ?

    17.解決Bug的臨時(shí)分支?

    軟件開發(fā)中,bug就像家常便飯一樣。有了bug就需要修復(fù),在Git中,由于分支是如此的強(qiáng)大,所以,每個(gè)bug都可以通過一個(gè)新的臨時(shí)分支來修復(fù),修復(fù)后,合并分支,然后將臨時(shí)分支刪除。

    當(dāng)你接到一個(gè)修復(fù)一個(gè)代號(hào)101的bug的任務(wù)時(shí),很自然地,你想創(chuàng)建一個(gè)分支issue-101來修復(fù)它,但是,等等,當(dāng)前正在dev上進(jìn)行的工作還沒有提交:

    ?

    [llg@localhost llg-test-git]$ git status # 位于分支 master # 您的分支領(lǐng)先 'origin/master'15 個(gè)提交。 # (使用 "git push" 來發(fā)布您的本地提交) # # 尚未暫存以備提交的變更: # (使用 "git add <file>..." 更新要提交的內(nèi)容) # (使用 "git checkout -- <file>..." 丟棄工作區(qū)的改動(dòng)) # # 修改: dele # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

    ?

    ?

    并不是你不想提交,而是工作只進(jìn)行到一半,還沒法提交,預(yù)計(jì)完成還需1天時(shí)間。但是,必須在兩個(gè)小時(shí)內(nèi)修復(fù)該bug,怎么辦?

    封鎖現(xiàn)場

    幸好,Git還提供了一個(gè)stash功能,可以把當(dāng)前工作現(xiàn)場“儲(chǔ)藏”起來,等以后恢復(fù)現(xiàn)場后繼續(xù)工作,再通過git status 查看發(fā)現(xiàn)工作區(qū)已經(jīng)干凈。?

    ?

    [llg@localhost llg-test-git]$ git stash Saved working directory and index state WIP on master: 7dec792 ss HEAD 現(xiàn)在位于 7dec792 ss [llg@localhost llg-test-git]$ git status # 位于分支 master # 您的分支領(lǐng)先 'origin/master'15 個(gè)提交。 # (使用 "git push" 來發(fā)布您的本地提交) # 無文件要提交,干凈的工作區(qū) 首先確定要在哪個(gè)分支上修復(fù)bug,假定需要在master分支上修復(fù),就從master創(chuàng)建臨時(shí)分支

    ?

    ?

    [llg@localhost llg-test-git]$ git checkout -b issue-101 切換到一個(gè)新分支 'issue-101'

    ?

    現(xiàn)在修復(fù)bug,我們通過修改文件模擬這一個(gè)過程

    ?

    [llg@localhost llg-test-git]$ vi delete.txt [llg@localhost llg-test-git]$ git add delete.txt [llg@localhost llg-test-git]$ git commit -m "ss" [issue-101 e0b9de9] ss 1 file changed, 1 insertion(+)

    ?

    修復(fù)完成后,切換到master分支,并完成合并,最后刪除issue-101分支

    ?

    [llg@localhost llg-test-git]$ git checkout master 切換到分支 'master' 您的分支領(lǐng)先 'origin/master'15 個(gè)提交。 (使用 "git push" 來發(fā)布您的本地提交) [llg@localhost llg-test-git]$ git merge --no-ff -m "merge bug fix 101" issue-101 Merge made by the 'recursive' strategy. delete.txt | 1 + 1 file changed, 1 insertion(+)

    ?

    還原現(xiàn)場?

    太棒了,原計(jì)劃兩個(gè)小時(shí)的bug修復(fù)只花了5分鐘!

    現(xiàn)在,是時(shí)候接著回到dev分支干活了,切換到dev分支然后用git stash list命令看看

    ?

    [llg@localhost llg-test-git]$ git stash list stash@{0}: WIP on master: 7dec792 ss

    ?

    工作現(xiàn)場還在,Git把stash內(nèi)容存在某個(gè)地方了,但是需要恢復(fù)一下,有兩個(gè)辦法:

    一是用git stash apply恢復(fù),但是恢復(fù)后,stash內(nèi)容并不刪除,你需要用git stash drop來刪除;

    另一種方式是用git stash pop,恢復(fù)的同時(shí)把stash內(nèi)容也刪了:?

    ?

    [llg@localhost llg-test-git]$ git stash pop # 位于分支 master # 您的分支領(lǐng)先 'origin/master'17 個(gè)提交。 # (使用 "git push" 來發(fā)布您的本地提交) # # 尚未暫存以備提交的變更: # (使用 "git add <file>..." 更新要提交的內(nèi)容) # (使用 "git checkout -- <file>..." 丟棄工作區(qū)的改動(dòng)) # # 修改: dele # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a") 丟棄了 refs/stash@{0} (fa2bbbe411ba20c94501e912ec120fa944c06b92) 再用git stash list查看,就看不到任何stash內(nèi)容了?

    ?

    ?

    [llg@localhost llg-test-git]$ git stash list [llg@localhost llg-test-git]$

    ?

    小結(jié)

    • 修復(fù)bug時(shí),我們會(huì)通過創(chuàng)建新的bug分支進(jìn)行修復(fù),然后合并,最后刪除;
    • 當(dāng)手頭工作沒有完成時(shí),先把工作現(xiàn)場git stash一下,然后去修復(fù)bug,修復(fù)后,再git stash pop,回到工作現(xiàn)場

    ?

    18.強(qiáng)制刪除分支

    當(dāng)需要開發(fā)一個(gè)新功能的時(shí)候,最好創(chuàng)建一個(gè)新的分支進(jìn)行代碼編輯,但是因?yàn)橐恍┣闆r不需要這個(gè)分支了,但是這個(gè)分支從來沒有合并過,所以要使用 git branch -D?的方式強(qiáng)制刪除

    ?

    [llg@localhost llg-test-git]$ vi feichuan.txt.swp [llg@localhost llg-test-git]$ git add feichuan.txt.swp [llg@localhost llg-test-git]$ git commit -m "ss" [feature-vulcan 4cd8736] ss 1 file changed, 1 insertion(+) create mode 100644 feichuan.txt.swp [llg@localhost llg-test-git]$ git checkout master M dele 切換到分支 'master' 您的分支領(lǐng)先 'origin/master'17 個(gè)提交。 (使用 "git push" 來發(fā)布您的本地提交) [llg@localhost llg-test-git]$ git branch -D feature-vulcan 已刪除分支 feature-vulcan(曾為 4cd8736)。

    ?

    19.rebease整理分叉歷史

    在上一節(jié)我們看到了,多人在同一個(gè)分支上協(xié)作時(shí),很容易出現(xiàn)沖突。即使沒有沖突,后push的童鞋不得不先pull,在本地合并,然后才能push成功。

    每次合并再push后,分支變成了這樣

    總之看上去很亂,有強(qiáng)迫癥的童鞋會(huì)問:為什么Git的提交歷史不能是一條干凈的直線?

    其實(shí)是可以做到的!

    Git有一種稱為rebase的操作,有人把它翻譯成“變基”。

    先不要隨意展開想象。我們還是從實(shí)際問題出發(fā),看看怎么把分叉的提交變成直線。

    在和遠(yuǎn)程分支同步后,我們對(duì)hello.py這個(gè)文件做了兩次提交。用git log命令看看:

    ?

    $ git log --graph --pretty=oneline --abbrev-commit * 582d922 (HEAD -> master) add author * 8875536 add comment * d1be385 (origin/master) init hello * e5e69f1 Merge branch 'dev' |\ | * 57c53ab (origin/dev, dev) fix env conflict | |\ | | * 7a5e5dd add env | * | 7bd91f1 add new env ...

    ?

    注意到Git用(HEAD -> master)和(origin/master)標(biāo)識(shí)出當(dāng)前分支的HEAD和遠(yuǎn)程origin的位置分別是582d922 add author和d1be385 init hello,本地分支比遠(yuǎn)程分支快兩個(gè)提交。

    現(xiàn)在我們嘗試推送本地分支:

    ?

    $ git push origin master To github.com:michaelliao/learngit.git ! [rejected] master -> master (fetch first) error: failed to push some refs to 'git@github.com:michaelliao/learngit.git' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details.

    ?

    很不幸,失敗了,這說明有人先于我們推送了遠(yuǎn)程分支。按照經(jīng)驗(yàn),先pull一下:?

    ?

    $ git pull remote: Counting objects: 3, done. remote: Compressing objects: 100% (1/1), done. remote: Total 3 (delta 1), reused 3 (delta 1), pack-reused 0 Unpacking objects: 100% (3/3), done. From github.com:michaelliao/learngit d1be385..f005ed4 master -> origin/master * [new tag] v1.0 -> v1.0 Auto-merging hello.py Merge made by the 'recursive' strategy. hello.py | 1 + 1 file changed, 1 insertion(+)

    ?

    再用git status看看狀態(tài):

    ?

    $ git status On branch master Your branch is ahead of 'origin/master' by 3 commits. (use "git push" to publish your local commits)nothing to commit, working tree clean

    ?

    加上剛才合并的提交,現(xiàn)在我們本地分支比遠(yuǎn)程分支超前3個(gè)提交。

    用git log看看:

    ?

    $ git log --graph --pretty=oneline --abbrev-commit * e0ea545 (HEAD -> master) Merge branch 'master' of github.com:michaelliao/learngit |\ | * f005ed4 (origin/master) set exit=1 * | 582d922 add author * | 8875536 add comment |/ * d1be385 init hello ...

    ?

    對(duì)強(qiáng)迫癥童鞋來說,現(xiàn)在事情有點(diǎn)不對(duì)頭,提交歷史分叉了。如果現(xiàn)在把本地分支push到遠(yuǎn)程,有沒有問題?

    有!

    什么問題?

    不好看!

    有沒有解決方法?

    有!

    這個(gè)時(shí)候,rebase就派上了用場。我們輸入命令git rebase試試:

    ?

    $ git rebase First, rewinding head to replay your work on top of it... Applying: add comment Using index info to reconstruct a base tree... M hello.py Falling back to patching base and 3-way merge.. Auto-merging hello.py Applying: add author Using index info to reconstruct a base tree... M hello.py Falling back to patching base and 3-way merge... Auto-merging hello.py

    ?

    ?

    ?

    ?

    輸出了一大堆操作,到底是啥效果?再用git log看看:

    ?

    ?

    $ git log --graph --pretty=oneline --abbrev-commit * 7e61ed4 (HEAD -> master) add author * 3611cfe add comment * f005ed4 (origin/master) set exit=1 * d1be385 init hello

    ?

    原本分叉的提交現(xiàn)在變成一條直線了!這種神奇的操作是怎么實(shí)現(xiàn)的?其實(shí)原理非常簡單。我們注意觀察,發(fā)現(xiàn)Git把我們本地的提交“挪動(dòng)”了位置,放到了f005ed4 (origin/master) set exit=1之后,這樣,整個(gè)提交歷史就成了一條直線。rebase操作前后,最終的提交內(nèi)容是一致的,但是,我們本地的commit修改內(nèi)容已經(jīng)變化了,它們的修改不再基于d1be385 init hello,而是基于f005ed4 (origin/master) set exit=1,但最后的提交7e61ed4內(nèi)容是一致的。

    這就是rebase操作的特點(diǎn):把分叉的提交歷史“整理”成一條直線,看上去更直觀。缺點(diǎn)是本地的分叉提交已經(jīng)被修改過了。

    最后,通過push操作把本地分支推送到遠(yuǎn)程:

    ?

    Mac:~/learngit michael$ git push origin master Counting objects: 6, done. Delta compression using up to 4 threads. Compressing objects: 100% (5/5), done. Writing objects: 100% (6/6), 576 bytes | 576.00 KiB/s, done. Total 6 (delta 2), reused 0 (delta 0) remote: Resolving deltas: 100% (2/2), completed with 1 local object. To github.com:michaelliao/learngit.git f005ed4..7e61ed4 master -> master

    ?

    再用git log看看效果:

    $ git log --graph --pretty=oneline --abbrev-commit * 7e61ed4 (HEAD -> master, origin/master) add author * 3611cfe add comment * f005ed4 set exit=1 * d1be385 init hello

    ?

    ?

    遠(yuǎn)程分支的提交歷史也是一條直線。

    ?

    總結(jié)?

    • rebase操作可以把本地未push的分叉提交歷史整理成直線;

    • rebase的目的是使得我們?cè)诓榭礆v史提交的變化時(shí)更容易,因?yàn)榉植娴奶峤恍枰綄?duì)比。

    20.什么是標(biāo)簽管理

    發(fā)布一個(gè)版本時(shí),我們通常先在版本庫中打一個(gè)標(biāo)簽(tag),這樣,就唯一確定了打標(biāo)簽時(shí)刻的版本。將來無論什么時(shí)候,取某個(gè)標(biāo)簽的版本,就是把那個(gè)打標(biāo)簽的時(shí)刻的歷史版本取出來。所以,標(biāo)簽也是版本庫的一個(gè)快照。

    Git的標(biāo)簽雖然是版本庫的快照,但其實(shí)它就是指向某個(gè)commit的指針(跟分支很像對(duì)不對(duì)?但是分支可以移動(dòng),標(biāo)簽不能移動(dòng)),所以,創(chuàng)建和刪除標(biāo)簽都是瞬間完成的。

    Git有commit,為什么還要引入tag?

    “請(qǐng)把上周一的那個(gè)版本打包發(fā)布,commit號(hào)是6a5819e...”

    “一串亂七八糟的數(shù)字不好找!”

    如果換一個(gè)辦法:

    “請(qǐng)把上周一的那個(gè)版本打包發(fā)布,版本號(hào)是v1.2”

    “好的,按照tag v1.2查找commit就行!”

    所以,tag就是一個(gè)讓人容易記住的有意義的名字,它跟某個(gè)commit綁在一起。

    21.創(chuàng)建Git倉庫版本標(biāo)簽

    在Git中打標(biāo)簽非常簡單,首先,切換到需要打標(biāo)簽的分支上

    ?

    [llg@localhost llg-test-git]$ git branch dev issue-101 * master [llg@localhost llg-test-git]$ git checkout dev 切換到分支 'dev'

    ?

    創(chuàng)建當(dāng)前版本標(biāo)簽

    然后,敲命令git tag <name>就可以打一個(gè)新標(biāo)簽

    [llg@localhost llg-test-git]$ git tag v1.0

    創(chuàng)建其他版本標(biāo)簽

    默認(rèn)標(biāo)簽是打在最新提交的commit上的。有時(shí)候,如果忘了打標(biāo)簽,比如,現(xiàn)在已經(jīng)是周五了,但應(yīng)該在周一打的標(biāo)簽沒有打,怎么辦?

    方法是找到歷史提交的commit id,然后打上就可以了:

    ?

    [llg@localhost llg-test-git]$ git log --pretty=oneline --abbrev-commit 8699b49 dele 3a5456c merge with no-ff b68ba37 add merge 0ed0fe3 測試 b1dd3cc cscs 478f0bc ss 43149ab ccc a22d668 Merge branch 'fantasy' 1575642 xx 57e8b85 Merge branch 'fantasy' 709521d 版本沖突 87bc5d7 ss 8c8117b 在分支上提交版本信息 3956cc3 測試兩個(gè)文件提交留一個(gè)文件不提交 44449dc 這次測試一次提交三個(gè)文件 abde635 git練習(xí)測試 [llg@localhost llg-test-git]$ git tag v1.0 [llg@localhost llg-test-git]$ git tag v0.9 3a5456c [llg@localhost llg-test-git]$ git tag v0.9 v1.0

    ?

    查看所有標(biāo)簽?

    ?

    [llg@localhost llg-test-git]$ git tag v0.8 v0.9 v1.0

    ?

    查看標(biāo)簽詳細(xì)信息

    注意,標(biāo)簽不是按時(shí)間順序列出,而是按字母排序的??梢杂胓it show <tagname>查看標(biāo)簽信息

    [llg@localhost llg-test-git]$ git show v0.9 commit 3a5456c07d50d99437d01fbf538a41a4556d7504 Merge: 0ed0fe3 b68ba37 Author: llg <903857227@qq.com> Date: Sun Sep 16 16:04:56 2018 +0800merge with no-ff

    創(chuàng)建帶說明文字的標(biāo)簽

    還可以創(chuàng)建帶有說明的標(biāo)簽,用-a指定標(biāo)簽名,-m指定說明文字

    ?

    [llg@localhost llg-test-git]$ git tag -a v0.8 -m "version 0.8 released" b68ba37 [llg@localhost llg-test-git]$ git show v0.8 tag v0.8 Tagger: llg <903857227@qq.com> Date: Mon Sep 17 09:31:27 2018 +0800version 0.8 releasedcommit b68ba371b04d5b7b6305454c160d7ef88178ea2d Author: llg <903857227@qq.com> Date: Sun Sep 16 16:04:19 2018 +0800add mergediff --git a/dele b/dele index 20c0828..a36d773 100644 --- a/dele +++ b/dele @@ -10,3 +10,4 @@ sad end1111111111111111111111 +2222222222222222222222

    ?

    22.操作標(biāo)簽

    刪除標(biāo)簽

    如果標(biāo)簽打錯(cuò)了,也可以刪除

    ?

    [llg@localhost llg-test-git]$ git tag -d v0.8 已刪除 tag 'v0.8'(曾為 658e2ab)

    ?

    推送某個(gè)標(biāo)簽到遠(yuǎn)程倉庫?

    因?yàn)閯?chuàng)建的標(biāo)簽都只存儲(chǔ)在本地,不會(huì)自動(dòng)推送到遠(yuǎn)程。所以,打錯(cuò)的標(biāo)簽可以在本地安全刪除。

    如果要推送某個(gè)標(biāo)簽到遠(yuǎn)程,使用命令git push origin <tagname>

    ?

    [llg@localhost llg-test-git]$ git push origin v1.0 Username for 'https://github.com': 903857227@qq.com Password for 'https://903857227@qq.com@github.com': Total 0 (delta 0), reused 0 (delta 0) To https://github.com/llgeill/llg-centos-git--test.git * [new tag] v1.0 -> v1.0

    ?

    ?推送所有標(biāo)簽到遠(yuǎn)程倉庫?

    或者,一次性推送全部尚未推送到遠(yuǎn)程的本地標(biāo)簽:

    ?

    [llg@localhost llg-test-git]$ git push origin --tag Username for 'https://github.com': 903857227@qq.com Password for 'https://903857227@qq.com@github.com': Total 0 (delta 0), reused 0 (delta 0) To https://github.com/llgeill/llg-centos-git--test.git * [new tag] v0.9 -> v0.9

    ?

    刪除遠(yuǎn)程標(biāo)簽

    首先在本地刪除標(biāo)簽

    ?

    [llg@localhost llg-test-git]$ git tag -d v0.8 已刪除 tag 'v0.9'(曾為 3a5456c)

    ?

    然后,從遠(yuǎn)程刪除。刪除命令是?git push origin :refs/tags/xxx

    ?

    [llg@localhost llg-test-git]$ git push origin :refs/tags/v0.8 Username for 'https://github.com': 903857227@qq.com Password for 'https://903857227@qq.com@github.com': To https://github.com/llgeill/llg-centos-git--test.git - [deleted] v0.8

    ?

    最后去官網(wǎng)github上查看tag是否被刪除,發(fā)現(xiàn)確實(shí)被刪除了

    ?

    23.如何使用Github

    我們一直用GitHub作為免費(fèi)的遠(yuǎn)程倉庫,如果是個(gè)人的開源項(xiàng)目,放到GitHub上是完全沒有問題的。其實(shí)GitHub還是一個(gè)開源協(xié)作社區(qū),通過GitHub,既可以讓別人參與你的開源項(xiàng)目,也可以參與別人的開源項(xiàng)目。

    在GitHub出現(xiàn)以前,開源項(xiàng)目開源容易,但讓廣大人民群眾參與進(jìn)來比較困難,因?yàn)橐獏⑴c,就要提交代碼,而給每個(gè)想提交代碼的群眾都開一個(gè)賬號(hào)那是不現(xiàn)實(shí)的,因此,群眾也僅限于報(bào)個(gè)bug,即使能改掉bug,也只能把diff文件用郵件發(fā)過去,很不方便。

    但是在GitHub上,利用Git極其強(qiáng)大的克隆和分支功能,廣大人民群眾真正可以第一次自由參與各種開源項(xiàng)目了。

    參與別人的開源項(xiàng)目?

    如何參與一個(gè)開源項(xiàng)目呢?比如人氣極高的bootstrap項(xiàng)目,這是一個(gè)非常強(qiáng)大的CSS框架,你可以訪問它的項(xiàng)目主頁https://github.com/twbs/bootstrap,點(diǎn)“Fork”就在自己的賬號(hào)下克隆了一個(gè)bootstrap倉庫,然后,從自己的賬號(hào)下clone:

    ??

    ?

    [llg@localhost 桌面]$ git clone git@github.com:llgeill/bootstrap.git 正克隆到 'bootstrap'... remote: Counting objects: 126027, done. remote: Compressing objects: 100% (40/40), done. remote: Total 126027 (delta 44), reused 45 (delta 35), pack-reused 125952 接收對(duì)象中: 100% (126027/126027), 123.12 MiB | 4.97 MiB/s, done. 處理 delta 中: 100% (83420/83420), done.

    ?

    一定要從自己的賬號(hào)下clone倉庫,這樣你才能推送修改。如果從bootstrap的作者的倉庫地址git@github.com:twbs/bootstrap.git克隆,因?yàn)闆]有權(quán)限,你將不能推送修改。

    Bootstrap的官方倉庫twbs/bootstrap、你在GitHub上克隆的倉庫my/bootstrap,以及你自己克隆到本地電腦的倉庫,他們的關(guān)系就像下圖顯示的那樣:

    如果你想修復(fù)bootstrap的一個(gè)bug,或者新增一個(gè)功能,立刻就可以開始干活,干完后,往自己的倉庫推送。

    如果你希望bootstrap的官方庫能接受你的修改,你就可以在GitHub上發(fā)起一個(gè)pull request。當(dāng)然,對(duì)方是否接受你的pull request就不一定了。

    ?

    23.如何使用碼云

    使用GitHub時(shí),國內(nèi)的用戶經(jīng)常遇到的問題是訪問速度太慢,有時(shí)候還會(huì)出現(xiàn)無法連接的情況(原因你懂的)。

    如果我們希望體驗(yàn)Git飛一般的速度,可以使用國內(nèi)的Git托管服務(wù)——碼云(gitee.com)。

    和GitHub相比,碼云也提供免費(fèi)的Git倉庫。此外,還集成了代碼質(zhì)量檢測、項(xiàng)目演示等功能。對(duì)于團(tuán)隊(duì)協(xié)作開發(fā),碼云還提供了項(xiàng)目管理、代碼托管、文檔管理的服務(wù),5人以下小團(tuán)隊(duì)免費(fèi)。

    ?碼云的免費(fèi)版本也提供私有庫功能,只是有5人的成員上限。

    使用碼云和使用GitHub類似,我們?cè)诖a云上注冊(cè)賬號(hào)并登錄后,需要先上傳自己的SSH公鑰。選擇右上角用戶頭像 -> 菜單“修改資料”,然后選擇“SSH公鑰”,填寫一個(gè)便于識(shí)別的標(biāo)題,然后把用戶主目錄下的.ssh/id_rsa.pub文件的內(nèi)容粘貼進(jìn)去:

    ?

    已有本地倉庫關(guān)聯(lián)遠(yuǎn)程倉庫?

    如果我們已經(jīng)有了一個(gè)本地的git倉庫(例如,一個(gè)名為learngit的本地庫),如何把它關(guān)聯(lián)到碼云的遠(yuǎn)程庫上呢?

    首先,我們?cè)诖a云上創(chuàng)建一個(gè)新的項(xiàng)目,選擇右上角用戶頭像 -> 菜單“控制面板”,然后點(diǎn)擊“創(chuàng)建項(xiàng)目”:

    創(chuàng)建遠(yuǎn)程倉庫

    關(guān)聯(lián)遠(yuǎn)程倉庫

    由于剛才已經(jīng)關(guān)聯(lián)了github,如果用同一個(gè)tag orgin的話將會(huì)關(guān)聯(lián)失敗,所以我用了orgins 關(guān)聯(lián)碼云

    ?

    [llg@localhost llg-test-git]$ git remote add origin git@gitee.com:eill/llg-test-git.git fatal: 遠(yuǎn)程 origin 已經(jīng)存在。 [llg@localhost llg-test-git]$ git push -u origin master Username for 'https://github.com': 903857227@qq .com Password for 'https://903857227@qq.com@github.com': 分支 master 設(shè)置為跟蹤來自 origin 的遠(yuǎn)程分支 master。 Everything up-to-date

    這樣一來,我們的本地庫就可以同時(shí)與多個(gè)遠(yuǎn)程庫互相同步:

    刪除關(guān)聯(lián)

    [llg@localhost llg-test-git]$ git remote rm origin [llg@localhost llg-test-git]$ git remote -v origins git@gitee.com:eill/centos-git-gitee-test.git (fetch) origins git@gitee.com:eill/centos-git-gitee-test.git (push)

    碼云也同樣提供了Pull request功能,可以讓其他小伙伴參與到開源項(xiàng)目中來。你可以通過Fork我的倉庫:https://gitee.com/liaoxuefeng/learngit,創(chuàng)建一個(gè)your-gitee-id.txt的文本文件, 寫點(diǎn)自己學(xué)習(xí)Git的心得,然后推送一個(gè)pull request給我,這個(gè)倉庫會(huì)在碼云和GitHub做雙向同步。

    24.自定義Git配置

    在安裝Git一節(jié)中,我們已經(jīng)配置了user.name和user.email,實(shí)際上,Git還有很多可配置項(xiàng)。

    開啟命令行顏色

    比如,讓Git顯示顏色,會(huì)讓命令輸出看起來更醒目

    [llg@localhost llg-test-git]$ git config --global color.ui true

    忽略特殊文件

    有些時(shí)候,你必須把某些文件放到Git工作目錄中,但又不能提交它們,比如保存了數(shù)據(jù)庫密碼的配置文件啦,等等,每次git status都會(huì)顯示Untracked files ...,有強(qiáng)迫癥的童鞋心里肯定不爽。

    好在Git考慮到了大家的感受,這個(gè)問題解決起來也很簡單,在Git工作區(qū)的根目錄下創(chuàng)建一個(gè)特殊的.gitignore文件,然后把要忽略的文件名填進(jìn)去,Git就會(huì)自動(dòng)忽略這些文件。

    不需要從頭寫.gitignore文件,GitHub已經(jīng)為我們準(zhǔn)備了各種配置文件,只需要組合一下就可以使用了。所有配置文件可以直接在線瀏覽:https://github.com/github/gitignore

    忽略文件的原則是:

  • 忽略操作系統(tǒng)自動(dòng)生成的文件,比如縮略圖等;
  • 忽略編譯生成的中間文件、可執(zhí)行文件等,也就是如果一個(gè)文件是通過另一個(gè)文件自動(dòng)生成的,那自動(dòng)生成的文件就沒必要放進(jìn)版本庫,比如Java編譯產(chǎn)生的.class文件;
  • 忽略你自己的帶有敏感信息的配置文件,比如存放口令的配置文件。
  • 舉個(gè)例子:

    假設(shè)你在Windows下進(jìn)行Python開發(fā),Windows會(huì)自動(dòng)在有圖片的目錄下生成隱藏的縮略圖文件,如果有自定義目錄,目錄下就會(huì)有Desktop.ini文件,因此你需要忽略Windows自動(dòng)生成的垃圾文件:

    # Windows: Thumbs.db ehthumbs.db Desktop.ini

    然后,繼續(xù)忽略Python編譯產(chǎn)生的.pyc、.pyo、dist等文件或目錄:

    # Python: *.py[cod] *.so *.egg *.egg-info dist build

    加上你自己定義的文件,最終得到一個(gè)完整的.gitignore文件,內(nèi)容如下:

    # Windows: Thumbs.db ehthumbs.db Desktop.ini# Python: *.py[cod] *.so *.egg *.egg-info dist build# My configurations: db.ini deploy_key_rsa

    最后一步就是把.gitignore也提交到Git,就完成了!當(dāng)然檢驗(yàn).gitignore的標(biāo)準(zhǔn)是git status命令是不是說working directory clean。

    使用Windows的童鞋注意了,如果你在資源管理器里新建一個(gè).gitignore文件,它會(huì)非常弱智地提示你必須輸入文件名,但是在文本編輯器里“保存”或者“另存為”就可以把文件保存為.gitignore了。

    有些時(shí)候,你想添加一個(gè)文件到Git,但發(fā)現(xiàn)添加不了,原因是這個(gè)文件被.gitignore忽略了:

    $ git add App.class The following paths are ignored by one of your .gitignore files: App.class Use -f if you really want to add them.

    如果你確實(shí)想添加該文件,可以用-f強(qiáng)制添加到Git:

    $ git add -f App.class

    或者你發(fā)現(xiàn),可能是.gitignore寫得有問題,需要找出來到底哪個(gè)規(guī)則寫錯(cuò)了,可以用git check-ignore命令檢查:

    $ git check-ignore -v App.class .gitignore:3:*.class App.class

    Git會(huì)告訴我們,.gitignore的第3行規(guī)則忽略了該文件,于是我們就可以知道應(yīng)該修訂哪個(gè)規(guī)則。

    小結(jié)

    • 忽略某些文件時(shí),需要編寫.gitignore;

    • .gitignore文件本身要放到版本庫里,并且可以對(duì).gitignore做版本管理!

    配置別名

    有沒有經(jīng)常敲錯(cuò)命令?比如git status?status這個(gè)單詞真心不好記。

    如果敲git st就表示git status那就簡單多了,當(dāng)然這種偷懶的辦法我們是極力贊成的。

    我們只需要敲一行命令,告訴Git,以后st就表示status(這個(gè)功能在linux上也有)

    [llg@localhost llg-test-git]$ git config --global alias.st status [llg@localhost llg-test-git]$ git st # 位于分支 dev # 尚未暫存以備提交的變更: # (使用 "git add <file>..." 更新要提交的內(nèi)容) # (使用 "git checkout -- <file>..." 丟棄工作區(qū)的改動(dòng)) # # 修改: dele # 修改尚未加入提交(使用 "git add" 和/或 "git commit -a"

    配置文件

    配置Git的時(shí)候,加上--global是針對(duì)當(dāng)前用戶起作用的,如果不加,那只針對(duì)當(dāng)前的倉庫起作用。

    配置文件放哪了?每個(gè)倉庫的Git配置文件都放在.git/config文件中:

    $ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true ignorecase = true precomposeunicode = true [remote "origin"] url = git@github.com:michaelliao/learngit.git fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master [alias] last = log -1

    別名就在[alias]后面,要?jiǎng)h除別名,直接把對(duì)應(yīng)的行刪掉即可。

    而當(dāng)前用戶的Git配置文件放在用戶主目錄下的一個(gè)隱藏文件.gitconfig中:?

    $ cat .gitconfig [alias] co = checkout ci = commit br = branch st = status [user] name = Your Name email = your@email.com 配置別名也可以直接修改這個(gè)文件,如果改錯(cuò)了,可以刪掉文件重新通過命令配置。

    小結(jié)

    給Git配置好別名,就可以輸入命令時(shí)偷個(gè)懶。我們鼓勵(lì)偷懶。

    25.搭建Git服務(wù)器

    在遠(yuǎn)程倉庫一節(jié)中,我們講了遠(yuǎn)程倉庫實(shí)際上和本地倉庫沒啥不同,純粹為了7x24小時(shí)開機(jī)并交換大家的修改。

    GitHub就是一個(gè)免費(fèi)托管開源代碼的遠(yuǎn)程倉庫。但是對(duì)于某些視源代碼如生命的商業(yè)公司來說,既不想公開源代碼,又舍不得給GitHub交保護(hù)費(fèi),那就只能自己搭建一臺(tái)Git服務(wù)器作為私有倉庫使用。

    搭建Git服務(wù)器需要準(zhǔn)備一臺(tái)運(yùn)行Linux的機(jī)器,強(qiáng)烈推薦用Ubuntu或Debian,這樣,通過幾條簡單的apt命令就可以完成安裝。

    假設(shè)你已經(jīng)有sudo權(quán)限的用戶賬號(hào),下面,正式開始安裝。(在這里我使用的是Centos)

    第一步,安裝git

    [llg@localhost llg-test-git]$ sudo yum install git

    第二步,創(chuàng)建一個(gè)git用戶,用來運(yùn)行g(shù)it服務(wù)

    [llg@localhost llg-test-git]$ sudo adduser git

    第三步,創(chuàng)建證書登錄:

    收集所有需要登錄的用戶的公鑰,就是他們自己的id_rsa.pub文件,把所有公鑰導(dǎo)入到/home/git/.ssh/authorized_keys文件里,一行一個(gè)。

    第四步,初始化Git倉庫:

    先選定一個(gè)目錄作為Git倉庫,假定是/srv/sample.git,在/srv目錄下輸入命令:

    [llg@localhost llg-test-git]$ sudo git init --bare sample.git 初始化空的 Git 版本庫于 /home/llg/桌面/llg-test-git/sample.git/

    Git就會(huì)創(chuàng)建一個(gè)裸倉庫,裸倉庫沒有工作區(qū),因?yàn)榉?wù)器上的Git倉庫純粹是為了共享,所以不讓用戶直接登錄到服務(wù)器上去改工作區(qū),并且服務(wù)器上的Git倉庫通常都以.git結(jié)尾。然后,把owner改為git(用戶權(quán)限)

    [llg@localhost llg-test-git]$ sudo chown -R git:git sample.git

    第五步,禁用shell登錄:

    出于安全考慮,第二步創(chuàng)建的git用戶不允許登錄shell,這可以通過編輯/etc/passwd文件完成。找到類似下面的一行:

    git:x:1001:1001:,,,:/home/git:/bin/bash

    改為:

    git:x:1001:1001:,,,:/home/git:/usr/bin/git-shell

    這樣,git用戶可以正常通過ssh使用git,但無法登錄shell,因?yàn)槲覀優(yōu)間it用戶指定的git-shell每次一登錄就自動(dòng)退出。

    第六步,克隆遠(yuǎn)程倉庫:

    現(xiàn)在,可以通過git clone命令克隆遠(yuǎn)程倉庫了,在各自的電腦上運(yùn)行:

    [llg@localhost llg-test-git]$ git clone git@127.0.0.1:/llg-test-git/sample.git/

    剩下的推送就簡單了。

    管理公鑰

    如果團(tuán)隊(duì)很小,把每個(gè)人的公鑰收集起來放到服務(wù)器的/home/git/.ssh/authorized_keys文件里就是可行的。如果團(tuán)隊(duì)有幾百號(hào)人,就沒法這么玩了,這時(shí),可以用Gitosis來管理公鑰。

    這里我們不介紹怎么玩Gitosis了,幾百號(hào)人的團(tuán)隊(duì)基本都在500強(qiáng)了,相信找個(gè)高水平的Linux管理員問題不大。

    管理權(quán)限

    有很多不但視源代碼如生命,而且視員工為竊賊的公司,會(huì)在版本控制系統(tǒng)里設(shè)置一套完善的權(quán)限控制,每個(gè)人是否有讀寫權(quán)限會(huì)精確到每個(gè)分支甚至每個(gè)目錄下。因?yàn)镚it是為Linux源代碼托管而開發(fā)的,所以Git也繼承了開源社區(qū)的精神,不支持權(quán)限控制。不過,因?yàn)镚it支持鉤子(hook),所以,可以在服務(wù)器端編寫一系列腳本來控制提交等操作,達(dá)到權(quán)限控制的目的。Gitolite就是這個(gè)工具。

    這里我們也不介紹Gitolite了,不要把有限的生命浪費(fèi)到權(quán)限斗爭中。

    小結(jié)

    • 搭建Git服務(wù)器非常簡單,通常10分鐘即可完成;

    • 要方便管理公鑰,用Gitosis;

    • 要像SVN那樣變態(tài)地控制權(quán)限,用Gitolite。

    26.總結(jié)

    經(jīng)過兩天的學(xué)習(xí),站在巨人的肩膀上,我把命令都執(zhí)行了一遍,大概有了個(gè)印象。

    Git雖然極其強(qiáng)大,命令繁多,但常用的就那么十來個(gè),掌握好這十幾個(gè)常用命令,你已經(jīng)可以得心應(yīng)手地使用Git了。

    友情附贈(zèng)國外網(wǎng)友制作的Git Cheat Sheet,建議打印出來備用:

    Git Cheat Sheet

    Git的官方網(wǎng)站:http://git-scm.com

    ?

    ?

    ?

    ?

    ?

    ?


    作者:廖雪峰
    鏈接:https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
    來源:廖雪峰的官方網(wǎng)站

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/liliguang/p/9661646.html

    總結(jié)

    以上是生活随笔為你收集整理的分布式版本控制系统Git的安装与使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    黄色av观看 | 欧美日韩国产色综合一二三四 | 大荫蒂欧美视频另类xxxx | 国产成人在线播放 | 91精品999| 日韩二区三区 | 麻豆视频免费在线播放 | 国产精品四虎 | 国产人成一区二区三区影院 | 亚洲一级影院 | 日韩电影在线观看一区二区 | 91亚洲精品乱码久久久久久蜜桃 | 久久夜色精品国产欧美乱极品 | 欧美狠狠色 | 美女视频黄网站 | 97在线视频免费 | 五月婷在线 | 最近更新中文字幕 | 久久avav | 日韩在线理论 | 天天综合成人网 | 国产精品日韩欧美一区二区 | 中文字幕久久精品亚洲乱码 | 狠狠操.com| 欧美一二三区播放 | 美女在线免费视频 | 久久一区二区三区日韩 | 精品一区二区综合 | 三级大片网站 | 久久久久久综合网天天 | 国产欧美久久久精品影院 | 免费又黄又爽视频 | 色婷婷99| 日韩一级电影在线 | 黄色一级网 | 久久久久亚洲精品成人网小说 | 久久国产一二区 | 一区二区三区电影在线播 | 最近中文字幕高清字幕免费mv | av免费线看| 日韩精品在线观看视频 | 五月开心六月婷婷 | 国产视频一区在线播放 | 国产成人精品av久久 | 综合伊人av | 亚洲免费不卡 | 欧美一级特黄aaaaaa大片在线观看 | 国产福利资源 | 中文字幕精品一区 | 免费在线观看一区二区三区 | 日本久久电影 | 国产精品久久久久久久久久久杏吧 | 日日夜夜操av | 五月激情综合婷婷 | 日韩精品久久久久久 | 国产剧情一区 | 亚洲精品一区二区网址 | 国产精品福利一区 | 国产一级精品在线观看 | 亚洲精品短视频 | 久久亚洲精品国产亚洲老地址 | 久久免费毛片视频 | 在线视频精品 | 欧美日韩国产综合一区二区 | 久久久久免费精品视频 | 欧美另类高清 videos | 91x色| 亚洲激情小视频 | 天天操天天爱天天爽 | 中文字幕在线观看一区 | 狠狠躁18三区二区一区ai明星 | 九色精品免费永久在线 | 日韩av线观看 | 午夜久久视频 | 在线天堂中文www视软件 | 免费在线观看亚洲视频 | 日韩一区二区免费播放 | www.五月婷 | 狠狠色丁香婷婷综合欧美 | 国产精品video爽爽爽爽 | 日韩av免费在线电影 | 国产一级片播放 | 欧美日韩不卡在线观看 | 最近日本中文字幕 | 色婷婷综合五月 | 中文字幕的| 日本黄色免费观看 | 欧美狠狠操| 92av视频 | 亚洲精品福利在线 | 色婷婷丁香| 久久久国产网站 | 三级黄色网址 | 最新色站| 久久精品视 | 久久国产免费看 | 五月天开心 | 中文字幕资源在线观看 | 免费在线黄色av | 九九热在线观看视频 | 国产高清绿奴videos | 国产99久久精品一区二区300 | 在线小视频 | 免费看的av片 | 欧美日韩国产精品一区二区亚洲 | 日韩精品一区二区三区免费观看视频 | 国产精品久久久久影院日本 | 国产做aⅴ在线视频播放 | 精品国产_亚洲人成在线 | 婷婷亚洲综合五月天小说 | 2019免费中文字幕 | 久久免费视频一区 | 99久久99久久精品 | 欧美 日韩精品 | 色美女在线 | 日韩精品免费在线观看视频 | 尤物九九久久国产精品的分类 | 日韩视频免费观看高清完整版在线 | 国产日韩欧美中文 | 国产精品免费久久久久 | 国产精品一区免费观看 | 久久免费视频8 | 久久草精品 | 麻豆精品视频在线观看免费 | 欧美视屏一区二区 | 日韩视频1 | 亚洲伊人婷婷 | 开心激情网五月天 | 婷婷在线观看视频 | 国产免费久久 | 婷婷在线视频观看 | 五月丁婷婷| 国内精品视频一区二区三区八戒 | 日韩在线视频网 | 五月天免费网站 | 欧美激情xxxx | 中日韩在线视频 | 久久久免费精品国产一区二区 | 九草在线视频 | 午夜久久福利 | 国产高清免费 | 亚洲免费成人 | 亚洲国产大片 | 国产成人精品一区二区三区 | 天天干天天干天天操 | 日韩精品一区二区久久 | 久久久久成人免费 | 狠狠色狠狠色合久久伊人 | 中文在线免费视频 | 亚洲成av人片在线观看www | av大片免费在线观看 | 深夜福利视频一区二区 | 91视频在线观看下载 | av高清一区二区三区 | 狠狠狠狠狠色综合 | 中文字幕精品在线 | 亚洲一级电影在线观看 | 久久不卡国产精品一区二区 | 成人91在线观看 | 亚洲精品99久久久久久 | 免费在线观看av网址 | 精品99在线 | 亚州精品视频 | 黄网站污| 激情亚洲综合在线 | 伊人色综合网 | 成人av片免费观看app下载 | 国产一区二区电影在线观看 | 日日干夜夜爱 | 国产精品视频在线观看 | 久久国产福利 | 中文在线免费一区三区 | 探花视频在线观看免费 | 成年人视频在线免费播放 | 国产在线观看黄 | 国产精品毛片一区二区在线 | 色悠悠久久综合 | 亚洲成人国产 | 亚洲性少妇性猛交wwww乱大交 | 91男人影院| 免费大片av | 国产午夜三级一二三区 | 精品播放 | 国产精品久久久久久久久久久杏吧 | 国产一级二级在线播放 | 日韩电影一区二区三区在线观看 | 免费在线电影网址大全 | 日韩欧美视频一区二区三区 | zzijzzij亚洲成熟少妇 | 91视频久久久久 | 亚洲最大在线视频 | 午夜视频在线观看一区二区三区 | 亚洲视频每日更新 | 国产在线观看国语版免费 | 美女视频黄免费 | av在线免费播放 | 亚洲午夜精 | 激情五月六月婷婷 | 亚洲免费av网站 | 中国精品一区二区 | 欧美日韩精品区 | 久久久国产一区二区三区四区小说 | 综合久久久久 | 国产精品一区二区精品视频免费看 | 久久人人爽人人 | 国产又黄又硬又爽 | 亚洲视频www | 国产色视频| 伊人黄色网 | www.亚洲视频.com | 黄色av高清| 午夜色场 | 成人91视频| 色综合天天色 | .国产精品成人自产拍在线观看6 | 亚洲 成人 欧美 | 欧美精品在线一区二区 | 亚洲精品福利在线观看 | 国产黄大片在线观看 | 久久深夜 | 成年人免费在线观看网站 | 国产 中文 日韩 欧美 | 亚洲精品乱码久久久久久写真 | 免费色视频在线 | 欧美精彩视频 | 97视频在线观看播放 | 黄色大片日本免费大片 | 日本成人a | 国产二区免费视频 | 国产精品久久久久久久久久久不卡 | 国产欧美精品一区aⅴ影院 99视频国产精品免费观看 | 欧美日韩亚洲在线 | 国外成人在线视频网站 | 久草在线免 | 日韩精品一区二区三区免费观看 | 开心激情婷婷 | 亚洲成人在线免费 | 四虎国产精品成人免费4hu | 综合成人在线 | 欧美少妇xxxxxx| av色网站| 激情图片久久 | 久久国产亚洲 | 爱爱av网 | 日韩在线播放欧美字幕 | 91av视频导航 | 亚洲片在线资源 | 久久y| 少妇bbbb揉bbbb日本 | 国精产品一二三线999 | 91成人网在线播放 | 精品国产区在线 | 色视频成人在线观看免 | 免费在线日韩 | 97色在线观看免费视频 | 在线观看午夜 | 97视频中文字幕 | 成人黄色在线 | 丁香婷婷综合激情 | 欧美另类视频 | 99欧美精品 | 97在线视 | 久久综合九色欧美综合狠狠 | 91精品国产乱码久久 | 黄色91在线观看 | 在线免费黄网站 | 美女视频免费一区二区 | 91精品国产91久久久久 | 西西444www| 天堂资源在线观看视频 | 久草在线资源观看 | 高清视频一区二区三区 | 天天爱天天操天天射 | 精品久久精品久久 | 一区二区 久久 | 天天操天天操天天操天天操天天操天天操 | 国产精品久久网站 | 亚洲一区二区三区在线看 | 美女福利视频网 | 97在线观看免费高清 | 高清中文字幕av | 中文字幕在线视频网站 | 国产一卡二卡在线 | 992tv人人草| 伊在线视频 | 欧美一区在线看 | 99爱视频在线观看 | 在线天堂中文www视软件 | 国产黄影院色大全免费 | 成人免费观看在线视频 | 国产亚洲午夜高清国产拍精品 | av女优中文字幕在线观看 | av丝袜在线 | 黄色一级大片在线观看 | 久久免费激情视频 | 成人免费xxxxxx视频 | 国产成人久久精品77777 | 菠萝菠萝蜜在线播放 | 成人免费一级片 | 在线视频手机国产 | 精品国产免费av | 国产码电影| 在线免费观看的av | 九九精品视频在线观看 | 久草在线免费看视频 | 日日夜夜添 | 免费在线播放 | 亚洲电影久久 | 亚洲欧洲国产精品 | 国产特级毛片aaaaaa高清 | 偷拍精偷拍精品欧洲亚洲网站 | 五月激情姐姐 | 欧美视频日韩视频 | 视频在线观看一区 | av中文字幕在线看 | 国产精品麻豆果冻传媒在线播放 | 国产成人99久久亚洲综合精品 | 精品视频97| 成人免费av电影 | 最近日本韩国中文字幕 | 少妇激情久久 | 99av国产精品欲麻豆 | 国产一区二区在线播放 | 中文字幕91在线 | 日韩三级视频在线观看 | 日日摸日日碰 | 中文字幕有码在线播放 | 国产在线观看地址 | 国产精品区免费视频 | 免费在线国产视频 | www.夜夜操.com | 日韩欧美成| 五月天综合色激情 | 国产精品久久久久久久久费观看 | 涩av在线| 最新日韩在线观看 | 干干夜夜 | 精品国产1区2区3区 国产欧美精品在线观看 | 精品一区久久 | 激情网在线视频 | 久久久久久国产精品久久 | 免费福利在线播放 | 超薄丝袜一二三区 | 精品久久一二三区 | 国产精品99久久久久久久久久久久 | av高清一区二区三区 | 女人18毛片a级毛片一区二区 | 亚洲精品xxx | 国产精品18久久久久久久网站 | 99视频在线看 | 日韩精品短视频 | 中文字幕在线观看免费高清完整版 | 日本高清久久久 | 日韩三级免费观看 | 日韩国产精品久久久久久亚洲 | 中文字幕日韩国产 | 婷婷网五月天 | 一区二区视频免费在线观看 | 激情综合五月天 | 久久成人在线 | 伊人黄色网 | 久久精品播放 | 中文字幕精品一区二区三区电影 | 91麻豆国产福利在线观看 | 国精产品一二三线999 | 黄色一级大片在线免费看产 | 国产日韩欧美在线一区 | 五月天综合激情 | 日韩在线视频在线观看 | 国产精品99久久久久的智能播放 | 日日草天天干 | 日韩精品一区二区三区在线播放 | 狠狠操狠狠干2017 | 97天天综合网| 日韩久久久久久久久 | 久草在线 | 国产美女免费 | 天天天色综合a | 又黄又刺激的视频 | 久久国产99 | 亚洲精品国产品国语在线 | 国产精品久久久av | 99久久99久久综合 | 国产剧情av在线播放 | 亚洲涩涩网 | 国产精品久久久一区二区 | 亚洲精品在线观看视频 | 久久久久99精品成人片三人毛片 | 国内精品久久久久影院一蜜桃 | 天天操天天插 | 国产一区二区久久久久 | 96香蕉视频| 99久久夜色精品国产亚洲96 | 狠狠做六月爱婷婷综合aⅴ 日本高清免费中文字幕 | 日韩精品视频免费看 | 成人欧美日韩国产 | 亚洲.www | 亚洲精品999 | 中文字幕乱在线伦视频中文字幕乱码在线 | 日韩高清在线一区二区三区 | 久草精品在线 | 日韩超碰 | 日韩中文字幕亚洲一区二区va在线 | 日韩电影在线观看一区 | 久久精品日产第一区二区三区乱码 | 国产精品高清在线观看 | 成人免费一级 | 久久久黄视频 | 精品99视频 | 久久综合九色欧美综合狠狠 | 99热国产精品 | 人人澡人人模 | 成人羞羞视频在线观看免费 | 国产精品一区二区在线 | av黄色在线播放 | 久久福利电影 | 天干啦夜天干天干在线线 | 免费观看黄色12片一级视频 | 婷婷丁香自拍 | 亚洲一级黄色大片 | 99亚洲精品在线 | 99一区二区三区 | 91桃色在线播放 | 99久热 | 亚洲日韩中文字幕在线播放 | 一级片免费观看 | 国产二区精品 | 国产精品亚 | www五月天com| 国产丝袜高跟 | 日韩精品一区二区三区视频播放 | 中文区中文字幕免费看 | 色婷婷丁香 | 在线观看视频你懂得 | 国产精品国产亚洲精品看不卡 | 免费在线看v | 国产精品美女久久久久久久久久久 | 国产三级精品三级在线观看 | 久草国产视频 | 美女黄频在线观看 | 狠狠躁夜夜躁人人爽超碰91 | 欧美伦理一区二区三区 | 亚洲精品成人在线 | 日色在线视频 | 97视频在线看 | av成年人电影 | 成人av片免费观看app下载 | 五月的婷婷 | 丁香影院在线 | 国产精品九九九 | 成人性生交大片免费观看网站 | 四虎影视成人精品国库在线观看 | 亚洲精品国产精品国自产观看浪潮 | 国产欧美久久久精品影院 | 激情综合狠狠 | 91九色视频国产 | 国产中文字幕在线视频 | 人人爽人人爽人人 | 久久成 | 国产一区视频免费在线观看 | 婷婷激情站 | 最近高清中文在线字幕在线观看 | 黄色网大全 | 亚洲精品视频观看 | 免费成人av电影 | 99av国产精品欲麻豆 | 日韩在线一二三区 | 激情六月婷婷久久 | www.com黄色| 视频一区二区精品 | 天天艹天天操 | 看片一区二区三区 | 精品国产电影 | 日本高清中文字幕有码在线 | 在线天堂亚洲 | 亚洲乱码国产乱码精品天美传媒 | 在线视频亚洲 | 精品日韩av| 精品不卡视频 | 一区二区三区视频 | 在线观看中文 | 精品黄色在线观看 | av一区二区三区在线播放 | 天天干,天天射,天天操,天天摸 | 中文字幕精 | 草久视频在线 | 六月丁香在线视频 | 国产精品一区二区中文字幕 | 久久精品99国产国产 | 久操操 | 成人91av | www.日日操.com| 国产精品视频在线观看 | 国产无吗一区二区三区在线欢 | 999国产 | 国产精品久久久久久吹潮天美传媒 | 国产日韩视频在线 | 国产麻豆精品一区 | 视频在线观看入口黄最新永久免费国产 | 成人av片免费观看app下载 | 精品久久综合 | 色综合久久中文字幕综合网 | 中文在线字幕免费观 | 在线免费观看欧美日韩 | 国产精品综合久久 | 国产成人一区二区三区电影 | 久久久久电影网站 | 99免费国产 | 色噜噜在线观看视频 | 天堂网一区二区 | 色婷婷综合成人av | 欧美性极品xxxx做受 | 婷婷丁香国产 | 国产精品亚州 | 久久国产精品免费视频 | 99久久99久久精品免费 | 国产一级黄 | 日韩免费视频一区二区 | 亚洲精品视频在线观看免费视频 | 日韩免费观看av | 国产又粗又猛又色又黄视频 | 综合色亚洲| 欧美极品在线播放 | 亚洲欧洲av| 国产亚洲一区 | 久久99久久久久久 | 日韩免费精品 | 精品亚洲成人 | 亚洲国产精品资源 | 国产精品日韩在线观看 | 亚洲97在线| av不卡免费看 | 国产一级片免费视频 | 精品国产亚洲日本 | 97超碰成人在线 | 国产在线一线 | 日韩视频欧美视频 | 最新久久久 | 四虎国产精品免费观看视频优播 | 992tv人人草 黄色国产区 | 日韩午夜在线播放 | 99久国产| 五月色综合 | 中文字幕永久免费 | 日韩资源在线 | 久久久久久毛片精品免费不卡 | 久久久久久久精 | 福利一区视频 | 成人一级免费电影 | 96av视频| 久久人人爽人人人人片 | 美女搞黄国产视频网站 | 香蕉影视app | 91九色视频在线观看 | 97超视频 | 99精品系列 | 91桃色免费观看 | 干 操 插| 日韩欧美在线不卡 | 久免费 | 丁香色天天 | 狠狠搞,com| 成人av中文字幕在线观看 | 国产精品18久久久久vr手机版特色 | 五月婷婷丁香激情 | 人人爽人人射 | 97超碰总站 | 人人插人人干 | 最近中文字幕大全 | 99免费国产| 在线观看国产区 | 亚洲黄色一级电影 | 亚洲视频国产 | 国产黄色视 | 中文字幕资源在线观看 | 久久综合免费视频影院 | 91自拍91| 激情综合网在线观看 | 国产精品二区在线观看 | 欧美午夜理伦三级在线观看 | 黄色免费网站下载 | 在线免费观看麻豆视频 | 国偷自产中文字幕亚洲手机在线 | 欧美精品生活片 | 久久久午夜影院 | 久久亚洲日本 | 欧美黄色高清 | 亚洲伊人网在线观看 | 欧美精品天堂 | 99久久婷婷国产综合精品 | 五月天久久婷 | 亚洲 欧美 综合 在线 精品 | www免费看 | 九九热视频在线免费观看 | 亚洲成人资源 | 99久久精品免费看国产免费软件 | 一区二区精品在线 | 国产精品视频免费观看 | aaaaaa毛片| 少妇18xxxx性xxxx片 | 亚洲影院一区 | 成片免费观看视频999 | 国产麻豆视频免费观看 | 天天摸天天操天天爽 | 就要干b| 国产精品久久久久久久久久免费 | 天天操天天色天天 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 久久天天躁 | 99精品一区二区三区 | 成人av资源站 | 不卡精品 | 天天天天射 | 久久99国产精品免费 | 国产精品免费在线 | 91理论片午午伦夜理片久久 | 欧美日韩中字 | 日韩欧美高清一区二区三区 | 九九在线高清精品视频 | 一本一本久久a久久精品综合妖精 | 九九99靖品 | 91最新在线观看 | 伊人导航 | 在线 你懂| 欧美激情视频一二三区 | 久久精品国产一区二区三 | 欧美日韩视频在线播放 | 婷婷六月中文字幕 | 免费在线观看国产黄 | 免费一级特黄录像 | 在线色网站 | 97人人模人人爽人人喊网 | 97在线超碰 | 99re热精品视频 | 国内精品视频在线 | 最近中文字幕在线 | 欧美先锋影音 | 亚洲综合色网站 | 亚洲天堂网视频在线观看 | 日韩av播放在线 | 久久久观看 | 国产在线精品二区 | 色婷婷综合久久久久 | 8x成人免费视频 | 蜜臀aⅴ国产精品久久久国产 | av高清影院 | 久久精品视频日本 | 在线观看aa | 国产精品毛片久久久久久久 | 国产日本亚洲 | 国产一级二级在线 | 欧美日韩1区 | 亚洲一区网站 | 国内小视频在线观看 | 91在线视频免费91 | 天天操天天射天天 | 91精品视频在线看 | 999久久久免费视频 午夜国产在线观看 | 成人av在线直播 | 亚洲三级影院 | 国产精品高潮在线观看 | 五月婷婷综合网 | 国产成人无码AⅤ片在线观 日韩av不卡在线 | 国产福利不卡视频 | 日韩免费成人 | 国产伦理一区 | 亚洲激情五月 | 香蕉97视频观看在线观看 | 国产裸体视频网站 | 日韩欧美国产激情在线播放 | 天天草av| 手机看片国产 | 一级a毛片高清视频 | 色婷婷婷 | 精品一区二区免费在线观看 | 国产 日韩 欧美 自拍 | 亚洲一级理论片 | 精品视频中文字幕 | 日韩专区在线观看 | 久久人操 | 中文字幕资源网在线观看 | 69av国产| 亚洲精品高清在线 | 91免费观看网站 | 久久久久久不卡 | 国产视频欧美视频 | 国产精品久久婷婷六月丁香 | 亚洲精品视频在 | 国产精品久久网站 | 久久国产精品99久久久久久进口 | 日韩一区二区三区不卡 | 可以免费观看的av片 | 久久久精品国产免费观看一区二区 | 国产精品久久久久永久免费 | 97在线精品 | 免费看黄的视频 | 99免在线观看免费视频高清 | 91最新国产 | 99久久精品电影 | 久久中文视频 | 国产中文字幕91 | 日本久久中文字幕 | 免费观看一级成人毛片 | 麻花天美星空视频 | av日韩在线网站 | 丝袜美腿av| 国产91影院 | 欧美精品一区二区三区一线天视频 | 免费网站观看www在线观看 | 九九热视频在线播放 | 国产日产在线观看 | 综合色狠狠 | 中文字幕在线观看日本 | 欧美精品久久久久久久久久白贞 | 午夜久操 | 国产在线播放一区 | 中文字幕免费高清 | 国产黄色精品在线观看 | 一区二区三区免费在线观看视频 | 精品国产亚洲一区二区麻豆 | 亚洲国产综合在线 | 精品伊人久久久 | 97在线视频网站 | 欧美日韩高清在线一区 | 中国一区二区视频 | 超碰人在线 | 成人在线免费看视频 | 亚洲高清视频在线播放 | 在线观看久| 特级xxxxx欧美 | 成年人视频在线 | 日本韩国欧美在线观看 | 国产精品国产三级国产不产一地 | 亚洲精品国产精品乱码在线观看 | 国产亚洲视频系列 | 99热国产在线观看 | 欧美日本在线视频 | 久久久免费视频播放 | 亚洲精品久久久久999中文字幕 | 亚洲免费观看在线视频 | 日本午夜免费福利视频 | 爱情影院aqdy鲁丝片二区 | 美女视频黄免费的久久 | 日韩在线视频在线观看 | 国产精品9区 | 在线视频 你懂得 | 啪啪免费视频网站 | 国产精品大片免费观看 | 丁香在线观看完整电影视频 | 激情久久久久久久久久久久久久久久 | 欧美在线观看小视频 | 91成人精品国产刺激国语对白 | 国产精品欧美日韩 | 一区二区三区在线观看 | 国产中文字幕精品 | 天天爽夜夜爽人人爽曰av | 日韩亚洲欧美中文字幕 | 日韩av偷拍 | 久草在线免费在线观看 | 亚洲专区在线播放 | 国产一区在线不卡 | 欧美a级在线播放 | 久久久www免费电影网 | 国色天香永久免费 | 成年人国产在线观看 | 欧美日本在线观看视频 | 亚洲精品视频网 | 69视频国产 | 香蕉视频国产在线 | 奇米影视8888 | 国产精品6| 亚洲国产色一区 | 中文字幕精品一区 | 国产一区二区高清视频 | 草久在线观看视频 | 天天操天天射天天爽 | 欧美性黄网官网 | 国产一区高清在线观看 | 国产亚洲精品久久久久久电影 | 久久xx视频 | 97超碰在线免费 | 成人av中文字幕在线观看 | 日韩网站一区二区 | 欧洲亚洲国产视频 | 精品999在线| 91在线看免费 | 亚洲黄a | 成人理论电影 | 日日碰狠狠添天天爽超碰97久久 | 青草视频免费观看 | 午夜精品福利一区二区 | av中文字幕网| 色九九在线 | 亚洲欧美成aⅴ人在线观看 四虎在线观看 | 国产精品免费久久久久久久久久中文 | 久草在线综合网 | 欧美久久久久久久久中文字幕 | 中文字幕日韩无 | 香蕉97视频观看在线观看 | 欧美成人tv | 国产精品ⅴa有声小说 | 久久综合成人 | 国产精品日韩 | 狠狠的操你 | 久久er99热精品一区二区 | 黄色小说免费在线观看 | 国产91精品高清一区二区三区 | 国产不卡精品 | 国产高清在线a视频大全 | 国产高清在线观看 | 在线观看中文字幕dvd播放 | 欧美精品xx| 日韩精品久久一区二区三区 | 成年美女黄网站色大片免费看 | 免费看片网站91 | 久久少妇免费视频 | 国产亚洲精品久久久久久久久久久久 | 午夜成人免费影院 | 久久精品99国产精品日本 | 波多野结衣网址 | 国产精品网站一区二区三区 | 日本三级不卡视频 | 天天综合网在线 | 亚洲精品视 | 亚洲欧美日韩在线一区二区 | 久久免费在线视频 | 亚洲国产精品一区二区久久hs | 国产午夜精品一区 | 在线播放第一页 | 成人久久影院 | 国产精品夜夜夜一区二区三区尤 | 亚洲国产精品女人久久久 | 日日夜夜天天射 | 97影视| 久久色在线播放 | 日韩中文在线观看 | 亚洲精品免费看 | 一区二区电影在线观看 | 天堂av在线网址 | 亚州精品在线视频 | 久久99爱视频 | 天天做综合网 | 美女国产精品 | 日韩欧美国产激情在线播放 | 深爱激情综合网 | 欧美91视频 | 日韩欧美视频免费看 | 日本 在线 视频 中文 有码 | 国内精品小视频 | 天天操天天曰 | 丁香六月综合网 | 五月婷婷伊人网 | 一级黄色免费 | 久久99精品国产99久久6尤 | 九九精品无码 | 激情五月婷婷激情 | 亚洲天堂网在线视频 | 69av视频在线| 久久久九色精品国产一区二区三区 | 香蕉在线视频观看 | 国产精品手机在线播放 | 又粗又长又大又爽又黄少妇毛片 | 亚洲精品18日本一区app | 在线观看免费av网站 | 在线亚洲欧美日韩 | 久久久国产99久久国产一 | 在线 视频 一区二区 | 欧美韩日在线 | 日本久久片 | 久久一级电影 | 黄色av一区 | 亚洲欧美日韩一二三区 | 欧美色噜噜噜 | www.久草.com | 国产18精品乱码免费看 | 欧美色图另类 | 欧美精品久久久久久 | 一区二区三区精品在线视频 | 黄色片亚洲| 黄色视屏免费在线观看 | 在线色亚洲 | 久久99热这里只有精品国产 | 中文字幕在线乱 | 日韩av手机在线看 | 91系列在线 | 成人免费观看视频大全 | 操久 | 中文字幕影片免费在线观看 | 一级黄色在线视频 | 国产美女在线观看 | 久久久夜色 | 天天干,狠狠干 | 人人干97| 精品理论片| 99视频免费在线观看 | 免费a v视频| 四虎影视成人精品 | a级片在线播放 | 国产一区二区在线播放视频 | 成人精品一区二区三区电影免费 | 在线免费观看涩涩 | 亚洲伦理电影在线 | av一级网站| 男女全黄一级一级高潮免费看 | 亚洲精品白浆高清久久久久久 | 五月天综合激情网 | 免费视频网| 97精品一区二区三区 | 国产无区一区二区三麻豆 | 97综合在线 | 亚洲精品一区二区三区四区高清 | 久久精品影视 | 国产视频精选 | 超碰免费av| 国产精品系列在线播放 | 亚洲欧美综合精品久久成人 | 亚洲在线成人精品 | 91在线日韩 | 天天干天天弄 | 亚洲视频在线观看免费 | 国产精品k频道 | 国精产品满18岁在线 | 日韩va欧美va亚洲va久久 | 日本黄色免费播放 | 又黄又爽的免费高潮视频 | 91精品视频在线观看免费 | 色资源网免费观看视频 | 亚洲精品视 | 一区二区三区av在线 | 日韩欧美在线第一页 | 国产精品高潮久久av | av东方在线| 97在线公开视频 | 我爱av激情网 | 亚洲天天在线日亚洲洲精 | 黄色免费大片 | 国产欧美日韩一区 | .国产精品成人自产拍在线观看6 | 亚洲精品456在线播放 | 亚洲 欧美 国产 va在线影院 | 在线观看国产区 | 亚洲区精品 | 久久激情影院 | 日韩色综合网 | 91黄色视屏| 欧美性精品 | 丁香久久久 | 国产91勾搭技师精品 | 亚洲永久在线 | 久久久久国产精品厨房 | 国精产品999国精产 久久久久 | 一级黄色在线免费观看 | 国产视频欧美视频 | 成人免费一区二区三区在线观看 | 久久久免费看视频 | 国内精品国产三级国产aⅴ久 | 国产91精品看黄网站 | 亚洲精品色视频 | 999超碰| 中文字幕在线看视频国产 | 在线看福利av | 麻豆久久精品 | 国产精品成人在线观看 | 国产午夜精品一区二区三区四区 | 美女久久网站 | 日韩欧美在线高清 | 又爽又黄又无遮挡网站动态图 | 91视频在线看 | 国模一区二区三区四区 | 成人午夜久久 | a午夜在线| 欧美激情精品 | 探花视频免费观看 | 日韩电影一区二区在线 | 日韩三级在线观看 | 国产999精品久久久影片官网 | 麻豆成人精品视频 | 久久国产精品免费视频 | 精品国产伦一区二区三区观看体验 | 91成人在线免费观看 | 欧美日韩一区二区免费在线观看 | 中文字幕乱码在线播放 | 九热在线| 国产999精品久久久久久麻豆 | 国产精品99久久久久的智能播放 | 国产日韩在线播放 | 99久久精品费精品 | av在线激情 | 国产精品婷婷午夜在线观看 | 久久免费美女视频 | 国产午夜精品一区二区三区 | 亚洲精欧美一区二区精品 | 日韩高清一区在线 | 人人超碰免费 | 婷婷激情欧美 | 久久国内精品99久久6app | 久久久久国产精品视频 | 最近中文字幕完整视频高清1 |