# Remote repository

Git repository 除了本機以外，還可以是遠端 repository ，例如雲端 GitHub、Gitlab、Bitbucket，或者自架的 Git Server。

作為版本控制用途，Remote repository 不是必要的，除非想要多人協作開發共同的專案。

Git Repository Providers

- [Codeberg](https://codeberg.org/) - 德國非營利的軟體開發平台
- [GitLab](https://about.gitlab.com/)

##### Clone from remote repo.

```bash
# Specified version
git clone -b 8.3.0 https://github.com/OpenSIPS/opensips-cp.git /var/www/opensips-cp
```

##### Git remote

從遠端儲存庫下載專案或要推送本地專案至遠端儲存庫時，用來檢視、修改遠端儲存庫位址。

- branch (分支)有區分 local 與 remote，而 remote branch 預設為 origin 開頭。
- `git remote show` 資訊有時不是最新的，可以使用 `git remote update` 來更新。這指令也會更新遠端 branch 的 commit 紀錄，作用與 `git fetch` 相同。

```bash
# Show the configuration of the remote repository
git remote -v

origin	https://github.com/a-lang/sshto.git (fetch)
origin	https://github.com/a-lang/sshto.git (push)

# Get more information
git remote show origin

* 遠端 origin
  取得位址：https://github.com/a-lang/sshto.git
  推送位址：https://github.com/a-lang/sshto.git
  HEAD 分支：master
  遠端分支：
    master 已追蹤
  為 'git pull' 設定的本機分支：
    master 與遠端 master 合併
  為 'git push' 設定的本機引用：
    master 推送至 master (最新)

# Update the contents of remote branch
git remote update
```

##### Remote branches

本地庫的遠端 branch (分支) 清單

```bash
# Way 1
git branch -r

# Way 2
git remote show origin
```

##### Push

將本地庫的更新推送到遠端庫

```bash
# 推送本地更新至遠端庫分支 refactor
git push origin refactor
git push -u origin refactor  # 第一次推送本地更新至遠端庫分支 refactor

# 刪除遠端庫分支 refactor
git push --delete origin refactor

# 強制推送更新至遠端庫分支
# 強制推送會覆蓋遠端分支原有的 commit 紀錄，這僅適用在 pull request 的分支。
git push -f
```

##### Pull

更新遠端庫的異動紀錄至本地端，並且與本地 branch 自動作合併。

```bash
cd my_proj
git pull
```

Pull vs. Fetch

- Pull: 同步遠端庫與本地庫，且自動合併本地 branch
- Fetch: 同步遠端庫與本地庫，需手動合併本地 branch

##### 避免每次詢問密碼

輸入一次密碼，可以暫存系統 15 分鐘

```bash
git config --global credential.helper cache
```

##### SSH Key Authentication

```bash
# 建立 ssh-key
# 預設路徑: ~/.ssh/id_rsa (private key) , ~/.ssh/id_rsa.pub (public-key)
ssh-keygen -t rsa -b 4096 -C "alang@my-linux-desktop"
ssh-keygen -t ed25519 -C "alang@my-linux-desktop"

# Gitlab 網站匯入 public ssh-key
# 測試 ssh key authentication
# 如果輸出 Welcome to GitLab, @alang! 表示連線認證成功
ssh -T git@gitlab.shurafom.eu

# 下載專案
# NOTE: 位址必須是 git@XXX.xxx.xxx 開頭。
# 如果使用 https:// 則必須改用 Personal Token 認證方式  
git clone git@gitlab.shurafom.eu:myproject/myprog.git

```

GitHub: For specified Repo

\[YOUR-REPO\] ➜ Settings ➜ Security ➜ Deploy keys ➜ Add deploy key

- Title : *自訂*
- Key : *SSH 公鑰*

Linux 主機端

- 私鑰檔可以是預設檔名：`~/.ssh/id_rsa`
- 自訂的私鑰檔名，須執行 `ssh-add ~/.ssh/id_yourcustomname` 加入到 ssh-agent

```bash
# Testing SSH connection
ssh -T git@github.com
```

~/.ssh/config

```
Host github-project1
    User git
    HostName github.com
    IdentityFile ~/.ssh/github.project1.key
```

Usage

```bash
git clone git@github-project1:orgname/some_repository.git
```

##### Fetch  


Git 本地庫與遠端庫並不會自動保持同步，而是用指令 `git fetch` 手動將遠端庫的所有 branches 異動 (commit) 紀錄更新至本地端。注意：這指令不會將遠端庫的異動合併至本地庫的 branches 資料（與 `git pull` 不同）

1\. 如何知道遠端儲存庫有其他更新？

```bash
git remote show origin
```

```
* remote origin
  Fetch URL: https://github.com/redquinoa/health-checks.git
  Push  URL: https://github.com/redquinoa/health-checks.git
  HEAD branch: master
  Remote branch:
    master tracked
  Local branch configured for 'git pull':
    master merges with remote master
  Local ref configured for 'git push':
    master pushes to master (local out of date)
```

這行 *master pushes to master (local out of date)* 表示遠端庫有其他的更新。

2\. 更新遠端庫 branches 異動紀錄至本地端

- 遠端 branch: origin/master
- 本地 branch: master
- 檢視遠端 branch log 時，出現 *HEAD -&gt; master* 與 *origin/master* 不在同一行，表示本地庫與遠端庫版本不同步。

```bash
# 更新遠端 branches 異動紀錄至 local
git fetch

# 檢視遠端 branch 的 commit log 是否有更新
git branch -r         # List all remote branches
git log origin/master # Check the log for the remote branch origin/master

commit b62dc2eacfa820cd9a762adab9213305d1c8d344 (origin/master, origin/HEAD)
Author: Blue Kale <bluekale@example.com>
Date:   Mon Jan 6 14:32:45 2020 -0800
    Add initial files for the checks
commit 807cb5037ccac5512ba583e782c35f4e114f8599 (HEAD -> master)
Author: My name <me@example.com>
Date:   Mon Jan 6 14:09:41 2020 -800
    Add one more line to README.md
commit 3d9f86c50b8651d41adabdaebd04530f4694efb5
Author: Red Quinoa <55592533+redquinoa@users.noreply.github.com>
Date:   Sat Sep 21 14:04:15 2019 -0700
    Initial commit
```

3\. 合併遠端 branch 最新異動至本地 branch（手動同步）

- git status : 快速檢視本地 branch 與遠端 branch 有無內容差異

```bash
# 檢查狀態
git status

On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
nothing to commit, working tree clean

# 合併遠端 branch 至本地 branch
git merge origin/master

Updating 807cb50..b62dc2e
Fast-forward
 all_checks.py | 18 ++++++++++++++++++
 disk_usage.py | 24 ++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100755 all_checks.py
 create mode 100644 disk_usage.py
```

##### 複製遠端庫某個分支至本地庫分支  


```bash
# 檢視遠端的分支清單
git remote show origin

# 建立本地分支
git checkout <remote-branch-name>

# 檢視本地分支
git branch
```