緊接上篇,今天從實在操做方面說一下GIT使用中,使用最多的流程-提交到倉庫。開始說明提交流程以前,能夠先去看一下上篇提到的GIT總體架構圖。本章說的內容是上面這張圖的前面部分,以下:git
只有提交本地倉庫的流程,並無涉及到遠程倉庫。關於提交流程,經常使用的命令:add和commit,add負責提交到暫存區,commit提交到倉庫。但並非只有這兩個命令就足夠了。github
在開始以前,咱們先須要作一些初始化工做。centos
操做系統:centos7 GIT版本: 1.8.3.1。bash
提交git倉庫,須要作兩個基本的配置操做:架構
$ git config --global user.name poloxue
$ git config --global user.email poloxue123@163.com
複製代碼
配置姓名與郵箱地址。關於git配置還有不少內容,本章內容重點不在於此,就不做過多詳解。svn
首先咱們須要一個git倉庫,兩個命令能夠實現: init 和 clone。 git init,是經過初始化本地目錄的方式建立倉庫。 首先,建立一個測試的文件夾。執行初始化操做,查看文件夾變化,以下:post
$ mkdir experiment
$ cd experiment/
$ git init
複製代碼
初始化空的 Git 版本庫於 /home/vagrant/work/git/experiment/.git/測試
$ ls -a
. .. .git
複製代碼
文件夾下多出了一個.git的文件,上面一節對.git有過簡單說明。咱們的暫存區和本地倉庫就是存在於這個文件下面。ui
git clone,經過遠程克隆方式獲取版本庫。本人剛開始使用git的時候,覺得git像svn同樣須要依賴遠程,獲取倉庫首先想到的是去github上面clone。centos7
clone的使用很簡單,咱們經過克隆goquery的源碼來演示,以下:
$ git clone https://github.com/PuerkitoBio/goquery.git
Cloning into 'goquery'...
remote: Enumerating objects: 8, done.
remote: Counting objects: 100% (8/8), done.
remote: Compressing objects: 100% (6/6), done.
remote: Total 1212 (delta 2), reused 8 (delta 2), pack-reused 1204
Receiving objects: 100% (1212/1212), 434.03 KiB | 49.00 KiB/s, done.
Resolving deltas: 100% (697/697), done.
Checking connectivity... done.
$ ls -a
. bench_array_test.go expand.go property.go
.. bench_example_test.go expand_test.go property_test.go
.git bench_expand_test.go filter.go query.go
.gitattributes bench_filter_test.go filter_test.go query_test.go
.gitignore bench_iteration_test.go go.mod testdata
.travis.yml bench_property_test.go go.sum traversal.go
LICENSE bench_query_test.go iteration.go traversal_test.go
README.md bench_traversal_test.go iteration_test.go type.go
array.go doc manipulation.go type_test.go
array_test.go doc.go manipulation_test.go utilities.go
bench example_test.go misc utilities_test.go
複製代碼
從文件生命週期看提交流程,首先一個文件在整個生命週期可能存在哪些狀態,以下:
仍是先動手畫個圖,以下:
上面的圖以文件狀態的角度出發,指出了一個文件從建立到提交文件倉庫再到脫離倉庫追蹤的整個過程可能經歷的各類狀態。
在開始正文以前先介紹一下GIT查看倉庫中文件狀態的命令:git status。若是倉庫文件有所變化,執行此命令能夠查看各個變化文件狀態。
在工做目錄下新建立的一個文件初始狀態處於未追蹤。此時文件不受版本系統的控制。 下面在咱們以前初始化爲git倉庫的experiment的工做目錄,新建一個README.md。而後隨意輸入一些內容。使用git status查看一下當前倉庫狀態,以下:
$ touch "experiment" >> README.md
$ git status
# On branch master
#
# Initial commit
#
# Untracked files
# (use "git add <file>..." to include in what will be committed)
#
# README.md
nothing added to commit but untracked files present (use "git add" to track)
複製代碼
此時README.md爲untracked file,下面提示 Use "git add ..." to include in what will be committed,即爲使用git add命令去添加將被提交的文件。彷佛沒有說明怎麼追蹤文件,繼續看,如須要被追蹤 use "git add" to track, 意爲使用git add追蹤文件。
爲了下面的內容更方便講解,先來講說文件的已更新狀態。啥叫已更新呢?我的總結,上圖中把文件的三種狀況都歸於已更新:編輯更新,衝突更新,刪除更新。下面從這三種更新的角度來談談,看看這些更新狀態如何產生。
編輯更新就是因咱們修改文件而致使的更新。下面看下如何產生一個編輯更新狀態的文件。
首先,快速經過如下三步添加一個新文件modify.go到版本庫中。
$ touch modify.go
$ git add modify.go
$ git commit -m "new file modify.go"
複製代碼
下面咱們修改文件modify.go,添加任意內容修改,git status查看狀態:
#
# Changes not staged for commit:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes will working directory)
#
# modified: modify.go
#
# no changes added to commit (use "git add" and/or "git commit -a")
複製代碼
此時能夠看到modify.go文件爲modified狀態。使用git時,大多數更新都是屬於這種類型。
衝突更新是怎麼產生的呢?咱們知道GIT支持強大的分支功能,前面說明GIT的優勢也提到了這個問題。可是分支就會有一個問題,兩個分支同時修改同一文件的同一部份內容,衝突就產生了。下面演示這種類型的更新如何產生?
首先,快速經過如下三步添加一個新文件conflict.go到版本庫中。
$ touch conflict.go
$ git add conflict.go
$ git commit -m "new file conflict.go"
複製代碼
建立兩個分支:feature
$ git branch feature
複製代碼
在master上conflict.go添加內容: master,在feature上conflict.go添加內容: feature。並都提交到倉庫。
在master執行合併操做:
$ git merge feature
Auto-merging conflict.go
CONFLICT (content): Merge conflict in conflict.go
Automatic merge failed; fix conflicts and then commit the result.
複製代碼
能夠看到衝突很容易就產生。團隊合做開發時,衝突更新也是咱們平時最不喜歡遇到的,若是衝突的內容都是本身的,那還好處理。若是涉及了不少人,就會涉及大量的溝通成本。
刪除也算更新,這個邏輯理解起來有點怪。但刪除畢竟改變了文件內容,讓文件不存在了,因此也算更新。這種更新如何產生呢?
首先,快速經過如下三步添加一個新文件delete.go到版本庫中。
$ touch delete.go
$ git add delete.go
$ git commit -m "new file delete.go"
複製代碼
提交以後,手動刪除delete.go文件
$ rm delete.go
複製代碼
此時使用git status查看delete.go文件狀態即是刪除更新的狀態。
在上面的一、2兩段,關於未追蹤和已更新,總結的是工做區文件存在的各類狀態。可是在把文件提交到版本以前,還須要中間的一個過渡階段:暫存區。
文件提交到暫存區即是已暫存狀態。看上面文件各個狀態之間的轉化圖,咱們知道文件能夠由未跟蹤和已更新兩種狀態轉化而來。
由以前的操做,如今已經有了各類狀態的文件:
下面如何使用git add將這些文件添加到暫存區:
當不肯定時,可直接添加某文件git add filepath;
注:評論區有朋友回覆說,他的測試 git add . 會把刪除更新加入暫存區,我分別在 git 1.8.3.1 和 2.9.3 兩個版本測試了下,新版的確和舊版行爲不一樣,會把刪除更新加入到暫存區。
$ git add modify.go;
複製代碼
刪除更新也可使用git rm命令,直接將刪除文件提交到暫存區同時刪除文件,如需刪除提交暫存區但工做區文件保留可以使用選項--cached:
$ git rm delete.go
$ git rm delete.go --cached
複製代碼
好!下面把全部文件提交到暫存區:
$ git add -A
複製代碼
此時,git status查看文件狀態:
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage
#
# renamed: delete.go -> README.md
# modified: conflict.go
# modified: modify.go
# new file: new.go
複製代碼
由於同時存在刪除和新建,delete.go被認爲rename爲README.md,正常狀況工做區文件狀態與暫存區的對應關係以下:
工做區 暫存區
untracked new file
modified modified
both modified modified
deleted deleted
複製代碼
怎麼讓文件轉化爲未更新狀態呢?提交倉庫!咱們已經把全部內容提交暫存,下面能夠藉助於commit命令進行倉庫提交:
提交倉庫的經常使用,執行以下命令:
$ git commit -m "feat: new function"
複製代碼
再查看文件狀態,發現已經沒有內容能夠提交,此時倉庫處於未更新的狀態。
git commit -am "message"
複製代碼
能夠將編輯更新直接從工做區提交倉庫,即跨過暫存區。不支持刪除與衝突更新和新文件的提交。
如提交有誤,支持對當前提交進行修訂。
$ git commit --amend
複製代碼
有什麼做用?可用來修改提交日誌;在提交漏提交文件時,仍保持爲一個提交。
本文主要從GIT文件的生命週期來看整個提交流程。爲了便於理解,本身總結了編輯更新、刪除更新、衝突更新幾個新詞,但願不會形成誤解。