git 實作練習 5

@ver 0.1.1 @date 2019-04-19 21:37:21 (星期五)

上一篇實作遠端倉庫, 衝突合併後, 不同的開發者出現寫入權限問題

這一篇我們重頭再來, 但透過 ssh 使用一個共用的帳號, 就叫它 g , 注意 帳號就一個字 g , git 的第一個英文字, 可以少打幾個字

注意 以下的文章, 若有 #### **@G** 標記, 表示不同於上一篇的差異說明, 請仔細閱讀

來源 : 伺服器上的 Git - 架設伺服器

  1. 開發者 : 金鑰

### 每位開發者請使用 ssh-keygen 各自建立

#### 命令 bash cd ~ mkdir .ssh chmod 700 .ssh cd .ssh ls -la ssh-keygen -t rsa # 一直按 ENTER 直到結束 ls -la # 可以看到 `公開金鑰 id_rsa.pub` 及 `私密金鑰 id_rsa` 兩個檔案 # 以下文章簡稱 `公鑰` 及 `私鑰`

#### 執行結果 shell [alex2@nvda ~ ]$ cd ~ [alex2@nvda ~ ]$ mkdir .ssh [alex2@nvda ~ ]$ chmod 700 .ssh [alex2@nvda ~ ]$ cd .ssh [alex2@nvda ~/.ssh ]$ ls -la 總計 8 drwx------ 2 alex2 admin 4096 4月 13 08:04 . drwxr-xr-x 9 alex2 admin 4096 4月 19 13:29 .. [alex2@nvda ~/.ssh ]$ [alex2@nvda ~/.ssh ]$ ssh-keygen -t rsa Generating public/private rsa key pair. Enter file in which to save the key (/home/alex2/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /home/alex2/.ssh/id_rsa. Your public key has been saved in /home/alex2/.ssh/id_rsa.pub. The key fingerprint is: SHA256:8QjjdgpuJBgbfYEPZpeSofmM16BDy59eyVdop643LTg alex2@nvda.org.tw The key's randomart image is: +---[RSA 2048]----+ | .+.. | | +B o. | |=+o=. o . | |oX.+.. o.+ | |*o= + ooSo. | | o.+oooo+ | | oo+oo. | | ...Eo+ . | | . .+.o | +----[SHA256]-----+ [alex2@nvda ~/.ssh ]$ [alex2@nvda ~/.ssh ]$ ls -la 總計 16 drwx------ 2 alex2 admin 4096 4月 19 22:10 . drwxr-xr-x 9 alex2 admin 4096 4月 19 13:29 .. -rw------- 1 alex2 admin 1675 4月 19 22:10 id_rsa -rw-r--r-- 1 alex2 admin 399 4月 19 22:10 id_rsa.pub [alex2@nvda ~/.ssh ]$

複製一份自己的 公鑰/tmp/ 目錄下, 但每個人要先改名, 避免檔名重複. 稍後給共用帳號 g 加入到它的 authorized_keys 讓 git 認證用, 完成後即可刪除

例如 : cp ~/.ssh/id_rsa.pub /tmp/id_rsa.alex.pub

  1. 新增本機 git 共用的帳號 g

### 新增帳號 g

#### 命令 bash sudo -i adduser g su g cd mkdir .ssh ls -la .ssh

#### 執行結果 shell [alex@nvda ~ ]$ sudo -i [sudo] password for alex: root@nvda:~# adduser g ...(略) Is the information correct? [Y/n] root@nvda:~# root@nvda:~# su g g@nvda:/root$ cd g@nvda:~$ mkdir .ssh g@nvda:~$ g@nvda:~$ ls -la .ssh 總計 8 drwxr-xr-x 2 g g 4096 4月 19 22:02 . drwxr-xr-x 3 g g 4096 4月 19 22:02 .. g@nvda:~$ ### 所有開發者的公鑰

我先把我兩個帳號的公鑰加入 ~/.ssh/authorized_keys , 其他開發請自行想辦法操作加入 :-)

#### 命令 bash ls -l /tmp/*.pub cat /tmp/id_rsa.alex.pub >> ~/.ssh/authorized_keys cat /tmp/id_rsa.alex2.pub >> ~/.ssh/authorized_keys ...其他開發請自行想辦法操作加入 :-D

#### 執行結果 shell g@nvda:~$ ls -l /tmp/*.pub -rw-r--r-- 1 alex2 admin 399 4月 19 22:20 /tmp/id_rsa.alex2.pub -rw-r--r-- 1 alex admin 398 4月 19 22:20 /tmp/id_rsa.alex.pub g@nvda:~$ cat /tmp/id_rsa.alex.pub >> ~/.ssh/authorized_keys g@nvda:~$ cat /tmp/id_rsa.alex2.pub >> ~/.ssh/authorized_keys g@nvda:~$ ls -l ~/.ssh/authorized_keys -rw-r--r-- 1 g g 797 4月 19 22:25 /home/g/.ssh/authorized_keys g@nvda:~$

### 重要 不淮 g 登入 shell

請在完成 g 的遠端倉庫並初始化後再設定.

git 有一個額外的防範措施, 它內建 git-shell 工具限制此帳號的活動範圍. 只要把 /usr/bin/git-shell 用戶就無法使用普通的 bash 或者 csh 的 shell 程式.

#### 命令 bash sudo vipw

#### 執行結果 shell g:x:1002:1001:,,,:/home/g:/bin/bash # 改為 g:x:1002:1001:,,,:/home/g:/usr/bin/git-shell

  1. 建立者 : 遠端倉庫

### 建立本機的建立遠端倉庫並初始化

重要 只要執行一次.

我們把遠端倉庫放在 /home/g/repo 目錄名稱不重要, 用新的使用者 g 建立, 並設定共同開發者群組權限.

#### 命令 bash sudo -i #### **@G** 切換為帳號 g su g #### **@G** 回到 g 的家 cd /home/g mkdir repo cd repo git init --bare ls -la cd .. #### **@G** 權限, `o-rwx` , 好像 `g-rwx` 也可以設, 因為所有共同開發者都只會用到 `user g` chmod -fR o-rwx repo/ tree -f repo/ du -csb repo/

#### 執行結果及說明 ``shell # 更換為 root 身份 [alex@nvda ~ ]$ sudo -i # **注意** 切換為帳號 g root@nvda:~# su g # **注意** 回到 g 的家 g@nvda:/root$ cd /home/g # 建立遠端倉庫子目錄, 名為repo` g@nvda:~$ mkdir repo # 進入子目錄 g@nvda:~$ cd repo # 遠端倉庫初始化 g@nvda:~/repo$ git init --bare Initialized empty Git repository in /home/g/repo/ # 查看 g@nvda:~/repo$ ls -la 總計 40 drwxr-xr-x 7 g g 4096 4月 19 22:57 . drwxr-xr-x 4 g g 4096 4月 19 22:57 .. drwxr-xr-x 2 g g 4096 4月 19 22:57 branches -rw-r--r-- 1 g g 66 4月 19 22:57 config -rw-r--r-- 1 g g 73 4月 19 22:57 description -rw-r--r-- 1 g g 23 4月 19 22:57 HEAD drwxr-xr-x 2 g g 4096 4月 19 22:57 hooks drwxr-xr-x 2 g g 4096 4月 19 22:57 info drwxr-xr-x 4 g g 4096 4月 19 22:57 objects drwxr-xr-x 4 g g 4096 4月 19 22:57 refs g@nvda:~/repo$

# 統計 repo 有 9 個目錄, 14 個檔案 g@nvda:~/repo$ cd .. g@nvda:~/repo$ tree -f repo/ ...(略) 9 directories, 14 files

# 統計總 Bytes 為 56630 g@nvda:~/repo$ du -cshb repo/ 56630 repo/ 56630 總計 g@nvda:~/repo$ ```

### 共同開發者們, 權限可讀寫

重要 : 因為以後所有 git push pull 的帳號都會是 g 所以不用處理權限可讀寫的問題.

  1. 建立者 : laravel 基礎框架

### 基礎框架

重要 也是只要執行一次

回到建立者的身份及家目錄, 現在是 alex, 我們從頭開始建立一個新的 laravel 專案, 暫時先叫做 prj0, 名稱不重要, 這只會當作基礎起點框架上傳到遠端倉庫.

後續此所有共同開發者, 都將會在每個人各自家目錄 clone 回來的專案目錄裡修改操作.

### 建立全新 laravel 專案

建立遠端倉庫用的 laravel 基礎框架時, 先不處理資料庫設定, 但之後各自要把它完成. 每位開發者可以有各自開發用資料庫, 公用測試版也有它的資料庫. 當然, 網站正式上線一定會有正式版專用的資料庫.

同時也不處理 .envvendor 的 composer 安裝, 這些檔案都被禁止或者不需要上傳至遠端倉庫, 前者是安全問題, 後者是跟隨原開發者會有經常性變動. 詳細可查閱 .gitignore 檔案.

#### 命令及說明 ```shell [alex@nvda ~ ]$ laravel new prj0 # 等待約 60 秒 ... 完成 [alex@nvda ~ ]$ cd prj0/ [alex@nvda ~/prj0 ]$ php artisan -V # 版本 Laravel Framework 5.8.12

# 修改系統基礎設定 [alex@nvda ~/prj0 ]$ vi config/app.php # 時間 timezone 預設 UTC, 改為 Asia/Taipei # 本地化 locale 預設 en, 改為 zh-TW # (可不用修改) 另外有一個 'fallback_locale' => 'en', 這個是指如果 'zh-TW' 找不到的話, 它要找誰的語言來替代顯示, 因為所有各種版本都一定有英文對應文字, 所以就用 'en' 即可, 改成 'zh-TW' 或其他語言也沒有什麼問題, 只是可能會顯示空白, 也許剛好可以拿來測試未翻譯本地化的文字. ```

### git init 及 commit 基礎框架 shell git init # Initialized empty Git repository in /home/alex/prj0/.git/ git add . # 本地第一次提交 git commit -m '創立遠端倉庫用的 laravel 基礎框架 5.8.12' git log [alex@nvda ~/prj0 ]$ git log 1 commit 281f0cbb70b2b78e0b65643bc889f6b5adbad636 2 Author: alex <alex@forblind.org.tw> 3 Date: Wed Apr 17 07:41:40 2019 +0800 4 5 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex@nvda ~/prj0 ]$

### 重要 : 設定 git 本地倉庫到遠端倉庫的連結

> 注意 這一個版本會用到 ssh 連結 > > 如果是從本機以外, 例如我在家裡用 Mac 連回 NVDA 主機, 則改成外部 IP, 但要先完成下列工作, 即可正常使用

#### 命令 bash #### **@G** 以下為 g@127.0.0.1 本機內部連結版本 git remote add origin g@127.0.0.1:/home/g/repo #### **@G** 以下為 g@172.104.76.106 從本機以外的連結版本 #### **@G** git remote add origin g@172.104.76.106:/home/g/repo #### **@G** 以下為舊版本, 請比對它們兩個的差異 #### **@G** git remote add origin 127.0.0.1:/home/repo

### git push 遠端倉庫

第一次 push 會要求 The authenticity of host '127.0.0.1 (127.0.0.1)'... 的授權, 請輸入 yes 即可.

#### 命令 bash git push origin master

#### 執行結果 ```shell [alex@nvda ~/prj0 ]$ git push origin master The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. ECDSA key fingerprint is SHA256:kvXp+0IOtRbKfesB+OxXE2WuNlNeE8WmaY32oZIEfGA. Are you sure you want to continue connecting (yes/no)?

Counting objects: 116, done. Delta compression using up to 2 threads. Compressing objects: 100% (98/98), done. Writing objects: 100% (116/116), 236.51 KiB | 0 bytes/s, done. Total 116 (delta 9), reused 0 (delta 0) remote: Resolving deltas: 100% (9/9), done. To 127.0.0.1:/home/g/repo * [new branch] master -> master [alex@nvda ~/prj0 ]$ ```

完成 建置 laravel 基礎框架 5.8.12 並推送到 本機內部的遠端倉庫

#### 遠端倉庫第一次 push 之後, 跟先前原始 bare 時統計比對

```shell # 統計 repo 有 9 個目錄, 17 個檔案 g@nvda:~$ tree -f repo/ ...(略) 9 directories, 17 files

# 統計總 Bytes 為 303173 g@nvda:~$ du -csb repo/ 303173 repo/ 303173 總計 g@nvda:~$ ```

#### 番外篇 : 如何在 Mac 使用 ssh 公鑰, 免輸入密碼登入主機 1. Mac 就是 *nix 系統, 跟第一小節作法相同 2. ssh-keygen -t rsa 3. 產生 id_rsa, id_rsa.pub 4. ssh-copy-id alex2@172.104.76.106, 有錯誤, 要加選項 [alexkuo : ~/.ssh ] ➠ $ ssh-copy-id alex2@172.104.76.106 /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 6 key(s) remain to be installed -- if you are prompted now it is to install the new keys Received disconnect from 172.104.76.106 port 22:2: Too many authentication failures Disconnected from 172.104.76.106 port 22 [alexkuo : ~/.ssh ] ➠ $ 5. ssh-copy-id -o IdentitiesOnly=yes alex2@172.104.76.106 ``` [alexkuo : ~/.ssh ] ➠ $ ssh-copy-id -o IdentitiesOnly=yes alex2@172.104.76.106 /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: INFO: 6 key(s) remain to be installed -- if you are prompted now it is to install the new keys alex2@172.104.76.106's password:

Number of key(s) added: 6

Now try logging into the machine, with: "ssh -o 'IdentitiesOnly=yes' 'alex2@172.104.76.106'" and check to make sure that only the key(s) you wanted were added. 6. 回到 NVDA 主機, 查看 `cat ~/.ssh/authorized_keys` 會有新的公鑰加入此檔案, 時間則是此刻 [alex2@nvda ~/.ssh ]$ ll ~/.ssh/authorized_keys -rw------- 1 alex2 admin 2286 4月 20 14:38 /home/alex2/.ssh/authorized_keys 7. ssh -o IdentitiesOnly=yes alex2@172.104.76.106 仍然要輸入密碼 [alexkuo : ~ ] ➠ $ ssh -2 -o IdentitiesOnly=yes alex2@172.104.76.106 alex2@172.104.76.106's password: 8. ssh -o IdentitiesOnly=yes alex2@172.104.76.106 -i ~/.ssh/nvda.alex2.id_rsa [alexkuo : ~ ] ➠ $ ssh -2 -o IdentitiesOnly=yes alex2@172.104.76.106 -i ~/.ssh/nvda.alex2.id_rsa Linux nvda.org.tw 4.18.16-x86_64-linode118 #1 SMP PREEMPT Mon Oct 29 15:38:25 UTC 2018 x86_64

The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Sat Apr 20 14:08:06 2019 from 122.116.30.130 alex2@nvda:~$ ```

  1. 開發者 : clone 並補齊 laravel 設定

### 把遠端倉庫複製回開發者工作目錄

重要 共同開發者只要操作一次 clone

#### @G 注意 git clone 路徑的差異

目前實驗的開發者是 alex2, 但 git author name 設為 ben 便於識別. 先回到自己的家目錄, git clone g@127.0.0.1:/home/g/repo 複製遠端倉庫的程式碼回來

> 補充 : git clone <repository> [<directory>] > > 也就是說, git clone g@127.0.0.1:/home/g/repogit clone g@127.0.0.1:/home/g/repo benPrj 皆可, 而後者更方便, 原先 clone 回來預設目錄名稱, 直接指定為自己想要的新名稱.

#### 命令 bash cd ~ #### **@G** 注意 `git clone` 路徑的差異 git clone g@127.0.0.1:/home/g/repo ls -ld repo mv repo benPrj # 或者直接指定目錄新名稱 git clone g@127.0.0.1:/home/g/repo benPrj cd benPrj ls -l .env ls -l vendor

#### 執行結果及說明 ```shell # 本機對本機, 只有 303173 Bytes, 所以 clone 會很快, 咻一下就結束 [alex2@nvda ~ ]$ git clone g@127.0.0.1:/home/g/repo benPrj Cloning into 'benPrj'... The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. ECDSA key fingerprint is SHA256:kvXp+0IOtRbKfesB+OxXE2WuNlNeE8WmaY32oZIEfGA. Are you sure you want to continue connecting (yes/no)? yes

Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts. remote: Counting objects: 116, done. remote: Compressing objects: 100% (89/89), done. remote: Total 116 (delta 9), reused 116 (delta 9) Receiving objects: 100% (116/116), 236.51 KiB | 0 bytes/s, done. Resolving deltas: 100% (9/9), done. [alex2@nvda ~ ]$

# 此時會 git 會自動幫我們建立一個名為 benPrj 子目錄 [alex2@nvda ~ ]$ ls -ld benPrj/ drwxr-xr-x 12 alex2 admin 4096 4月 19 23:25 benPrj/

# 改成自己喜歡的工作目錄名, 或移動到其他自己方便操作的子目錄之下(例如, 個人偏好放在 ~/jobs/ 之下), 都不會影響開發工作

# git 預設禁止把 .env 檔跟 vendor 目錄放進去追踪, 所以 沒有此一檔案或目錄, 都是正常的 [alex2@nvda ~/benPrj ]$ ls -l .env ls: 無法存取 '.env': 沒有此一檔案或目錄 [alex2@nvda ~/benPrj ]$ ls -l vendor ls: 無法存取 'vendor': 沒有此一檔案或目錄 [alex2@nvda ~/benPrj ]$ ```

首要工作, 就是把 .envvendor/ 目錄裡的套件程式生出來

#### 命令及說明 bash cd ~/benPrj/ composer install npm install cp .env.example .env vi .env php artisan -V

#### 執行結果及說明 ```shell # 進工作目錄 [alex2@nvda ~ ]$ cd ~/benPrj/

# 安裝所有 composer 套件 # 要等待一點時間, 讓它把所有套件下載回 vendor/ 子目錄 [alex2@nvda ~/benPrj ]$ composer install Loading composer repositories with package information ...(略) Discovered Package: nunomaduro/collision Package manifest generated successfully. [alex2@nvda ~/benPrj ]$

# 安裝所有 node 套件 # 要等待一點時間, 讓它把所有套件下載回 node_modules/ 子目錄 [alex2@nvda ~/benPrj ]$ npm install

# .env 從 .env.example 複製再修改 [alex2@nvda ~/benPrj ]$ cp .env.example .env # 修改正確的 mysql ... 等各項設定 [alex2@nvda ~/benPrj ]$ vi .env # 都完成後, 查看現在版本 [alex2@nvda ~/benPrj ]$ php artisan -V Laravel Framework 5.8.12 [alex2@nvda ~/benPrj ]$ ```

### git log 查看

我們可以看到由 Author: alexDate: Wed Apr 17 07:41:40 2019 +0800 創建的 log 資訊

#### 命令 shell git log

#### 執行結果 shell [alex2@nvda ~/benPrj ]$ git log 1 commit 281f0cbb70b2b78e0b65643bc889f6b5adbad636 2 Author: alex <alex@forblind.org.tw> 3 Date: Wed Apr 17 07:41:40 2019 +0800 4 5 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex2@nvda ~/benPrj ]$

### 啟動服務試試

#### 命令 shell php artisan serve --host=nvda --port=2019

進入 瀏覽器 會出現錯誤, 訊息如下:

#### 頁面訊息 plaintext RuntimeException No application encryption key has been specified.

這是因為從遠端倉庫 clone 回來時, key 也是被忽略(.gitignore)的文件之一

### 重新產生 laravel 的 key, 完成後再啟動服務

#### 命令 shell php artisan key:generate php artisan serve --host=nvda --port=2019

#### 執行結果 shell [alex2@nvda ~/benPrj ]$ php artisan key:generate Application key set successfully. [alex2@nvda ~/benPrj ]$ php artisan serve --host=nvda --port=2019 Laravel development server started: <http://nvda:2019>

太棒了, 像日出日落一樣的正常

### 建立資料庫

一開始建立遠端倉庫用的 laravel 基礎框架時, 可先不處理資料庫設定, 但之後各自要把它完成. 每位開發者有各自開發用資料庫, 公用測試版也有它的資料庫. 當然, 網站正式上線一定會有正式版專用的資料庫.

#### 命令及說明 shellql # 進入 mysql 命令列, 以下 `MYDATABASE, MYDBUSER, MYDBPASSWORD` 請修改對應, charset 用 utf8mb4, collation 用 utf8mb4_general_ci DROP DATABASE IF EXISTS MYDATABASE; CREATE DATABASE MYDATABASE DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; # mysql 5.7 以下可以使用 `WITH mysql_native_password` 或 `WITH sha256_password` 兩種不同的密碼加密方式, 若是 mysql 5.6 以下, 就把這兩個單字移除 CREATE USER 'MYDBUSER'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MYDBPASSWORD'; GRANT ALL ON MYDATABASE.* TO 'MYDBUSER'@'localhost'; FLUSH PRIVILEGES; # 修改 USER 加密方式 ALTER USER 'MYDBUSER'@'localhost' IDENTIFIED WITH sha256_password BY 'MYDBPASSWORD'; ALTER USER 'MYDBUSER'@'localhost' IDENTIFIED WITH mysql_native_password BY 'MYDBPASSWORD';

### 前置作業

#### 命令及說明 `` # 修改資料連結的參數 vi .env # 設定 mysql 建立資料庫時的MYDATABASE, MYDBUSER, MYDBPASSWORD`

vi config/database.php # (可不用修改, 預設 utf8mb4_unicode_ci) mysql 資料庫 collation 預設 utf8mb4_unicode_ci 改為 utf8mb4_general_ci

vi config/logging.php # (可暫時跳過) 修改 建立 自定義版本 log # (可暫時跳過) 自定義的單一日期時間 log 檔案, 每一次 request 產生一個記錄 # (可暫時跳過) 複製自定義 log class, app/Loggers/my1LocalLogger.php # (可暫時跳過) 複製自定義 json 輸出 class, app/Loggers/JsonFormatter.php ```

  1. 開發者 : clone, clone, clone

所有開發者請現在回到各自家目錄, 開始做 clone 並補齊 laravel 設定, 讓大家版本一致

稍後各自增修同一支程式相同行數位置的內容, 製造 conflict 衝突, 然後使用 merge conflict 合併衝突來解決.

  1. 開發者 : 戰鬪, 然後推入遠端倉庫

上一節 clone 並補齊 laravel 設定 的基本工作完成後. 單兵開始就戰鬪位置. 現在的開發實作人員的身份仍然為 alex2git nameben

### 開發者 ben 修改或增加檔案

#### 命令 bash vi resources/views/welcome.blade.php vi resources/views/abcd.blade.php vi routes/web.php git st -s

#### 執行結果及說明 ```shell # 加一些字到 welcome.blade.php [alex2@nvda ~/benPrj ]$ vi resources/views/welcome.blade.php

# 84 行 Laravel 改為 Ben's Laravel # 85 行新增一行

83
84 Ben's Laravel 85

86

# 新增一個 blade 給路由 /a 測試 [alex2@nvda ~/benPrj ]$ vi resources/views/abcd.blade.php

# 這個檔案, 只加了一行 1 hello, 你好

# 修改 route 加入一段 /abcd 路由到上面的 abcd.blade.php 的程式 [alex2@nvda ~/benPrj ]$ vi routes/web.php

18 Route::get('/abcd', function () { 19 return view('abcd'); 20 });

[alex2@nvda ~/benPrj ]$ git st -s M resources/views/welcome.blade.php M routes/web.php ?? resources/views/abcd.blade.php [alex2@nvda ~/benPrj ]$ ```

進入 首頁/abcd 完美如昔. 讚, ben 今天完工了, 要把修改及增加的程式碼 push 推入遠端倉庫.

### 推入遠端倉庫

推入遠端之前, 本地端仍然要先 commit 到本地倉庫. 也才能從本地倉庫推到遠端倉庫.

#### 命令 ```bash git st -s git add . git commit -m '動到 2 支 blade (1 舊 1 新) 及 route

welcome.blade.php abcd.blade.php 在 routes/web.php 加上 /abcd 路由到上面的 abcd.blade.php 的程式' ```

#### 執行結果 shell [alex2@nvda ~/benPrj ]$ git st -s M resources/views/welcome.blade.php M routes/web.php ?? resources/views/abcd.blade.php [alex2@nvda ~/benPrj ]$ git add . [alex2@nvda ~/benPrj ]$ git st -s A resources/views/abcd.blade.php M resources/views/welcome.blade.php M routes/web.php [alex2@nvda ~/benPrj ]$ git commit -m '動到 2 支 blade (1 舊 1 新) 及 route > > welcome.blade.php > abcd.blade.php > 在 routes/web.php 加上 /abcd 路由到上面的 abcd.blade.php 的程式' [master 8aa45d6] 動到 2 支 blade (1 舊 1 新) 及 route 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 resources/views/abcd.blade.php [alex2@nvda ~/benPrj ]$

推入遠端倉庫, 但我們在執行前後看一下 log, 觀察它的 (HEAD -> master) , (origin/master, origin/HEAD) 指示器位置

#### 命令 bash git ld git push origin master

#### 執行結果 shell [alex2@nvda ~/benPrj ]$ git ld 1 [#8aa45d6] ben, 2019-04-19 23:47:42 +0800 : (HEAD -> master) 動到 2 支 blade (1 舊 1 新) 及 route 2 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : (origin/master, origin/HEAD) 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex2@nvda ~/benPrj ]$ git push origin master Counting objects: 9, done. Delta compression using up to 2 threads. Compressing objects: 100% (8/8), done. Writing objects: 100% (9/9), 82.58 KiB | 0 bytes/s, done. Total 9 (delta 5), reused 0 (delta 0) To 127.0.0.1:/home/g/repo 281f0cb..8aa45d6 master -> master [alex2@nvda ~/benPrj ]$ git ld 1 [#8aa45d6] ben, 2019-04-19 23:47:42 +0800 : (HEAD -> master, origin/master, origin/HEAD) 動到 2 支 blade (1 舊 1 新) 及 route 2 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex2@nvda ~/benPrj ]$

完美, 沒有錯誤, 很好, 收工回家.

  1. 開發者 : 持續的開發, 衝突, 合併, 解決

### 共同開發者

共同開發者, 第一次也同樣 clone 遠端倉庫回自己家, 改目錄名或移到適當位置, 現在以另一開發者 alex, git namealex 開發者身份測試

相同的基本 clone 工作及必要設定結束後, 開發者 alex 也積極開始工作, 但我們先看看最新的 git log, 目前 alex 的本地倉庫

#### 執行結果 [alex@nvda ~/ak1 ]$ git ld 1 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : (HEAD -> master, origin/master, origin/HEAD) 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex@nvda ~/ak1 ]$

現在先 alex 也修改 welcome.blade.php

#### 命令 ``bash vi resources/views/welcome.blade.php # 第 84 行的Laravel改為Alex's Laravel` ...(前略) 83

84 Alex's Laravel 85
...(後略)


    `alex` 打算收工暫時告一段落, 結束目前的工作, 把程式推入遠端倉庫, 本地端仍然要先 `commit` 到本地倉庫. 也才能從本地倉庫推到遠端倉庫.

	### 推入遠端倉庫之衝突發生

	#### 命令
	```bash
	git s
	git a .
	git cm '修改 resources/views/welcome.blade.php 的內容'
	git ld
	git push origin master
	```

    #### 執行結果

[alex@nvda ~/ak1 ]$ git s M resources/views/welcome.blade.php [alex@nvda ~/ak1 ]$ git a . [alex@nvda ~/ak1 ]$ git cm '修改 resources/views/welcome.blade.php 的內容' [master c41cf86] 修改 resources/views/welcome.blade.php 的內容 1 file changed, 1 insertion(+), 1 deletion(-) [alex@nvda ~/ak1 ]$ git ld 1 [#c41cf86] alex, 2019-04-17 12:39:14 +0800 : (HEAD -> master) 修改 resources/views/welcome.blade.php 的內容 2 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : (origin/master, origin/HEAD) 創立遠端倉庫用的 laravel 基礎框架 5.8.12

[alex@nvda ~/ak1 ]$ git push origin master To /home/repo/ ! [rejected] master -> master (fetch first) error: failed to push some refs to '/home/repo/' hint: Updates were rejected because the remote contains work that you do hint: not have locally. This is usually caused by another repository pushing hint: to the same ref. You may want to first integrate the remote changes hint: (e.g., 'git pull ...') before pushing again. hint: See the 'Note about fast-forwards' in 'git push --help' for details. [alex@nvda ~/ak1 ]$ ```

哇, 爆炸了, 為什麼被拒絕 ! [rejected] , 注意同一行最後那個括號裡的字 (fetch first), 此刻 alex 並不知道 ben 先前已 push 過, 而且剛好也是都改到相同的一個檔案.

### fetch first

既然如此, 就按照它的指示, 開始操作. fetch 完成後, 還不能 push, 會得到相同的錯誤. 緊接著要做的是用合併解決衝突.

#### 命令 bash git fetch origin master git merge origin/master

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git fetch origin master [alex@nvda ~/ak1 ]$ git merge origin/master Auto-merging resources/views/welcome.blade.php CONFLICT (content): Merge conflict in resources/views/welcome.blade.php Automatic merge failed; fix conflicts and then commit the result. [alex@nvda ~/ak1 ]$

注意 CONFLICT (content): Merge conflict in resources/views/welcome.blade.php , 它指出衝突的來源, 其實就是兩個開發者都改了同一個 resources/views/welcome.blade.php 檔案, 那麼就解決它吧.

### 解決 merge 的 CONFLICT 衝突

#### 命令 shell vi resources/views/welcome.blade.php

#### 執行結果 html 83 <div class="title m-b-md"> 84 <<<<<<< HEAD 85 Alex's Laravel 86 ======= 87 Ben's Laravel 88 <p>改</p> 89 >>>>>>> origin/master 90 </div>

打開衝突發生的檔案, 會看到

第 84 行 <<<<<<< HEAD 到 86 行 ======= 之間的程式碼, 表示現在 alex 自己開發版本修改的內容.

第 86 行 ======= 到 89 行 >>>>>>> origin/master 之間的程式碼, 表示遠端倉庫最後被 ben push 上傳的內容.

alex 此刻要呼叫 ben 來解決問題, 或者找 此專案的總工程師 來解決...... 經過溝通後, 程式修改成另一版本, 原先 <<<<<<<, =======, >>>>>>> 標記的三行, 都要刪除

#### 程式修改完美協調版本 html 83 <div class="title m-b-md"> 84 NVDA Laravel 85 <p>改</p> 86 </div>

### 解決衝突後, 再度 git

#### 命令 bash git s git a . git s git cm '解決 resources/views/welcome.blade.php 衝突' git ld git push origin master git ld git push origin master

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git s A resources/views/abcd.blade.php UU resources/views/welcome.blade.php M routes/web.php [alex@nvda ~/ak1 ]$ git a . [alex@nvda ~/ak1 ]$ git s A resources/views/abcd.blade.php M resources/views/welcome.blade.php M routes/web.php [alex@nvda ~/ak1 ]$ [alex@nvda ~/ak1 ]$ git cm '解決 resources/views/welcome.blade.php 衝突' [master d826a09] 解決 resources/views/welcome.blade.php 衝突 [alex@nvda ~/ak1 ]$ [alex@nvda ~/ak1 ]$ git ld 1 [#d826a09] alex, 2019-04-17 13:06:31 +0800 : (HEAD -> master) 解決 resources/views/welcome.blade.php 衝突 2 [#c41cf86] alex, 2019-04-17 12:39:14 +0800 : 修改 resources/views/welcome.blade.php 的內容 3 [#054f3fe] ben, 2019-04-17 12:24:53 +0800 : (origin/master, origin/HEAD) 動到 2 支 blade (1 舊 1 新) 及 route 4 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex@nvda ~/ak1 ]$ git push origin master Counting objects: 10, done. Delta compression using up to 2 threads. Compressing objects: 100% (9/9), done. Writing objects: 100% (10/10), 931 bytes | 0 bytes/s, done. Total 10 (delta 6), reused 0 (delta 0) To /home/repo/ 054f3fe..d826a09 master -> master [alex@nvda ~/ak1 ]$ [alex@nvda ~/ak1 ]$ git ld 1 [#d826a09] alex, 2019-04-17 13:06:31 +0800 : (HEAD -> master, origin/master, origin/HEAD) 解決 resources/views/welcome.blade.php 衝突 2 [#c41cf86] alex, 2019-04-17 12:39:14 +0800 : 修改 resources/views/welcome.blade.php 的內容 3 [#054f3fe] ben, 2019-04-17 12:24:53 +0800 : 動到 2 支 blade (1 舊 1 新) 及 route 4 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex@nvda ~/ak1 ]$ git push origin master Everything up-to-date [alex@nvda ~/ak1 ]$

最後看到的 log , alex 提交了兩次, 一次改檔本地提交, 另一次是解決衝突. 好了, 終於可以回家了 :-(

  1. 每天工作前第一件事?

### 每天工作前第一件事?

是什麼, 就是把遠端倉庫裡的最新資料拉回來 :-D, 拉回來後, 該解決衝突就馬上解決

> 備註 : git fetch + git merge 等同於 git pull。

目前再度回到 ben 的家

#### 命令 bash git ld git pull origin master git ld

#### 執行結果 shell [alex2@nvda ~/benPrj ]$ git ld 1 [#054f3fe] ben, 2019-04-17 12:24:53 +0800 : (HEAD -> master, origin/master, origin/HEAD) 動到 2 支 blade (1 舊 1 新) 及 route 2 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex2@nvda ~/benPrj ]$ git pull origin master remote: Counting objects: 10, done. remote: Compressing objects: 100% (9/9), done. remote: Total 10 (delta 6), reused 0 (delta 0) Unpacking objects: 100% (10/10), done. From /home/repo 054f3fe..d826a09 master -> origin/master Updating 054f3fe..d826a09 Fast-forward resources/views/welcome.blade.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) [alex2@nvda ~/benPrj ]$ git ld 1 [#d826a09] alex, 2019-04-17 13:06:31 +0800 : (HEAD -> master, origin/master, origin/HEAD) 解決 resources/views/welcome.blade.php 衝突 2 [#c41cf86] alex, 2019-04-17 12:39:14 +0800 : 修改 resources/views/welcome.blade.php 的內容 3 [#054f3fe] ben, 2019-04-17 12:24:53 +0800 : 動到 2 支 blade (1 舊 1 新) 及 route 4 [#281f0cb] alex, 2019-04-17 07:41:40 +0800 : 創立遠端倉庫用的 laravel 基礎框架 5.8.12 [alex2@nvda ~/benPrj ]$

現在啟動服務, 進入 瀏覽器, 看看首頁內容, 衝突解決了.

  1. 實用相關資訊

### 本地端設定值

#### 命令 bash cat .git/config

#### 執行結果 shell [alex@nvda ~/ak1 ]$ cat .git/config [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] url = /home/repo/ fetch = +refs/heads/*:refs/remotes/origin/* [branch "master"] remote = origin merge = refs/heads/master [alex@nvda ~/ak1 ]$

注意 [remote "origin"][branch "master"] 這兩段

[core] 這裡看到的是 本地倉庫 local 之值, 可比對 cat ~/.gitconfig 的 global 值, 常用的我們都會設定到 global, 除非有特定目的才會設在這裡.

### 在本地倉庫端顯示 fetch, push 遠端倉庫的資訊

#### 命令 bash git remote -v

#### 執行結果 shell [alex@nvda ~/ak1 ]$ git remote -v origin /home/repo/ (fetch) origin /home/repo/ (push) [alex@nvda ~/ak1 ]$

### 好用的連結

* Git 面試題

* 四種將分支與主線同步的方法

* 以上這兩篇文章寫得不錯, 跟我們此篇內容有比較多的關聯, 大家找時間把它精讀.

* Git的奇技淫巧 - 簡體中文 此為老外整理 Most commonly used git tips and tricks. 的簡體中文版, 很實用, 極具參考價值.

  1. 本章總結

### 本章使用 git 命令總結 bash ssh-keygen -t rsa # 產生個人公鑰及私鑰 git init --bare # 遠端倉庫初始化 git remote add origin g@127.0.0.1:/home/g/repo # 設定 git 本地倉庫到遠端倉庫的連結, ssh 共用帳號 g git remote add origin 127.0.0.1:/home/repo # 設定 git 本地倉庫到遠端倉庫的連結, 原始版 git clone g@127.0.0.1:/home/g/repo myPrj # 複製遠端倉庫回家, 指定目錄名稱, ssh 共用帳號 g git clone /home/repo myPrj # 複製遠端倉庫回家, 指定目錄名稱, 原始版 git push origin master # 本地倉庫(分支 master)提交後, 推入遠端倉庫(origin 的分支 master) git pull origin master # 拉回遠端倉庫(origin 的分支 master)最後版本到本地倉庫(分支 master) git fetch origin master # 取得遠端倉庫分支 master 的資料 git merge origin/master # 合併本地倉庫分支 origin/master 的程式碼