作業のやり直しは基本的にローカルリポジトリでの作業をやり直すときに使います。プライベート利用のリモートリポジトリを除いて、基本的にリモートリポジトリへすでにプッシュされているコミットをやり直してはいけません。
目次
コミットのやり直し (git commit --amend)
git commit --amendは直近のコミットをやり直すのに利用できます。直近のコミットをやり直すためには、通常のコミットのようにgit add等を行った後にgit commitではなく、git commit --amendとすると直近のコミット履歴にその内容が反映されます。その時のコミット内容に含めるべき内容についての間違えにすぐに気づいた時の修正に利用できます。
まず、以下のようなコミット履歴で例を示します。
1 2 3 4 5 6 |
~/TestProject (master) $ git log --oneline --decorate --name-status 48de76c (HEAD -> master) 2 commit A file2.txt A file3.txt ab3ab54 1 commit A file1.txt |
コミットのやり直しとして、コミットメッセージを修正せずにコミットするファイルの追加や削除についての例を示します。
--amendオプションを利用するとコミットメッセージを修正するためのエディタが開きます。
--no-editオプションを利用するとエディタを開かず、コミットメッセージをそのままにコミット内容をやり直すことができます。
以下はfile3.1.txtを追加して、file3.txtを削除してコミットをやり直す例になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
~/TestProject (master) $ touch file3.1.txt ~/TestProject (master) $ git add file3.1.txt ~/TestProject (master) $ git rm file3.txt rm 'file3.txt' ~/TestProject (master) $ git commit --amend --no-edit [master f73b6fd] 2 commit Date: Mon Apr 1 11:17:07 2024 +0900 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 file2.txt create mode 100644 file3.1.txt ~/TestProject (master) $ ~/TestProject (master) $ git log --oneline --decorate --name-status f73b6fd (HEAD -> master) 2 commit A file2.txt A file3.1.txt ab3ab54 1 commit A file1.txt |
また、ファイルの内容を修正するのも同じようにできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
~/TestProject (master) $ git log --oneline --decorate --numstat f73b6fd (HEAD -> master) 2 commit 0 0 file2.txt 0 0 file3.1.txt ab3ab54 1 commit 0 0 file1.txt ~/TestProject (master) $ echo 'line 1' >> file2.txt ~/TestProject (master) $ git add file2.txt ~/TestProject (master) $ git commit --amend --no-edit [master 638e2a5] 2 commit Date: Mon Apr 1 11:17:07 2024 +0900 2 files changed, 1 insertion(+) create mode 100644 file2.txt create mode 100644 file3.1.txt ~/TestProject (master) $ ~/TestProject (master) $ git log --oneline --decorate --numstat 638e2a5 (HEAD -> master) 2 commit 1 0 file2.txt 0 0 file3.1.txt ab3ab54 1 commit 0 0 file1.txt |
コミットメッセージも修正したい場合は--no-editを使わずにgit commit --amendを利用します。
ただし、エディタが開くので、エディタの設定が行われていない場合は意図しないエディタが開く場合があるので注意が必要かもしれません。
1 2 3 4 5 6 |
~/TestProject (master) $ git log -n1 --oneline --decorate bc1abe2 (HEAD -> master) 2 commit ~/TestProject (master) $ git commit --amend --出力省略-- ~/TestProject (master) $ git log -n1 --oneline --decorate d9989c8 (HEAD -> master) add file2.txt file3.1.txt |
エディタの設定は、例えば、以下のように設定できます。以下のコマンドはグローバル設定になります。
1 |
git config --global core.editor vim |
このコマンドで修正できるのは直近のコミットだけになります。コミットを修正するとハッシュ値が変更されます。直近より前のコミット修正はローカルリポジトリだけに存在する状況では行う可能性があるかもしれません。その場合はまた別のコマンドを利用することになり、その修正したコミットからパッチを再適用し直す必要があり、それらのハッシュ値はすべて変更されるでしょう。リモートリポジトリのコミットの修正を行うのは共同で作業をしている人の迷惑になるため、基本的に行うべきではありません(行うとしてもまず関係者全員の合意が必要になりますし、現実にはその判断を下すことができる地位や権限を持っていなければならないかもしれません)。
ステージしたファイルのやり直し (git reset)
ステージしたファイルのステージングをやり直ししたい場合はgit resetでステージングを取り消すことができます
まず以下の状態でステージングを行ったファイルがあるとします。
1 2 3 4 5 6 7 8 9 |
~/TestProject (master) $ echo 'line 1' >> file1.txt ~/TestProject (master) $ touch file2.txt ~/TestProject (master) $ git add file1.txt file2.txt ~/TestProject (master) $ git status ブランチ master コミット予定の変更点: (use "git restore --staged <file>..." to unstage) modified: file1.txt new file: file2.txt |
この状態でgit resetを行うとgit addのステージング操作を取り消すことができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
~/TestProject (master) $ git reset Unstaged changes after reset: M file1.txt ~/TestProject (master) $ git status ブランチ master Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: file1.txt 追跡されていないファイル: (use "git add <file>..." to include in what will be committed) file2.txt no changes added to commit (use "git add" and/or "git commit -a") |
また、git reset <ファイル>で個別にファイルのステージングを取り消すことができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
~/TestProject (master) $ git add file1.txt file2.txt ~/TestProject (master) $ git reset file1.txt Unstaged changes after reset: M file1.txt ~/TestProject (master) $ git status ブランチ master コミット予定の変更点: (use "git restore --staged <file>..." to unstage) new file: file2.txt Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: file1.txt |
ファイルへの変更の取り消し (git checkout <ファイル>)
ファイルをバージョン管理しているときにそのファイルをいろいろ変更したがステージングをする前にやっぱり変更する必要がないと思った場合、
git checkout <ファイル>でそのファイルに対しての変更した操作をなかったことにし、ファイルをリポジトリに保存した元の状態に戻すことができます。
1 2 3 4 5 6 7 8 |
~/TestProject (master) $ echo 'line 1' >> file1.txt ~/TestProject (master) $ git status -s M file1.txt ~/TestProject (master) $ ~/TestProject (master) $ git checkout file1.txt Updated 1 path from the index ~/TestProject (master) $ git status -s ~/TestProject (master) $ |
ファイルをステージングに上げた場合でもgit resetでステージングを取り消して、
git checkout <ファイル>でファイルを元に戻すことができます。
1 2 3 4 5 6 7 8 9 10 11 12 |
~/TestProject (master) $ echo 'line 1' >> file1.txt ~/TestProject (master) $ git add file1.txt ~/TestProject (master) $ git status -s M file1.txt ~/TestProject (master) $ ~/TestProject (master) $ git reset file1.txt Unstaged changes after reset: M file1.txt ~/TestProject (master) $ git checkout file1.txt Updated 1 path from the index ~/TestProject (master) $ git status -s ~/TestProject (master) $ |