[Git] Git을 μ–΄λ–»κ²Œ ν•©μΉ˜μ§€? : Git Merging

Posted by Euisuk's Dev Log on February 28, 2024

[Git] Git을 μ–΄λ–»κ²Œ ν•©μΉ˜μ§€? : Git Merging

원본 κ²Œμ‹œκΈ€: https://velog.io/@euisuk-chung/κΉƒ-λ¨Έμ§•κ³Ό-νŒ¨μŠ€νŠΈν¬μ›Œλ”©-이해와-ν™œμš©

κΉƒ(Git)은 μ†Œν”„νŠΈμ›¨μ–΄ κ°œλ°œμ—μ„œ 버전 관리λ₯Ό μœ„ν•΄ 널리 μ‚¬μš©λ˜λŠ” λ„κ΅¬μž…λ‹ˆλ‹€. μ—¬λŸ¬ κ°œλ°œμžκ°€ λ™μ‹œμ— λ‹€μ–‘ν•œ κΈ°λŠ₯을 κ°œλ°œν•  λ•Œ, μ΄λ“€μ˜ μž‘μ—…μ„ 효율적으둜 ν†΅ν•©ν•˜κΈ° μœ„ν•΄μ„œλŠ” κΉƒμ˜ λ¨Έμ§•(merging)κ³Ό νŒ¨μŠ€νŠΈν¬μ›Œλ”©(fast-forwarding) κΈ°λŠ₯에 λŒ€ν•œ 이해가 ν•„μˆ˜μ μž…λ‹ˆλ‹€.

이 λΈ”λ‘œκ·Έ ν¬μŠ€νŠΈμ—μ„œλŠ” λ¨Έμ§•κ³Ό νŒ¨μŠ€νŠΈν¬μ›Œλ”©μ˜ κ°œλ…μ„ μ„€λͺ…ν•˜κ³ , 보편적인 μ˜ˆμ‹œλ₯Ό 톡해 이λ₯Ό μ–΄λ–»κ²Œ ν™œμš©ν•  수 μžˆλŠ”μ§€ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

κΉƒ λ¨Έμ§•(Merging)

머징은 두 개 μ΄μƒμ˜ 개발 브랜치λ₯Ό ν†΅ν•©ν•˜λŠ” κ³Όμ •μž…λ‹ˆλ‹€. κ°€μž₯ ν”ν•œ μ‹œλ‚˜λ¦¬μ˜€λŠ” κΈ°λŠ₯ κ°œλ°œμ„ μœ„ν•œ 브랜치(feature branch)μ—μ„œμ˜ μž‘μ—…μ„ 메인 브랜치(main branch)둜 ν†΅ν•©ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λ¨Έμ§• κ³Όμ •μ—μ„œλŠ” λ‹€μŒκ³Ό 같은 단계λ₯Ό κ±°μΉ©λ‹ˆλ‹€:

  1. λͺ©ν‘œ 브랜치둜 μ²΄ν¬μ•„μ›ƒν•˜κΈ°: λ¨Έμ§•ν•  λͺ©ν‘œ 브랜치둜 μ²΄ν¬μ•„μ›ƒν•©λ‹ˆλ‹€.
    1
    
    git checkout main
    
  2. λ¨Έμ§• μ‹€ν–‰ν•˜κΈ°: κ°œλ°œν•œ κΈ°λŠ₯이 μžˆλŠ” 브랜치λ₯Ό ν˜„μž¬ λΈŒλžœμΉ˜μ— λ¨Έμ§•ν•©λ‹ˆλ‹€.
    1
    
    git merge feature-branch
    

λ¨Έμ§• κ³Όμ •μ—μ„œ 좩돌(conflict)이 λ°œμƒν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” 두 λΈŒλžœμΉ˜μ—μ„œ 같은 파일의 같은 뢀뢄을 μˆ˜μ •ν–ˆμ„ λ•Œ 주둜 λ°œμƒν•©λ‹ˆλ‹€. 좩돌이 λ°œμƒν•˜λ©΄, 깃은 κ°œλ°œμžμ—κ²Œ μΆ©λŒμ„ ν•΄κ²°ν•˜κ³  머징을 μ™„λ£Œν•  것을 μš”μ²­ν•©λ‹ˆλ‹€.

νŒ¨μŠ€νŠΈν¬μ›Œλ”©(Fast-Forwarding)

νŒ¨μŠ€νŠΈν¬μ›Œλ”©μ€ λ¨Έμ§•μ˜ ν•œ ν˜•νƒœλ‘œ, 브랜치λ₯Ό 톡합할 λ•Œ 기쑴의 νžˆμŠ€ν† λ¦¬λ₯Ό μœ μ§€ν•˜λ©΄μ„œ 브랜치의 ν¬μΈν„°λ§Œ μ΅œμ‹  μ»€λ°‹μœΌλ‘œ μ΄λ™μ‹œν‚€λŠ” λ°©λ²•μž…λ‹ˆλ‹€. μ΄λŠ” κΈ°λŠ₯ λΈŒλžœμΉ˜μ—μ„œ 메인 브랜치둜의 λ³€κ²½ 사항이 μ„ ν˜•μ μΈ 경우(즉, 메인 λΈŒλžœμΉ˜μ—μ„œ κΈ°λŠ₯ λΈŒλžœμΉ˜κ°€ λΆ„κΈ°λœ 이후 메인 λΈŒλžœμΉ˜μ— λ‹€λ₯Έ λ³€κ²½ 사항이 없을 λ•Œ)에 κ°€λŠ₯ν•©λ‹ˆλ‹€.

νŒ¨μŠ€νŠΈν¬μ›Œλ”© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  1. κΈ°λŠ₯ λΈŒλžœμΉ˜μ—μ„œ μž‘μ—…ν•˜κΈ°: feature-branchμ—μ„œ μƒˆλ‘œμš΄ κΈ°λŠ₯에 λŒ€ν•œ μž‘μ—…μ„ μ™„λ£Œν•©λ‹ˆλ‹€.
  2. 메인 브랜치둜 μ²΄ν¬μ•„μ›ƒν•˜κΈ°: μž‘μ—…μ„ 톡합할 메인 브랜치둜 μ „ν™˜ν•©λ‹ˆλ‹€.

    1
    
    git checkout main
    
  3. νŒ¨μŠ€νŠΈν¬μ›Œλ”© λ¨Έμ§• μ‹€ν–‰ν•˜κΈ°: 메인 λΈŒλžœμΉ˜μ—μ„œ feature-branch의 λ³€κ²½ 사항을 νŒ¨μŠ€νŠΈν¬μ›Œλ“œ λ°©μ‹μœΌλ‘œ λ¨Έμ§•ν•©λ‹ˆλ‹€.

    1
    
    git merge feature-branch
    

νŒ¨μŠ€νŠΈν¬μ›Œλ”©μ΄ κ°€λŠ₯ν•œ 경우, 깃은 메인 브랜치의 ν—€λ“œλ₯Ό feature-branch의 μ΅œμ‹  μ»€λ°‹μœΌλ‘œ μ΄λ™μ‹œν‚€κ³ , λ³„λ„μ˜ λ¨Έμ§€ 컀밋을 μƒμ„±ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 이 방식은 νžˆμŠ€ν† λ¦¬λ₯Ό κΉ”λ”ν•˜κ²Œ μœ μ§€ν•  수 μžˆμ–΄ λ§Žμ€ κ°œλ°œμžκ°€ μ„ ν˜Έν•©λ‹ˆλ‹€.

git fetchλž€?

git fetch λͺ…λ Ήμ–΄λŠ” 원격 μ €μž₯μ†Œμ˜ μ΅œμ‹  λ³€κ²½ 사항을 둜컬 μ €μž₯μ†Œμ— κ°€μ Έμ˜€λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€. 이 λͺ…λ Ήμ–΄λŠ” 원격 μ €μž₯μ†Œμ˜ 데이터λ₯Ό λ‘œμ»¬μ— λ‹€μš΄λ‘œλ“œν•˜λ˜, ν˜„μž¬ μž‘μ—… 쀑인 브랜치의 μ½”λ“œλ₯Ό μžλ™μœΌλ‘œ μ—…λ°μ΄νŠΈν•˜μ§€λŠ” μ•ŠμŠ΅λ‹ˆλ‹€. git fetchλŠ” 원격 μ €μž₯μ†Œμ˜ μƒνƒœλ₯Ό ν™•μΈν•˜κ³ , ν•„μš”ν•œ 경우 둜컬 μ €μž₯μ†Œμ˜ 브랜치λ₯Ό 원격 브랜치의 μ΅œμ‹  μƒνƒœμ™€ λ™κΈ°ν™”ν•˜κΈ° μœ„ν•œ 첫 λ‹¨κ³„λ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.

μ‚¬μš©λ²•

git fetch λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•˜λŠ” κ°€μž₯ 기본적인 ν˜•νƒœλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

1
git fetch origin

μ—¬κΈ°μ„œ origin은 기본적으둜 μ„€μ •λœ 원격 μ €μž₯μ†Œμ˜ μ΄λ¦„μž…λ‹ˆλ‹€. 이 λͺ…령은 originμ—μ„œ λ³€κ²½λœ λͺ¨λ“  브랜치 정보λ₯Ό 둜컬 μ €μž₯μ†Œμ— κ°€μ Έμ˜΅λ‹ˆλ‹€. κ°€μ Έμ˜¨ μ •λ³΄λŠ” 둜컬의 원격 좔적 λΈŒλžœμΉ˜μ— μ €μž₯되며, μ΄λŠ” origin/main, origin/feature-branch λ“±μœΌλ‘œ ν‘œμ‹œλ©λ‹ˆλ‹€.

git fetch ν›„μ˜ μž‘μ—…

git fetchλ₯Ό μ‹€ν–‰ν•œ ν›„, λ³€κ²½ 사항을 ν˜„μž¬ λΈŒλžœμΉ˜μ— μ μš©ν•˜λ €λ©΄ 좔가적인 λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 원격 μ €μž₯μ†Œμ˜ main λΈŒλžœμΉ˜μ—μ„œ λ³€κ²½λœ 사항을 ν˜„μž¬ μ²΄ν¬μ•„μ›ƒλœ main λΈŒλžœμΉ˜μ— μ μš©ν•˜κ³ μž ν•  λ•ŒλŠ” λ‹€μŒκ³Ό 같이 ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

  1. 둜컬 main 브랜치둜 μ „ν™˜ν•˜κΈ°:
    1
    
    git checkout main
    
  2. λ³€κ²½ 사항 λ¨Έμ§€ν•˜κΈ°:
    1
    
    git merge origin/main
    

이 과정은 origin/main의 μ΅œμ‹  λ³€κ²½ 사항을 둜컬의 main λΈŒλžœμΉ˜μ— ν†΅ν•©ν•©λ‹ˆλ‹€.

git fetch와 git pull의 차이

git fetch와 λΉ„μŠ·ν•œ λͺ…λ Ήμ–΄λ‘œ git pull이 μžˆμŠ΅λ‹ˆλ‹€. git pull은 git fetchλ₯Ό μ‹€ν–‰ν•œ ν›„, λ°”λ‘œ git mergeλ₯Ό μ‹€ν–‰ν•˜μ—¬ 원격 브랜치의 λ³€κ²½ 사항을 ν˜„μž¬ λΈŒλžœμΉ˜μ— μžλ™μœΌλ‘œ λ¨Έμ§€ν•©λ‹ˆλ‹€. 즉, git pull은 git fetch ν›„ git mergeλ₯Ό ν•œ λ²ˆμ— μˆ˜ν–‰ν•˜λŠ” λͺ…λ Ήμ–΄μž…λ‹ˆλ‹€.

κ°œλ°œμžκ°€ 원격 μ €μž₯μ†Œμ˜ μ΅œμ‹  λ³€κ²½ 사항을 ν™•μΈν•˜κ³  μ‹Άμ§€λ§Œ, μ¦‰μ‹œ ν˜„μž¬ λΈŒλžœμΉ˜μ— ν†΅ν•©ν•˜κ³  μ‹Άμ§€ μ•Šμ€ 경우 git fetchλ₯Ό μ‚¬μš©ν•˜λŠ” 것이 μ’‹μŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 λ³€κ²½ 사항을 κ²€ν† ν•˜κ³ , ν•„μš”ν•œ 경우 μˆ˜λ™μœΌλ‘œ λ¨Έμ§€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ²΄ν¬μ•„μ›ƒν•œ λΈŒλžœμΉ˜κ°€ μ—†λŠ”λ°?!

git fetch originκ³Ό git checkout -b project1 origin/project1 λͺ…λ Ήμ–΄λŠ” 두 단계에 원격 μ €μž₯μ†Œμ˜ λ‚΄μš©μ„ μ—…λ°μ΄νŠΈλ‘œ 이λ₯Ό 브렌치둜 μ •μ˜ν•˜λ©΄ λ©λ‹ˆλ‹€. 각각의 단계에 λŒ€ν•΄μ„œ μ‚΄νŽ΄λ³΄μ‹œμ£ .

1. git fetch origin

  • 이 λͺ…λ Ήμ–΄λŠ” 원격 μ €μž₯μ†Œ originμœΌλ‘œλΆ€ν„° μ΅œμ‹  정보λ₯Ό 둜컬 μ €μž₯μ†Œλ‘œ κ°€μ Έμ˜΅λ‹ˆλ‹€(fetch). μ—¬κΈ°μ„œ origin은 둜컬 μ €μž₯μ†Œμ— λ“±λ‘λœ 원격 μ €μž₯μ†Œμ˜ κΈ°λ³Έ μ΄λ¦„μž…λ‹ˆλ‹€.
  • git fetchλŠ” 원격 μ €μž₯μ†Œμ˜ λͺ¨λ“  브랜치 정보λ₯Ό μ—…λ°μ΄νŠΈν•˜μ§€λ§Œ, ν˜„μž¬ μ²΄ν¬μ•„μ›ƒλœ 브랜치의 μž‘μ—… νŠΈλ¦¬λ‚˜ 인덱슀λ₯Ό λ³€κ²½ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. 즉, λ‘œμ»¬μ—μ„œ μž‘μ—… 쀑인 μ½”λ“œμ—λŠ” 영ν–₯을 μ£Όμ§€ μ•Šκ³ , 원격 μ €μž₯μ†Œμ˜ μ΅œμ‹  μƒνƒœλ§Œμ„ λ‘œμ»¬μ— λ°˜μ˜ν•©λ‹ˆλ‹€.
  • 이 과정을 톡해 원격 μ €μž₯μ†Œμ˜ μƒˆλ‘œμš΄ λΈŒλžœμΉ˜λ‚˜ μ—…λ°μ΄νŠΈλœ 브랜치 정보λ₯Ό 둜컬 μ €μž₯μ†Œμ— κ°€μ Έμ˜¬ 수 μžˆμŠ΅λ‹ˆλ‹€.

2. git checkout -b project1 origin/project1

  • 이 λͺ…λ Ήμ–΄λŠ” project1μ΄λΌλŠ” μƒˆλ‘œμš΄ 둜컬 브랜치λ₯Ό μƒμ„±ν•˜κ³ , 이λ₯Ό origin/project1 원격 브랜치의 μ΅œμ‹  μ»€λ°‹μœΌλ‘œ μ„€μ •ν•œ ν›„, ν•΄λ‹Ή 브랜치둜 μ „ν™˜(checkout)ν•©λ‹ˆλ‹€.
  • μ—¬κΈ°μ„œ git checkout -bλŠ” μƒˆλ‘œμš΄ 브랜치λ₯Ό μƒμ„±ν•˜κ³  ν•΄λ‹Ή 브랜치둜 μ „ν™˜ν•˜λŠ” λͺ…λ Ήμ–΄μž…λ‹ˆλ‹€. project1은 생성할 μƒˆλ‘œμš΄ 둜컬 브랜치의 이름이며, origin/project1은 볡제(clone)ν•˜κ±°λ‚˜ μ—…λ°μ΄νŠΈ(fetch)ν•  원격 브랜치λ₯Ό μ§€μ •ν•©λ‹ˆλ‹€.
  • 이 과정은 특히 원격 μ €μž₯μ†Œμ— μƒˆλ‘œ μƒμ„±λ˜κ±°λ‚˜ μ—…λ°μ΄νŠΈλœ 브랜치λ₯Ό 기반으둜 λ‘œμ»¬μ—μ„œ μž‘μ—…μ„ μ‹œμž‘ν•˜κ³ μž ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€. μƒˆλ‘œμš΄ 브랜치 project1은 원격 브랜치 origin/project1의 μƒνƒœλ₯Ό κ·ΈλŒ€λ‘œ λ°˜μ˜ν•˜μ—¬ μƒμ„±λ©λ‹ˆλ‹€.

μš”μ•½ν•˜λ©΄, 이 두 λͺ…λ Ήμ–΄λŠ” 원격 μ €μž₯μ†Œ originμ—μ„œ project1 브랜치의 μ΅œμ‹  μƒνƒœλ₯Ό 둜컬 μ €μž₯μ†Œλ‘œ 가져와(git fetch origin), κ·Έ μƒνƒœλ₯Ό 기반으둜 μƒˆλ‘œμš΄ 둜컬 브랜치 project1을 μƒμ„±ν•˜κ³  ν•΄λ‹Ή 브랜치둜 μ „ν™˜(git checkout -b project1 origin/project1)ν•˜λŠ” μž‘μ—…μ„ μˆ˜ν–‰ν•©λ‹ˆλ‹€. μ΄λŸ¬ν•œ 과정을 톡해 κ°œλ°œμžλŠ” 원격 μ €μž₯μ†Œμ˜ νŠΉμ • 브랜치λ₯Ό κΈ°μ€€μœΌλ‘œ λ‘œμ»¬μ—μ„œ μƒˆλ‘œμš΄ μž‘μ—…μ„ μ‹œμž‘ν•  수 있게 λ©λ‹ˆλ‹€.

μΆ”κ°€ μ„€λͺ…

git checkout -b μ‚¬μš© μ‹œλ‚˜λ¦¬μ˜€

git checkout -b λͺ…λ Ήμ–΄λŠ” μƒˆλ‘œμš΄ 브랜치λ₯Ό μƒμ„±ν•˜κ³  ν•΄λ‹Ή 브랜치둜 λ°”λ‘œ μ „ν™˜ν•˜λŠ” μž‘μ—…μ„ ν•œ λ²ˆμ— μˆ˜ν–‰ν•©λ‹ˆλ‹€. 이 λͺ…λ Ήμ–΄λŠ” 특히 μƒˆλ‘œμš΄ κΈ°λŠ₯ 개발, 버그 μˆ˜μ •, μ‹€ν—˜μ μΈ μ‹œλ„ 등을 μœ„ν•œ μƒˆλ‘œμš΄ μž‘μ—… 브랜치λ₯Ό μ‹œμž‘ν•  λ•Œ μœ μš©ν•©λ‹ˆλ‹€. git checkout -b λͺ…λ Ήμ–΄μ˜ 일반적인 μ‚¬μš©λ²•μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

1
git checkout -b [μƒˆλ‘œμš΄ 브랜치 이름]

이 λͺ…령은 ν˜„μž¬ 브랜치의 μƒνƒœλ₯Ό 기반으둜 [μƒˆλ‘œμš΄ 브랜치 이름]으둜 λͺ…λͺ…λœ μƒˆλ‘œμš΄ 브랜치λ₯Ό μƒμ„±ν•˜κ³ , 이 μƒˆλ‘œμš΄ 브랜치둜 μ „ν™˜(checkout)ν•©λ‹ˆλ‹€.

μ˜ˆμ‹œ: μƒˆλ‘œμš΄ κΈ°λŠ₯ κ°œλ°œμ„ μœ„ν•œ 브랜치 생성

예λ₯Ό λ“€μ–΄, μƒˆλ‘œμš΄ 둜그인 κΈ°λŠ₯을 κ°œλ°œν•˜κΈ° μœ„ν•΄ feature-loginμ΄λΌλŠ” 브랜치λ₯Ό μƒμ„±ν•˜κ³ μž ν•  λ•Œ, λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€:

1
git checkout -b feature-login

이 λͺ…λ Ήμ–΄λŠ” ν˜„μž¬ μœ„μΉ˜ν•œ 브랜치(예: main λ˜λŠ” develop)의 μ΅œμ‹  μƒνƒœλ₯Ό 기반으둜 feature-login 브랜치λ₯Ό μƒμ„±ν•˜κ³ , μžλ™μœΌλ‘œ ν•΄λ‹Ή 브랜치둜 μ „ν™˜ν•©λ‹ˆλ‹€. 이둜써 κ°œλ°œμžλŠ” μƒˆ κΈ°λŠ₯에 λŒ€ν•œ μž‘μ—…μ„ μ¦‰μ‹œ μ‹œμž‘ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

git checkout -b와 원격 브랜치

git checkout -b λͺ…λ Ήμ–΄λŠ” 원격 브랜치λ₯Ό 기반으둜 μƒˆλ‘œμš΄ 둜컬 브랜치λ₯Ό μƒμ„±ν•˜κ³  싢을 λ•Œλ„ μ‚¬μš©λ©λ‹ˆλ‹€. 이 경우 λͺ…λ Ήμ–΄ ν˜•μ‹μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

1
git checkout -b [μƒˆλ‘œμš΄ 둜컬 브랜치 이름] origin/[원격 브랜치 이름]

예λ₯Ό λ“€μ–΄, 원격 μ €μž₯μ†Œμ— μžˆλŠ” feature-login 브랜치λ₯Ό 기반으둜 λ‘œμ»¬μ—μ„œ λ™μΌν•œ μ΄λ¦„μ˜ 브랜치λ₯Ό μƒμ„±ν•˜λ €λ©΄, λ‹€μŒκ³Ό 같이 μ‹€ν–‰ν•©λ‹ˆλ‹€:

1
git checkout -b feature-login origin/feature-login

μ΄λŠ” μ›κ²©μ˜ feature-login 브랜치 μƒνƒœλ₯Ό λ³΅μ œν•˜μ—¬ λ‘œμ»¬μ— feature-login 브랜치λ₯Ό μƒμ„±ν•˜κ³ , ν•΄λ‹Ή 브랜치둜 μ „ν™˜ν•©λ‹ˆλ‹€.



-->