天天看點

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

工程化專題之Git

Git 是一個開源的分布式版本控制系統,用于靈活高效地處理任何或小或大的項目。

Git 是 Linus Torvalds 為了幫助管理 Linux 核心開發而開發的一個開放源碼的版本控制軟體。

Git 與常用的版本控制工具 CVS, Subversion 等不同,它采用了分布式版本庫的方式,不必伺服器端軟體支援。

Git 與 SVN 差別

Git 不僅僅是個版本控制系統,它也是個内容管理系統(CMS),工作管理系統等。

如果你是一個具有使用 SVN 背景的人,你需要做一定的思想轉換,來适應 Git 提供的一些概念和特征。

Git 與 SVN 差別點:

  • 1、Git 是分布式的,SVN 不是:這是 Git 和其它非分布式的版本控制系統,例如 SVN,CVS 等,最核心的差別。
  • 2、Git 把内容按中繼資料方式存儲,而 SVN 是按檔案:所有的資源控制系統都是把檔案的元資訊隐藏在一個類似 .svn、.cvs 等的檔案夾裡。
  • 3、Git 分支和 SVN 的分支不同:分支在 SVN 中一點都不特别,其實它就是版本庫中的另外一個目錄。
  • 4、Git 沒有一個全局的版本号,而 SVN 有:目前為止這是跟 SVN 相比 Git 缺少的最大的一個特征。
  • 5、Git 的内容完整性要優于 SVN:Git 的内容存儲使用的是 SHA-1 雜湊演算法。這能確定代碼内容的完整性,確定在遇到磁盤故障和網絡問題時降低對版本庫的破壞。
git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

在 Windows 平台上安裝 Git 同樣輕松,有個叫做 msysGit 的項目提供了安裝包,可以到 GitHub 的頁面上下載下傳 exe 安裝檔案并運作:

安裝包下載下傳位址:https://gitforwindows.org/

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

完成安裝之後,就可以使用指令行的 git 工具(已經自帶了 ssh 用戶端)了,另外還有一個圖形界面的 Git 項目管理工具。

在開始菜單裡找到"Git"->"Git Bash",會彈出 Git 指令視窗,你可以在該視窗進行 Git 操作。

安裝

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

檢視配置資訊

要檢查已有的配置資訊,可以使用 git config --list 指令:

$ git config --list
http.postbuffer=2M
user.name=zz
[email protected]      

有時候會看到重複的變量名,那就說明它們來自不同的配置檔案(比如 /etc/gitconfig 和 ~/.gitconfig),不過最終 Git 實際采用的是最後一個。

這些配置我們也可以在 ~/.gitconfig 或 /etc/gitconfig 看到,如下所示:

vim ~/.gitconfig      

顯示内容如下所示:

[http]
    postBuffer = 2M
[user]
    name = zz
    email = [email protected]      

也可以直接查閱某個環境變量的設定,隻要把特定的名字跟在後面即可,像這樣:

$ git config user.name
zz      

Git 工作流程

一般工作流程如下:

  • 克隆 Git 資源作為工作目錄。
  • 在克隆的資源上添加或修改檔案。
  • 如果其他人修改了,你可以更新資源。
  • 在送出前檢視修改。
  • 送出修改。
  • 在修改完成後,如果發現錯誤,可以撤回送出并再次修改并送出。

下圖展示了 Git 的工作流程:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

Git 工作區、暫存區和版本庫

基本概念

我們先來了解下Git 工作區、暫存區和版本庫概念

  • 工作區:就是你在電腦裡能看到的目錄。
  • 暫存區:英文叫stage, 或index。一般存放在 ".git目錄下" 下的index檔案(.git/index)中,是以我們把暫存區有時也叫作索引(index)。
  • 版本庫:工作區有一個隐藏目錄.git,這個不算工作區,而是Git的版本庫。

下面這個圖展示了工作區、版本庫中的暫存區和版本庫之間的關系:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

圖中左側為工作區,右側為版本庫。在版本庫中标記為 "index" 的區域是暫存區(stage, index),标記為 "master" 的是 master 分支所代表的目錄樹。

圖中我們可以看出此時 "HEAD" 實際是指向 master 分支的一個"遊标"。是以圖示的指令中出現 HEAD 的地方可以用 master 來替換。

圖中的 objects 辨別的區域為 Git 的對象庫,實際位于 ".git/objects" 目錄下,裡面包含了建立的各種對象及内容。

當對工作區修改(或新增)的檔案執行 "git add" 指令時,暫存區的目錄樹被更新,同時工作區修改(或新增)的檔案内容被寫入到對象庫中的一個新的對象中,而該對象的ID被記錄在暫存區的檔案索引中。

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

當執行 "git reset HEAD" 指令時,暫存區的目錄樹會被重寫,被 master 分支指向的目錄樹所替換,但是工作區不受影響。

當執行 "git rm --cached <file>" 指令時,會直接從暫存區删除檔案,工作區則不做出改變。

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

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

Git 建立倉庫

你可以使用一個已經存在的目錄作為Git倉庫。

git init

Git 使用 git init 指令來初始化一個 Git 倉庫,Git 的很多指令都需要在 Git 的倉庫中運作,是以 git init 是使用 Git 的第一個指令。

在執行完成 git init 指令後,Git 倉庫會生成一個 .git 目錄,該目錄包含了資源的所有中繼資料,其他的項目目錄保持不變(不像 SVN 會在每個子目錄生成 .svn 目錄,Git 隻在倉庫的根目錄生成 .git 目錄)。

使用方法

使用目前目錄作為Git倉庫,我們隻需使它初始化。

git init      

該指令執行完後會在目前目錄生成一個 .git 目錄。

使用我們指定目錄作為Git倉庫。

git init newrepo      

初始化後,會在 newrepo 目錄下會出現一個名為 .git 的目錄,所有 Git 需要的資料和資源都存放在這個目錄中。

如果目前目錄下有幾個檔案想要納入版本控制,需要先用 git add 指令告訴 Git 開始對這些檔案進行跟蹤,然後送出:

$ git add *.c
$ git add README
$ git commit -m '初始化項目版本'      

以上指令将目錄下以 .c 結尾及 README 檔案送出到倉庫中。

git clone

我們使用 git clone 從現有 Git 倉庫中拷貝項目(類似 svn checkout)。

克隆倉庫的指令格式為:

git clone <repo>      

如果我們需要克隆到指定的目錄,可以使用以下指令格式:

git clone <repo> <directory>      

參數說明:

  • repo:Git 倉庫。
  • directory:本地目錄。

比如,要克隆 Ruby 語言的 Git 代碼倉庫 Grit,可以用下面的指令:

$ git clone git://github.com/schacon/grit.git      

執行該指令後,會在目前目錄下建立一個名為grit的目錄,其中包含一個 .git 的目錄,用于儲存下載下傳下來的所有版本記錄。

如果要自己定義要建立的項目目錄名稱,可以在上面的指令末尾指定新的名字:

$ git clone git://github.com/schacon/grit.git mygrit      

Git 基本操作

Git 的工作就是建立和儲存你項目的快照及與之後的快照進行對比。本章将對有關建立與送出你的項目快照的指令作介紹。

擷取與建立項目指令

git init

用 git init 在目錄中建立新的 Git 倉庫。 你可以在任何時候、任何目錄中這麼做,完全是本地化的。

在目錄中執行 git init,就可以建立一個 Git 倉庫了。比如我們建立 runoob 項目:

$ mkdir runoob
$ cd runoob/
$ git init
Initialized empty Git repository in /Users/tianqixin/www/runoob/.git/
# 在 /www/runoob/.git/ 目錄初始化空 Git 倉庫完畢。      

現在你可以看到在你的項目中生成了 .git 這個子目錄。 這就是你的 Git 倉庫了,所有有關你的此項目的快照資料都存放在這裡。

ls -a
.    ..    .git      

git clone

使用 git clone 拷貝一個 Git 倉庫到本地,讓自己能夠檢視該項目,或者進行修改。

如果你需要與他人合作一個項目,或者想要複制一個項目,看看代碼,你就可以克隆那個項目。 執行指令:

git clone [url]      

[url] 為你想要複制的項目,就可以了。

例如我們克隆 Github 上的項目:

$ git clone [email protected]:schacon/simplegit.git
Cloning into 'simplegit'...
remote: Counting objects: 13, done.
remote: Total 13 (delta 0), reused 0 (delta 0), pack-reused 13
Receiving objects: 100% (13/13), done.
Resolving deltas: 100% (2/2), done.
Checking connectivity... done.      

克隆完成後,在目前目錄下會生成一個 simplegit 目錄:

$ cd simplegit/
$ ls
README   Rakefile lib      

上述操作将複制該項目的全部記錄。

$ ls -a
.        ..       .git     README   Rakefile lib
$ cd .git
$ ls
HEAD        description info        packed-refs
branches    hooks       logs        refs
config      index       objects      

預設情況下,Git 會按照你提供的 URL 所訓示的項目的名稱建立你的本地項目目錄。 通常就是該 URL 最後一個 / 之後的項目名稱。如果你想要一個不一樣的名字, 你可以在該指令後加上你想要的名稱。

基本快照

Git 的工作就是建立和儲存你的項目的快照及與之後的快照進行對比。本章将對有關建立與送出你的項目的快照的指令作介紹。

git add

git add 指令可将該檔案添加到緩存,如我們添加以下兩個檔案:

$ touch README
$ touch hello.php
$ ls
README        hello.php
$ git status -s
?? README
?? hello.php
$      

git status 指令用于檢視項目的目前狀态。

接下來我們執行 git add 指令來添加檔案:

$ git add README hello.php      

現在我們再執行 git status,就可以看到這兩個檔案已經加上去了。

$ git status -s
A  README
A  hello.php
$      

新項目中,添加所有檔案很普遍,我們可以使用 git add . 指令來添加目前項目的所有檔案。

現在我們修改 README 檔案:

$ vim README      

在 README 添加以下内容:# Runoob Git 測試,然後儲存退出。

再執行一下 git status:

$ git status -s
AM README
A  hello.php      

"AM" 狀态的意思是,這個檔案在我們将它添加到緩存之後又有改動。改動後我們再執行 git add 指令将其添加到緩存中:

$ git add .
$ git status -s
A  README
A  hello.php      

當你要将你的修改包含在即将送出的快照裡的時候,需要執行 git add。

git status

git status 以檢視在你上次送出之後是否有修改。

我示範該指令的時候加了 -s 參數,以獲得簡短的結果輸出。如果沒加該參數會詳細輸出内容:

$ git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

    new file:   README
    new file:   hello.php      

git diff

執行 git diff 來檢視執行 git status 的結果的詳細資訊。

git diff 指令顯示已寫入緩存與已修改但尚未寫入緩存的改動的差別。git diff 有兩個主要的應用場景。

  • 尚未緩存的改動:git diff
  • 檢視已緩存的改動: git diff --cached
  • 檢視已緩存的與未緩存的所有改動:git diff HEAD
  • 顯示摘要而非整個 diff:git diff --stat

在 hello.php 檔案中輸入以下内容:

<?php
echo '菜鳥教程:www.runoob.com';
?>      
$ git status -s
A  README
AM hello.php
$ git diff
diff --git a/hello.php b/hello.php
index e69de29..69b5711 100644
--- a/hello.php
+++ b/hello.php
@@ -0,0 +1,3 @@
+<?php
+echo '菜鳥教程:www.runoob.com';
+?>      

git status 顯示你上次送出更新後的更改或者寫入緩存的改動, 而 git diff 一行一行地顯示這些改動具體是啥。

接下來我們來檢視下 git diff --cached 的執行效果:

$ git add hello.php 
$ git status -s
A  README
A  hello.php
$ git diff --cached
diff --git a/README b/README
new file mode 100644
index 0000000..8f87495
--- /dev/null
+++ b/README
@@ -0,0 +1 @@
+# Runoob Git 測試
diff --git a/hello.php b/hello.php
new file mode 100644
index 0000000..69b5711
--- /dev/null
+++ b/hello.php
@@ -0,0 +1,3 @@
+<?php
+echo '菜鳥教程:www.runoob.com';
+?>      

git commit

使用 git add 指令将想要快照的内容寫入緩存區, 而執行 git commit 将緩存區内容添加到倉庫中。

Git 為你的每一個送出都記錄你的名字與電子郵箱位址,是以第一步需要配置使用者名和郵箱位址。

$ git config --global user.name 'runoob'
$ git config --global user.email [email protected]      

接下來我們寫入緩存,并送出對 hello.php 的所有改動。在首個例子中,我們使用 -m 選項以在指令行中提供送出注釋。

$ git add hello.php
$ git status -s
A  README
A  hello.php
$ git commit -m '第一次版本送出'
[master (root-commit) d32cf1f] 第一次版本送出
 2 files changed, 4 insertions(+)
 create mode 100644 README
 create mode 100644 hello.php      

現在我們已經記錄了快照。如果我們再執行 git status:

$ git status
# On branch master
nothing to commit (working directory clean)      

以上輸出說明我們在最近一次送出之後,沒有做任何改動,是一個"working directory clean:幹淨的工作目錄"。

如果你沒有設定 -m 選項,Git 會嘗試為你打開一個編輯器以填寫送出資訊。 如果 Git 在你對它的配置中找不到相關資訊,預設會打開 vim。螢幕會像這樣:

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
# modified:   hello.php
#
~
~
".git/COMMIT_EDITMSG" 9L, 257C      

如果你覺得 git add 送出緩存的流程太過繁瑣,Git 也允許你用 -a 選項跳過這一步。指令格式如下:

git commit -a      

我們先修改 hello.php 檔案為以下内容:

<?php
echo '菜鳥教程:www.runoob.com';
echo '菜鳥教程:www.runoob.com';
?>      

再執行以下指令:

git commit -am '修改 hello.php 檔案'
[master 71ee2cb] 修改 hello.php 檔案
 1 file changed, 1 insertion(+)      

git reset HEAD

git reset HEAD 指令用于取消已緩存的内容。

我們先改動檔案 README 檔案,内容如下:

# Runoob Git 測試
# 菜鳥教程      

hello.php 檔案修改為:

<?php
echo '菜鳥教程:www.runoob.com';
echo '菜鳥教程:www.runoob.com';
echo '菜鳥教程:www.runoob.com';
?>      

現在兩個檔案修改後,都送出到了緩存區,我們現在要取消其中一個的緩存,操作如下:

$ git status -s
 M README
 M hello.php
$ git add .
$ git status -s
M  README
M  hello.php
$ git reset HEAD hello.php 
Unstaged changes after reset:
M    hello.php
$ git status -s
M  README
 M hello.php      

現在你執行 git commit,隻會将 README 檔案的改動送出,而 hello.php 是沒有的。

$ git commit -m '修改'
[master f50cfda] 修改
 1 file changed, 1 insertion(+)
$ git status -s
 M hello.php      

可以看到 hello.php 檔案的修改并未送出。

這時我們可以使用以下指令将 hello.php 的修改送出:

$ git commit -am '修改 hello.php 檔案'
[master 760f74d] 修改 hello.php 檔案
 1 file changed, 1 insertion(+)
$ git status
On branch master
nothing to commit, working directory clean      

簡而言之,執行 git reset HEAD 以取消之前 git add 添加,但不希望包含在下一送出快照中的緩存。

git rm

如果隻是簡單地從工作目錄中手工删除檔案,運作 git status 時就會在 Changes not staged for commit 的提示。

要從 Git 中移除某個檔案,就必須要從已跟蹤檔案清單中移除,然後送出。可以用以下指令完成此項工作

git rm <file>      

如果删除之前修改過并且已經放到暫存區域的話,則必須要用強制删除選項 -f

git rm -f <file>      

如果把檔案從暫存區域移除,但仍然希望保留在目前工作目錄中,換句話說,僅是從跟蹤清單中删除,使用 --cached 選項即可

git rm --cached <file>      

如我們删除 hello.php檔案:

$ git rm hello.php 
rm 'hello.php'
$ ls
README      

不從工作區中删除檔案:

$ git rm --cached README 
rm 'README'
$ ls
README      

可以遞歸删除,即如果後面跟的是一個目錄做為參數,則會遞歸删除整個目錄中的所有子目錄和檔案:

git rm –r *      

進入某個目錄中,執行此語句,會删除該目錄下的所有檔案和子目錄。

git mv

git mv 指令用于移動或重命名一個檔案、目錄、軟連接配接。

我們先把剛移除的 README 添加回來:

$ git add README      

然後對其重名:

$ git mv README  README.md
$ ls
README.md      

Git 分支管理

幾乎每一種版本控制系統都以某種形式支援分支。使用分支意味着你可以從開發主線上分離開來,然後在不影響主線的同時繼續工作。

有人把 Git 的分支模型稱為必殺技特性,而正是因為它,将 Git 從版本控制系統家族裡區分出來。

建立分支指令:

git branch (branchname)      

切換分支指令:

git checkout (branchname)      

當你切換分支的時候,Git 會用該分支的最後送出的快照替換你的工作目錄的内容, 是以多個分支不需要多個目錄。

合并分支指令:

git merge      

你可以多次合并到統一分支, 也可以選擇在合并之後直接删除被并入的分支。

開始前我們先建立一個測試目錄:

$ mkdir gitdemo
$ cd gitdemo/
$ git init
Initialized empty Git repository...
$ touch README
$ git add README
$ git commit -m '第一次版本送出'
[master (root-commit) 3b58100] 第一次版本送出
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 README      

Git 分支管理

列出分支

列出分支基本指令:

git branch      

沒有參數時,git branch 會列出你在本地的分支。

$ git branch
* master      

此例的意思就是,我們有一個叫做 master 的分支,并且該分支是目前分支。

當你執行 git init 的時候,預設情況下 Git 就會為你建立 master 分支。

如果我們要手動建立一個分支。執行 git branch (branchname) 即可。

$ git branch testing
$ git branch
* master
  testing      

現在我們可以看到,有了一個新分支 testing。

當你以此方式在上次送出更新之後建立了新分支,如果後來又有更新送出, 然後又切換到了 testing 分支,Git 将還原你的工作目錄到你建立分支時候的樣子。

接下來我們将示範如何切換分支,我們用 git checkout (branch) 切換到我們要修改的分支。

$ ls
README
$ echo 'runoob.com' > test.txt
$ git add .
$ git commit -m 'add test.txt'
[master 3e92c19] add test.txt
 1 file changed, 1 insertion(+)
 create mode 100644 test.txt
$ ls
README        test.txt
$ git checkout testing
Switched to branch 'testing'
$ ls
README      

當我們切換到 testing 分支的時候,我們添加的新檔案 test.txt 被移除了。切換回 master 分支的時候,它們有重新出現了。

$ git checkout master
Switched to branch 'master'
$ ls
README        test.txt      

我們也可以使用 git checkout -b (branchname) 指令來建立新分支并立即切換到該分支下,進而在該分支中操作。

$ git checkout -b newtest
Switched to a new branch 'newtest'
$ git rm test.txt 
rm 'test.txt'
$ ls
README
$ touch hello.php
$ git add .
$ git commit -am 'removed test.txt、add runoob.php'
[newtest c1501a2] removed test.txt、add runoob.php
 2 files changed, 1 deletion(-)
 create mode 100644 runoob.php
 delete mode 100644 test.txt
$ ls
README        runoob.php
$ git checkout master
Switched to branch 'master'
$ ls
README        test.txt      

如你所見,我們建立了一個分支,在該分支的上移除了一些檔案 test.txt,并添加了 runoob.php 檔案,然後切換回我們的主分支,删除的 test.txt 檔案又回來了,且新增加的 runoob.php 不存在主分支中。

使用分支将工作切分開來,進而讓我們能夠在不同開發環境中做事,并來回切換。

删除分支

删除分支指令:

git branch -d (branchname)      

例如我們要删除 testing 分支:

$ git branch
* master
  testing
$ git branch -d testing
Deleted branch testing (was 85fc7e7).
$ git branch
* master      

分支合并

一旦某分支有了獨立内容,你終究會希望将它合并回到你的主分支。 你可以使用以下指令将任何分支合并到目前分支中去:

git merge      
$ git branch
* master
  newtest
$ ls
README        test.txt
$ git merge newtest
Updating 3e92c19..c1501a2
Fast-forward
 runoob.php | 0
 test.txt   | 1 -
 2 files changed, 1 deletion(-)
 create mode 100644 runoob.php
 delete mode 100644 test.txt
$ ls
README        runoob.php      

以上執行個體中我們将 newtest 分支合并到主分支去,test.txt 檔案被删除。

合并完後就可以删除分支:

$ git branch -d newtest
Deleted branch newtest (was c1501a2).      

删除後, 就隻剩下 master 分支了:

$ git branch
* master      

合并沖突

合并并不僅僅是簡單的檔案添加、移除的操作,Git 也會合并修改。

$ git branch
* master
$ cat runoob.php      

首先,我們建立一個叫做 change_site 的分支,切換過去,我們将 runoob.php 内容改為:

<?php
echo 'runoob';
?>      

建立 change_site 分支:

$ git checkout -b change_site
Switched to a new branch 'change_site'
$ vim runoob.php
$ head -3 runoob.php
<?php
echo 'runoob';
?>
$ git commit -am 'changed the runoob.php'
[change_site 7774248] changed the runoob.php
 1 file changed, 3 insertions(+)      

将修改的内容送出到 change_site 分支中。 現在,假如切換回 master 分支我們可以看内容恢複到我們修改前的(空檔案,沒有代碼),我們再次修改 runoob.php 檔案。

$ git checkout master
Switched to branch 'master'
$ cat runoob.php
$ vim runoob.php    # 修改内容如下
$ cat runoob.php
<?php
echo 1;
?>
$ git diff
diff --git a/runoob.php b/runoob.php
index e69de29..ac60739 100644
--- a/runoob.php
+++ b/runoob.php
@@ -0,0 +1,3 @@
+<?php
+echo 1;
+?>
$ git commit -am '修改代碼'
[master c68142b] 修改代碼
 1 file changed, 3 insertions(+)      

現在這些改變已經記錄到我的 "master" 分支了。接下來我們将 "change_site" 分支合并過來。

$ git merge change_site
Auto-merging runoob.php
CONFLICT (content): Merge conflict in runoob.php
Automatic merge failed; fix conflicts and then commit the result.

$ cat runoob.php     # 代開檔案,看到沖突内容
<?php
<<<<<<< HEAD
echo 1;
=======
echo 'runoob';
>>>>>>> change_site
?>      

我們将前一個分支合并到 master 分支,一個合并沖突就出現了,接下來我們需要手動去修改它。

$ vim runoob.php 
$ cat runoob.php
<?php
echo 1;
echo 'runoob';
?>
$ git diff
diff --cc runoob.php
index ac60739,b63d7d7..0000000
--- a/runoob.php
+++ b/runoob.php
@@@ -1,3 -1,3 +1,4 @@@
  <?php
 +echo 1;
+ echo 'runoob';
  ?>      

在 Git 中,我們可以用 git add 要告訴 Git 檔案沖突已經解決

$ git status -s
UU runoob.php
$ git add runoob.php
$ git status -s
M  runoob.php
$ git commit
[master 88afe0e] Merge branch 'change_site'      

現在我們成功解決了合并中的沖突,并送出了結果。

Git 檢視送出曆史

在使用 Git 送出了若幹更新之後,又或者克隆了某個項目,想回顧下送出曆史,我們可以使用 git log 指令檢視。

針對我們前一章節的操作,使用 git log 指令列出曆史送出記錄如下:

$ git log
commit d5e9fc2c811e0ca2b2d28506ef7dc14171a207d9 (HEAD -> master)
Merge: c68142b 7774248
Author: runoob <[email protected]>
Date:   Fri May 3 15:55:58 2019 +0800

    Merge branch 'change_site'

commit c68142b562c260c3071754623b08e2657b4c6d5b
Author: runoob <[email protected]>
Date:   Fri May 3 15:52:12 2019 +0800

    修改代碼

commit 777424832e714cf65d3be79b50a4717aea51ab69 (change_site)
Author: runoob <[email protected]>
Date:   Fri May 3 15:49:26 2019 +0800

    changed the runoob.php

commit c1501a244676ff55e7cccac1ecac0e18cbf6cb00
Author: runoob <[email protected]>
Date:   Fri May 3 15:35:32 2019 +0800      

我們可以用 --oneline 選項來檢視曆史記錄的簡潔的版本。

$ git log --oneline
$ git log --oneline
d5e9fc2 (HEAD -> master) Merge branch 'change_site'
c68142b 修改代碼
7774248 (change_site) changed the runoob.php
c1501a2 removed test.txt、add runoob.php
3e92c19 add test.txt
3b58100 第一次版本送出      

這告訴我們的是,此項目的開發曆史。

我們還可以用 --graph 選項,檢視曆史中什麼時候出現了分支、合并。以下為相同的指令,開啟了拓撲圖選項:

*   d5e9fc2 (HEAD -> master) Merge branch 'change_site'
|\  
| * 7774248 (change_site) changed the runoob.php
* | c68142b 修改代碼
|/  
* c1501a2 removed test.txt、add runoob.php
* 3e92c19 add test.txt
* 3b58100 第一次版本送出      

現在我們可以更清楚明了地看到何時工作分叉、又何時歸并。

你也可以用 --reverse 參數來逆向顯示所有日志。

$ git log --reverse --oneline
3b58100 第一次版本送出
3e92c19 add test.txt
c1501a2 removed test.txt、add runoob.php
7774248 (change_site) changed the runoob.php
c68142b 修改代碼
d5e9fc2 (HEAD -> master) Merge branch 'change_site'      

如果隻想查找指定使用者的送出日志可以使用指令:git log --author , 例如,比方說我們要找 Git 源碼中 Linus 送出的部分:

$ git log --author=Linus --oneline -5
81b50f3 Move 'builtin-*' into a 'builtin/' subdirectory
3bb7256 make "index-pack" a built-in
377d027 make "git pack-redundant" a built-in
b532581 make "git unpack-file" a built-in
112dd51 make "mktag" a built-in      

如果你要指定日期,可以執行幾個選項:--since 和 --before,但是你也可以用 --until 和 --after。

例如,如果我要看 Git 項目中三周前且在四月十八日之後的所有送出,我可以執行這個(我還用了 --no-merges 選項以隐藏合并送出):

$ git log --oneline --before={3.weeks.ago} --after={2010-04-18} --no-merges
5469e2d Git 1.7.1-rc2
d43427d Documentation/remote-helpers: Fix typos and improve language
272a36b Fixup: Second argument may be any arbitrary string
b6c8d2d Documentation/remote-helpers: Add invocation section
5ce4f4e Documentation/urls: Rewrite to accomodate transport::address
00b84e9 Documentation/remote-helpers: Rewrite description
03aa87e Documentation: Describe other situations where -z affects git diff
77bc694 rebase-interactive: silence warning when no commits rewritten
636db2c t3301: add tests to use --format="%N"      

Git 标簽

如果你達到一個重要的階段,并希望永遠記住那個特别的送出快照,你可以使用 git tag 給它打上标簽。

比如說,我們想為我們的 runoob 項目釋出一個"1.0"版本。 我們可以用 git tag -a v1.0 指令給最新一次送出打上(HEAD)"v1.0"的标簽。

-a 選項意為"建立一個帶注解的标簽"。 不用 -a 選項也可以執行的,但它不會記錄這标簽是啥時候打的,誰打的,也不會讓你添加個标簽的注解。 我推薦一直建立帶注解的标簽。

$ git tag -a v1.0      

當你執行 git tag -a 指令時,Git 會打開你的編輯器,讓你寫一句标簽注解,就像你給送出寫注解一樣。

現在,注意當我們執行 git log --decorate 時,我們可以看到我們的标簽了:

*   d5e9fc2 (HEAD -> master) Merge branch 'change_site'
|\  
| * 7774248 (change_site) changed the runoob.php
* | c68142b 修改代碼
|/  
* c1501a2 removed test.txt、add runoob.php
* 3e92c19 add test.txt
* 3b58100 第一次版本送出      

如果我們忘了給某個送出打标簽,又将它釋出了,我們可以給它追加标簽。

例如,假設我們釋出了送出 85fc7e7(上面執行個體最後一行),但是那時候忘了給它打标簽。 我們現在也可以:

$ git tag -a v0.9 85fc7e7
$ git log --oneline --decorate --graph
*   d5e9fc2 (HEAD -> master) Merge branch 'change_site'
|\  
| * 7774248 (change_site) changed the runoob.php
* | c68142b 修改代碼
|/  
* c1501a2 removed test.txt、add runoob.php
* 3e92c19 add test.txt
* 3b58100 (tag: v0.9) 第一次版本送出      

如果我們要檢視所有标簽可以使用以下指令:

$ git tag
v0.9
v1.0      

指定标簽資訊指令:

git tag -a <tagname> -m "runoob.com标簽"      

PGP簽名标簽指令:

git tag -s <tagname> -m "runoob.com标簽"      

Git 遠端倉庫(Github)

Git 并不像 SVN 那樣有個中心伺服器。

目前我們使用到的 Git 指令都是在本地執行,如果你想通過 Git 分享你的代碼或者與其他開發人員合作。 你就需要将資料放到一台其他開發人員能夠連接配接的伺服器上。

本例使用了 Github 作為遠端倉庫,你可以先閱讀我們的 Github 簡明教程。

添加遠端庫

要添加一個新的遠端倉庫,可以指定一個簡單的名字,以便将來引用,指令格式如下:

git remote add [shortname] [url]      

本例以 Github 為例作為遠端倉庫,如果你沒有 Github 可以在官網 https://github.com/注冊。

由于你的本地 Git 倉庫和 GitHub 倉庫之間的傳輸是通過SSH加密的,是以我們需要配置驗證資訊:

使用以下指令生成 SSH Key:

$ ssh-keygen -t rsa -C "[email protected]"      

後面的 [email protected] 改為你在 Github 上注冊的郵箱,之後會要求确認路徑和輸入密碼,我們這使用預設的一路回車就行。成功的話會在 ~/ 下生成 .ssh 檔案夾,進去,打開 id_rsa.pub,複制裡面的 key。

回到 github 上,進入 Account => Settings(賬戶配置)。

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

左邊選擇 SSH and GPG keys,然後點選 New SSH key 按鈕,title 設定标題,可以随便填,粘貼在你電腦上生成的 key。

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

添加成功後界面如下所示

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

為了驗證是否成功,輸入以下指令:

$ ssh -T [email protected]
Hi tianqixin! You've successfully authenticated, but GitHub does not provide shell access.      

以下指令說明我們已成功連上 Github。

之後登入後點選" New repository " 如下圖所示:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

之後在在Repository name 填入 runoob-git-test(遠端倉庫名) ,其他保持預設設定,點選"Create repository"按鈕,就成功地建立了一個新的Git倉庫:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

建立成功後,顯示如下資訊:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

以上資訊告訴我們可以從這個倉庫克隆出新的倉庫,也可以把本地倉庫的内容推送到GitHub倉庫。

現在,我們根據 GitHub 的提示,在本地的倉庫下運作指令:

$ mkdir runoob-git-test                     # 建立測試目錄
$ cd runoob-git-test/                       # 進入測試目錄
$ echo "# 菜鳥教程 Git 測試" >> README.md     # 建立 README.md 檔案并寫入内容
$ ls                                        # 檢視目錄下的檔案
README
$ git init                                  # 初始化
$ git add README.md                         # 添加檔案
$ git commit -m "添加 README.md 檔案"        # 送出并備注資訊
[master (root-commit) 0205aab] 添加 README.md 檔案
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

# 送出到 Github
$ git remote add origin [email protected]:tianqixin/runoob-git-test.git
$ git push -u origin master      

以下指令請根據你在Github成功建立新倉庫的地方複制,而不是根據我提供的指令,因為我們的Github使用者名不一樣,倉庫名也不一樣。

接下來我們傳回 Github 建立的倉庫,就可以看到檔案已上傳到 Github上:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

檢視目前的遠端庫

要檢視目前配置有哪些遠端倉庫,可以用指令:

git remote      

執行個體

$ git remote
origin
$ git remote -v
origin    [email protected]:tianqixin/runoob-git-test.git (fetch)
origin    [email protected]:tianqixin/runoob-git-test.git (push)      

執行時加上 -v 參數,你還可以看到每個别名的實際連結位址。

提取遠端倉庫

Git 有兩個指令用來提取遠端倉庫的更新。

1、從遠端倉庫下載下傳新分支與資料:

git fetch      

該指令執行完後需要執行git merge 遠端分支到你所在的分支。

2、從遠端倉庫提取資料并嘗試合并到目前分支:

git merge      

該指令就是在執行 git fetch 之後緊接着執行 git merge 遠端分支到你所在的任意分支。

假設你配置好了一個遠端倉庫,并且你想要提取更新的資料,你可以首先執行 git fetch [alias] 告訴 Git 去擷取它有你沒有的資料,然後你可以執行 git merge [alias]/[branch] 以将伺服器上的任何更新(假設有人這時候推送到伺服器了)合并到你的目前分支。

接下來我們在 Github 上點選" README.md" 并線上修改它:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

然後我們在本地更新修改。

$ git fetch origin
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:tianqixin/runoob-git-test
   0205aab..febd8ed  master     -> origin/master      

以上資訊"0205aab..febd8ed master -> origin/master" 說明 master 分支已被更新,我們可以使用以下指令将更新同步到本地:

$ git merge origin/master
Updating 0205aab..febd8ed
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)      

檢視 README.md 檔案内容:

$ cat README.md 
# 菜鳥教程 Git 測試
## 第一次修改内容      

推送到遠端倉庫

推送你的新分支與資料到某個遠端倉庫指令:

git push [alias] [branch]      

以上指令将你的 [branch] 分支推送成為 [alias] 遠端倉庫上的 [branch] 分支,執行個體如下。

$ touch runoob-test.txt      # 添加檔案
$ git add runoob-test.txt 
$ git commit -m "添加到遠端"
master 69e702d] 添加到遠端
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 runoob-test.txt

$ git push origin master    # 推送到 Github      

重新回到我們的 Github 倉庫,可以看到檔案以及送出上來了:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

删除遠端倉庫

删除遠端倉庫你可以使用指令:

git remote rm [别名]      

執行個體

$ git remote -v
origin    [email protected]:tianqixin/runoob-git-test.git (fetch)
origin    [email protected]:tianqixin/runoob-git-test.git (push)

# 添加倉庫 origin2
$ git remote add origin2 [email protected]:tianqixin/runoob-git-test.git

$ git remote -v
origin    [email protected]:tianqixin/runoob-git-test.git (fetch)
origin    [email protected]:tianqixin/runoob-git-test.git (push)
origin2    [email protected]:tianqixin/runoob-git-test.git (fetch)
origin2    [email protected]:tianqixin/runoob-git-test.git (push)

# 删除倉庫 origin2
$ git remote rm origin2
$ git remote -v
origin    [email protected]:tianqixin/runoob-git-test.git (fetch)
origin    [email protected]:tianqixin/runoob-git-test.git (push)      

使用 CODING 倉庫

對于開發者而言 GitHub 已經不陌生了,在平時的開發中将代碼托管到 GitHub 上十分友善。但是、國内使用者通常會遇到一個問題就是: GitHub 的通路速度太慢。在阿裡雲和騰訊雲的主機上 clone 代碼時,如果主機的帶寬不夠大,clone 代碼簡直就是龜速。常常還會出現:丢包、失去連接配接等情況。對于這種情況,如果你想體驗飛速的 Git 服務,不妨試着用一下 騰訊雲開發者平台。相對于GitHub,CODING 除了提供免費的 Git 倉庫之外,還給我們提供了免費的私有倉庫(免費的普通會員提供 10 個私有項目、512M Git 倉庫容量)。此外、CODING 還為我們免費提供了,項目管理、任務管理、團隊管理、檔案管理等功能,十分強大。

下面,我是試着來建立一個 CODING 項目,并且将 GitHub 上的代碼遷移到 CODING。通常,分為三步:

  • 1、建立 CODING 項目
  • 2、将 GitHub 代碼 Pull 到本地
  • 3、本地關聯 CODING 倉庫,Push 代碼到 CODING

建立 CODING 項目:

登入 騰訊雲開發者平台 新增賬號,然後在項目管理頁面中建立項目,這一步不做贅述,按你的需要填寫項目名稱與描述,選擇 License 類型即可,關于 License 的選擇可以參考這篇文章:如何選擇開源許可證?。項目建立完成中,在右側菜單欄中的代碼頁籤可以對代碼進行相關的管理與操作

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建
git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

将 GitHub 代碼 Pull 到本地:

登入 GitHub 選擇你想要導入的倉庫并複制倉庫位址,在本地執行指令,将 GitHub 倉庫代碼拉下來:

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建
sudo git clone      

本地關聯 CODING 倉庫,Push 代碼到 CODING:

首先我們執行指令:

git remote -v

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

可以看到,目前的 git 已經關聯了一個遠端倉庫。

是以,接下來我們執行以下指令,來關聯 CODING 遠端倉庫(後面的倉庫位址需要替換為你的 CODING 項目的位址!) 第一條指令的作用是删除現有的倉庫關聯,後面兩條指令則是将倉庫關聯到 CODING 的位址,并且将代碼 Push 到 master 分支

sudo git remote rm origin
sudo git remote add origin https://git.coding.net/xxx/xxx.git
sudo git push -u origin master      

之後,我們再次進入 CODING 項目中代碼管理的頁面,便可以看到我們剛才 Push 上去的代碼了。至此、GitHub 上的項目已經完整遷移到了 CODING 平台!

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

CODING 倉庫的免密碼 Push/Pull

代碼遷移到 CODING 之後,我們發現,每次 Push/Pull 代碼的時候都會提示我們輸入使用者名和密碼。這是因為,我們的項目還沒有添加 SSH Key,隻能通過使用者名/密碼驗證。 而 CODING 是為我們提供了公鑰驗證的方式的,進入項目管理,在左側頁籤中點選"公鑰部署"按鈕,然後點選右側的"建立公鑰部署"

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

我們将本地的公鑰内容粘貼到對應位置,并且給公鑰命名一下(檢視/生成本機公鑰,可以參考這篇博文:檢視本機 ssh 公鑰,生成公鑰)。勾選"授予推送權限"則可以授予這台機器Push代碼的權限。

git 從入門到精通工程化專題之GitGit 工作流程Git 工作區、暫存區和版本庫Git 建立倉庫Git 基本操作Git 分支管理Git 檢視送出曆史Git 标簽Git 遠端倉庫(Github)Git 伺服器搭建Git 伺服器搭建

儲存好設定後,我們再次嘗試。此時,Push/Pull 代碼不在需要驗證使用者名密碼。至此,我們的代碼便完全托管在了 CODING 平台上,享受他的便捷與飛速吧!

如有疑問請查閱幫助文檔

現在 CODING 正在舉辦一場基于 Cloud Studio 工作空間的【我最喜愛的 Cloud Studio 插件評選大賽】。進入活動官網:https://studio.qcloud.coding.net/campaign/favorite-plugins/index,了解更多活動資訊。

Git 伺服器搭建

Git 伺服器搭建

上一章節中我們遠端倉庫使用了 Github,Github 公開的項目是免費的,但是如果你不想讓其他人看到你的項目就需要收費。

這時我們就需要自己搭建一台Git伺服器作為私有倉庫使用。

接下來我們将以 Centos 為例搭建 Git 伺服器。

1、安裝Git

$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git      

接下來我們 建立一個git使用者組和使用者,用來運作git服務:

$ groupadd git
$ useradd git -g git      

2、建立證書登入

收集所有需要登入的使用者的公鑰,公鑰位于id_rsa.pub檔案中,把我們的公鑰導入到/home/git/.ssh/authorized_keys檔案裡,一行一個。

如果沒有該檔案建立它:

$ cd /home/git/
$ mkdir .ssh
$ chmod 755 .ssh
$ touch .ssh/authorized_keys
$ chmod 644 .ssh/authorized_keys      

3、初始化Git倉庫

首先我們標明一個目錄作為Git倉庫,假定是/home/gitrepo/runoob.git,在/home/gitrepo目錄下輸入指令:

$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo

$ git init --bare runoob.git
Initialized empty Git repository in /home/gitrepo/runoob.git/      

以上指令Git建立一個空倉庫,伺服器上的Git倉庫通常都以.git結尾。然後,把倉庫所屬使用者改為git:

$ chown -R git:git runoob.git      

4、克隆倉庫

$ git clone [email protected]:/home/gitrepo/runoob.git
Cloning into 'runoob'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.      

192.168.45.4 為 Git 所在伺服器 ip ,你需要将其修改為你自己的 Git 服務 ip。

這樣我們的 Git 伺服器安裝就完成。

常用指令

  • git status
  • git remote
  • git clone [email protected]
  • git init
  • git remote add origin [email protected]:gupaoedu_com_vip/test10.git
  • git push -u origin master
  • git pull
  • git push
  • git checkout
  • git merge
  • git rebase
  • git tag 版本

經常幫人配置git的私鑰,來總結一下簡單的流程真心希望對大家有所幫助。

1.本地安裝好git;

2.桌面右鍵 Git Bash Here 打開git指令行;

3.ssh-keygen -t rsa -C "[email protected]"   (全部按enter);

4.cd ~/.ssh   (如果沒有執行第三步,則不會有這個檔案夾);

5.cat id_rsa.pub     在指令行打開這個檔案,會直接輸出密鑰;

6.複制,打開github   ,點自己頭像 >> settings >> SSH and GPG keys >>New SSH key 

7. titile  随便寫。  key裡    粘貼第六步的内容;完成。

版權聲明:本文為CSDN部落客「weixin_34244102」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。

原文連結:https://blog.csdn.net/weixin_34244102/article/details/91730560