팀원의 업데이트 반영하기

GitBeginner
지금 연습하기

소개

Riverlight Garden에는 정확한 방문객 안내서가 필요합니다. 준비된 로컬 커밋은 출입구 위치와 방문객 안내 데스크 전화번호를 바꿉니다. 팀원은 이미 새로운 무단차 이동 경로를 게시했습니다. 방문객에게는 이 세 가지 수정 사항이 모두 필요합니다.

팀원의 작업을 가져오고, 서로 독립적인 변경을 병합한 뒤 결과를 게시해 보겠습니다. 새 수신용 클론에서 실제로 전달된 파일을 확인합니다. 공유 저장소와 두 작업 복사본은 모두 하나의 교육용 머신에 있는 로컬 디렉터리입니다. 호스팅 서비스, 서버 설정, 계정 없이 실제 Git 협업을 진행합니다.

커밋, 브랜치, git add, git commit, 기본적인 diff를 이미 알고 있어야 합니다. 원격 저장소 이름, 가져오기(fetch), 병합(merge), 푸시(push), 복제(clone)는 여기서 설명합니다. 소요 시간 35분은 읽기와 일반적인 실수에 드는 시간을 포함한 저자의 추정치입니다.

팀원의 업데이트 확인하기

이 단계에서는 준비된 로컬 업데이트를 아직 전달할 수 없는 이유를 알아본 다음, 파일을 바꾸지 않고 팀원의 리비전을 가져옵니다.

Terminal을 여세요. 준비된 편집용 저장소에서 시작합니다.

cd /home/labex/project/guide-team/editor

cd는 이 터미널의 작업 디렉터리를 바꿉니다. 경로를 잘못 입력했다면 pwd로 현재 디렉터리를 출력하고 ls로 그 안의 항목을 나열한 다음, 위의 전체 cd 명령을 다시 실행하세요. 이런 일반적인 이동 오류 때문에 새 VM을 시작할 필요는 없습니다.

새 병합 커밋에는 작성자 정보가 필요합니다. --local은 이 저장소에만 설정을 저장합니다. 따옴표로 묶인 텍스트는 공백이 있어도 하나의 값이며, 예시 이메일은 가상의 주소입니다. 자신의 이름과 이메일을 사용해도 됩니다.

git config --local user.name "Guide Editor"
git config --local user.email "guide@example.com"

기존 로컬 커밋은 이미 완성되어 있습니다. 방문객 정보를 읽어 보세요.

cat guide.txt
cat contacts.txt

South entrance와 방문객 안내 데스크 번호 010-555-0120이 표시되어야 합니다. 안내서의 마지막 입장 시간 문장은 보존하세요. 별도의 경로 파일에는 아직 Use the north ramp가 적혀 있습니다.

cat access.txt

git status --short는 변경된 파일의 간결한 목록을 보여 줍니다. 여기서 출력이 없으면 준비된 작업이 커밋되어 있고 작업 트리가 깨끗하다는 뜻입니다.

git status --short

**원격(remote)**은 다른 저장소로 연결하는 이름 있는 연결입니다. origin은 이 연결의 이름이며 특별한 서버를 뜻하지 않습니다. -v는 가져오기와 푸시 주소를 표시합니다.

git remote -v

두 주소는 모두 /home/labex/project/guide-team/shared.git를 가리킵니다. 이곳은 **베어 저장소(bare repository)**입니다. 편집 가능한 작업 복사본 없이 공유 이력을 저장합니다. 내부 파일을 편집하지 마세요.

브랜치를 전달해 보세요. push는 커밋을 보내며, main은 origin에서 업데이트할 브랜치 이름입니다. 첫 번째 푸시는 0이 아닌 종료 상태로 실패하는 것이 정상입니다. 명령을 단독으로 실행하고 거부된 후 계속 진행하세요.

git push origin main

[rejected], main -> main, (fetch first)를 찾아보세요. 공유 브랜치에는 현재 이력에 없는 작업이 있으므로 Git은 이를 교체하지 못하게 합니다. 이는 비패스트포워드(non-fast-forward) 업데이트입니다. 기존 공유 브랜치 끝의 커밋이 제안한 끝 커밋의 조상이 아닙니다. 강제 푸시는 브랜치에서 팀원의 작업을 밀어내므로 이 과제의 요구 사항을 위반합니다.

fetch는 원격 커밋을 다운로드하고 로컬 원격 추적 포인터인 origin/main을 업데이트합니다. 자신의 main에 병합하거나 작업 파일을 다시 쓰지는 않습니다.

git fetch origin

이력을 비교하세요. --oneline은 커밋마다 짧은 한 줄을 표시하고, --graph는 부모 연결을 그립니다. --all은 로컬 및 원격 추적 브랜치를 모두 포함하며, --decorate는 이름표를 붙입니다. --no-pager는 출력을 바로 표시합니다. 다른 명령을 시험하다가 페이저가 열리면 q를 눌러 나오세요.

git --no-pager log --oneline --graph --all --decorate

Move the gate and update the visitor desk를 HEAD -> main에서, Update the step-free route를 origin/main에서 찾으세요. 둘 다 Open the garden guide에서 갈라졌습니다. HEAD는 현재 체크아웃된 커밋을 가리킵니다. 두 작업은 서로 다르며 어느 하나로 다른 하나를 대신할 수 없습니다.

팀원의 경로를 스냅샷에서 직접 읽어 보세요. show는 revision:path 표현식을 받으므로 origin/main:access.txt는 가져온 리비전에 들어 있는 해당 파일을 뜻합니다.

git --no-pager show origin/main:access.txt

여기에는 Use the riverside ramp가 적혀 있습니다. 작업 파일의 경로는 여전히 Use the north ramp입니다. 이 차이는 가져오기로 새 이력을 사용할 수 있게 되었지만 작업 트리는 그대로 남았음을 보여 줍니다. 첫 번째 확인 항목은 원래 로컬 커밋이 온전하게 남아 있고 팀원의 리비전을 가져온 상태를 확인합니다.

독립적인 두 작업 병합하기

이 단계에서는 두 이력을 하나의 리비전으로 합쳐 남쪽 출입구, 새 방문객 전화번호, 강변 경사로를 모두 포함합니다.

Terminal의 /home/labex/project/guide-team/editor에서 계속 진행하세요. **병합(merge)**은 이력을 합칩니다. 이 변경들은 서로 다른 파일을 수정하므로 Git이 텍스트를 자동으로 합칠 수 있습니다. --no-edit는 Git이 생성한 병합 메시지를 받아들이고 편집기가 열리지 않게 합니다.

git merge --no-edit origin/main

성공한 병합 요약이 표시되어야 하며, 보통 Merge made by the 'ort' strategy.가 나옵니다. Git은 원래 로컬 커밋과 팀원의 원래 커밋을 부모로 하는 두 부모 병합 커밋을 만듭니다. 어느 작업의 커밋도 다시 쓰지 않습니다.

실제로 합쳐진 파일을 읽어 보세요.

cat guide.txt
cat access.txt
cat contacts.txt

안내서에는 South entrance, 09:00-17:00, 마지막 입장 시간 문장이 유지되어야 합니다. 경로에는 Use the riverside ramp가, 전화번호에는 010-555-0120이 남아 있어야 합니다. 독립적인 변경은 충돌 없이 합쳐졌지만 그 의미는 직접 판단해야 합니다.

결과 이력을 검토하세요.

git --no-pager log --oneline --graph --all --decorate

HEAD -> main의 병합이 두 작업의 이력 선을 연결합니다. 푸시하기 전까지 origin/main은 이전에 가져온 팀원 커밋을 계속 가리킵니다. 정상적인 상태입니다. 병합은 공유 main이 아니라 로컬 main을 바꿨기 때문입니다.

작업 상태를 확인하세요.

git status --short

출력이 없어야 합니다. 다른 시도 때문에 병합이 진행 중으로 남아 있다면 git merge --abort로 미완성 병합을 취소하고 병합 전 상태로 돌아갈 수 있습니다. 병합 진행 중일 때만 실행한 다음 병합 명령을 다시 실행하세요. 이미 완성된 커밋을 취소하는 명령은 아닙니다. 확인 항목은 원래 두 부모와 완전한 세 파일을 포함하는 병합 커밋 하나를 요구합니다.

완성된 안내서 게시하고 받기

이 단계에서는 병합한 리비전을 공유 저장소에 전달하고 새 수신용 복사본에서 읽어 봅니다. 로컬에서 병합한 것만으로는 다른 복사본에 아무것도 전달되지 않습니다.

Terminal의 /home/labex/project/guide-team/editor에서 계속 진행하세요. push origin main은 로컬 main 이력을 origin이라는 저장소에 보냅니다. 이번에는 공유 작업이 병합 커밋의 조상이므로, 해당 작업을 제거하지 않고 공유 main을 앞으로 이동시킬 수 있습니다.

git push origin main

거부 없이 main -> main이 표시되어야 합니다. 거부되면 다시 가져오고 그래프를 확인하세요. 강제 옵션을 추가하지 마세요. 이 준비된 환경에는 백그라운드에서 작업하는 팀원이 없지만 실제 팀에서는 언제든 새 작업이 게시될 수 있습니다.

이제 두 저장소가 들어 있는 디렉터리로 이동하세요.

cd /home/labex/project/guide-team

git clone은 원본으로부터 새 저장소와 작업 파일을 만듭니다. 여기서 shared.git는 기존 로컬 원본 경로이고, received-guide는 새 대상 디렉터리입니다. 수신용 복사본은 공유 저장소를 원본으로 삼아야 합니다. 그래야 병합이 실제로 전달되었는지 확인할 수 있습니다.

git clone shared.git received-guide

Cloning into 'received-guide'...와 done.이 표시되어야 합니다. 시험하면서 이미 복제했다면 그 복사본을 보존하세요. received-guide로 들어가 앞서 배운 git fetch origin과 git merge --no-edit origin/main을 차례로 실행하여 최신 상태로 만드세요. 복제를 다시 시도하려고 원래 편집용 저장소를 삭제하지 마세요.

수신용 복사본에 들어가세요.

cd received-guide

각 실제 파일을 읽으세요. cat은 파일을 변경하지 않고 출력합니다.

cat guide.txt
cat access.txt
cat contacts.txt

앞 단계에서 합친 업무 요구 사항과 정보를 비교하세요. 변경하지 않은 줄까지 포함하여 세 파일이 모두 완전해야 합니다. 복제 성공 메시지만으로 정보가 정확하다고 입증할 수는 없습니다.

마지막으로 수신용 이력을 읽으세요. --oneline은 각 커밋을 짧게 표시하고, --graph는 부모 연결을 그리며, --decorate는 브랜치 포인터에 이름표를 붙입니다. --no-pager는 스크롤 가능한 뷰어를 열지 않고 직접 출력합니다.

git --no-pager log --oneline --graph --decorate

맨 위 병합에는 원래 두 작업의 메시지와 최초 커밋을 포함하는 두 갈래의 조상 이력이 있습니다. 구체적인 커밋 ID는 실행마다 다릅니다. 내용이 손실되지 않았고 수신용 복사본이 main에 있으며 추적 중인 작업 트리가 깨끗한지 확인하세요.

git status --short

출력이 없으면 스테이징된 변경, 스테이징되지 않은 변경, 미추적 변경이 없다는 뜻입니다. 이제 하나의 교육용 머신에서 실행되는 실제 Git 저장소들을 통해 사용 가능한 파일 모음을 전달했습니다.

요약

실제 푸시 거부를 처리하고, 자신의 파일을 덮어쓰지 않고 팀원의 커밋을 가져온 뒤, 독립적인 두 작업을 병합하여 완성된 안내서를 공유 저장소로 전달했습니다. 실제 수신용 클론에는 합쳐진 안내서, 무단차 이동 경로, 방문객 연락처가 들어 있습니다.

원래 커밋들은 이력에 남아 있습니다. 다음에는 두 사람이 같은 줄을 바꿔 Git이 사용자의 판단을 필요로 하는 병합을 연습합니다.