AveryChen
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.

      Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

      Explore these features while you wait
      Complete general settings
      Bookmark and like published notes
      Write a few more notes
      Complete general settings
      Write a few more notes
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Git - 進階篇 ## 使用分支(branch) 在增加新功能、修正 bug,或是想嘗試一些新做法時,都可以另外開一個分支來進行,等開發完確認沒問題之後再合併回來,就不會影響正在運行的功能。簡而言之,branch 的作用就是讓開發過程各自獨立。 ![branch](https://imgur.com/wQmzfvH.png) ### 分支的本質 在 Git 裡⾯的分⽀,其實就跟**⼀張貼紙**⼀樣,它會貼在某個 Commit 上: ![branch](https://imgur.com/eAJMurC.png) 當完成了一個新的 Commit,新的 Commit 會指向它的前一個 Commit,而目前的分支,會貼到剛剛完成的新的 Commit 上。也就是說分支會隨著每次 Commit 的新增一起移動: ![branch on new commit](https://imgur.com/Edjec69.png) 在 Git 的分⽀並不是複製⽬錄或檔案來進⾏開發與修改,**分⽀就只是⼀個指標、⼀張貼紙,貼在某個 Commit 上⾯⽽已**。 ### 查看專案分支 ```bash $ git branch * master ``` ### 建立分支 開發新功能之前,養成建立新分支的好習慣。 ```bash $ git branch develop $ git branch develop * master ``` ### 切換分支 ```bash $ git checkout develop Switched to branch 'develop' $ git branch * develop master ``` #### 在切換分⽀的時候發⽣了什麼事? 1. 更新暫存區以及⼯作⽬錄 Git 在切換分⽀的時候,會⽤該分⽀指向的那個 Commit 的內容來「更新」暫存區以及⼯作⽬錄。但是**在切換分⽀之前所做的修改則還是會留在⼯作⽬錄**,也就是說換切分⽀並**不會影響已經在⼯作⽬錄的那些修改**。 2. 變更 HEAD 的位置 除了更新暫存區以及⼯作⽬錄的內容外,同時 HEAD 也會指向剛剛切換過去的那個分⽀,也就是說 `.git/HEAD` 這個檔案會跟著被修改。 ### 修改分支名稱 分支改名**不會影響到檔案或目錄**。 ```bash $ git branch -m <old branch-name> <new branch-name> ``` ### 刪除分支 ```bash $ git branch feature $ git branch * develop feature master $ git branch -d feature Deleted branch feature (was babb78d). ``` 如果要刪除的分支還沒被完全合併,Git 會有小提示: ```bash $ git branch -d feature error: The branch 'feature' is not fully merged. If you are sure you want to delete it, run 'git branch -D cat'. ``` 如果刪除了**尚未被合併完成**的分支,但事後反悔了想將檔案救回來,還是有方法可行的。 ![delete unmerged branch](https://imgur.com/BOWWGhq.png) 從上圖可以看到,即便刪除了分支,但在該分支上原先的 Commit 依然保存著,那是因為**分支只是一個指向某個 Commit 的指標,刪除這個指標並不會造成那些 Commit 消失**。既然 Commit 沒有消失,就意味著還是可以重新把它找回來: ```bash $ git branch return_dev b174a5 ``` 這個指令的意思是「建立一個名為 `return_dev` 的分支,讓它指向 `b174a5a` 這個 Commit」,簡單來說就是再去拿一張新的貼紙貼回去的意思。 :::warning **補充** 如果沒有把被刪除的分支的 SHA-1 值記下來,該怎麼復原? 可以使用 **`git reflog`** 指令去查找。當 **`HEAD`** 有移動的時候(例如:切換分支或是 reset,都會造成 **`HEAD`** 移動),Git 就會在 Reflog 裡記上一筆。 ::: ### 合併分支 當在 `develop` 分支開發完新功能,要將功能上線到穩定系統,也就是把 `develop` 分支合併到主要分支 `master`,需要以下步驟: 0. 使用 `git log` 指令查詢歷史紀錄: ```bash $ git log --oneline 87e0bb8 (HEAD -> develop) <create> product management feature a3664cb <create> product page 6b9bf18 (master) <create> main feature dbbcdd9 <create> home style 4c6862a <create> home page ``` 1. 切回主要分支 `master` ``` bash $ git checkout master Switched to branch 'master' ``` 2. 輸入要合併的分支名稱 ```bash $ git merge develop Updating 6b9bf18..87e0bb8 Fast-forward product.html | 0 product.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 product.html create mode 100644 product.js ``` 在 `develop` 分支新增的 `product.html` 與 `product.js` 兩個檔案,因為主要分支 `master` 現在已經合併了 `develop` 分支,所以現在在主要分支 `master` 上也有這兩個檔案了。 :::danger **注意** 所謂的 Merge 並不是指分支與分支之間的合併,而是去 Merge 「**該分支所指向的那些 Commit**」。 ::: #### 快轉模式(Fast Forward) 快轉模式是指當主要分支 `master` 合併 `feature` 分支時,`master` 當前的節點一直和 `feature` 的根節點相同,沒有發生改變,此時就會採取「快轉模式」,其實就是把 `master` 這張貼紙撕起來,往前貼到 `feature` 分支所指的那個 Commit 而已。 ![fast forward](https://imgur.com/gh2tuar.gif) #### 非快轉模式(No Fast Forward) 當主要分支 `master` 當前的節點與 `feature` 分支的根節點不同時,此時合併分支並不會觸發快轉模式,會額外產出一個 Commit。 ![no fast forward](https://imgur.com/kiAcFZ6.gif) ### 另一種合併方式:rebase rebase 這個英文單字的翻譯是「重新定義分支的**參考基準**」。Rebase 合併分支跟 Merge 合併分支最明顯的差異在於,使用 Rebase 合併分支,Git 不會特別產生一個專門用來合併的 Commit。 > A `git rebase` copies the commits from the current branch, and puts these copied commits on top of the specified branch. ![rebasing](https://imgur.com/OXgklx2.gif) #### rebase 參考資料 [另一種合併方式(使用 rebase)](https://gitbook.tw/chapters/branch/merge-with-rebase) ### 合併時發生衝突(Merge Conflict) Git 有能力幫忙檢查簡單的衝突,所以並不是改到同一個檔案就一定會發生衝突,但是改到**同一個檔案的同一行程式碼**就沒辦法了。Git 無法幫你選擇哪一個當作最終版本,所以當發生衝突時,只能「自己手動調整」。 假設現在有一個 `index.html` 檔案,主要分支 `master` 與 `develop` 分支都同時修改了這個檔案的同一行程式碼,如果想要把 `develop` 分支 Merge 到主要分支 `master` 上,會出現以下訊息: ```bash $ git merge develop Auto-merging index.html CONFLICT (content): Merge conflict in index.html Automatic merge failed; fix conflicts and then commit the result. ``` 使用 `git status` 指令查詢目錄狀態: ```bash $ git status On branch master You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add <file>..." to mark resolution) both modified: index.html no changes added to commit (use "git add" and/or "git commit -a") ``` > You have unmerged paths. 你有一個未合併的路徑。意思就是**目前的合併尚未完成**。 進入 `index.html` 檔案會顯示衝突發生的位置,需要手動調整檔案內容: ![merge conflict message](https://imgur.com/rSN5i9L.png) Git 會把有衝突的段落標記出來: * 上半部是 `HEAD`,也就是目前所在的主要分支 `master` * 中間是分隔線 * 下半部是被合併的分支,也就是 `develop` 分支 修改完發生衝突的段落後,還是要把檔案重新安置到暫存區,並完成 Commit Message,才算解決 Merge Conflict。 ```bash $ git add index.html $ git commit -m 'conflict fixed' [master d634e31] conflict fixed ``` ![merge conflict](https://imgur.com/UWOIgkf.gif) ## 使用 GitHub 遠端共同協作 Git 是一個分散式版本控制工具,藉由它可以產生一個儲存庫(Repository),裡面存放著被 Git 版本控制的專案。 GitHub 是目前全球最大的 Git Server,許多 open-source 的專案都是使用 Github 進行程式碼的管理,可以把 GitHub 想成「**提供存放 / 使用 Git 專案儲存庫(Repository)的服務**」。 ### 將本地端 Repository 推送到遠端 1. 在 Github 上建立一個 Repository ![create repository](https://imgur.com/zStUuVM.png) 2. 建立好遠端 Repository 後,有兩種方式將本地端 Repository 與 GitHub 的遠端 Repository 連結: * 如果是全新開始的專案,依照「create a new repository on the command line」指示進行 * 如果是要上傳現有專案,依照「push an existing repository from the command line」指示進行 ![remote guide](https://imgur.com/SXpZV0E.png) 3. 以全新開始的專案為例: ```bash $ cd /desktop $ mkdir git-practice $ cd git-practice $ echo '# Git Practice' >> README.md $ git init Initialized empty Git repository in /desktop/git-practice/.git/ $ git add README.md $ git commit -m 'initial commit' [master (root-commit) 542dc7e] initial commit 1 file changed, 1 insertion(+) create mode 100644 README.md ``` 4. 將本地端 Repository 推送到 GitHub ```bash $ git remote add origin https://github.com/avery210412/git-practice.git ``` 意思是「**將本地端 Repository 新增一個名為 `origin` 的遠端 Repository**」。 * `git remote`:主要是跟遠端有關的操作 * `add`:要加入一個遠端的節點 * `origin`:是一個「代名詞」,指的是後面那串 GitHub 伺服器的位置 ```bash $ git push -u origin master Enumerating objects: 3, done. Counting objects: 100% (3/3), done. Writing objects: 100% (3/3), 229 bytes | 229.00 KiB/s, done. Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 To https://github.com/avery210412/git-practice.git * [new branch] master -> master Branch 'master' set up to track remote branch 'master' from 'origin'. ``` `git push` 指令其實做了幾件事: * 把 `master` 這個分支的內容,推向 `origin` 指向的 GitHub 伺服器位置 * 在 `origin` 指向的伺服器上,如果 `master` 分支不存在,就建立一個叫做 `master` 的同名分支。 * 如果伺服器上原本就存在 `master` 分支,便會移動伺服器上 `master` 分支的位置,使它指到目前最新的 Commit 上。 * `-u`:設定 `upstream`,使本地端分支開始追蹤指定的遠端分支,也就是說現在開始,「**本地端的 `master` 分支,會去追蹤遠端 origin 上的 `master` 分支**」 5. 回到瀏覽器上重新整理頁面: ![push repository finished](https://imgur.com/o7Jjyn1.png) 看到這個畫面,表示已經順利把本地端 Repository 的東西,推送到這個遠端 Repository 裡面了。 :::success **狀況題** 如何修改已經 Push 到遠端的 Commit? 假設現在已經完成一個 Commit,並且也推送到遠端 Repository 上,如果此時專案中的檔案做了一些小修改,但是又不想在這個 Commit 以後再新增一個 Commit 記錄此次的修改,只想要修改上一次的 Commit 並且重新 Push 到遠端 Repository,可以這樣操作: 1. 使用 **`--amend`** 參數進行 Commit,來修改上一次的 Commit,此時 SHA-1 值會重新計算 2. 使用 **`git push --force-with-lease origin <branch>`**,將 Commit 推送至遠端 Repository ::: #### `git push` 參考資料 [如何使用 git push 指令只 Push 部份的進度?](https://youtu.be/VShhhq_5sMc) [怎麼有時候推不上去](https://gitbook.tw/chapters/github/fail-to-push) [修改已經 Push 到遠端 Repository 的 Commit](https://tinyurl.com/y6gtw7s8) --- ### 將遠端 Repository 同步至本地端 #### Fetch 當本地端 Repository 完成推送到遠端 Repository 時,目前的分支圖如下: ![git branching diagram](https://imgur.com/TR4NUjH.png) 假使這個專案由多人協作開發,某位開發者 Push 了新的功能,此時遠端 Repository 就會新增一個 Commit: ![push a new feature](https://imgur.com/5Pngthu.png) 此時,若想要把遠端 Repository 的最新版本下載回本地端,但又擔心下載後,會與本地端的 Repository 發生合併衝突(Merge Conflict)的情形,此時可以使用 `git fetch` 指令。 當執行 Fetch 指令時,Git 會看一下遠端 Repository 的最新版本內容,再比較一下此時本地端 Repository 的內容,它會**把遠端有但是本地端沒有的內容**下載到本地端 Repository,但是**不會將這些內容合併到本地端 Repository**,因此分支圖還是會維持上面的情況: ![git fetch](https://imgur.com/5Pngthu.png) 由於 `origin/master` 這個遠端分支,是從本地端 `master` 分支推送到 GitHub 進而產生的,因此 `origin/master` 分支跟 `master` 分支**本是同根生**。如果要把 Fetch 得到的最新版本內容合併到本地端 Repository,會觸發快轉模式(Fast Forward),此時的分支圖如下: ![Fetch and Merge](https://imgur.com/QUQ5aAH.png) ![Fetch](https://imgur.com/tPCaQE5.gif) #### Pull > *git pull = git fetch + git merge* Pull 指令就是將遠端 Repository 的最新版本下載回本地端,並且將遠端分支合併到本地分支,也就是將 `origin/master` 這個遠端分支**直接合併**到本地端 `master` 分支。 ![Pull](https://imgur.com/RtefJ9S.gif) ### 從 GitHub 伺服器上取得 Repository 如果在 GitHub 上看到某個專案很有趣,想要下載到本地端研究,使用 Clone 指令就可以把整個專案複製一份到本地端了。 ```bash $ git clone https://github.com/sparanoid/chinese-copywriting-guidelines.git Cloning into 'chinese-copywriting-guidelines'... remote: Enumerating objects: 907, done. remote: Counting objects: 100% (212/212), done. remote: Compressing objects: 100% (98/98), done. remote: Total 907 (delta 137), reused 181 (delta 113), pack-reused 695 Receiving objects: 100% (907/907), 354.90 KiB | 2.25 MiB/s, done. Resolving deltas: 100% (529/529), done. ``` Clone 指令會把整個專案的內容複製一份到本地端,也就是你的電腦裡,這裡指的「內容」不是只有檔案,而是指**整個專案的歷史紀錄、分支、標籤等**內容都會複製一份下來。 :::danger **注意** 如果這個專案你是第一次看到,想要下載到你的電腦裡,請使用 **Clone** 指令;如果你已經下載過這個專案,只是想要把本地端的內容,更新成最新的線上版本內容,請使用 **Pull**(**Fetch**)指令。 **Clone 指令通常只會在第一次下載時使用,Clone 之後的更新,就是 Pull / Fetch 的事了。** ::: ## 使用 GitHub Flow 參與開源專案 Git 儲存庫並沒有**權限控管**的概念。當越多人參與同一個專案,每個人都有存取這個儲存庫的權限時,可能會遇到一些協作開發上的問題,例如:每個人都可以 Commit 到專案正式上線的分支(例如:`master`),在這種情況下,不同人彼此之間的程式碼會互相干擾。 GitHub 提供了 Fork 與 Pull Request 的機制,賦予儲存庫基本的權限控管。 ### GitHub Flow ![GitHub Flow](https://i.imgur.com/gns2luN.png) GitHub Flow 是一個基於分支(branch)的輕量化工作流程,藉由分支去管理功能的開發,以及來自社群的貢獻。 遵守 GitHub Flow 進行開發有一個規則:**`master` 分支必須保持隨時可以部屬正式環境(Production Ready)的狀態**。 ### GitHub Flow 步驟 #### Fork ![fork repository](https://imgur.com/Oq2TpJc.png) 如果想要參與一個你沒有推送(Push)權限的專案,可以先複製(**Fork**)一份原始專案的**副本**到自己的 GitHub 帳號底下,你對這個副本有全部的權限,之後的任何修改都在這個副本中執行。 所有人都可以 Fork 專案,對 Fork 出來的副本 Push 更新內容,然後去發送 Pull Request,來把這些更新內容貢獻回原始專案裡。 > Fork 在這邊翻譯成「複製」,但並不是這個詞的原意。在技術圈來說,這個詞使用的情境是「原作者做得不夠好,其它人覺得可以做得更好,或是想加入一些個人喜好的功能,而修改出另外的版本」。 #### Branch ![Create Branch](https://i.imgur.com/YxNhiqA.png) 將副本 Clone 到本地端,第一件事情就是**建立新分支**,之後的修改和討論都會**以這個分支為基準**。 在專案建立一個分支,代表建立了一個環境來開發新功能,在分支上所做的修改,都不會影響到 `master` 分支,所以可以自由的嘗試並提交修改。 #### Commits ![Add Commits](https://i.imgur.com/ehEeTyx.png) 在對專案進行功能開發、修改之前,執行 `git remote -v` 查看 Git 的遠端設定: ```bash $ git remote -v origin https://github.com/avery210412/chinese-copywriting-guidelines.git (fetch) origin https://github.com/avery210412/chinese-copywriting-guidelines.git (push) ``` 建議對 Git 的遠端設定進行調整,**將 fetch 的遠端位置,改成原始專案的位置**: ```bash $ git remote set-url origin https://github.com/sparanoid/chinese-copywriting-guidelines.git $ git remote -v origin https://github.com/sparanoid/chinese-copywriting-guidelines.git (fetch) origin https://github.com/sparanoid/chinese-copywriting-guidelines.git (push) $ git remote set-url --push origin https://github.com/avery210412/chinese-copywriting-guidelines.git $ git remote -v origin https://github.com/sparanoid/chinese-copywriting-guidelines.git (fetch) origin https://github.com/avery210412/chinese-copywriting-guidelines.git (push) ``` 這樣設定可以達到以下好處: * 之後會從原始專案中取得最新的專案資料(fetch),保持專案的一致性 * 所有修改的資料只會推送到自己的專案中(push),不會影響到其他人 完成設定後,就可以對專案進行功能開發。 #### Pull Request ![Open Pull Request](https://i.imgur.com/1XdLZa1.png) 功能開發完成後,將本地端的 Repository 推送到遠端的 GitHub Repository。 此時可以在 GitHub 上建立一個 Pull Request,Pull Request 提供了一個方式法來通知專案維護者,是否考慮使用你所做得修改。 這邊特別說明一件事,每個專案可能都有自己的規範,通常會寫在專案的 `README.md` 或是 `CONTRIBUTING.md`,請務必在修改或提交前,閱讀專案的規範,維持開源專案的品質。 #### Discuss And Review ![Discuss And Review](https://i.imgur.com/ser2wXQ.png) 專案維護者在檢視你所貢獻的程式碼後,可以在該 PR 中進行討論,討論程式碼內容或關於修改的建議。過程中如果有需要修改的地方,可以直接在該分支中進行修改,因為 **PR 是看分支的**,所以該分支於 PR 確認合併前,都可以新增 Commit,並納入該 PR 中。 #### Deploy ![Test Deploy](https://imgur.com/ibRwwDN.png) 正式合併到 `master` 分支之前,在這個階段可以先部署到測試環境,以進行合併前的最終測試。如果測試沒有通過或產生任何可以討論的議題,則可以取消合併,在通過一系列的測試後,才可以發佈到正式環境(Production Ready)上。 #### Merge ![Merge](https://i.imgur.com/IYJgbY5.png) 當所貢獻的程式碼經過一連串的檢閱、測試後,具有**原始專案合併權限的人**,就可以將你的貢獻合併到原始專案中了,你也成為原始專案的貢獻者(Contributions)之一了。 #### GitHub Flow 參考資料 [如何使用 GitHub Flow 來參與開源專案](https://blog.poychang.net/guide-to-use-github-flow/) [讓我們來了解 GitHub Flow 吧!](https://reurl.cc/1ZYDqp) ## 總結 ![Git Cheat Sheet](https://i.imgur.com/zzNkt5X.jpg) ### Git 版本控制參考資料 [為你自己學 Git](https://gitbook.tw/) [CS Visualized: Useful Git Commands](https://dev.to/lydiahallie/cs-visualized-useful-git-commands-37p1)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully