20210228のGitに関する記事は8件です。

GitHub リベース スタッシュ タグ

【GitHub リベース スタッシュ タグ】

山浦清透さん いつもありがとうございます。
Git:もう怖くないGit!チーム開発で必要なGitを完全マスター

リベース

リベースは、変更を統合する際に、履歴をきれいに整えること。
マージのようにただ変更内容を取り込むだけではないところが相違点。

リベースで履歴を整えた形で変更を統合する。
 → git rebase < ブランチ名 >

 ※ブランチの基点となるコミットを別のコミットに移動する。

注意:GitHubにプッシュしたコミットをリベースするのは絶対NG
 → GitHub上の履歴が壊れてしまう恐があるため。

マージかリベースどちらを使うか。

作業履歴を残したい場合は、マージを使う。
作業履歴を残す必要が無く、履歴をきれいにしたい場合は、リベースを使う。

プル時にリベースする。

マージコミットを残さずに、GitHubの内容を取得したい時に使う。
GitHubの情報を単純に取得したい時に使う。
 → git pull --rebase

デフォルトで、プルの挙動をリベース方に設定する。
→ git config --global pull.rebase true

※このコマンドを実行しておくことで、プル時に--rebaseが不要になる。

スタッシュ

スタッシュは、作業が途中でコミットしたくないけど、別のブランチで作業しないといけないような時に作業を一時退避する。

作業を一時退避

作業を一次退避する。
 → git stash

 ※stashは、隠すと言う意味。変更分をstashに一次退避。

一時退避した作業を確認

退避した作業の一覧を表示する。
 → git stash list

一時退避した作業を復元

退避した作業を復元する。
 → git stash apply (最新の作業を復元)
 → git stash apply --index (ステージの状況も復元)
 → git stash apply [スタッシュ名] (特定の作業を復元)

 ※ apply:適応すると言う意味。

一時退避した作業を削除

退避した作業を削除する。
 → git stash drop (最新の作業を削除)
 → git stash drop [スタッシュ名] (特定の作業を復元)
 → git stash clear (全作業を削除)

タグ

タグは、コミットを参照しやすくするためにわかりやすく名前を付ける。
リリースポイントによく使う。

タグの一覧表示

タグの一覧を表示する。
 → git tag -l ( -lを付けると絞り込みができる。)

タグの作成

アノテーション付き(annnotated)とシンプル版(lightweight)の2種類がある。

アノテーション付きのタグを作成する。
名前やコメント、署名を付けられる。
 → git tag -a [タグ名] -m "[メッセージ]"

 -aオプション:アノテーションタグを作成
 -mオプション:エディタを立ち上げずにメッセージ入力が可能

シンプル版のタグを作成する。
名前のみを付けられる。
 → git tag [タグ名]

 ※アノテーション付きとの違いは、-aオプションが付いているかいないか。

タグのデータを表示

タグのデータと関連付けられたコミットを表示する。
 → git show [タグ名]

タグをリモートリポジトリに送信

タグをリモートリポジトリに送信するには、git pushコマンドが必要。
 → git push [リモート名] [タグ名]

タグを一斉に送信する。
 → git push [リモート名] --tags

 ※--tagsを付けると、ローカルにあってリモートリポジトリに存在しないタグを一斉送信

おまけ

山浦清透さん ありがとうございました。
Git、GitHubの学習を一通り終えることができました。
今後のチーム開発に活かしていきます。
image.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

`git pull` した際に"reference broken"というエラーが出たときの対処法

発生した事象

コードをgit pullしようとしたところ、

error: cannot lock ref 'refs/remotes/main': unable to resolve reference 'refs/remotes/main': reference broken

という旨のエラーが出て失敗するようになってしまいました。

当該ファイル(.git/refs/remotes/main)を覗いてみたところ、40文字ほどのNULL文字が羅列されているだけの内容でした。

発生した環境はWindows 10 (64bit)およびgit version 2.30.1.windows.1です。

解決法

Googleで検索を掛けたところ、こちら

On my system (Windows 7 64-bit), when a BSOD happens, some of the stored reference files (most likely currently opened/being written into when BSOD happened) are overwritten with NULL characters (ASCII 0).

As others mentioned, to fix it, it's enough to just delete those invalid reference files and re-fetch or re-pull the repository.

と、自分と同様の事象と解決策の報告がありました。

この報告に従い、当該ファイルを削除して再度 git pullしたところ、無事にpullすることができました。

原因

詳細な発生原因は現状では不明ですが、上記の報告でもブルースクリーンが出た後に発生したという記述があり、自分もPCがフリーズして電源を落とした後に発生しました。
Gitが何らかの作業を行っている最中にシステムがクラッシュしたことが原因の可能性が高そうです。

参考資料

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHub チーム開発の流れ

【GitHub チーム開発の流れ】

山浦清透さん いつもありがとうございます。
Git:もう怖くないGit!チーム開発で必要なGitを完全マスター

Git 推奨される開発流れ

masterブランチをリリース用ブランチにして、開発はトピックブランチを作成して始めることが基本だそうです。

(私が従事する業務プロジェクトも上記のようなチーム開発の体制を取っています。)

masterブランチが最新リリースの状態に保っておくことが出来る。
バグが発生しても、前のバージョンに遡ればバグのない状態に出来る。
 → masterブランチで開発すると、バージョンの状態がややこしくなる。

プルリクエスト

自分の変更したコードをリポジトリに取り込んでもらえるようにする依頼する機能。

プルリクエストの手順

1、ローカルリポジトリからリモートリポジトリ(GitHub)にプッシュする。
2、プルリクエストを送る。
3、チームメンバーにレビューしてもらう。
4、OKであれば、プルリクエストマージする。
5、不要になったブランチは削除する。

GitHub Flow

GitHub社が自社でおこなっているワークフロー

GitHub Flowの手順

1、masterブランチからブランチを作成する。
2、ファイルを変更して、コミットする。
3、同名のブランチをGitHubにプッシュする。
4、プルリクエストを送る。
5、レビューをして、masterブランチにマージをする。
6、masterブランチを本番サーバにデプロイする。

ポイント

・masterブランチは、常に最新に保つ。
・新しく開発する場合は、masterブランチから新規で作成する。
・定期的なPushを心がける。
・masterブランチにマージするためのプルリクエストを欠かさない。
・必ずレビューを受けてから、masterブランチにマージして、デプロイする。
(テストとデプロイ作業は自動化しよう。)

※シンプルなワークフローにすることで、ミスを減らす!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

GitHub ブランチとマージについて

【GitHub ブランチとマージについて】

山浦清透さん いつもありがとうございます。
Git:もう怖くないGit!チーム開発で必要なGitを完全マスター

Gitは、大規模開発での必須ツールになっている。
複数人で複数の機能を並行して、開発することを可能にする。

ブランチ

ブランチは、コミットを指すポインタの役目をする。
スナップショットでファイルの記録をしている仕組みを利用して、
ブランチの作成や切り替えを高速におこなっている。

ブランチを利用することで分岐して作業が出来て、効率的になる。

ブランチを新規追加

ブランチ作成のみで、ブランチの切り替えはおこなわない。
 → git branch < ブランチ名 >

ブランチを一覧を表示

どんなブランチがあるかを確認する。
 → git branch (全てのブランチを表示したい時は、-a を付ける。)

ブランチを切り替え

既存に存在しているブランチに切り替える。
 → git checkout < 既存ブランチ名 >

 ※ブランチを新規に作成して切り替える。一度に実行できる。
  → git checkout -b < 新ブランチ名 >

ブランチを変更・削除

自分が作業しているブランチ名を変更する。
 → git branch -m < ブランチ名 >

ブランチを削除する。
 → git branch -d < ブランチ名 >

 ※-dコマンドは、masterにマージされていない変更があれば、警告をしてくれる。

ブランチを強制削除をする。
 → git branch -D < ブランチ名 > 

マージ

マージは、他の人の変更内容のを取り込む作業のこと。

変更履歴をマージする

自分の作業中のブランチにマージする。
 → git merge < ブランチ名 >
 → git merge < リモート名 / ブランチ名 >

コンフリクト

コンフリクトとは、複数人の人が同じ箇所で別々の変更した時に起こる。
Gitが、どの変更を優先したら良いかわからなくなっている状態。

コンフリクトを起こさないようにするには。

・複数人で同じファイルを変更しないようにする。
・pull, mergeをする前には、変更中の状態を無くしておく。
・pullする時には、pull対象のブランチに移動してから実行する。

※コンフリクトの対応を慌てずに出来るようにしておこう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

実装とリリースが前後するのを前提としたGit運用フロー

業務で主に Ruby On Rails での開発を行っていますが、そこで得た知見や、失敗への対応などについて記します。

今回は「実装とリリースが前後する」場合に Gitの運用フローをどのようにするか、についてです。

現状(要件)

弊社は アジャイルソフトウェア開発 のうち、とりわけ エクストリーム・プログラミング(XP) を主体とした開発プロセスを採用していますが、その結果として、常に

短い開発サイクルで頻繁に「リリース」する

状態になっています。

これは「Webアプリケーション」というサービス形態からも必要なことで、より多様なチャレンジをより早く提供するために最適な方法だと考えていますが、一方、実装がやや前倒し気味に行われることもあって、「実装はしたけれども、リリースは待つ」こともよく生じます。

これに対応する方法として、一般的に考えられるのは

  1. 新機能は「フラグで無効化」した上でリリースし、必要になれば「フラグを有効化」する
  2. 新機能を実装したブランチのマージを遅らせる(待つ)

の 2つで、このどちらを採用するのかで「Gitの運用方法」そのものも異なってきます。

この両者を比較しながら、弊社では 2. の「マージを遅らせる」方法を採っているので、その説明も合わせて行います。

1. 新機能は「フラグで無効化」した上でリリースし、必要になれば「フラグを有効化」する方法

これは フィーチャートグル と言われる方法で、有名なところでは

などが採用しています。

つまるところ、

  1. 新機能を実装する場合には、その機能を「無効」にした上で、メインブランチにマージしてしまう
  2. 利用開始までは、その機能は「無効」状態のまま、サービス全体のリリースに含めてしまう
  3. 利用開始になれば、その機能を「有効」に変える

といった方法で、具体的な Gitの運用フローとしては github-flow という名称で知られています。

この方法の良い点は

  • ブランチが事実上一つなので、マージ時のコンフリクトの可能性をかなり少なく出来る
  • 本番機でも「一部のユーザー」に新機能の提供が出来る
  • 「古い機能」と「新しい機能」の共存を前提とした実装になるので、反映時のトラブルの可能性を少なく出来る

ということになり、かなり良いことずくめな印象です。

しかし一方、逆の面としては

  • 「古い機能」と「新しい機能」の共存を前提とした実装に手間がかかる
  • 動作確認が「機能OFFのままリリースした時」と「機能ONにした時」と実質的に2倍になる
  • アプリケーションの実装が「フラグで無効化されている部分も含む」となって見通しが悪くなる

こともあって、開発上の負担も心配になるところです。

2. 新機能を実装したブランチのマージを遅らせる(待つ)

これは フィーチャーブランチ と言われる方法で、 特に Github での Pull Request (PR) はこの「フィーチャーブランチ」での開発を前提としたものと言えます。

これは、

  • 機能実装時にメインブランチから「フィーチャーブランチ」を分岐させ、そのブランチで開発を行う
  • 必要に応じて適宜、インテグレーション用のブランチなどにマージする
  • 最終的にリリース時に、メインブランチにマージすることによって、その新機能を利用開始状態にする

という方法で、具体的な Gitの運用フローとしては gitlab-flow という名称で知られています。

この方法は

  • 「古い機能」と「新しい機能」の共存状態を考慮しなくて済む場合が多い
  • 動作確認が「機能リリース時」だけに絞られる
  • アプリケーションの実装内容が「使われている機能のみ」となって見通しが良くなる

といった面で開発面での負担軽減になりやすい方法ですが、一方で

  • 実装に時間がかかったり、機能の利用開始時期が遅れるとマージ時にコンフリクトが発生する可能性が高い
  • 「一部のユーザー」にだけ新機能の提供をする、といった方法でのサービス提供がしにくくなる
  • 「古い機能」と「新しい機能」の共存を前提としない実装になるので、反映時にその部分の考慮不足があると不具合が生じる

などの面での注意を要します。

ではどちらを採用しているか

結論としては弊社は 2. の「フィーチャーブランチ」での開発を主体としています。

理由としては、

  1. 開発を早く廻すためには「ある程度のリスクが生じても、開発の負荷を減らす」ほうがメリットが多いと判断していること
  2. 特に「利用開始が遅れることによるコンフリクト発生の可能性」については、出来る限りの対処を行っていること(内容については次回に記します)
  3. 必要に応じて「フィーチャートグル」も取り入れて、一部テストや利用開始の遅延に対処するようにしていること(同上)

等があります。

実際にどのような工夫をして「フィーチャーブランチ」での開発を進めやすくしているかについてや、具体的に gitlab-flow をどのように用いているかについては、次回に記載します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Herokuのアプリケーション停止/実行

heroku gitにpushしたら自動でアプリケーション実行してくれるが、
停止する方法がわからず調べたので備忘録。
どうやらweb=0が停止でweb=1が実行らしい。

アプリケーション停止

$ heroku ps:scale web=0

アプリケーション実行(再開)

$ heroku ps:scale web=1
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

gitでコミットの前にprefixがない時にエラーを返すようにしてみた。

はじめに

最近あるプロジェクトに入っていた時にコミットの前によくprefixが入っているのをよく見るようになりました。
自分も真似てprefixをつけるのですが、たまに付けるのを忘れてしまう。。。

どうにかならないものか、、、

少し友人に聞いてみるとこちらの記事を教えてもらった!
まさにやりたいことはこれだった。

Git の commit-msg hook でコミットメッセージにチケット番号が含まれるかチェックする

早速参考にして書いてみた

commit-msg
#!/usr/bin/env ruby

regex = /fix: |feat: |bug: |add: |update: |change: |refactor: |disable: |delete: |rename: |upgrade: |style: /

message = File.read(ARGV[0]) 
if !regex.match(message)
  puts "\n//// HEY HEY HEY!!! ////\n\n"
  puts "//// please check prefix for the message ( ´・‿・`) ////\n\n\n"
  exit 1
end

結果

スクリーンショット 2021-02-28 0.19.32.png

出来た!!!!!

今回はRubyで書いたんですができればNode.jsで書きたかった。

この記事を参考にNode.jsでかけるようにでは出来たけど、コミットの引数をどうやってNode.jsで取得するかが分からなかったので出来ませんでした。。
この辺りわかる方がいましたらコメントくださいませ。。

オシマイ( ´・‿・`)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Git]既存のディレクトリのGit管理をmaster以外のブランチで始める

既存のディレクトリをmasterブランチ以外のブランチに反映する(同期する)手順(覚え書き)。
Gitのホスティングサービスは、GitLabを用いていますが、他を使用した場合も考え方は使えるかと。

やりたいこと

image.png

環境

  • OS: Amazon Linux2
  • Gitのホスティングサービス:GitLab

ディレクトリ構成

test
 |
 |----test.php
 |
 |----log →ログ出力用のディレクトリ:配下のファイルはGit管理対象外
 |      |----aaa.log
 |      |----bbb.log
 |      |----ccc.log
 |            :
 |            :
 | 
 |---dao                 
       |----testDao.php                   

testディレクトリのGit管理をmasterブランチではなく、developブランチで始めます。
また、logディレクトリ自体はGit管理の対象とするが、配下のログファイルは管理対象外とします。

手順

1. リモートリポジトリの作成

(1) まずGit管理を始めたいディレクトリと同名のプロジェクトを作成します。
GitLabにログインしたら、「New project」をクリックしましょう。
image.png

(2) 今回は、「Create blank project」(空のプロジェクト)にしました。
image.png

(3) 「Project name」にGit管理を始めたいディレクトリと同じ名前をつけ(①)、他は任意に入力し、「Create project」をクリック(②)。
image.png

(4) どうやら全く空だとブランチを作れない様子だったので、とりあえず.gitignore(Git管理の対象外とするファイルやディレクトリを記入する)を作っておくことに。
「New file」をクリック。
image.png

(5) 遷移先の画面にて、「New file」をクリック。
image.png

(6) 「.gitignore」をクリック。
image.png

(7) .gitignoreが作成されたら、ひとまず空のままコミットしてしまいます。
「Commit」をクリック。
image.png

(8) 別の「Commit」ボタンが出現するので、こちらもクリック。
image.png

(9) プロジェクトアイコンをクリックして、プロジェクトTOPに戻ります。
image.png

(10) すると、新しいブランチが作成できるようになっています。
「+」をクリックして(①)出現したプルダウンから、「New branch」をクリック(②)。
image.png

(11) 「Branch name」に「develop」と入力して(①)、「Create branch」をクリック(②)。
image.png

2. ローカルリポジトリの作成

続いて、ローカル環境で作業を行います。

(1)Git管理を始めたいディレクトリのある階層まで移動したら、対象のディレクトリをひとまずリネームしましょう(理由はページ下部の補足事項に記載しています)。

$ mv test test.origin

(2) 作成したリモートリポジトリのTOP画面で、「clone」をクリックし(①)、「Clone with HTTPS」右横の「Copy」ボタンをクリック。
image.png

(3) 以下のコマンドを実行して、developブランチとしてcloneします。

$ git clone -b develop [(2)でコピーしたURL] ([ディレクトリ名])

もし、プロジェクト名と異なる名称で、クローンしたい場合は、「[(2)でコピーしたURL]」から半角スペースを空けて、つけたい名称を入力しましょう(「([ディレクトリ名])」の部分)。

(4) リネームしたディレクトリ配下をcloneしたリポジトリにコピーします。

$ cp -Rp test.origin/* test/

(5) その後、リポジトリ配下に移動し、以下のコマンドを実行して、

  • 成果物がコピーできていること
  • cloneできていること(.git, リモートリポジトリで作成した.gitignoreが存在するか)

を確認します。

$ tree -a

(6) logディレクトリのみGit管理の対象とし、配下のファイルは対象外とする対処を施します。
まず、logディレクトリ配下で、.gitkeepを作成しましょう(隠しファイルであれば名前は問いません)。

$ cd log
$ touch .gitkeep

(7) 1階層上に戻って、.gitignoreに以下のように記述し、保存します。

.gitignore
log/*
!log/.gitkeep

これで、.gitkeepを除くlogディレクトリ配下のファイルが全てGit管理対象外となり、.gitkeepによってlogディレクトリはGit管理の対象とされます。

(8) ステージングに追加し、コミット、プッシュします。
ここで、サーバ上のdevelopは本来デプロイ用のもので(場合にもよると思いますが)、gitconfigにユーザー情報を保存せず、一時的な情報でコミットします。
コミットメッセージは任意で。

$ git add .
$ git -c user.name='hoge' -c user.email='hoge@test.com' commit -m 'first commit'
$ git push

3. リモートリポジトリへの反映確認

ローカルリポジトリの内容がリモートリポジトリのdevelopブランチに反映されているか確認します。

(1) developブランチは以下の通り、ローカルリポジトリの反映されていました。
image.png

(2) masterブランチは元の通りで、ローカルリポジトリの内容は反映されていません。
image.png

うまくいきました!

補足事項

Git管理したいディレクトリをリネームしている理由は以下の通り。

1. リネームせず、同階層でcloneしようとした場合

$ sudo git clone -b [GitLabよりコピーしたURL]
fatal: destination path 'test' already exists and is not an empty directory.

2. リネームせず、ディレクトリ直下でcloneしようとした場合

$ sudo git clone -b [GitLabよりコピーしたURL] .
fatal: destination path '.' already exists and is not an empty directory.

どちらの場合でもエラーになってしまうんですね。。
そのため、既存のディレクトリを一度リネームして、リモートリポジトリをクローンしてから、中身をコピーするという流れに落ち着きました。

終わりに

既存のディレクトリをGit管理する場合、リモートリポジトリのmasterと同期したいところですが、開発環境を使ってスタートするケースなど、そうもいかない場合もあったりするもの。
手順に少し癖がありますが、実現できる方法を見つけられてよかったです。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む