【Git】SourceTreeで基本操作を練習しました

2021/07/10に公開約8,800字

はじめに

開発業務においてGit管理・操作は不可欠となっているため、基本知識と操作コマンドに関して最低限押さえておきたいポイントを本記事でまとめた。

目次

最初に簡単な構成を記す。

  • Gitの基本知識
  • Git操作をSourTreeで理解する
  • マージリクエストの注意点

Gitの基本知識

Gitの3層構造

  1. リモートブランチ
  • プロジェクトの最新状態を保管するためのブランチで、リモート(URL)上に存在
  1. リモート追跡ブランチ
  • リモートブランチの状況を追跡するためのブランチで、ローカル上に存在
  1. ローカルブランチ
  • ローカルの中心となる統合ブランチで、ローカル上に存在

Gitの基本コマンド(ローカル→リモート)

  1. status
  • Gitで管理している内容とローカルの変更内容の差分を確認
git status
  1. add
  • ローカルで更新した内容をGit管理の対象に入れる
git add .
  1. commit
  • ローカルで更新した内容をGitのローカルブランチに乗せる
git commit -m "コメント"
  1. push
  • ローカルで更新した内容をGitのリモートブランチに反映させる
git push -u origin main(現在のブランチがmainで初回プッシュの時のみ)
or
git push(2回目以降のプッシュ時)
  1. stash
  • ローカルの更新内容で不要なファイルを一時的な管理領域に飛ばす
    ★ブランチ内で本来実装すべき機能以外のコードを編集してしまった場合、それらのコードを一時的に別領域の管理ボックスに飛ばす
git stash -u
  1. branch
  • ローカルで各機能ごとにブランチを派生させる
    feature/Issuesの連番値_実装したい機能名をブランチ名として指定する
  • 現在のブランチを確認
    projectAのdevelopブランチにいることがわかる
~/projectA(develop)
git branch
  • 新規ブランチの作成
~/projectA(develop)
$ git branch feature/01_Btn
  • 作成した新規ブランチに移動
~/projectA(develop)
$ git checkout feature/01_Btn
~/projectA(feature/01_Btn)
  1. merge(pull) request
  • 新規ブランチの変更内容を開発用ブランチに反映させる際に、コードレビューとマージを依頼する
  • マージリクエストの準備
~/projectA(feature/01_Btn)
git add.
git commit -m "[fix] UI"
git push --set-upstream origin branchname
  • リモートURLでマージリクエスト
    ~/projectA(feature/01_Btn) → ~/projectA(develop)
    Merge Request or Pull Requestボタンをクリック

Gitの基本コマンド(リモート→ローカル)

  1. clone
  • リモートの統合ブランチ(main)をローカルに取り込む
git clone https://github.com/username/projectA.git
  • リモートの開発ブランチ(develop)をローカルに取り込む
git clone -b develop https://github.com/username/projectA.git
  1. fetch
  • リモートの開発ブランチ(develop)をローカルのリモート追跡ブランチに取り込む
git fetch
  1. merge
  • ローカルのリモート追跡ブランチの最新情報をローカルブランチに取り込む(あまり使わない)
git merge
  1. pull
  • リモートブランチの最新情報をローカルブランチに取り込む
    fetch + merge
git pull

Git操作をSourTreeで理解する

下記のリンク先の動画教材でSourceTreeを用いたGUIでのGit操作を習得する。
全部で11章あるが一つ一つの内容は軽量なのでサクッと終えることができる。

https://www.youtube.com/playlist?list=PLvEni36L5VuXc3dpowx66hTDuj6qFg5Mm

動作環境

  • Windows 10
  • SourceTree
  • GitLab

★Sourcetreeとはブランチの関係性が視覚的に分かりやすいGitのGUIアプリケーション

1.Git操作の理解

前章のGitの基本知識と合わせて理解を深めたい

2.リポジトリを作成

試験用レポの作成

  • GitLabでプロジェクト「repos」を作成
  • Clone with HTTPSをクリックしURLをコピー
    https://lab.XXXX.com:Port/username/repos.git
  • SourceTreeのメニュータブでCloneボタンをクリックし保存先パスにローカルの空フォルダを指定して作成ボタンをクリック
    C:\Users\username\Documents\repos

3. ステージング

  • 作業ツリーのファイルを確認するとローカルの変更内容が表示される
  • 作業ツリーのファイルをドラッグアンドドロップするかチェック選択してステージングをクリック

★ファイルの左にあるマークには以下の意味があるので覚えておくとよい

  • 紫:Git管理されているファイルで参照先が見当たらないことを通知(新規作成ファイル)
  • オレンジ:Git管理されているファイルに変更内容があることを通知
  • 灰色:Git管理されているはずのファイルが削除されたことを通知

4.コミット

  • ステージングしたファイルを選択し右下のコミットボタンでコミット

★コミットの段階でファイルは分割できる

  • 例えば、headerとbodyとfooterの内容を更新する際、header用のブランチ内でheaderとbodyを更しまった場合、headerのみを選択してコミットし、後でbodyのみを選択してコミットする

5. コミット間の移動

  • 移動したいコミット項目をダブルクリックして確認画面が表示されるのでOKをクリック
  • HEADタグは、全体として進んでいるコミットに対して自分が存在するコミットを表示するマーク

.gitによって管理されるリポジトリの中でコミット間を移動すると、その時の状態までフォルダの中身が戻れる

  • コミット間を移動するに伴い、ローカルフォルダ内の階層構造やテキストが変化する

6. コミットメッセージの書き方

  • 1行目にタイトル、2行目は空行、3行目はコミットの詳細、のように箇条書きする
  • 1行目の内容がコミットヘッダ内容として表示される

★コミットハッシュ

  • 一つ一つのコミットにはコミットハッシュと呼ばれるランダムに割り当てられるアルファベットの文字列があり、プロジェクト内で実行検証を行う際にはその文字列をSlackなどで共有することで、同じ動作環境での検証を正確に行うことができる。

7. コミット内容の変更を破棄

  • 変更内容を破棄したい場合は作業ツリー上のファイルを右クリックして破棄をクリック

★破棄と削除の違い

  • 破棄:ファイルに行った変更内容を破棄するのであって、ファイル自体を削除するわけではない
    ⇔直前のコミット内容と状況と同じにする
  • 削除:ファイル自体を削除する
    ⇔本当に削除されるわけではなく灰色マークに変化するだけの変更
    ⇔この削除という行為を破棄すればファイル削除がキャンセルされファイルが復元される

★コミット内容を取り消したい

  • ローカルでの更新内容が不適切な状態でコミットしてしまいコミット自体を取り消す場合は、戻りたいコミットを選択して右クリックし「現在のブランチをこのコミットまでリセット」を選択
  • この操作は不可逆性なので一度リセットすると元に戻せない

8.リポジトリ内でファイルを除外する設定

外部からインポートするファイルが大きすぎるとgitのバージョン管理が重くなりすぎるので、それらのファイルを検知せず除外したい場合に作成するファイルを.gitignoreファイルと呼ぶ

以下の手順で.gitignoreファイルを作成する

  • ローカルでsettingファイルを作成する
  • 作業ツリーのファイルにて、先ほど作成したsettingファイルを右クリックして無視を選択
  • 「名前が完全に一致」をクリック、「無視するにはこのリポジトリのみ」をクリック、OKをクリックすると.gitignoreファイルが作成される
  • .gitignoreを選択し、メニューバー右上の設定/詳細/リポジトリ固有の無視リストを確認
  • .gitignore内で記載した内容が確認できる
  • .gitignore自体もコミット対象になる

9.ブランチの作成

開発者がそれぞれのブランチに明確な機能実装の目標を持ち作業を行うので、
互いに干渉することなく作業が行える環境を作ろうというのがブランチを切る目的

  • masterブランチからdemoAブランチをチェックアウトしtext.txtファイルを作成
  • masterブランチからdemoBブランチをチェックアウトしtext.txtファイルを作成
  • ここで初めて枝分かれがSourceTree上で確認できる

★ブランチのチェックアウトとは、ブランチを新規作成してそのブランチに切り替えることを意味する
★常にリポジトリ内をクリーンな状態に保つことで今から行う作業が明確になるため、後述するマージという作業が終了した段階で、ローカルとリモートに存在するマージ済みブランチを削除する

10.マージ

分岐したブランチの変更内容を組み合わせる

  • masterからdemoA, demoBがある状況で以下の内容を確認する
  1. 自分はどこにいるか
  2. 誰を取り込むか(マージするか)

ファーストフォワード(前に進ませるパターン)

  • masterにいる状態でメニュータブのマージをクリック
  • マージしたいブランチ(demoB)を選択してOKをクリック
  • Merge branch 'demoB'というコミットが自動で行われる
  • demoBがmasterと同じ場所に移動する

合体(枝分かれを吸収するパターン)

  • masterにいる状態でメニュータブのマージをクリック
  • マージしたいブランチ(demoA)を選択してOKをクリック
  • Merge branch 'demoA'というコミットが自動で行われる
  • demoAがmasterと同じ場所に移動する

11.コンフリクトの解決

マージを行った際にコンフリクトが起きた場合の解決策を説明する
意図的に衝突を起こす想定で下記の手順でファイル操作を行う

  • masterから新たにtestA, testBブランチを追加する
  • testAのtext.txtファイルの1行目末尾にインデント1つと修正Aと追記してコミット
  • testBのtext.txtファイルの1行目末尾にインデント1つと修正Bと追記してコミット
  • testBからtestAをマージする
  • 警告文が表示される → !「作業コピーでマージの衝突、続行するには解決が必要」!
  • 続行するをクリックするとまずマージ自体は完了する
  • 「コミットされていない変更」がコミット欄の最上部に表示される
  • 作業ツリーのファイルにて、ビックリマークのtext.txtをクリックし内部にHEADタグが追記されていることを確認

マージの競合(コンフリクト)とは

ブランチ間をマージしようとする際に、同じファイルの同じ箇所が変更されているために。
機械的にはどちらが適切かを判断できないため作業者の判断を待っている状態

  • VSCodeでは元々Git機能が備わっているのでコンフリクトした内容が色で判別できるようになっている
  • 「現在の変更を取り込む」は取り込む側の変更を反映し、「入力側を取り込む」はマージする対象の変更を取り込む
  • 手動で変更を反映させる際は、マージ前の入力内容に戻して、変更したい内容を追記したことを確認して保存
  • もしくはファイルを右クリックして競合を解決/自分or相手の内容で解決でも可能
  • コミットする際は自動的にコミットメッセージ内にマージの競合が起こったことが追記されている
Merge branch 'testA' into testB

# Conflicts:
#	test.txt

HEADタグ
HEAD領域の内容を修正せずに(マージの競合を解決せずに)コミットを完了してしまうとプログラムを修復するのが困難でありプロジェクトが詰んでしまう。マージの競合に対応する際はマージの変更前後の状態に関して詳しいチーム内のメンバーと相談しながら対応することが望ましい

マージリクエストの注意点

業務でマージリクエストを行った際に、PMから指摘された点があったので備忘録として残す。

プロジェクト構成

  • プロジェクトの例として、高橋さんが本を管理するアプリを作成する場合を考える
  • プロジェクトフォルダの構成は以下の通りで、ASP.NET MVCを用いる想定
  • MVCモデルでは、Controller内での制御文がModelのデータを抽出してViewに返却する
└── Controller
    ├── Takahashi
    ├── Book
└── Models
    ├── Takahashi
    ├── Book
└── Views
    └── Takahashi
        ├── Index
        ├── Edit
        ├── Create
    └── Book
        ├── Index
        ├── Edit
        ├── Create

マージリクエスト

  • developブランチにてリモートブランチから最新情報を取り込む(fetch → merge)
  • プロジェクト内のブランチ命名規則に従いブランチ名を決めて新規ブランチをチェックアウト
  • 適当に、Views/Book/Index、Controller/Bookの内容の2点を更新

★プロジェクトリーダーがコードレビューを行う際に気にしていること

  • のブランチに必要な機能実装のみを適切に行えているか
  • インデントやワードの変更に意図はあるか
    • リクエストに明確な意図がある場合はマージリクエスト時のdescription欄に記載する)
    • マージの衝突を未然に防ぐために、小さなインデントや改行、キーワード変更であっても明確な意図があるか否かをチェックする

★まとめると、プロジェクト内ではマニュアルに従い各ブランチに必要な機能のみを変更するという意識を持ち以下の3点に注意しておく
1.コミット時に表示されるdiffを確認する
2.スタッシュした状態でビルドが通ることを確認してプッシュ
3.変更内容を再度確認してマージリクエストを出す

1. コミット時に表示されるdiffを確認する

  • 前回のコードとに差分に明確な意図があるかを確認
  • コミット内容の差分に明確な意味があるかを確認し[add]/[delete]/[fix]で使い分けてコミット

例;[add]登録ボタン / [fix]ホーム画面の背景色)

2. スタッシュした状態でビルドが通ることを確認する

「コミットされていない変更があります」という内容がコミット最上部に表示されている場合
「マージリクエストした内容 + コミットされていない変更 = 自分がローカルでビルド成功した内容」であり、マージリクエストした内容単体でビルド成功するかを確認した上でマージリクエストを行う必要があるが、コミットされていない変更はどのように削除するのか?

★コミットされていない変更のファイルは以下の2パターン

  • オレンジの鉛筆マーク:Gitで管理しているファイルをローカルで変更した項目
  • 紫のはてなマーク:Gitで管理していないファイルをローカルで新規作成した項目

★それぞれの対応策

  • ファイルがオレンジの鉛筆マークのみ
    ・メニューバー左上のスタッシュボタンをクリックしファイルを一時的にスタッシュする
  • ファイルに1つでも紫のはてなマークが混在している
    ・メニューバー右上のターミナルボタンをクリックし、Sourcetree上で選択されているブランチのイニシャルパスをターミナルコマンドに反映させて以下のコマンドを叩く
git stash -u

3. 変更内容を再度確認

マージリクエスト時のCommit, Changesタブで再度コミットと変更内容を確認

変更内容の取り消し手順

コミットの取り消し

  • developから3つのテキストファイルをコミット
  • 3つ目の最新コミットの状態から最初のdevelopの状態に戻りたい
  • 戻りたいdevelopのコミットを選択
  • developのコミットメッセージタブを右クリック
  • 「現在のブランチをこのコミットまでリセット」をクリック
  • OKをクリックしてコミットをリセットできる

プッシュの取り消し

  • developから1つのテキストファイルをコミットしてプッシュ
  • リモートで反映されたことを確認
  • プッシュしたコミットメッセージタブを右クリックして、「このコミットを打消し...」をクリック
  • Revert "コミットメッセージ"として新たな打消しコミットが自動生成される
  • Revertコミットをリモートにプッシュ
  • リモートで反映されたことを確認

マージの取り消し方法1

  • developブランチから新たにfeature/01_Btnブランチをチェックアウト
  • feature/01_Btnから1つのテキストファイルをコミット・プッシュしてdevelopにマージ
  • リモートで反映されたことを確認する
  • feature/01_Btnでマージしたコミットメッセージタブを右クリックして、「このコミットを打消し」をクリック
  • Revert "コミットメッセージ"として新たな打消しコミットが自動生成される
  • Revertコミットをリモートにプッシュしてdevelopにマージ
  • リモートで反映されたことを確認

マージの取り消し方法2

  • MR画面のMergedタブにてRebertボタンをクリックしてRebert MRを行うブランチを選択
  • Rebert Mergeを承認して完了

おわりに

プロジェクト内で開発業務にあたりGit操作を行う際は、プロジェクト内で明確なルールに従い
ソースをGit管理しよう。自分だけのルールに従うと当然だがマージリクエストのレビューで激が飛ぶ、こんな風に。「本ブランチではモデルの定義のみを行う想定です。コントローラ内の追記コードは削除してください」「本案件では”ユーザ”ではなく”ユーザー”として表記すると決定しましたのでビューの修正をお願いします」「56行目のインデントを明確な意図がなく不手際で追加したのであれば削除してください」

些細な変更であれど、プロジェクトのバグを生み出す要因となる確率はゼロではないので、自分で行った変更内容に明確な意図を持ち、レビュアーを説得できる説明を用意しておくことが重要になる。

Discussion

ログインするとコメントできます