Git 과 GitHub (2부)

GitHub를 사용한다는 것은 자신의 프로젝트를 클라우드에 저장하기 위함이지만 대체로는 여러 개발자가 동시에 개발을 하기 위하여 사용됩니다. 그렇다면, 팀 프로젝트에서 사용되는 명령어는 어떤 것이 있을지 한번 보도록 하겠습니다.

 

해당 글은 1부에서 이어지는 글 입니다. 1부를 읽고 보시면 이해하는데 더욱 도움이 되실 듯 합니다.

 

Git 과 GitHub (1부)

Git이란? Git은 분산 버전 관리 시스템(Distributed Version Control System)입니다. 프로그래머와 소프트웨어 개발 팀이 소스 코드와 파일들의 변경 사항을 추적하고 관리하는 데 사용됩니다. Git은 리누스

jamesblog95.tistory.com


merge, conflict, fast-forward

"Merge"는 Git에서 두 개 이상의 브랜치를 결합하는 작업을 의미합니다. 즉, 독립적으로 개발된 브랜치에서의 변경사항을 하나의 브랜치로 통합하는 것입니다.

 

Git에서 브랜치는 동시에 여러 작업을 수행하기 위해 독립적으로 생성되는 가상의 작업 공간입니다. 예를 들어, 여러 개발자들이 동시에 같은 프로젝트에서 작업할 때 각자의 브랜치에서 개발을 진행하고, 완료된 작업은 다시 메인 브랜치에 통합(merge)하여 최종 결과물을 생성할 수 있습니다.

하지만 이러한 과정에서 같은 코드를 변경을 하게되고 merge를 시도하게 되면 conflict가 발생하게 됩니다. 이러한 경우에는 github에서 또는 IDE에서 제공하는 conflict 해결 기능을 통해 처리 후, merge를 하여야 합니다. 

conflict 난 상황

 

해결 후 merge

 

fast-forward

"Fast-forward"는 Git에서 브랜치를 병합할 때 발생할 수 있는 한 가지 병합 방식입니다. 두 개의 브랜치를 병합할 때, 병합 대상 브랜치가 기준 브랜치의 변경사항을 모두 흡수하고 있어서 추가적인 작업이 필요하지 않을 때 발생하는 병합 방식입니다.

 

이 경우, Git은 단순히 브랜치 포인터를 앞으로 이동시켜 병합을 처리합니다. 기준 브랜치에 있는 최신 커밋으로 브랜치 포인터가 이동하면서, 병합 대상 브랜치가 기준 브랜치의 변경사항을 모두 흡수합니다.

 


clone, fork

Git에서 "clone"과 "fork"는 둘 다 Git 저장소(repository)를 복제하는 작업을 의미하지만 목적과 동작 방식에서 차이가 있습니다.

Clone(복제)

"Clone"은 Git 저장소를 완전히 복제하여 로컬 환경으로 가져오는 작업을 말합니다. 기존 저장소의 모든 히스토리, 브랜치, 태그 및 파일을 복사하여 로컬에서 작업할 수 있게 해줍니다. 즉, 저장소를 다른 곳으로 복제하여 자체적으로 수정하고 관리할 수 있습니다.

 

Fork(포크)

"Fork"는 다른 사람의 Git 저장소를 자신의 GitHub 계정으로 복제하는 작업을 의미합니다. 주로 오픈 소스 프로젝트에서 사용됩니다. 포크를 하면 원본 저장소의 모든 내용이 복제되지만, 포크한 저장소는 독립적으로 관리됩니다. 포크한 저장소에서 변경 사항을 만들거나 추가 기능을 개발하여 별도의 브랜치로 유지할 수 있습니다.

 

Fork 작업은 GitHub과 같은 원격 Git 호스팅 서비스에서만 사용할 수 있으며, 해당 서비스의 웹 인터페이스에서 Fork 버튼을 클릭하면 됩니다. Fork한 저장소는 GitHub 계정 아래에 별도로 생성되며, 이후에는 clone과 동일한 방법으로 로컬 환경으로 가져올 수 있습니다.

 

clone과 fork 는 Merge는 어떻게 이루어 지는가?

clone은 당연히 원본 파일과 연동이 되어있어서 간단하게 push를 통해 수정된 코드를 바로 입력할 수 있습니다. 그렇다면 fork는 어떻게 원본 repository와 연동이 될 수 있을까요? 해당 부분에 대해서 추가적으로 파헤쳐보겠습니다.

 

우선 자신의 GitHub에 fork한 repository를 clone을 하여 로컬에서 작업을 합니다. 이후에 수정된 작업을 다시 fork된 repository로 push를 하면서 원본 repository에 pull request 요청을 하면 원본 repository도 변경이 되게 됩니다. 


tag, fetch

tag:

"Tag"는 Git에서 특정 커밋을 가리키는 정적인 참조 포인터입니다. 주로 특정 시점의 코드를 식별하고 버전을 표시하는 데 사용됩니다. 특히, 소프트웨어 버전 관리에 많이 활용됩니다.

Tag를 사용하여 특정 커밋을 명확하게 식별할 수 있으며, 해당 태그를 통해 해당 커밋을 참조하거나 체크아웃할 수 있습니다. 주로 다음과 같은 상황에서 활용됩니다:

  • 소프트웨어 버전 관리: 소프트웨어 프로젝트에서 특정 버전을 태그하여 해당 버전의 코드를 식별하고, 특정 시점의 소스 코드를 관리합니다. 버그 수정, 기능 추가, 출시 등의 중요한 마일스톤을 나타내는데 사용됩니다.
  • 배포 관리: 소프트웨어를 배포할 때 특정 버전을 태그하여 배포에 사용되는 코드의 상태를 명확히 합니다. 이를 통해 배포된 버전의 코드를 추적하고, 필요한 경우 해당 버전의 코드를 다시 가져올 수 있습니다.

 

fetch:

"Fetch"는 Git에서 원격 저장소로부터 최신 변경사항을 가져오는 작업을 의미합니다. 로컬 저장소가 원격 저장소와 동기화되어 있는지 확인하고, 원격 저장소에 있는 새로운 커밋, 브랜치, 태그 등의 정보를 가져옵니다.


rebase

"Rebase"는 Git에서 브랜치를 이동하거나 병합하기 위해 사용되는 작업입니다. Rebase는 기존 커밋 히스토리를 변경하고, 새로운 커밋 히스토리를 생성합니다.

Rebase를 사용하면 브랜치를 병합하는 과정을 더 선형적으로 만들 수 있습니다. 기존의 브랜치를 따라가며 변경사항을 적용하기 때문에, 병합 커밋이 새로운 커밋으로 대체되는 것이 아니라 새로운 커밋이 생성됩니다. 이를 통해 커밋 히스토리를 깔끔하게 유지하고, 가독성을 높일 수 있습니다.

 

Rebase는 주로 개인적인 브랜치에서 작업한 후, 해당 작업을 메인 브랜치로 통합할 때 사용됩니다. 예를 들어, 다른 개발자가 협업하는 중인 브랜치의 최신 변경사항을 가져오고 싶을 때 Rebase를 사용하여 최신 변경사항을 현재 브랜치에 적용할 수 있습니다.


amend

"Amend"은 Git에서 이전 커밋을 수정하는 작업을 의미합니다. Amend를 사용하면 가장 최근의 커밋에 새로운 변경사항을 추가하거나 커밋 메시지를 수정할 수 있습니다.

첫번째 커밋

 

amend 명령어를 사용한 커밋

Amend를 사용하면 이전 커밋을 수정할 수 있으므로, 특정 커밋의 변경사항이나 메시지를 보완하거나 수정할 수 있습니다. 주로 다음과 같은 상황에서 사용됩니다

  • 최근 커밋에 작은 수정을 추가하고 싶은 경우 (예: 오타 수정)
  • 최근 커밋의 메시지를 보완하거나 더 명확하게 작성하고 싶은 경우
  • 스테이징 영역에 있는 변경사항을 가장 최근의 커밋에 추가하고 싶은 경우

cherry-pick

"Cherry-pick"은 Git에서 특정 커밋을 선택하여 다른 브랜치로 가져오는 작업을 의미합니다. Cherry-pick을 사용하면 원하는 커밋만을 선택하여 다른 브랜치에 적용할 수 있습니다.

Cherry-pick을 사용하면 선택한 커밋의 변경사항을 현재 브랜치에 적용할 수 있습니다. 선택한 커밋의 변경사항을 새로운 커밋으로 생성하며, 원본 커밋의 기록을 유지합니다. Cherry-pick은 주로 다음과 같은 상황에서 사용됩니다.

  • 다른 브랜치에서 작업한 특정 커밋을 현재 브랜치에 가져와야 할 때
  • 특정 커밋의 변경사항을 반복하여 다른 브랜치에 적용해야 할 때

 

Cherry-pick을 사용하면 특정 커밋의 변경사항을 다른 브랜치로 선택적으로 가져올 수 있어서 유연성이 높습니다. 그러나 Cherry-pick은 커밋을 선택적으로 적용하는 작업이므로, 커밋 히스토리의 일관성과 충돌 가능성을 고려하여 사용해야 합니다.


reset

"Reset"은 Git에서 이전 커밋으로 HEAD를 이동시키거나, 작업 디렉토리와 인덱스의 상태를 변경하는 작업을 의미합니다. Reset을 사용하면 이전 커밋의 상태로 작업 트리를 되돌릴 수 있습니다.

reset 전
reset 후

Reset 작업은 다음과 같은 세 가지 모드로 수행될 수 있습니다: mixed, soft, hard.

 

Mixed Reset:

  • git reset --mixed <대상 커밋> 명령을 사용하여 수행합니다.
  • 기본적으로 Reset 명령은 mixed 모드로 동작합니다.
  • HEAD를 대상 커밋으로 이동시키고, 인덱스(Staging Area)를 대상 커밋의 상태로 리셋합니다. 작업 디렉토리는 변경사항을 유지한 채로 남습니다.
  • 이전 커밋의 변경사항을 다시 스테이징 영역에 추가하거나 새로운 커밋을 만들기 위해 작업 디렉토리를 정리하는 데 사용됩니다.

Soft Reset:

  • git reset --soft <대상 커밋> 명령을 사용하여 수행합니다.
  • HEAD를 대상 커밋으로 이동시키고, 인덱스와 작업 디렉토리는 변경사항을 유지한 채로 남깁니다.
  • 이전 커밋의 변경사항을 그대로 유지한 채로 새로운 커밋을 생성하거나, 커밋 메시지를 수정하기 위해 사용됩니다.

Hard Reset:

git reset --hard <대상 커밋> 명령을 사용하여 수행합니다.

HEAD를 대상 커밋으로 이동시키고, 인덱스와 작업 디렉토리를 대상 커밋의 상태로 완전히 리셋합니다. 이전 커밋의 변경사항은 삭제됩니다.

주의해야 할 점은 hard reset을 사용하면 작업 디렉토리에 있던 변경사항이 완전히 삭제되기 때문에, 되돌릴 수 없는 상태로 변경될 수 있습니다. 따라서 주의하여 사용해야 합니다.

이러한 Reset 모드들을 적절하게 선택하여 작업 트리를 원하는 상태로 변경하거나 커밋을 조작할 수 있습니다. 주의해서 사용해야 하며, 특히 hard reset을 사용할 때는 데이터의 손실 가능성을 염두에 두어야 합니다.


revert

"Revert"는 Git에서 이전 커밋을 취소하는 작업을 의미합니다. Revert를 사용하면 이미 존재하는 커밋을 취소하고, 해당 커밋의 변경사항을 취소하는 새로운 커밋을 생성할 수 있습니다.

revert 전
revert 후

Revert를 사용하면 이미 존재하는 커밋을 취소할 수 있으므로, 커밋 히스토리를 변경하지 않고도 이전 변경사항을 되돌릴 수 있습니다. Revert는 주로 다음과 같은 상황에서 사용됩니다.

  • 잘못된 커밋을 취소하고, 해당 커밋의 변경사항을 복구해야 할 때
  • 특정 커밋의 변경사항이 문제를 일으키거나 충돌을 일으킬 때

Revert를 사용하면 커밋을 취소하는 새로운 커밋을 생성하므로, 커밋 히스토리는 변경되지만 기존 커밋은 유지됩니다. 이를 통해 작업 히스토리의 추적과 변경사항의 롤백을 용이하게 할 수 있습니다.


stash

"Stash"는 Git에서 작업 중인 변경사항을 임시로 저장하고 나중에 다시 적용할 수 있는 기능을 제공하는 것을 말합니다. Stash를 사용하면 아직 커밋하지 않은 변경사항을 임시로 보관하고, 작업 디렉토리를 이전 상태로 되돌릴 수 있습니다.

stash save시
이후 commit
stash apply시

Stash는 작업 중인 변경사항을 일시적으로 보관하여 다른 브랜치로 전환하거나 충돌을 해결하는 등의 작업을 수행할 때 유용합니다. 작업 중인 변경사항을 커밋하지 않고 저장하고 싶을 때 사용할 수 있습니다.

 

Stash 작업은 변경사항을 스택(stack)에 저장하기 때문에, 여러 개의 stash를 생성하여 차례로 적용할 수도 있습니다. 이를 통해 작업 중인 다양한 변경사항을 관리하고, 필요한 시점에서 다시 적용할 수 있습니다.

 

Stash는 개인적인 브랜치에서 작업하는 동안 변경사항을 임시로 저장하고, 다른 브랜치로 전환하여 작업을 수행하거나 이전 상태로 되돌리고자 할 때 매우 유용합니다.

'Infra > Git-GitHub' 카테고리의 다른 글

Git 과 GitHub (1부)  (0) 2023.06.20