Git学習メモ
Commit
適切な変更を追加する
ステージング領域は,すべての変更から一部の変更をピックし,意味のあるコミットを構成するためのもの
git add -p ${file name}
一つのファイルの中の変更箇所ごとにステージングするかを選択できる(y/n
)
適切なコミットメッセージを作成する
Subject
何が起こったのかを簡潔にまとめる
Body
- 以前と何が違うのか
- 変更の理由は何か
- 注目すべき点,特筆すべき点は何か
ブランチ戦略
- チームでのルールを文書化すること
- 自動化できる規約に関しては自動化したい
極端な例:メインブランチのみの開発(常に統合された状態)
- 追跡が容易
- コミットが小さくなければいけない
- 高品質のテスト環境をセットアップする必要がある
極端な例:複数の異なるタイプのブランチでの開発
ブランチの種類
- 長期ブランチ
本番環境用,開発環境用など永続的に使用する - 短期ブランチ
マージ後に削除する
ブランチ戦略の例
- GitHub Flow
- 長期ブランチ
- メインブランチのみ
- 短期ブランチ
- 機能修正,バグ修正,リファクタリングなどアクティブに取り組んでいることに使う
- 長期ブランチ
- GitFlow
- main
- 本番環境を反映
- develop
- 開発環境を反映
- 機能開発のブランチ(feature)の分岐点と終着点になる
- リリースの出発点にもなる
- テスト,バグ修正用のブランチ(release)の分岐点と終着点になる
- すべての準備が整えば,本番環境(main)にマージされる
- 開発環境を反映
- main
プルリクエスト
背景
- 変更に対してフィードバックをもらうために行う
- 単にマージするよりも厳重に変更をマージできる
- マージするために必要な要件をまとめたテストを挟んだりすることもできる
- オープンソースリポジトリに貢献するために行う
- リポジトリに貢献したくても通常はアクセス権がない
- アクセス権がないレポジトリを変更したい場合,リポジトリをローカルへフォークして,変更を加えたのち,プルリクエストを出す必要がある
- フォーク
- gitリポジトリの個人的なコピー
- クローンとの違い
- クローンは,全ての履歴、ブランチ、タグ、コミット履歴などを含めて、全く同じコピーを作成します。そのため,リポジトリを他の場所に移動したり、別の人が同じコードベースを共有したりする場合に便利
- クローンは、元のリポジトリの変更内容を自動的に反映することができます。一方、フォークは、元のリポジトリの変更内容を手動でマージする必要があります。
- 両者とも、元のリポジトリから独立したコピーを作成する
競合(Conflict)の解決
いつ起こりうるか
マージが別のソースから変更され,それをマージする時
- 注意
-
git merge
以外の場面でもコンフリクトは起こりうる
-
実際には何なのか
矛盾した変更をマージすること
どのように解決するのか
矛盾した変更の内,どの変更を反映するのかを改めて指定する
- 手順
-
git merge
- マージしようとするとコンフリクトが発生したというメッセージが表示される
-
git status
- マージされていないパスが表示される
-
コンフリクトは以下のように表示されます
<<<<<<< HEAD
This is the original text in file.txt
=======
This is the new text from develop branch
>>>>>>> develop
HEADというのは現在作業しているブランチを示し、developはマージしようとしているブランチ名を示します。
<<<<<<< HEAD
から=======
の間にあるのは現在作業しているブランチでの変更内容で、=======
から>>>>>>> develop
の間にあるのはマージしようとしているブランチでの変更内容です。
別の方法としては変更を元に戻す方法もある
-
git merge --abort
- マージを中止して,現在の作業ツリーを前のコミットの状態に戻す(マージのために作成されたコミットを削除する)
- 注意
- コンフリクト解消のための編集を一切行っていない場合でしか使えない
- 作業の変更が隠されておらず,コミットも作成されていない場合,変更が削除されてしまう可能性がある
- 注意
- マージを中止して,現在の作業ツリーを前のコミットの状態に戻す(マージのために作成されたコミットを削除する)
git rebase --abort
Merge vs. Rebase
Merge
マージの際にGitは3つのコミットに注目する
- 共通祖先のコミット
- ブランチAの最終コミット
- ブランチBの最終コミット
Fast-Forward
共通祖先のコミットとブランチAの最終コミットが一致している場合,単純にブランチBのコミットをブランチAのコミットの先につなげればいい
Merge Commit
共通祖先のコミットとブランチAの最終コミットが一致していない場合,一致していない二つのブランチを接続するためのコミットがGitによって自動的に作成される
Rebase
git rebase branch-B
- 手順
- 共通祖先のコミットの後に発生したブランチAの全てのコミットをカットする(削除するわけではなく,別で保持している)
- ブランチBからの新しいコミットが共通祖先のコミットに追加される
- カットしたコミットをブランチの先端に追加する
- 共通祖先のコミットの後に発生したブランチAの全てのコミットをカットする(削除するわけではなく,別で保持している)
さらに次の点にも注意する必要がある
1つのコミットは以下の3つの主要な要素から構成される
- コミットのメタデータ
- 作成者
- 作成日時
- コミットメッセージ
- ツリーオブジェクト
- コミット時にステージングエリアにあったすべてのファイルとディレクトリの状態
- 親コミット
- 直前のコミットのハッシュ値
- Gitは、親コミットを使用して、新しいコミットがどのように変更されたかを特定します。
- 直前のコミットのハッシュ値
これより,C3は親コミットが変わったため,別のコミットとして扱われる
Gitはあなたのセーフティネット
ソフトウェア開発ではミスは頻繁に起こる
Gitは私たちのミスをやり直し,リカバーするのに役立つ
ファイルのローカルな変更を破棄する
git restore <file name>
動機
- コミット前で,納得のいかない変更を発見し,やり直したい
- 謝って削除してしまったファイルを取り戻したい
注意点
メモ
git checkout
でも現在の変更内容を破棄し,ブランチを移動することができるが,git restore
の方が,より用途が限定的であいまいさを解消できる
ファイルの一部を破棄する
git restore -p <file name>
動機
ファイルの変更の中で,やり直したい部分だけ削除して,あとはそのままにしたい
メモ
- このコマンドを実行するとファイル内のパッチが順番に表示され,どのパッチを削除するかを指定できる(
y/n
)
-
p
はpatch(継ぎ目)の略
すべてのローカルな変更を破棄する
git restore .
動機
全てがうまくいっておらず,修正するのではなく,一からやり直したい
注意点
メモ
.
は変更があった全てのファイルを意味する
最後のコミットを修正する
git commit --amend -m "<commit message>"
動機
コミットメッセージを忘れたり,追加すべきだった変更を追加し忘れたので,コミットを修正したい
注意点
途中のコミットを取り消す
動機
注意点
メモ
古いリビジョンにリセットする
動機
注意点
メモ
ファイルを古いリビジョンにリセットする
動機
ある特定のファイルについて,過去のバージョンに戻したい
注意点
メモ
Reflog
動機
注意点
メモ
削除されたコミットを復元する
動機
注意点
メモ
削除したブランチを復元する
動機
注意点
メモ
コミットを新しいブランチに移動する
動機
注意点
メモ
コミットを別のブランチに移動させる
動機
注意点
メモ
Interactive Rebase:できることの概説
Interactive Rebase:一般的な仕組みについて
Interactive Rebaseで古いコミットメッセージを編集する
動機
注意点
メモ
Interactive Rebaseでコミットを削除する
動機
注意点
メモ
Interactive Rebaseで複数のコミットを1つにまとめてしまう
動機
注意点
メモ
Interactive Rebaseで古いコミットに変更を加える
動機
注意点
メモ
Interactive Rebaseで古いコミットを分割・編集する