연습 - 공유 리포지토리를 사용하여 협업

완료됨

동일한 네트워크에 있는 경우 다른 사용자의 리포지토리에서 직접 끌어올 수 있습니다. 그러나 좋은 프로세스는 아니며 대부분의 협력자는 동일한 네트워크에 있지 않습니다. 모든 협력자가 밀어 넣고 끌어올 수 있는 중앙 리포지토리를 설정하는 것이 좋습니다.

개발자 친구인 Bob에게 프로젝트에 대해 알리고 Bob이 참가하겠다고 요청할 경우 수행해야 하는 작업이 바로 ‘bare 리포지토리’라고도 하는 중앙 리포지토리를 설정하는 것입니다.

bare 리포지토리 만들기

필요한 것은 작업 트리가 없는 리포지토리입니다. bare 리포지토리는 작업 트리 대비 다음과 같은 여러 장점이 있습니다.

  • 작업 트리가 없으므로 어떤 분기가 체크 아웃되었는지 걱정할 필요 없이 모든 사용자가 변경 내용을 밀어 넣을 수 있습니다.
  • 다른 사용자가 사용자 변경 내용과 충돌할 수 있는 변경 내용을 밀어 넣은 경우 Git에서 쉽게 감지할 수 있습니다.
  • 공유 리포지토리는 제한 없이 개발자에 맞게 크기가 조정됩니다. bare 리포지토리를 사용하는 경우 공유 리포지토리만 알면 되고 끌어와야 할 수 있는 다른 모든 협력자에 대해서는 몰라도 됩니다.
  • 모두 액세스할 수 있는 공유 리포지토리를 서버에 배치하면 방화벽과 사용 권한에 대해 걱정할 필요가 없습니다.
  • Git에서 각 커밋을 수행한 사용자를 추적하므로 서버에 별도의 계정이 필요하지 않습니다. GitHub에는 모두 git 계정을 공유하는 수백만 명의 사용자가 있습니다. 모든 사용자가 SSH(Secure Shell) 암호화 네트워크 프로토콜을 사용하며 사용자는 공개 키로 구분됩니다.

공유할 bare 리포지토리는 쉽게 만들 수 있습니다.

  1. AliceCats 디렉터리와 동일한 수준에 bare 리포지토리를 배치할 Shared.git이라는 라는 새 디렉터리를 만듭니다.

    cd ..
    mkdir Shared.git
    cd Shared.git
    
    

    디렉터리 이름은 중요하지 않지만, 이 연습에서는 Shared.git 디렉터리 또는 간단히 ‘공유’ 디렉터리로 참조하겠습니다.

    디렉터리 이름을 Shared.git으로 지정하는 것은 bare 리포지토리에 .git으로 끝나는 이름을 할당하여 작업 트리와 구분하는 오랜 전통을 따른 것입니다. 규칙이지만 요구 사항은 아닙니다.

  2. 이제 다음 명령을 사용하여 공유 디렉터리에 bare 리포지토리를 만듭니다.

    git init --bare
    
    
  3. 아직 bare 리포지토리이므로 git checkout 명령을 사용하여 기본 분기의 이름을 설정할 수 없습니다. 이 작업을 수행하려면 다른 분기(예제에서는 main 분기)를 가리키도록 HEAD 분기를 변경합니다.

    git symbolic-ref HEAD refs/heads/main
    
    
  4. 다음 단계에서는 소유 리포지토리의 콘텐츠를 공유 리포지토리로 가져옵니다. 다음 명령을 사용하여 리포지토리가 저장된 프로젝트 디렉터리로 돌아가 origin 원격을 설정하고 초기 밀어 넣기를 수행합니다.

    cd ../Cats
    git remote add origin ../Shared.git
    git push origin main
    
    
  5. 출력을 확인합니다. 출력에 성공했다고 표시됩니다.

    Counting objects: 12, done.
    Delta compression using up to 2 threads.
    Compressing objects: 100% (8/8), done.
    Writing objects: 100% (12/12), 1.07 KiB | 0 bytes/s, done.
    Total 12 (delta 1), reused 0 (delta 0)
    To ../Shared.git
     * [new branch]      main -> main
    
  6. 처음부터 복제하여 리포지토리를 만든 것처럼 기본적으로 pushpulloriginmain 분기를 사용하려고 합니다. 그러나 먼저 추적할 분기를 Git에 알려야 합니다.

    git branch --set-upstream-to origin/main
    
    
  7. 다음 출력을 확인합니다.

    Branch main set up to track remote branch main from origin.
    

    새 리포지토리에는 분기가 없으므로 초기 밀어 넣기 전에 이 명령을 실행하려고 하면 Git에서 경고를 표시합니다. Git은 존재하지 않는 분기를 추적할 수 없습니다. Git이 내부적으로 수행하는 작업은 .git/refs/remotes/origin에서 trunk라는 파일을 찾는 것뿐입니다.

협력자 설정

다음 단계는 Bob이 bare 리포지토리를 복제한 다음, Alice가 리포지토리의 origin을 설정하여 밀어 넣기 및 끌어오기 대상을 공유 리포지토리로 지정하는 것입니다.

  1. 프로젝트 디렉터리의 형제인 Bob이라는 디렉터리를 만들고 Bob 디렉토리로 변경합니다.

    cd ..
    mkdir Bob
    cd Bob
    
    
  2. 이제 공유 리포지토리를 복제합니다(명령의 끝에 마침표를 포함해야 함).

    git clone ../Shared.git .
    
    
  3. 현재 Alice의 리포지토리는 사용자 고유의 리포지토리에 밀어 넣고 끌어오도록 구성되어 있습니다. 다음 명령을 사용하여 Alice 디렉터리로 변경하고 공유 리포지토리를 가리키도록 origin을 변경합니다.

    cd ../Alice
    git remote set-url origin ../Shared.git
    
    

협업 시작

이제 Bob은 웹 사이트에서 작업할 준비가 되었으므로 페이지 맨 아래에 바닥글을 추가하기로 결정합니다. 잠시 동안 Bob 및 Alice의 가상 사용자가 되어 협업의 기본 사항을 알아보겠습니다.

  1. 먼저 Bob 디렉터리로 이동하여 Bob으로 작업합니다.

    cd ../Bob
    git config user.name Bob
    git config user.email bob@contoso.com
    
    
  2. index.html을 열고 (<body> 요소 끝에 있는) <hr> 요소를 다음으로 바꿉니다.

    <footer><hr>Copyright (c) 2021 Contoso Cats</footer>
    

    파일을 저장하고 편집기를 닫습니다.

  3. 변경 내용을 커밋하고 원격 원본에 밀어넣습니다.

    git commit -a -m "Put a footer at the bottom of the page"
    git push
    
    
  4. 출력을 확인합니다. 다음 예제와 같은 경고가 표시되더라도 걱정하지 마세요. 이 경고는 Git 기본 동작의 변경을 사용자에게 알리기 위한 것일 뿐입니다. 이 경고를 다시 표시하지 않으려면 git config --global push.default simple을 실행합니다.

    warning: push.default is unset; its implicit value has changed in
    Git 2.0 from 'matching' to 'simple'. To squelch this message
    and maintain the traditional behavior, use:
    
      git config --global push.default matching
    
    To squelch this message and adopt the new behavior now, use:
    
      git config --global push.default simple
    
    When push.default is set to 'matching', git will push local branches
    to the remote branches that already exist with the same name.
    
    Since Git 2.0, Git defaults to the more conservative 'simple'
    behavior, which only pushes the current branch to the corresponding
    remote branch that 'git pull' uses to update the current branch.
    
    See 'git help config' and search for 'push.default' for further information.
    (the 'simple' mode was introduced in Git 1.7.11. Use the similar mode
    'current' instead of 'simple' if you sometimes use older versions of Git)
    
  5. Bob이 사이트를 편집하는 동안 Alice도 편집하고 있습니다. Alice는 페이지에 탐색 모음을 추가하기로 결정합니다. 이 추가 작업을 위해 Alice는 index.htmlsite.css 파일 두 개를 수정해야 합니다. 먼저 Alice 디렉터리로 돌아갑니다.

    cd ../Alice
    
    
  6. 이제 index.html을 열고 줄 8의 <body> 태그 바로 뒤에 다음 줄을 삽입합니다.

    <nav><a href="./index.html">home</a></nav>
    

    파일을 저장하고 편집기를 닫습니다.

  7. 그런 다음 CSS 폴더에 있는 site.css를 열고 맨 아래에 다음 줄을 추가합니다.

    nav { background-color: #C0D8DF; }
    

    파일을 저장하고 편집기를 닫습니다.

  8. 이제 Alice가 Bob으로부터 사이트를 변경했음을 알리는 메일을 받는다고 가정해 봅시다. Alice는 변경 사항을 커밋하기 전에 Bob의 변경 사항을 끌어오려고 합니다. (Alice가 이미 변경 사항을 커밋한 경우 다른 문제가 발생하며 이 내용은 또 다른 모듈에서 설명합니다.) Alice는 다음 명령을 실행합니다.

    git pull
    
    
  9. 출력을 확인합니다. 출력에서는 Git이 문제를 방지한 것처럼 보입니다.

    remote: Counting objects: 3, done.
    remote: Compressing objects: 100% (3/3), done.
    remote: Total 3 (delta 2), reused 0 (delta 0)
    Unpacking objects: 100% (3/3), done.
    From ../Shared
       843d142..2cf6cbf  main     -> origin/main
    Updating 843d142..2cf6cbf
    error: Your local changes to the following files would be overwritten by merge:
            index.html
    Please commit your changes or stash them before you can merge.
    Aborting
    

    Git에서 끌어오기가 Alice의 index.html 버전을 덮어쓰고 변경 내용이 손실된다고 경고합니다. Bob이 index.html도 수정했기 때문입니다. Alice가 index.html을 변경하지 않았다면 Git은 병합을 커밋했을 것입니다.

  10. git diff 명령을 사용하여 Bob이 index.html에서 변경한 내용을 확인합니다.

    git diff origin -- index.html
    
    
  11. 출력을 확인합니다. 출력에서는 분명히 Alice의 변경 내용과 Bob의 변경 내용이 겹치지 않습니다. 이제 Alice가 변경 내용을 ‘스태시’할 수 있습니다.

    git stash는 몇 개의 임시 커밋을 수행하여 작업 트리 및 인덱스의 상태를 저장합니다. 스태시는 “실제” 커밋을 수행하거나 리포지토리 기록에 영향을 주지 않고 다른 작업을 수행하는 동안 현재 작업을 저장하는 방법으로 생각하면 됩니다.

    실제로 Alice는 끌어오기를 시도하기 전에 변경 내용을 스태시하거나 커밋했어야 합니다. “더티” 작업 트리로 끌어오면 쉽게 복구할 수 없는 작업이 수행될 수 있으므로 위험합니다.

    다음 명령을 사용하여 Alice의 변경 내용을 스태시합니다.

    git stash
    
    
  12. 출력을 확인합니다. 다음 예제와 같이 표시됩니다.

    Saved working directory and index state WIP on main: 95bbc3b Change background color to light blue
    HEAD is now at 95bbc3b Change background color to light blue
    
  13. 이제 Alice가 안전하게 끌어올 수 있으며, 이후 스택으로 구성된 스태시를 “팝”할 수 있습니다. (실제로 git stash은(는) git stash push의 축약형입니다. 아직 지급하지 않은 청구서를 배치하는 스택과 매우 비슷합니다.) 다음 명령을 실행합니다.

    git pull
    git stash pop
    
    

    스태시를 팝하면 변경 사항이 병합됩니다. 변경 내용이 겹치면 충돌이 발생할 수 있습니다. Microsoft Learn의 고급 Git 모듈에서 해당 상황을 해결하는 방법을 알아볼 수 있습니다.

  14. 출력을 확인합니다. Alice는 이 출력에서 병합에 성공했으며, 변경 내용이 복구되었지만 아직 커밋을 위해 스테이징되지는 않았음을 확인할 수 있습니다.

    Auto-merging index.html
    On branch main
    Your branch is up-to-date with 'origin/main'.
    Changes not staged for commit:
      (use "git add <file>..." to update what will be committed)
      (use "git checkout -- <file>..." to discard changes in working directory)
    
            modified:   CSS/site.css
            modified:   index.html
    
    no changes added to commit (use "git add" and/or "git commit -a")
    Dropped refs/stash@{0} (0cfb7b75d56611d9fc6a6ab660a51f5582b8d9c5)
    

    이때 Alice는 작업을 계속하거나 변경 내용을 커밋하고 밀어 넣을 수 있습니다. 바닥글에 탐색 모음과 동일한 스타일을 할당하여 Alice로 다른 변경 사항을 적용하겠습니다.

  15. CSS 폴더에 있는 site.css를 열고 <nav> 요소의 스타일을 지정하는 줄인 세 번째 줄을 다음 공유 CSS 규칙으로 바꿉니다. 그런 다음 평소처럼 변경 내용을 저장하고 편집기를 닫습니다.

    nav, footer { background-color: #C0D8DF; }
    
  16. 이제 변경 내용을 커밋하고 공유 리포지토리에 밀어 넣습니다.

    git commit -a -m "Stylize the nav bar"
    git push
    
    

    이제 업데이트된 사이트는 공유 리포지토리에 있습니다.

  17. 프로젝트 디렉터리로 돌아가서 끌어오기를 완료합니다.

    cd ../Cats
    git pull
    
    
  18. index.html(프로젝트 디렉터리에 있는 항목)을 열어 Bob과 Alice가 변경한 내용이 로컬 리포지토리에 있는지 확인합니다. index.html에 최신 코드가 있는지 확인합니다.

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset='UTF-8'>
        <title>Our Feline Friends</title>
        <link rel="stylesheet" href="CSS/site.css">
      </head>
      <body>
        <nav><a href="./index.html">home</a></nav>
        <h1>Our Feline Friends</h1>
        <p>Eventually we will put cat pictures here.</p>
        <footer><hr>Copyright (c) 2021 Contoso Cats</footer>
      </body>
    </html>
    
  19. 현재 사용자 리포지토리와 Alice의 리포지토리는 동기화되었지만 Bob의 리포지토리는 동기화되지 않았습니다. Bob의 리포지토리도 최신 상태로 만듭니다.

    cd ../Bob
    git pull
    
    

이제 세 개의 리포지토리가 모두 동기화되었습니다. 공유 리포지토리는 모든 사용자를 위한 단일 데이터 소스(single source of truth)이며 모든 밀어 넣기 및 끌어오기가 공유 리포지토리로 전달됩니다.

웹 사이트의 모양이 궁금하면 다음 미리 보기를 확인하세요.

Screenshot of the rendered Cats website.

원하는 경우 파일을 다운로드하여 로컬에서 미리 볼 수 있습니다.

  1. Cats 폴더를 압축합니다.

    cd ..
    zip -r Cats.zip Cats
    
    
  2. 압축된 파일을 다운로드합니다.

    download Cats.zip
    
    
  3. 이제 로컬 컴퓨터에서 파일의 압축을 풀고 index.html을 열어 직접 확인하세요.