<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: DanKim0213</title>
    <description>The latest articles on DEV Community by DanKim0213 (@dankim0213).</description>
    <link>https://dev.to/dankim0213</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F852910%2Fd15d22fd-ff09-4d63-8cf9-b7ad32bdb091.jpg</url>
      <title>DEV Community: DanKim0213</title>
      <link>https://dev.to/dankim0213</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dankim0213"/>
    <language>en</language>
    <item>
      <title>내가 팀프로젝트에서 사용한 Git</title>
      <dc:creator>DanKim0213</dc:creator>
      <pubDate>Wed, 24 May 2023 07:06:48 +0000</pubDate>
      <link>https://dev.to/dankim0213/naega-timpeurojegteueseo-sayonghan-git-50cg</link>
      <guid>https://dev.to/dankim0213/naega-timpeurojegteueseo-sayonghan-git-50cg</guid>
      <description>&lt;h3&gt;
  
  
  Github Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;다른 사람이 같은 이슈를 작업하고 있진 않는지 확인하기&lt;/li&gt;
&lt;li&gt;그렇지 않다면, 깃랩에서 이슈 생성 및 feature 브랜치를 생성하기

&lt;ol&gt;
&lt;li&gt;하루 단위로 작업할 수 있는 feature 브랜치를 만들어주세요 &lt;/li&gt;
&lt;li&gt;이슈 생성시, label을 명확히 분간하여 달아주세요&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;일 하기&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git add . &amp;amp;&amp;amp; git commit
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;최신 업데이트 하기&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git pull --rebase origin develop
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;깃랩에 푸시하기&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push origin feature-sth
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  FAQ
&lt;/h3&gt;

&lt;p&gt;Q. Error: Updates were rejected because the tip of your current branch is behind&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;깃랩에 있는 feature 브랜치를 삭제하고 다시 푸시하세요
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push -d origin feature-sth &amp;amp;&amp;amp; git push origin feature-sth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q. 작업하던 feature 브랜치를 업데이트 하는 방법은?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;develop 브랜치를 바탕으로 업데이트 합니다
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git pull --rebase origin develop 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q. 집 노트북으로 작업하던 것을 외부 노트북으로 연이어 작업하는 방법은?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;내 로컬 feature 브랜치를 깃랩 feature 브랜치로 업데이트 합니다
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git pull --rebase origin feature-sth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Q. merge 가 안됩니다&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;merge는 오직 maintainers만 할 수 있습니다. maintainers 에게 말해주세요&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Q. rebase 할때, conflict 났습니다. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;철회하고 maintainers 을 불러주세요
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git rebase --abort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reference
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://scottchacon.com/2011/08/31/github-flow.html"&gt;GitHub Flow&lt;/a&gt;&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>github</category>
    </item>
    <item>
      <title>How to Handle Error with Jest</title>
      <dc:creator>DanKim0213</dc:creator>
      <pubDate>Wed, 15 Feb 2023 21:13:56 +0000</pubDate>
      <link>https://dev.to/dankim0213/how-to-handle-error-with-jest-3m2n</link>
      <guid>https://dev.to/dankim0213/how-to-handle-error-with-jest-3m2n</guid>
      <description>&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The goal of this post&lt;/li&gt;
&lt;li&gt;expect.assertions(number) rather than done()&lt;/li&gt;
&lt;li&gt;.rejects rather than try-catch&lt;/li&gt;
&lt;li&gt;.toThrow rather than toMatch or toEqual&lt;/li&gt;
&lt;li&gt;Use-case 1: Handle Error in a function&lt;/li&gt;
&lt;li&gt;Use-case 2: Handle Error in an asynchronous function&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. The goal of this post
&lt;/h2&gt;

&lt;p&gt;The goal of this post is to give you an opinionated way of how to handle error with jest. Since a bunch of source, including the official guide, suggests various ways (but each way has its own rule to comply with 😡), it would mislead to testing.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. expect.assertions(number) rather than done()
&lt;/h2&gt;

&lt;p&gt;Both expect.assertions() and done() are used to test async functions. However, expect.assertions() is focused on to verify that a certain number of assertions are called during a test while done() is focused on to wait a certain assertion to be called. Therefore, expect.assertions() would fail if the number of expectations are not called while done() would fail because of timeout (mostly from not calling done() at the end). &lt;/p&gt;

&lt;p&gt;Let's compare between done() and expect.assertion(number) when doing async calls.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/docs/expect#expectassertionsnumber"&gt;API - expect.assertions(number)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure to add expect.assertions to verify that a certain number of assertions are called. Otherwise a fulfilled promise would not fail the test.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;doAsync calls both callbacks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;callback1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;callback2&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeTruthy&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;doAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;callback2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/docs/asynchronous#callbacks"&gt;Testing Asynchronous Code - callbacks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;done() is necessary. Otherwise, the test will complete as soon as fetchData completes, before ever calling the callback.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;the data is peanut butter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;done&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;peanut butter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You could notice at a glance that done(error) is declared in the catch block in order to avoid timeout. On the one hand, you could easily notice errors and reduce your time to figure out what went wrong by doing so. On the other hand, you could easily forget that where you need to declare done() properly. &lt;/p&gt;

&lt;p&gt;The rule of thumbs here is to declare expect.assertions(number) at the beginning of your tests. It never causes a problem at all. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. .rejects rather than try-catch
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/docs/expect#rejects"&gt;API - .rejects&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use .rejects to unwrap the reason of a rejected promise so any other matcher can be chained. If the promise is fulfilled the assertion fails.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rejects to octopus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;octopus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))).&lt;/span&gt;&lt;span class="nx"&gt;rejects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;octopus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;VS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/a/51821147"&gt;Stack Overflow&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You must handle errors at the catch block.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;calls the API and throws an error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Unauthorized&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You know the test is supposed to cause an error. The key point of .rejects() is that the assertion fails when the promise is fulfilled. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/docs/asynchronous#asyncawait"&gt;!CAUTION&lt;/a&gt;&lt;br&gt;
Be sure to return (or await) the promise - if you omit the return/await statement, your test will complete before the promise returned from fetchData resolves or rejects. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/docs/tutorial-async#rejects"&gt;!tip&lt;/a&gt;&lt;br&gt;
expect.assertions(number) while using .rejects is not required but recommended to verify that a certain number of assertions are called during a test.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. .toThrow rather than toMatch or toEqual
&lt;/h2&gt;

&lt;p&gt;You can provide an optional argument to test that a specific error is thrown such as regex, string, error object, and error class. However, toMatch and toEqual only do one thing each: to match a string and equal to an object. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://jestjs.io/docs/expect#tothrowerror"&gt;API - .toThrow&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;throws on octopus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;drinkFlavor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;octopus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackoverflow.com/a/46155381"&gt;Stack Overflow&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Test description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UNKNOWN ERROR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UNKNOWN ERROR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://jestjs.io/docs/expect#tothrowerror"&gt;!tip&lt;/a&gt;&lt;br&gt;
You must wrap the code in a function, otherwise the error will not be caught and the assertion will fail.&lt;/p&gt;

&lt;p&gt;!tip&lt;br&gt;
You don't need to wrap a promise function. Just invoke it.&lt;br&gt;
&lt;a href="https://jestjs.io/docs/asynchronous#asyncawait"&gt;Code Example&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;the fetch fails with an error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;rejects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toMatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Use-case 1: Handle Error in a function
&lt;/h2&gt;

&lt;p&gt;Let's integrate what we learned into a simple code snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Test description&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UNKNOWN ERROR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TypeError&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UNKNOWN ERROR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I declared expect.assertions(number) even though the above test is not asynchronous. It doesn't matter since expect.assertions() never causes a problem at all.&lt;/li&gt;
&lt;li&gt;I used .toThrow() rather than .toMatch or .toEqual since it handles Error object and string alike. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  6. Use-case 2: Handle Error in an asynchronous function
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;the fetch fails with an error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;assertions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()).&lt;/span&gt;&lt;span class="nx"&gt;rejects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toThrow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I declared expect.assertions(number) even though it is not required while using .rejects().&lt;/li&gt;
&lt;li&gt;I handled an error, by using .rejects, within a single block, not within a try-catch block. &lt;/li&gt;
&lt;li&gt;I used .toThrow rather than .toMatch or .toEqual. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  7. References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/docs/expect"&gt;Jest API - expect&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/docs/tutorial-async"&gt;Jest Guide - An Async Example&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jestjs.io/docs/asynchronous"&gt;Jest Introduction - Testing Asynchronous Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/46042613/how-to-test-the-type-of-a-thrown-exception-in-jest"&gt;How to test the type of a thrown exception in Jest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/50816254/necessary-to-use-expect-assertions-if-youre-awaiting-any-async-function-calls"&gt;Necessary to use expect.assertions() if you're awaiting any async function calls?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/47144187/can-you-write-async-tests-that-expect-tothrow/47887098#47887098"&gt;Can you write async tests that expect toThrow?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://freecontent.manning.com/writing-good-assertions/"&gt;Writing Good Assertions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jest</category>
      <category>test</category>
      <category>node</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>hint: Updates were rejected because the tip of your current branch is behind</title>
      <dc:creator>DanKim0213</dc:creator>
      <pubDate>Wed, 08 Feb 2023 11:40:30 +0000</pubDate>
      <link>https://dev.to/dankim0213/hint-updates-were-rejected-because-the-tip-of-your-current-branch-is-behind-4a70</link>
      <guid>https://dev.to/dankim0213/hint-updates-were-rejected-because-the-tip-of-your-current-branch-is-behind-4a70</guid>
      <description>&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;p&gt;I prefer rebasing my feature branch onto Master branch before PR (Pull Request). But, sometimes I got this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push origin feature/specific-feature
hint: Updates were rejected because the tip of your current branch is behind

hint: its remote counterpart. Integrate the remote changes (e.g.

hint: 'git pull ...') before pushing again.

hint: See the 'Note about fast-forwards' in 'git push --help' for details.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens when I already pushed Feature branch to Github and thus the sync between my local feature branch and the remote branch in GitHub got broken. To resolve this issue:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push -d origin specific-feature
$ git push origin specific-feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackoverflow.com/a/39400690"&gt;Some developers&lt;/a&gt; recommend using force-push. Though, in my preference, deleting the remote branch is more appropriate since force-push has &lt;a href="https://git-scm.com/docs/git-push#Documentation/git-push.txt---force"&gt;several caveats&lt;/a&gt; and I or my colleagues in some situations would abuse force-push if we are used to force-push. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This flag disables these checks, and can cause the remote repository to lose commits; use it with care.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>git</category>
      <category>troubleshoot</category>
      <category>todayilearned</category>
    </item>
    <item>
      <title>Is GitHub flow better than Git flow?</title>
      <dc:creator>DanKim0213</dc:creator>
      <pubDate>Wed, 08 Feb 2023 11:33:03 +0000</pubDate>
      <link>https://dev.to/dankim0213/is-github-flow-better-than-git-flow-3ckl</link>
      <guid>https://dev.to/dankim0213/is-github-flow-better-than-git-flow-3ckl</guid>
      <description>&lt;h2&gt;
  
  
  Git flow or Github flow?
&lt;/h2&gt;

&lt;p&gt;The world of Git offers several collaboration strategies, including Github Flow, Git Flow, Gitlab Flow, and others. In this post, I'd like to share my thoughts on Github Flow specifically.&lt;/p&gt;

&lt;p&gt;My team and I opted for Git Flow at the outset of our project, after a thorough discussion on which flow to adopt. We were all new to Git at the time, so we relied on &lt;a href="https://techblog.woowahan.com/2553/" rel="noopener noreferrer"&gt;a post&lt;/a&gt; for guidance and diligently followed its advice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's do it: GitHub flow
&lt;/h2&gt;

&lt;p&gt;As I continued to use Git Flow, I became aware of its limitations, particularly its complexity with the use of multiple branches - Master, Develop, Feature, Hotfix, and Release. However, this complexity can be mitigated through the use of Github Flow, which only requires two branches: Master and etc. As &lt;a href="https://scottchacon.com/2011/08/31/github-flow.html" rel="noopener noreferrer"&gt;Scott Chacon&lt;/a&gt; stated, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Anything in the master branch is deployable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Github Flow, first introduced by &lt;a href="https://nvie.com/posts/a-successful-git-branching-model/" rel="noopener noreferrer"&gt;Vincent Driessen&lt;/a&gt;, is a more suitable option for teams practicing &lt;a href="https://www.atlassian.com/continuous-delivery/principles/continuous-integration-vs-delivery-vs-deployment" rel="noopener noreferrer"&gt;continuous delivery&lt;/a&gt;, as it provides a simpler workflow compared to Git Flow. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your team is doing continuous delivery of software, I would suggest to adopt a much simpler workflow (like GitHub flow)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What if we require versioned releases?
&lt;/h2&gt;

&lt;p&gt;As previously mentioned, anything in the Master branch is deployable, but there are times when we need to maintain starting points for significant updates. This is where the &lt;a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging" rel="noopener noreferrer"&gt;Tagging&lt;/a&gt; feature in Git comes in handy. By utilizing the git tag command, we can easily create versioned releases, such as&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;$ git tag&lt;br&gt;
v1.0&lt;br&gt;
v2.0&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Further
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://scottchacon.com/2011/08/31/github-flow.html" rel="noopener noreferrer"&gt;&lt;strong&gt;GitHub flow&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/get-started/quickstart/github-flow" rel="noopener noreferrer"&gt;Get started GitHub flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ujuc.github.io/2015/12/16/git-flow-github-flow-gitlab-flow/" rel="noopener noreferrer"&gt;Git flow, GitHub flow, GitLab flow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>gaming</category>
      <category>gamedev</category>
      <category>esports</category>
      <category>pcgaming</category>
    </item>
    <item>
      <title>How to Set up SSH</title>
      <dc:creator>DanKim0213</dc:creator>
      <pubDate>Fri, 29 Apr 2022 07:22:52 +0000</pubDate>
      <link>https://dev.to/dankim0213/how-to-set-up-ssh-and-use-it-properly-go8</link>
      <guid>https://dev.to/dankim0213/how-to-set-up-ssh-and-use-it-properly-go8</guid>
      <description>&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;What is SSH&lt;/li&gt;
&lt;li&gt;Advantages of ssh-key authentication&lt;/li&gt;
&lt;li&gt;How to generate ssh-key &lt;/li&gt;
&lt;li&gt;How to configure generated ssh keys&lt;/li&gt;
&lt;li&gt;Use-case 1: GitHub&lt;/li&gt;
&lt;li&gt;Use-case 2: Remote server&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. What is SSH
&lt;/h2&gt;

&lt;p&gt;SSH stands for Secure Shell, by which users can manage systems or transfer of files from computer to computer. Users  can access to remote machines by username + password or ssh key. I personally prefer ssh-key authentication to traditional login authentication since you can use ssh-key to authenticate yourself not only on remote computers, but also on GitHub and so on. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Advantages of ssh-key authentication
&lt;/h2&gt;

&lt;p&gt;The use of multiple SSH keys to grant secure server access to multiple individuals affords three advantages over assigning separate user accounts with traditional login credentials.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grants access to multiple parties without sharing passwords.&lt;/li&gt;
&lt;li&gt;Simplifies permission management; all parties log in as the same user and thereby share permissions.&lt;/li&gt;
&lt;li&gt;Allow for easy access revocation as needed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. How to generate ssh-key
&lt;/h2&gt;

&lt;p&gt;There are multiple algorithms to generate ssh-key: RSA, DSA, ECDSA, and EdDSA. Mostly used algorithm is RSA (the default option for ssh-keygen), but EdDSA is newer and provides the highest security level compared to key length.&lt;/p&gt;

&lt;p&gt;simply: &lt;br&gt;
&lt;code&gt;ssh-keygen -t ed25519 -C "john@example.com"&lt;/code&gt;&lt;br&gt;
or more securely:&lt;br&gt;
&lt;code&gt;ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C "john@example.com"&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;-t&lt;/strong&gt; specifies the type of key to create, in our case the Ed25519.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-f&lt;/strong&gt; specifies the filename of the generated key file. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;-C&lt;/strong&gt; specifies a comment.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  4. How to configure generated ssh keys
&lt;/h2&gt;

&lt;p&gt;You need to use ssh-agent, which is a helper program that keeps track of user's identity keys and their passphrases. Make sure ssh-agent is running:&lt;br&gt;
&lt;code&gt;eval "$(ssh-agent -s)"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add a host onto "~/.ssh/config":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host myRemoteServer
  HostName 198.222.111.33
  User john
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, add your SSH key to the agent:&lt;/p&gt;

&lt;p&gt;option1 (Mac user):&lt;br&gt;
If you're using macOS Sierra 10.12.2 or later, you will need to modify your ~/.ssh/config file to automatically load keys into the ssh-agent and store passphrases in your keychain.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ssh-add -K ~/.ssh/id_ed25519&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;option2 (linux user):&lt;br&gt;
And then, add your newly generated Ed25519 key to SSH agent&lt;br&gt;
&lt;code&gt;ssh-add ~/.ssh/id_ed25519&lt;/code&gt; &lt;br&gt;
or add all generated keys to SSH agent&lt;br&gt;
&lt;code&gt;ssh-add&lt;/code&gt;  &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Use-case 1: GitHub
&lt;/h2&gt;

&lt;p&gt;First,&lt;br&gt;
&lt;code&gt;pbcopy &amp;lt; ~/.ssh/id_ed25519.pub&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Click my profile image -&amp;gt; Settings -&amp;gt; In the "Access" section of the sidebar, click  SSH and GPG keys -&amp;gt; Click New SSH key or Add SSH key -&amp;gt; paste the copied key into "Key" field.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Use-case 2: Remote server
&lt;/h2&gt;

&lt;p&gt;First of all, copy the public key to the remote server:&lt;br&gt;
&lt;code&gt;ssh-copy-id -i ~/.ssh/id_ed25519.pub john@198.222.111.33&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then:&lt;br&gt;
&lt;code&gt;ssh john@198.222.111.33&lt;/code&gt;&lt;br&gt;
or:&lt;br&gt;
&lt;code&gt;ssh myRemoteServer&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent"&gt;Generate a new ssh key and adding it to the ssh-agent&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account"&gt;Add a new ssh-key to your GitHub account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.techtarget.com/searchsecurity/definition/Secure-Shell"&gt;Secure Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxize.com/post/how-to-create-users-in-linux-using-the-useradd-command/"&gt;How to create users in linux using user add command&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/risan/upgrade-your-ssh-key-to-ed25519-c6e8d60d3c54"&gt;Upgrade your ssh key to ed25519&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxize.com/post/using-the-ssh-config-file/"&gt;Using the ssh config file&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ssh.com/academy/ssh/copy-id"&gt;ssh-copy-id&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>tutorial</category>
      <category>ssh</category>
    </item>
    <item>
      <title>How to use Git at Work</title>
      <dc:creator>DanKim0213</dc:creator>
      <pubDate>Mon, 25 Apr 2022 04:17:27 +0000</pubDate>
      <link>https://dev.to/dankim0213/how-to-use-git-at-work-2mko</link>
      <guid>https://dev.to/dankim0213/how-to-use-git-at-work-2mko</guid>
      <description>&lt;h2&gt;
  
  
  Agenda
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;General Concept &lt;/li&gt;
&lt;li&gt;Caveats&lt;/li&gt;
&lt;li&gt;how to clone&lt;/li&gt;
&lt;li&gt;how to branch&lt;/li&gt;
&lt;li&gt;how to commit&lt;/li&gt;
&lt;li&gt;how to update&lt;/li&gt;
&lt;li&gt;how to maintain&lt;/li&gt;
&lt;li&gt;Last Words&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. General Concept
&lt;/h2&gt;

&lt;p&gt;Basically, you'll get two branches at work: master and develop. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;master&lt;/strong&gt; branch is designed for production. The maintainers of your team project handle this branch to publish. &lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;develop&lt;/strong&gt; branch is designed for development. The developers of your team project stretch their own branches per feature and then merge the feature branches to the develop branch. The feature branches, of course, must be tested in advance of merging to the develop branch. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Caveats
&lt;/h2&gt;

&lt;p&gt;You need to know the difference between "origin develop", "origin/develop", and "develop". &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"origin develop" is a remote branch on sites such as GitHub, gitlab, etc. Thus, we use like:
&lt;code&gt;git fetch origin develop&lt;/code&gt;
&lt;code&gt;git push origin develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;On the other hand, "origin/develop" is a downloaded branch from a remote server such as gitHub, gitlab, etc. This means a downloaded branch could be out of date so that you must update the downloaded branch regularly. i.e. whenever you start coding in the morning or pushing your codes. Thus, we use like: 
&lt;code&gt;git merge origin/develop&lt;/code&gt;
&lt;code&gt;git rebase origin/develop&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;"develop" is a local branch you can modify. Thus, we use like:
&lt;code&gt;git checkout develop&lt;/code&gt;
&lt;code&gt;git diff develop your-new-feature&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. How to clone
&lt;/h2&gt;

&lt;p&gt;Before you start developing, you need to clone your team project so that your teammates can work with the same project maintained by the same git. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/&amp;lt;username&amp;gt;/&amp;lt;project.git&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and then, go to the develop branch:&lt;br&gt;
&lt;code&gt;git checkout develop&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. How to branch
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;git checkout -b your-new-feature&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  5. How to commit
&lt;/h2&gt;

&lt;p&gt;Let's add all changed files except for declared files in .gitignore. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git status&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git commit -m "message here."&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. How to update
&lt;/h2&gt;

&lt;p&gt;You need to update your downloaded branch before pushing your changes. &lt;br&gt;
&lt;code&gt;git fetch&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git rebase origin/develop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;And then, go to the develop branch, update your local develop branch ,and push your changes to the remote git repository. &lt;br&gt;
&lt;code&gt;git checkout develop&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git merge origin/develop&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git merge your-new-feature --no-ff&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git push origin develop&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. How to maintain
&lt;/h2&gt;

&lt;p&gt;You can track git commits: &lt;br&gt;
&lt;code&gt;git log --all --oneline --graph&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Or, you can track git commits of a specific file:&lt;br&gt;
&lt;code&gt;git log -p ./path/to/file&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can figure out what changes to be committed:&lt;br&gt;
&lt;code&gt;git status&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can figure out differences by two options:&lt;br&gt;
&lt;code&gt;git diff&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git diff --staged&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Last words
&lt;/h2&gt;

&lt;p&gt;This post could be a very unkind one since I skipped describing all details of git commands but focused on how to use git commands in a chronological order. However, by doing so, you can figure out the whole picture of how to use git at work. &lt;/p&gt;

&lt;p&gt;I will appreciate that all comments point out something wrong on my post :) Thanks.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/a/18137512"&gt;In Git, what is the difference between origin/master vs origin master?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge/804156#804156"&gt;When do you use Git rebase instead of Git merge?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nvie.com/posts/a-successful-git-branching-model/"&gt;git flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.github.com/en/get-started/quickstart/github-flow"&gt;github flow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/2003505/how-do-i-delete-a-git-branch-locally-and-remotely"&gt;How do I delete a git branch locally and remotely?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>git</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
