Gom3rye

Git 협업 본문

현대 오토에버 클라우드 스쿨

Git 협업

Gom3rye 2025. 7. 16. 17:01
728x90
반응형

형상 관리

Git Hub으로 협업

clone

원격 저장소를 복제하는 명령

  • 명령어 형식
  • 확인은 git remove -v
  • 저장소에 별도의 사용자 설정

push & pull

  • 첫 번째 저장소에서 파일을 수정한 후 커밋
  • 첫 번째 저장소에서 git hub으로 push : git push origin HEAD:master
  • 두 번째 저장소에서 작업을 하고자 하는 경우에는 pull을 받아야 한다. (안 그럼 변경된 내용이 적용이 안되니까)
  • 두 번째 저장소에서도 파일을 수정하고 git commit -am “~~”으로 커밋하기
  • 첫 번째 저장소에서 pull

충돌 해결하기

  • git pull은 원격 저장소의 파일을 가져오는 fetch 기능과 이를 병합하는 merge 기능을 한꺼번에 진행한다.
  • 병합 시 Git은 변경된 내용을 자동으로 병합하려 하지만, 충돌이 발생하면 어떤 내용을 유지할지 스스로 판단하지 못해 수동으로 해결해야 한다.
  • 위의 경우에는 작업자가 직접 파일의 내용을 수정하고 병합을 마무리해야 한다.
  • 충돌 발생
    • 첫 번째 저장소에서 ui.py 파일을 수정, 커밋, 푸시
    • 두 번째 저장소에서 ui.py 파일을 수정, 커밋 ,푸시: 푸시 과정에서 에러 발생
      • 현재 git hub에 올라가 있는 commit 보다 뒤쳐진 commit을 업데이트 하려고 해서 에러가 발생한다.
      • git pull을 이용해서 최신 버전을 받아서 수정하라는 에러 메시지가 뜬다.
    • 두 번째 저장소에서 git pull
      • 동일한 파일을 수정해서 자동으로 병합하는데 실패했다.
      • 충돌 해결 단계로 진입했다고 한다.
      • 해결 방법은 git reset --hard를 이용해서 pull 하기 전 상태로 되돌리거나 git merge --abort로 병합을 종료하면 된다.
      <<<<<<< HEAD
      // 내 로컬 수정 내용
      =======
      // 원격 저장소의 수정 내용
      >>>>>>> origin/master
      
      여기서 
      // 내 로컬 수정 내용
      // 원격 저장소의 수정 내용
      이렇게만 남겨두고 수정했다.
      
      • git commit -am “Merge origin/master”
      • git push origin master
      • 원격 저장소의 내용이 변경되었기 때문에 첫 번째 저장소에서도 git pull을 해줘야 한다.
      • 로그 확인

fetch & merge

  • git pull은 fetch와 merge를 한꺼번에 수행하는 동작이다. 이때 git이 자동으로 merge를 못하면 conflict를 직접 수정해서 해결하면 된다.

실습

  • 저장소 2에서 main.py를 수정하고 git commit -am “fetch와 merge 분리” git push origin master
  • 첫 번째 저장소에서 로그 확인
  • 첫 번째 저장소에서 fetch 명령을 수행
    • git fetch 원격저장소이름
    • git fetch origin
  • 첫 번째 저장소의 로그 확인 (fetch로 가져온 경우는 --all 옵션이 있어야 확인 가능하다.)
    • git log --oneline --all
    • fetch는 로컬 저장소의 브랜치의 변화를 가져오지 않는다.
  • git diff 명령을 이용해서 로컬 저장소와 원격 저장소 파일 내용의 차이를 확인
    • git diff [로컬 저장소 이름] [원격 저장소 이름]
    • git diff master origin/master
  • 내용을 병합
    • git merge [병합할 브랜치 이름]
    • git merge origin/master
  • 첫 번째 저장소에서 내용을 수정한 후
    • git commit -am “~~~”
    • git push origin HEAD:master

blame

코드의 수정 내역 확인

  • 특정 파일에 기록된 코드의 작성자 확인
    • git blame [파일 경로]
    • git blame main.py
  • 특정 커밋의 경우는 파일 경로 앞에
  • 파일의 일부분만 확인
    • git blame -L 시작라인, 끝라인 파일경로
    • git blame -L 3,7 main.py
    • 시작라인, 파일경로 또는 ,끝라인 파일경로 방식으로 사용 가능
  • -e 옵션을 추가하면 작성자의 이메일 주소가 출력된다.
  • 커밋 해시만 표시: -s

stash

작업 내용 임시 저장

  • Git에는 작업 중인 변경 사항을 임시로 보관할 수 있는 stash라는 영역이 있다. 이를 통해 현재 작업을 잠시 저장하고, 깨끗한 상태로 다른 작업을 할 수 있다.

실습

  • 첫 번째 저장소에서 코드를 수정하고 push
  • 두 번째 저장소에서 다른 파일의 내용을 수정
    • 두 번째 저장소에 첫 번째 저장소의 내용을 반영하고자 하는 경우 pull을 하게 되면 수정한 내용이 사라진다.
    • 이때 git stash를 사용하면 임시 저장 영역에 변경 내용을 저장할 수 있다.
  • git stash를 사용하면 이름과 메시지를 남길 수 있다.
    • 이름을 남기려면 git stash save [저장이름]
    • 메시지를 추가하려면 git stash -m [메시지]
  • 두 번째 저장소에 test.txt 파일을 만들고 git status를 해서 untracked 파일이 있는지 저장소 상태 확인
  • git stash 수행
    • no local changes to save 라는 메시지가 출력되는데 untracked 파일은 임시 저장하지 않는다.
  • untracked 파일을 임시 저장하려면 -u 옵션을 사용하면 된다.
    • git stash save test -um “Add Test test.txt”
  • 임시 저장한 내역을 조회
    • git stash list
    • 스택 구조라서 최근의 것이 먼저 보이게 된다.
  • 두 번째 저장소에 원격 저장소의 내용을 저장 : git pull origin master
  • 임시 저장한 내역 가져오기
    • git stash apply [stash 인덱스]
  • 임시 저장한 내역 지우기
    • git stash drop [stash 인덱스]
    • 인덱스를 생략하면 첫 번째 데이터가 삭제된다.
  • 모든 내역을 지울 때는 git stash clear
    • git stash pop [stash 인덱스]: 인덱스까지 모조리 삭제

Branch

  • 저장소 안의 논리적으로 독립적인 공간
  • 별도로 저장소를 생성하지 않고 기능 추가, 디버그, 테스트 등의 작업을 동시에 수행하는 것이 가능하다.
  • 첫 번째 저장소에서 커밋에 태그를 부여
    • git tag -a v2.0.0 -m “Release Version 2.0.0”
  • 브랜치 생성
    • git branch 브랜치이름
  • 브랜치 확인
    • git branch
  • 브랜치 이름 수정
    • git branch -m 기존브랜치이름 새로운브랜치이름
    • git branch -m test2 test2_new
  • 브랜치 삭제
    • git branch -d 브랜치이름
      • 이때 안 지워지면 -D 로 하면 강제로 지워진다.

실습

  • 첫 번째 저장소에 dev1 이라는 브랜치를 생성
    • git branch dev1
  • 브랜치를 확인해보고 로그도 확인
    • git branch
    • git log --oneline
      • 브랜치가 만들어지면 동일한 브랜치 이름으로 참조 개체가 추가된다. (여기서는 dev1 참조)
      • 현재는 HEAD가 master 브랜치를 가리킨다.
  • 브랜치 전환
    • git checkout
      • HEAD의 위치를 변경시키는 것
    • git checkout 다음에 전환하고자 하는 브랜치 이름을 대입
    • git checkout dev1
      • 깃 로그를 보면 이제 HEAD가 dev1을 가리키고 있는 것을 확인할 수 있다.
      • 현재는 브랜치를 전환해도 동일한 결과를 출력한다. (현재 브랜치랑 dev1이랑 가리키는 곳이 같아서)
  • 새로운 브랜치에서 작업
    • main.py 파일을 수정하고 커밋

merge

  • 현재 브랜치에 작업 내용을 병합할 때 사용
  • master로 브랜치를 변환
    • git checkout master
  • merge 형식
    • git merge [브랜치이름]
    • git merge dev1
      • git loc --oneline --graph 로 확인해보기
  • merge 방식
    • fast-forward merge
      • 기준 브랜치가 변경되지 않고, 단순히 병합 대상 브랜치의 최신 커밋으로 포인터만 이동 (뒤에 있는 브랜치의 참조 개체가 앞서 있는 브랜치의 개체가 참조하는 커밋으로 참조를 이동만 시킨다.)
      • 새로운 커밋이 만들어지지 않는다.
    • 3-way merge
      • 하나의 브랜치에서 작업을 수행하는 동안 다른 브랜치에서도 작업을 수행한 경우
      • 하나의 브랜치가 다른 브랜치의 마지막 커밋을 참조하지 않게 된다.
      • 3개의 커밋을 참조(base, 브랜치 하나의 마지막 커밋, 다른 브랜치의 마지막 커밋) → 이 경우 충돌이 발생하므로 직접 수정해야 한다.

옵션

  • fast-forward merge
    • 2개 브랜치의 참조가 base를 기준으로 일직선 상에 있는 경우에만 가능하다.
    • git merge를 할 때 별다른 옵션을 설정하지 않으면 가능하다.
    • merge를 할 때는 log를 확인해서 2개의 브랜치가 일직선상에 있는지 확인해야 한다.
    • master 브랜치에서 4개의 커밋을 취소: git reset --hard HEAD^^^^
    • --ff 옵션을 사용해서 merge를 해도 되고 생략해도 된다.
    • git merge (--ff) [병합할 브랜치 이름] (여기서는 dev1의 commit이 더 나중에 만들어졌으므로 master에서 dev1을 병합할 수 있다.)
  • non fast-forward merge
    • fast-forward 상태가 아닐 때 수행하는 merge
    • 옵션은 --no-ff
    • 실습
      • master 브랜치의 커밋을 수정: git reset --hard v2.0.0
      • 머지를 위한 커밋이 별도로 생성된다.
      • git merge --no-ff dev1
      • 로그 확인: git log --oneline --graph
        • 어떤 커밋들을 병합했는지 확인이 쉽고 메시지를 작성하기 때문에 나중에 알아보기도 좋다.
  • squash merge
    • 강압적인 머지 방식으로 병합된 브랜치 정보가 표시되지 않는다.
    • 옵션은 --squash
    • master 브랜치의 커밋을 수정
    • 브랜치의 내용을 가져오기만, 커밋은 생성하지 않는다.
    • 상대 브랜치의 작업 내용이 추가되어 파일 상태는 변경이 되고 변경된 파일은 스테이징 단계까지 이동한다.
    • git tag -a v2.1.0 -m "Release version 2.1.0" 태그를 붙이는 게 좋다.

rebase

브랜치 재배치

  • 여러 브랜치에서 작업한 내역을 하나의 브랜치에서 통합하고자 하는 경우 merge를 이용할 수 있지만 rebase를 이용하는 것도 가능하다.
  • rebase를 이용하는 방식은 base를 조정해서 정리하는 것으로 브랜치의 수가 많아질 때 유용하다.

실습- issue1 브랜치를 만들고 소스 코드를 수정

  • git checkout -b issue1 으로 브랜치를 만들고 바로 issue1 브랜치로 checkout 한다.
  • 수정 후 git commit -am “issue1 update”
  • 한 번 더 수정 후 git commit -am “issue1 update1” (커밋 2개가 있는 상태)
  • master 브랜치로 이동 git checkout master
  • issue2 브랜치를 만들고 git checkout -b issue2
  • 소스 코드 수정 git commit -am “issue2_1!”
  • 한 번 더 소스 코드 수정 후 git commit -am “issue2_2!”
  • 현재 상태
    • master → issue1
    • master → issue2
  • issue2의 base가 master인데 이를 변경할 수 있는 명령이 rebase이다.
  • git rebase [베이스가될브랜치]
  • 같은 파일을 작업했다면 충돌이 발생할 수 있고 이 경우 수동으로 수정해야 한다.
    • 동일한 파일을 수정한 경우 rebase가 안된다.
  • 여러 브랜치에서 작업한 내역을 합치고자 할 때는 브랜치의 순서를 재배치한 후 base에 병합하면 된다.

cherry-pick

다른 브랜치의 커밋을 적용하는 것

  • 일부 기능이나 중간 완성된 커밋을 다른 브랜치에서 가져와 시험해야 하는 상황이 종종 발생하는데 이때 사용한다.

실습

  • master 브랜치를 이용해서 dev1 브랜치를 만들고 2개의 작업을 수행한 후 각각 커밋 (main.py)
  • master 브랜치를 이용해서 dev2 브랜치를 만들고 2개의 작업을 수행한 후 각각 커밋 (ui.py)
  • dev2 브랜치에서 dev1의 커밋 가져오기: git cherry-pick 커밋해시

pull request

  • 여러 개발자가 동시에 작업할 때 병합 검토를 돕는 기능
  • Merge Request라고도 한다.
  • 이 명령은 git의 명령이 아니고 호스팅 서비스에서 제공하는 명령이다.
  • 연습을 할 때는 2개 이상의 계정으로 실습
    • 관리자용 계정 1개
    • 일반 개발자용 계정 1개 또는 여러 개
    • 초대 받은 개발자가 push를 하고 pull request를 생성해주면 저장소 옵션에 따라 모든 참여자가 코드 리뷰를 해야만 main 브랜치에 push를 할 수 있도록 할 수도 있고 관리자가 강제로 push를 하도록 할 수 있다.
728x90
반응형

'현대 오토에버 클라우드 스쿨' 카테고리의 다른 글

Jenkins  (0) 2025.07.18
Git Hub Action & Jenkins  (1) 2025.07.17
Git  (0) 2025.07.15
CI/CD  (1) 2025.07.14
Kubernetes- Volume API, Requests, Limits  (1) 2025.07.11