Close

Bitbucket Cloud を使用して Git での変更を元に戻す方法

目的

他のユーザーとコラボレーションしながら、ローカルマシンと Bitbucket Cloud リポジトリで変更を元に戻す方法を学習します。

ミッションの概要

このチュートリアルで説明するコマンド:

  • git revert、git reset、git log、および git status

所要時間

40 分

対象者

このチュートリアルは、git コマンド(git clonegit commitgit pull、および git push)に精通していることを前提としています。

誰でも間違えることはあります。すべてのプッシュ操作が完璧とは限りません。このチュートリアルは、最も一般的な git 機能を使用して変更を安全に元に戻すのに役立ちます。

このチュートリアルは、次の git コマンドの知識を持ったユーザーを対象としています。

これらのコマンドに精通していなくても、Bitbucket Cloud で git の使用方法を学べます。その後、こちらに戻って変更を元に戻す方法を確認してください。これらの git コマンドは Windows または Unix 環境向けのものです。このチュートリアルでは、ファイル システム ナビゲーションを説明する際に Unix コマンド ライン ユーティリティを使用します。


ローカルマシンで変更を元に戻す


元に戻したい変更がローカルシステムにあり、その変更をリモートリポジトリにプッシュしていない場合、変更を元に戻す主な方法が 2 つあります。

コマンド

用語の定義

Git revert

用語の定義

通常の元に戻す操作とは異なる、「元に戻す」コマンド。そのコミットがなかったことにするのではなく、そのコミットによって加えられた変更を打ち消し、コンテンツを打ち消す新しいコミットを追加します。これは Git の履歴を保全するためであり、改訂履歴の完全性とコラボレーションの信頼性の確保のために重要です。

Git のリセット

用語の定義

変更を元に戻す、汎用性のある git コマンド。git reset コマンドには強力なオプションがありますが、このチュートリアルでは次のリセットモードのみを使用します。

  • --soft:選択したコミットに対して HEAD のみをリセットします。基本的に git checkout と同じ動作ですが、Detached Head 状態を作成することはありません。
  • --mixed: 両方の履歴で選択したコミットに対して HEAD をリセットし、インデックスでの変更を元に戻します。
  • --hard: 両方の履歴で選択したコミットに対して HEAD をリセットし、インデックスでの変更を元に戻し、作業ディレクトリでの変更を元に戻します。このチュートリアルでは、ハードリセットのテストは行いません。

git reset の仕組みの詳細な説明については、git-scm.com の Git Tools - Reset Demystified (Git ツール - リセットコマンド詳説) をご覧ください。

Bitbucket ロゴ
ソリューションを見る

Git チュートリアル: 上級編

Git のロゴ
関連資料

Git コマンド

チュートリアルを進めるにつれて、変更を元に戻す方法の学習の一環として、他のいくつかの git コマンドを学びます。それでは、始めましょう。

リポジトリをフォークする


元のリポジトリのコードをすべて含む一意のリポジトリを作成することから始めましょう。このプロセスは、「リポジトリの フォーク」と呼ばれます。フォークとは、共有リポジトリが Bitbucket のようなサードパーティのホスティングサービスでホストされている場合に有効な拡張 git プロセスです。

1. 次の URL をクリック、または入力します。https://bitbucket.org/atlassian/tutorial-documentation-tests/commits/all

2. 左側のサイドバーで + 記号をクリックし、[このリポジトリをフォーク] を選択し、ダイアログを確認して [リポジトリをフォーク] をクリックします。

3. 新規リポジトリの概要が表示されます。

4. + 記号をクリックし、[このリポジトリをクローン] を選択します。

5. コンピューター上にリポジトリのクローンを作成します。

6. クローンのリポジトリを含むディレクトリに移動します。

これで、完全なコードを持つリポジトリとローカルシステムの既存の履歴を取得し、変更を元に戻す作業を開始できます。

ローカルシステムでの変更を見つける


元に戻したい変更を見つけて参照できるようにする必要があります。これには、特定の変更の場所を見つけるためのコマンドラインユーティリティのある Bitbucket のコミット UI を参照します。

git status


元に戻したい変更を見つけて参照できるようにする必要があります。これには、特定の変更の場所を見つけるためのコマンドラインユーティリティのある Bitbucket のコミット UI を参照します。

$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
nothing to commit, working tree clean

ここに示す git status の出力は、リモート main ブランチですべてが最新に保たれていて、コミットする必要がある保留中の変更がないことを示しています。次の例では、変更を保留中の状態のままリポジトリを編集して、そのリポジトリを調べてみます。これは、プロジェクト履歴への追加準備 (またはステージング) がなされていない、ローカル システム上のリポジトリのファイルに変更を加えたということです。

この次の例を説明するために、まず myquote2.html ファイルを開きます。myquote2.html の内容に変更を加え、ファイルを保存して終了します。もう一度 git status を実行し、この状態のリポジトリを調べましょう。

$ git status
On branch main
Your branch is up-to-date with 'origin/main'.
 
Changes not staged for commit:
 (use "git add <file>..." to update what will be committed)
 (use "git checkout -- <file>..." to discard changes in working directory)
 
 Modified: myquote2.html
 
no changes added to commit (use "git add" and/or "git commit -a")
--

ここに示す出力は、リポジトリには myquote2.html に対して保留中の変更があることを示しています。ここでよい点は、上記の例のように、元に戻したい変更がステージングエリアにまだ追加されていない場合、ファイルを編集するだけで続行できる点です。Git は、変更をステージングエリアに追加した時にのみ追跡を開始し、その後プロジェクト履歴に変更をコミットします。

では、myquote2.html に加えた変更を「元に戻す」操作を行いましょう。これは最小限の変更を行った簡単な例であるため、変更を元に戻すために利用可能な方法は 2 つあります。git checkout myquote2.html を実行すると、リポジトリは myquote2.html を前にコミットしたバージョンに復元します。または、git reset --hard を実行すると、リポジトリ全体を直前のコミットに戻すことができます。

git log


git log コマンドでは、プロジェクト履歴の一覧表示、フィルター、および特定の変更内容の検索を行うことができます。git status は作業ディレクトリとステージングエリアの状態を確認するためのものであるのに対し、git log はコミット済みの履歴 (コミット履歴) のみを表示します。

リポジトリの「コミット」ビューにアクセスすると、コミット履歴の同じログを Bitbucket UI 内で確認できます。当社のデモリポジトリのコミットビューは、https://bitbucket.org/dans9190/tutorial-documentation-tests/commits/all で確認できます。このビューの出力は、git log コマンドラインユーティリティと同様になり、元に戻す必要のあるコミットを見つけて特定することができます。

次の例では、履歴に複数の項目がありますが、それぞれ変更は根本的に 1 つずつのコミットです。つまり、コミットを見つけて元に戻す必要があります。

$ git status
On branch main
Your branch is up-to-date with 'origin/main'.

nothing to commit, working tree clean

$ git log

commit 1f08a70e28d84d5034a8076db9103f22ec2e982c
Author: Daniel Stevens <dstevens@atlassian.com>
Date:   Wed Feb 7 17:06:50 2018 +0000

    Initial Bitbucket Pipelines configuration

commit 52f823ca251a132225dd1cc18ad768de8d336e84
Author: Daniel Stevens <dstevens@atlassian.com>
Date:   Fri Sep 30 15:50:58 2016 -0700

    repeated quote to show how a change moves through the process

commit 4801b87c2147dce83f1bf31acfcffa6cb1d7e0a5
Merge: 1a6a403 3b29606
Author: Dan Stevens [Atlassian] <dstevens@atlassian.com>
Date:   Fri Jul 29 18:45:34 2016 +0000

    Merged in changes (pull request #6)

    Changes

一覧にあるコミットの 1 つをもう少し詳しく確認してみましょう。

commit 52f823ca251a132225dd1cc18ad768de8d336e84
Author: Daniel Stevens <dstevens@atlassian.com>
Date:   Fri Sep 30 15:50:58 2016 -0700
 
    repeated quote to show how a change moves through the process

各コミットメッセージには 4 つの要素があることがわかります。

要素

説明

コミットハッシュ

説明

この特定の変更を識別する英数字文字列 (SHA-1 エンコード)

作成者

説明

変更をコミットした人

日付

説明

変更がプロジェクトにコミットされた日付

Commit Message

説明

変更を説明するテキスト文字列。

ベストプラクティスのヒント: 短い説明のコミットメッセージを記載すれば、誰にとってもより調和のとれた作業リポジトリを作成できます。

特定のコミットを見つける


元に戻したい変更があっても、プロジェクト履歴をかなり遡らなければならず、またかなり広範囲になることがあります。そこで、git log を使用して特定の変更を見つける基本操作をいくつか学習しましょう。

1. 端末ウィンドウで、cd(ディレクトリ変更)コマンドを使用してローカル・リポジトリのトップレベルに移動します。

$ cd ~/repos/tutorial-documentation-tests/

git log --oneline コマンドを入力します。--oneline を追加すると、1 行ずつ各コミットが表示され、端末でより多くの履歴を確認できます。

q キーを押してコミットログを終了すると、いつでもコマンドプロンプトに戻ります。

次の例のような情報が表示されます。

$ git log --oneline
1f08a70 (HEAD -> main, origin/main, origin/HEAD) Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 (origin/changes) myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
...

2. q キーを押し、コマンド・プロンプトに戻ります。

3. git log コマンドによって生成されたリストから、ハッシュ c5826da がついていて変更が増えているコミットを見つけます。説明のコミット・メッセージは記述されていないため、そのコミットに必要な変更が行われているかどうかを確認する必要があります。

4. 端末ウィンドウで git log 結果からコミット・ハッシュ c5826da をハイライトしてコピーします。

5. git show と入力し、コピーしたコミット・ハッシュをペーストまたは転記し、Enter を押します。次のような情報が表示されます。

$git show c5826daeb6ee3fd89e63ce35fc9f3594fe243605
commit c5826daeb6ee3fd89e63ce35fc9f3594fe243605
Author: Daniel Stevens <dstevens@atlassian.com>
Date:   Tue Sep 8 13:50:23 2015 -0700

    more changes

diff --git a/README.md b/README.md
index bdaee88..6bb2629 100644
--- a/README.md
+++ b/README.md
@@ -11,12 +11,7 @@ This README would normally document whatever steps are necessary to get your app
 ### How do I get set up? ###

 * Summary of set up
-* Configuration
-* Dependencies
-* Database configuration
-* How to run tests
-* Deployment instructions
-* more stuff and things
:

下部のプロンプトは、すべての変更を表示するまで続行されます。q を押してコマンドプロンプトを終了します。

git log にフィルターをかけて特定のコミットを見つける


フィルター

機能

コマンドの例

結果

-

機能

表示されるコミットの数を制限する

コマンドの例

git log -10

結果

履歴での最新の 10 のコミット

--after

--before

機能

関連する期間に対して表示されるコミットを制限します。

次を使用することもできます。
--after "yyyy-mm-dd" --before "yyyy-mm-dd"

コマンドの例

git log --after 2017-07-04

結果

2017 年 7 月 4 日以降のすべてのコミット

--author="name"

機能

コミットの作成者と名前が一致するコミットをすべて一覧表示する

コマンドの例

git log --author="Alana"

結果

名前のフィールドに Alana とある名前の作成者によって作成されたすべてのコミット

--grep="message string"

機能

入力した文字列と一致するコミットメッセージを含むすべてのコミットを返す

コマンドの例

git log --grep="HOT-"

結果

メッセージ内のテキストに HOT- が含まれるすべてのコミット

ここまでは git log コマンドについて非常に簡単に説明しました。このようなコマンドにおける作業については、git log チュートリアル: 上級編をご確認ください。

git reset を使用して変更を元に戻す


まず、履歴にある直前のコミットを元に戻してみます。このとき、あなたは Bitbucket の CI/CD ソリューションパイプラインを有効化しましたが、スクリプトが正しくないことに気づいたとします。

1. 端末ウィンドウに git log --oneline と入力します。

2. log: 52f823c にある 2 番目のコミットのコミット・ハッシュをコピーし、q を押してログを終了します。

3. 端末ウィンドウに git reset --soft 52f823c と入力します。成功していればコマンドはバックグラウンドで実行されます。これで最初の変更が元に戻されました。では、このアクションの結果を確認しましょう。

4. 端末ウィンドウに git status と入力すると、コミットが元に戻り、コミットされていない変更となっていることがわかります。次のように表示されます。

$ git status
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
  (use "git pull" to update your local branch)
 
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
 
    new file:   bitbucket-pipelines.yml

5. 端末ウィンドウに git log --oneline と入力します。次のような情報が表示されます。

$ git log --oneline
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 (origin/changes) myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes

6.ブランチの新しい HEAD が想定どおりコミット 52f823c になっていることがわかります。

7. q を押し、ログを終了します。ここまでで簡単なリセットの方法を学習したので、端末を起動させたままにしておき、もう少し複雑な操作を試してみましょう。

git reset を使用して複数の変更を元に戻す


まず、履歴にある直前のコミットを元に戻してみます。このとき、あなたは Bitbucket の CI/CD ソリューションパイプラインを有効化しましたが、スクリプトが正しくないことに気づいたとします。

1. git log --online と入力します。

2. コミット・ハッシュ 1a6a403(myquote edited online with Bitbucket)をコピーします。このコミットはプル・リクエスト #6 の直後にあり、元に戻す必要のある変更が含まれています。

3. 端末ウィンドウに git reset 1a6a403 と入力します。出力は次のようになります。

$ git reset 1a6a403
Unstaged changes after reset:
M README.md
M myquote2.html

変更がコミットされていない状態になったことがわかります。つまり、プロジェクトの履歴とステージングエリアの両方から複数の変更を削除したことになります。

4. 端末ウィンドウに git status と入力します。出力は次のようになります。

$ git status
On branch main
Your branch is behind 'origin/main' by 6 commits, and can be fast-forwarded.
  (use "git pull" to update your local branch)
 
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)
 
    modified:   README.md
    modified:   myquote2.html
 
Untracked files:
  (use "git add <file>..." to include in what will be committed)
 
    bitbucket-pipelines.yml
 
no changes added to commit (use "git add" and/or "git commit -a")

元に戻した最初の変更 (bitbucket-pipelines.yml ファイル) が、完全に git では追跡できなくなりました。これは、git reset を呼び出すことにより、ブランチの HEAD と git の追跡エリアまたはインデックスエリアの両方から変更を削除したためです。根本的なプロセスは、ここで説明しているよりも少し複雑です。詳細については、git reset を参照してください。

5. 端末ウィンドウに git log --oneline と入力します。

1a6a403 myquote edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
e52470d README.md edited online with Bitbucket
e2fad94 README.md edited online with Bitbucket
592f84f Merge branch 'main' into new-feature2 Merge branch  especially if it merges an updated upstream into a topic branch.
7d0bab8 added a line
879f965 adding to the quote file
8994332 Merged in HOT-235 (pull request #2)
b4a0b43 removed sarcastic remarks because they violate policy.
b5f5199 myquote2.html created online with Bitbucket
b851618 adding my first file
5b43509 writing and using tests

ログの出力では、コミット履歴も変更され、コミット 1a6a403 で開始していることを示しています。さらに例を示して説明してみましょう。たとえば、たった今実行したリセットを元に戻したいとします。検討した結果、プル・リクエスト #6 の内容を保持することにします。

resets を Bitbucket にプッシュする


Git resets は、git が提供するいくつかの「元に戻す」方法の 1 つです。リセットは通常、変更を元に戻すための「安全ではない」オプションと見なされています。ローカルに独立したコードで作業する場合はリセットでも問題ありませんが、チームメンバーと共有する場合にはリスクを伴います。

リモートチームがリセットしたブランチを共有するには、「強制プッシュ」を実行する必要があります。「強制プッシュ」は git push -f を実行することによって起動します。強制プッシュを使用すると、プッシュの実行後に構築されたブランチの履歴がすべて削除されます。

この「安全ではない」シナリオの例としては、次のものがあります。

  • 開発者 A は、ブランチで新機能の開発作業に取り組んでいます。
  • 開発者 B は、同じブランチで別の機能の開発作業に取り組んでいます。
  • 開発者 B が、開発者 A と開発者 B の両者が作業を開始する前の状態にブランチをリセットすることにします。
  • その後、開発者 B はそのブランチをリモートリポジトリに強制的にプッシュし、リセットします。
  • 開発者 A が更新を受け取るためにブランチをプルします。このプルの間、開発者 A は強制された更新を受け取ります。これによって、開発者 A のローカルブランチは両者が今までに完了したすべての作業よりも前の時点にリセットされ、両者のコミットが失われます。

git reset を元に戻す


ここまでは、git commit の SHA ハッシュを git reset に渡していました。今、git log の出力からリセットしたコミットが失われています。このようなコミットを取り戻すにはどうしたらよいでしょうか?Git がコミットへのポインターを分離しない限り、コミットが完全に削除されることはありません。さらに、git は「reflog」と呼ばれるすべての ref 動作ログを別に保存しています。git reflog を実行すれば、reflog を調べることができます。

1a6a403 HEAD@{0}: reset: moving to 1a6a403
1f08a70 HEAD@{1}: reset: moving to origin/main
1f08a70 HEAD@{2}: clone: from git@bitbucket.org:dans9190/tutorial-documentation-tests.git

git reflog の出力は上記のようになるはずです。リポジトリでアクションの履歴を確認できます。最初の行は、プル リクエスト #6 を復元するために実行したリセットの参照です。それでは、プル リクエスト #6 を復元するためのリセットをリセットしましょう。この reflog の出力の 2 列目は、リポジトリで実行した変更アクションへの ref ポインターを示しています。ここで、HEAD@{0} は以前に実行したリセット コマンドの参照です。そのリセット コマンドには応答する必要はないため、リポジトリを HEAD@{1} に復元します。

$ git reset --hard HEAD@{1}
HEAD is now at 1f08a70 Initial Bitbucket Pipelines configuration

git log --oneline を使用して、リポジトリのコミット履歴を調べてみましょう。

$git log --online
1f08a70 Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
e52470d README.md edited online with Bitbucket
e2fad94 README.md edited online with Bitbucket
592f84f Merge branch 'main' into new-feature2 Merge branch  especially if it merges an updated upstream into a topic branch.
7d0bab8 added a line
:

ログの出力では、コミット履歴も変更され、コミット 1a6a403 で開始していることを示しています。さらに例を示して説明してみましょう。たとえば、たった今実行したリセットを元に戻したいとします。検討した結果、プル・リクエスト #6 の内容を保持することにします。

Git revert


前の例では、git resetgit reflog を使用して時間を遡る、重要な取り消し操作を実行しました。Git には、もう 1 つの取り消し操作ユーティリティがあり、ほとんどの場合、リセットよりも安全と見なされます。打消し操作では、指定したコミットの変更を打ち消す操作を含む新しいコミットが作成されます。このような打消しコミットはその後、リモートリポジトリに安全にプッシュされ、他の開発者と共有されます。

次のセクションでは、git revert の使用について説明します。前のセクションの例を続けて使用しましょう。まず、ログを調べて、打ち消すコミットを見つけます。

$ git log --online
1f08a70 Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
1f08a70 Initial Bitbucket Pipelines configuration
52f823c repeated quote to show how a change moves through the process
4801b87 Merged in changes (pull request #6)
1a6a403 myquote edited online with Bitbucket
3b29606 myquote2.html edited online with Bitbucket
8b236d9 myquote edited online with Bitbucket
235b9a7 testing prs
c5826da more changes
43a87f4 remivng
d5c4c62 a few small changes
23a7476 Merged in new-feature2 (pull request #3)
5cc4e1e add a commit message
cbbb5d6 trying a thing
438f956 adding section for permissions and cleaning up some formatting
23251c1 updated snipptes.xml organization into resources. other files misc changes
3f630f8 Adding file to track changes
e52470d README.md edited online with Bitbucket
e2fad94 README.md edited online with Bitbucket
592f84f Merge branch 'main' into new-feature2 Merge branch  especially if it merges an updated upstream into a topic branch.
7d0bab8 added a line
:

この例では、作業するコミットとして最新のコミット 1f08a70 を取り上げましょう。このシナリオでは、そのコミットで行った編集を元に戻すことにします。次を実行します。

$ git revert 1f08a70

これによって git merge ワークフローが開始されます。Git により新しいコミットが作成されます。その内容は、打消し操作に指定されたコミットを打ち消すことです。その後 Git によって構成済みのテキストエディターが起動し、新しいコミットメッセージが求められます。このコミットワークフローのため、打消しはより安全な取り消し操作のオプションと見なされています。打消しコミットの作成では、取り消し操作を実行した時のコミット履歴に明確な痕跡が残ります。

これで、変更を元に戻す方法の学習が終了しました。


お疲れさまでした。必要な時にこのチュートリアルを参照するか、「変更を元に戻す」セクションに進み、詳細を学習してください。Bitbucket で効率よく作業しましょう!


この記事を共有する
次のトピック

おすすめコンテンツ

次のリソースをブックマークして、DevOps チームのタイプに関する詳細や、アトラシアンの DevOps についての継続的な更新をご覧ください。

一面のツールを使ってコラボレーションしている人たち

Bitbucket ブログ

DevOps のイラスト

DevOps ラーニング パス

Demo Den アトラシアン・エキスパートによる機能デモ

Bitbucket Cloud が、Atlassian Open DevOps とどのように連携するか

DevOps ニュースレター購読

Thank you for signing up