<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>log</title>
        <link>https://velog.io/</link>
        <description></description>
        <lastBuildDate>Sat, 09 Apr 2022 12:02:24 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>log</title>
            <url>https://images.velog.io/images/www_1216/profile/e2fd71c6-8bf4-496f-9256-5f088af3bd24/Identicons2.png</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/www_1216" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[github issue로 이미지 첨부하기]]></title>
            <link>https://velog.io/@www_1216/github-issue%EB%A1%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%A8%EB%B6%80%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@www_1216/github-issue%EB%A1%9C-%EC%9D%B4%EB%AF%B8%EC%A7%80-%EC%B2%A8%EB%B6%80%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 09 Apr 2022 12:02:24 GMT</pubDate>
            <description><![CDATA[<h2 id="마크다운에서는-이미지를-이렇게-첨부합니다">마크다운에서는 이미지를 이렇게 첨부합니다.</h2>
<pre><code>### 형식
![이미지이름](이미지주소)

### 예시
![likelion logo](https://oopy.lazyrockets.com/api/v2/notion/image?src=https%3A%2F%2Fs3-us-west-2.amazonaws.com%2Fsecure.notion-static.com%2F76e97239-2fe2-4afd-90e5-e8b2b878cfe7%2FUntitled.png&amp;blockId=dfd76b38-4ff0-4b64-9231-475d1b0f57ea)</code></pre><ul>
<li><p>❓이미지 주소는 어떻게 가져오나요?
  우클릭해서 이미지를 저장하는게 아니라 이미지 <code>주소</code> 를 복사해오면 됩니다.</p>
<img alt="이미지 주소 복사하기" src="https://user-images.githubusercontent.com/60145951/162572691-29023892-8d5c-48b4-a5de-c36c2e28aad7.png"/>

</details>


</li>
</ul>
<h2 id="원래는">원래는,</h2>
<blockquote>
<p>github의 markdown에 이미지를 첨부하려면 동일 repo의 이미지 주소를 추가해야 했습니다.</p>
</blockquote>
<p>이게 무슨말이냐, 만약 내가 마크다운에 이미지를 추가하고 싶다면</p>
<details>
  <summary> 1. 레포에 다운로드 받은 이미지를 add, commit, push 합니다. </summary>
  <img alt="repo에 이미지 올리기" src="https://user-images.githubusercontent.com/60145951/162572812-151e9c84-0cbb-4fc0-a40f-6891bad2079b.png"/>

</details>

<details>
  <summary> 2. 레포에 내가 올린 이미지의 링크를 복사합니다.</summary>
  <img alt="repo에 올린 이미지 링크 복사하기" src="https://user-images.githubusercontent.com/60145951/162572880-a0833b67-20f7-4bc4-befc-f4771ae8adb2.png"/>
</details>

<details>
  <summary> 3. 마크다운 문법에 맞춰 <a>![image](이미지주소)</a> 로 이미지를 올립니다.</summary>
  github repo에서 가져온 주소이므로 이미지 주소는 다음과 같을 것입니다.
  <a> https://github.com/<userid>/<repository name>/blob/<branch name>/image </a> <br>
    하단의 예시는 마크다운이 아니라 html 예시지만 비슷한 방식으로 이미지를 추가한다고 알면 됩니다.

  <img alt="이미지 사용하기" src="https://user-images.githubusercontent.com/60145951/162572958-c2a83a02-bb78-4a86-b948-2cff6df798f4.png"/>
</details>


<h2 id="그런데-이렇게-매번-이미지를-올리는건-너무-번거롭습니다">그런데 이렇게 매번 이미지를 올리는건 너무 번거롭습니다.</h2>
<p>일단 이미지도 다운로드 받아야하고 이미지 이름도 정해줘야하고 이미지 올리려면 일단 이미지부터 add commit push 해야하고 여간 성가신게 아닙니다.</p>
<h2 id="이럴-때-쓰는-방법-github-issue">이럴 때 쓰는 방법: github issue</h2>
<blockquote>
<p>💡 issue 에 이미지를 붙여넣기 하거나 드래그 드롭하고, 거기에 생성된 이미지 링크를 사용합니다.</p>
</blockquote>
<ol>
<li><p><code>new issue</code> 를 만듭니다. 이슈 발행하지 않아도 되니까 일단 안심하고 만듭시다.
<img src="https://user-images.githubusercontent.com/60145951/162573073-e0fdcb27-06f5-4cf4-bf92-610b2426eea6.png" alt="image">  </p>
</li>
<li><p>issue를 만들었을때 보이는 화면은 이렇습니다. 체크표시 한 본문에 이미지를 붙여넣기합니다.</p>
<ol>
<li>이슈를 만들었을때 보이는 화면
 <img src="https://user-images.githubusercontent.com/60145951/162573097-b968e8f2-e137-4532-adf0-f7a881c84105.png" alt="image"></li>
<li>이미지 주소를 만드는 방법</li>
</ol>
<ul>
<li>클립보드를 이용한 복사 붙여넣기도도 괜찮고 다운로드 받은 이미지를 드래그드롭해도 괜찮습니다.</li>
<li>내가 마크다운에 넣고 싶은 이미지 예시: 스크린샷<pre><code> ![image](https://user-images.githubusercontent.com/60145951/162573135-dbd5d482-5d1f-483a-981d-46ad9c1dc919.png)</code></pre></li>
<li>붙여넣은 후의 이슈 본문: src 이후의 링크만 복사합니다.            <img src="https://user-images.githubusercontent.com/60145951/162573156-5516ebd3-92ac-4e3c-9d2e-030284e314c7.png" alt="image"></li>
</ul>
</li>
<li><p>생성된 issue에서의 이미지 링크만 복사해서 마크다운에 입력합니다.</p>
<pre><code class="language-html"> &lt;img width=&quot;863&quot; alt=&quot;image&quot; src=&quot;https://user-images.githubusercontent.com/60145951/162572357-a22b3d6f-9100-4dd5-8e68-4a2267de1e49.png&quot;&gt;</code></pre>
<p> 새 마크다운</p>
<pre><code class="language-markdown"> ![스크린샷](https://user-images.githubusercontent.com/60145951/162572357-a22b3d6f-9100-4dd5-8e68-4a2267de1e49.png)</code></pre>
</li>
</ol>
<blockquote>
<p>이제 마크다운을 편집할만큼 편집하고 add commit push 하면 이미지가 포함된 마크다운이 올라간다. 노션처럼 편하게 쓸 수 있습니다!</p>
</blockquote>
<h3 id="왜-이렇게-되나요">왜 이렇게 되나요?</h3>
<ul>
<li>왜 이렇게 되나요❓ : 이슈에 이미지를 올리면 바로 github 서버에 이미지가 업로드 되기 때문에 이미지의 고유 링크가 생성된다. 우리는 github 서버를 사용하는 셈입니다.</li>
<li>이슈를 발행하지 않아도 되나요❓ : 이미지를 이슈 본문에 붙여넣기 하는 순간 이미지 고유 링크가 생성되는 것이기 때문에 굳이 이슈를 발행하지 않아도 됩니다!</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[함수의 soft한 버전이란 무엇인가]]></title>
            <link>https://velog.io/@www_1216/%ED%95%A8%EC%88%98%EC%9D%98-soft%ED%95%9C-%EB%B2%84%EC%A0%84%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@www_1216/%ED%95%A8%EC%88%98%EC%9D%98-soft%ED%95%9C-%EB%B2%84%EC%A0%84%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Fri, 06 Aug 2021 07:19:33 GMT</pubDate>
            <description><![CDATA[<p>프로그래밍인사이트 출판사의 <code>머신러닝, 딥러닝에 필요한 기초수학 with 파이썬</code>을 읽다가 아래 문구를 봤다.</p>
<blockquote>
<p>softmax 함수는 max 함수의 soft한 버전인 것 같다. 그러나 max 함수의 soft한 버전은 softplus 이며 softmax 함수는 argmax 함수의 soft한 버전이며 관행적으로 arg를 생략하여 softmax 함수가 된 것이다. (p72)</p>
</blockquote>
<p>max 함수, softplus 함수, argmax 함수가 도대체 무엇이냐 이전에 궁금한 점이 있다.<br>함수의 soft한 버전은 도대체 뭘까</p>
<h2 id="functiona-called-soft--differentiable-function">functiona called &#39;soft&#39; : differentiable function</h2>
<p>한국어로 검색해도 잘 나오지 않는다. 일단 뭐라고 검색해야 할 지도 모르겠다. 일단 영문 위키에서 <a href="https://en.wikipedia.org/wiki/Rectifier_(neural_networks)">rectifier</a> 를 검색해보라고 해서 검색해봤다.</p>
<ul>
<li>rectifier : 정류기</li>
<li>아니 놀라운 사실을 알았다. ReLU가 Rectified Linear Unit의 약자였다.</li>
<li>아니? 더 놀라운 사실을 알았다. max 함수가 뭔가 했는데 ReLU였다! ($f(x) = max(0, x)$)</li>
</ul>
<br>
<center>
<img src="https://cdn-images-1.medium.com/max/800/1*w275Sin5bKAIaWBaJ6zXcA.png" width=400>
<br>
<i>이 그래프를 보길 원한 것 같다.</i>
</center>
<br>

<p>책이 출간된 이후로 업데이트가 이루어졌는지 위키피디아에 올라온 그래프는 ReLU와 GELU였다. 그래프 형태를 봐서는 조금 더 완화된 개형을 가진 함수들을 soft함수라고 부르는 것 같은데 맞는지 확인하는 작업을 거쳤다.<br>결론부터 말하자면 soft한 함수, 부드러운 함수는 미분이 가능하도록 변형한 함수다. ReLU함수와 argmax 함수의 공통점을 생각해보면 답이 나온다. 두 함수 모두 미분이 불가능한 함수다. (ReLU는 첨점, argmax는 큰 값의 인덱스를 반환한다는 함수특성)<br>딥러닝에서 미분이 불가능하다는 특성은 치명적인데 역전파 backpropagation 가 불가능해 가중치를 업데이트 할 수 없으므로 학습읋 할 수 없기 때문이다.<br>따라서 이를 미분 가능하게 완화한 함수를 사용하게 된다. 이 함수를 soft 함수라고 부른다.</p>
<h3 id="참고">참고</h3>
<p><a href="https://brunch.co.kr/@kdh7575070/27">Dying ReLU</a></p>
<h3 id="github-til"><a href="https://github.com/4923/TIL/blob/master/AI/mathematical_AI/soft_function.md">Github TIL</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[issue를 써보자]]></title>
            <link>https://velog.io/@www_1216/issue%EB%A5%BC-%EC%8D%A8%EB%B3%B4%EC%9E%90</link>
            <guid>https://velog.io/@www_1216/issue%EB%A5%BC-%EC%8D%A8%EB%B3%B4%EC%9E%90</guid>
            <pubDate>Fri, 06 Aug 2021 07:17:02 GMT</pubDate>
            <description><![CDATA[<blockquote>
<p>Activity overview : Commits 100% 에서 벗어나기 프로젝트</p>
</blockquote>
<p>일반적으로 github project에서 issue는 아래 단계를 따른다.</p>
<pre><code>  1. 문제상황 발생
  2. issue 발급 : create issue
  3. issue 해결 : 작업 후 PR, code review
  4. issue 반영 : merge</code></pre><h3 id="갑자기-웬-issue">갑자기 웬 issue?</h3>
<p>이 기능은 협업 과정에서 주로 사용한다고 알고 있는데 Django Project를 진행할 때마다 문제상황을 commit message에 기록하는것도 한계가 있고 무엇보다 문제가 발견됐을 때 마다 그 자리에서 해결하는게 슬슬 어려워지다 보니 이런 문제/issue들을 모아두고 관리할 수 있는 기능의 필요성을 느끼게 되었다.</p>
<h3 id="template을-만들어보자">template을 만들어보자</h3>
<p>프로젝트 관리를 위한 기능이니 여러사람이 사용해야 하고, 그렇게 되면 당연히 정해진 형식이 필요하다. 이걸 위한 기능이 template이다.
repository settings/Features/Issues에서 관리할 수 있으며 기본적으로 Bug report와 Feature request template을 제공하며 사용자가 형식을 정의 할 수도 있다.</p>
<ul>
<li>template 작성도 커밋으로 집계된다.</li>
<li>한 번에 여러 template을 생성하고 수정할 수 있는데 반드시! Propose changes를 눌러야 한다. 하지 않으면 애써 작성한 형식이 다 날아간다. (ㅠㅠ)</li>
</ul>
<h3 id="issue를-만들어보자">issue를 만들어보자</h3>
<p>issue는 repository의 issue탭에서 만들 수 있다.
repository에서 issue를 사용하지 않게 만들 수도 있는데 내가 알기론 별도의 설정 없이 저장소를 열 때 issue도 기본적으로 열린다.
상단 바의 issue탭으로 들어가서 New issue를 클릭하면 새로운 issue를 발급할 수 있다.</p>
<p>이 때 template을 작성해두었다면 골라서 issue를 생성할 수 있다.</p>
<p>제목과 본문 말고도 책임자(Assignees), 분류(Labels), 관련 Project(Projects), 세부분류? (Milestone) 등을 지정할 수 있다.</p>
<p>이것도 template에서 미리 지정할 수 있는데, 지정해두었다면 issue 생성과 동시에 기본값이 설정된다. 편리하다!</p>
<h3 id="issue를-해결하자--닫기">issue를 해결하자 : 닫기</h3>
<p>문제를 해결하면 된다. 한 issue 안에서 comments를 달 수도, emoji를 남길수도 있다.
issue 안에서 일어나는 모든 변화는 (label 변경 등) commit 처럼 내부에 기록된다.
(그리고 본문에서 : 콜론을 쓰면 바로 이모티콘을 쓸 수 있어 편하다.)</p>
<p>문제를 해결했다면 issue를 닫아야 하는데 웹에서 그냥 닫을 수는 없고 comment와 함께 닫아야 하는 것 같다.</p>
<p>comment 할 것이 없다면 commit message로 닫을 수도 있다. commit할 때 종료를 의미하는 키워드를 입력하고, issue 번호를 기입했다면 자동으로 issue를 종료한다.</p>
<p>종료 키워드 : close, fix, resolve
각 단어의 변형 (closed, fixes ...) 또한 인식한다.</p>
<h3 id="github-til"><a href="https://github.com/4923/TIL/blob/master/Git/github/issue/my_first_issue.md">Github TIL</a></h3>
]]></description>
        </item>
        <item>
            <title><![CDATA[깃허브도, 스택오버플로우도 터졌다. CDN이 뭐길래?]]></title>
            <link>https://velog.io/@www_1216/%EA%B9%83%ED%97%88%EB%B8%8C%EB%8F%84-%EC%8A%A4%ED%83%9D%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0%EB%8F%84-%ED%84%B0%EC%A1%8C%EB%8B%A4.-CDN%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98</link>
            <guid>https://velog.io/@www_1216/%EA%B9%83%ED%97%88%EB%B8%8C%EB%8F%84-%EC%8A%A4%ED%83%9D%EC%98%A4%EB%B2%84%ED%94%8C%EB%A1%9C%EC%9A%B0%EB%8F%84-%ED%84%B0%EC%A1%8C%EB%8B%A4.-CDN%EC%9D%B4-%EB%AD%90%EA%B8%B8%EB%9E%98</guid>
            <pubDate>Tue, 08 Jun 2021 13:18:39 GMT</pubDate>
            <description><![CDATA[<h1 id="fastly-global-cdn-disruption">Fastly Global CDN Disruption</h1>
<h3 id="0-해외-주요-서비스-접속-불가-문제-발생">0. 해외 주요 서비스 접속 불가 문제 발생</h3>
<blockquote>
<p>Error 503 Service Unavailable<br>Details : cache-itm 18821-ITM ~  
Vanish cache server<br><em>error: CNN</em></p>
</blockquote>
<blockquote>
<p>Fastly error: unknown domain: <a href="http://www.nytimes.com">www.nytimes.com</a>.  
Details: cache-itm18840-ITM<br><em>error: NYT</em></p>
</blockquote>
<blockquote>
<p>connection failure<br><em>error: Guardian</em></p>
</blockquote>
<p>21.06.08 화요일 7시 전후로 Github, Stackoverflow, Amazon, Twitch, 주요 외신 페이지 ... 등의 서비스가 터지는 문제가 발생했다. github는 html 이라도 보였는데 다른 서비스는 아예 접근 자체가 불가능했다. 그러고보니 Stackoverflow나 Github가 터진것만 확인해서 몰랐는데 이제보니 뉴욕타임즈 터졌을 때 Fastly error라고 적혀있었다.  </p>
<p>아무튼 에러메시지만 종합해보면 </p>
<ul>
<li>서버가 다운됐고</li>
<li>주된 문제는 캐시고</li>
<li>도메인 에러도 발생한 것 같다</li>
</ul>
<h3 id="1-뭐가-문제인가">1. 뭐가 문제인가</h3>
<p>사실 터진 서비스중에 Amazon이 보여서 AWS 문제인지 단순하게 의심했는데 그렇다기엔 AWS를 쓸 것 같지 않은 서비스도 터졌고 이모티콘 출력에만 문제가 생긴다거나 github도 action 기능은 된다고 하고 이것저것 의아한 점이 많았다. 배포서버에 문제가 생긴거면 아예 전부 먹통이 되어야 하는게 아닌가...<br>그러다 Fastly Incident Report를 발견했는데 CDN은 들어나 봤지 뭔지 정확히 확인해본 적이 없어서 서버 복구되기를 기다리면서 관련 정보를 찾아봤다.  </p>
<ul>
<li><a href="https://status.fastly.com/incidents/vpk0ssybt3bj">Incident Report</a></li>
</ul>
<p>Fastly측 Report에 따르면 해당 문제는 태평양시 09:58에 보고되어 5~10분 간격으로 상황이 갱신되다가 한시간가량 지난 10:44에 문제를 발견했다. 10:57에 모니터링을 시작해서 12:41에 Resolve 처리 되었으니 최소 한 시간동안은 장애가 발생했다고 보면 되겠다. 모르긴 몰라도 배상금이 엄청날것 같다. </p>
<h3 id="2-fastly-cdn">2. Fastly? CDN?</h3>
<blockquote>
<p>Fastly describes their network as an edge cloud platform, which is designed to help developers extend their core cloud infrastructure to the edge of the network, closer to users.<br>The Fastly edge cloud platform includes their <code>content delivery network</code>, image optimization, video and streaming, cloud security, and load balancing services. <a href="https://en.wikipedia.org/wiki/Fastly">wiki</a></p>
</blockquote>
<p>우선 Fastly는 미국의 클라우드 컴퓨팅 서비스 제공 업체로 개발자가 조금 더 사용자에게 가깝게 서비스할 수 있도록 돕는 것을 주 목표로 한다. <code>CDN</code>, image optimization, video &amp; streaming, cloud security, load balancing service 등을 제공하며 나열된 기술들은 모두 조금 더 빠르고, 불편함 없이 사용자가 서비스를 이용할 수 있게 한다.  </p>
<p><strong>CDN</strong><br>서버를 사용하는 사람이 많아지면 모든 요청이 메인 서버컴퓨터로 몰리기 때문에 병목현상 또는 접속장애가 발생한다. 게임 업데이트마다 서버가 터지는 이유도 아마 같은 문제인 것 같다.</p>
<p>(1)<br>우선, 서버컴퓨터가 사용자의 요청에 반응하기 어려운 상황이 무엇일까? </p>
<ol>
<li>요청이 지나치게 많다. 작업이 많아 속도가 느려진다.  </li>
<li>거리가 멀다. 아무리 전송 속도가 빠르다고 해도, 대륙을 건너는덴 시간이 소요될 수 밖에 없다. 이래서 내가 글로벌서버에서 게임을 못한다.  </li>
</ol>
<p>그렇다면 이 문제를 해결할 방법은 무엇일까. </p>
<ol>
<li>요청을 분산한다. 장사가 잘 되는 식당에서 직원(서버)를 많이 사용하는덴 이유가 있다.</li>
<li>세계 곳곳에 서버 컴퓨터를 설치한다.</li>
</ol>
<p>이게 CDN(Content Delivery Network) 이다. 서버의 부담을 줄이고 로딩하는데 오래 걸리는 콘텐츠들을 전송하기 위해 사용하는 <strong>분산 네트워크</strong>라고 정리할 수 있겠다. </p>
<p>(2)<br>웹 서핑을 하다보면 [사진 많음, 데이터 주의] 등의 머릿말을 단 게시글을 볼 수 있다. 사진이나 동영상이 데이터를 많이 잡아먹는다는건 누구나 아는 사실이다. 그러니 그 정보를 요청하는데도 시간이 오래 걸릴 수 밖에 없다.<br>따라서 사용자가 이미지, 동영상 등을 요청하면 전 세계에 있는 CDN은 사용자와 가장 가까운 POP(Point of Presence)의 서버에 저장/캐시된 정보를 전송한다. </p>
<ol>
<li>이 때 서비스가 CDN을 사용한다면 사용자는 특수한 도메인(DNS)에 파일을 요청하게 된다.</li>
<li>이 DNS는 가장 가까운 POP에 정보를 요청한다.  <ul>
<li>이 때 가까운 POP의 서버(edge server)에 적당한 정보가 없다면 에지 서버는 메인 서버에 파일을 요청하고 파일을 캐싱한다. </li>
<li>최초 요청시에는 시간이 다소 소요된다.</li>
</ul>
</li>
<li>캐싱된 정보는 HTTP 헤더에 지정된 TTL(Time To Live)가 만료될 때 까지 정보를 저장한다. (기본 7일)</li>
</ol>
<p>결과적으로, 사용자는 가장 가까운 POP의 서버로부터 정보를 받으므로 빠르고 편리하게 서비스를 이용할 수 있다.</p>
<p>여기까지 알게 되니 이 사태의 특수성이 이해가 된다. 도메인, 이모티콘과 사진 로드, 동영상 전송등에 문제가 생겼으니 이건 Fastly가 제공하는 서비스 중에서도 CDN 문제다.  </p>
<h3 id="3-생각">3. 생각</h3>
<p>우리가 유용하게 사용하는 서비스들이 한 순간, 한 회사의 문제로 이렇게 먹통이 될 수 있다는걸 목격하고 나니 괜히 허망해졌다. 구조상 어쩔 수 없고 이런 방식 덕분에 우리가 더 편하게 서비스를 사용할 수 있단걸 알고 있음에도 그랬다.<br>이전에도 서버가 터지는건 목격했지만 (게임할땐 특히 많이 봤지만,) 아예 맛이 가면 갔지 이렇게 애매하게 서비스가 다운되는 일은 본 적이 없어서 이것저것 찾아보다보니 TIL까지 쓰게 되었다.<br>멋사에 지원할 때에 적었던 지원서에 좋게 느꼈던 서비스가 왜, 구체적으로 어떤 것 때문에 좋았고 불편하게 느꼈던 서비스는 왜 또 불편하다고 생각했는지 알고싶다고 적은 기억이 난다. 오늘도 마찬가지다. 뭔가 잘못되었다는건 알겠는데, 뭐가 문제인지 알지 못하니 답답하기만 했다. 하릴없이 서버만 외치며 속을 끓이기보단, 화를 내더라도 구체적으로 화를 낼 수 있으면 좋겠다는 생각을 했다.<br>공부는 세상을 보는 해상도를 높이는 일이라고 하더라. Fastly 담당자는 지옥 비슷한걸 맛봤을테지만, 오늘 이 사건을 계기로 서버나 네트워크에 대해 조금 더 알 수 있게 되어 즐거웠다. 개발단계에서 뭘 건드리면 이 사태가 벌어지는지도 궁금하지만 그건... 회사에서 일하다보면 알게 되지 않을까?<br>그리고 클하에서 들어보니 PyPI도 Fastly를 통해 배포되고 있어서 여러 곳에서 이슈 리포트가 되고 있다는것 같다. 한밤 중의 개발자 파이팅.</p>
<p>그리고 레딧도 터졌는데 velog에 영문철자를 작성하면 자동으로 비공개로 전환된다. 광고로 분류돼서 그런가?</p>
<h3 id="참고">참고</h3>
<ul>
<li><a href="https://news.imaeil.com/CultureAll/2021060819193663226">매일신문/&quot;패스틀리 탓?&quot; CNN·백악관·아마존 등 세계 주요 홈페이지 &#39;먹통&#39; (종합)</a></li>
<li><a href="https://docs.microsoft.com/ko-kr/azure/cdn/cdn-overview">MS/Azure의 콘텐츠 배달 네트워크란?</a></li>
<li><a href="https://www.akamai.com/kr/ko/cdn/what-is-a-cdn.jsp">Akamai/CDN이란 무엇입니까?</a></li>
</ul>
<p><a href="https://github.com/4923/TIL/blob/master/Web/Server/Fastly_CDN_disruption.md">@4923/TIL</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Python : Class란?]]></title>
            <link>https://velog.io/@www_1216/Python-Class</link>
            <guid>https://velog.io/@www_1216/Python-Class</guid>
            <pubDate>Wed, 10 Mar 2021 12:46:16 GMT</pubDate>
            <description><![CDATA[<p>CPP를 얼레벌레 하고 넘어가서 OPP에 대한 개념이 모호하게 잡혀있었다.
클래스와 객체, 인스턴스, 메소드와 생성자, 소멸자의 개념을 정리했다.
예시는 프로그래머스의 파이썬 입문 강좌를 참고했다.</p>
<hr>
<h2 id="contents">Contents</h2>
<ol>
<li><a href="#%ED%81%B4%EB%9E%98%EC%8A%A4%EB%8A%94-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%9C%EA%B0%80?">클래스의 필요성</a></li>
<li><a href="#%EB%AC%B8%EB%B2%95">문법</a></li>
<li><a href="#%EC%9A%A9%EC%96%B4">용어</a><ul>
<li><a href="#1-%EA%B0%9D%EC%B2%B4%EB%9E%80?">1. 객체란?</a><ol>
<li>객체와 인스턴스의 차이</li>
<li>클래스와 인스턴스의 관계</li>
</ol>
</li>
<li><a href="#2-%EB%A9%94%EC%86%8C%EB%93%9C%EB%9E%80?">2. 메소드란?</a><ol>
<li><code>self</code></li>
</ol>
</li>
<li><a href="#3-%ED%8A%B9%EC%88%98%ED%95%9C-%EB%A9%94%EC%86%8C%EB%93%9C">3. 특수한 메소드</a><ol>
<li><code>__new__(cls)</code></li>
<li><code>__init__(self)</code></li>
<li><code>__str__(self)</code></li>
</ol>
</li>
<li><a href="#4-%EB%A9%A4%EB%B2%84%EB%B3%80%EC%88%98">4. 멤버변수</a></li>
<li><a href="#5-%EC%83%9D%EC%84%B1%EC%9E%90%EC%99%80-%EC%86%8C%EB%A9%B8%EC%9E%90">5. 생성자와 소멸자</a><ol>
<li>생성자</li>
<li>소멸자</li>
</ol>
</li>
<li><a href="#6-%EC%83%81%EC%86%8D%EA%B3%BC-%EC%98%A4%EB%B2%84%EB%9D%BC%EC%9D%B4%EB%93%9C">6. 상속과 오버라이드</a><ol>
<li>상속</li>
<li>오버라이드</li>
<li><code>super()</code></li>
</ol>
</li>
</ul>
</li>
</ol>
<hr>
<h2 id="클래스는-왜-필요한가">클래스는 왜 필요한가?</h2>
<p>여러대의 계산기로 계산을 수행한다고 할 때, 계산기 함수를 여러개를 만들 수도 있지만 클래스를 사용 할 수도 있다.<br>
클래스를 사용하면 함수 여러개를 사용 했을 때와 동일한 효과를 볼 수 있기 때문이다</p>
<h2 id="문법">문법</h2>
<ul>
<li>클래스와 인스턴스를 이용하면 데이터와 코드를 사람이 이해하기 쉽게 포장할 수 있다.</li>
<li>생성된 클래스는 함수 처럼 <code>()</code>를 붙여 호출할 수 있다. <code>Class()</code></li>
<li>클래스의 사용 예<pre><code class="language-py">class Human():
  &#39;&#39;&#39;인간&#39;&#39;&#39;
</code></pre>
</li>
</ul>
<p>person1 = Human()  # 인스턴스 생성
person2 = Human()  # 인스턴스 생성</p>
<h1 id="인스턴스를-클래스처럼-사용할-수-있다">인스턴스를 클래스처럼 사용할 수 있다.</h1>
<p>person1.language = &#39;한국어&#39;
person2.language = &#39;English&#39;</p>
<p>person1.person = &#39;한국인&#39;
person2.person = &#39;인도인&#39;</p>
<h1 id="함수-선언">함수 선언</h1>
<p>def speak():
    print(f&#39;{person.person}은 {person.language}를 사용합니다.&#39;)</p>
<h1 id="함수를-클래스에-적용--메소드-x---메소드-사용방법은-하단-참조">함수를 클래스에 적용 : 메소드 X -&gt; 메소드 사용방법은 하단 참조</h1>
<p>Human.speak = speak()</p>
<h1 id="사용">사용</h1>
<h1 id="아래-두-출력값은-같은-형식으로-출력된다">아래 두 출력값은 같은 형식으로 출력된다.</h1>
<p>speak(person1)  # 한국인은 한국어를 사용합니다.
person2.speak  # 인도인은 English를 사용합니다.</p>
<pre><code>
## 용어
### 1 객체란?
클래스로 만들어진 별개의 프로그램을 객체 object 라고 하는데, 이 객체는 다른 객체의 값에 영향을 받지 않는다.&lt;br&gt;
다시 말해, 객체는 각각 **고유한 성격**을 가진다. &lt;br&gt;
과자를 여러 개 만들 때, 과자 틀을 클래스에 비유한다면 과자 틀로 만들어진 각각의 과자는 객체라고 할 수 있을 것이다.&lt;br&gt;

```py
# class
class Cookie:
    pass

# object
# 클래스의 결과값을 돌려받은 a와 b가 객체다.
a = Cookie()
b = Cookie()</code></pre><ol>
<li><p>객체와 인스턴스는 어떻게 다른가?</p>
<blockquote>
<p>객체는 개념이고 인스턴스는 실체다.</p>
</blockquote>
<p> 클래스로 만든 객체를 인스턴스라고도 한다. OOP (Object Oriented Programming, 객체 지향 프로그래밍) 에서 객체와 인스턴스는 혼용이 가능하나 <strong>인스턴스는 클래스와 함께 사용되는것이 자연스럽다.</strong><br></p>
<p> <strong>객체는 클래스의 인스턴스이므로 실체에 가까운 개념은 인스턴스다.</strong> 예를들어, MMORPG 게임에서 <em>던전<em>이라는 *</em>클래스<strong>가 있다면 **객체</strong>는 모든 플레이어가 플레이하는 <em>A라는 이름의 던전</em>이고 <strong>인스턴스</strong>는 플레이어인 *내가 직접 플레이하는 던전 A의 복제</em> (통칭 인던, 인스턴스 던전) 이다.<br></p>
<ul>
<li>인스턴스 여부를 확인하는 방법 : <code>isinstance(instance, type)</code><br><ul>
<li>instance: 검사하고자 하는 인스턴스</li>
<li>type: 확인하고자 하는 클래스 또는 데이터 타입</li>
</ul>
</li>
</ul>
</li>
<li><p>클래스와 인스턴스는 어떤 관계인가?</p>
<blockquote>
<p>너와 나는 모두 인간 클래스의 인스턴스이지만 같은 인스턴스는 아니다.</p>
</blockquote>
<pre><code class="language-py"># 예시
list1 = list(&quot;instance&quot;)
list2 = list(&quot;instance&quot;)
</code></pre>
</li>
</ol>
<p>if list1 == list2:  # == 는 값을 비교하는 연산자다.
    print(&#39;list1과 list2의 값은 같지만&#39;))
    if list1 is list2:  # is 는 같은 인스턴스인지 확인한다. 
        print(&#39;list1과 list2는 같은 인스턴스다.&#39;)  # 이 줄은 실행되지 않는다.
    else:
        print(&#39;list1과 list2는 다른 인스턴스다.&#39;)  # 이 줄은 실행된다.</p>
<pre><code>
### 2 메소드란?
* 메소드 method 란 클래스 안의 함수를 이르는 명칭이다. 
* 선언 및 사용방법은 함수와 다르지 않다.
1. **`self`**
    * 생성된 객체 자기자신을 나타내는 예약어
    * 메소드의 첫번째 인자는 `self`이며 인스턴스를 호출할 때 `self`를 사용한다.
    * 단, 인스턴스의 매개변수를 전달할 때 self 인자는 **호출하지 않는다.**  
        * 예를들어 Class_example 이라는 클래스의 method_example(self) 라는 메소드를 호출하려면 `Class_example.method_example()` 만 사용하면 된다. 
        * 그러나 메소드의 인자가 다음과 같이 두개 method_example2(self, argument_example) 라면 호출 방법은 다음과 같아진다. `Class_example.method_example2(argument_example)`

```py
# 메소드를 활용한 클래스 활용 예
class Human():
    &#39;&#39;&#39;인간&#39;&#39;&#39;

    # person이라는 인스턴스에 name, weight 변수를 만들어 return하는 함수
    def create(name, weight):
        person = Human()
        person.name = name
        person.weight = weight
        return person

    def eat(self):
        self.weight += 0.1

    def walk(self):
        self.weight -= 0.1

person = Human.create(&quot;철수&quot;, 60.5)
eat()  

# 메소드가 아닌 함수를 호출하려면 person.eat = eat(person)을 선언하고
# eat(person) 또는 person.eat을 호출해야했다.</code></pre><h3 id="3-특수한-메소드">3 특수한 메소드</h3>
<pre><code>* Python 에서 특수한 메소드는 메소드를 `__` 언더바 두개로 감싼다.
* Special Method, Magic Method 라고도 부른다.
* Python이 내부적으로 구현한 내장 메소드다.</code></pre><ol>
<li><p><strong><code>__new(cls[,...])__</code></strong> : 객체 생성 함수</p>
<ol>
<li>클래스 cls의 새 인스턴스를 만들기 위해 호출된다.</li>
<li>인스턴스를 생성할 때 가장 먼저 실행되는 함수다.</li>
<li>클래스 자기 자신 (cls) 을 숨겨진 인자로 받는다.</li>
<li>반드시 cls, 생성된 인스턴스를 return 한다.<ul>
<li>이 때 cls 인스턴스를 돌려주지 않으면 <code>__init__()</code>은 호출되지 않는다.</li>
</ul>
</li>
<li>Allocator (할당함수) 로, Constructor (생성자)가 아니다.</li>
</ol>
</li>
<li><p><strong><code>__init__(self[,...])</code></strong> : 초기화 함수</p>
<ol>
<li><code>__new__()</code>에 의해 인스턴스가 만들어진 후, 호출자에게 돌려주기 위해 호출된다.</li>
<li>다시 말해, 인스턴스를 만드는 순간에 자동으로 호출된다.<ul>
<li>정리: <code>__new__()</code> 메소드가 인스턴스를 생성하면 <code>__init__()</code> 메소드가 이를 커스터마이징한다. (변수전달 등)</li>
<li><code>__init__()</code>은 Class에 메모리를 할당하지 않는다.</li>
</ul>
</li>
<li>주의! <code>__init__()</code> 메소드가 <code>None</code> 이외의 값을 돌려주면 실행 시간에 <code>TypeError</code>가 발생된다.</li>
<li>인자<ul>
<li><code>self</code>는 새 인스턴스이며 그 외의 다른 인자를 포함 할 수 있다.</li>
<li>이 때 self는 외의 다른 인자는 객체 생성자다.</li>
</ul>
</li>
<li>위에서 사용한 create 함수/메소드를 대체할 수 있다.</li>
</ol>
</li>
</ol>
<p><code>__init__</code> 활용 예시</p>
<pre><code class="language-py">class Human():
    &#39;&#39;&#39;인간&#39;&#39;&#39;
    def __init__(self):
        print(&quot;__init__이 실행되었습니다.&quot;)

# 출력
person = Human()
# __init__이 실행되었습니다.</code></pre>
<p><code>self</code> 활용 예시</p>
<pre><code class="language-py">class Human():
    &#39;&#39;&#39;인간&#39;&#39;&#39;
    def __init__(self, name, weight):
        print(&quot;__init__이 실행되었습니다.&quot;)
        print(f&quot;이름은 {name}이고 몸무게는 {weight} 입니다.&quot;)

# 출력
person = Human(&quot;철수&quot;, 60)
# __init__이 실행되었습니다.
# 이름은 철수이고 몸무게는 60입니다.

# 아무것도 하지 않았는데도 init 함수 안의 내용이 실행됨을 확인할 수 있다.</code></pre>
<p>create 함수와 비교</p>
<pre><code class="language-py">class Human():
    &#39;&#39;&#39;인간&#39;&#39;&#39;
    def __init__(self, name, weight):
        &#39;&#39;&#39;초기화 함수&#39;&#39;&#39;
        self.name = name
        self.weight = weight

# 출력
person = Human (&quot;철수&quot;, 60)
print(person.name)
print(person.weight)
# 철수
# 60

# 이전에 사용한 create 메소드
# 인스턴스명인 person이 self로 교체됨을 확인할 수 있다.
class Human():
    &#39;&#39;&#39;인간&#39;&#39;&#39;

    # person이라는 인스턴스에 name, weight 변수를 만들어 return하는 함수
    def create(name, weight):
        person = Human()
        person.name = name
        person.weight = weight
        return person</code></pre>
<ol start="3">
<li><p><strong><code>__str__(self)</code></strong> : 문자열화 함수</p>
<ol>
<li><p>인스턴스를 출력할 때 어떤 문자열을 출력할지 결정한다.</p>
</li>
<li><p>따로 print 처리 하지 않고 문자열을 return한다.</p>
</li>
<li><p><code>__str__</code> 함수를 사용하지 않은 상태에서 객체를 출력하면 &lt;<strong>main</strong>. ~ object ~&gt; 와 같은 메시지가 출력된다.</p>
<ul>
<li><code>str()</code> 함수가 자동으로 호출하는 것이 <code>__str__()</code> 이다.<pre><code class="language-py"># __str__ 예시
class Human():
&#39;&#39;&#39;인간&#39;&#39;&#39;
def __init__(self, name, weight):
self.name = name
self.weight = weight
</code></pre>
</li>
</ul>
<p>def <strong>str</strong>(self):
 return f&quot;{name}(몸무게 : {weight}kg)&quot;</p>
</li>
</ol>
</li>
</ol>
<p>person = Human(&quot;철수&quot;, 60)</p>
<h1 id="출력">출력</h1>
<p>print(person)</p>
<h1 id="철수몸무게--60">철수(몸무게 : 60)</h1>
<pre><code>
### 3 멤버 변수
* 클래스 안에 정의된 변수를 말한다.

### 4 생성자와 소멸자
1. 생성자 Constructor
    * `def __init__(self[,...]):`
    * 파이썬의 생성자는 객체를 생성할 때 호출되는 메소드다.
    * 객체를 생성할 때 초기화 작업을 위해 존재한다.
    * 생성 되는 객체의 변수를 세팅할 수 있다.
    * 참고사항
        * 객체를 직접 생성하지는 않는다.
        * 생성자는 인스턴스를 원하는 대로 사용하도록 커스터마이징하는 함수다.

2. 소멸자 Destructor
    * `def __del__(self)`
    * 객체가 소멸할 때 호출된다. finalizer라고도 부른다.
    * CPython에서는 오직 한번만 호출된다.
    * 리소스 해제 등 종료 작업을 위해 사용된다.

### 6 상속과 오버라이드
1. 상속 inheritance
    * 클래스의 인자로 다른 클래스를 받는 것.
    * 중복된 코드를 줄이기 위해 사용한다.
    * 사용 방법
        1. 공통되는 메소드를 부모클래스에 선언한다.
        2. 독립된 기능을 하는 클래스의 인자로 부모 클래스를 받는다. == 자식클래스
        3. 자식클래스에 자식클래스만의 메소드를 추가한다.
        4. 사용방식은 일반적인 메소드 사용법과 동일하다.
2. 오버라이드 override
    * 부모 클래스의 메소드를 자식클래스에서 덮어쓰는 것
    * 사용방법
        1. 자식클래스에서 덮어쓰기를 원하는 메소드를 생성한다.
            * 예: `wave(self)`
        2. 부모클래스의 메소드 이름과 동일한 메소드를 만든다.
            * 예: `greet()`
        3. 덮어쓴다.
            * 자식클래스의 메소드를 호출하려는 경우
                1. 동일한 이름의 메소드에서 덮어쓰기를 원하는 메소드를 `self.덮어쓰기를원하는메소드()` 형식으로 호출한다.
                * 예: `person.wave()`
                2. 부모클래스의 메소드가 아닌 자식 클래스의 메소드가 호출된다.
            * 단순히 덮어쓰려는 경우
                1. `def greet(self):` 아래에 새로운 작동 방식을 명령한다.
3. `super()`
    * 자식클래스에서 부모클래스의 내용을 사용하고 싶을 때 사용한다.
    * super().부모클래스내용
    * 오버라이드와는 무엇이 다른가?
        * 오버라이드로 충분하지 않을 때가 있다.
        * 부모 클래스의 동작을 그대로 하면서, 무언가를 끼워넣고 싶을 때 사용한다.
            * 예: `super().greet()`
    * 부모의 내용을 가져오는 `super()` 함수는 `__init__`과 함께 자주 사용된다.
        * 예: `super().__init__(name)`

```py
# 상속과 오버라이드 예
class Animal():  # 부모 클래스
    def __init__(self, name):
        self.name = name

    def greet(self):
        print(f&quot;{self.name} 이/가 인사한다&quot;)

class Cow(Animal):
    &#39;&#39;&#39;소&#39;&#39;&#39;  # 아무것도 안적으면 에러 발생하므로 주석을 추가한다.

class Human(Animal):  # 자식 클래스
    def wave(self):
        print(&quot;손을 흔들다&quot;)
    def greet(self):
        self.wave()  # 손을 흔들다.

class Dog(Animal):  # 자식 클래스
    def __init__ (self, name, emotion):  # __init__의 값 사용
        super().__init__(name)
        self.emotion = emotion

    def wag(self):
        print(f&quot;{self.emotion} 꼬리를 흔들면서&quot;,end=&quot; &quot;)  # 목표출력: 꼬리를 흔들면서 인사한다.

    def greet(self):
        self.wag()
        super().greet()  # 부모의 greet 메소드도 함께 사용하기 위해 super() 사용

# 출력
cow = Cow(&quot;소&quot;)
cow.greet()  # 소 이/가 인사한다

person = Human(&quot;철수&quot;)
person.greet()  # 손을 흔들다

dog = Dog(&quot;강아지&quot;,&quot;기쁘게&quot;)
dog.greet()  # 기쁘게 꼬리를 흔들면서 강아지 이/가 인사한다
# 위에서 부모 클래스의 __init__ 값을 빌려온 항목 : 강아지가</code></pre><h2 id="참고">참고</h2>
<ul>
<li><a href="https://wikidocs.net/28">점프 투 파이썬</a></li>
<li><a href="https://programmers.co.kr/learn/courses/2">프로그래머스/파이썬 입문</a></li>
<li><a href="https://weeklyit.code.blog/2019/12/24/2019-12%EC%9B%94-3%EC%A3%BC-python%EC%9D%98-__init__%EA%B3%BC-__new__/"><strong>new</strong>와 <strong>init</strong>의 차이</a></li>
<li><a href="https://docs.python.org/ko/3/reference/datamodel.html#object.__new__">Python 공식 문서 3.3: 특수 메서드 이름들</a></li>
<li><a href="https://blog.hexabrain.net/285">파이썬 강좌 8-2편. 생성자와 소멸자(Constructor and Destructor)</a></li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[Git Commit Message Convention]]></title>
            <link>https://velog.io/@www_1216/Git-Commit-Message-Convention</link>
            <guid>https://velog.io/@www_1216/Git-Commit-Message-Convention</guid>
            <pubDate>Fri, 05 Mar 2021 12:12:20 GMT</pubDate>
            <description><![CDATA[<p>들쭉날쭉한 커밋로그. 어떻게 해야 통일성 있게 작성할 수 있을까?<br>
<a href="https://udacity.github.io/git-styleguide/">Udacity Commit Message Style Guide</a>을 간략하게 번역 후 정리했다.</p>
<h2 id="메시지-구조">메시지 구조</h2>
<blockquote>
<p><strong>분류 : 제목</strong>
<strong>본문</strong>
<strong>꼬리말</strong></p>
</blockquote>
<h3 id="type--분류">Type / 분류</h3>
<p>커밋의 주제와 부합하는 항목을 아래의 카테고리에서 하나를 고른다.</p>
<ul>
<li>feat : 새 기능 추가</li>
<li>fix : 오류 해결</li>
<li>docs : 문서 수정</li>
<li>style : 코드의 내용을 변경하지 않는 한에서의 자잘한 수정 (코드구조, 세미콜론 추가 등)</li>
<li>refactor : 코드 리팩토링<ul>
<li>코드를 이해하기 쉽고, 수정하기 쉽도록 만드는 것. 소프트웨어의 기능을 변경하지 않으며 코드의 구조에 집중한다.</li>
</ul>
</li>
<li>test : 코드 테스트, 리팩토링 테스트 추가 (프로덕션 코드 변경 없음)</li>
<li>chore : 빌드 업데이트, 패키지 매니저 설정 (프로덕션 코드 변경 없음)</li>
</ul>
<h3 id="subject--제목">Subject / 제목</h3>
<ul>
<li>50글자 이내로 작성한다.</li>
<li>첫 글자는 대문자로 작성한다.</li>
<li>마지막에 마침표를 붙이지 않는다.</li>
<li>현재시제와 명령어만 사용한다.</li>
</ul>
<h3 id="body--본문-선택">Body / 본문 (선택)</h3>
<ul>
<li>부가 설명이 필요 할 때 작성한다.</li>
<li>제목과 본문 사이에 한 줄을 띄우고 작성한다.</li>
<li><strong>어떤</strong> 커밋을 <strong>왜</strong> 했는지 작성한다.</li>
<li><strong>어떻게</strong> 커밋했는지는 작성하지 않는다.</li>
<li>한 줄에 72글자를 넘지 않게 작성한다.</li>
</ul>
<h3 id="footer--꼬리말-선택">Footer / 꼬리말 (선택)</h3>
<ul>
<li>출처나 이슈트래커 ID를 작성한다.</li>
</ul>
<br>

<h2 id="예시-커밋-메시지">예시 커밋 메시지</h2>
<blockquote>
<p>feat: Summarize changes in around 50 characters or less</p>
</blockquote>
<p>More detailed explanatory text, if necessary. Wrap it to about 72
characters or so. In some contexts, the first line is treated as the
subject of the commit and the rest of the text as the body. The
blank line separating the summary from the body is critical (unless
you omit the body entirely); various tools like <code>log</code>, <code>shortlog</code>
and <code>rebase</code> can get confused if you run the two together.</p>
<blockquote>
</blockquote>
<p>Explain the problem that this commit is solving. Focus on why you
are making this change as opposed to how (the code explains that).
Are there side effects or other unintuitive consequences of this
change? Here&#39;s the place to explain them.</p>
<blockquote>
</blockquote>
<p>Further paragraphs come after blank lines.</p>
<blockquote>
</blockquote>
<ul>
<li>Bullet points are okay, too<blockquote>
</blockquote>
</li>
<li>Typically a hyphen or asterisk is used for the bullet, preceded
by a single space, with blank lines in between, but conventions
vary here<blockquote>
</blockquote>
If you use an issue tracker, put references to them at the bottom,
like this:<blockquote>
</blockquote>
Resolves: #123
See also: #456, #789</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[서로 다른 두 원격 저장소 병합하기]]></title>
            <link>https://velog.io/@www_1216/%EC%84%9C%EB%A1%9C-%EB%8B%A4%EB%A5%B8-%EB%91%90-%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C-%EB%B3%91%ED%95%A9%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@www_1216/%EC%84%9C%EB%A1%9C-%EB%8B%A4%EB%A5%B8-%EB%91%90-%EC%9B%90%EA%B2%A9-%EC%A0%80%EC%9E%A5%EC%86%8C-%EB%B3%91%ED%95%A9%ED%95%98%EA%B8%B0</guid>
            <pubDate>Fri, 05 Mar 2021 12:01:49 GMT</pubDate>
            <description><![CDATA[<p>깃허브를 관리하다 보면 연관된 두 원격 저장소를 병합해야 할 때가 있다. 파일들만 옮겨서 새로 커밋하는 방법도 있지만 커밋 로그까지 함께 옮겨지지는 않는다. 이럴 때 사용할 수 있는 명령어가 있다.</p>
<h2 id="병합-명령어">병합 명령어</h2>
<pre><code class="language-bash"># 병합할 저장소와 유지할 저장소에 동일한 이름의 파일이 없도록 한다. (README.md 등)

$ git remote add &lt;병합할 저장소 이름&gt; &lt;병합할 저장소 주소&gt;
$ git fetch &lt;병합할 저장소 이름&gt;
$ git merge --allow-unrelated-histories &lt;병합할 저장소 이름&gt;/&lt;병합하고 싶은 branch 이름&gt;
$ git remote remove &lt;병합할 저장소 이름&gt;
$ git commit -m &quot;Merge : &lt;병합할 저장소 이름&gt; into &lt;유지할 저장소 이름&gt;&quot;</code></pre>
<br>

<h2 id="명령어를-살펴보자">명령어를 살펴보자</h2>
<h3 id="1-커밋-로그를-병합하기-위해-병합할-원격-저장소를-병합할-저장소-이름으로--추가한다">1. 커밋 로그를 병합하기 위해 병합할 원격 저장소를 &lt;병합할 저장소 이름&gt;으로  추가한다.</h3>
<pre><code class="language-bash">$ git remote add &lt;병합할 저장소 이름&gt; &lt;병합할 저장소 주소&gt;  # 기본 형태
$ git remote add pre https://github.com/... .../pre  # pre: 병합할 저장소 예시</code></pre>
<p>원격 저장소의 기본 별칭은 <code>origin</code>이며 우리는 이를 <code>git push origin master</code> 등 자주 쓰는 git 명령어에서 확인할 수 있다.</p>
<p>원격 저장소의 별칭에 기본값이 있다면 다른 별칭도 지정할 수 있을까? 그렇다면 다른 별칭은 어떻게 설정하며 어떨 때 사용할 수 있을까?</p>
<p>로컬 폴더와 원격저장소를 연결하는 명령어는 <code>git remote add origin &lt;주소&gt;</code> 였다. origin 대신에 지정하고 싶은 별칭을 적고, 원격 저장소의 주소를 적으면 로컬 폴더와 원격 저장소가 지정한 별칭으로 연결된다. 이 때 <code>git push 별칭 master</code>를 사용하면 별칭과 함께 지정한 원격 저장소로 커밋 기록이 업로드 될 것이다.</p>
<br>

<h3 id="2-원격-저장소에-저장된-커밋-기록들을-가져온다-병합은-하지-않는다">2. 원격 저장소에 저장된 커밋 기록들을 가져온다. (병합은 하지 않는다.)</h3>
<pre><code class="language-bash">$ git fetch &lt;병합할 저장소 이름&gt;
$ git fetch pre</code></pre>
<p><code>git pull</code>은 <code>git fetch</code>와 <code>git merge</code>가 합쳐진 명령어였다. 원격 저장소의 내용과 로컬의 최신 커밋 내용이 동일하다면 바로 pull을 해도 되지만 이 경우는 그렇지 않으므로 <code>git fetch</code>로 병합할 저장소의 커밋로그를 가져와 현재 로컬 저장소의 파일들과 비교하는 단계를 거친다.</p>
<p>이 때 충돌하는 파일이 있거나, 제외하고 병합하려는 파일이 있다면 <code>git reset HEAD 파일이름</code> 으로 병합할 목록에서 제외해준다.    </p>
<ul>
<li>HEAD는 현재 작업중인 가장 최근의 커밋이다. bash를 쓰던 중 <code>HEAD -&gt; master</code> 또는 <code>origin/master</code>를 본 적이 있을 것이다. 이 때 <code>HEAD -&gt; master</code> 는 master로 이동될 예정인 로컬의 최신 커밋이며 <code>origin/master</code>는 원격저장소의 최신 커밋이다.</li>
</ul>
<br>

<h3 id="3-연관이-없는-기록들을-병합한다">3. 연관이 없는 기록들을 병합한다.</h3>
<pre><code class="language-bash">$ git merge --allow-unrelated-histories &lt;병합할 저장소 이름&gt;/&lt;병합하고 싶은 branch 이름&gt;
$ git merge --allow-unrelated-histories pre/master</code></pre>
<p>단계 2에서 파일 충돌이 일어나지 않도록 파일명을 변경하거나 제외해줬다면 <code>git merge</code>로 두 저장소의 커밋기록을 병합한다.</p>
<p>단, 새로운 커밋은 이전의 커밋기록과 연결되어야 하므로 서로 다른 원격 저장소를 병합할 때에는 refusing to merge unrelate histories error가 발생하거나 아예 merge가 불가능하게 된다.</p>
<p>이 때 <code>--allow-unrelated-histories</code> 옵션을 사용하면 문제없이 병합이 완료된다. 해당 옵션은 말 그대로 관계 없는 (커밋) 기록을 병합할 수 있게 허용한다는 뜻이다. (커밋 기록이 달라 push가 불가능 할 때에도 이 옵션을 사용해 push 한다.)</p>
<br>

<h3 id="4-병합이-완료되었으니-병합된-원격-저장소를-지운다">4. 병합이 완료되었으니 병합된 원격 저장소를 지운다.</h3>
<pre><code class="language-bash">$ git remote remove &lt;병합할 저장소 이름&gt;
$ git remote remove pre</code></pre>
<p>보통 두 원격 저장소를 병합하고 나면 병합된 원격저장소는 지우게 된다. 없앨 원격 저장소를 로컬과 연결해 둘 필요는 없으니 <code>git remote remove</code>로 지운다.</p>
<br>

<h3 id="5-병합-완료된-로그를-커밋한다">5. 병합 완료된 로그를 커밋한다.</h3>
<pre><code class="language-bash">$ git commit -m &quot;Merge : &lt;병합할 저장소 이름&gt; into &lt;유지할 저장소 이름&gt;&quot;</code></pre>
<p>4번까지의 과정은 HEAD에서 일어난 것이니 아직까지는 <code>git log</code>로 병합된 커밋 로그를 확인할 수 없다. 그렇다고 병합이 실패한 것은 아니니 침착하게 커밋을 하면 병합 된 최종 커밋로그를 확인 할 수 있다.</p>
<br>

<h3 id="6-폴더-정리">6. 폴더 정리</h3>
<p>이렇게 병합이 되었다면 어떤 폴더에서 bash를 열고 작업했든 병합한 저장소(코드예시에서 pre 저장소)의 파일과 폴더들이 <code>.git</code> 폴더가 존재하는 위치에 생성 될 것이다. 하나하나 이동해주면 된다.</p>
<ul>
<li><em>지정한 폴더 안에 원격 저장소 안의 내용을 옮겨오는 방법을 찾고싶은데 아직은 방법을 모르겠다. 찾게되면 추가 할 것 (21-03-05)</em></li>
</ul>
<br>
<hr>

<h2 id="참고">참고</h2>
<ul>
<li><a href="https://mansoo-sw.blogspot.com/2017/08/git-repository-merge.html">Git 저장소를 병합하는 방법(How to merge repositories in Git)
</a></li>
<li><a href="https://backlog.com/git-tutorial/kr/stepup/stepup2_7.html">6. 병합할 때 발생하는 충돌 해결하기</a></li>
</ul>
]]></description>
        </item>
    </channel>
</rss>