git 入門寶典


本篇教程是按照我自己的組織方式,然后從多篇教程中拼湊出來的,嘎嘎~,真佩服自己的技術! 原本想叫 git 寶典的,結果一查git的命令大全,還有那么多的git命令與功能沒有接觸到,所以...還是謙虛一點...加了一個入門...反正就當做是自己的學習筆記了,大家有興趣的話,可以看看....


目錄:
    git 簡介
    git 安裝
    git的基本構成
    git的基本操作
        基本命令
        vi命令
        創建版本庫
        添加文件
        提交文件
        查看狀態
        查看提交日志
        查看更改對比
        版本回滾
        撤銷操作
        刪除操作
    遠程倉庫
        認識github
        克隆遠程倉庫
        推送與拉取
    分支
        分支的基本概念
        分支的常用命令
              創建分支
              切換分支
              創建並切換分支
              查看分支
              合並分支
              刪除分支
        分支的注意事項
        分支沖突
        多人協作
        bug 分支
    標簽
        標簽的概念
        標簽的常用命令
    自定義
        用戶信息與加密key
        命令語法着色
        文件忽略
        自定義命令
        修改配置文件
        git常見問題


git 簡介##

git是由 Linus 開發的一種“分布式版本控制”軟件,而在此之前,版本控制基本上都是“集中式版本控制”,如:CVS,SVN 等。
下圖可以很好的幫助我們區分這兩者:

'branch'

"集中式版本控制系統"中,版本庫是集中存放在中央服務器中的,開發人員在干活的時候,要先去訪問中央服務器調取項目代碼,然后才能修改,最后再提交到中央服務器中,供別人拉取使用。因此它有一個很大的缺點,那就是必須鏈接到中央服務器才能夠正常工作。

'branch'

相比較“集中式版本控制”,“分布式版本控制” 並沒有真正意義上的中央服務器,而是開發者的每台電腦都可以作為一個中央節點來使用,因此工作時就無需鏈接主機,更不需要在只有有網絡的環境下才能工作,而且分布式版本控制系統的安全性要高很多,因為每個人電腦里都有完整的版本庫,某一個人的電腦壞掉了不要緊,隨便從其他人那里復制一個就可以了。如果集中式版本控制系統的中央服務器要是出了問題,所有人都沒法干活了。

“分布式版本控制”也有中央節點的概念,這是因為在實際使用“分布式版本控制系統”的時候,其實很少在兩人之間的電腦上推送版本庫的修改,因為可能你們倆不在一個局域網內,兩台電腦互相訪問不了,也可能今天你的同事病了,他的電腦壓根沒有開機。因此,分布式版本控制系統通常也有一台充當“中央服務器”的電腦,但這個服務器的作用僅僅是用來方便“交換”大家的修改,沒有它大家也一樣干活,只是交換修改不方便而已。

git 安裝

git的安裝很簡單,只需要下載git的程序安裝包,安裝好后即可,如果你是window系統,可以直接在自帶的gitbash中執行相應的git命令,gitbash 默認便有相應的語法着色,如果你是mac系統,則在自己的終端中執行git命令,這里我推薦通過配置的方式設置git的語法作色,可以參考最后一章“自定義”。

Git Download>>>

git的基本構成##

git的整體框架主要由兩部分組成,它們分別是“工作區”和“版本庫”。“工作區”就是我們本地的工作目錄,而版本庫則是我們通過 git init 命令創建的git倉庫。
“版本庫”用於監控文件的更改狀態。它又有兩個主要的部分構成,它們分別是:“暫存區”與“分支”,“暫存區”中保存的就是本地進行修改后等待提交的文件,而分支則是用於記錄已經提交但是等待推送的文件。git默認的分支只有一個,那就是 master分支,但是git也支持多個分支,並且分支之間可以切換,可以合並。而 HEAD 便是分支的索引標識,類似於一個指針,用於確定當前活動的分支。

'branch'

總的來說在git中發布一個版本,必須要經過以下幾個步驟:

1. 在工作區中新建,編輯,保存文件。
2. 將編輯好的文件,添加至暫存區緩存
3. 確認無誤后,將暫存區中的文件提交到分支中,等待推送。
4. 發布版本后,將本地倉庫的文件推送至遠程,以供別人拉取使用。

而在沒有推送之前,這個文件的修改在“工作區”與“版本庫”之間是可以相互重置撤銷的。

git的基本操作##

基本命令

下面是我們通過命令行工具來進行本地目錄與文件操作的常用命令。

命令 功能
cd 進入到指定的目錄。eg: cd d:/work/test
dir 列表化顯示目錄與文件。
ls 列表化顯示目錄與文件,但 win-cmd不支持
ls -a 列表化顯示目錄與文件包括隱藏文件,但 win-cmd不支持
mkdir 創建一個目錄。eg:mkdir dirName
touch 創建一個空的文件。eg:touch fileName.txt
vi 使用內置vi編輯器來編輯文件。eg:vi fileName.txt
rm 刪除文件。eg: rm fileName.txt
rm 刪除目錄。eg: rm -rf dirName
cat 查看文件內容。eg: cat fileName.txt
mv 移動文件或目錄。eg: mv a.txt ../
find 搜索當前目錄下的文件。eg: find *.txt
pwd 顯示當前目錄的路徑。

vi命令

vi是Unix及Linux系統下標准的編輯器,由美國加州大學伯克利分校的Bill Joy所創立。
我們可以在支持 vi 編輯器的命令行工具中,直接調用vi來編輯文件。
vi 有兩種狀態是我們經常使用到的,分別是“命令模式”以及“編輯模式”。
vi默認的模式就是命令模式,通過在命令行中輸入命令 a 便可以進入編輯模式,在編輯模式,按下 esc 鍵,再通過 shift+;(這里以window系統為例) 組合鍵,便又可返回命令模式。
下面是vi常用的命令:

命令 功能
a 進入編輯模式
q 退出vi編輯器
q! 強制退出vi編輯器
w 保存文件
wq 保存並退出
wq filename 保存文件退出並命名文件名稱
yyp 復制光標所在的行再插入到下一行
dd 刪除光標所在的行
u 返回上一次操作
set number 在編輯器中顯示行號
set nonumber 在編輯器中隱藏行號
h 左移一個字符
l 右移一個字符
j 上移一行
k 下移一行

創建版本庫###

什么是版本庫呢?版本庫又名倉庫,英文名repository,你可以簡單理解成一個目錄,這個目錄里面的所有文件都可以被Git管理起來,每個文件的修改、刪除,Git都能跟蹤,以便任何時刻都可以追蹤歷史,或者在將來某個時刻可以“還原”。
git創建版本庫非常簡單,首先選擇一個目錄,然后執行以下命令即可。

Administrator@LS1412PC0008 MINGW64 /
$ cd d:/work/

Administrator@LS1412PC0008 MINGW64 /d/work
$ mkdir test

Administrator@LS1412PC0008 MINGW64 /d/work
$ cd test

Administrator@LS1412PC0008 MINGW64 /d/work/test
$ git init
Initialized empty Git repository in D:/work/test/.git/


瞬間Git就把倉庫建好了,而且告訴你是一個空的倉庫(empty Git repository),細心的讀者可以發現當前目錄下多了一個.git的目錄,這個目錄是Git來跟蹤管理版本庫的,沒事千萬不要手動修改這個目錄里面的文件,不然改亂了,就把Git倉庫給破壞了。

如果你沒有看到.git目錄,那是因為這個目錄默認是隱藏的,用 ls -a 命令就可以看見。

另外git倉庫也不是全能的,它只能跟蹤文本文件的改動,比如TXT文件,網頁,所有的程序代碼等等,版本控制系統可以告訴你每次的改動,比如在第5行加了一個單詞“Linux”,在第8行刪了一個單詞“Windows”。而圖片、視頻這些二進制文件,雖然也能由版本控制系統管理,但沒法跟蹤文件的變化,只能把二進制文件每次改動串起來,也就是只知道圖片從100KB改成了120KB,但到底改了啥,版本控制系統不知道,也沒法知道。

不幸的是,Microsoft的Word格式是二進制格式,因此,版本控制系統是沒法跟蹤Word文件的改動的,前面我們舉的例子只是為了演示,如果要真正使用版本控制系統,就要以純文本方式編寫文件,並且強烈推薦文件的編碼為UTF-8。

添加文件

添加文件是指將文件添加至版本庫中的暫存區(stage),而暫存區中存放的內容,便是等待提交的內容。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ touch name.txt

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ vi name.txt

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git add name.txt

如果想一次性的將所有文件都添加至暫存區,可以用以下命令:

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
git add .

提交文件

如果暫存區中的文件確認無誤的話,便可可使用以下命令將內容提交至分支中:

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git commit name.txt -m 'commit name.txt'
[master (root-commit) 0c2dc57] commit name.txt
1 file changed, 1 insertion(+)
create mode 100644 name.txt

其中 -m 是本次提交的注釋內容,這個必須填寫

如果你想將暫存區中的所有內容都提交到分支中,可以這么寫

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git commit -m 'commit all stage'
[master d27ea06] commit all stage
1 file changed, 1 insertion(+), 1 deletion(-)

除此之外,你還可以將 addcommit 結合在一起使用

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git commit -a -m 'add & commit'
[master b602d26] add & commit
1 file changed, 1 insertion(+), 1 deletion(-)

查看狀態

git status命令可以列出當前目錄所有還沒有被git管理的文件或者是被git管理且被修改但還未提交(commit)的文件。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   name.txt

如果想看簡明扼要一點的狀態信息,可以加一個 -s 參數

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git status -s
M  name.txt

查看提交日志###

在提交了若干版本之后,想回顧下提交歷史,可以使用 git log 命令查看。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git log
commit b602d2600c2a4f84d427ff2a414a90384e77dfed
Author: guotaoShen <shenguotao@iwgame.com>
Date:   Thu Mar 30 11:00:19 2017 +0800

    add & commit

commit d27ea06b28a91095921ac55b2fb3c1f078e10a9b
Author: guotaoShen <shenguotao@iwgame.com>
Date:   Thu Mar 30 10:58:56 2017 +0800

    commit all stage

commit 0c2dc5716fc3b1ba0b8690a91e5dcad5d2b1dd24
Author: guotaoShen <shenguotao@iwgame.com>
Date:   Thu Mar 30 10:56:30 2017 +0800

    commit name.txt

在通過 git log 命令 打印的信息中,我們可以看到,git會按照提交時間去排序歷史記錄,最后一次提交排在最前面,除此之外,你還可以看到關於提交的一些標識,作者,時間,以及提交的說明等信息。

git log命令提供了很多可供自定義提交日志輸出的格式,這里,我就選擇幾個最常用到的

一行顯示提交歷史記錄
通過使用git log命令我們知道,打印出來的提交信息會占據多行,一旦提交次數變多到時候,這必將影響我們瀏覽。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git log --pretty=oneline

b602d2600c2a4f84d427ff2a414a90384e77dfed add & commit
d27ea06b28a91095921ac55b2fb3c1f078e10a9b commit all stage
0c2dc5716fc3b1ba0b8690a91e5dcad5d2b1dd24 commit name.txt

顯示提交文件的更改信息

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git log --pretty=oneline --stat

b602d2600c2a4f84d427ff2a414a90384e77dfed add & commit
 name.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 
d27ea06b28a91095921ac55b2fb3c1f078e10a9b commit all stage
 name.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 
0c2dc5716fc3b1ba0b8690a91e5dcad5d2b1dd24 commit name.txt
 name.txt | 1 +
 1 file changed, 1 insertion(+)

顯示提交文件的更改信息與更改內容

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git log --pretty=oneline -p -2

b602d2600c2a4f84d427ff2a414a90384e77dfed add & commit
diff --git a/name.txt b/name.txt
index 7e94c2b..9e0c614 100644
--- a/name.txt
+++ b/name.txt
@@ -1 +1 @@
-my name is shentao - 123
+my name is shentao - 1234

d27ea06b28a91095921ac55b2fb3c1f078e10a9b commit all stage
diff --git a/name.txt b/name.txt
index d137a88..7e94c2b 100644
--- a/name.txt
+++ b/name.txt
@@ -1 +1 @@
-my name is shentao - 12
+my name is shentao - 123

其中 -2 可以指定只顯示前兩條的提交信息,這個參數很實用,比如:

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git log --pretty=oneline -1
b602d2600c2a4f84d427ff2a414a90384e77dfed add & commit

查看更改對比

如果我們想比較一個文件在工作區與暫存區的更改狀態,我們可以使用 git diff 命令。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git diff name.txt

diff --git a/name.txt b/name.txt
index 465f661..d48e0e5 100644
--- a/name.txt
+++ b/name.txt
@@ -1,3 +1,4 @@
 my name is shentao - 12345
 new add line
 new add line 2
+new add line 3

如果想查看該文件在暫存區與分支中的更改對比,可以通過附加 --cached 實現

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git diff --cached
diff --git a/name.txt b/name.txt
index 8535cbf..465f661 100644
--- a/name.txt
+++ b/name.txt
@@ -1,2 +1,3 @@
 my name is shentao - 12345
 new add line
+new add line 2

若是想直接查看工作區與分支的對比狀態,則可以附加 HEAD 參數。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git diff HEAD
diff --git a/name.txt b/name.txt
index 8535cbf..d48e0e5 100644
--- a/name.txt
+++ b/name.txt
@@ -1,2 +1,4 @@
 my name is shentao - 12345
 new add line
+new add line 2
+new add line 3

版本回滾###

通過 git reset 命令我們可以重置分支中最新的提交。
首先,我們先通過 git log --pertty=oneline 來查看提交的歷史記錄。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git log --pretty=oneline
b602d2600c2a4f84d427ff2a414a90384e77dfed commit1
d27ea06b28a91095921ac55b2fb3c1f078e10a9b commit2
0c2dc5716fc3b1ba0b8690a91e5dcad5d2b1dd24 commit3

其中像 b602d2600c2a4f84d427ff2a414a90384e77dfed 的這樣一串字母與數字的混合,就是該提交的索引,一般我們取前6位 b602d2,便可以供我們使用了。
拿到提交索引,我們便可以告訴git重置到那個提交版本。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git reset --hard d27ea0
HEAD is now at d27ea0  commit2

此時我們便將分支中保存的最新提交 commit1 重置為了 commit2了。此時如果再使用 git log 去查看提交歷史記錄,便會驚訝的發現,commit1版本已經看不到了,但是如果你現在又要重新返回到 commit1版怎么辦呢?
不要擔心,雖然 git log 無法查看之前的版本,但是通過 git reflog 命令還是可以看到的提交的命令記錄。

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git reflog
b602d26 HEAD@{26}: commit: commit1
d27ea06 HEAD@{27}: commit: commit2
0c2dc57 HEAD@{28}: commit: commit3

在常規的使用時,git的版本重置還有一種簡寫方式。
git reset --hard HEAD ^ //返回到當前版本下一個版本

撤銷操作###

這里說的撤銷操作,是指將暫存區的內容或者是提交后的內容撤銷到工作區的操作。
首先我們准備一下要撤銷的環境,這里我以 name.txt 為例,我會讓該文件在不同的區域其內容不同。
在工作區:

add line to working

在暫存區:

add line to working 
add line to staged

提交后再分支中:

add line to working
add line to staged
add line to staged

現在我們開始我們的撤銷操作

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ cat name.txt
add line to working

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git checkout name.txt

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ cat name.txt
add line to working
add line to staged

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git checkout HEAD name.txt

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ cat name.txt
add line to working
add line to staged
add line to branch

刪除操作

在gitbash中,我們可以通過 rm 命令來刪除文件以及目錄。

rm name.txt //刪除文件
rm -rf .git //刪除本地版本庫目錄

相同的git也自帶了刪除命令,使用者可以選擇是否將工作區與暫存區的文件同時刪除,還是保留工作區只刪除暫存區。

git rm name.txt

同時刪除工作區與暫存區

git rm --cached name.txt

刪除暫存區,但保留工作區。

遠程倉庫##

所謂的遠程倉庫,就是git的中央節點,也就是遠程服務器上的git版本庫,與我們本地並沒有什么區別,純粹為了7x24小時開機並交換大家的修改。
git的遠程倉庫或者是中央節點,既可以我們自己搭建一個內部的git服務器,也可以使用目前網上流行的github遠程項目托管平台。

認識github###

github 是一個面向開源及私有軟件項目的托管平台,因為只支持 Git 作為唯一的版本庫格式進行托管,故名github。
github 不僅僅單純托管git版本庫,還提供了跨平台的web操作界面,因此深受很多開發者喜愛。
github 上的代碼項目都是公開的開源的,如果你想私有不公開你的項目代碼,那么就需要繳納一定的金額才能開通私有功能。
github的官網地址是:https://github.com/,想使用github的具體功能,你需要有一個賬號。

克隆遠程倉庫

我們既可以將遠程的版本庫直接克隆到本地,也可以先創建本地的git版本庫,然后再與遠程的git倉庫進行關聯,具體使用哪一種,就看你個人的選擇。通常來說,直接克隆的方式是最簡單的,但是你不能確認在你開發之前,遠程的git倉庫就已經建好供你使用了。

需要說明的是,以下示例中的遠程版本庫都是以github上的遠程倉庫為例。

直接克隆遠程版本庫

Administrator@LS1412PC0008 MINGW64 /d/work
$ git clone https://github.com/shenguotao2015/fdasfdsafsaf.git

這種方式會將遠程版本庫克隆一個副本到本地,並且可以自動將本地版本庫與遠程版本庫自動關聯。

關聯遠程版本庫

Administrator@LS1412PC0008 MINGW64 /d/work
$ mkdir test

Administrator@LS1412PC0008 MINGW64 /d/work
$ git init
Initialized empty Git repository in D:/work/.git/

Administrator@LS1412PC0008 MINGW64 /d/work (master)
$ git remote add origin https://github.com/shenguotao2015/test.git

這種方式先在本地創建一個git倉庫,然后再通過 git remote 命令與遠程版本庫進行關聯。
但如果我們關聯的遠程版本庫有誤的話,就需要先刪除remote的origin再從新設定remote的origin

// 查看遠程倉庫相關信息
git remote 

// 刪除關聯的origin
git remote rm origin

推送與拉取###

指定分支推送並關聯遠程庫

$ git push -u origin master
Username for 'https://github.com': shenguotao2015
Counting objects: 3, done.
Writing objects: 100% (3/3), 209 bytes | 0 bytes/s, done.
Total 3 (delta 0), reused 0 (delta 0)
Branch master set up to track remote branch master from origin.
To https://github.com/shenguotao2015/fdasfdsafsaf.git
 * [new branch]      master -> master

默認分支推送

 git push

這種方式默認推送的就是當前分支中的提交內容。

拉取指定分支的項目代碼

git pull origin master

拉取默認分支

git pull 

關於分支,我們下一節會詳細的說到。

分支##

分支的基本概念

前面我們已經說過 HEAD 它類似於指針和索引的概念,在git中,HEAD 指向的是分支,分支用於保存提交結果,並面向最后的推送。

git默認的分支是 master 分支,在沒有其它分支的情況下,所有的提交操作都會被保存保存到master分支上,最終這個分支的時間線會不斷的進行延伸。但不變的是 HEAD 指向mastermaster再面向最后的推送。

分支的優勢在於其類似於一個平行獨立的個體,不同的分支可以用來保存不同的提交和推送結果,從而避免在開發時產生的代碼沖突。

分支的常用命令

下面是分支常用的命令集合

創建分支

git branch <branchname>

切換分支

git checkout <branchname>

創建並切換分支

git checkout -b <branchname>

查看分支

查看本地分支
git branch
查看遠程分支

//查看所有分支
git branch -a
//查看遠程分支
git branch -r

合並分支

fast forward 模式合並
git merge <branchname>
非fast forward 模式合並
git merge --no-ff -m "merge width no-ff" <branchname>

fast forward 與非 fast foward模式在於前者屬於一種快速合並方式,不會保存歷史記錄,而后者會在合並時,創建commit提交,從而保留被合並分支之前的記錄,通過 git log --graph --pretty=oneline --abbrev-commit 命令可以查看--no-ff模式下的合並提交記錄。

刪除分支

一般刪除
git git branch -d <branchname>
強行刪除
git branch -D <branchName>
刪除遠程分支
git branch -r -a <branchName>

分支的注意事項

git 中的分支分為本地分支與遠程分支,本地分支就是使用者自己在本地倉庫中創建的分支,所以遠程分支便是使用者自己在遠程倉庫中建立的分支,具體示例如下圖:

'branch'

先簡單的介紹本地分支的操作流程,當我們在本地的git中創建一個 dev 的分支時,在沒有切換下,HEAD 依然指向的是默認的分支 master ,當我們通過 git checkout dev 切換到 dev 分支時,HEAD 便會指向 dev 分支。然后我們進行的提交操作,都會保存到 dev 分支中再面向最后的推送(push),如果此時再通過git命令切換到 master 分支,那么HEAD就會自然的再指向 master, 然后 master 面向提交,當我們在 master 基礎上合並 dev 分支時,git就會將dev分支上的參數信息合並到master上,這樣master上就可以看到之前的dev分支的所有提交內容了。
'branch'

接着再介紹一下遠程分支的概念,雖然我們說git中的分支分為“本地分支”與“遠程分支”,但實際上這個區分並不突出,這是因為我們在本地git倉庫中創建的分支,只要本地倉庫origin與遠程倉庫origin是相連的情況下,git會自動幫我們將本地與遠程同名的分支進行關聯,除此之外,在進行 fetch 操作時,git也會將本地的分支自動同步到遠程倉庫總。除此之外當我們 直接切換本地不存在但遠程存在的分支時,git都會自動幫我們創建,切換並進行關聯。
示例:

git checkout dev
//如果遠程倉庫存在dev分支,git會自動幫我們創建,關聯與切換dev分支

需要注意的一點是,在本地同一個機器下創建的多個分支,其工作區中的文件是可以共享的,但是一旦該文件在某個分支中推送到了遠程對應的分支時,那么該文件邊只會是該分支獨有的文件。

最后,關於分支的使用和注意事項,我做了幾條簡單的總結:

1.  遠程分支中的內容是獨立的,但是對於同一個機器的本地分支而言,所創建的資源文件都是共享的。但是如果本地分支中的內容,推送到對應的遠程文件,那么該內容在其它分支將會不可見。
2.  每個分支都會保存自己的提交狀態。
3.  分支面向最后的推送,而推送的內容不會影響其它分支下的同文件。但是一旦分支合並后,那么在參與合並的這幾個分支下,該文件便會是相同的內容。
4.  當前的分支如果文件發生了變更時,是無法進行分支切換的,只有提交操作后才能夠切換。

分支沖突

分支再合並的時候,有可能會產生沖突。
沖突的產生是因為在合並的時候,不同分支修改了相同的位置。所以在合並的時候git不知道那個到底是你想保留的,所以就提出疑問(沖突提醒)讓你自己手動選擇想要保留的內容,從而解決沖突。
錯誤提示如下:

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git merge feature
Auto-merging branch.txt
CONFLICT (content): Merge conflict in branch.txt
Automatic merge failed; fix conflicts and then commit the result.

Administrator@LS1412PC0008 MINGW64 /d/work/test (master|MERGING)
$ git status
On branch master
Your branch is ahead of 'origin/master' by 1 commit.
  (use "git push" to publish your local commits)
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)

        both modified:   branch.txt

no changes added to commit (use "git add" and/or "git commit -a")

解決沖突的方法也很簡單,通過 git bash 自帶的命令工具,修改沖突的文件內容即可,然后再重新提交,推送!

示例:

//第一步:
git checkout -b feature
vi readme.txt // 修改內容為 feature branch
git commit -a -m 'commit'

git checkout master
vi readme.txt //修改內容為 feature branch & master branch
git commit -a -m 'commit'

//第二步:
git merge feature
// 此時應該會提示沖突(CONFLICT)
git status
// 查看狀態會看到更多的沖突提示信息。

//第三步:重新編輯沖突文件,然后提交 [略]

多人協作

分支可以很好的幫助我們進行多人協同開發,我們知道每個分支可以保存不同的提交結果,我們可以將正式版保存在一個分支下,將測試版的提交保存到另一個分支下,還可以讓每個開發者都有自己的分支,每個開發者都在自己的分支上負責自己的工作,最后再合並分支,而這些分支的特性便為多人協同開發提供了堅強的支撐基礎。
前面我們也學到了分支的常規操作,以及分支沖突的解決,這里我們就簡單的來說下,多人協作下的分支開發是一種什么樣的情況。

首先,在多人協作開發中,分支應該分為三種,一種是版本分支(master),專門用於發布穩定的版本,二是開發分支(dev),開發人員的代碼會不斷的合並到該分支,最后便是用戶分支(user-*)每個開發者都會有自己的工作分支。

具體如圖所示:
'branch'

master分支應該是非常穩定的,也就是僅用來發布新版本,平時不能在上面干活;
那在哪干活呢?干活都在dev分支上,也就是說,dev分支是不穩定的,到某個時候,比如1.0版本發布時,再把dev分支合並到master上,在master分支發布1.0版本;
你和你的小伙伴們每個人都在dev分支上干活,每個人都有自己的分支,時不時地往dev分支上合並就可以了。

多人協作時,大家都會往master和dev分支上推送各自的修改。
現在,模擬一個你的小伙伴,可以在另一台電腦(注意要把SSH Key添加到GitHub)或者同一台電腦的另一個目錄下克隆:

$ git clone git@xxxxx.com/test.git
Cloning into 'learngit'...
remote: Counting objects: 46, done.
remote: Compressing objects: 100% (26/26), done.
remote: Total 46 (delta 16), reused 45 (delta 15)
Receiving objects: 100% (46/46), 15.69 KiB | 6 KiB/s, done.
Resolving deltas: 100% (16/16), done.

當你的小伙伴從遠程庫clone時,默認情況下,你的小伙伴只能看到本地的master分支。不信可以用git branch命令看看:

$ git branch
* master

現在,你的小伙伴要在dev分支上開發,就必須創建遠程origin的dev分支到本地,於是他用這個命令創建本地dev分支:

$ git checkout -b dev origin/dev

實際上,如果我們直接git chekout dev 也是可以自動創建,切換並關聯dev分支的。
現在,他就可以在dev上繼續修改,然后,時不時地把dev分支push到遠程:

git commit -m "add /usr/bin/env"

總的來說,多人協作的工作模式通常是這樣:

  • 首先,可以試圖用git push origin branch-name推送自己的修改;
  • 如果推送失敗,則因為遠程分支比你的本地更新,需要先用git pull試圖合並;
  • 如果合並有沖突,則解決沖突,並在本地提交;
  • 沒有沖突或者解決掉沖突后,再用git push origin branch-name推送就能成功!

如果git pull提示“no tracking information”,則說明本地分支和遠程分支的鏈接關系沒有創建,用命令git branch --set-upstream branch-name origin/branch-name。

這就是多人協作的工作模式,一旦熟悉了,就非常簡單。

bug 分支

首先讓我們代入一個問題去思考!如何在一個多人協作的開發情況下去修復一個bug呢?我想,我們會想到的是,現本地 pull 一下,然后找到那個bug所在的文件,然后修改bug,最后在與dev分支合並分支。
是的,基本的步驟就是如此,但現實情況卻總是那么骨感,比如你現在已經在你當前的分支上進行某項功能的開發,而且離你能完成的時間最少還需要1天,但是這個bug又需要立刻修掉,這種情況下你便不能直接用你當前的分支去修改,然后合並了,這會將你正在進行的工作也合並到dev,那么我們應該怎么去修復bug呢?
思路是一樣的,這種情況下,我們依然通過分支去修bug,但是我們會在暫存當前分支的工作狀態,然后新建並切換一個臨時分支去修復bug,然后與dev進行分支合並,最終再恢復之前工作狀態。

首先檢查自己工作分支的狀態

Administrator@LS1412PC0008 MINGW64 /d/work/test (shentao)
$ git status
On branch shentao
Untracked files:
  (use "git add <file>..." to include in what will be committed)

        shenguotao2.txt

nothing added to commit but untracked files present (use "git add" to track)

發現當前分支有更改,但是目前不需要合並到開發環境,所以保存工作狀態,建立臨時分支

Administrator@LS1412PC0008 MINGW64 /d/work/test (shentao)
$ git stash
No local changes to save

Administrator@LS1412PC0008 MINGW64 /d/work/test (shentao)
$ git checkout -b issue-01
Switched to a new branch 'issue-01'

然后切換到臨時分支,再去修改bug文件,這里我隨便添加點內容,然后切換到dev分支

Administrator@LS1412PC0008 MINGW64 /d/work/test (issue-01)
$ vi shenguotao.txt

Administrator@LS1412PC0008 MINGW64 /d/work/test (issue-01)
$ git add *

Administrator@LS1412PC0008 MINGW64 /d/work/test (issue-01)
$ git commit -m 'repair bug'
[issue-01 af1d81f] repair bug
 1 file changed, 1 insertion(+)

Administrator@LS1412PC0008 MINGW64 /d/work/test (issue-01)
$ git checkout dev
Switched to branch 'dev'

再將臨時分支與dev分支進行分支合並,然后刪除臨時分支

Administrator@LS1412PC0008 MINGW64 /d/work/test (dev)
$ git merge issue-01
Updating 587b031..af1d81f
Fast-forward
 shenguotao.txt | 1 +
 1 file changed, 1 insertion(+)

Administrator@LS1412PC0008 MINGW64 /d/work/test (dev)
$ git branch -d issue-01
Deleted branch issue-01 (was af1d81f).

最后我們再切換到自己工作的分支,查看當前的分支狀態是干凈的,所以要恢復之前的工作狀態

Administrator@LS1412PC0008 MINGW64 /d/work/test (shentao)
$ git status
On branch dev
nothing to commit, working tree clean

Administrator@LS1412PC0008 MINGW64 /d/work/test (shentao)
$ git stash pop
On branch dev
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   shenguotao2.txt

Dropped refs/stash@{0} (4323cae5c4f94b6df6c10b3abcacc71c0cf47f01)

這里的重點一是掌握通過分支解決bug的思路,二是掌握保存,刪除,恢復分支工作狀態的命令

** 保存當前分支的工作狀態**
git stash

** 查看當前分支的工作狀態列表**
git stash list

恢復分支最新的工作狀態
git stash pop

恢復分支指定的工作狀態
git stash appy stash@{0}
注:該命令可結合 git stash list 使用

刪除分支狀態
git stash drop

標簽

標簽的概念###

git 中的tag是標簽的意思,它就像是指向某個commit的指針,用於跟某個具體的提交綁定在一起。
git 有commit,為什么還要引入tag?

“請把上周一的那個版本打包發布,commit號是6a5819e...”
“一串亂七八糟的數字不好找!”
如果換一個辦法:
“請把上周一的那個版本打包發布,版本號是v1.2”
“好的,按照tag v1.2查找commit就行!”

所以tag 又類似於別名,因此在發布一個版本時,我們通常先在版本庫中打一個標簽(tag),這樣,就唯一確定了打標簽時刻的版本。

tag 與 branch的區別就在與一個是標識commit另一個則是存儲commit,所以標簽的數量是未知的,而分支的數量是可知的。

標簽的常用命令###

下面是關於tag的相關操作命令

創建標簽

git tag <tagName>

注意:默認的是為最新的 commit 創建tag。

為指定的commit創建標簽

git tag <tagName> [commitID]
//示例:git tag v0.9 6224937

創建帶注釋說明的標簽

git tag -a <tagName> -m 'note content'

查看標簽

git tag

查看指定標簽的信息

git show <tagName>

刪除標簽

git tag -d <tagName>

推送標簽到遠程

git push origin <tagName>

將本地所有標簽推送到遠程

git push origin --tags

刪除遠程標簽

git push origin :refs/tags/v0.9

自定義

用戶信息與加密key###

在我們本地的git中,可以配置使用者的相關信息

git config --global user.name "shenguotao"
git config --global user.email "sgt_ah@163.com"

然后可以通過
git config --list
去查看信息。

如果我們擔心在拉取或推送遠程倉庫時,會有人冒充,那么便可以使用ssh方式,並將自己的公鑰上傳到指定服務器上,供第一次鏈接時進行驗證使用。

首先生成本地電腦的私鑰與公鑰。

$ ssh-keygen -t rsa -C "youremail@example.com"

你需要把郵件地址換成你自己的郵件地址,然后一路回車即可,並無需設置密碼。
如果一切順利的話,可以在用戶主目錄里找到 .ssh 目錄,里面有id_rsaid_rsa.pub 兩個文件,這兩個就是SSH Key的秘鑰對,id_rsa是私鑰,不能泄露出去,id_rsa.pub是公鑰,可以放心地告訴任何人。
最后,登錄的你github,打開“Account settings”,“SSH Keys”頁面:
然后,點“Add SSH Key”,填上任意Title,在Key文本框里粘貼id_rsa.pub文件的內容便可。

為什么GitHub需要SSH Key呢?因為GitHub需要識別出你推送的提交確實是你推送的,而不是別人冒充的,而Git支持SSH協議,所以,GitHub只要知道了你的公鑰,就可以確認只有你自己才能推送。

當然,GitHub允許你添加多個Key。假定你有若干電腦,你一會兒在公司提交,一會兒在家里提交,只要把每台電腦的Key都添加到GitHub,就可以在每台電腦上往GitHub推送了。

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

命令語法着色###

可以在config中配置相關命令,使語法着色,讓命令更加突出。

git config --global color.ui true

文件忽略###

對於不想提交的文件,我們可以建一個.gitignore文件來設置那些文件是要被忽略的。然后再把.gitignore文件提交上去即可。
一般.gitignore文件編寫如下示例:

//.gitignore
example.png //忽略指定的文件
test //忽略整個目錄
*.md //忽略所有的.md文件

如果想強制將.gitignore文件中設定的忽略文件提交到版本庫中,可以使用以下命令:

git add -f <fileName>

如果想查看某個忽略聲明在.gitignore文件的那一行,可以使用如下命令:

git check-ignore -v example.png

自定義命令

如果你覺得git默認的命令過於繁雜難以記憶,那么你可以自定義git的命令

git config --global alias.st status

其它的有:

$ git config --global alias.co checkout
$ git config --global alias.ci commit
$ git config --global alias.br branch

說明:--global 用於設置該配置是否對全局都產生作用。

超推薦:

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

修改配置文件###

git中的配置信息是保存在配置文件中的,配置文件根絕作用范圍不同,分為當前版本庫的配置文件,其路徑,就是:.git/config ,另一個則是全局的git配置文件,是對所有的版本庫都起作用,它默認在操作系統的用戶目錄,文件名為 '.gitconfig' 。

cd .git
cat config
//-----
cd c:/Users
cat .gitconfig

在配置文件中,就可以修改 remote,alias等吧。

git常見問題###

空的git倉庫不能提交到遠程庫

Administrator@LS1412PC0008 MINGW64 /d/work/test (master)
$ git push -u origin master
error: src refspec master does not match any.
error: failed to push some refs to 'https://github.com/shenguotao2015/fdasfdsafsaf.git'

解決方法:建一個readme文件!

git報錯無法push
這是由於遠程repository和我本地的repository沖突造成,通常發生在多人協作的開發過程中

$git push
To gitkt:abroadweb
![rejected] master -> master(non-fast-forward)
error:failed to push some refs to 'gitkt:abroadweb'
hint:Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull..') before pushing again ...

解決方法:
1.使用強制push的方法:
git push -u origin master -f
這樣會使遠程修改丟失,一般是不可取的

2.push前先將遠程repository修改pull下來
git pull origin master
git push -u origin master

3.若不想merge遠程和本地修改,可以先創建新的分支:
git branch [name]
git push -u origin [name]

多人協作的開發過程,一般推薦熟練使用分支功能來進行代碼的托管,這樣就會避免沖突的發生。

postBuffer 超出

error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: unpack-objects failed

錯誤原因:
postBuffer是請求緩存區的意思,它的功能是當我們去 git clone 某個項目的時候,實際上git會有一個臨時的緩存區去保存克隆的內容,當確定所有的內容都下載好后,才會保存到本地,但是如果這個緩存區設置的大小小於項目本身大小時,就會產生以上錯誤。

解決方法:
將postBuffer的大小設置的更大一些。

git config --global http.postBuffer 524288000

這里我們就講postBuffer的緩存區設置為500MB


強烈推薦廖雪峰的git教程
http://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000
linux的常用命令
http://www.cnblogs.com/laov/p/3541414.html
vi的百度百科
http://baike.baidu.com/item/Vi/8987313


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM