LoginSignup
5
5

More than 5 years have passed since last update.

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

Last updated at Posted at 2012-04-25

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

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

  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]"
5
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5