20210509のGitに関する記事は4件です。

セットアップ - Git

はじめに セットアップ シリーズ、Git 編。 主に以下について。 Git クライアント Git サーバー Git ワークフロー 方針: Git クライアントの GUI 操作は、この記事では紹介しない。 GUI 操作は、VS Code で事足りると思う。VS Code の拡張機能については、別記事を参照。 ? Git クライアント ? Windows 用 Git 公式が提供する Windows 用の Git クライアント「Git for Windows」を使う。 インストール: https://gitforwindows.org/ からインストーラーを入手してインストールする。 インストーラーの選択肢の詳細は以下のとおり。 Information(情報): Next ボタン Select Destination Location(インストール先の選択): C:\Program Files\Git(デフォルト) Next ボタン Select Components(コンポーネントの選択): 以下にチェック ⬜ Additional Icons(Git Bash のショートカットを追加) ⬜ On the Desktop ✅ Windows Explorer Integration(コンテキストメニューに追加) ✅ Git Bash Here ✅ ➡ ⬜ Git GUI Here Git GUI は使わないので ✅ Git LFS (Large File Support)(大容量ファイルをサポート) ✅ Associate .git* configuration files with the default text editor(.git* 構成ファイルをデフォルトのテキストエディターに関連付ける) ✅ Associate .sh files to be run with Bash(.sh ファイルを Git Bash に関連付ける) ⬜ Use a TrueType font in all console windows(すべてのコンソールウィンドウで TrueType フォントを使う) チェックすると、多バイト文字で問題が出るらしい ⬜ ➡ ✅ Check daily for Git for Windows updates(更新プログラムを毎日確認する) 脆弱性対策のため最新版を使う Next ボタン Select Start Menu Folder(スタートメニューフォルダーの選択): デフォルトのまま Next ボタン Choosing the default editor used by Git(Git で使うデフォルトエディターの選択): Git のデフォルトエディターを選択する ⚪ Use Vim (the ubiquitous text editor) as Git's default editor(Vim を使う) デフォルト値。非推奨と書かれている ? Use Visual Studio Code As Git’s default editor(Visual Studio Code を使う) 今回はこれを選択する など Next ボタン The Vim editor, while powerful, can be hard to use. It's user interface is unintuitive and its key binding sare awkward. Vim エディターは強力ですが、使いにくい場合があります。 そのユーザーインターフェイスは直感的ではなく、キーバインディングは厄介です。 Note: Vim is the default editor of Git for Windows only for historical reasons, and it is highly recommended to switch to a modern GUI editor instead. 注:Vim は歴史的な理由のみで Git for Windows のデフォルトエディターであるので、 代わりに最新の GUI エディターに切り替えることを強くお勧めします。 Note: This will leave the 'core.editor' option unset, which will make Git fall back to the 'EDITOR' environment variable. The default editor is Vim - but you may it to some other editor of your choice. 注:これにより、「core.editor」オプションが未設定のままになり、Gitが「EDITOR」環境変数にフォールバックします。 デフォルトのエディターは Vim ですが、他のエディターを選択することもできます。 Adjusting the name of the initial branch in new repositories(新しいリポジトリの最初のブランチ名を設定): 最初のブランチ名を選択する ? Let Git decide(Git に決めさせる) デフォルト値。基本的にこれ ⚪ Override the default branch name for new repositories(新しいリポジトリのデフォルト ブランチ名を上書きする) main など、master 以外のブランチ名を使う場合 Next ボタン Adjusting your PATH environment(PATH の設定): Git Bash 以外の端末のために、PATH を通すか?(Git Bash 以外で git コマンドを使う場合以外は無視して OK) ⚪ Use Git from Git Bash only PATH 環境変数に何も設定しない 他の Unix 互換環境(MinGW, cygwin 等)を使っていて、影響を考慮する場合に使う ? Git from the command line and also from 3rd-party software 推奨。デフォルト値。基本的にこれ コマンドプロンプトや PowerShell などからは Git コマンドのみが使えるが、Unix コマンドは使えない ⚪ Use Git and optional Unix tools from the Command Prompt コマンドプロンプトや PowerShell などから Git コマンドだけでなく、Unix コマンドが使えるようになる ただし、find や sort などのコマンドが上書きされてしまうため、注意が必要 Next ボタン Choosing HTTPS transport backend(HTTPS トランスポートの設定): ルート証明書の参照先を選択する ? Use the OpenSSL library(OpenSSL のものを参照) デフォルト値。基本的にこれ ⚪ Use the native Windows Secure Channel library(Windows の Secure Channel を参照) 独自証明書を使っている場合 Next ボタン Configuring the line ending conbersions(行末の変換設定): 改行コードを自動変換するか選択する ⚪ Checkout Windows-style, commit Unix-style line endings チェックアウト時に CRLF へ変換し、コミット時に LF へ変換。デフォルト値 ⚪ Checkout as-is, commit Unix-style line endings チェックアウト時に何もないが、コミット時に LF へ変換 ? Checkout as-is, commit as-is 何もしない これを選択して、Git には任せず .editorconfig などで制御するのがオススメ Next ボタン Configuring the terminal emulator to use with Git Bash(ターミナルの設定): ターミナルエミュレーターを選択する ? Use MinTTY デフォルト値。基本的にこれ ⚪ Use Windows’s default console windows Windows のコンソールを使う場合 Next ボタン Choose the default behavior of git pull(git pull のデフォルト動作を選択): git pull のデフォルト動作を選択する ? Default (fast-forward or merge) デフォルト値。基本的にこれ。Git の標準的な動作に従う ⚪ Rebase ⚪ Only ever fast-forward Next ボタン Choose a credential helper(資格情報ヘルパーを選択): 資格情報ヘルパーを選択 ? Git Credential Manager Core デフォルト値。基本的にこれ ⚪ Git Credential Manager 非推奨。旧バージョンのものが必要な場合 ⚪ None 資格情報ヘルパーを使わない Next ボタン Configuring extra options(追加オプションの設定): 以下にチェック ✅ Enable file system caching(キャッシュを使う) ⬜ Enable symbolic links(シンボリックリンクを使う) Windows のシンボリックリンクは POSIX との完全な互換性がないので、無理に使うのはやめる派 有効化する場合は、以下を参照 cf. Git for Windows でシンボリックリンクを扱えるようにする - Qiita Next ボタン Configuring experimental options(実験オプションの設定): デフォルトのまま Install ボタン 確認: スタート メニュー > Git > Git Bash で起動し、以下を入力して確認。 # git の確認 $ which git && git --version /mingw64/bin/git git version 2.31.1.windows.1 # git flow の確認(一緒にインストールされている) $ git flow version 1.12.3 (AVH Edition) 設定: ➊ スタート メニュー > Git > Git Bash を順にクリック ➋ 起動した Git Bash のタイトル バーを右クリック > Options... をクリック Looks > Transparency で High を選択(端末の背景を半透明に) Text > Font で Lucida Console ➡ Consolas や HackGenNerd Console などに変更(日本語を見やすく) Save ボタンをクリック ? macOS 用 cf. Git - Downloading Package Homebrew で、最新バージョンの Git をインストールする。 Xcode Command Line Tools の Git はバージョンが古いので、脆弱性対策のためこちらは使わない。 # インストール $ brew install git # 確認 $ which git && git --version /usr/local/bin/git git version 2.31.1 ? Ubuntu 用 APT を使ってインストールする。 ちなみに公式サイトで案内される git-all は GUI などのサブパッケージを含むらしい。 cf. version control - Difference between installing git vs installing git-all - Ask Ubuntu 今回は不要なので git パッケージをインストールする。 # インストール $ sudo apt install git # 確認 $ which git && git --version /usr/bin/git /bin/git git version 2.25.1 ? Git クライアントの初期設定 公式ドキュメントの記載のとおり、インストール後に最初にすべきことは「ユーザー名」と「メールアドレス」の設定だ。 コミット情報で「個人のメールアドレス」を公開したくない場合は、GitHub なら「no-reply メールアドレス」(<ID+username>@users.noreply.github.com)を提供してくれるので、これを使う。 「no-reply メールアドレス」を取得するには、公式ドキュメントの「GitHub のコミットメールアドレスを設定する」の手順で、Keep my email address private(メールアドレスをプライベートに保つ)にチェックを入れる。 利用するメールアドレスが決まったら、Git Bash で以下を実行する。 # ユーザー名とメールアドレスを設定する(グローバル設定: 全リポジトリーの共通設定) $ git config --global user.name "サンプル 太郎" $ git config --global user.email taro@example.com # 確認 $ git config --global user.name && git config --global user.email > サンプル 太郎 > taro@example.com なお、特定のリポジトリーで「グローバル設定以外の設定」を適用する手順は以下のとおり。 # 作業中のリポジトリーへ移動(必要なら) $ cd <作業中のリポジトリーのフォルダーパス> # ユーザー名とメールアドレスを設定する(ローカル設定: グローバル設定より優先される、特定リポジトリーのための設定) $ git config user.name "サンプル 次郎" $ git config user.email jiro@example.com # 確認 $ git config user.name && git config user.email > サンプル 次郎 > jiro@example.com ? Git サーバー Git サーバーのホスティング先は、かつては自社サーバー等の「オンプレミス環境」も一般的だった。 (Git が国内で浸透し始めた 2010 年頃) 現在は、コスト的メリットから「クラウドサービス」が第一候補となるケースが多い。 代表的な Git サーバーのホスティング先は以下のとおり。 クラウドサービス型 GitHub 最もポピュラーな Gti サーバーのホスティングサービス。 2020 年 4 月から、有料だった機能の多くが無料プランでも利用できるように。 CI/CD (GitHub Actions) の利用や、プライベートリポジトリの作成を含む。 SSO の利用等は、引き続き有料プランへの加入が必要。 GitLab OSS であり、オンプレミス サーバー上にも構築可能。 Bitbucket Atlassian 社製のため、同社の製品との相性が良いらしい。 AWS CodeCommit アマゾン ウェブ サービス (AWS) が提供するため、ユーザー管理等を AWS で統一する場合は選択肢に挙がる。 Azure Repos Microsoft Azure (Azure) が提供するため、ユーザー管理等を Azure で統一する場合は選択肢に挙がる。 Cloud Source Repositories Google Cloud Platform (GCP) が提供するため、ユーザー管理等を GCP で統一する場合は選択肢に挙がる。 オンプレミス型 GitLab 2011 年登場の、セルフホスト型では最もメジャーな OSS Git サーバー。 高機能な反面、サーバーの要求スペックは高め。 GitBucket 2013 年登場の Git サーバー。 Gogs 2014 年登場の、現行の GitHub に近い見た目の Git サーバー。 軽量。 Gitea 2016 年に Gogs からフォークされた Git サーバー。 ? Git ワークフロー 代表的な Git ワークフローは以下の 2 種類がある。 GitHub フロー: シンプルで、リリースサイクルの早いワークフロー。 基本的にこれが推奨されるが、CI/CD のないプロジェクトでは採用すべきではない。 cf. GitHub のフロー - GitHub Docs git-flow: 古くからあるワークフロー。 複雑だが着実にリリースするために使われる。 cf. A successful Git branching model » nvie.com cf. git-flow cheatsheet 詳細は以下の記事が詳しい。 cf. 【図解】git-flow、GitHub Flow を開発現場で使い始めるためにこれだけは覚えておこう:こっそり始める Git/GitHub 超入門(終) - @IT ? GitHub フロー cf. Understanding the GitHub flow · GitHub Guides cf. GitHub Flow (日本語訳) シンプルなので特に説明することもないが、一応解説する。 ? ルール master ブランチは常時デプロイ可能な状態にする。 新しい何かに取り組む際は、master ブランチから feature ブランチを作成する。 (e.g. 会議開催通知機能を追加するなら feature/add-meeting-notice) あなたは feature ブランチで作業し、コミットする。定期的に push して、作業進捗を共有することも忘れずに。 フィードバックや助言が欲しい時、ブランチをマージしてもよいと思ったときは、プルリクエスト を作成する。 他の誰かがレビューをして OK を出してくれたら、プルリクエストで feature ブランチを master ブランチへマージする。 master ブランチが更新されたら、直ちにデプロイをする。 ? git-flow cf. nvie/gitflow git-flow でプルリクエストを使う場合のワークフロー例は以下のとおり。 ? インストール git-flow 用のツールをインストールする。 Windows: Git for Windows に含まれる。 macOS: # Homebrew でインストール $ brew install git-flow-avh Ubuntu: # APT でインストール $ sudo apt install git-flow ? ルール 基本ルール 基本となるブランチ: master ブランチは、リリースされた現行バージョンと同じ。 develop ブランチは、開発中の次期バージョン。(ワークフローの中心となるブランチ) feature ブランチは、各自の作業途中の状態。 開発フロー: 各自は develop ブランチから feature ブランチはを作成し、そこで作業する。 定期的に feature ブランチを push して作業進捗を共有しつつ、プルリクエストで TODO を示すこと。 feature ブランチでの作業が完了したら、プルリクエストで develop ブランチにマージする。 リリースフロー: develop から master ブランチにマージし、master ブランチをリリースする。 応用ルール 緊急対応の場合は feature ブランチの代わりに hotfix ブランチを作成する。 hotfix ブランチでの作業が完成したら、develop と master ブランチにマージし、master ブランチをリリースする。 ? 具体的な流れ (最初のみ)デフォルトブランチを設定する Git サーバー側の「デフォルトブランチ」を develop ブランチに変更する。 (最初のみ)初期化する 各ローカルリポジトリーごとに、git-flow を採用するための初期化が必要になる。 # 作業中のリポジトリーへ移動(必要なら) $ cd <作業中のリポジトリーのフォルダーパス> # git-flow で初期化 ## -d ... 推奨のブランチ名を採用する $ git flow init -d ➊ 開発する develop ブランチを元に、作業毎にfeature ブランチを作成する。 ブランチ名は、後から分かりやすいように説明的な名前をつけること。 # プル(必要なら) $ git pull origin develop # feature ブランチを作成 # e.g. git flow feature start add-meeting-notice $ git flow feature start <説明的なブランチ名> 修正のまとまり毎にコミットする。 feature ブランチは、完成前でも定期的に push して、作業進捗を共有する。 ➋ 開発進捗を報告する feature ブランチを push したら、develop ブランチにマージする形でプルリクエストを作成する。 作業が完了していない場合、プルリクエストのタイトルに [WIP] と記載し、本文に TODO を残す。 タイトル: [WIP] ○○ 機能の新規追加 本文: ## サマリー - ○○ を ○○ する機能を追加する。 ## TODO - [x] ○○.php に form を作成する - [x] ○○ テーブルを作成する - [ ] form をカスタマイズする - [ ] form の挙動を確認する - [ ] CSS の適応 - [ ] テスト ➌ レビューを依頼する feature ブランチでの作業が完了したら、push する。 プルリクエストのタイトルから [WIP] の記載を削除し、本文を更新した上で担当者をレビュアーに変更し、レビューを依頼する。 タイトル: ○○ 機能の新規追加 本文: ## サマリー - ○○ を ○○ する機能を追加する。 - (その他、共有すべき内容を記載) ## テスト結果 - (試験結果のエビデンスを記載) コミット内容などに問題がなければ、レビュアーはプルリクエストを使って develop ブランチにマージし、feature ブランチを削除する。 問題があればレビュー依頼者に差し戻す。 ➍ リリースする 必要な feature ブランチがマージし終われば、develop ブランチが問題ないことを確認する。 これも問題なければ、develop ブランチから master ブランチにマージし、master ブランチをリリースする。 # develop から release ブランチを作成し、master と develop ブランチにマージ $ git flow release start v1.0.0 $ git flow release finish v1.0.0 # プッシュ $ git push origin master develop && git push origin --tags (必要な場合のみ)緊急対応する 緊急対応には、feature ブランチの代わりに hotfix ブランチを使う。 hotfix ブランチでの修正が終われば、develop ブランチと master ブランチにマージし、master ブランチをリリースする。 # master から hotfix ブランチを作成 $ git flow hotfix start v1.0.1 # 修正をコミット # hotfix ブランチを master と develop ブランチにマージ $ git flow hotfix finish v1.0.1 # プッシュ $ git push origin master develop && git push origin --tags 参考文献 Git for Windows のインストールについて 私家版 Git For Windows のインストール手順 | OPCDiary 【0 から始める Git】Git をインストールしてみた | たくメモ 初期設定について Git - 最初の Git の構成 Git でのユーザ名を設定する - GitHub Docs コミットメールアドレスを設定する - GitHub Docs
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitを仕組みから再学習

Git gitの実体 gitはコミットした時点のファイルのスナップショットをそのファイルから計算したハッシュ値で紐づけたKVSのようなもので過去のversionを管理している。 $git initした時に作成される.gitがgitの実体であり、その中の.git/objectにハッシュ値で紐づけられた大量のスナップショット(blobオブジェクト)が保管されている。 オブジェクト .git/objectの中にはファイルのスナップショット(blobオブジェクト)だけが保存されているわけではない。blob、tree、commitの3種類のオブジェクトが存在する。 なお、オブジェクトを確認するには$git cat-fileコマンドを利用する。 .git/object以下はさらにハッシュ値の先頭2桁でフォルダ分けされており、先頭2桁のハッシュはオブジェクトのファイル名からは除かれているのでその値を追加してcat-fileする必要がある。見方は以下。 # ファイルのタイプを見たい。 $ git cat-file -t [中身を見たいハッシュ] # ファイルのサイズを見たい。 $ git cat-file -s [中身を見たいハッシュ] # ファイルの中身を見たい。 $ git cat-file -p [中身を見たいハッシュ] blobオブジェクト スナップショットにあたる。 ファイルを$git addすると、そのファイルがワークツリーからコピー・zlib圧縮され、blobオブジェクトとなる。また、そのファイルの中身からハッシュ値を計算し、blobオブジェクトはそのハッシュ値で区別されるようになる。 addしたファイル1つ1つに対応するようblobオブジェクトが作成されるため、.git/objectの中の任意のblobオブジェクトを覗くとどこかの時点での特定のファイルの中身を確認することができる。 treeオブジェクト ディレクトリのスナップショットに当たる。コミット時に生成。 ディレクトリはその直下にどのファイルが存在するかを管理するようにtreeオブジェクトはそのファイルの直下にどのblobやtreeオブジェクトが存在するかの情報(ハッシュ)を持っている。 $ git cat-file -p 90b4c465b199a20546f6fa0fee7cb2d213de1b4f 040000 tree 35f02fd1aa4e582cab3dbbf4591dfd0d7007f97f hoge 100644 blob c945dbe34b2b9b68b94a06ca1c0b31cb7d9f1bdd aaa.txt 100644 blob 83c831f0b085c70509b1fbb0a0131a9a32e691ac bbb.md 左から順に、アクセス権限、オブジェクトの種類、ハッシュ、ディレクトリ名orファイル名となっている。 commitオブジェクト コミットする毎に1つ作られるオブジェクト。 ルートのtreeオブジェクト(.gitを含む最上位のディレクトリ)のハッシュが記録されている。 また、親となるコミット(ひとつ前のコミット)のハッシュを持つ。 そのほか、authorやcommitter、コミットメッセージが記録される。 $ git cat-file -p a2e77fbbef72a23e6c908a0eb36c219d77e1a93b tree 123fdb23bd445760cfd90eaf90946648fb012b99 parent 2abb34478c89d08d2c83a46bc715db939b6ea1ce author *** <***@gmail.com> 1620306851 +0900 committer *** <***@gmail.com> 1620306851 +0900 test commit コミットまでの一連の流れを見てみる。 $git addすることでblobオブジェクトが作成され、$git commitによりローカルリポジトリにtreeオブジェクトとcommitオブジェクトが作成される。 1度目のコミット。 片方のファイルに修正を加えての2度目のコミット 注目すべきは、treeオブジェクトにおいて変更されていない方のblobオブジェクトのハッシュは変わっていない点である。 gitはcommitする度に全てのスナップショットを保存していくのではなく変更があったファイルのみをスナップショットとして保存し、変更されていないファイルは同じハッシュを使い回すことで容量を節約している。 なお、インデックスとローカルリポジトリの状態を確認するには以下のコマンドを利用することで確認可能。 # インデックス $ git ls-files --stage 100644 38e5cdb340ae9979fe513f62388dff69a9885ad1 0 test/aaa.txt 100644 83c831f0b085c70509b1fbb0a0131a9a32e691ac 0 test/bbb.md # リポジトリ $ git ls-files test/aaa.txt test/bbb.md gitの実体はハッシュ値をキーとし、圧縮したファイルを値としたKVSのようなものであり、各コミットは有向グラフとして過去の全ディレクトリ構造を辿れるように管理されているため、任意のコミットの状態に行き来できることが確認できた。 ブランチ ではどのようにして任意のコミットに移動したり、現在作業中のコミットを区別しているのか。 作成されたブランチは.git/refs/heads/以下に保存される。この中に作成したブランチ名のファイルが並んでおり、開くと単にテキストとして最新コミットのハッシュが書かれている。(テキストなのでcatコマンドなどで開ける。) 実は、ブランチとは枝分かれしたグラフの部分グラフ自体を指しているのではなく、それぞれの枝の最新のcommitオブジェクトのハッシュを表す単なるテキストである。 このイメージを持つことで、ブランチをマージする時に取り込みたい方のブランチに移動して$git mergeするのも納得できるし、マージ後のブランチが消えるのではなく、マージコミットを作る前の最後の最新コミットであることがわかる。 HEAD 複数の進行中のブランチがある中で、どのブランチにコミットするのか、この状態を保持しているのがHEADである。 HEADは.git/HEAD(テキストファイル)で確認でき、ブランチへの参照が載っている。 HEAD ref: refs/heads/master これにより現在のブランチを区別できる。 そして、ブランチへの参照ということは、その実体はcommitオブジェクトのハッシュであり、実はHEADもコミットへのハッシュであるということがわかる。実際、$git checkout [任意のコミットのハッシュ]とすると、detached HEADという状態に変わり、.git/HEADの中身が移動したコミットのハッシュに書き換わっていることが確認できる。 $ git checkout a2e77fbbef72a23e6c908a0eb36c219d77e1a93b Note: switching to 'a2e77fbbef72a23e6c908a0eb36c219d77e1a93b'. 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 switching back to a branch. If you want to create a new branch to retain commits you create, you may do so (now or later) by using -c with the switch command. Example: git switch -c <new-branch-name> Or undo this operation with: git switch - Turn off this advice by setting config variable advice.detachedHead to false HEAD is now at a2e77fb testcommit ブランチにアタッチされていないHEADの状態になっているので、$git checkout masterなどでブランチに戻してあげることができる。 なお、detached HEADの状態でも変更を記述し、コミットすることが可能であるが、コミット後にHEADを別のコミットに移動すると、ブランチによって参照されないこのコミットは$git log --graphからは表示されなくなる(objectとしては残るので直接ハッシュを指定して移動したらそのコミットに移動することは可能)。 ここまでの操作から、普段単にブランチを変えるコマンドだと思っていた$git checkoutコマンドというのは、実はHEADを指定したコミットに移動させるコマンドだとわかる。引数にはハッシュ自体も取れるし、実質その参照であるブランチやタグを指定することも可能である。 さらに、コマンド実行後、ワークツリーに表示されているファイルが移動先のファイルに変わっていることから、HEADを移動させるとともに、ワークツリーやインデックスを移動先のコミットの状態に書き換えるというのがcheckoutでしていたことである。 そうだとすると、例えば、feat/Aブランチで機能Aを実装中に、ちょっとmasterブランチのファイルを確認したいというような状況になった時、まだ書きかけでコミットしていないファイルを全て破棄するか、途中でも移動のためにコミットしないといけない事になる。それは不便だ。そこで利用されるのが、$git stashである。 スタッシュ 一時退避場所といった意味。 $git checkoutし、HEADを変える前に、書き換けのファイルをどっかに置いておいて、後で帰ってきたらまた展開したらいいじゃんというのが考え方。確かにそうだろう。 まずは適当にファイルを編集してaddせずに、別のブランチにcheckoutしようとしてみる。 するとまだコミットしてないファイルが上書きされるから移動できないと怒られる。 $ git checkout master error: Your local changes to the following files would be overwritten by checkout: test/aaa.txt Please commit your changes or stash them before you switch branches. Aborting スタッシュを利用するには以下。名前はつけてもつけなくてもいいし、saveも省略可。ここでやっていることは、現在のインデックスの状態でコミットを作成し、HEADとのマージコミットを作成している。これがstashの実体。つまり、stashもコミットと同じである。 # スタッシュへ移動。移動後はワークツリーとインデックスはHEADの状態に戻る。 $ git stash save [スタッシュ名(任意)] # スタッシュに送ったオブジェクトはここで一覧になって確認できる。 # on ** はどのブランチから退避させたstashかを示している。 $ git stash list stash@{0}: WIP on master: 6844080 teststash # スタッシュの中身は以下で見れる。stash@{0}も結局はコミットオブジェクト。 $ git cat-file -p stash@{0} # ピンポイントにそのファイルだけ見れてもなあ、、なので差分としてみる場合 $ git stash show stash@{0} -p スタッシュに送ることでワークツリー、インデックスはHEADの状態に戻り、checkout可能となる。さらに、移動した先でstashから取り出すことさえ可能だ。 $ git stash apply stash@{0} なお、stashから取り出してもstashには残ってしまうので、$git stash drop stash@{0}で削除できる。 (はじめから$git stash pop stash@{0}としたら削除までできる。) ただし、コミットオブジェクトとしては残っているので、ハッシュを指定してcheckoutするとそのstashを閲覧することもできる。(gitって何かミスってもそうそうものが無くなったりしなそう。) ここまでで、ブランチやタグ、HEAD、stash、どれもこれもがコミットへの参照であり、checkoutはどのコミットを手元の作業場(ワークツリー、インデックス)に持ってくるかを指定するものだとわかった。 なお、後述するがリモートリポジトリもローカルリポジトリからしたら1つのブランチとして表現される。 $git reset checkoutするとインデックスやワークツリーは移動先のコミットで上書かれてしまう。 インデックスの内容は今のままで移動させたい(例えばインデックスにあげたものを削除して、HEADの状態に戻したいなど)や、特定のファイルを移動させたいといった細かい動きにはresetを使う。 コミットを移動する。 $ git reset --[soft/mixed/head] [コミットのハッシュ] 移動先のハッシュにはよきHEADから相対的にn個前という表記としてHEAD~nとされる。1個前なら^もok。 オプションは3つ。デフォルトはmixedで、ほかにsoftとhardがある。 コミットの移動に関して、HEAD以外に何を移動しますか?というのがオプションで決めるところ。 softはHEADのみ。mixedはインデックスのみ、hardは全て移動させる。 重要なのは、移動させると当然ながらコミット前のファイルには二度と戻れないということ。(インデックスに関してはがんばればあるらしい?) ファイルを移動させる。 インデックスにあげてしまったファイルを戻したいとなった時、上の原理を使えば$git reset --mixed HEADとして、インデックスを丸ごと消してしまえばいいとわかる。さらに、--mixedオプションや引数HEADはデフォルトでこの値が選択されるので、$git resetだけでもよい。 もし、特定のファイルだけを戻したいなどであれば、ここにファイル名を続けることで実現できる。 すなわち、$git reset aaa.txtのようにするとaaa.txtのみをワークツリーに呼び戻せる。 ※ ただし、現在はrestoreコマンドがあり、それを使うことが推奨される。 # インデックスから特定のファイルをワークツリーに呼び戻す。 $ git restore --staged [ファイル名] # ワークツリーの特定のファイルを初期の状態に戻す。(未着手の状態に戻る。) # git restore [ファイル名] 旧来の方法で未着手の状態に戻すには$git checkoutコマンドを使う。 (この辺のcheckoutとresetの使い分けがいまいちわからない、、 → git reset & git checkout 使い分けまとめ、Git の Reset, Checkout, Revert の違い) # 特定のファイルを直前のコミットまで戻す $ git checkout -- [ファイル名] # ワークツリーを直前のコミットまで戻す $ git checkout . → 参考 git reset についてもまとめてみる $git rebase gitの実体は各時点でのスナップショットであるのでいらないコミットが増えるほど容量を食っていく。他にもタイポ打ち直したり、ケアレスミスを修正したくらいのコミットならpushしたくないとなるだろう。 そうした時に一度コミットした履歴を改竄するコマンドが$git rebaseである。 $ git rebase -i [ハッシュ] 指定したコミットオブジェクト以降のコミットをどちらかに混ぜ込んだり、無くしたりすることができる。 現時点からn個前とかなら、HEAD~nとしてもok rebaseの編集の仕方は色々ある。 pick → そのコミットを採用する。 squash → 特定のコミットをその直前のコミットに混ぜ込む。その際、新たなコミットとしてコミットメッセージをつける。 fixup → 特定のコミットをその直前のコミットに混ぜ込む。新たなコミットには直前のコミットメッセージと同じものをつける。 詳細はガイドの英語を読めばいい。 # Commands: # p, pick <commit> = use commit # r, reword <commit> = use commit, but edit the commit message # e, edit <commit> = use commit, but stop for amending # s, squash <commit> = use commit, but meld into previous commit # f, fixup <commit> = like "squash", but discard this commit's log message # x, exec <command> = run command (the rest of the line) using shell # b, break = stop here (continue rebase later with 'git rebase --continue') # d, drop <commit> = remove commit # l, label <label> = label current HEAD with a name # t, reset <label> = reset HEAD to a label # m, merge [-C <commit> | -c <commit>] <label> [# <oneline>] # . create a merge commit using the original merge commit's # . message (or the oneline, if no original merge commit was # . specified). Use -c <commit> to reword the commit message. ただし、歴史の改竄は未公開のローカルのコミットに対してのみやること。リモートが絡み始めると、他の人が迷惑を被るようになるためだめ。 リモートリポジトリ 既存のリモートリポジトリから全てのデータを取得する。 $ git clone https://github.com/***/test.git 既存のリモートリポジトリからgitのグラフを丸ごと持ってきてローカルに構築。リモートリポジトリのmasterブランチの先頭がどこにあるかを示すorigin/masterが生成される。 ローカルの変更を反映する。 $ git push [リモートリポジトリ名] [ブランチ名] どのリモートリポジトリ(一般的にはoriginとすることが多い)に対して、ローカルのどのブランチの変更を送るかを指定する。ここでもブランチが単にコミットのハッシュであることを利用すると、実はここはHEADと書いてもいい。 なお、ローカルでブランチを新設しても勝手にリモート側にもそのブランチができるわけではない。ローカルリポジトリからしたら リモートリポジトリは1つのブランチにすぎず、ブランチとはコミットへの参照でしかないから。 そこで、ローカルに新設したブランチをリモートリポジトリにも反映するには新しいブランチをつけたことを教えてあげる必要がある。 $ git push --set-upstream origin [新しいブランチ名] リモートの変更を取り込む。 $ git pull = $ git fetch + $ git merge pullはとってきてマージする操作を自動でやってくれるコマンドである。 リモートにもローカルにも変更がある場合にまじ、リモートから変更をとってきて(fetch)、ローカルのorigin/masterブランチを伸ばす。その後、ローカルでの変更との差を吸収するためにマージする。たいてい同じ箇所をそれぞれ変更していたりしない限りは成功するが、自動で判断できない場合はコンフリクトが発生し、手動で解消する必要がある。といってもどちらの変更を正としてマージコミットを作成しますか?ということなので、マージ後のあるべき姿に書き直してコミットすることを求められているということである。 なお、mergeではなく、rebaseしたい場合には----rebaseオプションを指定してpullしたらいい。 $ git pull --rebase = $ git fetch + $ git rebase また、ここまでの記述でoriginやorigin/masterとしていたが、その名称は任意に設定可能であり、別の名称をつけた物を複数用意し、リモートリポジトリを複数用意することも可能である。 リモートの設定は.git/configにテキストで書かれている。 config(抜粋) [remote "origin"] url = https://github.com/***/test.git fetch = +refs/heads/*:refs/remotes/origin/* リモートの名前(origin)、リモートリポジトリのURL、fetchする対象のrefspecが指定される。 refspecは、<リモート側の参照>:<ローカルの書き込み先>を意味しており、fetchする際にリモートのどのブランチをローカルのどこに対応づけて進めるかを指定している。なお、先頭の+は、fast-forwardでない場合でも参照を更新するよう指定している。 リモートの追加・削除は以下。 $ git remote add origin https://github.com/***/test.git $ git remote rm origin 参考 Gitが出来るまでの歴史と将来の展望(バージョン管理システム) Gitのつくりかた Gitの分散version管理の仕組み Gitのコミットの裏側で起こっていること 難しいGitコマンドは、仕組みから理解してみよう GitのHEADとは何者なのか git reset についてもまとめてみる
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Gitコマンドまとめてみた

はじめに これから就職するにあたって、いままで個人開発だけで済んでいたところ チーム開発をする必要が出てきたので、使いたいコマンドをまとめてみた。使えるコマンド一覧という形で簡単にまとめたので、詳しく知りたい場合は調べていただくとより理解が深まると思います。 解説 git status どのファイルが変更されたかを確認するコマンド 実際どんな変更を加えたか差分を見るコマンド addする前の変更分 git diff git diff <ファイル名> addする後の変更分 git diff --staged 変更履歴を確認する git log git log --oneline 一行で簡潔に表示する←これが便利そう git log -p index.htmlファイルの変更差分を表示する git log -n <コミット数> ファイルの削除を記録する git rm <ファイル名> git rm -rf <ファイル名> 上記のコマンドがうまくいかんかった時 git rm -r <ディレクトリ名> git rm --cached <ファイル名> ファイルを残したいけどgitの記録からは消したい場合 git reset HEAD rmを取り消す場合 ファイル名の変更を記録する git mv <旧ファイル> <新ファイル> git add とかcommitとかpushは割愛 とにかく当面はこれらのコマンドを頻繁に使って、慣れていこうと思います バージョン管理したくないファイルを無視する バージョン管理したくないファイルとは ➀passwordなどの、秘密情報が記載されて流出してはいけないファイル 例:AWSのpasswordなど ➁チーム開発において不要なファイル 例:キャッシュやWin, Macなどで自動生成されるファイル .gitignoreファイルの描き方 <ファイル名> 指定したファイルを除外 dir/ ディレクトリ以下を除外 ファイルへの変更を取り消す git checkout -- <ファイル名> git checkout -- <フォルダ名> git chechout --. 全変更を取り消す ステージした変更を取り消す git addしたけど間違えたときに使う取り消しコマンド git reset HEAD <ファイル名> git reset HEAD <ディレクトリ名> git reset HEAD . 全変更を取り消す 直前のコミットを取り消す git commit --amend ※pushする前のみ使える git commit --amend リモートの情報を確認する git remote git remote -v 対応するURLを表示 リモートリポジトリを複数持つこともできるよ 使い方→チーム開発と個別にいじりたいとき用で使い分けたい時 リモートから情報を取得する場合 git fetch <リモート名> git fetch origin 13 リモートから情報を取得する場合(pullの場合) マージするまでを一発でする方法 git pull <リモート名><ブランチ名> git pull origin master git pull 省略コマンド 次回 コンフリクトどうしよう問題 ## コンフリクト解決方法 同じ行を複数人が変更した場合など、どちらのブランチを優先すべきかとなりコンフリクトが起こる ## コンフリクトの予防法 追記 githubのソースコードコピペはRawからCtrl+Aの方が早いぞ!! (筆者は今までこれを知らず、長いコードも必死にドラッグしてコピペしてた) コマンドにエイリアスを付けると、コマンド入力が短く楽になるぞ!!(いちいちcheckoutとかstatusとか打つのめんどい) git config --global alias.br branch これで以降、git brでgit branchと同じコマンドとして使える この要領でckeckout→co, stasus→st, commit→ciという感じで設定していこう(備忘録→自分ではcommitはcmで設定している)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

コミットやSlack上の発言から日報を自動で生成するツールを作った

作ったもの こんな感じで、指定したリポジトリに積んだコミットやSlack上の発言を収集して、日報を自動で生成できます。 毎日日報を書くのがめんどくさい方、自分がその日に積んだコミットをモニタリングしたい方、ぜひご利用ください。 インストール方法 Homebrew $ brew install masatoraatarashi/nippo/nippo go get $ go get -u github.com/MasatoraAtarashi/nippo-generator 使い方 1. SlackのAPIトークンを取得 こちらの手順を参考にSlackのAPIトークンを取得してください。 User Token Scopesでsearch:readを指定してください。 2. 初期化する $ nippo init 上記のコマンドで$HOME/.nippo.yamlという設定ファイルが生成されます。 3. 設定ファイルを編集する 生成された設定ファイルを編集してください。 $HOME/.nippo.yaml template: #日報に含めたい見出しを自由に設定してください。 - 今日やったこと - 明日の予定 - 所感・連絡事項 - git - slack git: heading: "git" repositories: #コミットを取得したいディレクトリの絶対パスを記入してください。 - "Users/MasatoraAtarashi/workspace/hogehoge" - "Users/MasatoraAtarashi/workspace/hogehoge2" slack: token: "" #Slack APIトークンを記入してください。 username: "" #Slackのユーザ名を記入してください。 4. 日報を生成する $ nippot generate 出力例 # 2021-05-06 ## 今日やったこと ## 明日の予定 ## 所感・連絡事項 ## git ### hogehoge(3 commits) - 7ae0175 Add count option - 7335722 Add slack to default config - 3bcd230 Add slackname option ### hogehoge2(1 commits) - 3bcd230 Update README ## slack - `よろしくお願いいたします!` (random) - `こんにちは` (テスト) オプション templateを編集すれば日報に含める内容を自由に変更できます。 repositoriesを編集すれば日報に含めたいリポジトリを自由に指定できます。 使った技術 golangとcobraというライブラリを使って作りました。 https://github.com/spf13/cobra
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む