Kai Chen
    • 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

      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.
      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
    • 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 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

    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.
    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
    # 六角鼠年鐵人賽 Week 21 - Spring Boot - Redis 資料結構介紹 ==大家好,我是 "為了拿到金角獎盃而努力著" 的文毅青年 - Kai== ## Jerry Sloan :::info Hopefully this gives us some confidence to try to get better. That's the biggest thing. ::: ## 主題 上週已經介紹了安裝與環境設定的變數,這週就來學學 Redis 提供的五種資料結構的操作指令。 如同操作 RDBMS 一樣,我們會送許多指令到 Redis 執行,因此對於這些指令能夠有所了解是一件重要的事情,當然這不是說要你背下來,而是你必須知道有這些事務可以操作,詳細的方法再查教學文件即可。 ## Key Redis 是一個 Key-Value 形式的 NoSQL,因此除了資料結構外,最重要的便是針對 Key 的操作。 Redis 提供以下操作方法: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | SET [keyName] [keyValue] | 設定一個 Key-Value | 根據資料結構的不同,有可能用不同的 Set 指令,例如: Hash 使用 HMSET 的指令 | | DEL [keyName] | 刪除一個存在的 Key | 若不存在則不做任何動作 | | DUMP [keyName] | 返回該 Key 的序列化 Value || | EXISTS [keyName] | 檢查該 Key 是否存在 || | EXPIRE [keyName] [seconds] | 設定該 Key 的有效時間 | 單位為秒;返回 0 or 1;0 表示 Key 不存在或未超時;1 表示該 Key 存在且超時 | | EXPIRE [keyName] [timeStamp] | 設定該 Key 的有效時間 | Unix時間戳格式;其餘與上述效果一樣 | | PEXPIRE [keyName] [milliSeconds] | 設定該 Key 的有效時間 | 單位為毫秒 | | PEXPIRE [keyName] [milliSeconds-timeStamp] | 設定該 Key 的有效時間 | Unix毫秒時間戳格式 | | KEYS [pattern] | filter 查詢 Key |例如現在有 test1 "hello world", test2 "hi world", test3 "greeting world" 三筆資料,可以使用 KEYS test* 一次將三筆資料搜索出 | | MOVE [keyName] [DB Number] | 將該 Key 移動到指定 DB 中 | 可以在 redis-cli 使用 SELECT [DB Number] 方式,跳轉到指定 DB | | PERSIST [keyName] | 移除過期的 Key || | PTTL [keyName] | 檢視該 Key 的到期剩餘時間(返回單位為毫秒) | 返回值若為 -1 表示該 Key 尚未到期;-2 表示該 Key 不存在 | | TTL [keyName] | 檢視該 Key 的到齊剩餘時間(返回單位為秒) | 與上述效果一樣 | | RANDOMKEY | 隨機取得一個 Key || | RENAME [keyName] [New Name] | 更動該 Key 名稱 | 若新的 Key Name 已存在,則會覆蓋已存在的 Key Name 的 Value;若 更動前後名稱一樣或原本的 Key 不存在則返回 error | | RENAMENX [keyName] [New Name] | 更動該 Key 名稱 | 若新的 Key Name 已存在則不進行更新,並返回 0;若更動成功則返回 1| | TYPE [keyName] | 返回該 Key 的 Value 的型態| | FLUSHALL | 刪除所有 redis 保存的資料 | 不建議正式環境使用,測試可以常用 | ## String 字串是最常見的資料結構,在 Redis 中並不支援數值類型的資料型態,因此就算輸入的值沒有用雙引號括起來,還是會在儲存的時候被轉為字串儲存。 下列是關於字串的操作指令: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | SET [keyName] [keyValue] | 設定一個 Key-Value | 無論有無使用雙引號,全部會轉為字串儲存 | | SETBIT [keyName] [offset] [keyValue] | 設置一個 Key-Value,並設定 bit 位置的值為 0 or 1 || | SETEX [keyName] [seconds] [keyValue] | 設置一個 Key-Value,並有到期時間 | 單位為秒 | | PSETEX [keyName] [milliSeconds] [keyValue] | 設置一個 Key-Value,並有到期時間| 單位為毫秒 | | SETNX [keyName] [keyValue] | 設置一個 Key-Value 前會先檢查該 Key 是否存在,若不存在則建立,並返回 1,若存在則不覆蓋,並返回 0 || | SETRANGE [keyName] [start Number] [keyValue] | 使用新值去覆蓋一個 Key 的 Value,會從 start Number 的位置開始覆蓋 | 長度計算從 0 開始| | GET [keyName] | 取得該 Key 的 Value || | GETRANGE [keyName] [start Number] [end Number] | 取得該 Key 從 start Number 到 end Number 位置的值 | 長度計算從 0 開始;若 end Number 為 -1,表示全部取出 | | GETSET [keyName] [keyValue] | 設置該 Key 新的 Value,並同時返回舊 Value | 舊 Value 僅能取得一次,因為已經被覆蓋為新值 | | GETBIT [keyName] [offset] | 取得該 Key 的 bit 位置的值 || | STRLEN [keyName] | 取得該 Key 的 Value 字串長度 || | MSET [keyName1] [keyValue1] [keyName2] [keyValue2]... | 設置多個 Key-Value,若 Key 存在則會將已經存在的 Key 覆蓋 || | MSETNX [keyName1] [keyValue1] [keyName2] [keyValue2]... | 設置多個 Key-Value,當只有 Key 不存在的時候才會建立 || | INCR [keyName] | 當 Value 可以轉為整數數值型態時,進行 +1 的動作 | 限制可為 64位元帶符號整數 | | INCRBY [keyName] [increment] | 當 Value 可以轉為整數數值型態時,進行 +increment 的動作 | 限制可為 64位元帶符號整數 | | INCRBYFLOAT [keyName] [increment] | 當 Value 可以轉為浮點束束值型態時,進行 +increment 的動作 | 限制可為 64位元帶符號浮點數 | | DECR [keyName] | 當 Value 可以轉為整數數值型態時,進行 -1 的動作 | 限制可為 64位元帶符號整數 | | DECRBY [keyName] [decrement] | 當 Value 可以轉為整數數值型態時,進行 -decrement 的動作 | 限制可為 64位元帶符號整數 | | APPEND [keyName] [keyValue] | 串接新的值到該 Key 的尾端 | 並不會針對數值型態做相加的動作 | | SCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber] | filter 查詢所有 Key 的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]| > Redis 並沒有提供 DECRBYFLOAT 指令,是因為這個操作可以藉由 INCRBYFLOAT -0.5 的方式達成,同理諸多指令其實可以統一使用 INCR 完成即可 ## Hash Redis 提供關於 Hash 的處理,下方列出相關操作指令: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | HSET [keyName] [field] [keyValue] | 設置一個 Hash Key,並把值放入 field 內,若 field 已存在,則覆蓋原有 field 的 Value || | HMSET [keyName] [field1] [keyValue1] [field2] [keyValue2] | 設置一個 Hash Key,並設置多個 field 與其 Value,若 field 已存在則會進行覆蓋 || | HSETNX [keyName] [field] [keyValue] | 設置一個 Hash Key,並檢查 field 是否存在,不存在則建立,若存在則不做任何動作 || | HGET [keyName] [field] | 獲取該 Key 中的 field 的 Value|| | HMGET [keyName] [field1] [field2]...| 獲取該 Key 中指定的 field 的 Value|| | HGETALL [keyName] | 獲取該 Key 的所有 field 與 Value || | HDEL [keyName] | 刪除該 Hash Key || | HEXISTS [keyName] [field] | 檢查該 Key 中的 field 是否存在 |返回 1 表示該 field 包含值;返回 0 表示該 field 不包含值或不存在| | HINCBY [keyName] [field] [increment] | 若該 field 中的值可轉為整數數值型態,則進行 +increment 的動作|| | HICRBYFLOAT [keyName] [field] [increment] | 若該 field 中的值可轉為浮點數數值型態,則進行 +increment 的動作 || | HKEYS [keyName] | 獲取該 Key 中所有的 field || | HVALS [keyName] | 獲取該 key 中的所有 Value || | HLEN [keyName] | 獲取該 key 中的 field 數量 || | HSCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber] | filter 查詢所有 Key 的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]|| ## List List 是 Redis 中常見的資料結構,我們常會用來儲存各式各樣的一組資料在許多的 List 中,下面是操作指令: | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | LPUSH [keyName] [keyValue1] [keyValue2]... | 將一個或多個新值,從該 key 的首位開始塞入值,意即為最後一個塞入的值將會是該 List 第一筆資料 || | LPUSHX [keyName] [keyValue1] [keyValue2]... | 如上述,僅會在該 Key 存在時進行動作 || | LLEN [keyName] | 取得該 Key 的陣列長度 || | LPOP [keyName] | 取得該 Key 的首位值 || | BLPOP [keyName1] [keyName2]... [seconds] | 當 Key 的陣列為空或者無可以 POP 的值時,進行阻塞讓該 Key 無法被使用,直到有可以 POP 的值或是設定的時間超過為止 | 此動作可以避免輪詢的時候佔用太多資源 | | RPOPLPUSH [keyName] [KeyName2] | 將該 Key 尾端的值 POP 出,並將其值塞入 key2 的首位 || | LINDEX [keyName] [index] | 取得該 Key 的 index 位置的值 || | LINSERT [keyName] BEFORE/AFTER [targetValue] [keyValue] | 針對該 Key 在 targetValue 的前後增加新的值 || | LRANGE [keyName] [start Number] [end Number] | 列出陣列從 start 開始一直到 end 位子的值 | 也可以用 -1 -2 表示從尾端數來的值位子 | | LREM [keyName] [count] [keyValue] | 從首位開始刪除與輸入的 KeyValue 相等的值,當 count > 0 表示從頭的該位數到尾端;count < 0 表示從尾的該位數到首端;0 表示全部 || | LSET [keyName] [index] [keyValue] | 將該 Key 的 index 位置設置新的 value 進去覆蓋 | 若超出原先的陣列長度的位置則會返回錯誤 | | LTRIM [keyName] [start Number] [end Number] | 針對該 Key 從首端開始的 start 到 end 位置的值都將去除 || > 上述 L 開頭的指令通通可以換成 R 開頭,指令的意義即是從首位開始處理的方式變成從尾端開始處理 ## 集合 | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | SADD [keyName] [keyValue1] [keyValue2]... | 增加一個或多個新值進入該集合中|若新值已存在集合中則會覆蓋舊值;若 key 不存在則會自動建立包含新值的集合;若 key 不是集合類的資料結構會返回錯誤| | SISMEMBER [keyName] [value] | 判斷該 Value 是否為該 key 集合中的成員|返回 1 表示是集合成員;返回 0 表示不是集合成員或該 Key 不存在| | SPOP [keyName] | 取得該 key 中隨機一個成員,並且將其在集合中移除|| | SRANDMEMBER [keyName] [count] | 取得該 Key 中隨機 count 數的成員 |當 count > 0 則出現成員不重複; count < 0 則出現成員會有重複| | SREM [keyName] [keyValue1] [keyValue2]... | 移除該集合中指定的 value 成員| 在 Redis 2.4 版本以前,一次只能指定一個 keyValue| | SMOVE [keyName1] [keyName2] [keyValue] | 將 key1 的 value 成員移動到 key2 |返回 1 表示移動成功;返回 0 表示 key1 or key2 不存在或 value 並非 key1 的成員| | SCARD [keyName] | 返回該 Key 集合成員數目 |返回 0 表示沒有資料或是該 key 不存在| | SMEMBERS [keyName] |返回該 Key 集合成員 |空白表示為空集合或該 Key 不存在| | SSCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber] |filter 查詢所有 集合成員的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]|| | SINTER [keyName1] [keyName2]...| 返回兩個或兩個以上集合的交集成員 || | SINTERSTORE [keyName1] [keyName2]...| 返回兩個或兩個以上集合的交集成員數量 || | SUNION [keyName1] [keyName2]...|返回兩個或兩個以上集合的聯集成員|| | SUNIONSTORE [keyName1] [keyName2]...|返回兩個或兩個以上集合的聯集成員數量|| | SDIFF [keyName1] [keyName2]...|返回兩個或兩個以上集合的差集的成員|| | SDIFFSTORE [keyName1] [keyName2]...|返回兩個或兩個以上集合的差集的成員數量|| ## 有序集和 | 指令 | 描述 | 備註 | | ---- | ---- | ---- | | ZADD [keyName] [score1] [keyValue1] [score2] [keyValue2]... | 將一個或多個 Value 給予 score 後加入到 key 中| score 可以為整數或雙精度浮點數| | ZSCORE [keyName] [keyValue]| 返回該 value 在 key 中被給予的 score 值| score 值以字串顯示| | ZINCRBY [keyName] [increment] [keyValue] | 將 key 中的該 Value 增加 increment 數的 score || | ZCARD [keyName] | 返回該 key 中的成員數量 || | ZCOUNT [keyName] [min] [max] | 返回該 key 中 score 大於 min 且小於 max 的成員數目|| | ZRANGE [keyName] [start] [stop] ["WITHSCORES"] | 返回該 key 中從 start 位置到 stop 位置的值,若有使用 WITHSCORES 參數則會一併帶出該值的 score|| | ZREVRANGE [keyName] [start] [stop] ["WITHSCORES"] | 與上述效果相同,差別在返回的順序剛好相反|| | ZRANGEBYSCORE [keyName] [min] [max] ["WITHSCORES"] ["LIMIT offset count"] | 返回該 key 中 score 大於 min 且小於 max 的成員,若有使用 WITHSCORES 參數則會一併帶出該值的 score,LIMIT 可以用來控制返回值的數量|min 和 max 可以用 -inf 和 +inf 取代,意即最小無限制和最大無限制,但這樣可能會造成查找資源的使用過多| | ZREVRANGEBYSCORE [keyName] [min] [max] ["WITHSCORES"] ["LIMIT offset count"]| 與上述效果相同,差別在返回的順序剛好相反|| | ZRANK [keyName] [keyValue]| 返回該成員在集合中的排名 | 以 score 由小到大,排名為 0 ~ n - 1| | ZREVRANK [keyName] [keyValue]|返回該成員在集合中的排名| 以 score 由大到小,排名為 0 ~ n - 1| | ZREM [keyName] [keyValue1] [keyValue2]... | 將一個或多個 value 從 key 中移除|返回值為成功移除的成員數目| | ZREMRANGEBYRANK [keyName] [start] [stop] | 以 rank 由小到大,移除排名在 start 到 stop 之間的所有成員|| | ZREMRANGEBYSCORE [keyName] [min] [max]| 移除 score 在 start 到 stop 之間的所有成員|| | ZRANGEBYLEX [keyName] [min] [max] ["LIMIT offset count"] | 當該 Key 成員間具有相同的 score 時,則返回 value 在 min 和 max 之間的成員| mix 和 max 必須要用 "(" 或 "[" 明確標示範圍或字符;"(" 表示不包含值;"[" 表示包含該值| | ZLEXCOUNT [keyName] [min] [max]|與上述效果相同,差別在於返回符合的成員數量|| | ZREMRANGEBYLEX |與上上述效果相同,差別在於移除符合的成員| 返回值為移除的成員數量 | | ZSCAN [keyName] [cursor] ["match" pattern] ["count" LimitNumber]|filter 查詢所有 集合成員的方式| cursor 可設為 0;若有使用 match 功能,則指令為 match [keyName pattern];若有使用 Limit 功能,則指另為 count [LimitNumber]|| | ZUNIONSTORE [keyName1] [number keys] [keyName2] [keyName3] [weight1] [weight2] |將 number keys 數的 key2 和 key3 放入 key1 中,放入時針對 score 的部分各別乘上 weight1 和 weight2 的權重 | 返回為處理完成的 key1 成員數目 || | ZINTERSTORE [keyName1] [number keys] [keyName2] [keyName3] [weight1] [weight2] | 將 number keys 數的 key2 和 key3 放入 key1 中,放入時針對相同 value 的成員,其 score 會做相加的動作 | 返回處理完成的 key1 成員數目| ## 結語 :::danger 這週主要就是介紹所有我們會用到的 Redis 資料結構,這樣在使用上就可以有最基本的掌握,已經可以搭配程式開始處理一些比較棘手的 Cache 問題了 ~~下一篇將會繼續分享關於 Redis 幾個好用的功能~~ 下一篇將來分享 Java 與 Redis 的簡單結合使用範例 [六角鼠年鐵人賽 Week 22 - Spring Boot - Java & Redis 範例](/F2UaokVRRWmGVrvkKc7Ofw) ::: 首頁 [Kai 個人技術 Hackmd](/2G-RoB0QTrKzkftH2uLueA) ###### tags: `Redis`,`w3HexSchool`

    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

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    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