首先,Git是一個開源的分佈式版本控制系統,用於敏捷高效地處理任何或小或大的項目。 Git 也是 Linus Torvalds 爲了幫助管理 Linux 內核開發而開發的一個開放源碼的版本控制軟件。 Git 與經常使用的版本控制工具 CVS, Subversion 等不一樣,它採用了分佈式版本庫的方式,沒必要服務器端軟件的支持。php
一、GIT是分佈式的,SVN不是:這是GIT和其它非分佈式的版本控制系統,例如SVN,CVS等,最核心的區別。html
二、GIT把內容按元數據方式存儲,而SVN是按文件:全部的資源控制系統都是把文件的元信息隱藏在一個相似.svn,.cvs等的文件夾裏。git
三、GIT分支和SVN的分支不一樣:分支在SVN中一點不特別,就是版本庫中的另外的一個目錄。github
四、GIT沒有一個全局的版本號,而SVN有:目前爲止這是跟SVN相比GIT缺乏的最大的一個特徵。算法
Git 的工做須要調用 curl,zlib,openssl,expat,libiconv 等庫的代碼,因此須要先安裝這些依賴工具。在有 yum 的系統上(好比 Fedora)或者有 apt-get 的系統上(好比 Debian 體系),下面就覺得例Centos/RedHat,命令安裝:shell
$ yum install curl-devel expat-devel gettext-devel \
openssl-devel zlib-devel
$ yum -y install git-core
$ git --version
git version 1.7.1
在 Windows 平臺上安裝 Git 一樣輕鬆,有個叫作 msysGit 的項目提供了安裝包,能夠到 GitHub 的頁面上下載 exe 安裝文件並運行:vim
安裝包下載地址:http://msysgit.github.io/緩存
完成安裝以後,就可使用命令行的 git 工具(已經自帶了 ssh 客戶端)了,另外還有一個圖形界面的 Git 項目管理工具。在開始菜單裏找到"Git"->"Git Bash",會彈出 Git 命令窗口,你能夠在該窗口進行 Git 操做。ruby
Git 提供了一個叫作 git config 的工具,專門用來配置或讀取相應的工做環境變量。服務器
這些環境變量,決定了 Git 在各個環節的具體工做方式和行爲。這些變量能夠存放在如下三個不一樣的地方:
/etc/gitconfig
文件:系統中對全部用戶都廣泛適用的配置。若使用 git config
時用 --system
選項,讀寫的就是這個文件。~/.gitconfig
文件:用戶目錄下的配置文件只適用於該用戶。若使用 git config
時用 --global
選項,讀寫的就是這個文件。.git/config
文件):這裏的配置僅僅針對當前項目有效。每個級別的配置都會覆蓋上層的相同配置,因此 .git/config
裏的配置會覆蓋 /etc/gitconfig
中的同名變量。在 Windows 系統上,Git 會找尋用戶主目錄下的 .gitconfig 文件。主目錄即 $HOME 變量指定的目錄,通常都是 C:\Documents and Settings\$USER。
此外,Git 還會嘗試找尋 /etc/gitconfig 文件,只不過看當初 Git 裝在什麼目錄,就以此做爲根目錄來定位。
用戶信息
配置我的的用戶名稱和電子郵件地址:
$ git config --global user.name "w3c"
$ git config --global user.email w3c@w3cschool.cn
若是用了 --global 選項,那麼更改的配置文件就是位於你用戶主目錄下的那個,之後你全部的項目都會默認使用這裏配置的用戶信息。
若是要在某個特定的項目中使用其餘名字或者電郵,只要去掉 --global 選項從新配置便可,新的設定保存在當前項目的 .git/config 文件裏。
文本編輯器
設置Git默認使用的文本編輯器, 通常可能會是 Vi 或者 vim。若是你有其餘偏好,好比 Emacs 的話,能夠從新設置::
$ git config --global core.editor emacs
差別分析工具
還有一個比較經常使用的是,在解決合併衝突時使用哪一種差別分析工具。好比要改用 vimdiff 的話:
$ git config --global merge.tool vimdiff
Git 能夠理解 kdiff3,tkdiff,meld,xxdiff,emerge,vimdiff,gvimdiff,ecmerge,和 opendiff 等合併工具的輸出信息。
查看配置信息
要檢查已有的配置信息,可使用 git config --list 命令:
$ git config --list
user.name=Scott Chacon
user.email=schacon@gmail.com
color.status=auto
color.branch=auto
color.interactive=auto
color.diff=auto
...
有時候會看到重複的變量名,那就說明它們來自不一樣的配置文件(好比 /etc/gitconfig 和 ~/.gitconfig),不過最終 Git 實際採用的是最後一個。
也能夠直接查閱某個環境變量的設定,只要把特定的名字跟在後面便可,像這樣:
$ git config user.name
Scott Chacon
通常工做流程以下:
下圖展現了 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 init
使用咱們指定目錄做爲Git倉庫:
git init newrepo
初始化後,在當前目錄下會出現一個名爲 .git 的目錄,全部 Git 須要的數據和資源都存放在這個目錄中。
若是當前目錄下有幾個文件想要歸入版本控制,須要先用 git add 命令告訴 Git 開始對這些文件進行跟蹤,而後提交:
$ git add *.c
$ git add README
$ git commit -m 'initial project version'
克隆倉庫的命令格式爲:git clone [url] 。好比,要克隆 Ruby 語言的 Git 代碼倉庫 Grit,能夠用下面的命令:
$ git clone git://github.com/schacon/grit.git
執行該命令後,會在當前目錄下建立一個名爲grit的目錄,其中包含一個 .git 的目錄,用於保存下載下來的全部版本記錄。若是要本身定義要新建的項目目錄名稱,能夠在上面的命令末尾指定新的名字:
$ git clone git://github.com/schacon/grit.git mygrit
一、git init
用 git init 在目錄中建立新的 Git 倉庫。 你能夠在任什麼時候候、任何目錄中這麼作,徹底是本地化的。
在目錄中執行 git init,就能夠建立一個 Git 倉庫了。好比咱們建立 abc項目:
$ mkdir abc
$ cd abc
$ git init
Initialized empty Git repository in /www/abc/.git/
# 在 /www/abc/.git/ 目錄初始化空 Git 倉庫完畢。
如今你能夠看到在你的項目目錄中有個 .git 的子目錄。 這就是你的 Git 倉庫了,全部有關你的此項目的快照數據都存放在這裏。
ls -a
. .. .git
二、git clone
使用 git clone 拷貝一個 Git 倉庫到本地,讓本身可以查看該項目,或者進行修改。
若是你須要與他人合做一個項目,或者想要複製一個項目,看看代碼,你就能夠克隆那個項目。 執行命令: git clone [url]。其中,[url] 爲你想要複製的項目,就能夠了。例如:
$ git clone git://github.com/schacon/simplegit.git
Initialized empty Git repository in /private/tmp/simplegit/.git/
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (86/86), done.
remote: Total 100 (delta 35), reused 0 (delta 0)
Receiving objects: 100% (100/100), 9.51 KiB, done.
Resolving deltas: 100% (35/35), done.
$ 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 最後一個 / 以後的項目名稱。若是你想要一個不同的名字, 你能夠在該命令後加上你想要的名稱。
(2)基本快照
一、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 .。如今咱們改個文件,再執行一下 git status:
$ vim README
$ 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 有兩個主要的應用場景。
在 hello.php 文件中輸入如下內容:
<?php echo 'www.abc.cn'; ?> $ git status -s A README AM hello.php $ git diff diff --git a/hello.php b/hello.php index e69de29..d1a9166 100644 --- a/hello.php +++ b/hello.php @@ -0,0 +1,3 @@ +<?php +echo 'www.abc.cn'; +?>
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..704cce7 --- /dev/null +++ b/README @@ -0,0 +1 @@ +w3cschool.cn diff --git a/hello.php b/hello.php new file mode 100644 index 0000000..d1a9166 --- /dev/null +++ b/hello.php @@ -0,0 +1,3 @@ +<?php +echo 'www.abc.cn'; +?>
四、git commit
使用 git add 命令將想要快照的內容寫入了緩存, 而執行 git commit 記錄緩存區的快照。
Git 爲你的每個提交都記錄你的名字與電子郵箱地址,因此第一步須要配置用戶名和郵箱地址。
$ git config --global user.name 'w3cschool'
$ git config --global user.email w3c@w3cschool.cn
接下來咱們寫入緩存,並提交對 hello.php 的全部改動。在首個例子中,咱們使用 -m 選項以在命令行中提供提交註釋。
$ git add hello.php
$ git status -s
A README
A hello.php
$ git commit -m 'test comment from abc.cn'
[master (root-commit) 85fc7e7] test comment from abc.cn
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)
以上輸出說明咱們在最近一次提交以後,沒有作任何改動,是一個"乾淨的工做目錄"。
若是你沒有設置 -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 ..." to unstage) # # modified: hello.php # ~ ~ ".git/COMMIT_EDITMSG" 9L, 257C
若是你以爲 git add 提交緩存的流程太過繁瑣,Git 也容許你用 -a 選項跳過這一步。命令格式以下:git commit -a
$ git commit -am 'changes to hello file'
[master 78b2670] changes to hello file
1 files changed, 2 insertions(+), 1 deletions(-)
五、git reset HEAD
git reset HEAD 命令用於取消緩存已緩存的內容。
這裏咱們有兩個最近提交以後又有所改動的文件。咱們將兩個都緩存,並取消緩存其中一個。
$ git status -s
M README
M hello.php
$ git add .
$ git status -s
M README
M hello.pp
$ git reset HEAD -- hello.php
Unstaged changes after reset:
M hello.php
$ git status -s
M README
M hello.php
如今你執行 git commit 將只記錄 README 文件的改動,並不含如今並不在緩存中的 hello.rb。
六、git rm
git rm 將文件從緩存區中移除。
如咱們刪除 hello.PHP文件:
$ git rm hello.php
rm 'hello.php'
$ ls
README
默認狀況下,git rm file 會將文件從緩存區和你的硬盤中(工做目錄)刪除。 若是要在工做目錄中留着該文件,可使用命令:
git rm --cached。
七、git mv
git mv 命令作得全部事情就是 git rm --cached, 重命名磁盤上的文件,而後再執行 git add 把新文件添加到緩存區。所以,雖然有 git mv 命令,但它有點多餘 。
幾乎每一種版本控制系統都以某種形式支持分支。使用分支意味着你能夠從開發主線上分離開來,而後在不影響主線的同時繼續工做。
有人把 Git 的分支模型稱爲"必殺技特性",而正是由於它,將 Git 從版本控制系統家族裏區分出來。建立分支命令:
git branch (branchname)
切換分支命令:
git checkout (branchname)
當你切換分支的時候,Git 會用該分支的最後提交的快照替換你的工做目錄的內容, 因此多個分支不須要多個目錄。合併分支命令:
git merge
你能夠屢次合併到統一分支, 也能夠選擇在合併以後直接刪除被併入的分支。
列出分支基本命令: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 'abc.cn' > test.txt
$ git add .
$ git commit -m 'add test.txt'
[master 048598f] add test.txt
2 files changed, 1 insertion(+), 3 deletions(-)
delete mode 100644 hello.php
create mode 100644 test.txt
$ ls
README test.txt
$ git checkout testing
Switched to branch 'testing'
$ ls
README hello.php
當咱們切換到"testing"分支的時候,咱們添加的新文件test.txt被移除了, 原來被刪除的文件hello.PHP文件又出現了。切換回"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 test2.txt
rm 'test2.txt'
$ ls
README test.txt
$ git commit -am 'removed test2.txt'
[newtest 556f0a0] removed test2.txt
1 file changed, 1 deletion(-)
delete mode 100644 test2.txt
$ git checkout master
Switched to branch 'master'
$ ls
README test.txt test2.txt
如你所見,咱們建立了一個分支,在該分支的上下文中移除了一些文件,而後切換回咱們的主分支,那些文件又回來了。
使用分支將工做切分開來,從而讓咱們可以在不一樣上下文中作事,並來回切換。
刪除分支命令: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 test2.txt
$ git merge newtest
Updating 2e082b7..556f0a0
Fast-forward
test2.txt | 1 -
1 file changed, 1 deletion(-)
delete mode 100644 test2.txt
$ ls
README test.txt
以上實例中咱們將 newtest 分支合併到主分支去,test2.txt 文件被刪除。
合併並不只僅是簡單的文件添加、移除的操做,Git 也會合並修改。
$ git branch
* master
$ cat test.txt
abc.cn
首先,咱們建立一個叫作"change_site"的分支,切換過去,咱們將內容改成 www.abc.cn 。
$ git checkout -b change_site
Switched to a new branch 'change_site'
$ vim test.txt
$ head -1 test.txt
www.abc.cn
$ git commit -am 'changed the site'
[change_site d7e7346] changed the site
1 file changed, 1 insertion(+), 1 deletion(-)
將修改的內容提交到 "change_site" 分支中。 如今,假如切換回 "master" 分支咱們能夠看內容恢復到咱們修改前的,咱們再次修改test.txt文件。
$ git checkout master
Switched to branch 'master'
$ head -1 test.txt
abc.cn
$ vim test.txt
$ cat test.txt
abc.cn
新增長一行
$ git diff
diff --git a/test.txt b/test.txt
index 704cce7..f84c2a4 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1,2 @@
bcd.cn
+新增長一行
$ git commit -am '新增長一行'
[master 14b4dca] 新增長一行
1 file changed, 1 insertion(+)
$ git merge change_site Auto-merging test.txt CONFLICT (content): Merge conflict in test.txt Automatic merge failed; fix conflicts and then commit the result. $ cat test.txt <<<<<<< HEAD abc.cn 新增長一行 ======= www.abc.cn >>>>>>> change_site
如今這些改變已經記錄到個人 "master" 分支了。接下來咱們將 "change_site" 分支合併過來。
咱們將前一個分支合併到 "master" 分支,一個合併衝突就出現了,接下來咱們須要手動去修改它。
$ vim test.txt
$ cat test.txt
www.abc.cn
新增長一行
$ git diff
diff --cc test.txt
index f84c2a4,bccb7c2..0000000
--- a/test.txt
+++ b/test.txt
@@@ -1,2 -1,1 +1,2 @@@
- w3cschool.cn
+ www.abc.cn
+新增長一行
在 Git 中,咱們能夠用 git add 要告訴 Git 文件衝突已經解決
$ git status -s
UU test.txt
$ git add test.txt
$ git status -s
M test.txt
$ git commit
[master 88afe0e] Merge branch 'change_site'
在使用 Git 提交了若干更新以後,又或者克隆了某個項目,想回顧下提交歷史,咱們可使用 git log 命令查看。針對咱們前一章節的操做,使用 git log 命令列出歷史提交記錄以下:
$ git log commit 88afe0e02adcdfea6844bb627de97da21eb10af1 Merge: 14b4dca d7e7346 Author: abc<abc.cn> Date: Sun Mar 1 15:03:42 2015 +0800 Merge branch 'change_site' Conflicts: test.txt commit 14b4dcadbdc847207651d5a9fae0d315057f346e Author: abc<abc.cn> Date: Sun Mar 1 14:53:15 2015 +0800 新增長一行 commit d7e734640da06055e107eaf29cf350b3f1de1c2c Author: abc<abc.cn> Date: Sun Mar 1 14:48:57 2015 +0800 changed the site commit 556f0a0637978097b82287ac665a717623b21f3f Author: abc<abc.cn> Date: Sun Mar 1 14:40:34 2015 +0800 removed test2.txt
咱們能夠用 --oneline 選項來查看歷史記錄的簡潔的版本。
$ git log --oneline
88afe0e Merge branch 'change_site'
14b4dca 新增長一行
d7e7346 changed the site
556f0a0 removed test2.txt
2e082b7 add test2.txt
048598f add test.txt
85fc7e7 test comment from abc.cn
咱們還能夠用 --graph 選項,查看歷史中何時出現了分支、合併。如下爲相同的命令,開啓了拓撲圖選項:
$ git log --oneline --graph
* 88afe0e Merge branch 'change_site'
|\
| * d7e7346 changed the site
* | 14b4dca 新增長一行
|/
* 556f0a0 removed test2.txt
* 2e082b7 add test2.txt
* 048598f add test.txt
* 85fc7e7 test comment from abc.cn
你也能夠用 '--reverse'參數來逆向顯示全部日誌。
$ git log --reverse --oneline
85fc7e7 test comment from abc.cn
048598f add test.txt
2e082b7 add test2.txt
556f0a0 removed test2.txt
d7e7346 changed the site
14b4dca 新增長一行
88afe0e 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 tag 給它打上標籤。
好比說,咱們想爲咱們的 w3cschoolcc 項目發佈一個"1.0"版本。 咱們能夠用 git tag -a v1.0 命令給最新一次提交打上(HEAD)"v1.0"的標籤。-a 選項意爲"建立一個帶註解的標籤"。 不用 -a 選項也能夠執行的,但它不會記錄這標籤是啥時候打的,誰打的,也不會讓你添加個標籤的註解。 我推薦一直建立帶註解的標籤。
$ git tag -a v1.0
當你執行 git tag -a 命令時,Git 會打開你的編輯器,讓你寫一句標籤註解,就像你給提交寫註解同樣。如今,注意當咱們執行 git log --decorate 時,咱們能夠看到咱們的標籤了:
$ git log --oneline --decorate --graph
* 88afe0e (HEAD, tag: v1.0, master) Merge branch 'change_site'
|\
| * d7e7346 (change_site) changed the site
* | 14b4dca 新增長一行
|/
* 556f0a0 removed test2.txt
* 2e082b7 add test2.txt
* 048598f add test.txt
* 85fc7e7 test comment from abc.cn
若是咱們忘了給某個提交打標籤,又將它發佈了,咱們能夠給它追加標籤。例如,假設咱們發佈了提交 85fc7e7(上面實例最後一行),可是那時候忘了給它打標籤。 咱們如今也能夠:
$ git tag -a v0.9 85fc7e7
$ git log --oneline --decorate --graph
* 88afe0e (HEAD, tag: v1.0, master) Merge branch 'change_site'
|\
| * d7e7346 (change_site) changed the site
* | 14b4dca 新增長一行
|/
* 556f0a0 removed test2.txt
* 2e082b7 add test2.txt
* 048598f add test.txt
* 85fc7e7 (tag: v0.9) test comment from abc.cn
若是咱們要查看全部標籤可使用如下命令:
$ git tag
v0.9
v1.0
指定標籤信息命令:
git tag -a <tagname> -m "abc.cn標籤"
PGP簽名標籤命令:
git tag -s <tagname> -m "abc.cn標籤"
Git 並不像 svn 那樣有個中心服務器。
目前咱們使用到的 Git 命令都是在本地執行,若是你想經過 Git 分享你的代碼或者與其餘開發人員合做。 你就須要將數據放到一臺其餘開發人員可以鏈接的服務器上。
要添加一個新的遠程倉庫,能夠指定一個簡單的名字,以便未來引用,命令格式以下:git remote add [shortname] [url] 。本例以Github爲例做爲遠程倉庫,若是你沒有Github能夠在官網Https://github.com/註冊。
因爲你的本地Git倉庫和GitHub倉庫之間的傳輸是經過ssh加密的,因此咱們須要配置驗證信息:使用如下命令生成SSH Key:
$ ssh-keygen -t rsa -C "youremail@example.com"
後面的your_email@youremail.com改成你在github上註冊的郵箱,以後會要求確認路徑和輸入密碼,咱們這使用默認的一路回車就行。成功的話會在~/下生成.ssh文件夾,進去,打開id_rsa.pub,複製裏面的key。
回到github上,進入 Account Settings(帳戶配置),左邊選擇SSH Keys,Add SSH Key,title隨便填,粘貼在你電腦上生成的key。
爲了驗證是否成功,輸入如下命令:
$ ssh -T git@github.com
Hi WongJay! You've successfully authenticated, but GitHub does not provide shell access.
如下命令說明咱們已成功連上 Github。以後登陸後點擊" New repository " 以下圖所示:
以後在在Repository name 填入 w3cschool.cn(遠程倉庫名) ,其餘保持默認設置,點擊"Create repository"按鈕,就成功地建立了一個新的Git倉庫:
建立成功後,顯示以下信息:
以上信息告訴咱們能夠從這個倉庫克隆出新的倉庫,也能夠把本地倉庫的內容推送到GitHub倉庫。如今,咱們根據GitHub的提示,在本地的倉庫下運行命令:
$ ls
README
W3Cschool教程測試.txt
test.txt
$ git remote add origin git@github.com:WongJay/w3cschool.cn.git
$ git push -u origin master
Counting objects: 21, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (15/15), done.
Writing objects: 100% (21/21), 1.73 KiB | 0 bytes/s, done.
Total 21 (delta 4), reused 0 (delta 0)
To git@github.com:WongJay/w3cschool.cn.git
* [new branch] master -> master
Branch master set up to track remote branch master from origin.
如下命令請根據你在Github成功建立新倉庫的地方複製,而不是根據我提供的命令,由於咱們的Github用戶名不同,倉庫名也不同。接下來咱們返回 Github 建立的倉庫,就能夠看到文件已上傳到Github上:
要查看當前配置有哪些遠程倉庫,能夠用命令:
git remote
$ git remote
origin
$ git remote -v
origin git@github.com:WongJay/w3cschool.cn.git (fetch)
origin git@github.com:WongJay/w3cschool.cn.git (push)
執行時加上 -v 參數,你還能夠看到每一個別名的實際連接地址。
Git 有兩個命令用來提取遠程倉庫的更新。
一、從遠程倉庫下載新分支與數據:
git fetch
該命令執行完後須要執行git merge 遠程分支到你所在的分支。
二、從遠端倉庫提取數據並嘗試合併到當前分支:
git pull
該命令就是在執行 git fetch 以後緊接着執行 git merge 遠程分支到你所在的任意分支。假設你配置好了一個遠程倉庫,而且你想要提取更新的數據,你能夠首先執行 git fetch [alias] 告訴 Git 去獲取它有你沒有的數據,而後你能夠執行 git merge [alias]/[branch] 以將服務器上的任何更新(假設有人這時候推送到服務器了)合併到你的當前分支。
接下來咱們在 Github 上點擊"w3cschoolW3Cschool教程測試.txt" 並在線修改它。以後咱們在本地更新修改。
$ git fetch origin
Warning: Permanently added the RSA host key for IP address '192.30.252.128' to the list of known hosts.
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 1), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:WongJay/w3cschool.cn
7d2081c..f5f3Dd5 master -> origin/master
以上信息"7d2081c..f5f3dd5 master -> origin/master" 說明 master 分支已被更新,咱們可使用如下命令將更新同步到本地:
$ git merge origin/master
Updating 7d2081c..f5f3dd5
Fast-forward
"w3cschool\350\217\234\351\270\237\346\225\231\347\250\213\346\265\213\350\257\225.txt" | 1 +
1 file changed, 1 insertion(+)
推送你的新分支與數據到某個遠端倉庫命令: git push [alias] [branch] 。以上命令將你的 [branch] 分支推送成爲 [alias] 遠程倉庫上的 [branch] 分支,實例以下。
$ git merge origin/master
Updating 7d2081c..f5f3dd5
Fast-forward
"w3cschool\350\217\234\351\270\237\346\225\231\347\250\213\346\265\213\350\257\225.txt" | 1 +
1 file changed, 1 insertion(+)
bogon:w3cschoolcc WongJay$ vim w3cschoolW3Cschool教程測試.txt
bogon:w3cschoolcc WongJay$ git push origin master
Everything up-to-date
刪除遠程倉庫你可使用命令:git remote rm [別名]
$ git remote -v
origin git@github.com:WongJay/w3cschool.cn.git (fetch)
origin git@github.com:WongJay/w3cschool.cn.git (push)
$ git remote add origin2 git@github.com:WongJay/w3cschool.cn.git
$ git remote -v
origin git@github.com:WongJay/w3cschool.cn.git (fetch)
origin git@github.com:WongJay/w3cschool.cn.git (push)
origin2 git@github.com:WongJay/w3cschool.cn.git (fetch)
origin2 git@github.com:WongJay/w3cschool.cn.git (push)
$ git remote rm origin2
$ git remote -v
origin git@github.com:WongJay/w3cschool.cn.git (fetch)
origin git@github.com:WongJay/w3cschool.cn.git (push)
接下來咱們將以 Centos 爲例搭建 Git 服務器。
$ yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-devel
$ yum install git
接下來咱們 建立一個git用戶組和用戶,用來運行git服務:
$ groupadd git
$ adduser git -g git
收集全部須要登陸的用戶的公鑰,公鑰位於id_rsa.pub文件中,把咱們的公鑰導入到/home/git/.ssh/authorized_keys文件裏,一行一個。
若是沒有該文件建立它:
$ cd /home/git/
$ mkdir .ssh
$ chmod 700 .ssh
$ touch .ssh/authorized_keys
$ chmod 600 .ssh/authorized_keys
首先咱們選定一個目錄做爲Git倉庫,假定是/home/gitrepo/w3cschoolcn.git,在/home/gitrepo目錄下輸入命令:
$ cd /home
$ mkdir gitrepo
$ chown git:git gitrepo/
$ cd gitrepo
$ git init --bare w3cschoolcn.git
Initialized empty Git repository in /home/gitrepo/w3cschoolcn.git/
以上命令Git建立一個空倉庫,服務器上的Git倉庫一般都以.git結尾。而後,把倉庫所屬用戶改成git:
$ chown -R git:git w3cschoolcn.git
$ git clone git@192.168.45.4:/home/gitrepo/w3cschoolcn.git
Cloning into 'w3cschoolcn'...
warning: You appear to have cloned an empty repository.
Checking connectivity... done.
192.168.45.4 爲 Git 所在服務器 ip ,你須要將其修改成你本身的 Git 服務 ip。
這樣咱們的 Git 服務器安裝就完成了,接下來咱們能夠禁用 git 用戶經過shell登陸,能夠經過編輯/etc/passwd文件完成。找到相似下面的一行:
git:x:503:503::/home/git:/bin/Bash
改成:
git:x:503:503::/home/git:/sbin/nologin