Git 커밋 기록을 깨끗하게 유지하는 방법 (그리고 이유!)

커밋은 Git 저장소의 핵심 부분 중 하나입니다. 그리고 커밋 메시지는 저장소의 수명 기록입니다. 프로젝트 / 저장소가 시간이 지남에 따라 발전함에 따라 (새로운 기능 추가, 버그 수정, 아키텍처 리팩토링) 커밋 메시지는 변경된 내용과 방법을 볼 수있는 곳입니다. 따라서 이러한 메시지는 기본 변경 사항을 짧고 정확하게 반영하는 것이 중요합니다.

의미있는 Git 커밋 기록이 중요한 이유

Git 커밋은 무엇을합니까? Git 커밋 메시지 터치 한 코드에 남긴 지문입니다. 오늘 커밋하는 코드, 지금부터 1 년 후 동일한 변경 사항을 볼 때, 여러분이 작성한 명확하고 의미있는 커밋 메시지에 감사 할 것입니다. 동료 개발자의 삶을 더 쉽게 만듭니다. 컨텍스트를 기반으로 커밋을 분리하면 특정 커밋으로 인해 발생한 버그를 더 빨리 찾을 수 있고, 처음에 버그를 일으킨 커밋을 되 돌리는 것이 더 쉬워집니다.

대규모 프로젝트에서 작업하는 동안 업데이트, 추가 또는 제거되는 많은 움직이는 부분을 처리하는 경우가 많습니다. 이러한 경우 커밋 메시지를 유지하는 것은 까다로울 수 있습니다. 특히 개발이 며칠에 걸쳐 진행되는 경우에는 더욱 그렇습니다. 몇 주, 심지어 몇 달. 그래서 concis를 유지하는 노력을 단순화하기 위해 e 커밋 기록,이 기사에서는 개발자가 Git 저장소에서 작업하는 동안 직면 할 수있는 몇 가지 일반적인 상황을 사용합니다.

  • 상황 1 : 가장 최근 커밋을 변경해야합니다
  • 상황 2 : 특정 커밋을 변경해야합니다.
  • 상황 3 : 커밋을 추가, 제거 또는 결합해야합니다.
  • 상황 4 : 내 커밋 기록이 새로운 시작이 필요합니다!

하지만 들어가기 전에 가상의 Ruby 애플리케이션에서 일반적인 개발 워크 플로가 어떻게 보이는지 빠르게 살펴 보겠습니다.

참고 :이 기사에서는 Git의 기본 사항, 분기 작동 방식, 단계에 분기의 커밋되지 않은 변경 사항을 추가하는 방법 및 변경 사항을 커밋하는 방법을 알고 있다고 가정합니다. 이러한 흐름이 확실하지 않은 경우 문서가 좋은 출발점입니다.

하루의 하루

여기에서 소규모 Ruby on Rails 프로젝트를 진행하고 있습니다. 홈페이지에 탐색보기를 추가해야하며 여기에는 여러 파일을 업데이트하고 추가해야합니다. 다음은 전체 흐름을 단계별로 분석 한 것입니다.

  • 파일 업데이트로 기능 작업을 시작합니다. ; application_controller.rb
  • 이 기능을 사용하려면 뷰도 업데이트해야합니다. index.html.haml
  • 색인 페이지에 사용되는 부분을 추가했습니다. _navigation.html.haml
  • 추가 된 부분을 반영하도록 페이지 스타일도 업데이트해야합니다. styles.css.scss
  • 이제 기능이 원하는 변경 사항과 함께 준비되었으며 테스트도 업데이트 할 시간입니다. 업데이트 할 파일은 다음과 같습니다.
    • application_controller_spec.rb
    • navigation_spec.rb
  • 테스트가 예상대로 업데이트되고 통과되었습니다. 이제 변경 사항을 커밋 할 시간입니다!

모든 파일이 아키텍처의 다른 영역에 속하므로 커밋합니다. 각 커밋이 특정 컨텍스트를 나타내며 특정 순서로 이루어 지도록하기 위해 서로 격리 된 변경 사항입니다. 저는 보통 백엔드-> 프런트 엔드 순서를 선호합니다. 대부분의 백엔드 중심 변경이 먼저 커밋되고 중간 레이어가 이어지고 Git 목록에서 프런트 엔드 중심 변경이 커밋됩니다.

이제 변경 사항을 커밋 했으므로 분기와 병합 요청을 만듭니다. 병합 요청이 열리면 일반적으로 변경 사항이 저장소의 master 브랜치에 병합되기 전에 동료가 검토합니다. 이제 어떤 상황이 발생할 수 있는지 알아 보겠습니다. 코드 검토 중에.

상황 1 : 가장 최근 커밋을 변경해야합니다.

검토자가 styles.css.scss를 살펴본 사례를 상상해보십시오. 변경을 제안했습니다. 이 경우 스타일 시트 변경이 브랜치의 마지막 커밋의 일부이므로 변경하는 것이 매우 간단합니다. 이를 처리하는 방법은 다음과 같습니다.

  • 지점에서 styles.css.scss에 필요한 변경을 직접 수행합니다.
  • 한 번 변경을 마쳤습니다. 이러한 변경 사항을 스테이지에 추가합니다. git add styles.css.scss를 실행합니다.
  • 변경 사항이 준비되면 이러한 변경 사항을 마지막 커밋에 추가해야합니다. git commit --amend를 실행합니다.
    • 명령 분석 : 여기서는 git commit 명령에 모든 변경 사항을 수정하도록 요청합니다. 가장 최근 커밋에 스테이지합니다.
  • 이렇게하면 탐색을위한 스타일 추가 커밋 메시지가있는 Git 정의 텍스트 편집기에서 마지막 커밋이 열립니다.
  • CSS 선언 만 업데이트했기 때문에 커밋 메시지를 변경할 필요가 없습니다.이 시점에서 Git이 열어 준 텍스트 편집기를 저장하고 종료하면 변경 사항이 커밋에 반영됩니다.

기존 커밋을 수정 했으므로 이러한 변경이 필요합니다. git push --force-with-lease <remote_name> <branch_name>를 사용하여 원격 저장소로 강제 푸시됩니다. 이 명령은 로컬 리포지토리에서 방금 만든 업데이트 된 커밋으로 원격 리포지토리의 커밋 Add styles for navigation를 재정의합니다.

브랜치를 강제로 푸시 할 때 유의해야 할 한 가지 사항 여러 사람과 동일한 브랜치에서 작업하는 경우 강제 푸시는 다른 사용자가 새 커밋이 강제로 푸시 된 원격 브랜치에서 변경 사항을 정상적으로 푸시하려고 할 때 문제를 일으킬 수 있다는 것입니다. 따라서이 기능을 현명하게 사용하십시오. 여기에서 Git 강제 푸시 옵션에 대해 자세히 알아볼 수 있습니다.

상황 2 : 특정 커밋을 변경해야합니다.

이전 상황에서는 수정해야했기 때문에 수정이 다소 간단했습니다. 마지막 Git 커밋 일 뿐이지 만 리뷰어가 _navigation.html.haml에서 무언가 변경을 제안했다고 상상해보세요. 이 경우에는 맨 위에서 두 번째 커밋이므로 변경은 첫 번째 상황 에서처럼 직접적이지 않습니다.이를 처리하는 방법을 살펴 보겠습니다.

커밋이 분기에서 만들어지면 고유 한 SHA1 해시 문자열로 식별됩니다. 하나의 커밋을 다른 커밋과 구분하는 고유 ID로 생각하십시오. git log를 실행하여 분기의 SHA1 해시와 함께 모든 커밋을 볼 수 있습니다. 이렇게하면 다음과 같은 출력이 표시되며 가장 최근 커밋이 맨 위에 있습니다.

여기서 git rebase 명령이 작동합니다. git rebase를 사용하여 특정 커밋을 편집 할 때마다 먼저 HEAD를 편집하려는 커밋 직전 지점으로 다시 이동하여 분기를 리베이스해야합니다. 이 경우 Page Navigation View라는 커밋을 변경해야합니다.

여기에서 수정하려는 커밋 바로 앞에있는 커밋 해시를 확인합니다. 해시를 복사하고 다음 단계를 수행합니다.

  • 대상 커밋 전에 커밋으로 이동하도록 브랜치를 리베이스합니다. git rebase -i 8d74af102941aa0b51e1a35b8ad731284e4b5a20
    • 실행 명령 분석 : 여기에서는 제공된 SHA1 해시를 사용하여 대화 형 모드로 Git의 rebase 명령을 실행합니다. 리베이스 할 커밋으로.
  • 대화 형 모드에서 Git에 대한 rebase 명령을 실행하고 리베이스 한 커밋 이후에 발생한 모든 커밋을 보여주는 텍스트 편집기가 열립니다. . 다음과 같이 보일 것입니다.

각 커밋에 앞에 있으며 아래 내용에는 사용할 수있는 모든 키워드가 있습니다. 커밋을 편집하고 싶기 때문에 pick 4155df1cdc7 Page Navigation Viewedit 4155df1cdc7 Page Navigation View로 변경해야합니다. 변경 사항을 저장하고 편집기를 종료합니다.

이제 브랜치는 _navigation.html.haml가 포함 된 커밋 직전 시점으로 리베이스됩니다. 파일을 열고 검토 피드백에 따라 원하는 변경을 수행합니다. 변경이 완료되면 git add _navigation.html.haml를 실행하여 준비합니다.

변경 사항을 준비 했으므로 분기 HEAD를 다시 우리가 원래 가지고 있었던 커밋 (새로 추가 한 변경 사항도 포함)하고 git rebase --continue를 실행하면 터미널에서 기본 편집기가 열리고 리베이스 중에 편집 한 커밋 메시지가 표시됩니다. Page Navigation View. 원하는 경우이 메시지를 변경할 수 있지만 지금은 그대로 두므로 편집기를 저장하고 종료합니다.이 시점에서 Git은 모든 커밋을 재생합니다. 방금 편집 한 커밋 이후에 이어졌고 이제 브랜치 HEAD가 우리가 원래 가지고 있던 맨 위 커밋으로 돌아가며 커밋 중 하나에 대한 새로운 변경 사항도 포함합니다.

이미 원격 저장소에있는 커밋을 다시 수정 했으므로 git push --force-with-lease <remote_name> <branch_name>를 사용하여이 분기를 다시 강제 푸시해야합니다.

상황 3 : 커밋을 추가, 제거 또는 결합해야합니다.

일반적인 상황은 이전에 커밋 된 것을 고치기 위해 여러 커밋을 수행 한 경우입니다. 이제 가능한 한 많이 줄여서 원래 커밋과 결합 해 보겠습니다.

다른 시나리오 에서처럼 대화 형 리베이스를 시작하기 만하면됩니다.

이제 이러한 모든 수정 사항을 c22a3fa0c5c Render navigation partial에 결합한다고 가정 해보십시오. 다음을 수행하면됩니다.

  1. 최종 유지하려는 커밋 바로 아래에 있도록 수정 사항을 이동합니다.
  2. picksquash 또는 fixup (각 수정 사항)

참고 : squash는 설명에 커밋 메시지를 유지합니다. fixup는 수정 사항의 커밋 메시지를 무시하고 원본을 유지합니다.

다음과 같은 결과가 나타납니다.

변경 사항을 저장하고 편집기를 종료합니다. , 그러면 완료됩니다! 결과 기록은 다음과 같습니다.

이전과 마찬가지로 지금해야 할 일은 git push --force-with-lease <remote_name> <branch_name> 및 변경 사항이 있습니다.

squash 또는 fixup, drop를 작성하거나 단순히 해당 줄을 삭제하십시오.

충돌 방지

충돌을 방지하려면 “타임 라인을 위로 이동하는 것은 그 뒤에 남겨진 커밋이 건 드리는 동일한 파일을 건드리지 않습니다.

프로 팁 : 빠른 수정

수정할 커밋을 정확히 알고 있다면 커밋 할 때 “수정 1”, “수정 2”,…에 대한 좋은 임시 이름을 생각하면서 두뇌주기를 낭비 할 필요가 없습니다. “Fix 42”.

1 단계 : --fixup

수정이 필요한 사항을 수정 한 후 변경 사항을 준비한 후 Git은 다음과 같이 모든 변경 사항을 커밋합니다.

(이것은 커밋 c22a3fa0c5c Render navigation partial의 해시입니다.)

다음 커밋 메시지를 생성합니다. fixup! Render navigation partial.

2 단계 : 조수 --autosquash

쉬운 대화 형 리베이스. gitfixup을 올바른 위치에 자동으로 배치하도록 할 수 있습니다.

git rebase -i 4155df1cdc7 --autosquash

기록은 다음과 같이 표시됩니다.

검토하고 진행하십시오.

모험이 있다고 느끼면 비대화 형 리베이스 git rebase --autosquash를 수행 할 수 있지만 위험하게 사는 것을 좋아하는 경우에만 가능합니다. 적용되기 전에 만들어지는 스쿼시를 검토 할 기회가 없습니다.

상황 4 : 내 Git 커밋 내역이 의미가 없습니다. 새로 시작해야합니다.

“대규모 기능에 대해 작업 중입니다. 자주 커밋되는 몇 가지 수정 및 검토 피드백 변경 사항이있는 것이 일반적입니다. 분기를 지속적으로 리베이스하는 대신 개발이 끝날 때까지 커밋을 정리하지 않아도됩니다.

여기에서 패치 파일을 만드는 것이 매우 편리합니다. 실제로 패치 파일은 공동 작업 중에 이메일을 통해 코드를 공유하는 주요 방법이었습니다. GitLab과 같은 Git 기반 서비스가 개발자에게 제공되기 전에 대규모 오픈 소스 프로젝트에서. 근본적인 변경 사항을 명확하게 전달하지 않는 수많은 커밋이있는 그러한 분기 (예 : add-page-navigation)가 있다고 가정 해보십시오. 다음은 모든 사용자를위한 패치 파일을 만드는 방법입니다. 이 브랜치에서 변경 한 사항 :

  • 패치 파일을 만드는 첫 번째 단계는 브랜치에 master 분기하고 동일한 항목과 충돌하지 않습니다.
  • 확인하는 동안 git rebase master 또는 git merge master를 실행할 수 있습니다. add-page-navigation 브랜치에서 master의 모든 변경 사항을 브랜치로 가져옵니다.
  • 이제 패치 파일을 만듭니다. ; git diff master add-page-navigation > ~/add_page_navigation.patch를 실행합니다.
    • 명령 분석 : 여기서는 Git의 diff 기능을 사용하고 master 분기 및 add-page-navigation 분기 및 출력 (> 기호를 통해)을 우리의 er 홈 디렉토리 (* nix 운영 체제에서는 일반적으로 ~/)
  • 이 파일을 보관할 경로를 지정할 수 있습니다. 파일 이름과 확장자는 원하는대로 지정할 수 있습니다.
  • 명령이 실행되고 오류가 표시되지 않으면 패치 파일이 생성됩니다.
  • 지금 체크 아웃 master 지점; git checkout master를 실행합니다.
  • 로컬 저장소에서 브랜치 add-page-navigation를 삭제합니다. git branch -D add-page-navigation를 실행합니다. 이미 생성 된 패치 파일에이 분기의 변경 사항이 있음을 기억하십시오.
  • 이제 동일한 이름으로 새 분기를 생성하십시오 (master가 체크 아웃되는 동안). git checkout -b add-page-navigation를 실행합니다.
  • 이 시점에서 이것은 새로운 브랜치이며 변경 사항이 없습니다.
  • 마지막으로 적용 패치 파일의 변경 사항; git apply ~/add_page_navigation.patch.
  • 여기에서 모든 변경 사항이 브랜치에 적용되며 모든 수정 사항이 커밋되지 않은 것처럼 표시됩니다. 완료되었지만 실제로 브랜치에서 수정 된 사항은 없습니다.
  • 이제 간결한 커밋 메시지로 원하는 순서대로 영향 영역별로 그룹화 된 개별 파일 또는 파일을 커밋 할 수 있습니다.
  • li>

이전 상황과 마찬가지로 기본적으로 전체 분기를 수정 했으므로 이제 강제로 밀어 넣을 시간입니다!

결론

Git을 사용하여 일상적인 워크 플로에서 발생하는 가장 일반적인 기본 상황을 다루었지만 Git 기록을 다시 작성하는 것은 방대한 주제이며 익숙해지면 위의 팁에서 Git 공식 문서에서 주제에 대한 고급 개념을 배울 수 있습니다. 행복한 git “ing!

Unsplash의 pan xiaozhen의 사진

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다