Git命令大全

Add & Commit

git init

初始化一個 Git 倉庫(repository),即把當前所在目錄變成 Git 可以管理的倉庫。

git add 文件

把文件添加到 暫存區(stage),可被 track 追蹤紀錄下來。可多次使用來添加多個文件

**git add **

添加所有修改到暫存區,效果同 git add all待驗證

git add -A

暫存所有的文件,包括新增加的、修改的和刪除的文件。

git add .

暫存新增加的和修改的文件,不包括已刪除的文件。即當前目錄下所有文件。

git add -u

暫存修改的和刪除的文件,不包括新增加的文件。

git add -i

交互式添加文件到暫存區。

git add -p

暫存文件的一部分。

git commit -m "本次提交說明"

一次性把暫存區所有文件修改提交到倉庫的當前分支。注意:提交信息可為中文也可為英文,若為英文則通常用一般現在時。如果不加參數 -m 則會跳轉到編輯器強制填寫提交說明信息。

git commit -am "本次提交說明"

使用該命令,Git 就會自動把所有已經跟蹤過的文件暫存起來一并提交,從而跳過 git add 步驟,參數 -am 也可寫成-a -m。**“在 oh-my-zsh 下,直接用 gcam “message” 就搞定了” 魔都三帥語

git commit --amend

重新提交,最終只會有一個提交,第二次提交將 **代替 **第一次提交的結果。尤其適用于提交完了才發現漏掉了幾個文件沒有添加,或者提交信息寫錯了的情況。

git commit --amend --reset-author

在上一次 commit 之后想重新更新一下時間。amend 實際上修改了上一個 commit。所以如果已經 push 了上一個 commit,請盡量不要 amend。如果一定要 amend 已經 push 了的 commit,請確保這個 commit 所在的 branch 只有你一個人使用(否則會給其他人帶來災難),然后在 amend 之后使用 git push –force。只要多加小心,該命令貌似沒什么卵用。

git commit -p

commit 文件的一部分,適合工作量比較大的情況。之后,Git 會對每塊修改彈出一個提示,詢問你是否 stage,按 y/n 來選擇是否 commit 這塊修改,? 可以查看其他操作的說明。

Diff & Show

git status

顯示當前倉庫的最新狀態。提交之后,工作區就是“干凈的”,即沒有新的修改;有未提交文件時,最上面顯示的是在 staging area,即將被 commit 的文件;中間顯示沒有 stage 的修改了的文件,最下面是新的還沒有被 Git track 的文件。“在 oh-my-zsh 下,輸入 gst 就出來了,誰用誰知道,裝逼利器,效率杠杠的”魔都三帥語

git status -s 或 git status --short

狀態簡覽。輸入此命令后,有如下幾種情況(總共5種情況):新添加的未跟蹤文件前面有 ?? 標記,新添加到暫你可能注意到了 M 有兩個可以出現的位置,出現在右邊的 M 表示該文件被修改了但是還沒放入暫存區,出現在靠左邊的 M 表示該文件被修改了并放入了暫存區

git diff

查看 工作區中的修改

git diff --staged 或 git diff --cached

查看 暫存區中的修改

git diff <commit id1> <commit id2>

比較兩次 commit 之間的差異。

git diff <branch1> <branch2>

在兩個 branch 之間比較。

git diff 文件

查看指定文件具體修改了哪些內容。

git diff HEAD -- 文件

查看版本庫最新版本和工作區之間的區別,貌似沒什么卵用

git difftool --tool-help

查看系統支持哪些 Git Diff 插件,貌似沒什么卵用

git show

查看最后一個 commit 的修改。

git show HEAD~3

查看倒數第四個 commit 的修改,HEAD~3 就是向前數三個的 commit,即倒數第四個 commit。

git show deadbeef

查看 hash 為 deadbeef 的 commit 的修改。

git blame 文件

查看誰什么時間改了哪些文件。

log & reset

git log

顯示從最近到最遠的提交日志,包括每個提交的 SHA-1 校驗和、作者的名字和電子郵件地址、提交時間以及提交說明等基本信息。

git log -p -2

除顯示基本信息之外,還顯示每次提交的內容差異,-2 意思是僅顯示最近兩次提交。特別適用于進行代碼審查,或者快速瀏覽某個搭檔提交的 commit 所帶來的變化

git log --start

顯示每次提交的簡略的統計信息,貌似不太好用

git log --graph

查看分支合并圖。

git log --pretty=oneline

簡化日志信息,將每個提交放在一行顯示,查看的提交數很大時非常有用,也可帶有** –graph** 參數,效果同 git config format.pretty oneline

git log --graph --pretty=oneline --abbrev-commit

查看分支的合并情況,包括分支合并圖、一行顯示、提交校驗碼縮略顯示。

git log --oneline --decorate

查看各個分支當前所指的提交對象(commit object)Git 倉庫中有五個對象:三個 blob 對象(保存著文件快照)、一個樹對象(記錄著目錄結構和 blob 對象索引)以及一個提交對象(包含著指向前述樹對象的指針和所有提交信息)

git log --oneline --decorate --graph --all

查看分叉歷史,包括:提交歷史、各個分支的指向以及項目的分支分叉情況。

git reset --hard HEAD^

回退到上一個版本。同理,回退到上上個版本為:HEAD^ ^, 回退到上100個版本為:HEAD-100貌似波浪號 ~ 也可以,變成倒數第101個

git reflog

紀錄每一次命令,可用于查找某一提交版本的 commit id

git reset --hard <commit id>

回退到某一提交過的版本,如果已經 push,則回退的意義不大了。恢復一個徹底刪掉的 commit,見鏈接:
https://github.com/xhacker/GitProTips/blob/master/zh_CN.md#別人-push-了修改我無法-push-了怎么辦

working area & repo area

工作區(Working Directory)

項目所在的文件目錄。

版本庫(Repository)

工作區有一個隱藏目錄文件** .git**(可通過命令 ls -ah 查看隱藏文件),這就是 Git 的版本庫。版本庫里主要有稱為 **stage **的暫存區、Git 自動創建的 **master **分支,以及指向 master 的一個指針 HEAD,表示版本庫的最新版本。

reset & revert

git checkout -- 文件

丟棄工作區的修改,包括 **修改后還沒有放到暫存區 添加到暫存區后又作了修改 兩種情況。總之,讓該文件回到最近一次 git commitgit add 之后的狀態。注意:沒有 – ,就變成了切換分支的命令了郭神的書 P195 沒有 – 符號,可能是筆誤

git reset HEAD 文件

暫存區 的修改撤銷(unstage),回退到工作區。注意:在 Git 中任何已提交的東西幾乎總是可以恢復的。甚至那些被刪除的分支中的提交或使用 –amend 選項覆蓋的提交也可以恢復。然而,任何未提交的東西丟失后很可能再也找不到了。

git reset --hard

重置所有文件到未修改的狀態。

git reset <commit SHA>

重置到某個 commit。

git reset HEAD~1

將當前 branch 重置為倒數第二個 commit(即丟棄最后一個 commit)。git reset 有三個參數可以選擇,–soft、–mixed 和 –hard

git reset --soft

修改最后一個 commit。貌似沒什么卵用

git revert <commit id>

還原某個 commit。還原(revert)的實質是產生一個新的 commit,內容和要還原的 commit 完全相反。比如,A commit 在 main.c 中增加了三行,revert A 產生的 commit 就會刪除這三行。如果我們非常確定之前的某個 commit 產生了 bug,最好的辦法就是 revert 它。git revert 后 git 會提示寫一些 commit message,此處最好簡單描述為什么要還原;而重置(reset)會修改歷史,常用于還沒有 push 的本地 commits。

git revert HEAD

還原到上次 commit。

remove

git rm 文件

把文件從版本庫中刪除,不會再追蹤到。

git rm -f 文件

強制刪除版本庫中有修改的文件。

git rm --cached 文件

把文件從版本庫中刪除,但讓文件 保留在工作區且不被 Git 繼續追蹤(track),通常適用于在 rm 之后把文件添加到 .gitignore 中的情況。

git rm log/*.log

刪除 log/ 目錄下擴展名為 .log 的所有文件。

git rm *~

刪除以 ~ 結尾的所有文件。

Remote repo

remote & push

git remote

查看已經配置的遠程倉庫服務器,效果同 git remote show

git remote -v

顯示需要讀寫遠程倉庫使用的 Git 保存的簡寫與其對應的 URL。

git ls-remote <remote-name>

顯示獲得遠程引用的完整列表。

git remote show <remote-name>

參數 remote-name 通常都是縮寫名 origin,可以得到遠程分支更為詳細的信息以及 pull 和 push 相關提示信息。

git remote add <shortname> <url>

添加并關聯一個遠程庫。其中,shortname 一般是 origin,也可以是其他字符串,用來代替整個 url。

git push

推送本地修改到 origin。

git push -u origin master

關聯后,使用該命令第一次推送 master 分支的所有內容,后續再推送的時候就可以省略后面三個參數了,其中參數 u 代表上游(upstream)的意思。

git push origin 遠程分支(通常是 master)

推送最新修改。注意:多人協作時,除了 merge 可能會發生沖突之外,推送時也有可能發生沖突。在他人推送之后是不能立即推送自己的修改的,想想也是,因為可能會覆蓋他人的工作,所以必須先拉取(pull)別人的修改合并(merge)之后才能推送。如果不是第一次推送,后面的參數可省略。

git push <remote-name> <commit SHA>:<remote-branch_name>

push 一部分 commit。例如:git push origin 9790eff:master 即為 push 9790eff 之前的所有 commit 到 master。

git remote rename old_name new_name

重命名一個遠程倉庫的簡寫名。

git remote rm <remote-name>

移除一個遠程倉庫。

git remote add origin http://github.com/username/<repo name>.git

Create a remote repo named origin pointing at your Github repo (after you’ve already created the repo on Github) (used if you git init since the repo you created locally isn’t linked to a remote repo yet).

git remote add origin git@github.com:username/<repo name>.git

Create a remote repo named origin pointing at your Github repo (using SSH url instead of HTTP url).

clone

git clone git@github.com:username/<repo name>.git

從遠程庫(origin)克隆一份到本地,倉庫名同遠程倉庫名。

git clone https://github.com/username/repo name.git

作用同上。但 不建議使用 https 協議,原因有二:一是速度慢;二是每次推送必須輸入口令,麻煩。但在某些只開放 http 端口的公司內部就無法使用原生的 ssh 協議而只能用 https,倉庫名同遠程倉庫名。

git clone <repo url> <folder name>

克隆一個倉庫到指定文件夾。

git clone <repo url> .

克隆一個倉庫到當前文件夾(應該是空的)。

Branch

branch & merge

git branch

列出本地當前所有分支,方便查看。當前分支前面會標有一個 * 號。

git branch -r

查看遠程分支列表。

git branch -a

顯示所有分支,包括本地和遠程。

git branch -v

查看每一次分支的最后一次提交。

git branch -vv

查看設置的所有跟蹤分支。將所有的本地分支列出來并且包含更多的信息,如每一個分支正在跟蹤哪個遠程分支與本地分支是否是領先、落后或是都有。

git branch --merged

查看所有已經被 merge 的 branch。

git branch --no-merged

查看所有還沒被 merge 的 branch。

git branch --merged | xargs git branch -d

刪除所有已經被 merge 的 branch。

git checkout -b 分支

**創建 **并 **切換 到新的分支,相當于下面兩條命令:git branch 分支 + git checkout **分支。

git checkout -

切換到上一個 branch。

git cherry-pick <commit id>

假如我們在某個 branch 做了一大堆 commit,而當前 branch 想應用其中的一個,可以使用該命令。

git merge 分支

合并指定分支到當前所在的分支。

git merge --no-ff -m "提交說明信息" 分支

參數 –no-ff 表示 禁用 Fast forward 快進模式,用普通模式合并,這樣合并后的歷史有分支,能看出來曾經做過合并,而 fast forwad 合并就看不出來曾經做過合并。

git branch -d 分支

普通刪除分支(相對強制刪除而言)。一般情況下,先合并完分支,然后再刪除,否則會刪除失敗,除非使用 -D 參數強制刪除。注意:因為創建、合并和刪除分支非常快,所以 Git 鼓勵使用分支完成某個任務,合并后再刪除分支,這個直接在 master 分支上工作效果是一樣的,但過程更安全

git branch -D 分支

強行刪除分支,尤其適用分支內容有了新的修改但還沒有被合并的情況。

git push origin --delete 遠程分支 或 git push origin:遠程分支

刪除一個遠程分支。基本上這個命令做的只是從服務器上移除這個指針。 Git 服務器通常會保留數據一段時間直到垃圾回收運行,所以如果不小心刪除掉了,通常是很容易恢復的

git push origin -delete 分支

在本地和遠程同步刪除分支。

git rebase 目標分支(通常是 master)

在本地 master 上進行變基操作。注意:merge 與 rebase 都是整合來自不同分支的修改

merge 會把兩個分支的最新快照以及二者最近的共同祖先進行三方合并,合并的結果是生成一個新的快照(并提交)。

rebase 會把提交到某一分支(當前分支)上的所有修改都轉移至另一分支(目標分支)上,就好像“重新播放”一樣

變基是將一系列提交按照原有次序依次應用到另一分支上,而合并是把最終結果合在一起。簡言之:這兩種整合方法的最終結果沒有任何區別,但是變基使得提交歷史更加整潔

采用變基操作后,項目的最終維護者就不再需要進行整合工作,只需要快進合并便可。

git rebase –ongo 目標分支 第一分支 第二分支:選中在第二分支里但不在第一分支里的修改,將它們在目標分支(通常是 master)上重演。

變基有風險,需要遵守的準則是:不要對在你的倉庫外有副本的分支執行變基。否則,會導致混亂。總的原則是,只對尚未推送或分享給別人的本地修改執行變基操作清理歷史,從不對已推送至別處的提交執行變基操作,這樣才能享受到兩種方式帶來的便利。

還可以有這樣的命令:git rebase -i master,git rebase -i 22e21f2,git rebase -i HEAD~3

stash

git stash

把當前分支的工作現場儲存起來,等以后恢復現場后繼續工作。一般適用于還沒有 commit 的分支代碼。

git stash list

查看儲存的工作現場紀錄列表。

git stash apply + git stash drop

用 git stash apply 命令恢復最近 stash 過的工作現場,但是恢復后,stash 內容并不刪除,用 git stash drop 命令來刪除。apply 和 drop 后面都可以加上某一指定的 stash_id。

git stash pop

相當于上面兩條命令,恢復回到工作現場的同時把 stash 內容也刪除了。

git stash clear

清空所有暫存區的 stash 紀錄。drop 是只刪除一條,當然后面可以跟 stash_id 參數來刪除指定的某條紀錄,不跟參數就是刪除最近的。

git stash apply stash@{0}

上面命令中 大括號中的數字不是固定的,因為可以多次 stash,恢復的時候,先用 git stash list 命令查看,然后恢復指定的 stash。

git biselect

發現了一個 bug,用該命令知道是哪個 commit 導致的,貌似不太好用

pull & push

git push origin 分支

把該分支上的所有本地提交推送到遠程庫對應的遠程分支上。

git checkout 分支 origin/分支

如果遠程有某一個分支而本地沒有,怎用該命令把遠程的這個分支遷到本地。

git checkout -b 分支 origin/分支

把遠程分支遷到本地順便****切換到該分支。

git pull

抓取遠程庫最新提交,拉取并合并。

git fetch

沒有 merge 的 pull。

git branch --set-upstream 分支 origin/分支

建立本地分支和遠程分支的關聯。

git submodule update --recursive

第三方依賴與遠程同步,還可以在最后添加 -f 參數。

Tag

init tag

git tag

查看所有標簽。注意:標簽不是按照時間列出,而是按照字母排序,但這并不重要

git show <tag-name>

查看標簽信息。

git tag -l 'tag-name'

使用特定的模式查找標簽。

git checkout <tag-name>

切換 tag。

git tag <tag name> <commit id>

在需要打標簽的分支上創建一個輕量標簽(lightweight),默認為 HEAD,也可以指定一個 commit id。

git tag -a <tag-name> -m "標簽說明文字" <commit id>

創建附注標簽(annotated),用 -a 指定標簽名,-m 指定說明文字,也可以指定一個 commit id。

git tag -a <tag-name> 提交的校驗和或部分校驗和

后期打標簽,即對過去的提交打標簽。校驗和(checksum):長度為 40位的16進制數的 SHA-1 值字符串。然而,只要沒有沖突,通常可以用一個比較短的前綴來表示一個 commit。

git tag -s <tag-name> -m "標簽說明文字" <commit id>

通過 -s 用私鑰簽名一個標簽。簽名采用 GPG 簽名,因此,必須首先按照 pgp(GnuPG),如果沒有找到 gpg,或者沒有 gpg 秘鑰對,就會報錯。如果報錯,請參考 GnuPG 幫助文檔配置 Key。

manipulate tag

git tag -d <tag-name>

刪除一個本地標簽。因為創建的標簽都只存儲在本地,不會自動推送到遠程。所以,打錯的標簽可以在本地安全刪除。

git push origin <tag-name>

推送本地某個標簽到遠程,默認情況下,git push 命令并不會推送標簽到遠程,必須顯示推送。

git push origin --tags

參數 **–****tags **表示一次性推送全部未推送到遠程的本地標簽,當其他人從倉庫中克隆或拉取,他們也能得到那些標簽。

git push origin :refs/tags/<tag-name>

刪除一個遠程標簽,先從本地刪除,再用該命令從遠程刪除。

git checkout -b <branch-name> <tag-name>

在特定的標簽上創建一個新分支,貌似沒什么卵用

Custom git

ignore


git add -f 文件

使用 **-f 參數,強制添加被 .gitignore **忽略的文件到 Git。

git check-ignore -v 文件

可能是 .gitignore 寫得有問題,使用該命令找出到底哪個命令寫錯了。

https://github.com/github/gitignore

GitHub 上的一個十分詳細的針對數十種項目及語言的 .gitignore 文件列表。

注意:

忽略某些文件時,需要編寫 .gitignore 文件;

.gitignore 文件本身要放到版本庫里,并且可以對 .gitignore 做版本管理。

alias

git config --global alias.st status

使用 git st 代替 git status 命令。

git config --global alias.co checkout

使用 git co 代替** git checkout** 命令。

git config --global alias.cm commit

使用 git cm 代替** git commit **命令。

git config --global alias.br branch

使用 git br 代替 **git branch **命令。

git config --global alias.unstage 'reset HEAD --'

使用 git unstage 文件 命令代替** git reset HEAD – 文件** 命令。

git config --global alias.last 'log -1'

配置一個** git last **命令,讓其顯示最近一次的提交信息。

git config --global alias.lg "log --color --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit"

喪心病狂地配置 git lg 命令,讓顯示 log 更加優雅,逼格更高。

git config --global alias.visual '!gitk'

Git 只是簡單地將別名替換為對應的命令。如果想要執行外部命令而不是一個 Git 子命令,可以在命令前面加入 !符號。 如果自己要寫一些與 Git 倉庫協作的工具的話,那會很有用。貌似沒什么卵用

Help

git help <key>

git <key> --help

**man git-<key> **

git --help

Others

git config -l 或 git config --list

列舉所有 Git 能找到的配置,如果有重復的變量名,Git 會使用它找到的每一個變量的最后一個配置。

git config <key>

檢查 Git 的某一項配置。

git config --glabal core.editor <vim/emacs/...>

配置默認文本編輯器。

git config --global color.ui true

讓 Git 顯示顏色,使命令輸出看起來更醒目。

git config core.ignorecase false

Git 是大小寫不敏感的,如果要大小寫敏感需要執行此命令。

git config --global core.quotepath false

設置顯示中文文件名。

git config --global credential.helper cache

如果正在使用 HTTPS URL 來推送,Git 服務器會詢問用戶名與密碼。 默認情況下它會在終端中提示服務器是否允許你進行推送。如果不想在每一次推送時都輸入用戶名與密碼,可以設置一個 “credential cache”。 最簡單的方式就是將其保存在內存中幾分鐘,使用該命令即可,貌似沒什么卵用

git config --global user.name "your name"
git config --global user.email "your email"

設置 commit 中的姓名和 email,去掉 –global 參數則為針對每個 repo 單獨設定姓名和郵箱。

git commit --author "your name <your email>"

以其他身份 commit。

git mv old_filename new_filename

重命名文件。相當于下面三條命令:

mv old_filename new_filename

git rm old_filename

git add new_filename

git log 常用選項:

-p — 按補丁格式顯示每個更新之間的差異。

–stat — 顯示每次更新的文件修改統計信息。

–shortstat — 只顯示 –stat 中最后的行數修改添加移除統計。

–name-only — 僅在提交信息后顯示已修改的文件清單。

–name-status – 顯示新增、修改、刪除的文件清單。

–abbrev-commit — 僅顯示 SHA-1 的前幾個字符,而非所有的 40 個字符。

–relative-date — 使用較短的相對時間顯示(比如,“2 weeks ago”)。

–graph — 顯示 ASCII 圖形表示的分支合并歷史。

–pretty — 使用其他格式顯示歷史提交信息。可用的選項包括 oneline,short,full,fuller 和 format(后跟指定格式)。

git log --pretty=format:"%h - %an, %ar : %s"

自定義 log 顯示樣式,也可帶有 –graph 參數。常用的格式占位符寫法及其代表的意義:

%H — 提交對象(commit)的完整哈希字串

%h — 提交對象的簡短哈希字串

%T — 樹對象(tree)的完整哈希字串

%t — 樹對象的簡短哈希字串

%P — 父對象(parent)的完整哈希字串

%p — 父對象的簡短哈希字串

%an — 作者(author)的名字

%ae — 作者的電子郵件地址

%ad — 作者修訂日期(可以用 –date= 選項定制格式)

%ar — 作者修訂日期,按多久以前的方式顯示

%cn — 提交者(committer)的名字

%ce — 提交者的電子郵件地址

%cd — 提交日期

%cr — 提交日期,按多久以前的方式顯示

%s — 提交說明

git log --since=2.weeks

顯示按照時間限制的 log 信息,這個時間格式可以是:“2008-01-15”“2 years 1 day 3 minutes ago” 等。可用的參數還有:–until,–author,–grep(提交說明中的關鍵字)等。注意:如果要得到同時滿足這兩個選項搜索條件的提交,就必須用 –all-match 選項。否則,滿足任意一個條件的提交都會被匹配出來

git log -Sfunction_name

顯示添加或移除某一個特定函數的引用(字符串)的提交。

限制 git log 輸出的選項:

-(n) — 僅顯示最近的 n 條提交。

–since, –after — 僅顯示指定時間之后的提交。

–until, –before — 僅顯示指定時間之前的提交。

–author — 僅顯示指定作者相關的提交。

–committer — 僅顯示指定提交者相關的提交。

–grep — 僅顯示含指定關鍵字的提交。

-S — 僅顯示添加或移除了某個關鍵字的提交。

For example,git log –pretty=”%h - %s” –author=gitster –since=”2008-10-01” \ –before=”2008-11-01” –no-merges – t/,即為:查看 Git 倉庫中,2008 年 10 月期間,作者提交的但未合并的測試文件。

git config 保存用戶名和密碼
打開C盤用戶路徑下的.gitconfig文件,編輯如下
[user]
name = 用戶名
email = 郵箱
password = 密碼
[credential]
helper = store

git 查詢某段時間內某個用戶提交的代碼行數

git log --author=用戶名 --since=2023-03-26 --until=2023-04-04 --pretty=tformat: --numstat | awk '{loc+=($1-$2)} END {print loc}' 
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 以下內容是我在學習和研究Git時,對Git操作的特性、重點和注意事項的提取、精練和總結,可以做為Git操作的字典,...
    科研者閱讀 4,240評論 4 50
  • git常用命令 GIT常用命令備忘:http://stormzhang.com/git/2014/01/27/gi...
    新篇章閱讀 8,610評論 1 26
  • 1. 安裝 Github 查看是否安裝git: $ git config --global user.name "...
    Albert_Sun閱讀 13,719評論 9 163
  • 偶見一熱門微博話題: “和你暗戀的人,說一句其實我喜歡你”,或許有意想不到的收獲。 網友的評論大都令人歡喜。 很多...
    鎖鎖快跑閱讀 678評論 0 1
  • 今天吃完午飯,上樓時看到一只鳥在角落里對著玻璃窗沖撞,就是南方常見的那種翅膀上帶點黃的鳥,我小心將它捉住,想著打開...
    玄道閱讀 223評論 0 1