高度なGitガイド:Gitスタッシュ、リセット、リベースなど

公開: 2022-03-11

すべての開発者はバージョン管理をよく理解している必要があり、Gitはソフトウェア開発におけるバージョン管理の事実上の標準になっています。

ただし、多くの場合、開発者はいくつかの簡単なコマンドを学習するだけで、Gitの歴史の力やGitがあなたをはるかに効率的にするためにできる他のことを見落としています。 たとえば、リリースの管理はgit tagを使用したGitで非常に簡単です。

私はGitオンライン(Githubを使用)で上級コースを受講し、Githubと組み合わせて初心者向けのGitクラスを教えました。 お気に入りのGit機能に関する技術記事があまりないことに気付いたとき、私はそれを仲間の開発者と共有する機会に飛びつきました。 この投稿では、次の高度なGit機能を活用する方法を学習します。

  • git stashは、コードを一時的にローカルに保存します
  • git reset 。これにより、コミットを実行する前にコードを整理できます。
  • git bisect 、悪いコミットを追い出すことを可能にする関数
  • コミットを組み合わせることができるgit squash
  • git rebaseは、あるブランチから別のブランチに変更を適用できるようにします

Git Stash

Git stashを使用すると、コミットせずにコードを保存できます。 これはどのように役立ちますか? 次のシナリオを想像してください。

あなたはすでに3つのきちんと整頓されたコミットをしましたが、かなり厄介なコミットされていないコードもあります。 最初にデバッグコードを削除せずにコミットしたくないでしょう。 次に、何らかの理由で、突然別のタスクに参加し、ブランチを切り替える必要があります。 これは、 mainブランチにいて、機能の新しいブランチを作成するのを忘れた場合によく発生します。 現在、コードは次のようになっています。

 $ git status On branch my-feature 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: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")
 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }

git stashを実行すると、コミットされていないコードはコミットされずに消えます。 スタッシングは、ブランチへの一時的なローカルコミットを保存するようなものです。 スタッシュをリモートリポジトリにプッシュすることはできないため、スタッシュは個人的な使用のみを目的としています。

 $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color

これで、最後のコミットを行ったときのブランチが表示されます。 これで、コードを失ったり、面倒なコミットをしたりすることなく、ブランチを安全に変更できます。 ブランチに戻ってgitstashlistを実行すると、次のようなgit stash listが表示されます。

 $ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color

git stash applyを実行すると、隠されたコンテンツを簡単に再適用できます。 git stash apply stash@{1}を実行して、特定のスタッシュを適用することもできます(複数回スタッシュした場合)(「1」は最後のスタッシュの2番目前を示します)。 複数のコミットを隠して別の隠しを適用する例を次に示します。

 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..b63c664 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; } $ git stash Saved working directory and index state WIP on my-feature: 49ee696 Change text color
 $ git stash list stash@{0}: WIP on my-feature: 49ee696 Change text color stash@{1}: WIP on my-feature: 49ee696 Change text color stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash apply stash@{2} On branch my-feature 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: css/common.scss no changes added to commit (use "git add" and/or "git commit -a")

git stash apply stash@{2}は、テキストの色を赤に変更したときに、最も古い隠しコードを適用しました。

 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: #333; + color: red; background-color: #f00; }

スタッシュを復元した後で作業をコミットしないことにした場合は、gitcheckoutを実行できますgit checkout . 、コミットされていないすべてのコードをリセットします。

Git stashの使用方法の別の例として、新しいファイルがいくつかあり、そのうちの1つにバグがあるとします。 疑わしいバグファイルを除くすべてをステージングせずに残し(コードをステージングしてスタッシュする必要があります)、そのファイルをスタッシュして問題のトラブルシューティングを行うことができます。 隠しファイルに問題がなかった場合は、隠しファイルを復元できます。

 $ git status On branch my-feature Untracked files: (use "git add <file>..." to include in what will be committed) css/colors.scss nothing added to commit but untracked files present (use "git add" to track)
 $ git add css/colors.scss $ git stash Saved working directory and index state WIP on my-feature: 0d8deef delete colors $ git status On branch my-feature nothing to commit, working tree clean $ git stash apply stash@{0} On branch my-feature Changes to be committed: (use "git reset HEAD <file>..." to unstage) new file: css/colors.scss

git stash branchを使用して、隠しコミットを新しい機能ブランチまたはデバッグブランチに引き継ぐこともできます。

 $ git status On branch my-feature 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: css/common.scss no changes added to commit (use "git add" and/or "git commit -a") $ git stash Saved working directory and index state WIP on my-feature: 66f3f3b Add colors file $ git stash branch debugging-branch M css/common.scss Switched to a new branch 'debugging-branch' Unstaged changes after reset: M css/common.scss On branch debugging-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: css/common.scss Dropped refs/stash@{0} (d140624f60d8deef7bceb0d11fc80ed4fd47e0a1)

スタッシュを適用した場合、スタッシュは削除されないことに注意してください。 git dropを使用して個別にスタッシュを削除するか、 git stash clearを使用してすべてのスタッシュを削除できます。

 $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors stash@{2}: WIP on my-feature: 49ee696 Change text color $ git stash drop stash@{2} Dropped stash@{2} (8ed6d2ce101aa2e28c8ccdc94cb12df8e5c468d6) $ git stash list stash@{0}: WIP on my-feature: 66f3f3b Add colors file stash@{1}: WIP on my-feature: 0d8deef delete colors $ git stash clear $ git stash list $

Gitリセット

誤って厄介なコードをコミットした場合は、「ソフト」リセットを実行できます。 これは、コードがまだコミットされていないように見えることを意味します。 次に、よりクリーンなコミットを行う前に、IDEでコードを整理できます。 これを行うには、 git reset --soft HEAD~1を実行します。 これにより、最新のコミットがリセットされます。 ~の後に番号を変更することで、複数のコミットをリセットして戻すことができます(例: git reset --soft HEAD~2

 $ git reset --soft HEAD~1 $ git status On branch debugging-branch Changes to be committed: (use "git reset HEAD <file>..." to unstage) modified: css/common.scss 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: css/common.scss
 $ git diff diff --git a/css/common.scss b/css/common.scss index 2090cc4..90fd457 100644 --- a/css/common.scss +++ b/css/common.scss @@ -13,6 +13,6 @@ body { font-family: "Proxima Nova", Arial, sans-serif; font-size: 13px; - color: $grey; + color: red; background-color: #f00; }

Gitのリセットは、特に新しいGitユーザーに教える場合は、少し混乱します。 ソフトリセットは本物の間違いのために予約する必要がありますが、スタッシュはコードをスワップインおよびスワップアウトするために使用できます。

ハードリセットを実行することもできます( git reset --hard HEAD~1 )。 このタイプのリセットは、基本的に最後のコミットを消去します。 コミットを復元する方法がないため、特にブランチをプッシュする場合は、ハードリセットの実行に十分注意する必要があります。

Git Bisect

私のお気に入りのGitツールはgit bisectです。 私はそれをほんの一握りしか必要としませんでした、しかし私がそうしたとき、それはかけがえのないものでした! 私は主に、激しいデバッグを行った後でも、根本的な原因を誰も見つけられないという問題があった大規模なコードベースで使用しました。

git bisectは基本的に、指定された2つのコミット間でバイナリ検索を実行し、特定のコミットの詳細を表示します。 まず、Gitに、機能が機能していることがわかっている適切なコミットと、不適切なコミットを与える必要があります。 良いコミットと悪いコミットが1つある限り、コミットは何年も離れている可能性があることに注意してください(ただし、過去にさかのぼると、より困難になります!)。

git bisectの最も楽しい点は、開始時に誰がバギーコミットを書いたかを通常は本当に知らないということです。 バグが発生した場所を見つけることに興奮したことで、数人の同僚が私のコンピューターの周りに群がりました。

開始するには、バグのあるブランチをチェックして、適切なコミットを見つけてください。 コミット履歴を調べてコミットハッシュを見つけてから、その特定のコミットをチェックしてブランチをテストする必要があります。 作業するのに良い場所と悪い場所を見つけたら、 git bisectを実行できます。

このシナリオでは、作成したこのWebサイトのテキストは赤ですが(UIデザイナーを使用することもできます)、いつどのように赤にしたかはわかりません。 これは非常に単純な例です。実際のシナリオでは、フォームが送信/機能しないなど、それほど明白ではない問題が発生する可能性があります。

git logを実行すると、選択するコミットのリストが表示されます。

 $ git log commit a3cfe7f935c8ad2a2c371147b4e6dcd1a3479a22 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Update .gitignore file for .DS_Store commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:51:23 2021 +0100 Change styling of page commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit 032a41136b6653fb9f7d81aef573aed0dac3dfe9 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:42:57 2021 +0100 Change text color commit 246e90977790967f54e878a8553332f48fae6edc Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:41:23 2021 +0100 delete colors commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:07:36 2021 +0100 ...

最新のコミットハッシュでWebページを開くと、テキストが赤になっているため、問題があることがわかります。

Gitバイセクト、ステップ1:赤いテキストのあるWebページ。

次に、バイセクトを開始し、Gitに悪いコミットがあることを伝えます。

 $ git bisect start $ git bisect bad 8d4615b9a963ef235c2a7eef9103d3b3544f4ee1

ここで、時間をさかのぼって、テキストが赤ではないコミットを見つけようとします。 ここで最初のコミットをチェックしてみます…

 $ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles

…そしてウェブページを更新する…

Gitバイセクト、ステップ2:黒いテキストのWebページ。

テキストは赤ではなくなったので、これは良いコミットです! コミットが新しいほど、つまり、悪いコミットに近いほど良いです。

 $ git checkout d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Previous HEAD position was ce861e4c6989a118aade031020fd936bd28d535b Add CSS styles HEAD is now at d647ac4 Change text color

Gitは、適切なコミットを見つける前に検索する必要のあるコミットの数を通知します。 Gitがトラバースするコミットの数は、良いコミットと悪いコミットの間にあるコミットの数によって異なります(時間が長いほど、Gitが反復する必要がある回数が多くなります)。

次に、ブランチを再度テストして、問題が解消されたかどうかを確認する必要があります。 モジュールを定期的に更新する場合、フロントエンドリポジトリにノードモジュールを再インストールする必要があるため、これは少し面倒な場合があります。 データベースが更新されている場合は、これらも更新する必要があります。

git bisectは、良いコミットと悪いコミットの途中でコミットを自動的にチェックアウトします。 ここでは、悪いコミットを見つけるための1つのステップを見積もっています。

 $ git bisect good 1cdbd113cad2f452290731e202d6a22a175af7f5 Bisecting: 1 revision left to test after this (roughly 1 step) [ce861e4c6989a118aade031020fd936bd28d535b] Add CSS styles $ git status HEAD detached at ce861e4 You are currently bisecting, started from branch '8d4615b'. (use "git bisect reset" to get back to the original branch)

ページを更新して、問題がなくなったかどうかを確認します。 問題はまだ残っているので、これはまだ悪いコミットであるとGitに伝えます。 Gitはチェックアウトしたコミットを使用するため、今回はコミットハッシュを参照する必要はありません。 Gitがすべての可能なステップを通過するまで、このプロセスを繰り返す必要があります。

 $ git bisect bad Bisecting: 0 revisions left to test after this (roughly 0 steps) [cbf1b9a1be984a9f61b79ae5f23b19f66d533537] Add second paragraph to page

ページを更新すると、問題が再び解消されるので、これは良いコミットです。

Gitバイセクト、ステップ3:同じWebページにいくつかの追加の黒いテキストがあります。

この段階で、Gitは最初の悪いコミットを見つけました。

 $ git bisect good ce861e4c6989a118aade031020fd936bd28d535b is the first bad commit commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles :000000 100644 0000000000000000000000000000000000000000 092bfb9bdf74dd8cfd22e812151281ee9aa6f01a M css

これで、 git showを使用してコミット自体を表示し、問題を特定できます。

 $ git show ce861e4c6989a118aade031020fd936bd28d535b commit ce861e4c6989a118aade031020fd936bd28d535b Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:52:57 2021 +0100 Add CSS styles diff --git a/css/base.scss b/css/base.scss index e69de29..26abf0f 100644 --- a/css/base.scss +++ b/css/base.scss @@ -1,7 +1,7 @@ body { background-color: $white; margin: 0px; line-height: 20px; - color: $grey; + color: red; }

終了したら、 git bisect resetを実行して、ブランチを通常の動作状態にリセットできます。

コミットが近ければ近いほど、Gitは問題を見つけやすくなりますが、10ステップ前に実行しても、悪いコミットを簡単に見つけることができます。 動作が保証されているわけではありませんが、ほとんどの場合、問題が見つかりました。 おめでとうございます、あなたはコード考古学者です!

あなたのコミットを押しつぶす

私は以前、グローバル組織のオープンソースプロジェクトにフルタイムで取り組んでいましたが、コミットを押しつぶす、または組み合わせることがいかに重要であるかをすぐに学びました。 たとえあなたの雇用主がそれを必要としないとしても、それは入るのに良い習慣だと思います。 後で作成した機能を確認および編集する必要がある他の開発者にとっては特に配慮が必要です。

なぜあなたのコミットを押しつぶすのですか?

  • リポジトリへの寄稿者が読みやすくなります。 次のようなコミットリストがある場合を想像してみてください。
    • カルーセルスライダーを実装する
    • カルーセルにスタイリングを追加
    • カルーセルにボタンを追加
    • カルーセルを使用したIEの奇妙な問題を修正
    • カルーセルのマージンを調整する

    これらを「ホームページにカルーセルを追加する」という1つのコミットにまとめる方がはるかに簡単です。

  • プルリクエストを行うたびにコミットを1つにまとめる必要がある場合は、コミットメッセージを理解可能で関連性のあるものに保つことをお勧めします。 「WIP」、「ログインページのバグ修正」、または「タイプミスの修正」というタイトルのコミットを何回見ましたか。 関連するコミット名を付けることが重要です。たとえば、「#444ログインページのバグ修正-$scope関数がないためにちらつきを修正する」などです。

コミットを潰したくない理由は、非常に詳細で長い機能に取り組んでいて、後でバグに遭遇した場合に備えて、毎日の履歴を自分で保持したいためである可能性があります。 そうすれば、機能のデバッグが簡単になります。 ただし、機能をメインブランチにチェックインし、バグがないと確信している場合でも、潰すことは理にかなっています。

このシナリオでは、5つのコミットを行いましたが、それらはすべて1つの機能に関連しています。 私のコミットメッセージは、分離するメリットと密接に関連しています。すべてのコミットは、この新機能のページのスタイル設定に関するものです。

 $ git log commit a8fbb81d984a11adc3f72ce27dd0c39ad24403b7 (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:16:10 2021 +0100 Import colors commit e2b3ddd5e8b2cb1e61f88350d8571df51d43bee6 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 11:15:32 2021 +0100 Add new color commit d647ac489ad43b3c6eaea5aceb02b0a7d7e5cf8e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 10:50:48 2021 +0100 Change text color commit c005d9ceeefd4a8d4e553e825fa40aaafdac446e Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:59:57 2021 +0100 Add CSS styles commit 9e046b7df59cef07820cc90f694fabc666731bd2 Author: Ursula Clarke <[email protected]> Date: Tue Jan 11 09:56:28 2021 +0100 Add second paragraph to page commit 5aff973577d67393d914834e8af4c5d07248d628 Author: Ursula Clarke <[email protected]> Date: Mon Jan 10 16:04:22 2021 +0100 Add colors CSS file and edit background color

git merge --squashを使用することもできますが、コミットをチェリーピックすると、コミットの説明が見やすくなるため、 rebaseを使用する方が明確だと思います。 git merge --squashを実行する場合は、最初にコミットのハードリセットを実行する必要があり( git reset --hard HEAD~1 )、これを実行するために必要なコミットの正確な数と混同されがちです。 git rebaseの方が視覚的だと思います。

git rebase -i --rootを実行することから始めます。コマンドラインでデフォルトのテキストエディタが開き、コミットのリストが表示されます。

 pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page pick c005d9c Add CSS styles pick d647ac4 Change text color pick e2b3ddd Add new color pick a8fbb81 Import colors # Rebase a8fbb81 onto b862ff2 (7 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

最後のいくつかのコミットを潰したい場合があります。その場合、 git rebase -i HEAD~3を実行して、最後の3つのコミットを表示できます。

 pick eb1eb3c Update homepage pick 5aff973 Add colors CSS file and edit background color pick 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

これで、以下に示すように、すべてのコミットを最初のコミットに押しつぶすことができます。

 pick eb1eb3c Update homepage squash 5aff973 Add colors CSS file and edit background color squash 9e046b7 Add second paragraph to page # Rebase b862ff2..9e046b7 onto b862ff2 (3 commands) # # Commands: # p, pick = use commit # r, reword = use commit, but edit the commit message # e, edit = use commit, but stop for amending # s, squash = use commit, but meld into previous commit # f, fixup = like "squash", but discard this commit's log message # x, exec = run command (the rest of the line) using shell # d, drop = remove commit # # These lines can be re-ordered; they are executed from top to bottom. # # If you remove a line here THAT COMMIT WILL BE LOST. # # However, if you remove everything, the rebase will be aborted. # # Note that empty commits are commented out

ファイルを保存すると、Gitはコミットメッセージを開いて編集します。

 # This is a combination of 3 commits. # This is the 1st commit message: Update homepage # This is the commit message #2: Add colors CSS file and edit background color # This is the commit message #3: Add second paragraph to page # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # Date: Wed Jan 13 18:31:28 2021 +0100 # # interactive rebase in progress; onto b862ff2 # Last commands done (3 commands done): # squash 5aff973 Add colors CSS file and edit background color # squash 9e046b7 Add second paragraph to page # No commands remaining. # You are currently rebasing branch 'main' on 'b862ff2'. # # Changes to be committed: # new file: .gitignore # new file: css/base.css # new file: css/base.scss # new file: css/colors.css # new file: css/colors.css.map # new file: css/colors.scss # new file: css/common.css # new file: css/common.scss # new file: index.html #

リベースを実行している間、読みやすくするためにコミットの説明を編集することもできます。

 Implement new design for homepage. Add .gitignore file for Sass folder. # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. #

このファイルをもう一度保存すれば完了です。 Gitログをもう一度見ると、クリーンなコミットが1つしかないことがわかります。

 [detached HEAD 574ec7e] Implement new design for homepage. Add .gitignore file for Sass folder. Date: Wed Jan 13 18:31:28 2021 +0100 10 files changed, 215 insertions(+) create mode 100644 .gitignore create mode 100644 css/base.css create mode 100644 css/base.scss create mode 100644 css/colors.css create mode 100644 css/colors.css.map create mode 100644 css/colors.scss create mode 100644 css/common.css create mode 100644 css/common.scss create mode 100644 index.html create mode 100644 verylargefile.txt Successfully rebased and updated refs/heads/main. $ git log commit 574ec7e5d7d7a96427e049cad9806cdef724aedd (HEAD -> main) Author: Ursula Clarke <[email protected]> Date: Wed Jan 13 18:31:28 2021 +0100 Implement new design for homepage. Add .gitignore file for Sass folder.

Git Rebase

開発者は通常、リベースを使用してコードベースからファイルを完全に削除できることを知っているため、 git rebaseの使用を躊躇します。

上で見たように、 git rebaseを使用してコードを保持し、コードを整理して削除することができますが、本当にファイルを履歴から完全に削除したい場合はどうでしょうか。

私はかつて、開発チームのメンバーが誤って非常に大きなファイルをコードベースにコミットしたというシナリオを目撃しました。 これははるかに大きなブランチの一部であったため、コードレビューで大きなファイルが見過ごされ、誤ってメインブランチにチェックインされました。 これは、誰かがリポジトリのクローンを再作成したいときに問題になりました-ダウンロードするのに非常に長い時間がかかりました! そしてもちろん、問題のファイルは不要でした。 ファイルがメインブランチへの最後のコミットである場合は問題ありませんでした。その場合は、ハードリセット( git reset --hard HEAD~1 )を実行して、ブランチを強制的にプッシュすることができます。

同様に、特定のコミットでファイルが唯一の変更である場合は、 git reset --hard <commit-id>実行することで、コミット全体を削除できます。 ただし、このシナリオでは、大きなファイルは、最後から2番目のコミットとして、履歴に保持したい他のコードと一緒にコミットされました。

面倒なコミットを見つけたら、 git checkoutとコミットハッシュを使用してチェックアウトします。

 $ git checkout ce861e4c6989a118aade031020fd936bd28d535b Note: checking out 'ce861e4c6989a118aade031020fd936bd28d535b'. You are in 'detached HEAD' state. You can look around, make experimental changes and commit them, and you can discard any commits you make in this state without impacting any branches by performing another checkout. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -b with the checkout command again. Example: git checkout -b <new-branch-name> HEAD is now at ce861e4 Add CSS styles

ファイルを削除するか、コードを編集して、残しておきたいコードをそのまま残します。

 $ rm verylargefile.txt $ git status HEAD detached at ce861e4 Changes not staged for commit: (use "git add/rm <file>..." to update what will be committed) (use "git checkout -- <file>..." to discard changes in working directory) deleted: verylargefile.txt no changes added to commit (use "git add" and/or "git commit -a")

git add -Aを実行して、削除したファイルがステージングされ、Gitがそれを削除することを認識できるようにしてください。 ここgit commit --amend -vを実行すると、Gitはコミットメッセージを編集するように要求します。

この後、 git rebase --onto HEAD <commit-id> main実行します。 これは、いくつかのマージの競合に遭遇する可能性がある場所です。つまり、新しいコミットと古いコードの間に競合があります。 Gitは、競合を解決するように求めます。

 $ git add -A $ git status HEAD detached at ce861e4 Changes to be committed: (use "git reset HEAD <file>..." to unstage) deleted: verylargefile.txt $ git commit --amend -v [detached HEAD 7c9516a] Add CSS styles Date: Thu Jan 14 14:43:54 2021 +0100 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 css/common.css.map delete mode 100644 verylargefile.txt $ git status HEAD detached from ce861e4 nothing to commit, working tree clean $ git rebase --onto HEAD ce861e4 First, rewinding head to replay your work on top of it... Fast-forwarded HEAD to HEAD.

テキストエディタでファイルを開くと、Gitが2つのバージョンのインデックスファイルをマークアウトしていることがわかります。 必要な変更を保持するには、1つを削除するか、1つを編集するだけです。

 <p> Toptal was created by engineers. We are entrepreneurs, all passionate about working with top tech talent and exciting companies from all over the world. </p> <<<<<<< HEAD <p> Toptal connects the top 3% of freelance talent all over the world. </p> </main> </body> </html> ======= </main> </body> </html> >>>>>>> Add index file

<<<<<<< HEADと等号の行の間のコードは1つのバージョンであり、等号と>>>>>>> Add index fileの間のコードは、「インデックスファイルの追加」コミットからのバージョンです。 。 したがって、一方のバージョンには「Toptalが世界中のフリーランスの才能の上位3%をつなぐ」という追加の段落があり、もう一方のバージョンにはないことがわかります。

編集したファイルを保存し、 git add filenameを実行してからgit rebase --continueを実行します。 変更がない場合は、 git rebase --skipを実行することもできます。 「大きなファイル」のコミットとメインの最新のコミットの間に多くのコミットがあった場合、リベースが完了するまでに時間がかかることがあります。

辛抱強く、大規模なチームに所属している場合は、セカンドオピニオンを取得してください。 可能であれば、マージするコミットを作成した人に相談することが特に重要です。

マージの変更は、最新の変更ではなく、履歴内の特定のコミットに関連していることに注意してください。 つまり、サイトのテキストがArialであったときからコミットを編集していて、現在はVerdanaである場合でも、フォント面としてArialの履歴を使用してそのコミットを保持する必要があります。

Gitがスペースまたは行末文字を検出した場合、マージの競合が発生する可能性があることにも注意してください。注意してください。

コミットしてプルするだけではありません

Gitは、多くの開発者が考えるよりも強力です。 初心者を紹介する場合は、これらの貴重な機能に関するヒントを必ず提供してください。 これにより、ワークフローがより効率的になります。

Gitについてもっと知りたいですか? ToptalのGitのヒントと実践のページをご覧ください。