Project.log

WebDevCurriculum / 형상관리 시스템 본문

ETC

WebDevCurriculum / 형상관리 시스템

jinuk_ 2023. 5. 4. 23:11
728x90
반응형

Knowre-Dev의 WebDevCurriculum의 레포지토리를 Fork하여 퀘스트를 해결해 나가는 글입니다.

Introduction

  • git은 2021년 현재 개발 생태계에서 가장 각광받고 있는 버전 관리 시스템입니다. 이번 퀘스트를 통해 git의 기초적인 사용법을 알아볼 예정입니다.

Checklist

  • 형상관리 시스템은 왜 나오게 되었을까요?

형상관리의 단어가 생소해서 단어부터 찾아보았습니다.

"소프트웨어 구성 관리 또는 형상 관리는 소프트웨어의 변경사항을 체계적으로 추적하고 통제하는 것으로, 형상 관리는 일반적인 단순 버전관리 기반의 소프트웨어 운용을 좀 더 포괄적인 학술 분야의 형태로 넓히는 근간을 이야기한다."

라고 되있습니다.

 

형상 관리 시스템은 소프트웨어 개발 프로세스에서 발생하는 문제를 해결하기 위해 만들어진것 같습니다.

과거에는 소프트웨어 개발이 단순히 하나의 프로그래머가 작업을 하는 경우가 많았습니다. 이런 경우에는 소스 코드를 직접 관리할 수 있었습니다. 하지만 소프트웨어 개발이 복잡해지면서 다수의 개발자들이 함께 작업하는 경우가 많아지면서 소스 코드의 관리가 어려워졌습니다.

여러 명의 개발자들이 동시에 작업을 하다 보면 각자의 버전을 관리하기가 어려워지고, 파일을 분산시키거나 삭제하는 등의 문제가 발생할 수 있습니다. 이러한 문제를 해결하기 위해 형상 관리 시스템이 만들어졌다고 합니다.

형상 관리 시스템은 파일 버전 관리, 변경 이력 추적, 파일 공유, 코드 병합, 충돌 해결 등을 제공하여 여러 명의 개발자들이 함께 작업할 때 소스 코드를 효과적으로 관리할 수 있게 해줍니다. 이로써 소프트웨어 개발의 효율성을 높이고, 소프트웨어 개발 과정에서 발생하는 문제를 최소화할 수 있게 됩니다.

 

  • git은 어떤 형상관리 시스템이고 어떤 특징을 가지고 있을까요? 분산형 형상관리 시스템이란 무엇일까요?

git은 분산형 버전 관리 시스템으로, 소프트웨어 개발에서 가장 많이 사용되는 형상 관리 시스템 중 하나입니다. git은 2005년 리누스 토발즈가 개발하였으며, 빠른 속도, 단순한 구조, 분산형 관리 등의 특징으로 널리 사용되고 있습니다.

  1. 분산형 버전 관리 시스템: git은 중앙 서버가 없는 분산형 버전 관리 시스템입니다. 이는 개발자들이 서로 독립적으로 작업하며, 각각의 로컬 저장소에서 작업 내용을 관리하고 이를 다른 개발자들과 공유할 수 있다는 것을 의미합니다.
  2. 빠른 속도: git은 파일 버전을 빠르게 관리할 수 있는 빠른 속도를 가지고 있습니다. 이는 파일 변경 내용을 스냅샷 형태로 저장하고, 변경된 파일만을 추적하므로 빠른 속도를 보장합니다.
  3. 유연한 브랜치 관리: git은 브랜치를 자유롭게 생성하고 관리할 수 있습니다. 이를 통해 개발자들은 자신이 원하는 브랜치를 만들어서 작업할 수 있으며, 여러 개발자들이 같은 파일을 동시에 작업할 때 충돌을 최소화할 수 있습니다.
  4. 변경 이력 추적: git은 파일 변경 이력을 자세하게 추적할 수 있습니다. 파일 변경 내용, 작업자, 작업 시간 등을 모두 기록하기 때문에, 문제가 발생했을 때 누가 언제 어떤 작업을 했는지를 확인할 수 있습니다.
  5. 다양한 협업 기능: git은 여러 개발자들이 함께 작업할 때 협업에 필요한 기능을 제공합니다. 예를 들어, 코드 리뷰, 이슈 관리, 메시지 전송 등의 기능을 제공하여 개발자들 간의 의사소통과 협업을 용이하게 해줍니다.
  6. 오픈소스: git은 오픈소스로 개발되어 있기 때문에 누구나 소스 코드를 열람하고 수정할 수 있습니다. 이는 개발자들이 필요에 따라 git을 커스터마이징하거나 개선할 수 있게 해줍니다.

 

    • git은 어떻게 개발되게 되었을까요? git이 분산형 시스템을 채택한 이유는 무엇일까요?

git은 2005년에 리누스 토발즈가 리눅스 커널의 소스 코드 버전 관리 시스템으로 개발하기 위해 시작되었습니다. 그 당시 리눅스 커널은 BitKeeper라는 상용 버전 관리 시스템을 사용하고 있었는데, 무료로 사용할 수 없는 라이선스 변경으로 인해 리누스 토발즈는 새로운 버전 관리 시스템을 찾아야 했습니다.

리누스 토발즈는 BitKeeper와 같은 중앙집중식 시스템이 문제가 될 수 있다는 것을 알고 있었습니다. 중앙 집중식 시스템은 하나의 서버에 모든 소스 코드를 저장하고, 개발자들은 이 서버에 접속하여 소스 코드를 다운로드하고 수정한 후, 다시 서버에 업로드하는 방식으로 동작합니다. 이 방식은 개발자들이 동시에 작업할 때 충돌이 발생할 가능성이 높으며, 서버가 다운되거나 손상될 경우 소스 코드를 복구하기 어렵습니다.

그래서 리누스 토발즈는 분산형 시스템을 채택하기로 결정했습니다. 분산형 시스템은 모든 개발자가 로컬 컴퓨터에 소스 코드를 저장하고, 이를 서로 공유함으로써 동시 작업 문제와 서버 다운 문제를 해결할 수 있습니다. 또한, 개발자가 서로 다른 버전을 작업하는 경우에도 소스 코드를 병합하는 과정을 통해 충돌을 최소화할 수 있습니다.

 

  • git과 GitHub은 어떻게 다를까요?

git은 분산 버전 관리 시스템으로, 소스 코드의 버전을 관리하는 도구입니다. git을 사용하면 여러 개발자가 동시에 작업하고, 각자의 작업 내용을 버전으로 관리할 수 있습니다. git은 로컬 컴퓨터에서 동작하며, 사용자는 커맨드 라인 또는 GUI 도구를 사용하여 Git을 제어할 수 있습니다.따라서 git과 GitHub은 같은 프로젝트 관리에 사용되지만, git은 로컬에서 버전 관리를 수행하고, gitHub은 클라우드 기반 협업을 위한 서비스입니다. 

gitHub은 git을 기반으로 한 웹 기반 호스팅 서비스입니다. gitHub을 사용하면 git으로 관리하는 소스 코드를 클라우드에 업로드하여 다른 개발자와 협업할 수 있습니다. gitHub은 다양한 소스 코드 호스팅 기능뿐만 아니라, 이슈 트래킹, 웹페이지 호스팅, CI/CD 등 다양한 개발 관련 기능을 제공합니다. 또한, gitHub은 개인 무료 저장소 및 공개 저장소를 지원하고 있어, 개발자들이 오픈소스 프로젝트를 공유하고 협업하는 데 매우 유용합니다.

 

  • git의 clone/add/commit/push/pull/branch/stash 명령은 무엇이며 어떨 때 이용하나요? 그리고 어떻게 사용하나요?

clone: git 저장소를 복제하여 로컬 컴퓨터에 가져옵니다. 새로운 프로젝트를 시작하거나, 다른 개발자의 코드를 가져와 협업할 때 사용합니다. 

$ git clone [저장소 URL] [DIR]

[저장소 URL]에는 클론해올 저장소의 주소를 지정해줍니다. [DIR] 인자는 저장소를 로컬에 복제할 위치를 지정합니다. [DIR] 생략 가능하며, 특별한 이유가 없다면 보통 생략합니다.

 

add: 작업 디렉토리의 변경 사항을 스테이징 영역에 추가합니다. 새로 생성한 파일이나 수정된 파일 등 변경 사항을 스테이징 영역에 추가하여, 커밋을 수행하기 전에 변경 사항을 검토하거나 분리하여 커밋을 수행할 수 있습니다.

# 작업 디렉토리의 변경 내용의 일부만 스테이징 영역에 넘기고 싶을 때
$ git add [파일명]
   
# 작업 디렉토리 내의 모든 변경 내용을 전부 스테이징 영역으로 넘기고 싶을 때
$ git add -A 
   
# 현재 디렉토리의 모든 변경 내용을 스테이징 영역으로 넘기고 싶을 때
$ git add .

 

commit: 스테이징 영역에 추가된 변경 사항을 저장소에 (기록)커밋합니다. 변경 사항에 대한 설명을 커밋 메시지로 함께 작성해야 합니다.

$ git commit -m "commit message"

 

push: 로컬 저장소의 변경 사항을 원격 저장소에 업로드합니다. 협업을 위해 다른 개발자들과 변경 사항을 공유하거나, 클라우드 기반 저장소에 백업할 때 사용합니다.

$ git push [저장소명] [브랜치명]
$ git push origin master
   
# 현재 프로젝트에 등록된 리모트 저장소를 확인할 수 있다.
$ git remote
   
# -u 옵션은 최초 한번만 저장소명, 브랜치명을 입력하고 이후에는 git push만 사용해도 되게 해준다.
$ git push -u origin master
   
# 가급적 사용하지 말것, 지양해야 할 행위
# -f 옵션으로 강제로 현재 로컬 저장소의 변경사항을 원격 저장소에 덮어씌우는 행위
$ git push -f origin master

 

pull:원격 저장소의 변경 사항을 로컬 저장소로 가져옵니다. 다른 개발자들이 작성한 변경 사항을 로컬 저장소에 반영하거나, 로컬 저장소와 원격 저장소 간의 일관성을 유지하기 위해 사용합니다.

$ git pull
   
# pull은 아래 두가지로 분류될 수 있다
$ git fetch
$ git diff HEAD origin master # 이거는 fetch해서 가져온 변경사항과 현재 내 저장소를 비교해주는 명령어
$ git merge

 

branch: 독립적인 작업 영역을 만들기 위해 브랜치를 생성합니다. 각 브랜치는 서로 독립적으로 변경 사항을 관리할 수 있어, 복잡한 프로젝트의 경우 여러 개의 브랜치를 사용하여 개발을 진행합니다.

$ git branch # 브랜치 목록을 불러오기.

$ git branch [-a] [-d] [-m] [-r] [--merged] [--no-merged] [<branch_name>]

# 주요 옵션들
-a : 로컬 저장소와 원격 저장소의 모든 브랜치를 보여줍니다.
-d : 브랜치를 삭제합니다. 삭제하려는 브랜치가 현재 checkout된 브랜치가 아니면 삭제할 수 있습니다.
-m : 브랜치의 이름을 변경합니다.
-r : 원격 저장소의 브랜치를 보여줍니다.
--merged : 현재 checkout된 브랜치에 병합된 브랜치를 보여줍니다.
--no-merged : 현재 checkout된 브랜치에 병합되지 않은 브랜치를 보여줍니다.

$ git branch <branch_name> # 이름이 branch_name인 브랜치를 생성한다.
   
$ git checkout <branch_name> # branch_name 브랜치로 작업공간을 전환해준다.

 

stash: 작업 중인 변경 사항을 일시적으로 저장하고, 이전 상태로 돌아가는 기능입니다. 다른 작업을 해야 할 때, 변경 사항을 커밋하지 않고 일시적으로 저장할 수 있어, 편리합니다.

$ git stash [save] [-p] [-k] [-u|--include-untracked] [-a|--all] [<message>]

# 주요옵션들
save : 변경 사항을 스택에 저장합니다. save를 생략해도 상관없습니다.
-p : 변경 사항을 일부만 stash에 저장합니다.
-k : 변경 사항 중 색인에 없는 것은 stash하지 않습니다.
-u|--include-untracked : 추적되지 않은 파일까지 stash에 저장합니다.
-a|--all : 수정된 모든 파일을 stash에 저장합니다.
<message> : stash에 대한 커스텀 메시지를 입력합니다.

$ git stash list # list : stash 리스트를 보여줍니다.

$ git stash show [-p] [<stash>] # show : stash의 변경 내용을 보여줍니다.

$ git stash apply [--index] [<stash>] # apply : stash를 적용합니다.

$ git stash branch <branchname> [<stash>] # branch : stash를 적용하고, 새 브랜치에서 작업을 계속합니다.

$ git stash drop [<stash>] # drop : stash를 제거합니다.

$ git stash pop [--index] [<stash>] # pop : stash를 적용하고, stash 스택에서 제거합니다.

 

  • git의 Object, Commit, Head, Branch, Tag는 어떤 개념일까요? git 시스템은 프로젝트의 히스토리를 어떻게 저장할까요?

git 시스템에서는 프로젝트의 히스토리를 다양한 객체(object)를 사용하여 저장합니다. 이러한 객체는 기본적으로 파일 시스템의 스냅샷(snapshot)이라고 생각할 수 있습니다. git은 이러한 객체를 트리(tree), 커밋(commit), 헤드(head), 브랜치(branch), 태그(tag)와 같은 다양한 개념으로 추상화하여 사용합니다.

  • Object: git에서 저장되는 모든 데이터는 오브젝트(object)로 표현됩니다. git에서 사용되는 객체는 blob, tree, commit, tag 등이 있습니다. 이러한 객체들은 SHA-1 해시 값으로 식별되며, 일종의 포인터로도 생각할 수 있습니다.
  • Commit: git에서 커밋(commit)은 작업 디렉토리에서 변경된 내용을 스냅샷 형태로 저장한 것입니다. 각 커밋은 고유한 해시 값으로 식별되며, 이전 커밋의 해시 값에 대한 참조를 가지고 있습니다. 커밋 메시지, 작성자 정보, 작성 시간 등과 함께 이전 커밋과의 차이점(diff) 정보를 포함하고 있습니다.
  • Head: git에서 헤드(head)는 현재 작업 중인 브랜치의 커밋을 가리키는 포인터입니다. 헤드를 이용하여 현재 브랜치에 새로운 커밋을 추가할 수 있습니다.
  • Branch: git에서 브랜치(branch)는 커밋의 연속성을 나타내는 포인터입니다. 새로운 브랜치를 만들면, 해당 브랜치는 커밋 그래프에서 새로운 포인터로 추가되며, 이전 브랜치와 공통된 커밋을 가리키게 됩니다. 이후에 커밋이 추가되면, 브랜치는 해당 커밋을 가리키는 포인터로 업데이트됩니다.
  • Tag: git에서 태그(tag)는 특정 커밋을 가리키는 포인터입니다. 태그는 보통 특정 버전을 나타내기 위해 사용됩니다. 이러한 태그는 브랜치와 유사하게 동작하지만, 태그는 브랜치와 달리 이동하지 않으며, 고정된 포인터로 사용됩니다.

git 시스템은 이러한 개념들을 기반으로 프로젝트의 히스토리를 저장합니다. 모든 파일의 상태는 Object로 저장되며, 변경 사항을 저장할 때마다 새로운 Commit을 생성합니다. Branch를 사용하여 독립적인 작업 공간을 만들고, Tag를 사용하여 특정 버전에 대한 이름표를 붙입니다. 이렇게 저장된 모든 정보는 git에서 추적하고 관리할 수 있으며, 프로젝트의 이전 버전으로 쉽게 되돌아갈 수 있습니다.

 

  • 리모트 git 저장소에 원하지 않는 파일이 올라갔을 때 이를 되돌리려면 어떻게 해야 할까요?

원격 저장소에 커밋을 잘못 기록했을 때 되돌리는 방법은 크게 두가지가 있다. 첫번째는 git reset을 사용해 커밋을 취소하는 방식, 두번째는 git revert를 사용하여 커밋 내용을 되돌리는 방식이다.

로컬에서 커밋 되돌린 후 강제 푸시

첫번째 방법은 로컬 저장소에서 일단 커밋을 되돌린 후, 이를 원격 저장소에 강제로 반영시키는 방법이다.

 

먼저 로컬에서 $ git reset 명령어를 이용해 내가 되돌리고 싶은 커밋들을 되돌린다.

$ git reset --hard HEAD~3

 

그리고 난 후, $ git push를 실행하면

$ git push origin master

 

에러 문구가 나타날 것이다.

 

로컬 저장소의 커밋 히스토리가 원격 저장소의 커밋 히스토리보다 뒤쳐져 있는데 푸시를 하였으므로 발생하는 에러이다. 하지만 지금 우리가 원하는 것은 이 뒤쳐져 있는 로컬 저장소의 커밋 히스토리를 원격 저장소의 커밋 히스토리로 강제로 덮어쓰는 것이므로 이를 위한

옵션 -f 또는 --force 를 명령어에 추가하여야 한다.

$ git push -f origin master

 

GitHub 페이지를 통해 원격 저장소에서의 커밋이 되돌려졌음을 확인할 수 있다.

 

git revert 사용하기

revert 명령어를 사용하는 방식은 커밋기록을 삭제하는 것이 아닌 “커밋의 변경사항을 되돌린다”는 커밋을 만들어 주는 방식이다.

$ git revert [해당커밋해시값]

--no-commit 옵션을 사용해 커밋을 남기지 않고 revert를 쌓을 수 있다.

또 HEAD~n..을 붙여주어 한번에 여러개의 커밋에 대해 revert를 실행시킬 수 있다.

 

$ git revert --no-commit HEAD~3..

 

 

참고한 사이트

https://j1mmyson.github.io/posts/AboutGit/

https://roaving-dev.tistory.com/6

728x90
반응형