본문 바로가기

프로그래밍/Git

Git의 주요 명령어

모든 깃 명령어를 사용하기 전에는 git init를 이용해 해당 디렉토리를 이용해 버전관리를 하겠다고 선언해야 한다.

git init 사용시 화면


git (명령어) --help를 활용하면 해당 명령에 대한 추가적인 옵션들에 대한 리스트를 웹을 통해 볼 수 있게 된다.

git을 처음 설치 후 cmd를 활용해 운용을 한다면 한글이 전부 깨진 상태로 출력되는 것을 확인할 수 있는데 이는 명령 프롬프트 자체의 언어 인코딩 설정이 된 상태가 아니기 때문에 발생하는 문제다.

한글 출력을 정상적으로 수행하도록 하기 위해서는 컴퓨터의 환경변수에 UTF-8을 새로 추가해주는 과정을 거쳐야 한다.

 

주요 명령어

git status / git add / git commit / git remote / git push / git pull / git reset

git revert / git branch / git merge / git rebase / git cherry-pick

 

1. git status

  • 현재 커밋이 필요한 가지 등 여러 상태들을 표시해준다.
  • 빨간 글씨일 경우 깃이 아직 관리를 시작하지 않은(Untracked) 상태라는 것을 의미한다.
  • .idea/나 .vscode/와 같은 폴더들은 작성 프로그램에 따라 다르기 때문에 크게 신경쓸 필요는 없다. 또한 앞에 .이 붙는다면 평소에는 숨기는 파일이라는 것을 의미한다.
  • 일반적으로 보안에 위협을 초래하는 중요한 파일들은 git을 통해 관리하지 않는 것을 권장한다.

초기화 후 곧장 git status명령 시 나타나는 화면


 

2. git add

  • 명령 사용시 커밋 대기 상태로 관리할 파일을 전환시켜준다. 간단히 말해 업로드 대기라고 보면 된다.

git add . 명령을 통한 업로드


  • 이는 곧 Untracked(빨강)에서 Staged(초록)로 올라갔다는 것을 의마한다.
  • warning이 출력될 수도 있는데 이는 주의정도로 error가 아니니 무시해도 무방하다.
  • 커밋 대기된 파일을 다시 되돌리고자 한다면 rm --cached 파일명 을 이용하면 되는데 이 때 --cached를 붙이지 않을 경우 종종 원본 파일이 삭제되는 경우가 발생할 수도 있기 때문에 꼭 붙여주는 것이 좋다.
  • 여러 가지 파일들을 한 번에 올리고 싶다면 git add .을 이용하면 된다.
  • .vscode나 .idea폴더 등을 관리하고싶지 않을 경우 .gitignore파일을 생성 후 내부에 .idea등 무시하고 싶은 폴더나 파일을 기입해준 다음 .gitignore를 관리해주면 된다.
  • .gitignore를 통해 무시하려 할 경우에도 이미 해당 파일이 커밋된 후에는 무시하지 못하게 된다. 이 때는 다시 커밋되었던 파일 또는 폴더를 제거해준 후 .gitignore에 재작성해 커밋하면 정상적으로 관리하지 않도록 만들어줄 수 있게 된다.

수정된 폴더가 Staged상태임과 동시에 Unstaged상태


  • 위 경우에서 볼 수 있듯이 Changes not staged for commit이 발생할 수 있다. 위 경우 Staged상태이며 동시에 Unstaged상태로 나온다. 이는 해당 파일 또는 폴더가 이미 커밋된 적이 있다는 것을 의미하며 추가적인 커밋요청이 아직 이루어지지 않았음을 의미한다.

 

3. git commit

  • 책갈피를 등록한다는 느낌으로 깃에게 추후 문제가 있을 경우 돌아올 수 있는 지점을 저장하는 명령이다. 백업과 비슷하다고도 볼 수 있다.

git commit명령을 수행했을 시 나타나는 화면


  • commit명령을 내리게 되면 위 캡쳐와 같은 화면이 나오게 되며 기본적인 입력 방식은 vi에디터의 방식을 따르게 된다.
  • esc를 통해 명령어 입력창으로 내려갈 수 있으며 :wq를 기입해줄 경우 write & quit, 즉 저장 후 vi에디터 화면을 나갈 수 있게 된다.


  • vi에디터를 생략하며 커밋을 진행하고 싶을 경우 위 명령어를 기입해주면 되며 ~~부분에 원하는 제목을 넣어주면 된다.

commit을 진행한 후의 로그 화면


  • 변경 사항을 add 후 commit을 할 경우 많은 과정을 거치며 효율이 떨어질 수 있다. 이를 해결하기 위해서 사용할 수 있는 방법으로는 git commit -a명령이 있다. 이는 add와 commit을 한 번에 수행할 수 있도록 해주며 커밋이 필요한 모든 파일들을 한 번에 커밋해준다.
  • git commit -a에 더해 -am "~~"을 해주면 뒤의 ~~부분에 원하는 메시지를 붙여줄 수 있다. 이 옵션을 붙여주지 않을 경우 vi에디터 화면으로 전환된다.
  • 특정 파일만 커밋하고자 할 경우 -a대신 해당 파일명을 적어주면 된다.
  • 커밋 메시지를 작성할 때는 어떤 부분을 수정했는지에 대해 상세하게 적어주는 것이 아주 좋다. 그렇지 않다면 협업 시 어떤 부분을 수정했는지에 대해 이해하는 것에 추가적인 시간을 소요하게 되며 또한 효율이 떨어지게 되는 부작용을 낳게 된다.

 

4. git remote

  • git remote add 리모트명 주소 명령을 통해 원하는 리모트 이름으로 등록하고자 하는 주소를 깃에게 기억하도록 할 수 있다.
  • remote는 단순히 생각해본다면 메일에서의 주소록과 비슷하다.

git remote add <리모트명> <주소>를 통해 해당 주소를 remote리스트에 넣어줄 수 있다


  • get-url 옵션을 사용한다면 각 리모트에 대해 어떤 주소가 등록되어 있는지 확인이 가능하다.

git remote get-url <리모트명>을 사용해 주소를 확인할 수 있다


  • 적어도 하나의 리모트를 등록하고 난 다음이라면 git remote만 입력하게 되면 여태까지 등록해놓은 모든 리모트들을 리스트 형태로 확인할 수 있다.

git remote를 통해 연결된 리모트들을 확인 가능하다


 

5. git push

  • git push 리모트명 브랜치명 명령을 사용하게 되면 remote를 통해 등록한 주소로 여태까지 커밋했던 내역들이 보내지게 된다.

git push origin master명령을 통해 깃허브로 커밋내용을 보낸다


 

6. git pull

  • git pull을 사용하게 되면 기존 깃허브 등 서버에 커밋되어있는 상태와 현재 개인 컴퓨터와의 동기화를 실행하게 된다.
  • 이 때 두 사용자(깃허브와 개인)간 log history가 다른 상태, 즉 서로 관련된 기록이 없는 이질적인 두 프로젝트를 병합하고자 할 때는 아래의 명령을 사용하게 되면 병합을 수행해준다.
git pull 리모트명 브랜치명 --allow-unrelated-histories

서로 연관되지 않은 가지기 때문에 발생한 문제
--allow-unrelated-histories옵션을 적용해 두개의 가지를 하나의 가지로 병합시켰다


  • 깃을 데스크탑과 랩탑에서 각각 합병하는 과정에서 한 가지 사실을 깨닫게 되었다. 그것은 PersonalPractice와 같이 폴더로 되어있는 것은 해당 폴더가 최상위폴더로서 Github폴더가 아닌 해당 폴더에 들어간 후 git init명령을 수행해야 한다는 것이었다.
  • 위 사실을 제대로 인지하지 못한 상태로 계속 커밋을 시도했기 때문에 위 병합문제 등이 발생하게 된 것이었다.
  • git pull명령은 git merge와 git fetch명령을 통합해 사용하는 명령이다.

 

*git fetch

  • pull명령을 수행했을 경우의 서버의 내용과 개인 pc 내 프로젝트 내용이 완전히 겹쳐져버리는 것과는 달리 merge과정이 생략된 채로 branch내용만 따로 불러오도록 만들어주는 명령이다.
  • 곧장 서버와 pc를 동기화시키는 것이 아닌 기존 pc의 프로젝트 내용과 서버에 기록되어 있는 내용의 차이를 비교해보고자 할 때 유용하게 활용 가능한 명령이다.
  • 보통은 자주 사용하지 않고 pull을 통해 바로 병합까지 수행하는 경우가 많다.

 

7. git reset

  • 기존의 add된 Staged상태인 커밋을 원래대로 Modified, 나아가 Unmodified로 만들고자 할 때 주로 쓰이는 명령이다.
  • 보통 옵션과 reset사이에는 HEAD를 추가적으로 넣어주며 이는 제일 위 커밋부터 몇번째 커밋까지를 되돌릴지 알려주기 위한 옵션이다.
  • 특별한 옵션을 추가하지 않는다면 기본적으로는 mixed가 되며 이는 커밋을 Modified상태로 만들게 된다.
  • soft 옵션을 부여한 상태로 reset 명령을 내리게 되면 커밋은 Unstaged상태로 돌아가게 된다.
  • hard 옵션을 부여한 상태로 reset 명령을 내리게 되면 커밋은 Unmodified상태로 돌아간다.
  • reset을 수행할 때 유의할 점은 깃허브 등 원격 서버에 미리 push해놓은 후 개인 컴퓨터에서 reset을 수행하게 되면 원격서버에 로그가 남게 되어 추후에 다시 복구할 수 있지만, 원격서버에 보내놓지 않은 상태로 reset을 하게되면 그대로 해당 커밋이 사라지게 된다는 것이다.

 

8. git revert

  • commit된 사실을 되돌리도록 하는 명령이다.

revert명령을 수행했을 경우 로그에 남는다

  • reset과는 다르게 되돌리는 과정 자체를 또다른 커밋으로 만들어준다. 이는 곧 reset은 log에 남지 않도록 아예 지워버리는 것이지만 revert는 log에 revert되었다는 사실 자체도 기록하는 것이다.
  • 협업을 진행할 때 주로 reset보다는 revert를 많이 사용하는데 이 실수한 사실을 같은 팀원들에게도 알림으로써 commit을 해당 버전으로 관리하도록 만들어줄 수 있기 때문이다.
  • 협업시에는 무조건 revert만 사용하도록 강제하는 것이 팀원들간 커밋 꼬이지 않도록 만들어주는것이 무조건 좋다고 생각하면 된다.
  • github에 올라간 커밋은 기본적으로는 되돌릴 수 없다고 생각하도록 하자. 예외적으로 falsepush나 reflog명령으로 해당 커밋을 제거할 수 있지만, 의도하지 않은 심각한 오류가 발생할 수 있기 때문에 revert같은 명령을 통해 되돌리는 것을 더 권장한다.

 

9. git branch

  • Git이 SVN이나 Mercurial보다 더 강력한 성능을 보유하게 만들어주는 시스템이다.
  • 주로 기존의 작업이 있어 커밋을 한 후 기존의 방법이 아닌 새로운 방법을 시도하고 싶을 때 새로운 방법의 가지를 만들 때 사용하게 된다. 마치 나무의 나뭇가지처럼 방법의 가짓수를 늘려주는 역할을 한다.
  • 각 가지들은 독자적으로 운용할 수도 있으며 그와 동시에 master 가지에 다시 합치는 것도 가능하다.
  • branch명령을 수행하다보면 각 commit들 간의 충돌이 발생할 가능성이 항상 존재하니 버전관리에 주의가 필요하다.

branch명령을 이용해 새로운 가지를 생성한다

  • 예를 들어 새로운 가지 'testbranch'를 생성했다면 해당 가지로 이동하고자 할 때는 git checkout testbranch와 같이 명령을 입력해주면 해당 가지로 넘어갈 수 있게 된다.

checkout명령을 통해 가지를 변경한다

*checkout명령은 두 가지 기능을 가지고 있다.

  1) 가지를 전환하는 기능

git checkout <가지명>

  2) 파일의 상태를 Staged에서 Modified로 만들어주는 기능

git checkout HEAD<~되돌릴 커밋 수>
  • 배포버전을 master가지에 두고 새로운 버전 개발을 다른 가지에 두고 개발을 진행하는 식으로 응용이 가능하다.
  • branch를 통한 작업을 할 때는 꼭 작업 시작 전에 branch명령으로 내가 어떤 가지에 위치해있는지를 확인해야 한다. 그렇지 않을 경우 master에 그대로 commit을 보내게 되는 경우도 발생할 수 있다.
  • 또한 매 작업을 시작하기 전에는 git pull origin master명령을 실행시켜 깃의 변동사항을 항상 받아와야 한다. 그렇지 않으면 버전간 충돌이 발생할 수 있다.
  • 작업의 가지를 관리할 때는 기본적으로 master가지가 가장 중요한 작업을 담당한다. 하지만 굳이 master를 가장 중요하게 두지 않고 임의의 다른 가지에 가장 중요한 작업을 관리해도 상관이 없다. 단지 default값이 master가지일 뿐이다.
  • 특정 가지를 버리고 싶을 경우 git branch -D <가지명>명령을 사용하면 된다.
git branch -D <branch name>

 

10. git merge

  • 가지로 나뉘어져있는 새로운 작업이 master에 합쳐지는 것보다는 master, 또는 받는 쪽에서 해당 가지를 다시 흡수하는 방식이라 이해해두는 것이 좋다.
  • merge를 하는 과정에서는 conflicts 등 오류가 자주 일어날 수 있기 때문에 버전을 최신상태로 유지하는 것이 아주 중요하다.
  • 만일 이미 서로 다른 가지를 뻗어나가 한 가지를 선택하기에 곤란할 경우 git merge --abort 명령을 내리게 되면 현재 진행하려 했던 병합 작업을 포기하고 서로 별개의 가지상태로 두게 된다.
  • 해당 파일을 둘 중 하나로 선택하는 것이 아닌 같은 파일명의 새로운 버전을 작성해 제 3의 선택지로 만들어 넣어주고자 한다면 add작업을 통해 해당 버전을 넣어주어 confilct를 해결하는 방법도 존재한다.

 

11. git rebase

  • git merge와 같은 의도로 쓰이는 명령이다.
  • merge와 마찬가지로 conflict등의 오류는 자동으로 해결되지 않고 팀원과 상의하는 등의 개별 해결책을 마련해야 한다.
  • 충돌을 해결할 제 3의 파일을 생성하는데 성공했다면 add명령을 통해 commit대기상태로 만든 후                    git rebase --continue명령을 내려 conflict를 해결할 수 있게 된다.
  • rebase는 merge와 같이 병합이 이루어지는데 merge와 다른 점은 merge는 해당 가지의 독자적인 진행 과정과 master의 진행과정이 그대로 보존되는 상태에서 가지가 합쳐지는 것을 보여주는데 rebase는 master의 진행 과정을 담은 commit이 사라지며 가지의 log만 남게 된다는 차이가 있다.
  • 한 라인으로 깔끔한 커밋관리를 원할 경우 rebase가 더 유용할 수 있다.

 

12. git cherry-pick

  • master에서 작업물을 가져오고자 할 때 기존에는 merge나 rebase를 했는데 안중요한 수정사항은 제외하고 중요한 수정사항만 불러오고 싶은 경우가 존재한다.
  • cherry-pick은 중요한 수정사항 등 자신이 원하는 커밋 내용만 선택해서 불러올 수 있도록 만들어주는 기능이다.
git cherry-pick <커밋 아이디>
  • cherry-pick 명령도 기존 두 명령과 마찬가지로 conflict 오류가 발생할 수 있다.
  • cherry-pick을 사용하기 위해 커밋 아이디를 찾는 일은 매우 불편하다. 이를 해결할 수 있는 방법으로는 태그를 지정해주는 것이다.

 

* git tag

  • 현재 가장 최신 커밋에 원하는 이름의 태그를 붙여줄 수 있다. 이를 활용한다면 바로 위의 cherry-pick나 reset과 같은 특정 커밋을 찾아야 할 때 아이디 대신 태그 이름을 넣을 수 있게 되어 훨씬 버전관리가 쉬워지게 된다.
git tag <태그 이름>
  • 예를 들어 특정 위치에 태그를 기록해둔 후 개발을 진행하던 중 예상치 못한 오류가 발생해 해당 위치로 돌아가고자 한다면 git reset "해당 태그명"을 통해 태그 위의 기록은 날리는 등의 작업을 더 쉽게 진행할 수 있게 된다.
  • 중요한 커밋들에는 태그를 붙여두는 것이 좋다.

 

* git stash

  • 임시저장과 비슷한 느낌의 기능을 한다.
  • 작업 중 올바르지 않은 가지에서 작업을 진행해 임시저장 후 원래의 가지에서 다시 apply를 통해 불러오는 등의 활용이 가능하다.
  • stash명령을 활용하게 된다면 진행중이었던 작업을 버리거나 commit을 통해 억지로 저장하지 않고도 가지 사이를 이동하는 등의 활동을 진행할 수 있게 된다.
git stash
  • 따로 하고자 했던 작업이 끝나게 되면 다시 git stash apply 명령을 내려주며 임시저장해두었던 커밋 내용을 불러올 수 있게 된다.
  • 여러 가지들 모두에게 stash를 통해 작업물을 여러 개 임시저장하는 것도 가능하다.
  • 저장한 stash를 지우고자 한다면 git stash drop을, stash를 적용 후 지우고자 한다면 git stash pop명령을 부여하면 된다.

'프로그래밍 > Git' 카테고리의 다른 글

Git Flow와 GitHub Flow의 이해  (1) 2019.10.31