Git - 실전 가이드

VCS(Version Control System)는 버전관리 시스템으로 파일의 상태를 커밋 단위로 구분하여 버전을 관리해주는 시스템입니다. 백업용뿐만 아니라 협업용으로도 넘사벽으로 많은 개발자분들이 사용하는 협업 관리 툴입니다. 간단하게 Git은 거대한 오픈소스 프로젝트답게 정말 파워풀한 기능들을 제공하지만 Git을 활용하기 위해서는 그만큼 높은 런닝커브를 요구합니다. 간단하게 개인용으로 프로젝트를 만들면서 기존의 소스를 건드리지 않고 내 마음대로 테스트하고 소스가 잘못되는 경우에도 이전의 커밋 상태를 되돌릴 때 Git처럼 유용한 도구는 없을 것입니다. 하지만 너무나 많은 기능이 있기 때문에 자주 사용하는 기능을 위주로 정리해보았습니다.

세가지 상태

Git은 기본적으로 파일을 Commited, Modified, Staged 이렇게 세가지 상태로 관리합니다.

  • commited란 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미합니다.
  • Modified는 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않는 상태입니다.
  • Staged란 현재 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미합니다.

워킹 트리, Stagin Area(index), Git 디렉토리

스크린샷 2019-11-29 오후 6 20 40

Git을 설치하고 프로젝트를 추적 및 관리할 때 가장 먼저 사용해야 하는 명령어는 git init입니다. 그러면 .git 디렉토리가 생성되는 것을 확인 할 수가 있는데 이 Git 디렉토리는 Git이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말합니다. 이 Git 디렉토리가 Git의 핵심입니다.
다른 컴퓨터에 있는 저장소를 clone 할 때 Git 디렉토리가 만들어집니다.

워킹 트리는 프로젝트의 특정 버전을 Checkout 한 것입니다. Git 디렉토리는 지금 작업하는 디스크에 있고 그 디렉토리 안에 압축된 데이터베이스에서 파일을 가져와서 워킹 트리를 만듭니다.

Staging Area는 index라고 불리며 Git 디렉토리에 있습니다. 단순한 파일이고 곧 커밋할 파일에 대한 정보를 지정합니다. Staging Area는 Working Directoy에 있는 파일들 중 수정한 파일이 존재하면 개발자가 커밋에 포함시킬 파일을 선별해서 Staging Area에 올립니다. 그리고 커밋을 수행하면 새로운 커밋 개체가 생성되어 개발자가 올린 파일들에 대해서만 이전 커밋정보를 관리합니다. 따라서 언제든지 원복을 할 수 있는 장점이 있습니다.

Git으로 하는 일은 기본적으로 아래와 같습니다.

  1. 워킹 트리에서 파일을 수정합니다.
  2. Staging Area에 파일을 Stage 해서 커밋할 스냅샷을 만듭니다. 모든 파일을 추가할 수도 있고 선택하여 추가할 수도 있습니다.
  3. Staging Area에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장합니다.

Git 디렉토리에 있는 파일들은 Committed 상태입니다. Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았으면 Modified 입니다.

참고로 Git은 데이터를 저장하기 전에 항상 체크섬을 구하고, 그 체크섬으로 데이터를 관리합니다. 그래서 체크섬을 이해하는 깃 없이는 어떠한 파일이나 디렉토리도 변경 할 수 없습니다. 기본적으로 Git은 SHA-1 해시를 사용하여 체크섬을 만듭니다. 체크섬은 40자 길이의 16진수 문자열로 구성되어 있고, 파일의 내용이나 디렉토리의 구조를 이용하여 체크섬을 구합니다.

24b9da6552252987aa493b52f8696cd6d3b00373

이제 위에 Git을 이해하기 위한 최소한의 개념과 용어들을 알아봤으니 바로 실제 많이 사용하는 Git 명령어들을 살펴보겠습니다.

Git 실전 명령 가이드

먼저 IDE(인텔리제이, 이클립스 등)로 프로젝트를 만들고 나서 그 프로젝트를 추적하고 관리하기 위해 사용하는 명령어를 소개합니다.

1.현재 프로젝트 경로에 들어가서 git을 사용할 수 있도록 초기화 해주는 명령어입니다.

git init 

2.프로젝트 디렉토리내의 모든 파일(.은 모든파일을 의미)을 Git의 Staging Area에 추가하는 명령어 입니다. 이 말은 커밋할 파일의 목록들을 의미하기도 합니다.

git add .

참고로 .을 아큐먼트로 주게 되면 모든 파일을 Staging Area에 추가하기 때문에 만약 커밋에 포함시키고 싶지 않는 파일이 존재하게 된다면 .gitignore 파일을 만들고 그 안에 무시할 파일 패턴을 적으면 됩니다.

ex) .gitignore 작성 예시

# 확장자가 .a인 파일 무시
*.a

# 윗 라인에서 확장자가 .a인 파일은 무시하게 했지만 lib.a는 무시하지 않음
!lib.a

# 현재 디렉토리에 있는 TODO 파일은 무시하고 subdir/TODO 처럼 하위 디렉토리에 있는 파일은 무시하지 않음
/TODO

# build/ 디렉토리에 있는 모든 파일은 무시
build/

# doc/notes.txt 파일은 무시하고 doc/server/arch.txt 파일은 무시하지 않음
doc/*.txt

# doc 디렉토리 아래의 모든 .pdf 파일을 무시

doc/**/*.pdf

3.커밋과 동시에 -m 옵션으로 커밋 메시지를 작성할 수 있습니다.

git commit -m "initial commit"

참고로 git commit -a -m "initial commit"에서 -a 옵션을 추가하게 된다면 Staging Area에 추가없이 Git이 관리하는 모든 파일을 자동으로 커밋상태로 만듭니다.

4.원격 저장소, 즉 github repository 주소를 origin이라는 이름으로 등록합니다.

git remote add origin repository주소

5.origin이라는 원격 저장소에 master 브랜치에 푸시합니다. 이때 -u옵션을 쓴다면 다음번 부터 git push만 입력해도 origin의 master 브랜치로 푸시가 됩니다.

git push -u origin master

새로운 변경 사항이 있을 때

로컬에서 파일을 수정하고 원격 저장소에 변경 이력을 반영하고 싶을 때 명령어 순서입니다.

git add
git commit -m "commit message"
git push

과정은 위에 내용이랑 비슷하지만 init과 원격 저장소 등록을 할 필요는 없습니다.

branch, merge 사용법

브랜치 생성은 Git에서 제공해주는 최고의 기능이라고 생각합니다. 이것 때문에 오랫동안 VCS로 Git이 개발자들 사이에 각광받는 이유가 아닐까 싶습니다.

브랜치란 독립적으로 어떤 작업을 진행하기 위한 개념입니다. 필요에 의해 만들어지는 각각의 븐래치는 다른 브랜치의 영향을 받지 않기 때문에 여러 작업을 동시에 진행할 수 있습니다.

Branch

스크린샷 2019-11-29 오후 7 16 45

또한 이렇게 만들어진 브랜치는 다른 브랜치와 병합(Merge)함으로써, 작업한 내용을 새로운 하나의 브랜치로 모을 수 있습니다.
master 브랜치는 저장소를 처음 만들면, Git은 바로 master라는 이름의 브랜치를 만들어 둡니다. 이 새로운 저장소에 새로운 파일을 추가 한다거나 추가한 파일의 내용을 변경하여 그 내용을 저장(commit)하는 것은 모두 master라는 이름의 브랜치를 통해 처리할 수 있는 일이 됩니다.
master가 아닌 또 다른 새로운 브랜치를 만들어서 이제부터 이 브랜치를 사용할거야! 라고 선언하지 않는 이상 모든 작업은 master 브랜치에서 이루어 집니다.

이제 브랜치에 대한 개념을 살펴보았으니 위에 명령어와 마찬가지로 브랜치 생성 및 병합에 대한 명령어 순서를 살펴보겠습니다.

1.새로운 브랜치를 생성(기존 브랜치는 master)

git branch 브랜치 이름설정

만약 브랜치 생성 후 Checkout까지 바로 하고 싶으면 아래 처럼 옵션을 주어서 사용할 수 있습니다.

git checkout -b feature-01

2.1번에서 생성한 브랜치로 변경

git checkout 브랜치이름

3.Staging Area에 모든 파일 추가

git add .

4.커밋개체 생성 및 메시지 작성

git commit -m "commit message"

5.origin 저장소의 새로운 브랜치에 푸시

git push origin 브랜치이름

Merge 수행

git checkout master <- master 브랜치로 변경

git merge 브랜치 이름 

위의 과정으로 master 브랜치에 새로운 브랜치를 merge 할수 있습니다.

이제 Merge를 수행했기 때문에 새로운 브랜치가 필요없다면 삭제를 해줘야 합니다.
예를 들어서 feature-01 브랜치를 생성하고 master 브랜치와 Merge 후에 삭제한다고 가정한다면 아래와 같습니다.

git checkout master <- master 브랜치로 이동해서 feature-01 브랜치 삭제

git branch -d feature-01

그러나 작업된 사항이나 commit한 이력이 남아 있는 경우, 해당 command로 branch가 삭제 되지 않는 경우가 있습니다.
이러한 경우에는 강제로 삭제할 수 있습니다.

git branch -D  feature-01 <- -D옵션을 사용함

이 경우, local의 branch는 삭제 되었으나, remote branch는 삭제가 되지 않았습니다. remote branch를 삭제하기 위해서는, 다음과 같은 command를 수행합니다.

git push origin :feature-01

해당 command를 통해서 원격 remote branch를 삭제할 수 있습니다.

Github(https://github.com/) 페이지에서 로그인 후에 새로운 repository 생성 후 로컬에서 작업한 내용을 올리기 위한 명령어 순서입니다.

충돌 시 해결 방법

pull이나 push를 했을 때 원격저장소의 내용과 로컬폴더내의 내용중 같은 라인에 다른 내용이 있다면 이 경우에는 충돌이 발생합니다.
터미널 로그에 충돌이 난 파일이 표시되니 직접 수정 후 다시 pull이나 push를 수행해야 합니다.

가장 좋은 방법은 협업자들끼리 역할을 완전히 분담해 애초에 같은 코드를 건드리지 않는 것이지만, 어쩔 수 없이 그렇게 된다면 항상 작업 전에 pull을 습관화하면 충돌을 최소한으로 줄일 수 있습니다.

풀 리퀘스트 보내기

오픈소스를 만들 때 가장 많이 쓰는 방법입니다.

내가 push한 내용을 repository의 마스터 권한을 가진 사람에게 pull 해달라고 요청합니다. 우선 참여하고 싶은 repository에 들어가 오른쪽 상단의 fork로 나의 repository에 복사합니다.

1.원본 repo의 코드들을 나의 로컬환경에 clone 합니다.

git clone 원본 repositoty 주소

2.포크해온 나의 repo주소를 새로운 이름으로 추가해줍니다.

git remote add 나의 repo 이름 나의 repo 주소

3.현재 등록되어 있는 원격 저장소가 어떤게 있나 확인합니다. 아마 origin이라는 이름의 원본 repo 주소와 새로 설정한 이름의 나의 repo의 주소가 존재할 것입니다.

git remote -v <- 현재 원격 프로젝트 저장소 및 url을 출력해줍니다.

git branch -r <- 원격 저장소 branch 리스트 확인

git branch -a <- 로컬, 원격 저장소의 branch 리스트 확인

4,혹시 모를 코드 변화가 있을 수 있으니 한번 pull해서 확인해줍니다.

git pull origin
  1. 원본 repo에 이슈명이나 키워드로 브랜치를 생성하고 이동합니다.
git checkout -b 브랜치이름(이슈)설정 origin/master

6.모든 작업 후에 6번으로 나의 repo에 푸시합니다.

git push 나의 repo 이름 브랜치 이름

위의 과정 이후에 github에서 fork한 나의 repo에서 방금 푸시한 브랜치명을 선택하면 옆에 pull request 버튼이 생기고, 절차에 따라 누르면 풀리퀘스트가 진행됩니다.

여기서도 충돌이 발생할 수 있으니, 코드를 보며 적절히 수정하면 됩니다.

아래 워너비 스페셜님의 글을 대부분 참조하였습니다.

참조:https://takeuu.tistory.com/103

원격 저장소의 branch 가져오기

현재 원격 저장소에 여러 개의 branch가 있다고 가정합니다. 하지만 원격 저장소의 모든 내용을 pull이나 clone을 받은 후에 git branch로 확인해 보면 원격 저장소의 branch는 받아지지 않고 기존에 있던 master 브랜치 하나만 존재합니다.

먼저 원격 브랜치에 접근하기 위해 git remote를 갱신해줄 필요가 있습니다.

git remote update

위의 상황에 만약 원격 저장소의 feature/test01 branch를 가져오고 싶다면, 아래 명령어를 사용하면 됩니다.

git checkout -t origin/feature/test01

-t옵션과 원격 저장소의 branch 이름을 입력하면 로컬의 동일한 이름의 branch를 생성하면서 해당 branch로 Checkout을 합니다.

만약 branch를 변경하여 가져오고 싶다면 위에서 언급한것 처럼 아래 명령어를 입력하면 됩니다.

git checkout -b 생성할 branch 이름 원격 저장소의 branch 이름

참조 로컬 브랜치로 생성없이 원격 저장소의 브랜치로 바로 Checkout한다면 원격 저장소의 브랜치로 워킹트리로 변경이 됩니다. 하지만 메시지에 detached HEAD 상태이고 소스를 보고 변경도 해볼 수 있지만 이곳에서 변경한 것은 잠시 확인해 보는 용도로 사용될뿐 저장되지 않습니다. 다른 브랜치로 checkout을 하면 사라집니다.

그렇기 때문에 브랜치를 추적하고 싶다면 위의 언급한 명령어인 git checkout -b 생성할브랜치명 원격브랜치명처럼 해줘어야 합니다.
이렇게 하는 이유는 Subversion과는 다르게 git같은 경우는 여러개의 원격저장소를 연결할 수 있고 그중에는 브랜치명이 겹칠 수도 있기 때문으로 보입니다.

Git stash 명령어 사용하기

stash 명령어를 배우기 전에 왜 사용해야 되는지 상황을 설명하겠습니다.
자신이 어떤 작업을 하던 중에 다른 요청이 들어와 하던 작업을 멈추고 잠시 브랜치를 변경해야 할 일이 있다고 합시다. 아직 완료하지 않는 일을 commit하는것은 껄그럽습니다. 이때 stash 기능을 사용하면 됩니다.

스크린샷 2019-11-29 오후 9 11 10

Git stash란?

아직 마무리하지 않는 작업을 스택에 잠시 저장할 수 있도록 하는 명령어 입니다. 이를 통해 아직 완료하지 않는 일을 commit하지 않고 나중에 다시 꺼내와 마무리할 수 있습니다.

  • git stash 명령을 사용하면 워킹 디렉토리에서 수정한 파일들만 저장합니다.

  • stash란 아래에 해당하는 파일들을 보관해두는 장소입니다.

    * Modified이면서 Tracked 상태인 파일

    - Tracked 상태인 파일을 수정한 경우
    - Tracked: 과거에 이미 commit하여 스냅샷에 넣어진 관리 대상 상태의 파일

*Staging Area에 있는 파일(Staged 상태의 파일)

  - git add 명령을 실행한 경우
  - Staged 상태로 만들려면 git add 명령을 실행해야 한다.
  - git add는 파일을 새로 추적할 때도 사용하고 수정한 파일을 Staged 상태로 만들 때도 사용한다.

하던 작업 임시로 저장하기

git stash 명령어를 통해 새로운 stash를 스택에 만들어 하던 작업을 임시로 저장합니다.

  • 예를 들어, 파일 1개를 수정한다면 아직 commit할게 아니기 때문에 stash에 넣습니다.

스크린샷 2019-11-29 오후 9 18 42

위의 명령어 git stash를 실행하면 스택에 새로운 stash가 만들어집니다. 이 과정을 통해서 Working directory는 깨끗해집니다.

stash 목록 확인하기

git stash list 

stash@{0}: WIP on master: 049d078 added the index file

stash 적용하기(했던 작업을 다시 가져오기)

// 가장 최근의 stash를 가져와 적용합니다.
git stash apply 
// stash 이름
git stash apply [stash 이름]

스크린샷 2019-11-29 오후 9 22 11

  • 위의 명령어로는 Staged 상태였던 파일을 자동으로 다시 Staged 상태로 만들어 주지 않는다. –index 옵션을 주어야 Staged 상태까지 복원한다. 이를 통해 원래 작업하던 파일의 상태로 돌아올 수 있다.
git stash apply --index
  • index 옵션 유무의 차이

git stash apply

스크린샷 2019-11-29 오후 9 29 02

git stash apply --index

스크린샷 2019-11-29 오후 9 29 30

수정했던 파일들을 복원할 때 반드시 stash했을 때와 같은 브랜치일 필요는 없습니다. 만약 다른 작업 중이던 브랜치에 이전의 작업들을 추가했을 때 충돌이 있으면 알려줍니다.

stash 제거하기

// 가장 최근의 stash를 제거합니다.
git stash drop

// stash 이름(ex. stash@{2})에 해당하는 stash를 제거한다.
git stash drop [stash 이름]

만약 적용과 동시에 스택에 해당 stash를 제거하고 싶으면 아래와 같은 명령어를 사용합니다.

git stash pop

stash 되돌리기

실수로 잘못 stash 적용한 것을 되돌리고 싶으면 위의 명령어를 이용합니다.

// 가장 최근의 stash를 사용하여 패치를 만들고 그것을 거꾸로 적용한다.
git stash show -p | git apply -R
// stash 이름(ex. stash@{2})에 해당하는 stash를 이용하여 거꾸로 적용한다.
git stash show -p [stash 이름] | git apply -R

TIP alias로 편리하게 사용이 가능합니다.

git config --global alias.stash-unapply '!git stash show -p | git apply -R'
git stash apply
#... work work work
// alias로 등록한 stash 되돌리기 명령어
git stash-unapply

참조:https://gmlwjd9405.github.io/2018/05/18/git-stash.html

'잡다한 것' 카테고리의 다른 글

IntelliJ 자주 사용하는 단축키 정리  (0) 2019.11.24
Dev Festival을 다녀와서...  (0) 2019.11.17
자기소개  (0) 2019.10.03

IntellJ 단축키

개발자에게는 프레임워크 기술에 대한 전반적인 지식과 문제해결능력이 생산성에 가장 직결되는 요소라고 생각하지만 IDE를 잘 다루는 능력 또한 중요하다고 생각합니다.
이러한 이유로 Mac OS 환경을 기준으로 jetbrains에서 만든 IntelliJ에서 자주 사용하는 단축키들을 정리해보았습니다.
참고로 맥에서 command(⌘) 키는 cmd, option(⌥) 키는 alt, control(⌃) 키는 각각 다른 키인것을 안다는 가정하에 정리하였습니다.

cmd(⌘) + N : 현재위치를 기준으로 디렉토리, 패키지 및 생성목록을 보여주는 것 이외에도 생성자/ getter/setter도 보여준다.

cmd(⌘) + P : 해당 클래스가 인스턴스를 생성하기 위해 필요한 인자 값을 확인 가능합니다.

alt(⌥) + space : 특정 메소드의 구현부를 보는 단축키 입니다.

alt(⌥) : Focus를 이동할때 단어별로 이동할때는 옵션(⌥) 키를 누릅니다.

alt(⌥) + 방향 키(^) : 해당 포커스의 단어가 선택됩니다. ^키를 한번 더 누르면 선택이 확장 됩니다. 계층구조로 포커스의 범위가 넓어집니다.

F1 : 키를 누르면 해당 메소드나 클래스의 Doc을 보여줍니다.

Fn + 좌우상하 키: 현재 포커스에서 좌우 상하로 쉽게 이동 가능합니다. 라인 첫/끝 이동, page Up / page Down

Fn + Shift(⇧) : 라인 전체를 선택 가능합니다.

cmd(⌘) + [,] : 이전 포커스 이동, 다음 포커스 이동을 하는 단축키입니다. 다른 클래스 파일에 있는 포커스에도 적용이 가능하기 때문에 클래스 단위로 이동이 가능합니다.

cmd(⌘) + F : 현재 파일에서 특정 문자열을 찾는 단축키 입니다.

cmd(⌘) + Shift(⇧) + F : 프로젝트 전체에서 특정 문자열 검색이 가능합니다.

cmd(⌘) + R : 현재 파일에서 해당 문자열을 변경하는 단축키입니다. 주로 클래스 파일에서 전역변수를 바꿀때 유용합니다.

cmd(⌘) + Shift(⇧) + R : 프로젝트 전체에서 특정 문자열 변경이 가능합니다.

control(⌃) + Shift(⇧) + R : 현재 클래스 파일의 실행 결과를 보여줍니다.

control(⌃) + R : 이전에 실행했던 클래스 파일의 실행 결과를 보여줍니다.

cmd(⌘) + Shift(⇧) + O : 파일 검색을 하는 단축키 입니다.

cmd(⌘) + alt(⌥) + O : getter, setter등 원하는 메소드를 검색하여 찾을 수 있는 단축키 입니다.

cmd(⌘) + Shift(⇧) + A : Action(rename, theme: 등)을 검색할 수 있는 단축키로 저는 주로 파일 명을 변경할 때 사용합니다.

cmd(⌘) + E : 최근에 열었던 파일들의 목록을 볼 수 있습니다.

cmd(⌘) + Shift(⇧) + E : 최근에 수정했던 파일 목록들을 보여줍니다.

Ctrl(⌃) + I : 인터페이스에 있는 추상메소드를 즉 오버라이딩 할 목록을 보여줍니다. Copy and Paste 작업을 할 필요가 없어지는 좋은 단축키입니다.

``cmd(⌘) + J` : 현재 포커스를 기준으로 나올 수 있는 라이브템플릿 축약어들을 보여줍니다. iter,inn,ifn 등이 존재합니다.

cmd(⌘) + alt(⌥) + L : 자동으로 코드를 정렬 해주기 때문에 코드의 가독성이 향상되는 효과가 있습니다. 정말 자주 사용하는 단축키입니다.

cmd(⌘) + alt(⌥) + O : 불필요한 Import 문을 없애주는 단축키 입니다. 마찬가지로 자주 사용되는 단축키입니다.

참고: Action(cmd(⌘) + Shift(⇧) + A) 입력 값에 optimize imports on the fly를 클릭하고 설정을 해주면 자동으로 불필요한 import 문을 없애주기 때문에 사용하지 않는 import문을 개발자가 신경을 안써도 됩니다.

Shift(⇧) + F6 : 클래스, 변수, 파라미터 이름을 일괄적으로 변경해주는 단축키 입니다.

cmd(⌘) + Shift(⇧) + F6: 타입을 일괄적으로 변경 할 수 있습니다. 리턴타입도 자동으로 변경 됩니다.

F6 : Inner Class를 외부로 추출하거나, 다른 클래스의 내부 클래스로 이동 할 수 있습니다.

F2: 에러가 발생한 곳으로 포커스를 이동하는 단축키 입니다.

스마트 자동 완성

Ctrl(⌃) + Shift(⇧) + Space : 클래스의 인스턴스 생성시 나올 수 있는 클래스만 보여주는 단축키입니다. 구글링하지 않고도 들어갈 수 있는 인자값을 넣을 수 있는 장점이 있습니다.

Shift(⇧) + Space*2 : 스태틱 메소드가 자동 완성되는 단축키 입니다.

디버깅 단축키

control(⌃) + Shift(⇧) + D : 현재 위치의 메소드에서 디버그 모드로 실행되는 단축키 입니다.

cmd(⌘) + alt(⌥) + R : Resume 다음 브레이크 포인트로 이동하는 단축키 입니다.

F8 : Step Over 현재 브레이크에서 다음 한줄로 이동하는 단축키

F7 : Step Into 현재 브레이크의 다음 메소드로 이동하는 단축키

Shift(⇧) + F8 : Step Out 현재 메소드 밖으로 이동하는 단축키

alt(⌥) + F8 : Evaluate Expression 브레이크 된 상태에서 코드 사용하는 단축키 입니다.

Watch : 브레이크 이후의 코드 변경을 확인하는 것으로 단축키는 없고 안경모양으로 되어 있습니다.

리팩토링 단축키

정말 IntelliJ에서 제공해주는 가장 최고의 기능 중 하나라고 생각하는 리펙토링을 자동으로 해주는... 대단히 훌륭한 기능이라고 생각해서 따로 뺐습니다. 동작하는 프로그램보다 유지보수가 쉽고 확장성에 대해서 열려있는 기능을 구현하기 위해서는 다른 개발자들이 내 소스를 얼마나 쉽게 읽고 이해 할 수 있는것도 신경쓰는게 정말 중요합니다. 그렇게 하기 위해서는 리팩토링 연습을 꾸준히 해야하는데 인텔리제이에서 제공해주는 단축키를 쓰면 습관을 들이는데 좋은 밑거름이 되지 않을까 싶습니다. 서론이 너무 길었습니다 ㅎㅎ...

cmd(⌘) + alt(⌥) + M : extractMethod로 복잡한 반복문 같은 경우 리팩토링하여 메소드로 뽑아내는 기능입니다. 정말 꿀 같은 기능입니다.

cmd(⌘) + alt(⌥) + V : 파라미터 변수를 생성하고 출력까지 합니다.

cmd(⌘) + alt(⌥) + P : extractVariable 변수를 만들어서 해당 값을 저장하고 출력까지 한번에 가능한 단축키로 마찬가지로 정말 좋은 단축키입니다.

쿼리를 위한 단축키

Ctrl(⌃) + Shift(⇧) + J : 하단에 있는 문자열을 합치는 단축키 입니다. 쿼리문 같은 문자열을 한줄로 합칠때 사용합니다.

Live Template Customizing 하는 방법

이것도 자주 사용하는 기능들을 축약어로 설정하여 빠르게 템플릿을 커스터마이징 해주는 훌륭한 기능입니다. 저 같은 경우에는 TDD를 실천하기 위해서 given, when, then 방식으로 테스트를 수행하기 위해서 tdd 축약어라는 테스트 코드를 라이브 템플릿으로 만들어 봤습니다.

스크린샷 2019-11-24 오후 5 27 45

'잡다한 것' 카테고리의 다른 글

Git- 실전 가이드  (0) 2019.11.29
Dev Festival을 다녀와서...  (0) 2019.11.17
자기소개  (0) 2019.10.03

TDD, 리팩토링

오늘은 이화여대에서 구글 및 다양한 IT기업에서 주최하는 Dev Festoval이 개최를 하여서 같은 개발직종에 종사하고 있는 대학교 친구랑 참가비 1만원을 내고 컨퍼런스에 참여하였습니다.

그중에서 관심있는 세션을 3개정도 들었습니다.
첫번째 세션은 현업에서 종사중인 Lisa라는 분의 빠르고 지속적으로 성장하는 방법에 대한 세션이였습니다.

그중에 가장 인상 깊었던 말씀은 하루에 10분 정도 투자해서 5F 회고를 하시는 거였는데 5F는 아래와 같은 약자를 가지고 있습니다.

5F

  • Fact (사실은 무엇인가?)
  • Feeling (무엇을 느꼈는가?)
  • Find (무엇을 발견하였는가?)
  • Future Action (미래에 해야할 행동)
  • Feed Back (피드백)

나이도 젊으신 개발자였는데 항상 자신의 부족한점을 극복하려고 노력하는 모습이 정말 멋있고 인상 깊으셨습니다.
저도 하루하루 살아가면서 비슷하게나마.. 5F를 실천하려고 노력해야겠습니다.

두번째 세션은 어떤 오픈소스에 참여할까?로 마찬가지로 흥미진진한 세션이였습니다.

이번에는 대학생 신분인데 벌써부터 오픈소스에 기여하여 발표를 하는 것을 보고 나는...이 나이때까지 무엇을 했나... 반 강제적으로 5F를 하게 되었습니다.
주로 깃허브의 중요성을 강조하셨던게 기억이 남았습니다. 깃허브는 개인 프로젝트를 할때 백업용으로도 쓰지만 현업에서는 협업 및 버전관리용으로 쓰는것을 강조하셨고 기본적으로 GIT을 다룰줄 알아야 된다고 강조하셨습니다.

그리고 오픈소스를 참여할때 어떤 오픈소스를 건드려야 될지 좋은 팁을 주셨는데 주로 오픈소스는 최근까지 논의가 활발하게 이루어진 오픈소스에 참여하는게 좋다고 하셨습니다. 최근까지 논의한 오픈소스를 어떻게 판별하는지는 최근까지 오픈소스 관리자의 피드백이 있으면 그 오픈소스는 지금도 활발하게 많은 Contributer가 참여하는 오픈소스이기 때문에 저 자신이 성장할 확률도 높습니다.

그리고 커밋 메시지를 남길때 대충 남기지 말고 그것 자체만으로도 협업하는 개발자들이 이해시킬 수 있도록 작성해야 하는걸 강조하셨습니다.

TDD, 리팩토리의 중요성

마지막으로 제가 들은 세션은.. 사실 이것을 듣기 위해 왔다고 해도 과언이 아닌 우아한테스크코스 교육을 담당하고 계시고 TDD에 관한 책도 저술하신 박재성님의 의식적인 연습으로 TDD, 리팩토링 연습하기 세션을 들었습니다.

기대했던만큼 돈이 아깝지 않을정도로 훌륭한 퀄리티의 세션이였습니다.
제가 앉은 자리는 맨 뒤쪽이여서... 리팩토링을 적용할 코드가 보이지 않았지만 다행히 구글링을 통해서 오늘 세션에서 봤던 리팩토링 예제코드를 보고 분석할 수 있었습니다.

간단하게 리팩토링 예제를 리뷰해보겠습니다.

아래 코드는 어떤 특정 구분자를 가진 문자열 숫자들을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 return 하는 코드입니다.

박재성님은 웹, 모바일 UI나 DB에 의존관계를 가지지 않는 요구사항으로 연습을 해야하고, 회사 프로젝트에 연습하지 말고 장난감 프로젝트를 활용하라고 하셨습니다.

public class StringCalculator {

    public static void main(String[] args) {

        String text = "1,3,5,7,9";


    }

    public static int splitAndSum(String text){
        int result = 0;
        if(text == null || text.isEmpty()){
            return 0;
        }else{
            String[] values = text.split(","); 
            for (String value : values) {
                result += Integer.parseInt(value);
            }
        }
        return result;
    }
}

가장 먼저 위의 코드는 if문과 else문으로 구성이 되어있습니다. 리팩토링에서는 else 예약어를 쓰지 않는것을 지향하고 있습니다.
그리고 splitAndSum()에는 문자열이 비어있는지 검사하고 문자열을 구분자를 기준으로 분리하여 각 숫자의 합을 구하는 등 많은 일들을 하고 있는게 보이고 있습니다.

이 코드를 메소드가 한 가지 일만 하도록 아래와 같이 구현해보겠습니다.

메소드 분리로 리팩토링 적용 후 코드

public class StringCalculator {

    public static void main(String[] args) {

        String text = "1,3,5,7,9";

        System.out.println(splitAndSum(text));
    }

    // 아래 메소드가 한 가지 일만 하도록 구현하고 있습니다.
    public static int splitAndSum(String text){

        if(isBlank(text)){
            return 0;
        }

        return sum(toInt(text.split(",")));
    }

    public static int[] toInt(String[] values){

        int[] numbers = new int[values.length];


        for (int i = 0; i < values.length; i++) {
            numbers[i] = Integer.parseInt(values[i]);
        }
        return numbers;
    }

    public static int sum(int[] numbers){

        int sum = 0;

        for (int number : numbers){
            sum += number;
        }

        return sum;
    }

    public static boolean isBlank(String text){
        return text == null || text.isEmpty();
    }
}

메소드 분리를 통해 리팩토링된 코드를 보면 각 메소드가 하나의 일만 수행하는 것을 알 수가 있습니다.

이것은 compose method 패턴을 적용하여 메소드(함수)의 의도가 잘 드러나도록 동등한 수준의 작업을 하는 여러 단계로 나누었습니다.

확실히 리팩토링을 통해서 이전 코드랑 비교했을때 가독성이 높아진 것을 알 수가 있습니다.

개발자들이 개발을 잘하는것도 중요하지만 돌아가는 프로그램에 초점을 맞추기 보다는 유지보수성과 기능 확장을 위해서 유연한 코드를 작성하는게 중요하다고 다시 한번 이번 세션을 통해 느꼈습니다. 유연한 코드를 작성하가 위해서는 협업하는 사람들이 코드를 읽기 쉽게 작성하는 거랑 일맥상통하는데 이러한 능력을 갖추기 위해서는 한 번에 한 가지 명확하고 구체적인 목표를 가지고 리팩토링을 연습하는 습관을 기르는게 중요하다고 생각합니다.

'잡다한 것' 카테고리의 다른 글

Git- 실전 가이드  (0) 2019.11.29
IntelliJ 자주 사용하는 단축키 정리  (0) 2019.11.24
자기소개  (0) 2019.10.03

안녕하세요. 

웹개발자를 준비하고 있는 주니어 개발자 임준영이라고 합니다.

스프링부트랑 ORM기술에 관심이 많아서 개발공부를 열심히 하고 있습니다.

hexo를 쓰다가 티스토리로 넘어오게 되었는데 앞으로 글 꾸준히 올리겠습니다.

 

'잡다한 것' 카테고리의 다른 글

Git- 실전 가이드  (0) 2019.11.29
IntelliJ 자주 사용하는 단축키 정리  (0) 2019.11.24
Dev Festival을 다녀와서...  (0) 2019.11.17

+ Recent posts