# Django 6.0.7 문서

# 코드 커밋

이 섹션은 머저(merger)와 Django에 코드가 어떻게 커밋되는지 알고자 하는 모든 사람을 대상으로 합니다. :ref:`committing-guidelines`는 커밋 권한 유무와 관계없이 모든 기여자에게 동일하게 적용됩니다.

Django에 코드를 기여하고 싶은 커뮤니티 구성원이라면 :doc:`/internals/contributing/writing-code/working-with-git`를 살펴보세요.

## pull requests 처리

장고는 깃허브에서 호스팅되기 때문에 패치는 pull requests 형태로 제공된다.

pull request를 제출할 때는 각 커밋이 아래에 명시된 가이드라인을 준수해야 합니다. 기여자는 pull request를 가능한 한 최선의 상태로 준비하는 것이 기대되며, 상황에 따라 가이드라인에 더 익숙한 머저가 직접 커밋을 수정하여 기준에 맞출 수도 있습니다.

Jenkins 또는 GitHub 작업이 Oracle 또는 Selenium과 같이 자동으로 실행되지 않는 pull request 빌더 중 하나를 사용하여 pull request를 테스트하도록 할 수 있습니다. 자세한 내용은 ‘CI Wiki 페이지’_를 참조하십시오.

로컬에서 pull request를 자주 체크아웃한다면, 다음과 같은 git 별칭이 유용합니다.

    [alias]
        pr = !sh -c \"git fetch upstream pull/${1}/head:pr/${1} && git checkout pr/${1}\"

“~.gitconfig”에 추가하고 “upstream”을 “django/django”로 설정합니다. 그런 다음 “gitpr ###”을 실행하여 해당 pull request를 확인할 수 있습니다.

이 시점에서 코드를 작업할 수 있습니다. “git rebase -i” 및 “git commit –amend”를 사용하여 커밋의 퀄리티가 예상된 수준인지 확인합니다. 준비가 되면:

/ 

    $ # Pull in the latest changes from main.
    $ git checkout main
    $ git pull upstream main
    $ # Rebase the pull request on main.
    $ git checkout pr/####
    $ git rebase main
    $ git checkout main
    $ # Merge the work as "fast-forward" to main to avoid a merge commit.
    $ # (in practice, you can omit "--ff-only" since you just rebased)
    $ git merge --ff-only pr/XXXX
    $ # If you're not sure if you did things correctly, check that only the
    $ # changes you expect will be pushed to upstream.
    $ git push --dry-run upstream main
    $ # Push!
    $ git push upstream main
    $ # Delete the pull request branch.
    $ git branch -d pr/xxxx

    ...\> REM Pull in the latest changes from main.
    ...\> git checkout main
    ...\> git pull upstream main
    ...\> REM Rebase the pull request on main.
    ...\> git checkout pr/####
    ...\> git rebase main
    ...\> git checkout main
    ...\> REM Merge the work as "fast-forward" to main to avoid a merge commit.
    ...\> REM (in practice, you can omit "--ff-only" since you just rebased)
    ...\> git merge --ff-only pr/XXXX
    ...\> REM If you're not sure if you did things correctly, check that only the
    ...\> REM changes you expect will be pushed to upstream.
    ...\> git push --dry-run upstream main
    ...\> REM Push!
    ...\> git push upstream main
    ...\> REM Delete the pull request branch.
    ...\> git branch -d pr/xxxx

주 베이스 리베이스 후 업스트림으로 병합 및 푸시하기 전에 분기로 강제 푸시합니다. 이렇게 하면 메인 및 분기의 커밋 해시가 일치하여 풀 요청이 자동으로 닫힙니다.

풀 요청을 여러 커밋으로 병합할 필요가 없는 경우 웹 사이트에서 GitHub의 “Squash and merge” 버튼을 사용할 수 있습니다. 필요에 따라 커밋 메시지를 편집하여 지침 ‘:ref:’에 준거하고 메시지의 첫 번째 줄에 자동으로 추가된 풀 요청 번호를 제거합니다.

꺼내기 요청의 커밋 이력을 다시 쓸 때 목표는 장고의 커밋 이력을 가능한 한 사용할 수 있게 만드는 것입니다.

- 패치에 앞뒤로 커밋이 포함된 경우 해당 커밋을 하나로 다시 씁니다. 예를 들어, 커밋이 일부 코드를 추가하고 두 번째 커밋이 첫 번째 커밋에서 도입된 스타일 문제를 수정하는 경우, 이러한 커밋은 병합하기 전에 스쿼시해야 합니다.

- 논리 그룹별로 다른 커밋에 대한 변경 내용 구분: 파일에 대한 다른 변경사항과 동시에 스타일 정리를 수행하는 경우 변경 내용을 두 개의 다른 커밋으로 분리하면 기록을 쉽게 검토할 수 있습니다.

- 풀 요청에서 업스트림 브랜치 병합에 주의하십시오.

- 테스트는 통과해야 하며 각 커밋 후에 문서를 작성해야 합니다. 검사나 문서 중 어느 것도 경고를 발하지 않아야 합니다.

- 일반적으로 사소한 패치와 작은 패치는 한 번의 커밋으로 수행하는 것이 가장 좋습니다. 중대형 작업은 의미가 있는 경우 여러 커밋으로 분할될 수 있습니다.

실용성은 순수함을 능가하므로, pull request를 위해 얼마나 많은 역사를 망칠지 결정하는 것은 각 merge에 달려 있습니다. 주요 포인트는 커뮤니티 참여, 작업 완료, 사용 가능한 커밋 기록 보유입니다.

## 커밋 가이드라인.

이러한 가이드라인은 기여자가 pull request를 통해 제출한 커밋이든, 머저가 직접 반영한 커밋이든 Django의 Git 저장소에 이루어지는 모든 커밋에 적용됩니다.

- “django/django” 지부의 출판 역사를 절대 억지로 밀어붙여서는 안 됩니다. 꼭 필요한 경우 (예를 들어 보안상의 이유로) 먼저 팀과 상황에 대해 논의합니다.

- 변경이 중간 규모 이상인지 여부는 기여자의 판단에 따르며, 해당되는 경우 변경 전에 `Django Forum`_에서 먼저 논의해주세요.

  논의를 제안했는데 아무도 반응하지 않더라도 이를 아이디어에 이의가 없다는 신호로 받아들여 바로 구현하려고 하지 마세요. 모든 사람이 항상 논의를 즉시 확인할 수 있는 것은 아니므로, 답변을 받기까지 며칠 정도 기다려야 할 수 있습니다.

- 커밋 메시지는 현재 시제가 아닌 과거 시제로 자세하게 작성하고 제목 끝에는 마침표를 붙이세요.

  - 올바른 예: “RSS API에서 Unicode 버그를 수정했습니다.”

  - 올바르지 않은 예: “RSS API에서 Unicode 버그를 수정합니다.” (현재 시제)

  - 올바르지 않은 예: “RSS API에서 Unicode 버그를 수정하는 중.” (-ing 형태)

  - 올바르지 않은 예: “RSS API에서 Unicode 버그를 수정했습니다” (마침표 누락)

  커밋 메시지는 한 줄당 최대 72자로 작성해야 합니다. 제목 줄을 작성한 뒤 빈 줄로 구분하고, 그 아래에 각 줄이 72자를 넘지 않는 단락을 작성합니다. 이 제한은 엄격하게 지켜야 하는 규칙은 아니지만, 제목 줄은 짧을수록 좋습니다.

  커밋 메시지의 본문은 자세할수록 좋으며, 무엇*이나 *어떻게*가 아니라 *왜 변경되었는지를 설명해야 합니다. 코드 자체가 변경 내용을 보여주므로, 커밋 메시지는 코드만으로 알 수 없는 문맥과 이유를 제공해야 합니다.

  Credit the contributors in the commit message: “Thanks A for the report and B for review.” Use git’s Co-Authored-By as appropriate, including anyone whose earlier work the change builds on.

  예시:

      Fixed #18307 -- Added git workflow guidelines.

      Refactored the Django's documentation to remove mentions of SVN
      specific tasks. Added guidelines of how to use Git, GitHub, and
      how to use pull request together with Trac instead.

      Thanks to Full Name for the report, and to Reviewer for reviews.

- 가장 세밀한 변경 사항으로 커밋을 제한합니다. 즉, 큰 커밋은 자주 사용하지 않고 작은 커밋을 자주 사용합니다. 예를 들어, 기능 X를 구현하기 위해 라이브러리 Y에 대한 작은 변경이 필요한 경우, 먼저 변경사항을 라이브러리 Y에 커밋한 다음 별도의 커밋에서 기능 X를 커밋합니다. 이는 모든 사람이 귀사의 변화를 따르도록 돕는 데 큰 도움이 됩니다.

- Separate bug fixes from feature changes. Bugfixes may need to be backported.

- 커밋이 Django “ticket tracker”에서 티켓을 닫는 경우 커밋 메시지를 “Fixed #xxxxx” 텍스트로 시작합니다. 여기서 “xxxxx”는 커밋이 수정하는 티켓 번호입니다. 예: “고정 #123 - Whizbang 기능 추가” 해당 형식의 커밋 메시지가 자동으로 참조된 티켓을 닫고 전체 커밋 메시지와 함께 의견을 게시하도록 Trac을 조정했습니다.

  궁금하신 분들을 위해 우리는 Trac plugin_을 사용하고 있습니다.

참고

Trac 통합은 꺼내기 요청에 대해 전혀 알지 못합니다. 따라서 커밋 메시지에 “closes #400”이라는 문구로 풀 요청을 닫으려고 하면 GitHub은 풀 요청을 닫지만 Trac 플러그인은 Trac에서 동일한 번호의 티켓을 닫지 않습니다.

- 커밋이 Django “ticket tracker”_의 티켓을 참조하지만 *티켓을 닫지 않는 경우 “Refs #xxxx” 구문을 포함하십시오. 여기서 “xxxxx”는 커밋이 참조하는 티켓 번호입니다. 그러면 해당 티켓에 대한 설명이 자동으로 게시됩니다.

## Backports

Bug fix backports to stable branches are done exclusively by mergers, following the 지원되는 버전. A backport consists of cherry-picking a commit from `main` onto the target `stable/A.B.x` branch.

A backport commit must include two things beyond the original commit message:

- A prefix `[A.B.x]` on the subject line, where `A.B.x` is the name of the `stable/A.B.x` branch being targeted.

- A suffix `Backport of <sha> from main.` line in the commit body, pointing to the original commit hash.

예시:

    [1.3.x] Fixed #17028 -- Changed diveintopython.org -> diveintopython.net.

    Backport of 80c0cbf1c97047daed2c5b41b296bbc56fe1d7e3 from main.

If the backport also fixes a regression, add a line identifying the commit that introduced it:

    Regression in 6ecccad711b52f9273b1acb07a57d3f806e93928.

There are three ways to do a backport, depending on your workflow:

Option 1: fully manual

Cherry-pick the commit onto the stable branch, then amend the commit message to add the required prefix and backport note:

    git cherry-pick <sha>
    git commit --amend

If the cherry-pick produces conflicts, resolve them, stage the changes, then run `git cherry-pick --continue` before amending. This option requires no setup but relies entirely on remembering to format the message correctly.

Option 2: using the helper script in the repo

The `scripts/backport.sh` Bash script automates the cherry-pick and rewrites the commit message with the correct prefix and backport note. Run it from the target stable branch:

    bash scripts/backport.sh <sha>

This is straightforward for clean cherry-picks, but if conflicts are produced, you will need to resolve them manually and add the prefix and backport note to the commit message yourself.

Option 3: using the `prepare-commit-msg` git hook

The `scripts/prepare_commit_msg.py` Python script can be installed as a `prepare-commit-msg` git hook. It automatically adds the `[A.B.x]` prefix to the subject line, appends `Backport of <sha> from main.` to the commit body, and ensures the subject line ends with a period, even when the cherry-pick produces conflicts. To install it, create an executable file `.git/hooks/prepare-commit-msg` containing:

    #!/bin/sh
    exec python scripts/prepare_commit_msg.py "$@"

Once installed, a plain `git cherry-pick <sha>` on a stable branch is sufficient; the hook handles the message formatting in all cases.

## 커밋 되돌리기

완벽한 사람은 없습니다. 실수가 있을 것입니다.

하지만 실수가 발생하지 않도록 각별히 주의하세요. 되돌리기 정책이 있다고 해서 최고 수준의 품질을 목표로 해야 하는 책임이 줄어드는 것은 아닙니다. 정말로, 커밋하기 전에 작업을 다시 확인하거나 다른 머저의 검토를 받으세요.

잘못된 커밋이 발견되면 다음 지침을 따르십시오.

- 가능한 경우, 원본 작성자가 자신의 커밋을 되돌리도록 합니다.

- 다른 작성자의 변경 내용을 원본 작성자의 허가 없이 되돌리지 마십시오.

- git revert 사용 - 역 커밋을 수행하지만 원래 커밋은 커밋 히스토리의 부분에 있을것입니다.

- 기존 작성자에게 합리적인 시간(하루 정도)이 지나도 연락이 닿지 않고, 문제가 충돌 버그나 주요 테스트 실패 등으로 심각한 경우에는 `Django Forum`_에서 이의가 있는지 먼저 확인한 뒤, 없다면 되돌리세요.

- 문제가 작을 경우(예: 기능이 정지된 후 커밋됨) 대기합니다.

- 머저와 되돌리려는 사람 사이에 이견이 있다면, `Django Forum`_에서 논의해 해결하세요. 합의에 이르지 못하면 표결에 부칩니다.

- 커밋이 확인되고 공개된 보안 취약성을 도입한 경우 다른 사람의 허가 없이 커밋을 즉시 되돌릴 수 있습니다.

- 릴리스 분기 유지 관리자는 커밋이 릴리스 분기를 중단하는 경우 허가 없이 릴리스 분기로 커밋을 백업할 수 있습니다.

- 주제 분기를 “django/django”로 잘못 누른 경우 삭제하십시오. 예를 들어 “git push upstream feature_antigravity”를 실행했다면 “git push upstream:feature_antigravity”를 역push 하십시오.