philomagi
    • 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
    オブジェクト指向設計実践ガイド読書会 - 第46回 === ###### tags: `オブジェクト指向設計実践ガイド読書会` # 開催概要 * 日程: 2023/02/04 Sat 21:00〜23:00 * 会場: https://discord.com/channels/432531367427964929/898843794101911622 * [README](https://hackmd.io/sSmTRzcQSCuvqiO7uDUkFg) * [タイムキーバー用テンプレート](https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw) ## 課題図書 『オブジェクト指向設計実践ガイド ~Rubyでわかる 進化しつづける柔軟なアプリケーションの育て方』(Sandi Metz 著, 髙山泰基 訳, 技術評論社) - 技術評論社, pdf版あり - https://gihyo.jp/book/2016/978-4-7741-8361-9 - Amazon - https://www.amazon.co.jp/dp/B01L8SEVYI ## 実施要領 - 事前読書なし。都度その場で読んで、感想を書いて、議論する、を繰り返す。 - 参加スタイルは自由形。チャットでも音声でもご自由に。 - 主催はチャット参加です。 ## タイマーについて 時間管理はタイマーbotで行います。 VCチャンネルに入っている人を対象にメンションが飛ぶので、VCチャンネルへの参加をお願いします。 また、タイマーは終了時に **音声がなる** ので、ご注意ください。 ## 当日までの準備 1. 課題図書を手元に用意する - 買う、借りる、etc(?) 2. 当日までに読んだり読まなかったりする - 当日その場で読むので、事前に読んでおく必要は無し - 気になったら事前に読んでおいても良し --- # 当日の進行 ## 進行フロー https://hackmd.io/sSmTRzcQSCuvqiO7uDUkFg?view#%E9%80%B2%E8%A1%8C%E3%83%95%E3%83%AD%E3%83%BC ## :goti: or :okawari: について - 各パートごとに :goti: or :okawari: を投票する. - :okawari: が1つでも有れば、パートを続行する. ## 開催コール https://1.bp.blogspot.com/-YrhlmWQ4uIQ/UrlmxoUdDeI/AAAAAAAAcLw/M6VFUKHnTos/s400/text_start.png ## タイムキーパー募集 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E3%82%BF%E3%82%A4%E3%83%A0%E3%82%AD%E3%83%BC%E3%83%91%E3%83%BC%E5%8B%9F%E9%9B%86 ## 読書パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E8%AA%AD%E6%9B%B8%E3%83%91%E3%83%BC%E3%83%88 ## 投票パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%8A%95%E7%A5%A8%E3%83%91%E3%83%BC%E3%83%88 ## トークパート ### 議論(:thinking_face:)パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E8%AD%B0%E8%AB%96%E3%83%91%E3%83%BC%E3%83%88 ### 任意トーク(:+1:)パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E4%BB%BB%E6%84%8F%E3%83%88%E3%83%BC%E3%82%AF%E3%83%91%E3%83%BC%E3%83%88 ### 次回繰越(:eyes:)パート https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%AC%A1%E5%9B%9E%E7%B9%B0%E8%B6%8A%E3%83%91%E3%83%BC%E3%83%88 ## 終了コール http://3.bp.blogspot.com/-zgTNWF_hBmI/UZYlh9RhuDI/AAAAAAAATQ8/dymPl5P4eAs/s500/undoukai_relay_animal.png # 読書メモ ## 9.1_意図を持ったテスト_いつテストをするかを知る_p.245_p.246 [前回の繰越](https://hackmd.io/VT6QJm4ZQd6t3mLT8Cr2jg?view=#91_%E6%84%8F%E5%9B%B3%E3%82%92%E6%8C%81%E3%81%A3%E3%81%9F%E3%83%86%E3%82%B9%E3%83%88_%E3%81%84%E3%81%A4%E3%83%86%E3%82%B9%E3%83%88%E3%82%92%E3%81%99%E3%82%8B%E3%81%8B%E3%82%92%E7%9F%A5%E3%82%8B_p245_p246) ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1071403487994318858 ### 感想 > p.245 テストを最初に書く意味があるのならば、いつでもそうしましょう。残念なことに、そうすることに意味があると判断するのは、初級プログラマーにとっては難しいこともあります。 :+1: - 難しいうえにテストを最初に書くこと自体が難しくでできなかった(今もできない) - %s/初級プログラマー/人類/ Hahaha :) - おまけに、意味があると判断できても、テストの目的を適切に設定できなかったり、テストの目的に沿ったテストを書けなかったりするので、人類には早(ry :+1: > 「テストとは再利用」であり、このコードの再利用はできないからです。 - p.245 - 「テストが再利用」というのは、言われてみれば確かに。だからこそ、TDDはプログラマを「最初の利用者」にするわけで。:+1: :+1: - この表現に乗っ取るなら、「テストが難しい」は「再利用が難しい」と近似とも考えられそう。 - テストを書く意義として「再利用できるかどうかを実際に確かめる」という観点も、この表現からより強く押し出せそう > p.245 そのため、初級の設計者はテストファーストでコードを書くことが最も有益です。 - テストできるコードを最初から書くのは難しいので、新人にはいつも最初にTDDブートキャンプ動画見てもらってる。いきなり3h動画はきついかも?と思いつつ。 :clap: - 経験がないと「何をテストすれば良いかわからん」という、鶏卵のジレンマはあるきがする - 実際、テストの書き方みたいなのをまともに勉強していなかったせいで、仕様(外部向け)通りに動作するかのチェックしかできてない。 > 適切な意図を持った初級者はしばしば、コストが高く重複のあるテストを、散らかって、強固に結合されたコードの周辺に書きます。 - [トークパート](https://discord.com/channels/432531367427964929/898843794101911622/1071407955523674172) - Well-intentioned novices often write expensive, duplicative tests around messy, tightly coupled code - 「適切な意図を持った初級者 = Well-intentioned novices」 - https://www.ei-navi.jp/dictionary/content/well-intentioned/ - > しばしば良くない結果を招くものの、善意を特徴とする - えぇ……(原文のニュアンスが迷子 > その複雑なコードには、対象のタスクが持つ複雑さではなく、プログラマーの経験不足が反映されているのです。 - p.245 - 対象が複雑だから複雑なのか、複雑にしかできない作者だから複雑になっているのか、という問題はジャンル問わずついてまわる…… :+1: :+1: :+1: - 使い慣れていない言語を触った時に「こんな書き方出来るんだ!」となるソレも - 言語やフレームワーク固有のルールを覚えるコストが高すぎて適切なテストを書くまで時間がかかる問題ある、かといってそれらを無視してシンプルに書きすぎても困るという - シンプルに書こうとした結果、言語やFWの設計思想と合っていなくて、結果的に複雑になってしまって、こんなはずじゃ……ってなったり。 :+1: - 目線を入れ替えて、実際に複雑な設計・対象だから複雑に見えるのか、シンプルな構造を理解できないから複雑に見えているだけなのか、というのも - 抽象概念の理解、という話題の方が適切かも > p.245: そういった初級者がつくった複雑すぎるアプリケーションは、不屈の努力のたまものとして見られるべき - 「動いてえらい!」の評価はわすれないようにすべき。 :tada: - レビューでは、未熟さに対して否定的にコメントせず、改善のための批判的な視点から個々の問題点を整理するようにしたいところ。 - ここの部分、そんなにポジティブな話ではないような……? - > The overcomplicated applications these novices produce should be viewed as triumphs of perseverance; it’s a miracle these applications work at all. - 「不屈の努力のたまもの」は、より素直に訳すなら「忍耐の勝利」とか「我慢比べに勝った」ぐらいの意味に見える(as triumphs of perserverance) - つまり、「動いてえらい!」という話とはむしろ逆というか、初心者が書いたコードが動いているのは単に「我慢比べに勝った」という話に過ぎず、奇跡的に動いているだけで問題は山積みだぞ(動いているからって喜んでいる場合じゃないぞ)という、むしろ手厳しめの話に見える :naruhodo: > スパイクを打つとは、コードだけを書き、実験をすることです。こういった実験は予備的なもので、解決法が 不確かな問題のときに実施されます。 - p.246 - どういうコードが必要か、というのがそもそもイメージできない時とか、とりあえず試しに妄想ベースでコード書いてみて、というのは確かにやる - とりあえず動かなくても良い(なんならコンパイルも通らなくて良い)から、今必要なことをコードというテキスト形式で書きなぐってみて、それで方向がつかめたら実装 + テストコードで清書するなり、モデルの更新に向かうなり、的な - コードからフィードバックを得る方法は、テストを書く以外にも色々あるよね、的な - 思考の整理に使えるのは強いですね。具体的な方法は後から気合でどうにかできますが、それ以前の話(コードのインターフェイスなど)は変更がめんどくなるので :+1: :+1: > MiniTest で書かれたテスト例はRuby1.9以上がインストールされている環境であればどこでも動作するから - テストを実行する手軽さほんと大事だと思う > 自身の強みを過大評価し、肥大した自己像をもって、テストをしないことの言い訳にしてはいけません。 - どちらかというと、時間やマンパワーの不足の方が、理由として挙げられることの方が多い印象 :+1: - ここでの「テスト」が「自動テスト」を指すのだとして ## 9.1_意図を持ったテスト_テストの方法を知る_MiniTestフレームワーク_p.246_p.249 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1071412201048522882 ### 感想 > 誰でも新しいRubyのテスティングフレームワークをつくれますし - 作れまてん :+1: - 出力とか気にせず、ただ実行するだけならそれっぽいものも案外できなくは無い - モック?フック?subjectみたいな一元化?parameterized test?むずかしくてぼくわかんない > コストと利益を理解できるのであれば、自身に合うどんなフレームワークでも自由に選びましょう。 - p.246-247 - またちょっと翻訳が怪しい(^^; - if you understand the costs and benefits, feel free to choose any framework that suits you. - 「コストと利益を理解できるのであれば、あなたに合うフレームワークを自由に選んで構いません」ぐらいかな :+1: - "feel free to choose" が、なんか無駄に情緒的な表現っぽいのも、ちょっと翻訳を混乱させていそうな気もする(ので、若干著者の責任もありそう(^^; > p.248. しかし、2つ目のカテゴリーの物については、テストは可能な限り無知であり続けるべきです。 - 利用側が賢すぎる場合、テスト対象が使いづらくなったり、利用側のコードでもいろいろな依存が生まれるから気を付けたい。 :+1: - コンストラクタで依存性注入するようにして、テスト対象クラスそのものがなんらかのI/Fに依存するようにできても、利用側で地獄が錬成されることがあった。(DIコンテナ使え) > 全体としての目標は、テストカバレッジを持つ - テストに対する全体設計とロードマップ(≒テストカバレッジのスコープ)をトップダウンで決めるべきだと思うが、実務ではこれがボトムアップになって膨れ上がってしまうイメージはある - TDDとBDDの関係のあたり、そういう感じだっけ?と思ってBeckのTDD本付録C(と、Freemanの方)を流し見ししてみたが、そういう感じだったっぽい(冤罪 - > GOOSに記されているMockistTDDはそれを要件定義やアーキテクチャ選定、チーム開発のレベルまで拡大していく試みと捉えてもよいでしょう。彼らのテスト駆動開発には向き、方向が出現しました。外から内へという向きは、同時に未知から既知へという向きでもあり、かつ時間の制御も意味します。学びと時期をテストで制御できるようにする試みであるとも言えます。 - > GOOSにおけるダブルループの外側、つまりATDD部分においては、BDDでは実際に要件や要望を持っている顧客に直接参画してもらうことを目指しました。 ### 疑問 ## 9.2_受信メッセージをテストする_使われていないインターフェースを削除する_p.249_251 ### discord開始地点 https://discord.com/channels/432531367427964929/898843794101911622/1071420128656359446 ### 感想 > p.249: 受信メッセージは、オブジェクトのパブリックインターフェースを構成します。外の世界へ示 す顔(face)です。アプリケーションのほかのオブジェクトが、そのシグネチャと戻り値に依存し ているため、これらのメッセージはテストを必要とします。 → 次回繰越 - メッセージ (しかも「受信」メッセージ) とメソッドの同一視のせいか、意味を読み取るのに初見で首を捻挫した - 「受信メッセージは、オブジェクトのパブリックインターフェースを構成」 - 「受信メッセージに応じて起動されるメソッドは、〜」かな。受信可能なメッセージの定義はプロトコルを定めるけれど、ここでいうインタフェースを定めるものなのだろうか。 - 「ほかのオブジェクトが、そのシグネチャと戻り値に依存している」 - メソッドに依存しているならその通りだけど、(本来の意味での) メッセージに依存しているとするならば、シグネチャとかメッセージ処理機構の実装に直接的に依存するものなのだろうか。 > p.251: 依存されてなさそうな受信メッセージが見つかったならば、 - (本書での用法はおいておいて) 普通の捉え方としては、「依存されてない受信メッセージ」は存在しないのでは。 - 「受信メッセージ」「送信メッセージ」は、あるメッセージを受信した側から見たとき、送信した側から見たときの呼び方。 - とすると、受信メッセージなるものが存在するならば、それはなにものかが送信したものであるはず。 - ならば、いかなる受信メッセージも、送信者が存在し、その送信者に依存されていると見做されるのが妥当。 - この奇異に見える文章は、 オブジェクト間で送受可能なメッセージと、 受信側のオブジェクトに備わっているメソッドを 同一視することにされるみに起因しているように思える。 - さらに、コードレベルでは、メソッド本体のコードも含めて「受信メッセージ」と呼んでいるように読める。 - それはメッセージを受け取った時の振る舞いであって、メッセージではない。 - 百歩譲って、メソッド呼出しをメッセージ送出と同一視することができたとしても、メソッド定義をメッセージと同一視することには同意しかねる。 > p.251: 依存されていない受信メッセージのテストをしてはいけません。 - 結構やってしまうな、相手のインターフェイスとして定義されているデータをとりあえず全てチェックちゃう(こちらでは利用しないものまで) :eyes: - 自分にはどういうようなテストなのか、ちょっとイメージできず、内容気になりました。どういうテストなんでしょう? > 相手のインターフェイスとして定義されているデータをとりあえず全てチェック - 例えば、Twitter APIのusers/showを使った際に、API Docに定義された構造はとりあえず全てチェックするイメージです(user_idしか使っていないとしても他の要素も全て) :naruhodo: > p.251: 受信メッセージには、必ずそこに依存するものがあります。表 9.1 に見て取れるように、これは diameter、gear_inches、ratio について成り立っています。(ただしそれらが受信メッセージで あるところで)。 - 日本語でおk - 素で意味がわからないんだけど、原文ではどうなってたのか。 > 依存されていない受信メッセージのテストをしてはいけません。そのメッセージは削除しましょう。 - p.251 - [トークパート](https://discord.com/channels/432531367427964929/898843794101911622/1071425079419875388) - 実際にプロダクトコードで使われていないコードを削除せよ、という主張自体は、特に異論無し - という一方で、それこそ将来想定される、あるいは「今時点では使わないが、近日中に必要になることが目に見えている」という実装も、時たま発生したりはする - そういうケースだと、「こういうことになったら、こういう実装やI/Fは多分必要だよね」という検討やそれに基づく実装(の一部)をまるっきり消すのもやや惜しい、となることも - そういうケースは、実装する代わりにIssueコメントやコードのコメント、あるいは単にテキストファイルなんかに想定していた実装のスニペット、実装しなかった経緯、どういう時に必要となる想定か、というのをメモして残したりはする - 大体はIssue、よほど確度が強ければテキストファイル、単にリリーススケジュールの都合でステップを刻んだだけならコメント or テキストファイル、みたいな使い方が多い - これって Pull Request ではなく Issue な感じですか?Pull Request にして close でもいいのかなと思ったんですが :eyes: - Pull Request でも良い気がしますね。自分は、PRには「本当はこういうふうに実装したかったけど、諸事情で諦めた(誰か頑張って実現して :heart: )」というのを残すことがあります。 :+1: ## {読書範囲} ### discord開始地点 ### 感想 ### 疑問 --- # ふりかえり - 感想/次回の課題それぞれで5分 - 要望に応じて :okawari: ## 感想 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%84%9F%E6%83%B3 ### 気づいたこと、気になったこと - 「テスト自体がコードの再利用」という観点は、言われてみればそれはそうなのだけれど、案外いままでそう捉えてなかった(or そう捉える感覚が薄かった). :+1: - この視点からテストを捉えると、「作ったモジュールが実際に再利用可能な設計になっているかどうか」という観点からテストを援用できそう :+1: :+1: - TDDとBDDの関係についての説明、「ホントォ?」という疑義は冤罪だったものの、それはそれとして付録CやFreeman本読み返す機会になったので :yoshi: (負け惜しみ - 作者の思いが強くこもっている部分もままあるなーという気持ちになった、とてもわかる - 最後の使われていないI/F云々も、最初にテストを書くことで、「これいらなくね?」という気づきが得られるかもしれない? - 自然と利用側として思考を回せると思うので、そういうのは利点だと思う。 ### 疑問点 ### 仕事に活用してみたいこと ## 次回の課題 https://hackmd.io/E0HZBN9OS9GBAtnsYXjDsw#%E6%AC%A1%E5%9B%9E%E4%BB%A5%E9%99%8D%E3%81%AE%E8%AA%B2%E9%A1%8C [まとめ用mdに追記](https://hackmd.io/wfDfaf4nRQuPG1BYtcy_jA) # 次回 https://hackmd.io/UzloqiPhQs-SJDiXbAOCFA?edit

    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