20191125のGitに関する記事は12件です。

GitHubリモートリポジトリをローカルにcloneする

自分のGitHubリポジトリをローカルPCにcloneする方法をまとめる。

前提条件

・GitHubアカウント取得済み
・Windows PCにgit for Windowsをインストール済み。(Macでもだいたい一緒かと思う)

Git Bashを起動

WindowsメニューからGit Bashを起動。
※スタートメニューの検索でgitと入れれば出てくるよ。

002.PNG

ローカルリポジトリ格納先に移動

cd コマンドでGitHubのリモートリポジトリを複製する、ローカルリポジトリ格納先を決めてカレントディレクトリにする。cloneするとリモートリポジトリのトップディレクトリごと生成されるので一つ上のフォルダに移動すればよい。

ここでは一つ上の階層のフォルダrepoを作成して、カレントディレクトリにしておく。

003.PNG

GitHubリポジトリのURLをコピー

ブラウザでGitHubリポジトリのページを開く。

GitHubリポジトリを選択し、clone or download(緑色)のプルダウンを選択。
httpsのURLが出てくるので、URL右側のコピーボタンを押し、クリップボードにコピーする。

001.PNG

Git Bashでcloneコマンドを実行

コピーしたURLをgit cloneコマンドの引数に指定して実行する。
sshも指定可能だが、ここではhttpsのURLを指定。

git clone https://github.com/kanazwk/dev.git

実行例:
004.PNG

cloneされたことの確認

GitHubリポジトリのトップディレクトリ(この例ではdevディレクトリ)が出来ていることを確認。

005.PNG

ls -laで見てみる。
.gitフォルダが生成され、コードがローカルに複製されたことを確認できる。
006.PNG

cloneしたローカルリポジトリをcommitし、pushしてみる

QIITAARTICLE.txtファイルを作成し、GitHubリモートリポジトリにpushする。

ファイルを作成:
007.PNG

commitしてpush:
009.PNG

Webで見ておくとGitHubに上がっていることが分かる。
010.PNG

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

Semantic Versioningでよくある間違いたち

はじめに

この記事は私が開発していて見かける『Semantic Versioning』の間違いについてまとめたものです。
対象は...

  • バージョン管理を任された方
  • Semantic Versioningを始めようと思っている方 or 始めたばかりの方
  • Gitのタグ付けに困っている方

などです。
『Semantic Versioning』は理解できています:bangbang: という方には物足りない内容になってしまうかなと思います。
よく分からないけど、興味はあるという方は、ぜひ『Semantic Versioning 2.0.0』に目を通してみてください。

よくある間違いたち

ここに挙げるものたちは、Semantic Versioningを行う上でよく見かける間違いたちです。
Semantic Versioningを導入する場合には、同じ間違いを犯さないように気を付けましょう

1. すべてメジャーアップデートで対応してしまう。

恐らくこれが一番見かけることが多いかなと思います。
何となくでSemantic Versioningを採用してしまっている場合に多いかなと思っています。

// このようなケースです。
1.0.0 -> 2.0.0 -> 3.0.0

これについては、Semantic Versioningの一番最初で各セクションの役割について言及されています。

バージョンナンバーは、メジャー.マイナー.パッチ とし、バージョンを上げるには、
1. APIの変更に互換性のない場合はメジャーバージョンを、
2. 後方互換性があり機能性を追加した場合はマイナーバージョンを、
3. 後方互換性を伴うバグ修正をした場合はパッチバージョンを上げます。

ここで示されている通り、各セクションはx.y.z(x:メジャー.y:マイナー.z:パッチ)を表しています。
↑の例だと、パッケージがリリースされる度にメジャーバージョンがインクリメントされているため、リリースするたびに後方互換性のないパッケージがリリースされているように見えてしまいます。

2. メジャー、マイナーのいずれかをインクリメントした際に下位の番号のリセットを忘れる

これも良く見かける間違いだと思います。
例えば下記のような感じです。

// マイナーをインクリメントしたが、パッチがそのまま...
1.1.9 -> 1.2.9

これだと、v1.2.0に対して、9個のパッチがあたっているように見えてしまいます。
この点ついても原文に明記されています。

7.マイナーバージョン Y (x.Y.z | x > 0)は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません(MUST)。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません(MUST)。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです(MAY)。その際にパッチレベルの変更も含めてもよいです(MAY)。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません(MUST)。

8.メジャーバージョン X (X.y.z | X > 0)は、パブリックAPIに対して後方互換性を持たない変更が取り込まれた場合、上げなければなりません(MUST)。その際にマイナーおよびパッチレベルの変更も含めてもよいです(MAY)。メジャーバージョンを上げた際には、パッチおよびマイナーバージョンを0にリセットしなければなりません(MUST)

マイナーバージョンを上げた際にはパッチバージョンを0にリセットする。

// パッチを0にリセット
1.2.8 -> 1.3.0

メジャーバージョンを上げた際には、パッチおよびマイナーバージョンを0にリセットする。

// マイナー、パッチを0にリセット
1.2.8 -> 2.0.0

3. パブリックなAPIを廃止しているのにマイナーバージョンをインクリメントしてしまう

これは、マイナーバージョンのインクリメント要件を勘違いしている時に発生することがあります。

7.マイナーバージョン Y (x.Y.z | x > 0)は、後方互換性を保ちつつ機能性をパブリックAPIに追加した場合、上げなければなりません(MUST)。また、いかなるパブリックAPIも廃止予定としたのなら、上げなければなりません(MUST)。プライベートコード内での新しい機能の追加や改善を取り込んだ場合は、上げてもよいです(MAY)。その際にパッチレベルの変更も含めてもよいです(MAY)。マイナーバージョンを上げた際にはパッチバージョンを0にリセットしなければなりません(MUST)。

ここで重要なのは『廃止予定としたのなら』です。『廃止したら』ではありません。
公開APIを廃止してしまうと、後方互換性は失われてしまいます。
そのため、最初に掲げている『後方互換性があり機能性を追加した場合はマイナーバージョンを、』に抵触してしまいます。

機能廃止については、FAQでも言及されており、一般的な流れとしては次のようになります。

  1. ドキュメントを更新し、対象のAPIが非推奨になることを報告する。
  2. 非推奨の機能を残したまま、マイナーバージョンをリリースする。
  3. 非推奨の機能を削除して、メジャーバージョンをリリースする。

4. 初期開発フェーズのバージョンを使い続ける

これは以前、私が自身がやっていて注意を受けたものです。
Semantic Versioningでは、メジャーバージョンに0を使用することで、『初期段階の開発用』という意味を持たせることができます。

// 開発用段階のバージョンであることを示している。
0.2.9

Packageを作成している側は、『初期段階の開発用』ということを明示的に表しておくことにより、公開されているAPIが不安定であること、破壊的な変更などいかなる変更も起こりえる。ということを対外的に示すことができます。
そのため、利用する側としては『公開されているAPIは不安定である。』と捉える必要があります。

いつ1.0.0を採番するのかについては、判断の難しいところですが、これについても一応の指針は示されています。

0.y.zのような初期の開発フェーズにおけるバージョンの取り扱いはどのようにすべきでしょうか?
一番簡単な方法は0.1.0からで開発版をリリースし、その後のリリースのたびにマイナーバージョンを上げていけばよいでしょう。

1.0.0のリリースはいつすべきでしょうか?
もし既にプロダクション用途であなたのソフトウェアが利用されているのなら、それは1.0.0であるべきでしょう。またもし安定したAPIを持ち、それに依存しているユーザーが複数いるのなら、それは1.0.0であるべきでしょう。もし後方互換性について多大な心配をしているのなら、それは1.0.0であるべきでしょう。

開発する側にとっては、ある意味で『責任を持たなくていい』ので楽かも知れませんが、使う側にすれば採用しづらいことこの上ないので、なるべくは明確なバージョンを採番することをオススメします。

5. プレリリースバージョンの優先度が高くなってしまう

Semantic Versioningは、x.y.zの記載以外にも、プレリリースを表す識別子の使用も許可されています。
(使用できる識別子は、ASCII英数字とハイフン [0-9A-Za-z-] である必要があります。)

// '-bata'の識別子を使って、プレリリースを表している。
1.0.0-beta

識別子が付いてしまっているためか、優先度が 1.0.0 < 1.0.0-beta であると勘違いされている方がいますが、識別子の使用はあくまでプレリリース『事前公開』を表すものなので、正式リリースではありません。
そのため、優先度は 1.0.0 > 1.0.0-beta となります。
(これについては、Semantic Versioningにも明記されています。)

メジャー、マイナー、パッチが同じ場合、プレリリースバージョンを持っている方が通常のバージョンよりも低い優先度です。例:1.0.0-alpha < 1.0.0。

これについては、使用している識別子が紛らわしいということも可能性としてあり得ますので、プレリリースであることが分かりやすい命名を意識する必要があるかなと思います。

判断が難しいものたち

ここに挙げるものは、間違いなのか判断が難しい微妙なものたちです。
(周りの人に聞いても、間違いなのか判断に迷う。ということだったので、↑とは別にしています。)

1. v1.2.3はSemantic Versioningではない

これだけ書くと、今までの話は何だったのか?となってしまうと思いますが、実はこれもSemantic Versioningに明記されています。

『v1.2.3』はセマンティック バージョンでしょうか?
いいえ、『v1.2.3』はセマンティック バージョンではありません。しかしながら、セマンティック バージョンに接頭辞の『v』を付けるのは英語ではバージョン番号であることを示す一般的な方法です。バージョン管理では、『バージョン』を『v』と略すことがよくあります。たとえば git tag v1.2.3 -m" Release version 1.2.3 " では『v1.2.3』はタグ名であり、セマンティック バージョンは『1.2.3』です。

要するにvはいらないよ!って話です。
ただ、これについては一概に間違いを指摘するのも、どうかなと私個人は思っています。
(間違いであると知っておくことは重要ですが、頭ごなしに指摘したり、今まで採番したものを全部修正するほどでもないかなと。)
本質的にインクリメントの要件が理解できていれば良いという意見もあるので、判断が難しいものとしました。

2. マイナー、パッチを同時にインクリメントしてしまう

バグ修正と機能追加が同時に行われてしまった場合に、マイナー、パッチを同時にあげるというものです。

// バグと機能追加が一緒なのでマイナー、パッチバージョンをインクリメント
1.1.0 -> 1.2.1

これは個人的には間違いに含まれるのかなと思っていますが、周りには許可するという方もいたので、こちらに記載しています。
(これを許可すると答えた方は、細分化すれば結局同じだから。ということでした。)

// 機能追加後、パッチを当てたと同じ状況では?ということ。
1.1.0 -> 1.2.0 -> 1.2.1

私個人の意見としては、たとえ結果が同じだとしても、同時にバージョンをあげてしまうのはNGかなと思っています。
Gitなどでタグを管理していた場合、↑の例であれば1.2.0のタグが存在しないことになってしまうというのも理由の一つ理由ですが、そもそも仮に同時に発生したとして、バグを修正した結果として機能性追加になったのであれば、マイナーバージョンアップで良いでは?と思っているからです。

まとめ

今回は『Semantic Versioningでよくある間違いたち』と題して、現場や開発で見かける間違いや勘違いについてまとめてみました。
極論を言ってしまえば、バージョンを管理できていれば何でも良い。と言われる方もおられると思いますし、意見としてもっともです。

ですが、Semantic Versioningを採用すると決めたのであれば、Semantic Versioningの利点である『バージョンのコードが次のバージョンへの変更された際に何が変更されたのかユーザーに伝えることできる。』という点を最大限に生かしていただければと思います。
この記事が他者に優しいVersion管理を行う一助になれば幸いです。

参考・引用

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

git 同じ名前のタグとファイルが存在する場合

first-tag という名前のタグがあるとします。

git
$ git tag
first-tag

また、first-tag という名前のファイルも存在しており編集中です。
まだコミットはされていません。

git
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   first-tag

no changes added to commit (use "git add" and/or "git commit -a")

この状態のとき、first-tag ファイルをチェックアウトする(編集を取り消し)にはどうすればよいでしょうか。
もし、単純にファイル名を指定してチェックアウトしてみると。

git
$ git checkout first-tag
error: Your local changes to the following files would be overwritten by checkout:
    first-tag
Please commit your changes or stash them before you switch branches.
Aborting

このようにタグをチェックアウトしようとする動作になり、怒られてしまいます。

こういったケースでは、-- (bare double dash) を使って、チェックアウトしたいのはファイルであることを明示してあげる必要があります。

git
$ git checkout -- first-tag
$ git status
On branch master
nothing to commit, working tree clean

# もちろんタグは残っています
$ git tag
first-tag
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

前のコミットの状態に戻したいときのコマンド

はじめに

ログイン機能を作った後にdeviseというGemをインストールしたらエラーが多発。

エラー解消の方法が結局分からなかったので、バージョンを戻すことに。

ローカルリポジトリの状態を戻す

まずは、ローカルリポジトリで戻したいバージョンを探します。

$ git log 

すると

commit 277e01ad992515f7005f80cb9216fa551e50985e(ハッシュ値)

コミットコメント

みたいにズラーっと今までのコミットが表示されます。

そのバージョンに戻してみましょう。

$ git reset --hard 277e01ad992515f7005f80cb9216fa551e50985e
HEAD is now at 277e01a コミットコメント

このようにHEADが戻したいバージョンになれば成功みたいです。

リモートリポジトリの状態を戻す

次に、リモートリポジトリの操作をしていきます。

普通にpushしても競合しちゃうので

$ git push origin +master

のようにpushしたいmasterの前に「+」をつけます。

これでローカルリポジトリもリモートリポジトリも、元通り!

ぼやき

ブランチを切っておいた方がよかったですよねこれは。
ブランチの概念がわかっていないので勉強します。。。

あと、途中からGem deviceをインストールするときの対処法あれば教えてください。

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

個人的 Emoji Prefix

? 内容 用途
? 最初のコミット リポジトリ作った!程度のコミット Readme 作成辺りで
? リリース まるで付ける必要がないけどリリース時のタイトルとかに
? ドキュメント ドキュメントの更新等
機能追加
一般的な更新 プロパティの追加/引数変更単位
? バグ修正 システム的な問題修正
誤字修正 誤字脱字による問題修正 正直?でいいと思う
? 修正 API 等の変更によるコード修正
? フォーマット インデント等
♻️ リファクタリング 処理方法の変更
? パフォーマンス パフォーマンス改善
? UI/UX デザイン的な
? コメント コメント追記
? WIP 作業中
? テスト テストコードの追加
? 非推奨 非推奨追加
? 移動 ファイル移動
?️ 削除 何かしら削除
? ローカライズ 翻訳ファイルなど
⚙️ 構成 package/tsconfigとか
依存関係の追加
依存関係の削除
⬆️ 依存パッケージのアップデート
⬇️ 依存パッケージのダウングレード
?️ Pull Request マージコミット

随時編集

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

githubでCompare & pull requestボタンがなかった時

始まりはgithubでプルリクが出せない!?
というものでしたが色々絡んでいて少し大変だった時の記録です。

前提、状況

今回新規でwordpressサイト立ち上げ時にローカルで開発して
featureブランチでプッシュ、そのあとmasterに
最初のプルリクエスト時にタイトルのメッセージが表示された。
そしてCompare & pull requestのボタンも見当たらないという状況。

エラーメッセージ

error.sh
The diff you're trying to view is too large. We only load the first 3000 changed files.

原因

wp-contentというディレクトリごと管理する方式をとっており
pluginディレクトリ、さらにはデフォルトのテーマも含んでいた。

タイトルの通り3000ファイル以上に変更が発生してしまった計算になった模様。

対応

githubのヘルプによると色々と制限があるようです。

ならばということでまずはいらないテーマを削除してプッシュしてみたら
Compare & pull requestのボタンは出たものの新たなエラーメッセージが

error2.sh
There isn’t anything to compare.
master and feature are entirely different commit histories.

とりあえずローカルのmasterブランチを最新にして
ローカルmaster → リモートmasterのプッシュを試みる

mergefromfeature.sh
$ git status
nothing to commit, working tree clean
$ git checkout master
$ git status
nothing to commit, working tree clean
$ git merge feature
$ git push origin master
! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'git@github.com:example/example.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

今回githubのリモートリポジトリを手動で作ったことが
ここでエラーの原因になっている模様。
要はmasterブランチがローカルとリモートでうまくリンクできていない状態。
(ちなみにgit remote -v , ssh -T git@github.com などのコマンドは正常に通っており、featureはローカルからプッシュが通る状態なのでなぜ?という印象でした。)

一旦プルしてという指示があったのでやってみる。
ローカルの既存ファイルが消えないかなという不安もあったので
一応macのfinderから手動でディレクトリごとバックアップコピーを取っておく。

pull.sh
$ git branch 
feature
* master
$ git pull origin master
remote: Enumerating objects: 3, done.
remote: Counting objects: 100% (3/3), done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), done.
From github.com:example/example
 * branch            master     -> FETCH_HEAD
 * [new branch]      master     -> origin/master
fatal: refusing to merge unrelated histories

成功したかと思いきやpushと同じ関連のない履歴ということで拒否されている。
どうやらGit 2.9から mergeコマンドとpullコマンドで
関連のないヒストリーを持つブランチをマージするには
オプション--allow-unrelated-historiesをつける必要があるとのこと。
こちらの記事を参考にさせていただきました。

参考記事を元に少し丁寧にfetchとmergeで

fetchandmerge.sh
$ git fetch origin master
$ git merge --allow-unrelated-histories origin/master
Merge made by the 'recursive' strategy.
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

うまくmergeできた模様。
ここでファイルをls -laで確認してみるとローカルにもともとあったファイルは消えずに残っていて
リモートにあったREADME.mdファイルが追加されている形になった。

これで$git push origin masterが成功し
この時点でローカルのマスターとリモートが同じになった。

あとはローカルのmasterをfeatureにマージして
ローカルfeature → リモートfeatureにプッシュ。

finish.sh
$ git status
On branch master
nothing to commit, working tree clean
$ git checkout feature
Switched to branch 'feature'
$ git branch
* feature
  master
$ git status
On branch feature
nothing to commit, working tree clean
$git merge master
Updating ********
Fast-forward
 README.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
 $ git push origin feature

これでgithub上でもfeature → masterにプルリクエスト&マージができるようになった。

今回得られた教訓

リソースの無駄はなるべく省く癖をつけよう。
最初の設定時はgithubから作成するか、ローカルからの場合はコマンドでgithub上にリモートリポジトリを作成した方が簡単そう。
構築前にまずgithub連携を行っておいた方が良さそう。

参考URL

githubヘルプ
関連のない履歴が拒否されたエラーの参考にさせていただきました。

Compare & pull requestがタイミングで出てこない場合もあります

これもたまに遭遇しますが以下のページにわかりやすく解説がありました。
参考ページ

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

gitでコミット時間を変更する

コミット時間を変更したいことって意外とけっこうありますよね。

やりかた

HEAD~数字のところは変えたいコミットの数を入力してください。

$ git rebase -i HEAD~数字
pick を edit に変更

以下を実行するとCommitDate と AuthorDateの両方が変更されます。

$ git commit --amend --date=now
$ git rebase --continue

以上です。

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

【随時更新】参考になったGitの神記事まとめ

はじめに

タイトルのとおり、Gitに関する操作でトラブルになった際にお世話になった記事や役に立った記事をまとめたリンク集です。

もちろん、新たにお世話になった記事があれば、随時更新していきます。

XXを取り消す

gitでのヤバイ!を取り消す方法
↑の記事のcase3の状況に対応したくて、検索していた際に出会いました。Gitでのヤバイ状況に対する対応が3つ書かれています。

【git】マージしたけどやっぱりやめたい時のやり方4種類
↑の記事のその2の状況に対応したくて、検索していた際に出会いました。タイトルのとおり、マージを止めたいときに非常に参考になる記事です。

エイリアス

gitで便利なエイリアス達
エイリアスを導入する際に参考にした記事です。
方法および豊富な具体例がとても勉強になりました。

おわりに

@ritukiii さん、
@chihiro さん、
おかげさまで、トラブルを解決できました。

@peccul さん
おかげさまで、エイリアスを導入することができました。

本当にありがとうございました。

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

Git操作まとめ 〜Gitのバージョン管理が必要ないファイルやディレクトリを除外する(.gitignore)

この記事では、Ubuntu18.04LTSにインストールしたGit(version 2.17.1)を使用しています。

.gitignore

Gitは、git initしたディレクトリの全てを履歴管理していきます。
そのディレクトリの中でも、履歴を追う必要のないファイルやディレクトリが出てくることがあります。

そうした場合、Git管理下のディレクトリで、.gitignoreというファイルを作成し、そこにGitの管理対象外にしたいファイルやディレクトリを記載することで、Gitの管理対象のから除外することができます。

touch .gitignore

.gitignoreファイルをエディタで開いてGitの管理対象外にするファイルを記述すればOKです。

この.gitignoreファイルはGitの管理対象にしておかなければならない(コミットする)ので、注意が必要です。


本記事目次ページ

Git操作まとめ

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

よく使うMarkdown記法

Markdownとは

markdownはqiitaの記事作成やgithubのREADMEファイルなどの文章の書き方です。
手軽に文章構造を明示できるので様々なオンラインプラットフォームで採用されています。
よく使われるMarkdownの記法を紹介します。

見出し

書き方

# 見出しh1
## 見出し h2
### 見出し h3
#### 見出し h4
##### 見出し h5
###### 見出し h6

実装後

見出しh1

見出し h2

見出し h3

見出し h4

見出し h5
見出し h6

強調

書き方

** テキスト **

実装後

テキスト

番号付きリスト

書き方

1. テキスト
2. テキスト
3. テキスト
  1. テキスト
  2. テキスト
  3. テキスト

リスト

書き方

* テキスト
* テキスト
* テキスト

実装後

  • テキスト
  • テキスト
  • テキスト

インライン表示

書き方

`ソースコード`
`var text = "hello"`

実装後

ソースコード
var text = "hello"

コードの追加

書き方
rubyとしている箇所は言語なので、phpで表記したい場合はphpにしてください

```ruby:title
puts "hello"
```

実装後

title
puts "hello"

リンクの書き方

書き方

[タイトル](URL)

[youtube](https://www.youtube.com/)

実装後
youtube

画像の追加

書き方

![desktop-1985856_1280.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/528825/c4e55ebc-2345-0de3-5e81-a6c785911dc5.jpeg)

実装後
desktop-1985856_1280.jpg

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

Work In Progressなプルリクエストをチームに適用した所感

チーム開発で今起きている以下の問題に対応する為、WIPなプルリクエストの運用を開始した

  • 巨大なプルリクエスト
    1000行超えるPRが結構な頻度で出来てた

  • 巨大な変更点に対するコメントのしずらさ
    そもそも論の修正だったりテストのやり直しに繋がりそうだなぁと思いコメントを控えてしまう

  • 1コミットがデカい
    デカい1機能1コミットにまとまって微修正のコミットが2,3個みたいな状況

  • テストやってるの?問題, どこまでやれば終わりなの?問題
    曖昧な機能要件に対するプルリクエストであるが故、テスト観点など不明瞭な為、テスト仕様書を求められたり、実装者もどこまでやれば良いか認識しきれていなかったり

これらはそもそもGitに扱いなれてないメンバーやチーム開発に慣れてないメンバーが多いや、タスクの切り方がしっかり出来ていないなどの問題の為起きていた。
なのでプルリクエストの在り方以前ではあったが、良い機会なので、課題の切り方やGitの運用方法なども見直した

WIPパターンのプルリクエストとは

WIP ... Work In Progressの略。進行中を表す

主な特徴としては

  • 最初のコミットは空コミットで始める
  • 実装者はプルリクエストをその時点で作成し、コメント内に実装内容などをチェックボックス形式で記載する(この時、PRのタイトルに[WIP]などつけ作業中を明確にし、マージを禁ずる)
  • レビュアーは認識の齟齬などないか確認する(実装者とレビュアーの意思疎通ツールとしてのプルリクエスト)
  • なるべく小さい粒度でコミットし、レビュアーやチームメンバーは適時コードをレビューしたりできる
  • すべての実装が完了したらタイトルの[WIP]を外し、最終レビューとマージをする

詳しくはこちら

Work in ProgressパターンによるPull Requestを利用した開発フロー

実際にやってみて

そもそも巨大なプルリクエストにならないようにタスクを切ったり、細かくコミットを心掛けるように喚起してから適用した。

良かった点

  • 未完成の段階でレビューや指摘ができる
    データ構造の設計や、アンチパターンを踏みそうなソースに早い段階で指摘できる
    完成してからだと実装者もレビュアーも心的疲労が大きい。それが改善された。
    当たり前だが、これが一番デカい。早い段階でパブリックな場所にソースが置かれるのは良いことしかない。
    特に若手メンバーを育成するのには最良だと思う。

  • 勿論コミットは小さくなるし、コンフリクトを未然に防げる
    前述と被るがコンフリクトしそうなソースに気づけ、指摘できる

  • 手戻りが減った。あったとしても早い段階で気付ける
    最初にタスクを細かく洗い出すので、レビューする時に「ここの〇〇ってどういう改修?」、「あれやってないけど大丈夫?」みたいなやり取りができる。

悪かった点

  • メンバーによってやったりやってなかったり
    コードレビューに重きを置いているメンバーや自分に近いメンバーはしっかりやってくれたが、始めた当初はメンバー間でモチベーション格差があった。
    タスクの洗い出しが雑だったり、コミットの粒度もマチマチだったり。
    コードレビューが怠惰なメンバーには単純に手間が増えたと感じるかもしれない。
    後述する空コミットの運用にも関係してくる

  • 空コミットが出来ない問題
    僕が所属してるチームが基本SourceTreeなどのGUIクライアントを使うメンバーが多く、コマンドでGitを操作したことないメンバー多数である。
    空コミットの仕方を教える手間や、空コミットだけターミナルでやる手間などが発生した。

  • プルリクエストが勝手にマージされてしまう
    チームで使っているリポジトリ管理がBacklogの為、ブランチを切っただけでプルリクエストが作れるメリットがあるのだが、その際空コミットしていないブランチが親ブランチがマージされるとそのブランチも差分なしと判断され、マージ済みになってしまう。(GithubはコミットないとPR作れないのでこの問題は起きないと思うが)
    これは空コミットの義務化をする以外ない

  • レビュータイミングが人によってまちまち
    これはwip適用する前からあった問題ではありますが、しっかりしたスクラムとかを組んでるわけではないので、結局実装完了後にPRを見るなんてこともありました。
    これに関しては週次なででコードレビューの時間や、レビュアー側のルール整備も必要だなといったところ

空コミットをGUIツール陣にも手軽にしてもらう施策

GUIツールにカスタムコマンドを登録する

Forkを例に挙げるが、SourceTreeにも同等の機能あり

  1. 設定からCustom Commandの項でAdd Branch Custom Commandを登録する
    fork-customCommand.png

  2. 空コミットのカスタムコマンドを登録
    この時、$shortname を含めておくと自動でブランチ名がコミットされ課題管理ツールと紐付き便利
    empty_commit_command.png

  3. 対象ブランチから右クリックから簡単に空コミットが出来るように
    empty_commit.png

まとめ

総じてメンバーやリーダー層やレビューする側からの評判が良く、やって良かったと言える。
やっぱりコードレビューはチーム開発においてかなりの比重と重要度を締めると思うので、一番改善しておくべきかつ効果が出るところ。
同じような悩みを抱えてるチームは一度やってみることを勧めます。
ただ、モチベーション格差などを感じた瞬間に、凹んだりしますが、チームビルディングってまぁこんな感じだよなぁと。利点を知って貰えるように自分が働きかける以外に道はないかなと思ってます。

現在、テストがない状態だったソースにテストコードを書くようにする施策などレガシーで非効率な開発スタイルから脱却しようと施策を打って少しでもチームがうまく回るように頑張っております。

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

Work In Progressなプルリクエストをチームに適用してみて

チーム開発で起きていた以下の問題に対応する為、WIPなプルリクエストの運用を開始した

  • 巨大なプルリクエスト
    1000行超えるPRが結構な頻度で出来てた

  • 巨大な変更点に対するコメントのしずらさ
    そもそも論の修正だったりテストのやり直しに繋がりそうだなぁと思いコメントを控えてしまう

  • 1コミットがデカい
    デカい1機能1コミットにまとまって微修正のコミットが2,3個みたいな状況

  • テストやってるの?問題, どこまでやれば終わりなの?問題
    曖昧な機能要件に対するプルリクエストであるが故、テスト観点など不明瞭な為、テスト仕様書を求められたり、実装者もどこまでやれば良いか認識しきれていなかったり

これらはそもそもGitに扱いなれてないメンバーやチーム開発に慣れてないメンバーが多いや、タスクの切り方がしっかり出来ていないなどの問題の為起きていた。
なのでプルリクエストの在り方以前ではあったが、良い機会なので、課題の切り方やGitの運用方法なども見直した

WIPパターンのプルリクエストとは

WIP ... Work In Progressの略。進行中を表す

主な特徴としては

  • 最初のコミットは空コミットで始める

  • 実装者はプルリクエストをその時点で作成し、コメント内に実装内容などをチェックボックス形式で記載する(この時、PRのタイトルに[WIP]などつけ作業中を明確にし、マージを禁ずる)

  • レビュアーは認識の齟齬などないか確認する(実装者とレビュアーの意思疎通ツールとしてのプルリクエスト)

  • なるべく小さい粒度でコミットし、レビュアーやチームメンバーは適時コードをレビューしたりできる

  • すべての実装が完了したらタイトルの[WIP]を外し、最終レビューとマージをする

詳しくはこちら

Work in ProgressパターンによるPull Requestを利用した開発フロー

実際にやってみて

そもそも巨大なプルリクエストにならないようにタスクを切ったり、細かくコミットを心掛けるように喚起してから適用した。

良かった点

  • 未完成の段階でレビューや指摘ができる
    データ構造の設計や、アンチパターンを踏みそうなソースに早い段階で指摘できる
    完成してからだと実装者もレビュアーも心的疲労が大きい。それが改善された。
    当たり前だが、これが一番デカい。早い段階でパブリックな場所にソースが置かれるのは良いことしかない。
    特に若手メンバーを育成するのには最良だと思う。

  • 勿論コミットは小さくなるし、コンフリクトを未然に防げる
    前述と被るがコンフリクトしそうなソースに気づけ、指摘できる

  • 手戻りが減った。あったとしても早い段階で気付ける
    最初にタスクを細かく洗い出すので、レビューする時に「ここの〇〇ってどういう改修?」、「あれやってないけど大丈夫?」みたいなやり取りができる。

悪かった点

  • メンバーによってやったりやってなかったり
    コードレビューに重きを置いているメンバーや自分に近いメンバーはしっかりやってくれたが、始めた当初はメンバー間でモチベーション格差があった。
    タスクの洗い出しが雑だったり、コミットの粒度もマチマチだったり。
    コードレビューが怠惰なメンバーには単純に手間が増えたと感じるかもしれない。
    後述する空コミットの運用にも関係してくる

  • 空コミットが出来ない問題
    僕が所属してるチームが基本SourceTreeなどのGUIクライアントを使うメンバーが多く、コマンドでGitを操作したことないメンバー多数である。
    空コミットの仕方を教える手間や、空コミットだけターミナルでやる手間などが発生した。

  • プルリクエストが勝手にマージされてしまう
    チームで使っているリポジトリ管理がBacklogの為、ブランチを切っただけでプルリクエストが作れるメリットがあるのだが、その際空コミットしていないブランチが親ブランチがマージされるとそのブランチも差分なしと判断され、マージ済みになってしまう。(GithubはコミットないとPR作れないのでこの問題は起きないと思うが)
    これは空コミットの義務化をする以外ない

  • レビュータイミングが人によってまちまち
    これはwip適用する前からあった問題ではありますが、しっかりしたスクラムとかを組んでるわけではないので、結局実装完了後にPRを見るなんてこともありました。
    これに関しては週次などでコードレビューの時間を設けたり、レビュアー側のルール整備も必要だなといったところ

空コミットをGUIツール陣にも手軽にしてもらう施策

GUIツールにカスタムコマンドを登録する

Forkを例に挙げるが、SourceTreeにも同等の機能あり

  1. 設定からCustom Commandの項でAdd Branch Custom Commandを登録する
    fork-customCommand.png

  2. 空コミットのカスタムコマンドを登録
    この時、$shortname を含めておくと自動でブランチ名がコミットされ課題管理ツールと紐付き便利
    empty_commit_command.png

  3. 対象ブランチから右クリックから簡単に空コミットが出来るように
    empty_commit.png

まとめ

総じてメンバーやリーダー層やレビューする側からの評判が良く、やって良かったと言える。
やっぱりコードレビューはチーム開発においてかなりの比重と重要度を締めると思うので、一番改善しておくべきかつ効果が出るところ。
同じような悩みを抱えてるチームは一度やってみることを勧めます。
ただ、モチベーション格差などを感じた瞬間に、凹んだりしますが、チームビルディングってまぁこんな感じだよなぁと。利点を知って貰えるように自分が働きかける以外に道はないかなと思ってます。

現在、テストがない状態だったソースにテストコードを書くようにする施策などレガシーで非効率な開発スタイルから脱却しようと施策を打って少しでもチームがうまく回るように頑張っております。

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