suzunedev's blog

@suzunedev のブログ

機能開発時の Git 操作の基本

はじめに

機能開発時に Git で操作している内容を記録します。 Git は 2.36.1 を使用しています。

$ git --version
git version 2.36.1

機能開発時の Git 操作

まずは最新の変更をローカルに取り込みます。

$ git pull
Already up to date.

develop ブランチから feature ブランチを作成します。

$ git branch
* develop
$ git switch -c feature/add-sample
Switched to a new branch 'feature/add-sample'
$ git branch
  develop
* feature/add-sample

feature ブランチで変更をコミットして push します。

$ echo "# sample" >> sample.md
$ git add sample.md
$ git commit -m "Add sample"
$ git push origin feature/add-sample 

GitHub 上で PR を作成してレビュー依頼を出します。 指摘事項がある場合は修正をして、再度 push します。

$ sed -i -e 's/sample/sample2/' sample.md
$ cat sample.md
# sample2
$ git add sample.md
$ git commit -m "Fix sample to sample2"
$ git push origin feature/add-sample 

コミットをまとめる場合

レビューが通ってから、コミットをまとめる場合の操作になります。 まずは、コミットログを確認します。

$ git log --oneline
8135068 (HEAD -> feature/add-sample, origin/feature/add-sample) Fix sample to sample2
1b50a84 Add sample
826ae54 (origin/main, origin/develop, develop) first commit

git rebase を使って、 Fix sample to sample2 を Add sample としてまとめるので、 HEAD から上二つを指定します。

$ git rebase -i HEAD~2

テキストエディタが開きます。 git rebase のインタラクティブモードでは古い順にコミットログが表示されます。 変更内容は表示されたファイルの内容を書き換えることで変更できます。

  1 pick 1b50a84 Add sample
  2 pick 8135068 Fix sample to sample2
  3 
  4 # Rebase 826ae54..8135068 onto 826ae54 (2 commands)
  5 #
  6 # Commands:
  7 # p, pick <commit> = use commit
  8 # r, reword <commit> = use commit, but edit the commit message
  9 # e, edit <commit> = use commit, but stop for amending
 10 # s, squash <commit> = use commit, but meld into previous commit
 11 # f, fixup [-C | -c] <commit> = like "squash" but keep only the previous
 12 #                    commit's log message, unless -C is used, in which case
 13 #                    keep only this commit's message; -c is same as -C but
 14 #                    opens the editor
 15 # x, exec <command> = run command (the rest of the line) using shell
 16 # b, break = stop here (continue rebase later with 'git rebase --continue')
 17 # d, drop <commit> = remove commit
 18 # l, label <label> = label current HEAD with a name
 19 # t, reset <label> = reset HEAD to a label
 20 # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
 21 # .       create a merge commit using the original merge commit's
 22 # .       message (or the oneline, if no original merge commit was
 23 # .       specified); use -c <commit> to reword the commit message
 24 #
 25 # These lines can be re-ordered; they are executed from top to bottom.
 26 #
 27 # If you remove a line here THAT COMMIT WILL BE LOST.
 28 #
 29 # However, if you remove everything, the rebase will be aborted.
 30 #

Fix sample to sample2 を pick から squash に書き換えて保存します。

  1 pick 1b50a84 Add sample
  2 squash 8135068 Fix sample to sample2

保存すると、別のファイルのテキストエディタが開きます。

  1 # This is a combination of 2 commits.
  2 # This is the 1st commit message:
  3 
  4 Add sample
  5 
  6 # This is the commit message #2:
  7 
  8 Fix sample to sample2
  9 
 10 # Please enter the commit message for your changes. Lines starting
 11 # with '#' will be ignored, and an empty message aborts the commit.
 12 #
 13 # Date:      Sat Nov 5 14:27:43 2022 +0900
 14 #
 15 # interactive rebase in progress; onto 826ae54
 16 # Last commands done (2 commands done):
 17 #    pick 1b50a84 Add sample
 18 #    squash 8135068 Fix sample to sample2
 19 # No commands remaining.
 20 # You are currently rebasing branch 'feature/add-sample' on '826ae54'.
 21 #
 22 # Changes to be committed:
 23 #>--new file:   sample.md
 24 #
 25 # Untracked files:
 26 #>--sample.md-e
 27 #>--sample.mde
 28 #

Add sample のみのコミットメッセージにまとめるために、 Fix sample to sample2 を削除して保存します。

  1 # This is a combination of 2 commits.
  2 # This is the 1st commit message:
  3 
  4 Add sample
  5 
  6 # Please enter the commit message for your changes. Lines starting
  7 # with '#' will be ignored, and an empty message aborts the commit.
  8 #
  9 # Date:      Sat Nov 5 14:27:43 2022 +0900
 10 #
 11 # interactive rebase in progress; onto 826ae54
 12 # Last commands done (2 commands done):
 13 #    pick 1b50a84 Add sample
 14 #    squash 8135068 Fix sample to sample2
 15 # No commands remaining.
 16 # You are currently rebasing branch 'feature/add-sample' on '826ae54'.
 17 #
 18 # Changes to be committed:
 19 #>--new file:   sample.md
 20 #
 21 # Untracked files:
 22 #>--sample.md-e
 23 #>--sample.mde
 24 #

コミットログを確認すると対象のコミットが一つに変更されたことが確認できます。

$ git log --oneline
2b926c7 (HEAD -> feature/add-sample) Add sample
826ae54 (origin/main, origin/develop, develop) first commit

git status を確認すると編集時のファイルが作成されているため、削除します。

$ git status
On branch feature/add-sample
Untracked files:
  (use "git add <file>..." to include in what will be committed)
    sample.md-e
    sample.mde

nothing added to commit but untracked files present (use "git add" to track)
$ rm sample.md-e sample.mde 

過去のコミットを書き換えているため、 force push を行います。

$ git push -f origin feature/add-sample 

おわりに

GitHub 上で PR をマージします。カレントブランチを develop に切り替えて変更内容をローカルに取り込みます。

$ git branch
  develop
* feature/add-sample
$ git switch develop
Switched to branch 'develop'
Your branch is up to date with 'origin/develop'.
$ git pull

feature ブランチでの変更が develop ブランチに反映されていることが確認できます。

$ git log --oneline
0dfdbb7 (HEAD -> develop, origin/develop) Merge pull request #1 from suzunedev/feature/add-sample
2b926c7 (origin/feature/add-sample, feature/add-sample) Add sample
826ae54 (origin/main) first commit

最後に feature ブランチを削除して機能開発時の操作はおわりです。

$ git branch -d feature/add-sample 
$ git branch
* develop