えいたろブログ

ソフトウェアエンジニアの日常学習ブログです

Gitの基本的なワークフロー

1. ローカルリポジトリの設定と作成

1-1. ローカルにユーザー情報をセットする

$ git config --global user.name "<username>"
$ git config --global user.email "<email>"

1-2. 設定内容を一覧で確認する

$ git config --global --list

1-3. リモートリポジトリからローカルリポジトリへコピー(clone)する

$ git clone <remote-repo-url>
  • <remote-repo-url>はGithubから取得する

1-4. ローカルリポジトリがリモートリポジトリに紐づいていることを確認する

$ git remote -v

2. ブランチの作成

2-1. ブランチの一覧を表示する

$ git branch

2-2. 作業用ブランチを作成する

$ git branch <branch-name>
  • 作業する内容がわかりやすい名前にする
  • 長すぎないようにする
  • 単語をつなげる場合は"-(ハイフン)"でつなげる

2-3. 作業するブランチを切り替える

$ git checkout <branch-name>
  • "-b" オプションをつけると、ブランチを作成して切り替えることが可能
$ git checkout -b <branch-name>

※ pagerを無効にする方法

$ git config --global --replace-all core.pager "less -F -X"
  • $ git branch や$ git diff 時にpagerで表示されるのを防ぐ

3. 作業内容をStaging areaに上げる

3-1. 作業状態を確認する

$ git status

3-2. 作業内容をStaging areaに追加する

特定のファイルの作業内容をStaging areaに追加する

$ add <filename>

カレントディレクトリは以下のすべてのファイル、フォルダをStaging areaに追加する

$ add .

4. Staging areaの内容をリポジトリにコミットする

4-1. 作業状態を確認する

$ git status

4-2. Staging areaの内容をコミットする

$ git commit -m "<commit message>"
  • コミット時は必ずコミットメッセージをつける
  • 基本的には一文で、どういう変更をしたかがわかるようにする
  • 書き方はチームでルールが決められていることも少なくない
  • コミット後にはコミットポイントが作られる

4-3. コミット履歴の一覧を表示する

$ git log
  • commit ID, Author, Date, コミットメッセージを一覧で表示する
  • 新しいコミットが上に表示される
  • 各ブランチの最新のコミットがどのコミットなのかがわかる

5. リモートリポジトリにローカルリポジトリの内容を反映する(push)

5-1. push前に一度リモートリポジトリの内容をローカルリポジトリに反映する(pull)

$ git pull <remote-ref> <branch-name>
  • 指定したリポジトリから指定したブランチの情報を今自分が作業しているブランチ(アクティブブランチ)に"反映"する
  • 実際にはfetchという処理とmergeという処理をしている

5-2. ローカルリポジトリの更新をリモートリポジトリに反映する

$ git push <remote-ref> <branch-name>
  • 指定したローカルブランチを,指定したリポジトリの同名のブランチに情報を送信する

6. pushしたブランチをmainブランチにマージする(pull requestを作成してマージする)

※ 全てGithub上で作業する

6-1. pull requestを作成する

6-2. pull requestを確認する

6-3. pull requestをマージする

6-4. mainブランチにて更新されていることを確認する

  • リモートリポジトリはチームで共有するリポジトリなので、自由にマージすることはできない
  • pull requestはmerge requestだと思えばOK
  • 原則他のメンバーが、自分が出したpull requestを確認してマージする
  • pull requestは"PR"や"プルリク"と呼ぶことが多い

7. ローカルリポジトリにリモートリポジトリの内容を反映する(pull)

7-1. mainブランチに移動する(checkoutする)

$ git checkout main

7-2. リモートリポジトリのmainブランチをpullする

$ git pull origin main

8. 不要になったブランチを削除する

8-1. ローカルリポジトリにて特定のブランチを削除する

$ git branch -d <branch-name>
  • mainにマージしていないブランチは削除できない
  • 強制削除する場合は-dではなく-Dオプションを用いる

8-2. リモートリポジトリにて特定のブランチを削除する

SAMLとは

SAMLとは

ユーザー

利用者のこと

IdP(Identity Provider)

ユーザーの認証情報を保存・管理するサービスのこと。 シングルサインオン(SSO)をする場合、ユーザーはIdPへログイン認証を行う必要がある。

SP(Service Provider)

ログイン先のサービスのこと。 SPはIdPとユーザーの認証情報をやり取りし、認証処理をする。

SAML認証の種類

SP Initiated(SP起点)とIdP Initiated(IdP起点)の2つがある。

SP Initiated(SP起点)

SP起点とは、最初にユーザーがSPにアクセスを行うパターン。 ユーザーがSPにアクセスすると、SPからIdPへリダイレクトが行われてIdP側で認証が行われる。 IdP側で未ログイン状態であった場合は、IdP側のログイン画面が表示されIdPへのログインを行う。 ログインが成功すると、今度はIdPからSPへリダイレクトが行われて、IdPから受け取った認証情報を元にSP側で認証を行い、認証に成功するとユーザーはSPへログイン成功となる。

IdP Initiated(IdP起点)

IdP起点とは、最初にユーザーがIdPの画面から利用したいSPを選択して利用するパターンになる。 ユーザーがIdPへログインを行い、IdPのSP一覧画面から利用したいSPを選択すると、対象のSPに認証情報が送信されてログイン認証が行われる。

事前に設定が必要な情報

SP側

  • ログインURL →SPからIdPへリダイレクトを行う際のリダイレクト先URL
  • ログアウトURL →SPからログアウトした後のリダイレクト先URL。
  • エンティティID →IdPをグローバルに一意に認識するためのID。(IdPから取得)
  • IdPの証明書 →IdPが認証応答の署名に用いる秘密鍵に対応する公開鍵。(IdPから取得)

IdP側

  • Assertion Consumer Service URL →IdPからSPへリダイレクトを行う際のリダイレクト先URL。
  • エンティティID →SPをグローバルに一意に認識するためのID。(IdPから取得)

SP Initiated 初回認証フロー

IdP側にセッションがない場合

sequenceDiagram
    participant user as ユーザー
    participant sp as SP
    participant idp as IdP
    Note over sp,idp: 事前に必要な情報を設定<br>(信頼関係構築)
    user->>sp: SPへアクセス GET
    sp->>user: SAML認証要求を発行(IdPに問い合わせ要求) 302リダイレクト
    Note left of sp: AuthnRequest
    user->>idp: SAML認証要求を送信(ログイン認証要求) GET
    Note right of user: AuthnRequest
    idp->>user: 認証画面を表示(ログイン画面などを表示) 200OK
    user->>idp: 認証情報を送信 POST
    idp->>idp: 認証処理
    idp->>user: SAML認証応答を発行(IdPの秘密鍵で署名) 303リダイレクト
    Note left of idp: Response
    user->>sp: SAML認証応答を送信 POST
    Note right of user: Response
    sp->>sp: SAML認証応答をIdPの公開鍵で検証
    sp->>user: SPにログイン成功(SP側に紐づくアカウント) 200OK

SP Initiated 2回目認証フロー

IdP側にセッションがある場合

sequenceDiagram
    participant user as ユーザー
    participant sp as SP
    participant idp as IdP
    Note over sp,idp: 事前に必要な情報を設定<br>(信頼関係構築)
    user->>sp: SPへアクセス GET
    sp->>user: SAML認証要求を発行(IdPに問い合わせ要求) 302リダイレクト
    Note left of sp: AuthnRequest
    user->>idp: SAML認証要求を送信(ログイン認証要求) GET
    Note right of user: AuthnRequest
    idp->>user: SAML認証応答を発行(IdPの秘密鍵で署名) 303リダイレクト
    Note left of idp: Response
    user->>sp: SAML認証応答を送信 POST
    Note right of user: Response
    sp->>sp: SAML認証応答をIdPの公開鍵で検証
    sp->>user: SPにログイン成功(SP側に紐づくアカウント) 200OK

AuthnRequestの中身

<?xml version="1.0"?>
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    ID="identifier_1"
                    Version="2.0"
                    IssueInstant="2023-10-25T07:39:28.807Z"
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                    Destination="https://idp.example.com/"
                    AssertionConsumerServiceURL="https://sp.example.com/">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://sp.example.com/</saml:Issuer>
  <samlp:NameIDPolicy xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                      Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
                      AllowCreate="true" />
</samlp:AuthnRequest>

Responseの中身

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<samlp:Response xmlns="urn:oasis:names:tc:SAML:2.0:assertion"
                xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"
                Destination="https://sp.example.com/"
                ID="identifier_2"
                InResponseTo="identifier_1"
                IssueInstant="2023-10-25T07:39:28Z"
                Version="2.0">
  <Issuer>https://idp.example.com/</Issuer>
  <samlp:Status>
    <samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success" />
  </samlp:Status>
  <Assertion ID="identifier_3"
             IssueInstant="2023-10-25T07:39:28Z"
             Version="2.0">
    <Issuer>https://idp.example.com/</Issuer>
    <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
      ...
    </Signature>
    <Subject>
      <NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified"
              SPNameQualifer="https://sp.example.com/">UIDxxxxxxxxx</NameID>
      <SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
        <SubjectConfirmationData InResponseTo="identifier_1"
                                 NotOnOrAfter="2023-10-25T07:49:28Z"
                                 Recipient="https://sp.example.com/" />
      </SubjectConfirmation>
    </Subject>
    <Conditions NotBefore="2023-10-25T07:34:28Z"
                NotOnOrAfter="2023-10-25T07:49:28Z">
      <AudienceRestriction>
        <Audience>https://sp.example.com/</Audience>
      </AudienceRestriction>
    </Conditions>
    <AttributeStatement>
      <Attribute Name="UID">
        <AttributeValue>UIDxxxxxxxxx</AttributeValue>
      </Attribute>
    </AttributeStatement>
    <AuthnStatement AuthnInstant="2023-10-25T07:39:28Z"
                    SessionIndex="identifier_3">
      <AuthnContext>
        <AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</AuthnContextClassRef>
      </AuthnContext>
    </AuthnStatement>
  </Assertion>
</samlp:Response>

参考