Git
Chapters ▾ 2nd Edition

6.2 GitHub - GitHub 프로젝트에 기여하기

GitHub 프로젝트에 기여하기

계정은 이제 만들었으니 프로젝트에 참여하는 방법을 살펴볼 차례가 됐다.

프로젝트 Fork 하기

참여하고 싶은 프로젝트가 생기면 아마 그 프로젝트에 Push 할 권한은 없을 테니까 “Fork” 해야 한다. “Fork” 하면 GitHub이 프로젝트를 통째로 복사해준다. 그 복사본은 사용자 네임스페이스에 있고 Push 할 수도 있다.

Note

과거에는 “Fork” 가 좋은 의미로 쓰이지 않았다. 오픈 소스 프로젝트를 “Fork” 한다는 것은 복사해서 조금은 다른 프로젝트를 만드는 것을 의미했고 때때로 원래 프로젝트와 경쟁하거나 기여자를 나누는 결과를 가져오기도 했다. GitHub에서 “Fork” 는 단순히 자신의 네임스페이스로 복사하는 것을 뜻한다. 그래서 공개한 상태로 수정하고 좀 더 열린 방식으로 참여할 수 있다.

이 방식에서는 사람들을 프로젝트에 추가하고 Push 권한을 줘야 할 필요가 없다. 사람들은 프로젝트를 “Fork” 해서 Push 한다. 그리고 Push 한 변경 내용을 원래 저장소로 보내 기여한다. 이것을 Pull Request라고 부르는데 나중에 다시 설명한다. 토론 스레드를 만들고 거기서 코드 리뷰를 하면서 토론하는 스레드를 만들어 토론을 시작한다. 프로젝트 소유자 마음에 들 때까지 소유자와 기여자는 함께 토론한다. 마음에 들게 되면 Merge 한다.

프로젝트는 쉽게 Fork 할 수 있다. 프로젝트 페이지를 방문해서 오른쪽 꼭대기에 있는 “Fork” 버튼을 클릭한다.

``Fork'' 버튼.
Figure 89. “Fork” 버튼.

몇 초안에 복사된 프로젝트 페이지로 이동한다. 이 새 프로젝트의 소유자는 Fork 한 사람 자신이기 때문에 쓰기 권한이 있다.

GitHub 플로우

GitHub은 Pull Request가 중심인 협업 워크플로를 위주로 설계됐다. 이 워크플로는 Fork 해서 프로젝트에 기여하는 것인데 단일 저장소만 사용하는 작은 팀이나 전 세계에서 흩어져서 일하는 회사, 혹은 한 번도 본 적 없는 사람들 사이에서도 유용하다. Git 브랜치 에서 설명했던 토픽 브랜치 중심으로 일하는 방식이다.

보통은 아래와 같이 일한다.

  1. 프로젝트를 Fork 한다.

  2. master 기반으로 토픽 브랜치를 만든다.

  3. 뭔가 수정해서 커밋한다.

  4. 자신의 GitHub 프로젝트에 브랜치를 Push 한다.

  5. GitHub에 Pull Request를 생성한다.

  6. 토론하면서 그에 따라 계속 커밋한다.

  7. 프로젝트 소유자는 Pull Request를 Merge 하고 닫는다.

이 방식은 기본적으로 Integration-Manager 워크플로에서 설명하는 Integration-Manager 워크플로와 같다. 토론이나 리뷰를 이메일이 아니라 GitHub에서 제공하는 웹 기반 도구를 사용하는 것뿐이다.

GitHub에 있는 오픈소스 프로젝트에 이 워크플로를 이용해서 뭔가 기여하는 예제를 살펴보자.

Pull Request 만들기

Tony는 자신의 Arduino 장치에서 실행해볼 만한 코드를 찾고 있었고 GitHub에 있는 https://github.com/schacon/blink에서 매우 흡족한 프로그램을 찾았다.

기여하고자 하는 프로젝트.
Figure 90. 기여하고자 하는 프로젝트.

다 좋은데 너무 빠르게 깜빡이는 게 마음에 안 들었다. 매초 깜빡이는 것보다 3초에 한 번 깜빡이는 게 더 좋을 것 같았다. 그래서 프로그램을 수정하고 원 프로젝트에 다시 보내기로 했다.

앞서 설명했던 것처럼 Fork 버튼을 클릭해서 프로젝트를 복사한다. 사용자 이름이 “tonychacon” 이라면 https://github.com/tonychacon/blink 에 프로젝트가 복사된다. 이 프로젝트는 본인 프로젝트이고 수정할 수 있다. 이 프로젝트를 로컬에 Clone 해서 토픽 브랜치를 만들고 코드를 수정하고 나서 GitHub에 다시 Push 한다.

$ git clone https://github.com/tonychacon/blink (1)
Cloning into 'blink'...

$ cd blink
$ git checkout -b slow-blink (2)
Switched to a new branch 'slow-blink'

$ sed -i '' 's/1000/3000/' blink.ino (macOS) (3)
# If you're on a Linux system, do this instead:
# $ sed -i 's/1000/3000/' blink.ino (3)

$ git diff --word-diff (4)
diff --git a/blink.ino b/blink.ino
index 15b9911..a6cc5a5 100644
--- a/blink.ino
+++ b/blink.ino
@@ -18,7 +18,7 @@ void setup() {
// the loop routine runs over and over again forever:
void loop() {
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  [-delay(1000);-]{+delay(3000);+}               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  [-delay(1000);-]{+delay(3000);+}               // wait for a second
}

$ git commit -a -m 'three seconds is better' (5)
[slow-blink 5ca509d] three seconds is better
 1 file changed, 2 insertions(+), 2 deletions(-)

$ git push origin slow-blink (6)
Username for 'https://github.com': tonychacon
Password for 'https://tonychacon@github.com':
Counting objects: 5, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 340 bytes | 0 bytes/s, done.
Total 3 (delta 1), reused 0 (delta 0)
To https://github.com/tonychacon/blink
 * [new branch]      slow-blink -> slow-blink
  1. Fork 한 개인 저장소를 로컬에 Clone 한다.

  2. 무슨 일인지 설명이 되는 이름의 토픽 브랜치를 만든다.

  3. 코드를 수정한다.

  4. 잘 고쳤는지 확인한다.

  5. 토픽 브랜치에 커밋한다.

  6. GitHub의 개인 저장소에 토픽 브랜치를 Push 한다.

Fork 한 내 저장소에 가면 GitHub은 토픽 브랜치가 하나 Push 됐다는 것을 알려주고 원 저장소에 Pull Request를 보낼 수 있는 큰 녹색 버튼을 보여준다.

아니면 저장소의 브랜치 페이지로(https://github.com/<user>/<project>/branches) 가서 해당 브랜치의 “New pull request” 버튼을 이용한다.

Pull Request 버튼
Figure 91. Pull Request 버튼

녹색 버튼을 클릭하면 Pull Request의 제목과 설명을 입력하는 화면이 보인다. 항샹 프로젝트 소유자가 판단을 내릴 수 있을 정도로 공을 들여 작성해야 한다. 왜 수정했는지 얼마나 가치 있는지 설명해서 관리자를 설득해야 한다.

그리고 “ahead” 토픽 브랜치가 master 브랜치에서 달라진 커밋도 보여주고 수정된 내용을 “unified diff” 형식으로 보여준다. 이 수정 내용이 프로젝트 관리자가 Merge 할 내용이다.

Pull Request 생성
Figure 92. Pull Request를 생성하는 페이지

화면에 있는 Create pull request 버튼을 클릭하면 프로젝트 원소유자는 누군가 코드를 보냈다는 알림을 받는다. 그 알림에는 해당 Pull Request에 대한 모든 것을 보여주는 페이지의 링크가 들어 있다.

Note

Pull Request는 보통 공개 프로젝트에서 사용한다. 기여자는 수정하고 나서 원 저장소에 Pull Request를 연다. 개발 초창기에는 프로젝트 내부에서도 많이 사용한다. 이미 Pull Request를 열어 놓은 토픽 브랜치라고 할지라도 계속 Push 할 수 있다. 마지막이 아니라 처음부터 Pull Request를 열면 어떤 주제를 가지고 팀 동료와 함께 토론할 수 있어서 좋다.

Pull Request 놓고 감 놓고 배 놓기

Pull Request가 오면 프로젝트 소유자는 변경 점이 무엇인지 확인한 후, Merge 혹은 거절하거나 코멘트를 달 수 있다. 소유자가 아이디어 자체를 마음에 들어 한다면 빛을 보기까지 좀 더 공을 들여야 한다.

이런 소통을 이메일로 하는 워크플로는 분산 환경에서의 Git에 설명했었다. GitHub에서는 온라인에서 한다. 프로젝트 소유자는 unified diff 형식의 변경사항을 검토하고 즉각 해당 라인에 코멘트를 달 수 있다.

PR 라인 코멘트
Figure 93. Pull Request의 코드에 코멘트 달기

관리자가 코멘트를 달면 Pull Request를 만든 사람에게 알림이 간다. 실제로는 저장소를 'Watch’하는 사람 모두에게 알림이 간다. 알림 정책은 설정할 수 있지만, 다음에 검토한다. 알림을 받는 Tony가 이메일 알림을 켜놨다면 이메일 알림도 받는다.

이메일 알림으로 온 코멘트
Figure 94. 이메일 알림으로 온 코멘트

누구나 Pull Request에 코멘트를 달 수 있다. Pull Request 토론 페이지를 보면 프로젝트 소유자가 코드에 코멘트를 달거나 Pull Request 자체에 코멘트를 달면서 토론하는 것을 보여 준다. 코드 코멘트도 맥락을 이루어 커뮤니케이션 할 수 있다.

PR 토론 페이지
Figure 95. Pull Request 토론 페이지

이 토론을 보고 기여자는 자신이 무엇을 해야 자신의 코드가 받아들여질지 알 수 있다. 다행히 매우 직관적이다. 만약 이 일을 이메일로 하고자 한다면 관련 커밋을 다시 말아서 메일링 리스트에 다시 보내야 한다. 하지만, GitHub에서는 해당 토픽 브랜치에 이어서 커밋하고 Push 하면 된다. 최종 Pull Request에서 Push로 업데이트한 PR의 코드를 보면 예전 코드에 달렸던 코멘트는 나오지 않는다. 추가된 커밋으로 인해 코드가 수정되었기 때문이다.

기존 PR에 이어서 Push를 하면 알림이 가지 않는다. 그래서 Tony는 자신이 작업한 내용을 코멘트로 남겼다. 그러면 프로젝트 소유자는 무슨 일이 있었는지 쉽게 알 수 있다.

최종 PR
Figure 96. 최종 Pull Request

꼭 짚고 넘어가야 할 것이 있다. 이 Pull Request의 “Files Changed” 탭을 클릭하면 “unified” diff를 볼 수 있다. 이 Pull Request가 주 브랜치에 Merge 되면 어떻게 달라지는지 보여준다. git diff 명령을 빌어 표현하자면 `git diff master…​<branch>`와 같은 명령이 실행되는 거고 `<branch>`는 Pull Request의 브랜치를 의미한다. 무슨 내용인지 확인하기에서 자세히 설명한다.

그 외 알아두면 좋은 것은 GitHub은 Pull Request가 Merge 될 수 있는지 검사해서 서버에서 Merge 할 수 있도록 Merge 버튼을 제공한다. 이 버튼은 저장소에 쓰기 권한이 있는 사람만 볼 수 있고 이 버튼으로 Merge 하면 Merge 커밋이 생긴다(Trivial Merge). “fast-forward” Merge가 가능할 때도 “non-fast-forwrd” 로 Merge 한다.

로컬에 Pull Request 브랜치를 당겨와서 Merge 해도 된다. master 브랜치에 Merge 해서 GitHub에 Push 하면 자동으로 해당 Pull Request가 닫힌다.

이런 방식이 대부분의 GitHub 프로젝트가 사용하는 기본 워크플로다. 토픽 브랜치를 만들고 Pull Request를 연다. 거기서 토론을 계속 하고 그 브랜치에 커밋을 하기도 한다. 마지막에는 Merge하고 Request를 닫는다.

Note
Fork는 옵션

한 저장소의 두 브랜치를 두고도 Pull Request를 열 수 있다. 한 저장소에 쓰기 권한이 있는 동료 둘이서 어떤 기능을 추가하려고 하고 있다면 토픽 브랜치를 만들고 Push 한다. 그리고 나서 같은 저장소의 master 브랜치에 대해 Pull Request를 만들어 코드 리뷰와 토론을 시작한다. Fork는 필수가 아니다.

Pull Request 팁

GitHub에서 프로젝트에 기여하는 방법 중 가장 기본적인 방법을 살펴봤다. Pull Request를 사용할 때 도움이 되는 유용한 팁을 몇 가지 살펴보자.

Patch를 Pull Request로 보내기

보통 프로젝트에서는 Pull Request의 Patch가 완벽하고 큐처럼 꼭 순서대로 적용돼야 한다고 생각하지 않는다. 메일링 리스트를 사용하던 프로젝트에서는 Patch 순서가 의미가 있다고 생각한다. GitHub의 Pull Request는 어떤 주제를 두고 논의하는 자리다. 논의가 다 무르익으면 Merge 한다.

이 차이는 매우 중요하다. 일반적으로 처음부터 완벽한 코드를 보낼 수 없어서 메일링 리스트로 Patch를 보낼 일은 별로 없다. Pull Request는 초기부터 프로젝트 관리자와 소통할 수 있도록 해주기 때문에 혼자 답을 찾는 게 아니라 커뮤니티에서 함께 찾을 수 있다. 누군가 Pull Request를 열면 관리자와 커뮤니티는 어떻게 수정하는 게 좋을지 의견을 낸다. Patch를 처음부터 다시 전체를 작성하지 않아도 된다. 수정한 만큼만 해당 브랜치에 커밋하고 하던 일과 대화를 계속 해 나가면 된다.

최종 Pull Request로 돌아가서 다시 보면 기여자가 커밋을 Rebase 하거나 Pull Request를 다시 열지 않았다는 것을 확인할 수 있다. 그냥 기존 브랜치에 좀 더 커밋하고 Push 했을 뿐이다. 나중에 시간이 지나서 이 Pull Request를 다시 읽으면 왜 이런 방향으로 결정했는지에 대한 맥락을 쉽게 알 수 있다. 웹사이트에서 “Merge” 버튼을 누르면 Merge 커밋을 일부러 남기겠다는 뜻이 된다. 이 Merge 커밋에는 Pull Request 정보가 들어가기 때문에 필요하면 언제든지 맥락을 확인할 수 있다.

Pull Request를 최신으로 업데이트하기

Pull Request가 만든 지 오래됐거나 깨끗하게 Merge 되지 않으면 메인테이너가 쉽게 Merge 할 수 있게 수정한다. GitHub은 자동으로 Merge 할 수 있는 Pull Request인지 아닌지 Pull Request 페이지 하단에서 알려준다.

PR Merge 실패
Figure 97. 깨끗하게 Merge 할 수 없는 Pull Request

깨끗하게 Merge 할 수 없는 Pull Request 같은 메시지를 보면 해당 브랜치를 고쳐서 녹색으로 만든다. 메인테이너가 고치지 않아도 되도록 한다.

이 문제를 해결하는 방법은 두 가지가 있다. 대상 브랜치(보통은 master 브랜치)를 기준으로 Rebase 하는 방법이 있고 대상 브랜치를 Pull Request 브랜치에 Merge 하는 방법이 있다.

GitHub을 사용하는 개발자는 대부분 후자를 고른다. 앞서 살펴봤던 것과 같은 이유다. Rebase 하면 히스토리는 깨끗해지지만 훨씬 더 어렵고 에러 나기 쉽다.

Pull Request가 Merge 될 수 있도록 대상 브랜치를 Merge 하려면 먼저 원 저장소를 리모트로 추가한다. 그리고 나서 Fetch 하고 그 저장소의 대상 브랜치를 해당 토픽 브랜치에 Merge 한다. 문제를 해결하고 그 브랜치에 도로 Push 한다.

“tonychacon” 예제에 이 워크플로를 적용해보자. 원저자가 뭔가 수정을 했는데 Pull Request와 충돌이 난다. 여기부터 살펴보자.

$ git remote add upstream https://github.com/schacon/blink (1)

$ git fetch upstream (2)
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (3/3), done.
Unpacking objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
From https://github.com/schacon/blink
 * [new branch]      master     -> upstream/master

$ git merge upstream/master (3)
Auto-merging blink.ino
CONFLICT (content): Merge conflict in blink.ino
Automatic merge failed; fix conflicts and then commit the result.

$ vim blink.ino (4)
$ git add blink.ino
$ git commit
[slow-blink 3c8d735] Merge remote-tracking branch 'upstream/master' \
    into slower-blink

$ git push origin slow-blink (5)
Counting objects: 6, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 682 bytes | 0 bytes/s, done.
Total 6 (delta 2), reused 0 (delta 0)
To https://github.com/tonychacon/blink
   ef4725c..3c8d735  slower-blink -> slow-blink
  1. 원 저장소를 “upstream” 이라는 이름의 리모트로 추가한다

  2. 리모트에서 최신 데이터를 Fetch 한다

  3. 대상 브랜치를 토픽 브랜치에 Merge 한다

  4. 충돌을 해결한다

  5. 동일한 토픽 브랜치에 도로 Push 한다

이렇게 하면 Pull Request는 자동으로 업데이트되고 깨끗하게 Merge 할 수 있는지 재확인된다.

PR 고침
Figure 98. 깨끗하게 Merge 할 수 있는 Pull Request.

연속성은 Git의 장기 중 하나다. 오랫동안 무엇인가 만들고 있다면 최신으로 유지하기 위해 대상 브랜치를 쉽게 Merge 해 올 수 있다. 다 마칠 때까지 하고 또 하고 할 수 있다. Merge 할 때 발생하는 충돌만 해결하면 되고 지속적으로 개발 프로세스를 관리할 수 있다.

브랜치를 꼭 깨끗하게 유지하고 싶어서 Rebase 해야 한다고 생각한다면 이미 열어 놓은 Pull Request에 대고 Push 하지 말아야 한다. 그럼 이 브랜치를 가져다 Merge 해 놓은 사람들은 Rebase 의 위험성에 설명했듯이 충격에 빠질 것이다. 대신 브랜치를 새로 만들어 Push 한다. 그리고 Pull Request도 새로 여는데 원 Pull Request가 뭔지 알 수 있도록 참조를 달고 원래 것은 닫는다.

참조

그럼 바로 “어떻게 Pull Request를 참조시키지?” 라는 의문이 들겠지만, 방법은 매우 많다. GitHub에 쓰기 가능한 곳 어디에서나 참조를 달 수 있다.

먼저 Issue와 Pull Request를 서로 참조시키는 방법부터 살펴보자. 모든 Pull Request와 Issue에는 프로젝트 내에서 유일한 번호를 하나 할당한다. 예를 들어, 3인 Pull Request와 #3인 Issue는 동시에 있을 수 없다. `<num>`과 같은 형태로 코멘트가나 설명에 Pull Request와 Issue를 참조시킬 수 있다. 이 방법은 단일 프로젝트 범위에서만 유효하다. Fork 저장소의 Issue나 Pull Request를 참조시키려고 한다면 `username#<num>`라고 쓰고 아예 다른 저장소면 `username/repo#<num>`라고 써야 한다.

설명을 위해 이미 브랜치를 Rebase 했고 Pull Request를 새로 만들었다고 하자. 그럼 예전 Pull Request가 뭔지 알 수 있도록 새것에서 예전 것을 참조하게 해보고 Pull Request의 상호 참조 편집.같이 Fork 한 저장소의 이슈나 아예 다른 저장소의 이슈도 참조하게 해보자.

PR 참조 편집
Figure 99. Pull Request의 상호 참조 편집.

이 Pull Request를 보내면 Pull Request의 상호 참조.처럼 보인다.

PR 참조
Figure 100. Pull Request의 상호 참조.

GitHub URL을 전부 입력해도 딱 필요한 만큼으로 줄어든다.

그리고 원래 있던 Pull Request를 닫으면 새 Pull Request에는 기존 Pull Request가 닫혔다고 언급된다. GitHub은 Pull Request 타임라인에 트랙백 이벤트를 자동으로 만든다. 그래서 이 Pull Request에 방문하는 사람은 예전 Pull Request가 닫혔는지 알 수 있고 그 링크가 있어서 바로 클릭해서 예전 것을 볼 수 있다. 이 링크는 닫은 Pull Request의 트랙백처럼 생겼다.

닫은 PR의 트랙백
Figure 101. 닫은 Pull Request의 트랙백

이슈뿐만 아니라 커밋의 SHA도 참조할 수 있다. 40자 SHA를 적으면 GitHub은 자동으로 해당 커밋에 링크를 걸어 준다. Fork 저장소나 아예 다른 저장소의 커밋도 이슈와 동일한 방식으로 링크시킬 수 있다.

GitHub Flavored Markdown

다른 이슈를 링크하는 것은 GitHub 글쓰기의 첫걸음에 불과하다. “GitHub Flavored Markdown” 이라는 형식으로 이슈나 Pull Request의 설명, 코멘트, 코드 주석 등에서 글을 쓸 수 있다. Markdown 형식으로 글을 쓰면 그냥 텍스트로 쓴 글이지만 형식을 갖춰 미끈하고 아름답게 렌더링된다.

GitHub Flavored Markdown 예제.는 Markdown으로 쓴 글이 어떻게 렌더링되는지 보여준다.

Markdown 예제
Figure 102. GitHub Flavored Markdown 예제.

GitHub Flavored Markdown

GitHub Flavored Markdown(이하 GFM)은 기본 Markdown을 확장했다. GFM은 Pull Request나 이슈 등의 글을 쓸 때 매우 유용하다.

타스크 리스트

GFM이 확장한 것 기능 중 타스크 리스트가 있는데 Pull Request에서 사용하면 좋다. 간단히 말해서 타스크 리스트는 완료했다고 표시할 수 있는 체크박스의 목록이다. 이슈나 Pull Request에서 다 했다고 표기하고 싶을 때 사용한다.

타스크 리스트는 아래와 같이 사용한다.:

- [X] Write the code
- [ ] Write all the tests
- [ ] Document the code

이 타스크 리스트를 이슈나 Pull Request에 사용하면 타스크 리스트.처럼 렌더링된다.

타스크 리스트
Figure 103. 타스크 리스트.

Pull Request를 Merge 하기 전에 꼭 처리해야 하는 일의 목록을 표현할 때 타스크 리스트를 사용한다. Markdown을 직접 고치지 않고 체크박스만 클릭해도 해당 타스크가 완료됐다고 업데이트되기 때문에 상당히 좋은 기능이다.

GitHub은 이슈나 Pull Requests에 있는 타스크 리스트를 집계해서 목록 화면에서 보여준다. 예를 들어, 타스크들이 정리된 Pull Request가 있으면 Pull Request 요약 페이지에서 얼마나 진행됐는지 볼 수 있다. 그래서 Pull Request를 타스크 여러 개로 쪼개 두면 그 브랜치가 얼마나 진행됐는지 알기 쉽다. Pull Request 목록 화면에서 보여주는 타스크 현황.를 보자.

타스크 리스트의 예
Figure 104. Pull Request 목록 화면에서 보여주는 타스크 현황.

Pull Request부터 열어 두고 일을 하면 해당 기능이 얼마나 진행됐는지 쉽게 알 수 있다.

코드 조각

코멘트에 코드 조각도 넣을 수 있다. 실제로 구현해서 브랜치에 커밋하기 전에 뭔가 아이디어를 코드로 표현해 볼 때 좋다. 그 외에도 단순히 코드 예제를 보여주기 위해서 사용하거나 해당 Pull Request에서 구현한 것이 무엇인지 보여줄 때도 사용한다.

백틱으로 된 “Fence” 안에 코드 조각을 넣는다.

```java
for(int i=0 ; i < 5 ; i++)
{
   System.out.println("i is : " + i);
}
```

코드 조각에 언어 이름을 쓰면 GitHub은 구문강조(Syntax Highlight)도 해준다. 구문강조로 미끈해진 코드.는 언어 이름을 넣어서 구문 강조된 결과다.

미끈한 코드
Figure 105. 구문강조로 미끈해진 코드.

인용

아주 긴 글에서 딱 한 부분만 집어서 논의하고 싶을 때 > 문자로 해당 부분을 인용하고 그 밑에 코멘트를 단다. 이 방법은 매우 흔히 사용하는 방법이라, 상당히 유용하고, 단축키도 지원한다. 인용하고 싶은 텍스트를 선택하고 r 키를 누르면 바로 코멘트 상자에 해당 텍스트가 인용된다.

아래와 같이 인용한다.

> Whether 'tis Nobler in the mind to suffer
> The Slings and Arrows of outrageous Fortune,

How big are these slings and in particular, these arrows?

이 텍스트는 인용 예제.처럼 렌더링된다.

인용 예제
Figure 106. 인용 예제.

Emoji

마지막으로 소개하는 것은 글에 Emoji를 넣을 수 있다는 것이다. Emoji는 GitHub 이슈나 Pull Request에서 정말 많이 사용된다. GitHub은 Emoji를 쉽게 사용할 수 있도록 돕는다. 코멘트를 쓸 때 : 문자로 Emoji 입력을 시작하면 선택해서 자동완성할 수 있도록 Emoji 목록을 보여준다.

Emoji 자동완성
Figure 107. Emoji 자동완성.

Emoji는 :<name>: 형식으로 생겼다. 아래 예제를 보자.

I :eyes: that :bug: and I :cold_sweat:.

:trophy: for :microscope: it.

:+1: and :sparkles: on this :ship:, it's :fire::poop:!

:clap::tada::panda_face:

렌더링되면 Emoji를 많이 쓴 글.처럼 보인다.

Emoji
Figure 108. Emoji를 많이 쓴 글.

Emoji는 정보 전달하는 데도 좋지만 얼마나 재밌고 기쁜지 같은 표현도 가능하다.

Note

Emoji 문자를 사용하는 웹 서비스가 정말 많다. 어떤 Emoji 문자가 있는지 쉽게 찾아볼 수 있는 치트시트가 있어서 두고두고 참고할 수 있다.

이미지

GitHub이 제공하는 글에 이미지를 포함시키는 기능은 기술적으로 GFM이 아니지만 엄청 유용하다. Markdown 형식으로 이미지를 첨부하고 싶을 때 일반적인 방법으로는 이미지를 올리고 그 URL을 찾아서 일일이 입력해야 하는데 번거롭다. GitHub에서는 그냥 이미지를 바로 Drag-and-Drop으로 붙여 넣을 수 있다.

Drag and drop images
Figure 109. 끌어다 놓기로 이미지 자동 붙이기.

끌어다 놓기로 이미지 자동 붙이기.로 돌아가서 보면 Text Area 위에 “Parsed As Markdown” 이라는 표시를 볼 수 있다. 그 링크를 클릭하면 GitHub에서 Markdown을 어떻게 사용하는지 알려주는 치트시트를 보여준다.