Git Bare Repo
===
###### tags: `git` `GSS`
## 前言
遇到一個情境是需要將 Subversion 上的專案搬到 Git 上,但原本的 Subversion 將會有其他人繼續開發,而 Git 上後續變更的內容將不會推回 Subversioin 上,但 Subversion 上的版本將不會頻繁地更新回 Git 上,所以更像是 Subversion **單向** 的更新/匯出到 Git 上。
在使用 **subgit** 工具轉換時,Subversion 轉出來的是一個 Bare Repo,故有了此篇的 Bare Repo 簡介。
詳情: [Subversion to Git](https://hackmd.io/@hbdoy/By5D89GsH)
基本 Git 教學: [Git 筆記](https://hackmd.io/@hbdoy/By5kZvuzx)
## 簡介
Git 儲存庫 (Git Repository) 大致可以分為三種
* 本地的儲存庫 (local repository)
* 共用的儲存庫 (shared repository)
* 遠端的儲存庫 (remote repository)
其實都是差不多的東西,Git 是分散式的版本控制,所以只是放置的位置、使用者不同而已。
## local repository
```
$ git init myproject
$ cd myproject
$ ls
.git/
```
用 ``init`` 不帶參數新增的專案包含: 工作目錄 (Working Directory) + Git 儲存庫 (Git Repository)
- **工作目錄**: 放置程式的地方,ex: ``.py``、``.js`` 的檔案
- **Git 儲存庫**: ``.git`` 資料夾
## remote repository
常見的託管平台: github、gitlab、BitBucket、...etc
遠端已經存在的專案
```
$ git clone http://github.com/hbdoy/xxx
```
將 local 的 repo 首次提交
```
$ git remote add origin https://github.com/hbdoy/xxx.git
$ git push -u origin master
// also you can use
$ git push --all
$ git push --tags
// or
$ git push --mirror
```
若遠端的 repo 網址改變,可以修改 origin 位址
```
$ git remote set-url origin https://github.com/hbdoy/new_xxx.git
```
## shared repository
和 ``remote repository`` 差不多,都可供多人同時使用開發,實作上也可以理解為 **Git Bare Repo** (裸庫)
```
$ git init --bare bareproject
```
不同於上面,**Bare Repo** 只有 **Git 儲存庫** (Git Repository) 而已,也就是沒有 **工作目錄**,因為沒有程式檔案,所以你無法在上面 ``git add``、``git commit``,他的用意也不是要讓你在上面開發的。
**Bare Repo** 雖說有 Git 儲存庫,但他沒有 ``.git`` 資料夾,而是將裡面的內容直接放到專案根目錄下,專案的資料夾名稱習慣會在最後面加上 ``.git``,EX: bareproject.git
``bareproject.git/``

對比一般含有工作目錄的 Repo

:::success
Bare Repo 的儲存庫內容物其實不完全等於 ``.git`` 中的東西,``.git`` 還會包含一些工作目錄下的資訊,而這些資訊不會放到 Bare Repo 中
:::
### 用途
**Bare Repo** 像是一個 Git Server,可以讓別人 clone 下來開發,開發完再 push 回去,比起上面兩者是用來開發(工作)用的,Bare Repo 是用來分享(共享)的,而且沒有存著程式檔案,整個專案資料夾容量較小。
### 情境
- 在 Linux 上建立 Bare Repo,讓數個開發者透過 ssh 來存者這個資料夾,進行 clone & push 等操作
> 如何在 Linux 上建立 Remote Bare Git Repo 可參考:
1. https://blog.gtwang.org/linux/linux-git-server-using-ssh/
2. https://stevenitlife.blogspot.com/2015/02/repository.html
- 或是建立在其他資料夾同步軟體,EX: Google Sync、Dropbox
### 差異
- **一般 Git Repo** 用來開發,工作目錄存著``程式檔案``、儲存庫記錄著所有``檔案的版本訊息``
- **Bare Repo** 用來單純紀錄``檔案的版本訊息``,中心點上建立一個 Bare Repo,所有專案成員可以 push 自己編輯的版本訊息到這個 Repo
## Bare Repo 常用指令
### 建立
#### local
```
$ git --bare init xxx
```
#### 將 Remote Repo 轉成 Bare Repo
```
$ git clone --bare http://github.com/hbdoy/mypoject
```


### Clone
#### Clone From Bare Repo
此處示範 clone 本地上的 bare repo
```
$ git clone roulette.git
```

可以看到 Bare Repo Clone 出來的專案自動長出工作目錄

但要注意他的 origin,若要推到其他 remote repo 記得修改

### Push
#### Push to Bare Repo
延續上方的 clone from local bare repo
``$ cd roulette/``
1. 在 ``roulette`` 下新增一個 ``test.txt`` 檔案

2. git add、git commit
3. git push (to bare repo)

進入一開始 clone 來源的 bare repo
``$ cd roulette.git/``
此時可以看到剛剛 clone 來源的 bare repo: ``roulette.git`` 已經多了一個 git log

但是一樣不會看到 ``test.txt`` 檔案

### 搬遷 Remote Git Repo 情境
#### 本地沒有完整專案
不需要 clone 一大包東西下來,可以 clone 一個 bare git repo (只有 git 儲存庫),再推到新位址去就好
```
$ git clone --bare https://github.com/hbdoy/xxx
```
```
$ cd xxx.git
$ git push --mirror https://github.com/hbdoy/new_project
```
### 參考文件
https://blog.csdn.net/pcplayer/article/details/72784096
https://ithelp.ithome.com.tw/articles/10132804
https://www.saintsjd.com/2011/01/what-is-a-bare-git-repository/