Showing posts with label git. Show all posts
Showing posts with label git. Show all posts

Tuesday, June 17, 2025

pre-commit으로 팀의 코드 품질 자동화하기

개발자라면 누구나 한 번쯤은 커밋 메시지에 "Fix typo"나 "Apply linter" 같은 내용을 적어본 경험이 있을 겁니다. 이런 사소한 실수는 코드 리뷰 과정에서 불필요한 시간을 소모하게 하고, 팀 전체의 생산성을 저하시키는 원인이 되기도 합니다. 만약 이런 실수를 커밋하기 전에 자동으로 바로잡을 수 있다면 어떨까요? 바로 이 지점에서 Git Hook, 특히 pre-commit hook이 강력한 해결책으로 등장합니다.

이 글에서는 Git Hook의 기본 개념부터 시작하여, 팀 단위 프로젝트에서 코드 품질을 일관되게 유지하고 개발 워크플로우를 혁신적으로 개선할 수 있는 pre-commit 프레임워크의 설정 및 활용법을 상세히 다룹니다.

Git Hook이란 무엇인가?

Git Hook은 Git의 특정 이벤트(예: 커밋, 푸시)가 발생했을 때 자동으로 실행되는 스크립트입니다. 이를 통해 개발자는 특정 조건이 충족되지 않았을 때 커밋을 막거나, 커밋 메시지 형식을 강제하거나, 테스트를 자동으로 실행하는 등 다양한 자동화 작업을 수행할 수 있습니다.

Git Hook 스크립트는 모든 Git 저장소의 .git/hooks/ 디렉토리 안에 위치합니다. git init으로 새로운 저장소를 생성하면, 이 디렉토리 안에 다양한 샘플 훅(.sample 확장자)들이 생성된 것을 볼 수 있습니다.

$ ls .git/hooks/
applypatch-msg.sample         pre-commit.sample           pre-rebase.sample
commit-msg.sample             pre-merge-commit.sample     pre-receive.sample
fsmonitor-watchman.sample     pre-push.sample             update.sample
post-update.sample            prepare-commit-msg.sample

이 샘플 파일들 중 하나의 확장자에서 .sample을 제거하고 실행 권한을 부여하면 해당 훅이 활성화됩니다. 예를 들어, pre-commit.sample 파일의 이름을 pre-commit으로 바꾸고 실행 권한을 주면, git commit 명령을 실행하기 직전에 해당 스크립트가 실행됩니다.

가장 강력한 훅: pre-commit

수많은 훅 중에서도 pre-commit은 가장 널리 사용되고 강력한 훅 중 하나입니다. 커밋이 실제로 생성되기 직전에 실행되기 때문에, 코드 품질과 관련된 거의 모든 검사를 이 단계에서 수행할 수 있습니다.

  • 코드 스타일 검사 (Linting): 코드가 팀의 코딩 컨벤션을 따르는지 확인합니다.
  • 코드 포맷팅 (Formatting): 정해진 규칙에 따라 코드 스타일을 자동으로 수정합니다.
  • 비밀 키 및 민감 정보 유출 방지: 커밋에 실수로 포함된 API 키나 비밀번호를 찾아냅니다.
  • 디버깅 코드 방지: console.logdebugger 같은 코드가 커밋되는 것을 막습니다.
  • 단위 테스트 실행: 커밋하려는 코드가 기존 테스트를 통과하는지 빠르게 확인합니다.

전통적인 Git Hook 방식의 한계

.git/hooks/ 디렉토리에 직접 셸 스크립트를 작성하는 방식은 간단하지만 팀 프로젝트에서는 몇 가지 치명적인 단점이 있습니다.

  1. 버전 관리가 안 된다: .git 디렉토리는 Git의 추적 대상이 아니므로, 훅 스크립트를 팀원들과 공유하고 버전을 관리하기가 매우 어렵습니다.
  2. 설정이 번거롭다: 새로운 팀원이 프로젝트에 합류할 때마다 수동으로 훅 스크립트를 설정하고 실행 권한을 부여해야 합니다.
  3. 다양한 언어 환경 지원의 어려움: 파이썬, 자바스크립트, 자바 등 여러 언어를 사용하는 프로젝트에서는 각 언어에 맞는 린터와 포맷터를 설정하고 관리하는 것이 복잡해집니다.

이러한 문제들을 해결하기 위해 등장한 것이 바로 pre-commit 프레임워크입니다.

pre-commit 프레임워크로 스마트하게 관리하기

pre-commit은 Python으로 만들어진 Git Hook 관리 프레임워크입니다. 이 프레임워크는 .pre-commit-config.yaml이라는 설정 파일을 통해 훅을 정의하고 관리합니다. 이 파일은 프로젝트 루트에 위치하여 버전 관리가 가능하므로, 팀원 모두가 동일한 훅 설정을 공유할 수 있습니다.

1. 설치 및 초기 설정

먼저, pre-commit을 설치합니다. Python 패키지 매니저인 pip를 사용하는 것이 일반적입니다.

# pip를 사용하여 설치
pip install pre-commit

# Homebrew (macOS)를 사용하여 설치
brew install pre-commit

설치가 완료되면, 프로젝트 루트 디렉토리에 .pre-commit-config.yaml 파일을 생성합니다. 이 파일에 우리가 사용할 훅들을 정의합니다.

다음은 기본적인 설정 파일 예시입니다.

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0 # 항상 최신 안정 버전을 사용하는 것이 좋습니다.
    hooks:
    -   id: trailing-whitespace # 파일 끝의 공백 제거
    -   id: end-of-file-fixer # 파일 끝에 개행 문자 추가
    -   id: check-yaml # YAML 파일 문법 검사
    -   id: check-added-large-files # 대용량 파일이 추가되는 것을 방지

설정 파일 작성이 끝났다면, 다음 명령어를 실행하여 Git Hook을 .git/hooks/pre-commit에 설치합니다. 이 과정은 프로젝트를 처음 클론받았을 때 한 번만 실행하면 됩니다.

pre-commit install

이제 git commit을 시도하면, pre-commit이 스테이징된 파일들에 대해 설정된 훅들을 자동으로 실행합니다.

2. 다양한 언어를 위한 훅 추가하기

pre-commit의 진정한 강력함은 다양한 언어와 도구를 손쉽게 통합할 수 있다는 점에서 나옵니다. 예를 들어, Python 프로젝트에서는 black(포맷터)과 ruff(린터), JavaScript 프로젝트에서는 prettier(포맷터)와 eslint(린터)를 추가할 수 있습니다.

Python 프로젝트 예시 (black, ruff)

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
-   repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
    -   id: black
-   repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.4
    hooks:
    -   id: ruff
        args: [--fix] # 자동으로 수정 가능한 오류는 수정
    -   id: ruff-format

JavaScript/TypeScript 프로젝트 예시 (prettier, eslint)

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
-   repo: https://github.com/prettier/prettier
    rev: 3.2.5
    hooks:
    -   id: prettier
        # 추가적인 인자를 전달하여 특정 파일 타입에만 적용 가능
        # types: [javascript, typescript, css, markdown]
-   repo: local # 로컬에 설치된 eslint를 사용하는 경우
    hooks:
    -   id: eslint
        name: eslint
        entry: npx eslint --fix
        language: node
        types: [javascript, typescript]
        # 초기 실행 속도를 위해 항상 실행되도록 설정
        always_run: true
        # 스테이징된 파일만 인자로 전달
        pass_filenames: false

repo: local을 사용하면, package.json에 명시된 버전의 도구를 사용할 수 있어 팀원 간의 도구 버전 불일치 문제를 해결할 수 있습니다.

3. 실제 워크플로우

이제 모든 설정이 완료되었습니다. 개발자가 코드를 수정한 후 커밋을 시도하면 어떤 일이 벌어질까요?

  1. 개발자가 파일을 수정하고 git add . 명령으로 스테이징합니다.
  2. git commit -m "피처 추가" 명령을 실행합니다.
  3. pre-commit이 자동으로 실행되어 .pre-commit-config.yaml에 정의된 훅들을 스테이징된 파일에 대해 순차적으로 실행합니다.
  4. 성공 시나리오: 모든 훅이 성공적으로 통과하면, 커밋이 정상적으로 완료됩니다.
    $ git commit -m "새로운 기능 추가"
    Trim Trailing Whitespace........................................Passed
    Fix End of Files................................................Passed
    Check Yaml......................................................Passed
    black...........................................................Passed
    ruff............................................................Passed
    [feature/new-logic 1a2b3c4] 새로운 기능 추가
     2 files changed, 15 insertions(+)
    
  5. 실패 시나리오: 하나 이상의 훅이 실패하면(예: 린팅 오류 발견), pre-commit은 해당 오류를 출력하고 커밋을 중단시킵니다.
    $ git commit -m "버그 수정"
    Trim Trailing Whitespace........................................Passed
    Fix End of Files................................................Passed
    black...........................................................Failed
    - hook id: black
    - files were modified by this hook
    
    reformatted my_bad_file.py
    
    All done! ✨ 🍰 ✨
    1 file reformatted.
    

    이 경우, black이나 prettier와 같이 자동 수정 기능이 있는 훅은 파일을 직접 수정합니다. 개발자는 수정된 파일을 다시 스테이징(git add my_bad_file.py)하고 다시 커밋을 시도하면 됩니다. 이 과정을 통해 지저분한 "Fix lint" 커밋 없이 항상 깔끔한 코드를 유지할 수 있습니다.

결론: 왜 pre-commit을 도입해야 하는가?

pre-commit 프레임워크를 도입하는 것은 단순한 도구 추가를 넘어, 개발 문화 자체를 개선하는 효과적인 방법입니다.

  • 일관성 있는 코드 품질: 모든 팀원이 동일한 규칙에 따라 코드를 작성하고 검사하므로, 프로젝트 전체의 코드 품질이 상향 평준화됩니다.
  • 리뷰 시간 단축: 코드 리뷰어는 스타일이나 사소한 오류 대신 비즈니스 로직에 더 집중할 수 있습니다.
  • 자동화된 워크플로우: 개발자는 린팅이나 포맷팅 같은 반복적인 작업을 신경 쓸 필요 없이 개발에만 집중할 수 있습니다.
  • 실수 방지: 민감 정보나 디버깅 코드가 저장소에 커밋되는 것을 사전에 차단하여 보안을 강화합니다.

처음에는 설정을 추가하고 팀원들에게 사용법을 안내하는 약간의 노력이 필요할 수 있습니다. 하지만 이 작은 투자는 장기적으로 팀의 생산성을 극대화하고, 더 견고하고 유지보수하기 쉬운 코드를 만드는 밑거름이 될 것입니다. 지금 바로 여러분의 프로젝트에 pre-commit을 도입하여 자동화된 코드 품질 관리의 힘을 경험해 보세요.

Automating Code Quality: A Practical Guide to Git Pre-Commit Hooks

If you're a developer, you've likely made commits with messages like "Fix typo" or "Apply linter." These minor mistakes can consume unnecessary time during code reviews and hinder the entire team's productivity. What if you could automatically fix these issues before they are even committed? This is where Git Hooks, and specifically the pre-commit hook, emerge as a powerful solution.

This article will cover everything from the basic concepts of Git Hooks to a detailed guide on setting up and using the pre-commit framework to consistently maintain code quality and revolutionize your development workflow in a team environment.

What Are Git Hooks?

Git Hooks are scripts that run automatically when a specific Git event occurs, such as a commit or a push. They allow developers to perform various automated tasks, like preventing a commit if certain conditions aren't met, enforcing a commit message format, or automatically running tests.

Git Hook scripts are located in the .git/hooks/ directory of every Git repository. When you create a new repository with git init, you'll find this directory populated with various sample hooks (with a .sample extension).

$ ls .git/hooks/
applypatch-msg.sample         pre-commit.sample           pre-rebase.sample
commit-msg.sample             pre-merge-commit.sample     pre-receive.sample
fsmonitor-watchman.sample     pre-push.sample             update.sample
post-update.sample            prepare-commit-msg.sample

To activate a hook, you simply remove the .sample extension from one of these files and make it executable. For example, if you rename pre-commit.sample to pre-commit and grant it execute permissions, that script will run just before you execute a git commit command.

The Most Powerful Hook: pre-commit

Among the many hooks available, pre-commit is one of the most widely used and powerful. Because it runs just before a commit is actually created, it's the perfect stage to perform nearly any check related to code quality.

  • Code Style Checking (Linting): Ensures that code adheres to the team's coding conventions.
  • Code Formatting: Automatically reformats code according to a predefined set of rules.
  • Preventing Secret Leaks: Detects API keys or passwords accidentally included in a commit.
  • Blocking Debug Code: Prevents code like console.log or debugger from being committed.
  • Running Unit Tests: Quickly verifies that the code being committed passes existing tests.

The Limitations of the Traditional Git Hook Approach

While writing shell scripts directly in the .git/hooks/ directory is straightforward, it has several critical drawbacks for team projects.

  1. Not Version-Controlled: The .git directory is not tracked by Git, making it extremely difficult to share and version-control hook scripts with team members.
  2. Cumbersome Setup: Every time a new team member joins the project, they must manually set up the hook scripts and grant execute permissions.
  3. Difficulty Supporting Multi-Language Environments: In projects using multiple languages like Python, JavaScript, and Java, setting up and managing the appropriate linters and formatters for each language becomes complex.

The pre-commit framework was created to solve these very problems.

Smart Management with the pre-commit Framework

pre-commit is a Git Hook management framework built in Python. It defines and manages hooks through a configuration file named .pre-commit-config.yaml. This file is placed in the project root, making it version-controllable, so every team member can share the exact same hook configuration.

1. Installation and Initial Setup

First, install pre-commit. Using the Python package manager, pip, is the most common method.

# Install using pip
pip install pre-commit

# Install using Homebrew (macOS)
brew install pre-commit

Once installed, create a .pre-commit-config.yaml file in your project's root directory. This file will define the hooks we want to use.

Here is an example of a basic configuration file:

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0 # It's always a good idea to use the latest stable version.
    hooks:
    -   id: trailing-whitespace # Trims trailing whitespace.
    -   id: end-of-file-fixer # Ensures a file is either empty or ends with a newline.
    -   id: check-yaml # Checks yaml files for parseable syntax.
    -   id: check-added-large-files # Prevents giant files from being committed.

After creating the configuration file, run the following command to install the Git hook into .git/hooks/pre-commit. This step only needs to be done once when you first clone the project.

pre-commit install

Now, when you attempt to git commit, pre-commit will automatically run the configured hooks on the staged files.

2. Adding Hooks for Different Languages

The true power of pre-commit lies in its ability to easily integrate with various languages and tools. For instance, you can add black (formatter) and ruff (linter) for a Python project, or prettier (formatter) and eslint (linter) for a JavaScript project.

Example for a Python Project (black, ruff)

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
-   repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
    -   id: black
-   repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.4
    hooks:
    -   id: ruff
        args: [--fix] # Automatically fix what can be fixed.
    -   id: ruff-format

Example for a JavaScript/TypeScript Project (prettier, eslint)

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
-   repo: https://github.com/prettier/prettier
    rev: 3.2.5
    hooks:
    -   id: prettier
        # You can pass additional arguments to target specific file types
        # types: [javascript, typescript, css, markdown]
-   repo: local # Use locally installed eslint
    hooks:
    -   id: eslint
        name: eslint
        entry: npx eslint --fix
        language: node
        types: [javascript, typescript]
        # To improve initial run speed, set it to always run
        always_run: true
        # Pass only staged files as arguments
        pass_filenames: false

Using repo: local allows you to use the tool versions specified in your package.json, resolving tool version mismatch issues among team members.

3. The Actual Workflow

Now that everything is set up, what happens when a developer tries to commit their code?

  1. A developer modifies files and stages them with git add ..
  2. They run the command git commit -m "Add new feature".
  3. pre-commit runs automatically, executing the hooks defined in .pre-commit-config.yaml sequentially on the staged files.
  4. Success Scenario: If all hooks pass successfully, the commit is completed normally.
    $ git commit -m "Add new feature"
    Trim Trailing Whitespace........................................Passed
    Fix End of Files................................................Passed
    Check Yaml......................................................Passed
    black...........................................................Passed
    ruff............................................................Passed
    [feature/new-logic 1a2b3c4] Add new feature
     2 files changed, 15 insertions(+)
    
  5. Failure Scenario: If one or more hooks fail (e.g., a linting error is found), pre-commit will print the error and abort the commit.
    $ git commit -m "Fix bug"
    Trim Trailing Whitespace........................................Passed
    Fix End of Files................................................Passed
    black...........................................................Failed
    - hook id: black
    - files were modified by this hook
    
    reformatted my_bad_file.py
    
    All done! ✨ 🍰 ✨
    1 file reformatted.
    

    In this case, hooks with auto-fixing capabilities, like black or prettier, will modify the files directly. The developer simply needs to stage the modified files again (git add my_bad_file.py) and re-attempt the commit. This process ensures a clean commit history without messy "Fix lint" commits.

Conclusion: Why Should You Adopt pre-commit?

Adopting the pre-commit framework is more than just adding a tool; it's an effective way to improve your development culture.

  • Consistent Code Quality: Since every team member writes and checks code against the same rules, the overall code quality of the project is elevated.
  • Reduced Review Time: Code reviewers can focus on business logic instead of style nits or minor errors.
  • Automated Workflow: Developers can concentrate on development without worrying about repetitive tasks like linting or formatting.
  • Mistake Prevention: It enhances security by preventing sensitive information or debug code from being committed to the repository.

Initially, it may require a small effort to add the configuration and guide your team on how to use it. However, this small investment will pay off in the long run by maximizing team productivity and laying the foundation for more robust and maintainable code. Introduce pre-commit to your project today and experience the power of automated code quality management.

pre-commitフックで実現する、チーム開発の品質自動化

開発者であれば、「タイポ修正」や「リンター適用」といったコミットメッセージを一度は書いた経験があるでしょう。このような些細なミスは、コードレビューの過程で不要な時間を消費させ、チーム全体の生産性を低下させる原因となります。もし、これらのミスをコミットする前に自動的に修正できるとしたらどうでしょうか?まさにこの点で、Gitフック、特にpre-commitフックが強力な解決策として登場します。

この記事では、Gitフックの基本概念から始め、チーム単位のプロジェクトでコード品質を一貫して維持し、開発ワークフローを革新的に改善できるpre-commitフレームワークの設定と活用法を詳しく解説します。

Gitフックとは何か?

Gitフックとは、Gitの特定のイベント(例:コミット、プッシュ)が発生した際に自動的に実行されるスクリプトです。これにより、開発者は特定の条件が満たされない場合にコミットを中止させたり、コミットメッセージのフォーマットを強制したり、テストを自動実行したりするなど、様々な自動化タスクを実行できます。

Gitフックのスクリプトは、すべてのGitリポジトリの.git/hooks/ディレクトリ内に配置されています。git initで新しいリポジトリを作成すると、このディレクトリ内に様々なサンプル(.sample拡張子)が生成されているのを確認できます。

$ ls .git/hooks/
applypatch-msg.sample         pre-commit.sample           pre-rebase.sample
commit-msg.sample             pre-merge-commit.sample     pre-receive.sample
fsmonitor-watchman.sample     pre-push.sample             update.sample
post-update.sample            prepare-commit-msg.sample

これらのサンプルファイルの一つから.sampleという拡張子を削除し、実行権限を付与することで、そのフックが有効になります。例えば、pre-commit.sampleファイルの名前をpre-commitに変更して実行権限を与えると、git commitコマンドを実行する直前にそのスクリプトが実行されるようになります。

最も強力なフック:pre-commit

数あるフックの中でも、pre-commitは最も広く使われ、強力なフックの一つです。コミットが実際に作成される直前に実行されるため、コード品質に関連するほぼすべてのチェックをこの段階で実行できます。

  • コードスタイルチェック(リンティング):コードがチームのコーディング規約に従っているか確認します。
  • コードフォーマット:定められたルールに従ってコードスタイルを自動的に修正します。
  • 秘密鍵や機密情報の漏洩防止:コミットに誤って含まれたAPIキーやパスワードを検出します。
  • デバッグ用コードの混入防止:console.logdebuggerのようなコードがコミットされるのを防ぎます。
  • ユニットテストの実行:コミットしようとしているコードが既存のテストをパスするかを素早く確認します。

従来のGitフック方式の限界

.git/hooks/ディレクトリに直接シェルスクリプトを作成する方法はシンプルですが、チームプロジェクトではいくつかの致命的な欠点があります。

  1. バージョン管理ができない:.gitディレクトリはGitの追跡対象ではないため、フックスクリプトをチームメンバーと共有し、バージョンを管理することが非常に困難です。
  2. 設定が煩雑:新しいチームメンバーがプロジェクトに参加するたびに、手動でフックスクリプトを設定し、実行権限を付与する必要があります。
  3. 多様な言語環境への対応の難しさ:Python、JavaScript、Javaなど複数の言語を使用するプロジェクトでは、各言語に適したリンターやフォーマッターを設定・管理することが複雑になります。

これらの問題を解決するために登場したのが、pre-commitフレームワークです。

pre-commitフレームワークによるスマートな管理

pre-commitはPythonで作成されたGitフック管理フレームワークです。このフレームワークは、.pre-commit-config.yamlという設定ファイルを通じてフックを定義・管理します。このファイルはプロジェクトのルートに配置され、バージョン管理が可能なため、チームメンバー全員が同じフック設定を共有できます。

1. インストールと初期設定

まず、pre-commitをインストールします。Pythonのパッケージマネージャーであるpipを使用するのが一般的です。

# pipを使用してインストール
pip install pre-commit

# Homebrew (macOS)を使用してインストール
brew install pre-commit

インストールが完了したら、プロジェクトのルートディレクトリに.pre-commit-config.yamlファイルを作成します。このファイルに、使用するフックを定義します。

以下は基本的な設定ファイルの例です。

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0 # 常に最新の安定版を使用することを推奨します
    hooks:
    -   id: trailing-whitespace # ファイル末尾の空白を削除
    -   id: end-of-file-fixer # ファイルの末尾に改行を追加
    -   id: check-yaml # YAMLファイルの構文をチェック
    -   id: check-added-large-files # 大容量ファイルが追加されるのを防止

設定ファイルの作成が終わったら、次のコマンドを実行してGitフックを.git/hooks/pre-commitにインストールします。この作業は、プロジェクトを最初にクローンしたときに一度だけ実行すれば十分です。

pre-commit install

これで、git commitを試みると、pre-commitがステージングされたファイルに対して設定済みのフックを自動的に実行します。

2. 様々な言語向けのフックを追加する

pre-commitの真の強力さは、多様な言語やツールを容易に統合できる点にあります。例えば、Pythonプロジェクトではblack(フォーマッター)とruff(リンター)、JavaScriptプロジェクトではprettier(フォーマッター)とeslint(リンター)を追加できます。

Pythonプロジェクトの例 (black, ruff)

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
-   repo: https://github.com/psf/black
    rev: 24.4.2
    hooks:
    -   id: black
-   repo: https://github.com/astral-sh/ruff-pre-commit
    rev: v0.4.4
    hooks:
    -   id: ruff
        args: [--fix] # 自動修正可能なエラーは修正する
    -   id: ruff-format

JavaScript/TypeScriptプロジェクトの例 (prettier, eslint)

# .pre-commit-config.yaml
repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.6.0
    hooks:
    -   id: trailing-whitespace
    -   id: end-of-file-fixer
-   repo: https://github.com/prettier/prettier
    rev: 3.2.5
    hooks:
    -   id: prettier
        # 追加の引数を渡して特定のファイルタイプにのみ適用可能
        # types: [javascript, typescript, css, markdown]
-   repo: local # ローカルにインストールされたeslintを使用する場合
    hooks:
    -   id: eslint
        name: eslint
        entry: npx eslint --fix
        language: node
        types: [javascript, typescript]
        # 初回実行速度向上のため、常に実行するように設定
        always_run: true
        # ステージングされたファイルのみを引数として渡す
        pass_filenames: false

repo: localを使用すると、package.jsonに記載されたバージョンのツールを使用できるため、チームメンバー間のツールバージョンの不一致問題を解決できます。

3. 実際のワークフロー

これで全ての設定が完了しました。開発者がコードを修正した後にコミットを試みると、何が起こるでしょうか?

  1. 開発者がファイルを修正し、git add .コマンドでステージングします。
  2. git commit -m "機能追加"コマンドを実行します。
  3. pre-commitが自動的に起動し、.pre-commit-config.yamlに定義されたフックをステージングされたファイルに対して順次実行します。
  4. 成功シナリオ:すべてのフックが正常にパスすると、コミットが通常通り完了します。
    $ git commit -m "新機能の追加"
    Trim Trailing Whitespace........................................Passed
    Fix End of Files................................................Passed
    Check Yaml......................................................Passed
    black...........................................................Passed
    ruff............................................................Passed
    [feature/new-logic 1a2b3c4] 新機能の追加
     2 files changed, 15 insertions(+)
    
  5. 失敗シナリオ:一つ以上のフックが失敗した場合(例:リンティングエラーが発見された)、pre-commitは該当のエラーを出力し、コミットを中断します。
    $ git commit -m "バグ修正"
    Trim Trailing Whitespace........................................Passed
    Fix End of Files................................................Passed
    black...........................................................Failed
    - hook id: black
    - files were modified by this hook
    
    reformatted my_bad_file.py
    
    All done! ✨ 🍰 ✨
    1 file reformatted.
    

    この場合、blackprettierのように自動修正機能を持つフックはファイルを直接修正します。開発者は修正されたファイルを再度ステージング(git add my_bad_file.py)し、再びコミットを試みるだけです。このプロセスにより、「リンター修正」のような雑然としたコミットを残すことなく、常にクリーンなコードを維持できます。

結論:なぜpre-commitを導入すべきか?

pre-commitフレームワークを導入することは、単なるツールの追加を超え、開発文化そのものを改善する効果的な方法です。

  • 一貫したコード品質:すべてのチームメンバーが同じルールに従ってコードを記述・チェックするため、プロジェクト全体のコード品質が向上します。
  • レビュー時間の短縮:コードレビュアーはスタイルや些細なエラーではなく、ビジネスロジックにより集中できます。
  • 自動化されたワークフロー:開発者はリンティングやフォーマットといった反復的な作業を気にすることなく、開発に専念できます。
  • ミスの防止:機密情報やデバッグ用コードがリポジトリにコミットされるのを事前に防ぎ、セキュリティを強化します。

最初は設定を追加し、チームメンバーに使い方を案内する少しの努力が必要かもしれません。しかし、この小さな投資は、長期的にはチームの生産性を最大化し、より堅牢で保守しやすいコードを作る礎となるでしょう。今すぐあなたのプロジェクトにpre-commitを導入し、自動化されたコード品質管理の力を体験してみてください。

Tuesday, March 12, 2024

Git 고수의 비결: Rebase, Cherry-Pick, Bisect 완벽 정복

Git은 현대 소프트웨어 개발의 핵심인 분산 버전 관리 시스템입니다. 대부분의 개발자는 git commit, git push, git pull과 같은 기본 명령어에 익숙하지만, Git의 진정한 힘은 그 너머에 있는 고급 명령어들을 자유자재로 다룰 때 발휘됩니다. 이러한 고급 명령어들은 단순히 복잡한 작업을 처리하는 것을 넘어, 프로젝트의 이력을 깔끔하게 관리하고, 팀과의 협업을 원활하게 하며, 버그 추적 시간을 획기적으로 단축시켜 줍니다.

이 글에서는 Git을 한 단계 더 깊이 있게 사용하고자 하는 개발자들을 위해, 실무에서 가장 유용하게 쓰이는 세 가지 고급 명령어를 심층적으로 다룹니다. 이 명령어들을 마스터하면 복잡한 개발 시나리오에서도 자신감 있게 대처할 수 있는 '프로 개발자'로 거듭날 수 있을 것입니다.

본문에서 다룰 핵심 명령어는 다음과 같습니다.

  • git rebase: 복잡하게 얽힌 커밋 히스토리를 깔끔한 직선 형태로 재정렬하여 가독성을 높입니다.
  • git cherry-pick: 다른 브랜치에 있는 특정 커밋 하나만 골라서 현재 브랜치에 적용합니다.
  • git bisect: 이진 탐색을 통해 수많은 커밋 중에서 버그를 유발한 단 하나의 커밋을 놀랍도록 빠르게 찾아냅니다.

이제 Git의 숨겨진 능력을 깨우고 당신의 개발 워크플로우를 혁신해 보세요.

커밋 히스토리를 예술로 만드는 `git rebase`

git rebase는 커밋 히스토리를 '재배치'하여 깨끗하고 논리적인 흐름으로 만드는 강력한 도구입니다. merge가 두 브랜치의 역사를 합치면서 'Merge commit'을 남기는 반면, rebase는 현재 브랜치의 변경사항을 대상 브랜치의 최신 커밋 위로 하나씩 옮겨 심는 것처럼 작동합니다. 그 결과, 마치 처음부터 최신 버전에서 작업을 시작한 것처럼 보이는 깔끔한 직선형 히스토리가 만들어집니다.

예를 들어, feature 브랜치에서 신규 기능 개발을 하는 동안 다른 팀원이 main 브랜치에 새로운 내용을 반영했다고 상상해 보세요. 이때 rebase를 사용하면 내 작업 내용을 main 브랜치의 최신 변경사항 위에 깔끔하게 얹을 수 있어, 나중에 코드를 리뷰하거나 히스토리를 추적하기가 훨씬 수월해집니다.

`git rebase` 기본 사용법

기본적인 사용법은 매우 간단합니다. 현재 브랜치의 커밋들을 옮겨놓을 새로운 기준(base)이 될 브랜치를 지정해주기만 하면 됩니다.

git rebase <기준_브랜치>

가장 일반적인 시나리오는 기능 브랜치를 최신 main 브랜치에 맞춰 업데이트하는 경우입니다.

# 1. 작업 중인 기능 브랜치로 이동
git checkout feature

# 2. main 브랜치를 기준으로 rebase 실행
git rebase main

이 명령을 실행하면 Git은 feature 브랜치에만 있는 커밋들을 잠시 따로 보관한 뒤, feature 브랜치를 main 브랜치의 최신 지점으로 이동시키고, 그 위에 보관했던 커밋들을 차례대로 다시 적용합니다.

Rebase의 황금률: 절대 공유된 브랜치에는 사용 금지!

rebase는 히스토리를 '수정'하는 강력한 기능인 만큼, 치명적인 문제를 일으킬 수도 있습니다. 반드시 지켜야 할 **황금률**은 바로 **"팀원들과 공유하는 원격 브랜치(예: `origin/main`)에는 절대 `rebase`를 사용해서는 안 된다"**는 것입니다. rebase는 기존 커밋을 지우고 새로운 커밋 ID를 가진 복제본을 만들기 때문에, 만약 다른 팀원이 당신이 지워버린 옛날 히스토리를 기반으로 작업하고 있었다면 팀 전체의 저장소가 뒤죽박죽 엉망이 될 수 있습니다. rebase는 아직 원격 저장소에 push하지 않은, 나 혼자 쓰는 로컬 브랜치를 정리할 때만 사용하세요.

원하는 커밋만 쏙 빼오는 `git cherry-pick`

"다른 브랜치에 있는 저 커밋 하나만 지금 당장 필요한데..." 이런 상황을 겪어본 적 있으신가요? 예를 들어, develop 브랜치에서 수정한 치명적인 버그를, 전체 브랜치를 병합하지 않고 해당 수정사항만 골라서 안정 버전인 main 브랜치에 즉시 반영해야 할 때가 있습니다. 바로 이럴 때 사용하는 명령어가 git cherry-pick입니다.

이름 그대로, 잘 익은 '체리'를 하나 '골라 따오듯이' 다른 브랜치에 있는 특정 커밋의 변경사항을 현재 브랜치에 새로운 커밋으로 복제해올 수 있습니다. 이는 불필요한 변경사항 없이 필요한 내용만 정확하게 가져올 수 있어 매우 유용합니다.

`git cherry-pick` 사용법

사용법은 매우 직관적입니다. 가져오고 싶은 커밋의 고유 ID(커밋 해시)만 알면 됩니다.

git cherry-pick <가져올_커밋_해시>

예를 들어, develop 브랜치에 있는 버그 수정 커밋(해시: `a1b2c3d`)을 긴급하게 main 브랜치에 적용해야 하는 상황을 가정해 보겠습니다.

# 1. 수정사항을 적용할 main 브랜치로 이동
git checkout main

# 2. develop 브랜치에서 원하는 커밋을 cherry-pick
git cherry-pick a1b2c3d

이 명령을 실행하면, `a1b2c3d` 커밋과 동일한 변경 내용을 가진 새로운 커밋이 main 브랜치의 맨 끝에 생성됩니다. 이를 통해 서비스 안정성에 영향을 줄 수 있는 다른 미완성 기능들을 제외하고, 오직 버그 수정사항만 안전하게 반영할 수 있습니다.

버그 탐정 `git bisect`로 범인 찾기

어느 날 갑자기 발견된 버그, "대체 이 버그는 언제부터 있었던 거지?"라며 막막했던 경험은 모든 개발자의 악몽입니다. 수백, 수천 개의 커밋을 일일이 뒤져보며 버그의 원인을 찾는 것은 엄청난 시간 낭비입니다. 이때, 명탐정처럼 범인을 찾아주는 도구가 바로 git bisect입니다.

git bisect는 버그를 유발한 최초의 커밋을 찾기 위해 '이진 탐색' 알고리즘을 사용합니다. 개발자가 "버그가 없었던 정상적인 커밋(good)"과 "버그가 확실히 존재하는 커밋(bad)"을 알려주면, Git은 그 사이의 커밋들을 절반씩 나눠가며 버그 유무를 질문합니다. 이 과정을 몇 번만 반복하면, 마법처럼 버그를 만든 단 하나의 커밋을 정확히 지목해 줍니다.

`git bisect`를 이용한 버그 추적 과정

git bisect는 Git과 대화하듯 진행됩니다. 추적을 시작하고, 범위를 알려준 뒤, Git의 질문에 답하기만 하면 됩니다.

현재 최신 버전(HEAD)에서 버그가 발생하고, 과거의 `v1.2.0` 태그 시점에서는 정상이었다는 것을 알고 있는 상황을 예로 들어보겠습니다.

# 1. bisect 모드를 시작합니다.
git bisect start

# 2. 현재 버그가 있는 커밋을 'bad'로 지정합니다.
git bisect bad HEAD

# 3. 버그가 없었던 정상 커밋을 'good'으로 지정합니다.
git bisect good v1.2.0

이제 Git은 `good`과 `bad`의 중간 지점에 있는 커밋으로 자동 체크아웃하며 "이 커밋은 괜찮은가요?"라고 묻습니다. 당신은 코드를 테스트해 본 후, 버그가 여전히 존재하면 git bisect bad, 버그가 사라졌다면 git bisect good을 입력합니다. 이 과정을 몇 번 반복하면 Git이 최종적으로 범인 커밋을 찾아내 알려줍니다.

범인을 찾았다면, 아래 명령어로 `bisect` 모드를 종료하고 원래 작업하던 브랜치로 돌아올 수 있습니다.

git bisect reset

수동으로 했다면 몇 시간이 걸렸을지도 모를 버그 추적을 단 몇 분 만에 끝낼 수 있게 해주는 매우 강력한 도구입니다.

결론

Git의 기본 명령어만으로도 개발은 가능하지만, git rebase, git cherry-pick, git bisect와 같은 고급 명령어를 능숙하게 사용하면 개발의 생산성과 코드의 품질을 한 차원 높일 수 있습니다. 깔끔한 히스토리 관리, 유연한 변경사항 적용, 신속한 버그 해결 능력은 뛰어난 개발자가 갖춰야 할 중요한 역량입니다. 오늘 배운 명령어들을 실제 프로젝트에 적극적으로 활용하여, 더 효율적이고 전문적인 개발자로 성장해 나가시길 바랍니다.

Git上級者への道:rebase, cherry-pick, bisectを使いこなす

Gitは、現代のソフトウェア開発に不可欠な分散型バージョン管理システムです。多くの開発者はgit commitgit pushといった基本的なコマンドには慣れ親しんでいますが、その先にはさらに強力で便利なコマンドが数多く存在します。これらの高度なコマンドを習得することで、日々の作業効率を飛躍的に向上させ、より洗練されたプロジェクト管理が可能になります。

この記事では、Gitの基本から一歩進んで、特に重要な3つの高度なコマンドに焦点を当てます。コミット履歴をクリーンに保ち、特定の変更だけを的確に取り込み、そして驚くべき速さでバグの原因を特定するためのテクニックを学びましょう。これらのツールは、複雑な開発シナリオにも自信を持って対応するための、いわば「プロの道具箱」です。

本稿で詳しく解説するコマンドは以下の通りです。

  • git rebase: コミット履歴を書き換え、直線的で読みやすいログを作成します。
  • git cherry-pick: 他のブランチから特定のコミットだけを選んで現在のブランチに適用します。
  • git bisect: 二分探索を用いて、バグが混入したコミットを高速で特定する強力なデバッグツールです。

さあ、これらのコマンドをマスターし、あなたのGitスキルを次のレベルへと引き上げましょう。

コミット履歴を美しく整形する `git rebase`

git rebaseは、コミット履歴をよりクリーンで直線的なものにするための強力なコマンドです。主な機能は、あるブランチ(例:featureブランチ)で行った一連のコミットを、別のブランチ(例:mainブランチ)の最新の状態の上に「再適用(re-base)」することです。これにより、git mergeで生じるようなマージコミットが不要になり、誰がいつどのような変更を加えたのかが非常に分かりやすい、一本のきれいな歴史の流れを作り出すことができます。

例えば、あなたがfeatureブランチで作業している間に、チームの他のメンバーがmainブランチを更新したとします。この時、mergeを使う代わりにrebaseを行うと、あたかもあなたがmainブランチの最新の状態から作業を始めたかのように、コミット履歴を整えることができます。

`git rebase` の基本的な使い方

基本的な構文は非常にシンプルです。現在のブランチのコミットを、どのブランチを新しい土台(ベース)にして再適用するかを指定します。

git rebase <base-branch>

例えば、featureブランチをmainブランチの最新の状態に更新するには、以下のコマンドを実行します。

# まず、作業中のfeatureブランチに切り替える
git checkout feature

# mainブランチを新しいベースとしてrebaseを実行
git rebase main

このコマンドは、featureブランチにしかないコミットを一時的に退避させ、featureブランチをmainの最新状態まで進め、その上に退避させたコミットを一つずつ適用していきます。

`rebase`の黄金律:共有ブランチでは絶対に使わない

rebaseはコミット履歴を「書き換える」ため、非常に強力であると同時に注意が必要です。最も重要なルールは、**「他の開発者と共有しているリモートブランチ(例: origin/main)に対しては、決してrebaseを実行してはならない」**というものです。履歴を書き換えるとコミットIDが新しく作り直されるため、もし他の人が古い履歴を元に作業している場合、チーム全体のGitリポジトリが深刻な混乱状態に陥る原因となります。rebaseは、まだ自分しか使っていないローカルのブランチの整理に限定して使いましょう。

特定のコミットだけを摘み取る `git cherry-pick`

「他のブランチにある、たった一つのコミットだけが今すぐ欲しい」。そんな経験はありませんか?例えば、開発中のdevelopブランチで発見された重大なバグの修正コミットを、緊急で本番用のmainブランチにも適用したい、といったケースです。このような「つまみ食い」的な操作を実現するのがgit cherry-pickです。

git cherry-pickは、コミットハッシュ(コミットの固有ID)を指定することで、そのコミットが持つ変更内容だけを、現在のブランチに新しいコミットとしてコピーすることができます。まるで果樹園の木(他のブランチ)から、美味しいサクランボ(特定のコミット)だけを一つ摘んで自分のカゴ(現在のブランチ)に入れるようなイメージです。

`git cherry-pick` の使い方

使い方は非常に直感的で、適用したいコミットのハッシュ値さえ分かれば実行できます。

git cherry-pick <commit-hash>

例として、developブランチにあるバグ修正コミット(ハッシュ値: `a1b2c3d`)を、緊急でhotfixブランチに適用するシナリオを考えてみましょう。

# 修正を適用したいhotfixブランチに切り替える
git checkout hotfix

# developブランチから特定のコミットを適用する
git cherry-pick a1b2c3d

これを実行すると、a1b2c3dのコミットと全く同じ変更内容を持つ新しいコミットがhotfixブランチに作成されます。これにより、関連のない他の変更を取り込むことなく、必要な修正だけを安全かつ正確に反映させることができます。

バグの原因を自動で特定する `git bisect`

開発中にバグを発見したとき、「一体いつからこのバグは存在しているんだ?」と頭を抱えることは少なくありません。昨日なのか、一週間前なのか、あるいは数ヶ月前なのか。過去のコミットを一つ一つ手作業でチェックして原因を探すのは、非常に時間のかかる悪夢のような作業です。そんな時、あなたの最高の相棒となるのがgit bisectです。

git bisectは、バグが混入したコミットを自動で探し出すための強力なデバッグツールです。あなたが「バグがなかった正常なコミット(good)」と「バグが存在するコミット(bad)」をGitに教えるだけで、Gitはその間の膨大なコミット履歴を対象に「二分探索」を実行します。これにより、調査範囲を半分、また半分と効率的に狭めていき、最終的にバグを生み出した張本人であるコミットをピンポイントで特定してくれるのです。

`git bisect` の実践的な使い方

git bisectは対話形式で進めていきます。セッションを開始し、範囲を指定した後は、Gitの指示に従ってテストと報告を繰り返すだけです。

現在の最新版(HEAD)でバグが起きており、バージョン`v1.2.0`の時点では正常だったことが分かっている場合の操作手順を見てみましょう。

# 1. bisectセッションを開始する
git bisect start

# 2. 現在のコミットが「バグあり(bad)」だと教える
git bisect bad HEAD

# 3. 正常だったことが分かっているコミットを「バグなし(good)」だと教える
git bisect good v1.2.0

このコマンドを実行すると、Gitは`good`と`bad`の中間にあたるコミットを自動でチェックアウトします。あなたの仕事は、その状態でプログラムを動かしてバグが再現するかをテストすることです。もしバグがあればgit bisect bad、なければgit bisect goodと報告します。これを繰り返すと、Gitは数回のやり取りで犯人となるコミットを特定し、「`xxxxxxx` is the first bad commit」のように表示してくれます。

原因が特定できたら、以下のコマンドでセッションを終了し、元のブランチに戻ります。

git bisect reset

このコマンドは、手作業なら数時間かかっていたかもしれないバグ調査を、わずか数分で終わらせてくれる可能性を秘めています。

まとめ

基本的なGitコマンドが日々の業務に必須である一方、git rebasegit cherry-pick、そしてgit bisectのような高度なツールを使いこなすことで、開発の生産性と品質は新たな次元に到達します。rebaseでクリーンな履歴を保ち、cherry-pickで柔軟な変更管理を行い、bisectで迅速なバグ修正を実現する。これらのコマンドを自身のワークフローに組み込むことで、あなたはより効率的で信頼性の高い開発者へと成長できるでしょう。

Mastering Git: A Deep Dive into Rebase, Cherry-Pick, and Bisect

Git is the cornerstone of modern software development, a distributed version control system that empowers teams to manage project history with precision. While most developers are comfortable with `git commit`, `git push`, and `git pull`, a world of powerful, advanced commands lies just beneath the surface. Mastering these commands can transform your workflow from merely functional to exceptionally efficient.

This article moves beyond the basics to explore three of Git's most potent tools. We'll delve into advanced commands that help you craft a clean and logical project history, surgically apply specific changes, and hunt down bugs with incredible speed. These are the tools that separate the novice from the expert, enabling you to handle complex scenarios with confidence.

We will explore the following commands in detail:

  • git rebase: For rewriting and cleaning up commit history to create a linear and more readable log.
  • git cherry-pick: For selecting and applying specific commits from one branch to another.
  • git bisect: A powerful debugging tool that uses binary search to quickly find the exact commit that introduced a bug.

Let's unlock these new capabilities and elevate your Git expertise.

Rewriting History: A Deep Dive into `git rebase`

The git rebase command is a powerful tool for creating a cleaner, more linear commit history. Its primary function is to take a series of commits from a feature branch and "replay" them on top of another branch, such as `main`. This avoids the "merge commit" that git merge creates, resulting in a straight-line history that is often easier to read and navigate.

Imagine your `main` branch has moved forward while you were working on a `feature` branch. Instead of merging `main` into your feature branch and cluttering its history, you can rebase your feature branch onto the latest version of `main`. This makes it seem as though you started your work from the latest point, keeping the project history tidy.

However, this power comes with a crucial warning, often called **The Golden Rule of Rebase**: Never rebase a public or shared branch that other developers are using. Rebasing rewrites commit history, creating new commit hashes. If you rebase a branch that others have pulled, it will cause significant confusion and repository divergence for your team.

How to Use `git rebase`

The basic syntax for `git rebase` is straightforward. You specify the new "base" commit or branch you want to move your current branch's commits onto.

git rebase <base-branch>

For example, to update your `feature` branch with the latest changes from the `main` branch, you would run the following commands:

# Switch to your feature branch
git checkout feature

# Rebase your commits on top of the latest main branch
git rebase main

This command takes all the commits unique to the `feature` branch, moves them aside temporarily, updates the `feature` branch to match `main`, and then reapplies your commits one by one on top of the new base. For even more control, you can use interactive rebase (git rebase -i) to squash, edit, or reorder commits before they are applied.

Precision Patching with `git cherry-pick`

Have you ever needed just one specific commit from another branch, but not the entire branch's history? This is a common scenario, such as when a critical bug fix is committed to a development branch and needs to be applied immediately to a production hotfix branch. This is precisely what git cherry-pick is for.

git cherry-pick allows you to select a specific commit by its hash and apply it as a new commit on your current branch. It’s like reaching into another branch, picking a single "cherry" (a commit), and placing it in your own basket (your current branch).

How to Use `git cherry-pick`

The command's usage is as simple as its concept. You just need the hash of the commit you want to apply.

git cherry-pick <commit-hash>

Let's say a critical bug fix with commit hash `abc123def` was made on the `develop` branch. To apply this fix to the `release-v1.1` branch, you would do the following:

# Switch to the branch where you need the fix
git checkout release-v1.1

# Apply the specific commit from the develop branch
git cherry-pick abc123def

Git will now create a new commit on the `release-v1.1` branch containing the exact changes from `abc123def`. This allows you to backport fixes or forward-port features with surgical precision, without merging unrelated changes.

Automated Bug Hunting with `git bisect`

One of the most frustrating moments in development is discovering a bug and having no idea when it was introduced. Was it yesterday? Last week? Last month? Manually checking out old commits to find the source can be a tedious and time-consuming nightmare. This is where git bisect becomes your best friend.

git bisect is a powerful debugging tool that automates the search for a specific commit. By telling it a "good" commit (where the bug doesn't exist) and a "bad" commit (where the bug does exist), `git bisect` performs a binary search on your commit history. It repeatedly checks out a commit halfway between the good and bad range, asks you to test it, and narrows down the search by half each time until it pinpoints the exact commit that introduced the bug.

How to Use `git bisect`

Using git bisect is an interactive process. You start a session, provide the boundaries, and then iteratively test and provide feedback to Git.

Let's say you know the current `HEAD` is broken, but version `v2.0` of your project was working correctly. The process would look like this:

# 1. Start the bisect session
git bisect start

# 2. Mark the current commit as "bad"
git bisect bad HEAD

# 3. Mark a known working commit as "good"
git bisect good v2.0

Git will then check out a commit in the middle of that range. Your job is to build and test your project. If the bug is still present, you tell Git git bisect bad. If the bug is gone, you tell it git bisect good. Git will repeat this process, narrowing the search space each time, until it declares, "X is the first bad commit."

Once you've found the culprit, you can end the session and return to your original branch with:

git bisect reset

This command can save hours of manual searching and is an invaluable tool for maintaining code quality in large projects.

Conclusion

While the basic Git commands are essential for day-to-day work, mastering advanced tools like git rebase, git cherry-pick, and git bisect unlocks a new level of productivity and control. Using rebase helps maintain a clean and professional project history, cherry-pick provides the flexibility to manage changes across branches with precision, and bisect offers a fast, automated way to ensure code quality. By integrating these commands into your workflow, you can handle complex development scenarios with ease and become a more effective and efficient developer.

Thursday, March 24, 2022

Git 로그를 보기 편하게 포맷팅하기

Git 로그 확인하기: 효과적인 포맷팅 방법

Git 로그는 프로젝트의 이력을 확인하는 데 있어 매우 중요한 도구입니다. 이 글에서는 Git 로그를 보다 효율적으로 확인하는 방법에 대해 알아보겠습니다.

Git 로그 포맷팅

Git 로그를 확인할 때 다음과 같은 명령어를 사용하면, 보기 편한 형식으로 출력할 수 있습니다:

git log --pretty=format:"%h - %an, %ar : %s"

Git 로그 명령어 옵션들

위 명령어에서 사용된 각각의 옵션들은 다음과 같은 정보를 나타냅니다:

  • %H: Commit hash
  • %h: Short commit hash
  • %an: Author name
  • %ae: Author email
  • %cd: Committer date
  • %s: Subject

Git 로그 활용

위와 같이 git log 명령어를 통해 특정 정보를 선택적으로 확인할 수 있습니다. 이를 통해 프로젝트의 히스토리를 보다 효과적으로 관리할 수 있습니다. 즐거운 코딩 되세요!