Git: バグの修正と新機能の追加を同時にやってしまった場合の対処方法

More than 1 year has passed since last update.

動作確認を行いつつ分割コミットするやりかた.

以下のような手順を行う.(バグ修正 → 新機能追加の順にコミットする場合)

  1. git add -p などを使って,バグの修正の部分だけを index に上げる.

  2. git stash --keep-index をして index にない変更を脇にどける.

  3. コンパイルしたり実行したりテストしたりして,ちゃんと動作することを確かめる.
    [追記] ダメだった場合は git stash pop して git reset することで最初の状態に戻れる.

  4. git commit する.間違えて -a を付けないように注意.

  5. git stash pop して,新機能追加の部分を working tree に戻す.

  6. git commit -a する.

例として以下のようなfizzbzzのコードを考える.

fizzbazz.c
#include <stdio.h>

int main() {
  int i;
  int n = 30;

  for (i = 1; i <= n; ++i) {
    if (i % 15 == 0) {
      puts("fizzbazz");
    } else if (i % 3 == 0) {
      puts("fizz");
    } else if (i % 5 == 0) {
      puts("bass");
    } else {
      printf("%d\n", i);
    }
  }
  return 0;
}

このコードに対して次の2つの修正をしてしまったとする.

  • "bazz" と書くべきところを "bass" と書いてしまっているので修正した.
  • n の値をコマンドライン引数から読むようにした.
fizzbazz.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
  int i;
  int n = (argc > 1) ? atoi(argv[1]) : 30;

  for (i = 1; i <= n; ++i) {
    if (i % 15 == 0) {
      puts("fizzbazz");
    } else if (i % 3 == 0) {
      puts("fizz");
    } else if (i % 5 == 0) {
      puts("bazz");
    } else {
      printf("%d\n", i);
    }
  }
  return 0;
}

このとき,分割コミットは以下のような手順になる.

$ git diff
2つの変更が混ざったdiffが表示される

$ git add -p fizzbazz.c
puts("bass"); を含む hunk だけを stage する

$ git stash --keep-index

$ git diff
何も表示されない

$ git diff --cached
バグ修正の部分だけが表示される

$ gcc -Wall fizzbazz.c
$ ./a.out
動作確認する

$ git commit -m "Fix typo"

$ git stash pop

$ git diff
新機能追加の部分だけが表示される

$ git commit -a -m "Take n from argv[1]"
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.