搭建git遠端伺服器

GeekWay發表於2014-10-27

搭建git遠端伺服器

我的官方部落格地址:www.wangminli.com


在公司裡使用git進行程式碼管理,犯了很多錯後,深深的體會到git的強大。儘管可以比較順暢的使用git了,但也只停留在使用它提交程式碼上,並不瞭解git伺服器是如何建立的,也不清楚本地分支是如何關聯到遠端分支的。這個疑問一隻縈繞在心頭,今天有空,決定將這一課補上。查詢了一些資料後,有所收穫,記錄以備忘。

宣告:這是我試用可行的一種方案,並沒有系統的研究各種方案的可行性,如您有更好的方案,請告知,謝謝!

建立遠端伺服器

建立遠端伺服器的原理很簡單,首先你要在本地有一個程式碼倉庫,然後將這個倉庫匯出為一個“裸倉庫”,最後將這個“裸倉庫”推送到遠端伺服器就OK了。“裸倉庫”聽起來很玄乎,其實就是僅包含本地倉庫中“.git”目錄中的部分檔案,不包含工作目錄的倉庫檔案。git為我們提供了建立這個“裸倉庫”的方法(git clone --bare *** ***)。

建立本地倉庫

為方便測試,首先我們的本地要有一個程式碼倉庫,我建立一個gittest的目錄,並將其作為程式碼倉庫。

wangminli@debian:~$ mkdir gittest
wangminli@debian:~$ cd gittest
wangminli@debian:~/gittest$ ls
wangminli@debian:~/gittest$ git init
初始化空的 Git 版本庫於 /home/wangminli/gittest/.git/

版本庫建立完畢後,git會為我們自動建立一個預設分支master,我們可以使用命令git branch檢視到這個分支。

wangminli@debian:~/gittest$ git branch 
* master

方便演示,我建立一個檔案並提交。

wangminli@debian:~/gittest$ > initialized.txt
wangminli@debian:~/gittest$ ls
initialized.txt
wangminli@debian:~/gittest$ git add initialized.txt
wangminli@debian:~/gittest$ git commit -m "initialized."
[master(根提交) f331862] initialized.
wangminli@debian:~/gittest$ git log --oneline
f331862 initialized.

建立裸倉庫

這時,我們簡單演示了下git的基本操作,並有了一些基礎檔案,下面我們用它進行測試。

我們回到根目錄下,使用命令git clone --bare gittest gittest.git

wangminli@debian:~$ git clone --bare gittest gittest.git
克隆到裸版本庫 'gittest.git'...
完成。
wangminli@debian:~$ ls
gittest  gittest.git
...

我們對比gittest.git(裸倉庫)和gittest中的.git檔案,發現除了少了幾個檔案外,其他並無二異,另外gittest.git中並不包含gittest中的工作目錄,既工作區的程式碼。

wangminli@debian:~$ ls gittest.git/ gittest/.git/
gittest/.git/:
branches  COMMIT_EDITMSG  config  description  HEAD  hooks  index  info  logs  objects  refs

gittest.git/:
branches  config  description  HEAD  hooks  info  objects  packed-refs  refs

將裸倉庫推送到遠端伺服器

基礎準備已經做好了,下面我們將這個“裸倉庫”推送到遠端伺服器一個指定位置。

scp -r gittest.git root@115.28.86.226:gittest
wangminli@debian:~$ scp -r gittest.git root@115.28.86.226:gittest
root@115.28.86.226's password: 
HEAD                                                                                                                        100%   23     0.0KB/s   00:00    
prepare-commit-msg.sample                                                                                                   100% 1239     1.2KB/s   00:00    
update.sample                                                                                                               100% 3611     3.5KB/s   00:00    
pre-rebase.sample                                                                                                           100% 4898     4.8KB/s   00:00    
pre-applypatch.sample                                                                                                       100%  398     0.4KB/s   00:00    
applypatch-msg.sample                                                                                                       100%  452     0.4KB/s   00:00    
commit-msg.sample                                                                                                           100%  896     0.9KB/s   00:00    
pre-commit.sample                                                                                                           100% 1704     1.7KB/s   00:00    
post-update.sample                                                                                                          100%  189     0.2KB/s   00:00    
packed-refs                                                                                                                 100%   85     0.1KB/s   00:00    
description                                                                                                                 100%   73     0.1KB/s   00:00    
9de29bb2d1d6434b8b29ae775ad8c2e48c5391                                                                                      100%   15     0.0KB/s   00:00    
c7c176e2f6069320b1e685e1d35c89f6f774ec                                                                                      100%   60     0.1KB/s   00:00    
31862e5ce318312448730612213ca36f897736                                                                                      100%  126     0.1KB/s   00:00    
config                                                                                                                      100%  115     0.1KB/s   00:00    
exclude                                                                                                                     100%  240     0.2KB/s   00:00    
wangminli@debian:~$ 

注意,遠端伺服器最初可以沒有gittest目錄,scp命令會自動建立沒有該目錄的目錄。 下面我們登入遠端伺服器檢視git伺服器是否建立。

[root@Debian ~]# ls
gittest 
.....
[root@Debian ~]# 

你會發現,建立的目錄名字是“gittest”,而不是“gittest.git“。這時,本地gittest.git中的檔案已在gittest目錄中了。

[root@Debian ~]# ls gittest/
branches  config  description  HEAD  hooks  info  objects  packed-refs  refs
[root@Debian ~]#

我們還會發現,使用git的一些常用命令無效了,就向上面提到的,因為它並不包含git的工作目錄。

[root@Debian ~]# cd gittest/
[root@Debian gittest]# git status
fatal: This operation must be run in a work tree
[root@Debian gittest]# git branches/
git: 'branches/' is not a git command. See 'git --help'.
[root@Debian gittest]# git branch
* master
[root@Debian gittest]# git log
commit f331862e5ce318312448730612213ca36f897736
Author: wangminli <wongminli@163.com>
Date:   Mon Oct 27 11:35:35 2014 +0800

    initialized.

至此,遠端git伺服器已經建立好了! 不過,為了更好的使用遠端git伺服器,我們還需要進行一些必要設定,如建立遠端分支等。

推送並關聯遠端分支

跟理解有所出入的是,遠端分支並不是在遠端git伺服器上建立的,而是以在本地基於一個提交(或分支)推送一個遠端分支的形式間接建立的,說白了就是推送一個已有分支,在推送的同時指定一個遠端分支名字,推送成功後,遠端分支也就建立了,如“git push origin master:zhangsan”。 另外,如果我們在本地建立一個分支,在不進行其他配置的情況下,是不會與遠端分支建立關聯的,因為它找不到需要關聯的遠端分支嘛。一個遠端分遠端分支可以在原有提交上建立,也可以在原有分支上建立。

還需要注意的一點是,我們剛才建立的gitdemo倉庫因為沒有與遠端建立關聯,無法直接推送和拉取,索性我們不需要它了,直接通過克隆(clone)遠端上的分支建立本地與遠端的關聯,克隆的倉庫已與遠端分支自動建立關聯。

下面進行演示,我們建立一個gittest1目錄,並克隆遠端分支

wangminli@debian:~$ mkdir gittest1
wangminli@debian:~$ cd gittest1
wangminli@debian:~/gittest1$ git clone root@115.28.86.226:gittest
正克隆到 'gittest'...
root@115.28.86.226's password: 
remote: Counting objects: 3, done.
Receiving objects: 100% (3/3), 215 bytes, done.
remote: Total 3 (delta 0), reused 0 (delta 0)
wangminli@debian:~/gittest1$ ls
gittest
wangminli@debian:~/gittest1$ cd gittest
wangminli@debian:~/gittest1/gittest$ ls
initialized.txt

我們發現,我們之前建立的initialized.txt已經克隆到了我們新的倉庫下! 下面我們建立一個遠端分支,供使用者zhangsan使用。

wangminli@debian:~/gittest1/gittest$ git branch 
* master
wangminli@debian:~/gittest1/gittest$ git push origin master:zhangsan
root@115.28.86.226's password: 
Total 0 (delta 0), reused 0 (delta 0)
To root@115.28.86.226:gittest
 * [new branch]      master -> zhangsan
wangminli@debian:~/gittest1/gittest$ git branch 
* master

origin是我們遠端git伺服器的名字。 我們推送一個遠端分支zhagnsan上去,並且注意到,本地並沒有zhangsan分支。 我們可以在本地手動建立zhagnsan分支,並與遠端的zhangsan分支建立關聯,但有簡便方法將這兩步合為一步,那就是“檢出”(checkout)操作,我們檢出zhangsan分支並跟蹤這個遠端分支即可。 實現方式是將遠端的zhangsan檢出的同時跟蹤(track)這個分支就可以了。

wangminli@debian:~/gittest1/gittest$ git checkout --track origin/zhangsan
Branch zhangsan set up to track remote branch zhangsan from origin.
切換到一個新分支 'zhangsan'
wangminli@debian:~/gittest1/gittest$ git branch 
  master
* zhangsan
wangminli@debian:~/gittest1/gittest$ 

執行速度非常快,我們推測,遠端zhagnsan分支在本地也是存在的,只是我們沒有配置,所以它並沒有顯現出來。 好了,我們在本地也建立了一個分支上去。

測試

下面我們在zhangsan分支上提交檔案,並推送(push)測試一下。

wangminli@debian:~/gittest1/gittest$ git branch 
  master
* zhangsan
wangminli@debian:~/gittest1/gittest$ > zhangsan.txt
wangminli@debian:~/gittest1/gittest$ git add zhangsan.txt
wangminli@debian:~/gittest1/gittest$ git commit -m "zhangsan.txt"
[zhangsan 1ce074e] zhangsan.txt
 0 個檔案被修改
 create mode 100644 zhangsan.txt
wangminli@debian:~/gittest1/gittest$ git status
# 位於分支 zhangsan
# 您的分支領先 'origin/zhangsan' 共 1 個提交。
#
無須提交(乾淨的工作區)
wangminli@debian:~/gittest1/gittest$ git push
root@115.28.86.226's password: 
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 250 bytes, done.
Total 2 (delta 0), reused 0 (delta 0)
To root@115.28.86.226:gittest
   f331862..1ce074e  zhangsan -> zhangsan
wangminli@debian:~/gittest1/gittest$ 

可以看出我們推送(push)成功了。 為了能看到效果,我們再克隆一下這個版本庫,看看zhangsan.txt是否在zhangsan分支下。

wangminli@debian:~$ mkdir gittest2
wangminli@debian:~$ cd gittest2
wangminli@debian:~/gittest2$ git  clone root@115.28.86.226:gittest
正克隆到 'gittest'...
root@115.28.86.226's password: 
remote: Counting objects: 5, done.
remote: Compressing objects: 100% (3/3), done.
Receiving objects: 100% (5/5), 434 bytes, done.
remote: Total 5 (delta 0), reused 0 (delta 0)
wangminli@debian:~/gittest2$ ls
gittest
wangminli@debian:~/gittest2$ cd gittest/
wangminli@debian:~/gittest2/gittest$ ls
initialized.txt
wangminli@debian:~/gittest2/gittest$ git branch 
* master   # 預設顯示的只有master分支
wangminli@debian:~/gittest2/gittest$ git checkout --track origin/zhangsan
Branch zhangsan set up to track remote branch zhangsan from origin.
切換到一個新分支 'zhangsan'
wangminli@debian:~/gittest2/gittest$ git branch 
  master
* zhangsan
wangminli@debian:~/gittest2/gittest$ ls
initialized.txt  zhangsan.txt  # zhangsan.txt出來了!
wangminli@debian:~/gittest2/gittest$ 

至此,一個簡單的git伺服器搭建完成了,可以在上面進行一些複雜的操作了。

當然,對git伺服器的搭建還遠不止這些,還有更多的知識等待我們研究使用。

相關文章