顯示具有 Git 標籤的文章。 顯示所有文章
顯示具有 Git 標籤的文章。 顯示所有文章

Jenkins的git log的中文出現亂碼

沒有留言:
首先我要強調的是,git log盡量不要打中文!XD

好!接下來,來介紹一下怎麼解決中文的問題。
先說說有一個指令。

$git config --global i18n.logOutputEncoding <編碼方式>

這個指令,可以設定log輸出的編碼方式是要utf-8?還是要big5?還是別的。


一開始,我想說Jenkins的網頁,都嘛utf8,所以輸出成utf8吧!
結果一直都亂碼,無法解決,也覺得我是不是漏設定了什麼。

有一天,我想到了一個測試的方式。
看看是怎麼回事。

$git log >> gitlog.txt

將git的log輸出成檔案。再用文字編輯器去開。就可以知道它是不是我想要的編碼方式啦!
我使用的文字編輯器是windows提供的WordPad,它....開啟utf8,是亂碼!= =

Oh~

怎麼和Jenkins一樣呢?

用big5顯示

讓Git log輸出log的編碼為big5

就把輸出log的編碼改成big5
結果WordPad開,是正常的!= =

所以要在Jenkins的繁體中文介面顯示正常的git log內容。請用這個設定

$git config --global i18n.logOutputEncoding big5


用UTF8顯示[1]

改Jenkins用的Java字集為UTF8

以系統管理員身分
  1. 開啟命令提示字元視窗
  2. X:\SETX /M JAVA_TOOL_OPTIONS -Dfile.encoding=UTF8
  3. 開啟Git Bash
  4. $git config --global i18n.logOutputEncoding utf8
  5. 重新啟動Jenkins


參考資料
[1] Jenkins on Windows 心得分享 (03):有效避免記錄檔或訊息出現亂碼的方法

用Sublime Text寫git的commit 內容(也就是之後要呈現在log的文字)

沒有留言:
要注意安裝的版本和路徑。

因為我使用的是Sublime Text 2,所以指令如下
在 bash 輸入這一行

git config --global core.editor "'c:/program files/sublime text 2/sublime_text.exe' -w"[1]

參考資料:
[1] Git config core.editor — how to make sublime text the default editor for git on Windows

git hook 壞掉了!

沒有留言:
有遇過,明明就建立好相同名稱的檔案(不是說好了這樣就可以hook了嗎?)
但是,打死就是不動!這個git專案的hook怎麼這麼懶呀?!><


其實,檢查一下這個hook檔案的權限是不是有開755(執行權限)

Git hook 快速指南

沒有留言:

說明

Git提供事件觸發功能(在此使用hoook,翻譯成掛鉤),在某些時間點,可以做一些客製化的事情。
以下我們先將這些掛鉤列出來看看[1]

安裝

掛鉤檔,都存放在.git/hooks(預設)目錄下,git會預設一些腳本範例。所有的hook檔範本都是shell腳本語言寫成,其中還包含一些Perl腳本。把一個正確命名且可執行的檔案放到指定的目錄中,即完成安裝,之後就會在正確的時機點被git呼叫。
範例檔都是以.sample副檔名,必須重新命名,才會被執行。

Client可用的掛鉤

提交工作流程掛鉤

pre-commit
輸入commit資訊前執行
prepare-commit-msg
commit資訊編輯器顯示之前
commit-msg
掛鉤接收一個參數,此參數是包含最近提交資訊的暫存檔路徑。
post-commit
整個提交過程完成後執行

E-mail 工作流掛鉤

運行git am指令時,會呼叫這三個掛鉤,如果你通過 e-mail 接收由git format-patch產生的補丁,這些掛鉤也許對你有用。

applypatch-msg
他接收一個參數:包含被建議提交資訊的暫存檔案名。
pre-applypatch
透過git am應用補丁時執行,該掛鉤不接收參數,在補丁被應用之後執行
post-applypatch
在git am操作期間執行

其他掛鉤

pre-rebase
rebase前執行
post-checkout
git checkout成功執行後執行
post-merge
git merge命令成功執行後會執行

Server可用的掛鉤

pre-receive and post-receive

pre-receive
git push執行後,接收commit內容之前執行。
post-receive
接收commit內容之後執行,不過執行過程使用者要保持連線。(注意此腳本是否會執行很久,連線就要保持一段時間)

update

update
每一個分支更新時執行一次

其它 有檔但是Pro Git沒提到的

post-update.sample
pre-push.sample

參考資料

[1]7.3 Git 客製化 - Git Hooks

刪除git的分支

沒有留言:
刪除本地分支
$git branch -d <branch name>

刪除遠端分支
$git push <repo name> :<branch name>
ex: $git push origin :<branch name>

刪除git branch -a的分支
$git branch -r -d <remotes branch name>

Git之...雙bare同步

沒有留言:
有時候因為操作習慣或備份,會架設兩個git bare,並且希望彼此同步。

雖然git本身並不是用一個git sync做到和所有的repo同步。
但是git有一個叫hook的客製化事件觸發(Pro Git中文版翻譯成掛鉤)

可以在指定的時機,執行指定的動作。
這麼一來可以擴充git很多功能,我想也是因為這樣,git才能和很多open source的工具整合得很好的原因。

現在就來看看,如何做到同步bare

建立Bare

首先,我們要兩個bare

Main  用git init --bare 建立
Mirror  用git clone --mirror --bare <Main Path>建立

讓Mirror成為Main的鏡像,這麼做的原因有兩個,也是我們要放hook的內容
在Mirror執行git push,即可讓Main有Mirror。
在Mirror執行git fetch,即可讓Mirror有Main。
(不過,彼此會互蓋,要小心)

安裝Hook

Git的Server hook有兩個事件可以使用,pre-receive和post-receive
在此,必須安裝在Mirror,client執行 git push時,會先執行
  1. pre-receive
  2. 將你push的內容放到bare裡
  3. 執行post-receive

如果在1.的時候,先git fetch,和Main同步,在3. 的時候git push讓Main和Mirror一樣。
那麼兩邊就可以同步了!

建立clone

Client建議clone Mirror這一邊,操作比較順暢。
如果萬一有人cline了Main,然後提交了,是不是會造成衝突呢?
這是一定的!就像是兩個人對同一個bare做push一樣。

同步衝突

這時,同步機制會卡在pre-receive做完fetch時,無法將你要push上來的東西放好,造成衝突,所以push失敗,這時你要執行git pull將同步好的下載下來,解決衝突,再重新push,即可解決。

Hook內容

最後的問題是hook的shell腳本怎麼寫?
sample的內容好複雜呀!?
我就在此獻醜一下,看看是不是有更好的做法(一定的有的啦)

post-receive

#!/bin/sh
git push

exit 0

pre-receive

#!/bin/sh
git fetch

參考資料 

[1] 7.3 Git 客製化 - Git Hooks

Gitolite 一個人 很多key 怎麼辦?

沒有留言:
最近,公司很聽話的建置了Git Server,並且使用Gitolite來管理user和project的存取權限。
功能強大!Github的lite版,實在不是浪得虚名呀。

不過,有Git Server就是要連回家時都可以coding呀!(公司同事一定會罵我,不該找這功能的)
當然不是回家要寫的呀!是在客戶那裡時,只要有網路,就一定要馬上push....

同事心裡的吶喊,我聽到了!
為了未來可以好好的在家工作,我也要好好的為自己鋪路呀....

在此就以回家使用自己電腦為例

在公司的電腦裡,生成了一組公鑰和私鑰。
在家裡的電腦裡,也生成了一組公鑰和私鑰。

那這兩組,怎麼都用同一組帳號(在此以chris為例)push, pull呢?

在此就簡單的針對一個人,很多key,做介紹。
假設都已安裝好Gitolite,Gitolite的相關權限設定也都會了(這樣的文件,Google一下就有啦!很多滴)

首先,我們知道,管理員會將我們提供的chris.pub,放在Gitolite的gitolite-admin\keydir目錄底下
像這樣
gitolite-admin\keydir\chris.pub

這樣,就可以提供chris這個帳號存取的權限了。
那另一台電腦的chris怎辦?在家也要用呀!

其實,只要這樣就可以了

在Gitolite的gitolite-admin\keydir目錄底下建置資料夾分開[1]
像這樣
gitolite-admin\keydir\home\chris.pub
gitolite-admin\keydir\company\chris.pub

兩個chris.pub分別是從不同的電腦生成的公鑰。
但是放在管理者這裡,必須要取成相同的名字,才會是「同一個」帳號唷!

參考資料
[1] 2.1 multiple keys per user

Git的簡單統計 用指令

沒有留言:
之前有介紹使用GitStats的工具來統計Git的log。
它會像Github一樣給你這個專案從頭到目前的各式各樣統計結果。
非常的好玩,而且不管是安裝還是使用上也相當簡單。

不過!它只不支援Windows。

那Windows的使用者怎辦?我也想統計呀?!
難道一定要上傳Github?(誤)
搞一個Linux的VM?(誤)
把Git弄得更熟練!!!!!!

「Git很神,一定有這功能的!」

就這樣找呀找。
終於找到一些有趣的來玩。

第一招

顯示每一次commit的日期、作者(這個可以自訂[1])
檔案修改、增加的行數、去除掉的行數

顯示的結果如下

Mon Aug 18 16:48:42 2014 +0800 Ken
1 file changed, 2 insertions(+), 2 deletions(-)

Mon Aug 18 16:12:16 2014 +0800 Ken
4 files changed, 57 insertions(+), 39 deletions(-)

Thu Aug 14 16:51:22 2014 +0800 Ken
1 file changed, 7 insertions(+), 5 deletions(-)

Thu Aug 14 14:35:53 2014 +0800 Ken
1 file changed, 7 insertions(+), 5 deletions(-)
...

在Bash下指令

git log --shortstat --pretty=format:"%cd %an" --author=ken --since="2014-05-06"

參數說明

--shortstat     簡短的統計內容
--pretty=format:"%cd %an"     每個commit的標題指定格式(在此指定: 日期、作者)
--author=ken    過濾作者字串

--author    列出作者名稱符合指定字串的更新。
--committer     列出提交者名稱符合指定字串的更新。

限制時間區間

--since="2014-05-06"
從2014/05/06開始找

-(n)    僅顯示最後 n 個更新
--since, --after      列出特定日期後的更新。
--until, --before     列出特定日期前的更新。

第二招[2]

統計commit的數目

顯示的結果如下

   356  chris
   317  YuKai
   113  Ken Tseng
    70  Kimi Lu
    37  vul3yo6
    29  Ken

在Bash下指令

git shortlog --numbered --summary

參數說明

--numbered 依commit數目排序(原本預設是依作者字母順序排列)
--summary 不顯示commit的標題文字,只顯示統計數字

第三招[2]

顯示這個專案所有時間統計下來的
作者、修改檔案數、增加行數、刪除行數、增加行數-刪除行數

顯示結果

chris,:  9497 fils, (+)1513667 (-)473535 = 104013
chris,vul3yo6,:  5 fils, (+)28 (-)28 = 0
chris,yukai,:  20 fils, (+)426 (-)454 = -28
vul3yo6,:  989 fils, (+)184025 (-)15499 = 168526
vul3yo6,yukai,:  25 fils, (+)936 (-)460 = 476
yukai,:  4859 fils, (+)689366 (-)338120 = 351246
yukai,chris,:  76 fils, (+)5127 (-)825 = 4302
yukai,vul3yo6,:  22 fils, (+)315 (-)44 = 271
yukai,zc1145,:  12 fils, (+)45 (-)39 = 6
zc1145,:  453 fils, (+)27439 (-)6025 = 21414
zc1145,yukai,:  38 fils, (+)866 (-)264 = 602
zc1145,yukai,vul3yo6,: 7 fils, (+)749 (-)71 = 678

在Bash下指令(超長的)

git log --shortstat --pretty="%cE" | sed 's/\(.*\)@.*/\1/' | grep -v "^$" | awk 'BEGIN { line=""; } !/^ / { if (line=="" || !match(line, $0)) {line = $0 "," line }} /^ / { print line " # " $0; line=""}' | sort | sed -E 's/# //;s/ files? changed,//;s/([0-9]+) ([0-9]+ deletion)/\1 0 insertions\(+\), \2/;s/\(\+\)$/\(\+\), 0 deletions\(-\)/;s/insertions?\(\+\), //;s/ deletions?\(-\)//' | awk 'BEGIN  {name=""; files=0; insertions=0; deletions=0;}  {if ($1 != name && name != "")  { print name ":  " files " fils, (+)" insertions " (-)" deletions " = " insertions-deletions ; files=0; insertions=0; deletions=0; name=$1; }  name=$1; files+=$2; insertions+=$3; deletions+=$4} END {print name ": " files " fils, (+)" insertions " (-)" deletions " = " insertions-deletions ;}'

參考資料:
[1] 2.3 Git 基礎 - 檢視提交的歷史記錄
[2] 统计本地Git仓库中不同贡献者的代码行数的一些方法

搜尋log 某個檔案的某一行內容的修改是....哪一次的commit

沒有留言:
今天,出現了一個情況。

有一個關鍵字的修改,忘記過去什麼時候修改的了。
從git上面去找,要找到民國幾年呀?

這時有兩個方法
  1. $git log -p,再使用 /<關鍵字> 找到你想看的段落。
  2. $git log -p -S'<keyword>' <file path name> 直接列出
第一個方法
$git log -p
列出log同時,附上檔案修改內容

遇到的困難是
當次的git log內容太多的時候,就會看不到commit的title

所以就找了第二個方法

第二個方法
$git log -p -S'<keyword>' <file path name>
列出指定檔案的log同時,附上有關鍵字的檔案修改內容

參考資料:
Git 初學筆記 - 指令操作教學

使用Gitstats統計git的log

沒有留言:
這是一個open source的工具,好用又簡單。
先來看看它的介紹[1]
但是又是江湖一點訣。

而且還是要Ubuntu平台,才會變好用。

安裝

$ sudo apt-get install gitstats      [2][3]

就醬!

使用

灌好了之後,使用上就和下指令一樣,隨時都可以下指令,而且可以指令任意輸出和輸入的路徑。

$ gitstats <repo path> <report path>      [3]
repo path就是輸入路徑,也就是你的source code with git的repo
report path就是輸出路徑,它的輸出是一堆網頁和圖檔,要用另一個料夾裝起來唷。
輸出之後,可以任意搬動,它會有index.htm,如果你有web serve就方便多了。

下面這個例子,就是半路抓一個repo再統計分析好,全部再砍掉,這樣也可以滴。

ex:

~/gitrepo$ git clone https://xxxxx                           
~/gitrepo$ gitstats ~/gitrepo/myproject ~/gitreport/myproject

這樣一邊是放原始碼,一邊就是放report。
有機會可以試試看唷!^^

參考資料:
[1] 从gitstats看Ubuntu Tweak三年之发展
[2] 重新安装系统之后要做的事情
[2] 要安装 gitstats 只是按照这些说明操作

刪除遠端分支

沒有留言:
每一次分支,都會有發佈與不發佈兩種狀態。
也就是你要不要上傳到遠端上去。

另一種是刪除不刪除兩種狀態。
但是,其實,是四個象限。

  刪除
   ^
1. | 2.
---+--->發佈
3. | 4. 

  1. 不發佈刪除
  2. 發佈刪除
  3. 不發佈不刪除
  4. 發佈不刪除

而我們常常在發佈後刪除(也就是2. 的情況),分支依然在遠端上。
在此,就要靠刪除遠端分支來幫我們清一下以前合併過的分支囉!


用這個無厘頭[1]的指令來刪除。
git push <remotename> :<branch name>

ex:
git push origin :serverfix

參考資料
[1] 3.5 Git 分支 - 遠端分支

git config push.default

沒有留言:
不確定以下內容是否完全正確。

push.default
定義了git push的內容應該做什麼動作,如果沒有明確指定refspec

不同的設定值適合不同的工作流程

例如
一個純中央工作流程upstream上,你可能要的設定值是
(fetch來源就是push目的地)

nothing
(無預設值)什麼都不push,除非明確指出refspec。
主要想避免由一開始就弄錯的人。

current
push local端只有目前branch,並且要相同名稱,才會上傳到remote repo
適用於中央與非中央的工作流程

upstream
push local端所有branch到remote repo

simple
如果upstream的branch的名稱不同於local的任何一個,就拒絕push的安全機制,類似upstream的用法。

自Git 1.7.11開始有此功能, Git 2.0為預設值

matching
push local端所有相同名稱branch到remote repo
Git 1.x預設值

再一次存到上次的commit

沒有留言:
認錯[1]的情況
反悔上一次的commit
完全重新覆蓋掉上一次的紀錄

都適用。

目前最新的進度存到上一次的commit上,而且可以修改commit內容
git commit --amend

然後,如果你上次的commit已經push了,然後local又改掉最後一次的commit要再次的push會失敗。

這時就要使用強制覆
git push --fource


參考:
[1] 章 5. 關於歷史

如何用git diff比較任意兩版本

沒有留言:
這篇,我們要利用下列指令完成版本差異比較
而且,看得出這兩個版本有哪些檔案有差異。

diff

tag1, 與 tag2 所有檔案的差異[1][2]

git diff tag1 tag2

tag1, 與 tag2 的指定檔案 file1, file2 的差異[1][2]

git diff tag1:file1 tag2:file2
要辦到指定版本(或檔案)就是要再學一個tag指令
file1, file2前有需要的話要加上路徑,路徑無須用'/'開頭,直接用資料夾名稱即可。

看「差異程度列表」時使用--stat[1]

列出檔案列表與修改次數,不顯示詳細修改內容
git diff --stat

tag

設定commit的hash碼(很長的那一串亂碼)為tag[1]

git tag <tag name> <hash前5碼>

刪除掉某一個tag [1][2]

git tag -d <tag name>
tab name 也可以使用中文唷[1](沒試過就是了)

參考資料:

[1] Git 初學筆記 - 指令操作教學
[2] Git 使用手冊

Git快速上手,初步簡易理解

沒有留言:

一開始的初始化

Client 端的init(拿來pull用的)
    git init
Server端的init(拿來push用的)
    git init --bare

基礎指令

上台→擺姿勢→拍照

上台
把檔案擺進資料夾中。

擺姿勢
修改完成,並且add該檔案

加入要追縱的檔案
    git add <file name>
拍照
當作玩RPG的"Save"
    git commit –m "<commit title>"
改到上次的commit
當作玩RPG的"Load"
    git reset –hard
回覆到某一個版本。(捨棄掉它的未來)
    $ git reset --hard <前五碼>
回去某一個版本看看。(保留它的未來)
    $ git checkout <前五碼>

上傳下載Server

檢查同步後上傳
    git push
檢查同步後下載
    git pull
不好解釋,我們來看看別人怎麼寫(可以說是「重新編排位址」)
    git rebase

查詢

圖形化開發歷程
    git log –graph --all
目前repo的狀態
    git status

DIY Git server by msysGit in windows

沒有留言:
在公司想架一個git server,但是公司主要的獲利不是寫程式,所以在git server的使用上較沒有太大的需求,基本上就只是幾個會寫程式的同事互相git就好了

一開始什麼都不懂,看了一篇Windows 上架設 Git 伺服器[1]之後覺得,還滿簡單的嘛!

動手吧!

結果還是搞了兩天!= =
這篇文章,寫得有點簡陋,在此做一個補完。

首先,準備兩台電腦,一台是Server(稱S),另一台是Client(稱C),兩台都去下載msysGit
並且安裝好。

寫這篇文章時,最新版是1.8.4,而只要選擇最上面的版本就可以了。
  1. Git-1.8.4-preview20130916.exe
    Full installer for official Git for Windows 1.8.4

  2. PortableGit-1.8.4-preview20130916.7z
    Portable application for official Git for Windows 1.8.4

  3. msysGit-netinstall-1.8.4-preview20130916.exe
    Net installer if you want to hack on Git

  4. msysGit-fullinstall-1.8.4-preview20130916.exe
    Full installer (self-contained) if you want to hack on Git

兩台都灌好之後。

在S電腦上:
  1. 安裝 msysgit(已完成)
  2. 執行 GIT-bash
  3. 在 git bash 裡執行下列指令
  4. mdkir /d/GitRepo # 建立檔案庫資料夾集散地
  5. mkdir /d/GitRepo/testRepo
  6. cd /d/GitRepo/testRepo
  7. git init --bare # 建立 Git repository
讀了一下4.2 服务器上的 Git - 在服务器上部署 Git的官方說明文章。
引用朋友在facebook給我的留言(真是金玉良言呀)
「如果當 central repo 用的話,就建立成 bare repo (`git init --bare`)」
「這樣作比較好啦,不然一般 repo 基本上是讓你 pull 的 不是讓你 push 的」


利用windows的網芳功能,將S電腦的GitRepo/做成網路磁碟機(G:)

在C電腦上:
  1. 安裝 msysgit(已完成)
  2. 執行 GIT-bash
  3. 在 git bash 裡執行下列指令
  4. mdkir /d/GitRepo # 建立檔案庫資料夾集散地
  5. mkdir /d/GitRepo/testRepo
  6. cd /d/GitRepo/testRepo
  7. git init # 建立 Git repository
這樣一來就可以在強大的(??)IT巨壁之內建立沒有傳輸安全性可言,卻可以運作的Git server。

最後最後,因為我還有使用中文的壞習慣。
所以要設定可以相容中文唷[3]

$ git config --global gui.encoding utf-8


有興趣的人可以在家試試唷!^^



後記
在git add 檔案時,不小心加入了專案檔,讓專案打開關閉都會讓檔案產生「變化」
那麼就要省略它們的變化
建一個.gitignore的文件檔,裡面直接寫你要省略的檔案

.*
*/debug/*.*
*/release/*.*
*.suo
*.ncb

主要是最後兩個.suo和.ncb,是visual studio的專案檔案之一。
只是因為光打開就會變動,所以才省略它們的變化。

不過因為我把它們git add了,所以必須取消這個追縱。
使用下面的指令取消追縱。[4]

$ git rm --cached your_filename




參考資料:
[1] Windows 上架設 Git 伺服器
[2] 4.2 服务器上的 Git - 在服务器上部署 Git
[3] Git Server on Windows 安裝手記
[4] gitignore 無法忽略檔案的解法

git所有的指令:

沒有留言:
練習介面即時圖解又有任務 http://pcottle.github.com/learnGitBranching/?demo    add        Add file contents to the index
   bisect     Find by binary search the change that introduced a bug
   branch     List, create, or delete branches
   checkout   Checkout a branch or paths to the working tree
   clone      Clone a repository into a new directory
   commit     Record changes to the repository
   diff       Show changes between commits, commit and working tree, etc
   fetch      Download objects and refs from another repository
   grep       Print lines matching a pattern
   init       Create an empty git repository or reinitialize an existing one
   log        Show commit logs
   merge      Join two or more development histories together
   mv         Move or rename a file, a directory, or a symlink
   pull       Fetch from and merge with another repository or a local branch
   push       Update remote refs along with associated objects
   rebase     Forward-port local commits to the updated upstream head
   reset      Reset current HEAD to the specified state
   rm         Remove files from the working tree and from the index
   show       Show various types of objects
   status     Show the working tree status
   tag        Create, list, delete or verify a tag object signed with GPG

Git裡的相對論

沒有留言:
我覺得玩Github最重要的就是要會開平行宇宙、時光回溯、合併時空。

時光回溯
    捨棄修改,到該分支的最新版
      git reset –hard
    回覆到某一個版本。(捨棄掉它的未來)
      $ git reset --hard <前五碼>
    回去某一個版本看看。(保留它的未來)
      $ git checkout <前五碼>
    單一檔案回溯到該分支的最新版。(捨棄掉它的修改)
      $ git checkout <file name>
開平行宇宙
    git branch <new branch name>
    git checkout -b <new branch name>

    checkout -b 是開了之後直接切過去,拿掉就變成純粹開branch,保持在原本的branch
合併時空
    git merge --no-ff <branch name>
    --no-ff 是讓branch在merge回去之後,保持原本分支的模樣(較符合原本的思緒)

關閉異次元(刪掉branch)
    git branch -d <branch name>

最簡單的用法就這樣,遇到困難,再來深入研究。

參考:
Git 版本控制系統(2) 開 branch 分支和操作遠端 repo.

第一次Git就上手

沒有留言:
每個Git教學都要說一下在什麼環境使用。
我是在windows底下使用!雖然支援度比較低,但是Github還是貼心的出了可愛的官方軟體

省下一些初始化的指令,如下:

git init
git add
git commit -a
git clone

灌好程式,就可以將檔案上傳下載同步(都包好了)



但是在程式壞掉時,還是要時光回溯!怎麼做呢?

git checkout 4372d4f4995c0a3dcd0b769997d63356c0b91a24

有看懂嗎?就是每一次commit時,會給你一串號碼,它的前五碼就可以當回溯的識別號碼了(不用全部打上去!真神)。


目前我就只會這樣,就用得很開心了!
開分支、合併、刪除,下次練習後再來寫吧!