20191222のGitに関する記事は7件です。

Git のブランチを学ぶ

Learn Git Branching

初心者は視覚的にも操作的にもここが一番よいです。自分が操作するとどうなるのか?というのが凄くわかりやすいし、自分でコマンドを打つのでドキュメントを読むだけより覚えやすいです。

ずっと英語版しかないと思っていましたが、日本語版もありました。自動翻訳みたいな日本語ですが問題なく読めるので最強です。

少し使ってみる

Welcome ページはこんな感じ。右ボタンを選択して進めましょう。

Image from Gyazo

カリキュラムが出てきました。 まずはここから の 1 をやってみようと思います。

Image from Gyazo

こんな感じで何を学べばよいのか説明が出てきます。

Image from Gyazo

Image from Gyazo

Image from Gyazo

それではカリキュラム通りに、2 回 Commit をしてみます。画面左側がコマンドのログで、左下がコマンドを打つ部分です。

Image from Gyazo

クリアするとチェックマークが付きます。こんな感じでわかりやすく学んでいくことが可能です。

Image from Gyazo

まとめ

個人的には無料で学べる Git のサービスとしては優秀だと思います。
カリキュラム以外にもデモがあったり、自由にコマンドを打てるので、これをするとどんな感じになるのだろう?みたいなコマンドの確認にも使えると思います。

それと Branch を全面的に押しているので少し分かりづらいですが右下にメニューがあります。 Level を選択したり Reset も出来るので、間違えたときは右下を開くということを覚えておけば学習がスムーズに進むと思います。

最近の IDE やエディターなどは GUI で Git 操作がかなり出来るので、コマンドを好きで打つ人は多くないのかもしれませんが、いざというときや特殊な操作がしたい状況にも対応できるようにコマンドを学んでみてはいかがでしょうか?

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

既存プロジェクトを別プロジェクトとして作り直す

既存のプロジェクトを他のプロジェクトに流用する際の手順を備忘録として残します。

プロジェクトの名前を変更する

まず、プロジェクトのリネームをします。

スクリーンショット 2019-12-22 19.06.55.png

リネームすると以下のように自動的に関連するファイルのリネームしてくれます。
スクリーンショット 2019-12-22 19.07.11.png

これだけだとScheme名とプロジェクトフォルダ名は元のままなので、それぞれリネームをします。

スクリーンショット 2019-12-22 19.30.33.png
スクリーンショット 2019-12-22 19.31.08.png

次にinfo.plistの設定をします。
「Choose Info.plist File...」をクリックして、plistを指定します。
スクリーンショット 2019-12-22 20.18.16.png

最後にBundle Identifierを変更します。
スクリーンショット 2019-12-22 20.24.00.png

リモートを変更

$ git remote -v
origin  git@github.com:gdate/MVVMTest.git (fetch)
origin  git@github.com:gdate/MVVMTest.git (push)

$ git remote set-url origin git@github.com:gdate/FluxTest.git
$ git remote -v
origin  git@github.com:gdate/FluxTest.git (fetch)
origin  git@github.com:gdate/FluxTest.git (push)

あとは変更点をコミットし、プッシュすれば新たなプロジェクトとして開発できます。

$ git add .
$ git commit -m 'initial commit'
$ git push origin master
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Subversionをこのまま使い続けるべきなのか、

現在、職場にてSubversionのバージョン管理ツールであるtortoiseSVNを使用している。自分が使っているWindows10のpcが調子が悪いせいで、開発ではMacbook proを使用しているのだが macからの共有サーバーへのcommitがうまくいかない??

社内の共有サーバーにリポジトリを作成しているため、macからのコミットができないみたいです。調べたところ共有サーバーを使用したやり方は、推奨されていないようだ。

どういうやり方ベストなのか分からないが、ひとまずmacからremoteでwindowsにつないで、共有したディレクトリ上で管理してやっていこうと思う。

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

?【SourceTree】作業ツリーのファイルを無視したいのに無視が選択できないのはソース管理されているから

環境

SourceTree
Windows 10

やりたいこと

無視したいファイルがあるのに無視できない...
.gitignoreに書いても意味無し...何故?

sourcetree.jpg

やったこと

解決法は単純極まりないです
対象がソース管理下のファイルだったので管理から外すと無視設定できました


対象ファイルを右クリックし表示されるメニュー(上記やりたいこと参照)から
「追跡をやめる」→削除しますか?ダイアログの「OK」

sourcetree2.jpg

(削除の文言が怖いですがファイルは残っています)

Indexにステージしたファイルにアイナス表記で対象ファイルが表示され、
作業ツリーには疑問符表記で同ファイルがあるのでソース管理から外れた状態になっている

対象ファイルをコミットして削除コミットを作成
コメントには管理から外した旨を書いていればいいかと

無視が選択できるようになっている

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

rebaseを用いたコンフリクト解消方法

はじめに

git rebaseを使用すると,きれいな一直線の歴史を保った状態で,分岐したブランチの統合を行うことができます.コンフリクトの解消を行う際によく使用するのですが,毎回調べてしまうのでメモっておきます.

1. 結論

先に結論をまとめておきます.

手順
① $ git checkout topic-branch
② $ git rebase {rebase先のコミットハッシュ}
③ コンフリクトの解消
④ git add 対象ファイル
⑤ git rebase --continue
# ③ ~ ⑤繰り返し
# rebase中にやばいと思ったら $ git rebase --abort

ここからは,上記の方法について解説していきます.
内容を理解できた方は,読み進める必要はありません.

2. rebaseの基本

まずrebaseの基本的な概念を確認しておきます.
masterブランチからfeatureブランチが派生し,それぞれmasterブランチで行った作業②④とfeatureブランチで行った作業③⑤がコミットされています.

merge.png

2.1 rebase

それでは,rebaseを用いたブランチの統合について解説していきます.まず,featureブランチをmasterブランチにrebaseします.①から派生した③が右にスルスルッとスライドして派生元を④に置き換えたイメージです.
(派生元が変わりコミットハッシュの値が変わるので'をつけています)

merge (4).png

次に,masterブランチからfeatureブランチをmergeする(fast-forward マージ)することで,マスターブランチは一直線のスナップショットを保ったまま,featureブランチ上の作業を取り込むことができます.
merge (5).png

2.2 merge

比較を行うために,同じ例を使用してfeatureブランチ上の作業をmergeで取り込んでみます.2つのブランチの最新のスナップショット④⑤を含んだ⑥が新しく作成されコミット(マージコミット)されます.
merge (1).png

mergeとrebaseを見比べてみると,rebaseを使用したほうがログが一直線できれいになっていることが見て取れます.

merge rebase
スクリーンショット 2019-12-22 11.36.24.png スクリーンショット 2019-12-22 11.51.23.png

3. rebaseを用いたコンフリクトの解消方法

以上のrebaseの概念を踏まえてコンフリクトの解消を行っていきたいと思います.基本的に操作は同じです.途中でコンフリクトを解消する操作と,リモートブランチに対する操作が入ります.

3.1 シチュエーション

チーム開発を行う時に,起こりうるコンフリクトのよくあるパターンとして,次のような例が挙げられます.

merge (7).png

統合ブランチであるmasterからAさんがトピックブランチfeature/A,Bさんがfeature/Bを作成し,作業を行います.

Aさんは,すでにfeature/A上での作業を完了し,②③をコミットした上で,masterブランチにマージしています.

Bさんもfeature/Bブランチ上での作業を終え,GitHubにプッシュし,feature/Bからmasterに向けたPull Requestを作成しました.しかし,④のコミットでの作業が,Aさんが③で行った作業と同一のファイルに対する操作を行っていたため,コンフリクトが発生しました.

スクリーンショット 2019-12-22 15.14.21.png

3.2 rebase先のコミットハッシュの取得

それではrebaseを用いてコンフリクトの解消を行ってみます.
feature/Bの分岐元をmasterの①からマージコミットの⑤にrebaseします.

最初に,リモートの作業履歴をローカルへ同期しておきます.

ターミナル
$ git checkout master
$ git pull origin master

# もしくは

$ git fetch --all

feature/Bの分岐元をmasterの①からマージコミットの⑤にrebaseしたいので,⑤のコミットハッシュを確認しておきます.

ターミナル
$ git checkout master
$ git log  --oneline
0ec4a5f (HEAD -> master, origin/master) Merge pull request #1 from takeru56/feature/A
f8a2c27 (origin/feature/A, feature/A) Add commit 3
aedc61b Add commit 2
5e28155 Add commit 1

⑤はマージコミットなので,一番上の0ec4a5fに対応します.
rebaseに渡す引数はブランチ名でも良いのですが,コミットハッシュを使用することで,ミスを減らすことができます.

3.3 rebaseの実行

続いて,rebaseを行います.
以下のコマンドでrebaseを実行します.

ターミナル
$ git checkout feature/B
$ git rebase 0ec4a5f
First, rewinding head to replay your work on top of it...
Applying: Add commit 4
Using index info to reconstruct a base tree...
M   file1.txt
Falling back to patching base and 3-way merge...
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
error: Failed to merge in the changes.
Patch failed at 0001 Add commit 4
hint: Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".

上記に記述してあるようにfile1.txtにてコンフリクトが発生しています.

file1.txt
Hello Git! This is commit 1.
<<<<<<< HEAD
Hello Git! This is commit 3 by A.
=======
Hello Git! This is commit 4.
>>>>>>> Add commit 4

ファイルを開いてコンフリクトを解消してあげましょう.

file1.txt
Hello Git! This is commit 1.
Hello Git! This is commit 3 by A.
Hello Git! This is commit 4.

ファイルの修正が完了したら,以下のコマンドでrebaseを続けます.
変更したフアイルをgit addgit rebase --continueします.
コミットする必要がないことに注意しましょう.

ターミナル
$ git add file1.txt
$ git rebase --continue
Applying: Add commit 4

これらをrebaseが完了するまで繰り返します.
Applying: Add ~が出力されたら,rebaseの完了です.

merge (8).png

正しく完了した場合,上記のように④を⑤からの分岐にrebaseできているバズです.
最後に,GitHubにpushしてmasterに対してfast-forwardマージしてあげれば,無事にfeature/Bブランチをmasterに取り込むことができるはずです.

④のコミットハッシュが書き換わっているので,-fオプションを付けてpushする必要があります.

ターミナル
$ git push -f origin feature/B

スクリーンショット 2019-12-22 16.22.36.png

注:rebase中になんかやばいなと思ったら

ターミナル
$ git rebase --abort

上記コマンドでrebaseを中断し,rebaseを行う前に戻ることができます.

4. まとめ

rebaseを使用することで,コミット履歴を直線に保ったまま,ブランチを統合し,コンフリクトの解消も行うこともできました.
しかし,他の文献でも触れられているように,分岐元が変わることでコミットハッシュの値が書き換わってしまい,歴史を改変することになります.それによって,チーム開発において問題が発生することも多々あるようです.統合ブランチはもちろんのこと,複数メンバーで使用しているトピックブランチにおいては,rebaseは行わないほうが無難かもしれません.

参考文献

git:Dockumentation > Git のブランチ機能 - リベース 
サルでもわかるGit入門

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

ランサーズ創業時から今まで12年分のコミットをビジュアライズしてみた

はじめに

ランサーズ AdventCalendar 21日目担当の @sayanet です。

ふだんはtoBの LancersEnterprise プロダクトの開発チームリーダーとして、プロジェクトマネジメントを行っています。最近プロダクトマネジメントもはじめました。

ハイ、さっそく本題にはいります!
私がランサーズに入社したのは2014年4月で、その頃はまだメンバーは50名に満たない規模でした。
今回、上場という節目においてここまでの軌跡をなにかの形で残しておきたいなと思い、主に Lancers の開発を行っているリポジトリで創業から今までの約12年(2008-2019)にわたるすべてのコミットをビジュアライズしてみました。
今回は公開用として、創業者兄弟である秋好社長&聡さんと著者以外はイニシャルにしています。

つくりかた

1. コミットログの取得

git shortlogを利用してユーザーごとのコミット数を取得します。

例えば今月のコミットをユーザーごとにリストアップしたい場合はこんなかんじです。

git shortlog -sn --no-merges --since='date +%Y/%m/01' --until='date +%Y/%m/%d'

オプション説明
-s: ユーザー毎にサマライズ
-n: コミット数多い順にソート
--no-merges: マージコミットは除外
--since: 対象期間いつから
--until: 対象期間いつまで

出力結果
コミット数合計とユーザー名が表示されます
image.png

さてさて、今回は年ごとにサマった述べコミット数がほしいので、創業から今年まで年単位でループをまわします。
それぞれの年に過去合計値をセットしたいのでsinceオプションは2008年固定にしておくのがミソ。

for ($year=2008; $year<=2019; $year++) {
    echo $year . "\n";
    $command = sprintf("git shortlog -sn --no-merges --since='2008/01/01' --until='%d/12/31'", $year, $year);
    system($command);
}

2. データを整形する

1で取得したユーザーごとのコミット数をスプレッドシートに貼り付けて整形。年とユーザー名をマトリクス表で表現していきます。

こちらがベースとなるデータ。年とユーザー名を結合させて下ごしらえ。
※ yosuke->秋好社長、satoshi->聡さん です。他の方はマスキング
image.png

年とユーザー名をもとにVLOOKUP使ってマトリクス表のシートにプロット。

image.png
ここで予期せぬ事態。同一人物でもコミット時のユーザー名が異なることが多々あり、名寄せするのが大変でした。仕組み化するならメアドを使って名寄せするとかうまいことやりたい。

さて、ここまでできればデータ整形完了!
このタイミングでユーザー名をイニシャル化にしています。

3. ビジュアライズする

ビジュアライズにはFlourishのBar chart raceを使いました。
https://app.flourish.studio/@flourish/bar-chart-race/9

Dataにスプレッドシートの内容をそのまま貼ればOKというお手軽さ。職種で色分けしたかったのでカテゴリー追加しています。

Previewモードで件数や速さなど表示の設定ができます。
動きを確認しながら調整できてトテモ便利 :angel_tone2:

image.png

デキアガリ\(^o^)/

image.png

APIも公開されていて捗りそうです :bar_chart:
https://app.flourish.studio/@flourish/bar-chart-race/9#api

まとめ

後半のデザイナーT.Tさんの伸びがすごかったです。コミット数が多い方は総じて仕事のスピードが早いなという印象。ちなみにT.Tさんからはプログラマーはプログラムを書くな! 有能なプログラマーはプログラムを書かないリンクをそっと渡されましたがそれもまたひとつの謙虚スタイル。リスペクト。

エンジニア出身の社長が今でもTOP17に残っているのを見て、ほんとうに創業時はめちゃくちゃエンジニアフルコミットだったんだなと思ったり、私が入社した2015年頃にメンバーが一気に増えてベンチャーの勢いを感じたり、最近入社したメンバーがガンガンコミット伸ばしていることに気づけたりとなかなかの感慨深さがありました。

もちろん、コミットの単位は時期や実装者・チームによって異なるし、fix:typoなどもあるため多いからよいとは一概にいえませんが、純粋にこれだけコミットしたのすごいな〜という意味合いで見ています。

ソースコードは日々刷新されますがコミットに込めた気持ちとビジョンが受け継がれて今のランサーズがあるんだなと再認識。日々の積み重ねって偉大ですね。

年末なので、一年の振り返りとして月ごとに出してみても面白そうだし、毎日眺めてがんばったなーとムフフするのも楽しそう。

それではみなさん、良いエンジニアライフを!

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

大学のサークルでGitbucketとGitを使ってゲームコンテンツをチーム開発をしてみた

めっちゃ遅れましたが計算研カレンダーの1日目の記事です。

1. はじめに

1.0. どういう記事か

大学サークル「計算研究会」で大学祭に向けて「GitbucketとGitを使ってゲームコンテンツをチーム開発をしてみた」ので、そのことについて書きたいと思います。

本記事は計算研で本年度行った開発方法を記事化して残し来年度に活かすという目的と我々と同じように大学サークルや趣味でゲームやサービス開発をしようと思っている方々に「こういうやり方である程度うまくいったよ」という知見を共有する目的で書かれています。GitやGitbucketを少し触った人であれば読んでもらうことができると思います。「もっとこうした方がいい」や「ここの定義間違ってるよ」とかがあればコメントをお願いします。

1.1. 参加メンバーの雰囲気

開発時のメンバーは大体2種類ぐらいのグループに分けることができて

  • 「Git触ったことがある」という人が1/3
  • 「Git全く触ったことない」という人が2/3

という構成でした。プログラミングに関しては全く触ったことがないという人はいませんでした。

2. ツールとその他用語解説

どの様に開発したのかを述べる前にチーム開発で用いた際のツールやその他用語について述べたいと思います。ツールの説明に関しては使い方の説明というよりも

  • そもそもどういう立ち位置のツールなのか
  • メリット

等の説明を行います。

2.1. Git とは

Gitとはフリーオープンソースの分散バージョン管理システムです。(公式定義

バージョン管理システム自体はあるファイルが

  • いつ
  • 誰が
  • どの様に

変更したのかを履歴として記録しておくものです。

Gitはリポジトリという単位でファイル群をまとめて管理します。またファイルの変更履歴はコミットという単位で管理されます。

またリポジトリも以下の2種類に分かれます。

  • ローカルリポジトリ・・・ユーザ一人ひとりが利用するために、自分の手元のマシン上に配置するリポジトリ
  • リモートリポジトリ・・・専用のサーバに配置して複数人で共有するためのリポジトリ

by 履歴を管理するリポジトリ|サルでもわかるGit入門【プロジェクト管理ツールBacklog】

最新版がどれなのか・いつのバージョンと違いどのような変更が施されているかを簡単に追跡することが可能です。(最新版、final版、最新版2というファイル分け管理による地獄をみなくなります。)

誰が変更したかを確認することができるため、どうしてもコード上で変更の意図が確認できなかった際、どの様な意図で変更したのかを問い合わせることができたりします。

他にも

  • バージョン巻き戻し機能 (reset、checkout) により修正機能が簡単で正確に
  • 変更履歴の分岐・統合 (branch、merge) による並行作業が柔軟に
  • プロジェクトの共有 (push、clone) が簡単に

など開発上でいいことづくめです。

2.2. Gitbucket とは

GitBucketとは、オープンソースにて開発されているGitをインターネット上で管理するプラットフォームである。

by wikipedia

感覚的にはGithubのようなネットでリポジトリを管理するシステムと同じようなものですが、相違点としてはGitbucketは自前でサーバーを設営することができ、使用の際に機能制限がなかったりプラグインを好きに導入できたり融通が利きます。

このシステムを使うことで簡単にリモートリポジトリを作成・管理・複製できます。Forkすることによりあるリモートリポジトリを他のリモートリポジトリとして複製することができます。この複製されたリモートリポジトリ同士でPull Requestというものを送り合って変更を柔軟に共有し合うことができます。

2.2.3. Fork とは

上記で若干解説しましたが、やったことを説明するためにもう少し詳しく説明します。

「フォーク」(Fork)はリポジトリのコピーです。 リポジトリをフォークすることにより、オリジナルのプロジェクトに影響を与えることなく変更を自由にテストできます。

by リポジトリをフォークする - GitHub ヘルプ

とGithubの公式で言われています。これをもう少しかみ砕いて見ます。GithubやGitbucketではユーザーがリモートリポジトリに紐づいています。同じリポジトリを複数ユーザーで編集していくことは可能ですが、これには以下のような不便が伴います。

  • 他のチームメンバーと、ブランチ名の衝突の可能性がある
  • 途中結果をなにかの問題を議論するため一時的に共有する際他プログラマの作業を妨害してしまう可能性がある。または妨害になった場合、途中結果が消される可能性がある

そこでForkを使って自由に作業結果をPushできるリポジトリを複製してしまうことで、上記の不便をなくし柔軟に作業を行うことができます。

複数ユーザーに紐づいているリポジトリをユーザーごとに紐づいたリポジトリに分散させています。作業の途中結果をアップロードすることが容易になります。

2.2.4. Pull request とは

プルリクエストとは、コードの変更をレビュワーに通知し、マージを依頼する機能です。

by GitHubでのプルリクエスト活用方法まとめ - ICS MEDIA

このPull requestを使うとブランチ間で変更を共有依頼を出すことできます。これはForkしたリポジトリ間でも出すことができ、これによって先ほど分散させたリポジトリ間で作業成果を共有することができます。

これを用いて分担して作業を行っていたプログラマの間で成果を結合することができます。

2.3. Trello とは

Trelloはプロジェクトをボードで整理できる、コラボレーションツールです。Trelloを使えば、現在の作業対象、作業しているユーザー、進行中の領域を確認できます。

by What is Trello? - Trello Help

いわゆるTodoリスト管理ツールです。複数で一つの管理ボードを共有することが可能で、タスク一つに人を割り当てることができ、名前ではなくアイコンであるため見慣れてくるとすぐ誰がやっているのか?誰がやる予定なのか?がすぐ認識できるようになります。

GUIは図のような感じです。

trefig4.png

3. 基本的な開発フローとリポジトリ構成

ツールの確認が終わったところで今回我々がやったことをを紹介したいと思います。

最初に開発フローの概観として我々が大学祭の開発で行った基本的な流れは

  1. 設計書及び仕様書から抽出したタスクをTrelloで発行
  2. コーディングに入る前や作業前に中央リポジトリ(リポジトリ構成で解説)の内容を取り込み
  3. 指定された<機能名>-devブランチを切ってコーディング開始
  4. (必要であれば)途中結果を自分のリモートリポジトリにPushし議論
  5. 作業が終わったと思ったら中央リポジトリ/developブランチにPull request
  6. リーダーや設計をした人がOKと感じたらMerge
  7. だめなら修正のコメントをPull requestに付与してリテイクしてもらう

という感じで、これを何度も繰り返してプロダクトを作成していきました。

3.0. リポジトリ構成

流れを確認したところでプロジェクト進行中でリモートリポジトリやブランチが大体どうなっていたかを紹介します。

Gitbucket側のリモートリポジトリの構成は

  • 中央リポジトリ・・・ここにある程度できあがった作業結果がMergeされる。このリポジトリをforkして作業用リポジトリになる。他の人の作業結果が共有されるときはこのリポジトリの内容をclone、fetch、pullして共有する。
  • forkした作業用リポジトリ・・・作業途中な作業結果もpushできる。

という風になりました。リーダーや設計者の人が中央リポジトリのオーナーにし、その他プログラマやモデラ等の作業者がForkした作業用リポジトリのオーナーにしました。

オーナーとはそのリモートリポジトリに自由にPushできたり、送られたプルリクエストをマージできる人です。

また中央リポジトリのブランチは大体

  • master・・・完成品、プロトタイプ
  • develop・・・機能開発用ブランチ
  • 3dassets-develop・・・3Dモデルのリソース共有用ブランチ

しかありませんでした。

forkした作業用リポジトリのブランチ構成は大体以下の構成でした。

$ git branch -a
master
develop
foo-dev
bar-dev
remotes/origin/master -> origin/master
remotes/origin/develop
remotes/origin/foo-dev
remotes/upstream/master
remotes/upstream/develop
  • remotes/originなんとかが作業者自身のリモートリポジトリを追跡するブランチ
  • remotes/upstreamなんとかがプロジェクトの中央リモートリポジトリを追跡するブランチ

です。

3.1. Trelloでタスク発行

もう少し詳しく開発フローを見ていきます。まず、タスクの発行ですが、以下のスクショに示したような設計書や仕様書(ざっくりとしたクラス構成やデータ、見た目等を共有するためのドキュメント)から現在作成できる部分を適宜抽出し

コメント 2019-12-21 235102.png

以下のようなチケットとしてTrelloに発行します。

trefig3.png

これを作業者が読み、作業に入ります。作業者のGit活用能力に差があったので、最初のうちは「ここでfetch してmergeしてbranchしてcheckout」というようなコマンドをTrelloのチケットに書き込んだりしていました。

3.2. fetch & merge して branch

次に依存する他作業者の完了済み作業結果等をローカルに取り込むため以下のコマンドを用いて、中央リポジトリの情報をローカルリポジトリに取り込みます。

$ git fetch upstream
$ git checkout develop
$ git merge upstream/develop

その後、割り当てられたタスクの内容に従い作業用のbranchを切ります。

$ git branch cool-feature
$ git checkout cool-feature

その後チェックアウトを行い実際にコーディングを行います。

3.3. Pull request & Merge

ここからは作業者がまずプルリクエストをforkリポジトリの該当ブランチから中央リポジトリの該当ブランチにだします。

作業者がやること

指定された成果物ができあがったらプルリクエストを送ります。まず作業者がForkしたリポジトリに作業内容をPushします。

$ git commit 
...適当にコミットメッセージ等を書く...
$ git push origin cool-feature

次にgitbucketをブラウザで開き該当リポジトリのPullRequest一覧を開き、プルリクエストを発行します。

pull request issue.png

中央リポジトリオーナーがやること

プルリクエストがだされたら中央リポジトリのオーナーは発行されたPullRequestをレビューしOKそうかチェックします。大丈夫そうならマージ。そうすると中央リポジトリのdevelopやmasterに作業結果が取り込まれます。

4. やってみて思ったこと

セクション3で紹介した流れを実際のVRコンテンツ開発で実施してみて思ったことを述べたいと思います。

11月の大学祭に間に合ってある程度体験に耐えうるシステムをつくることができたので、おおむねうまくいったと思います。その要因や今後の改善点として特におもったことを述べます。

4.1. 作業者が自分専用のリモートリポジトリを持つことで中央リポジトリが壊れづらくなる

1つのリポジトリに全ての作業者を押し込んでしまうと、誤ってdevelopやmasterにpushしてしまう等が起こったとき開発全体に影響が及びます。(pushする際の権限設定等をきちんと設定すれば別ですが、gitbucketを用いてチーム開発を行うのは初めてであったため、より簡単でわかりやすくそのような事故を抑止する手段としてForkを用いました。今回はgitに不慣れなメンバーも参加していたため、そういった事態が容易に発生しうると思いました。)

自分専用のリモートリポジトリを持つことでもしそのようなことがあっても開発全体がとまることがありません。開発全体の作業結果を管理する中央リポジトリには大丈夫だと判断されたPull requestしかマージされないため、そのような事故の確率が格段に下がったと考えます。(レビュワーがガバったりした場面がありましたがね。)

今回はLFSを一時的に併用していましたが、LFS回り以外では中央リポジトリが壊れ開発に支障がでることはほとんどありませんでした。

4.2. タスク分割 & 割り当てに注意

タスク分割単位があまり適切でなく、コンフリクト率があがってしまった場面がありました。

同一のソースファイルに複数のメソッドが記述されており、そのメソッドの実装を複数人で分担した時のことです。以下のような原因でコンフリクトをおこしました。

  • Visual Studioのコード成形機能を用いて無意識に自分の担当外の場所を修正していた
  • 他の人が命名を変更したフィールドを前の人が前の命名のまま使ってしまった場面があった(効率化のため最低限のprivateメソッド、フィールドの命名を指定するというルールを敷いていたため)

同一のソースファイルをいじるタイプのタスク分配はできるだけ少人数に抑える必要があると感じました。また、可能であれば設計段階で機能を細かく分割する工夫が必要だと思います。そういった「クラスに対する機能が多すぎないか」等の設計を再考するフェーズをもう少しちゃんととればよかったかなと思います。

4.3. LFS

ゲームコンテンツ開発を行ったのでバイナリでリソースを扱う場面が開発当初で出てきたため、Git-LFSサーバーを用意し運用しました。しかし、運用が思った以上に難しく何度か開発がとまってしまうことがありました。

例を挙げればgit lfs init してない作業者がgit cloneを叩いてしまい、pushできない等の現象が多発しました。

後半はLFSを切り離し、そのリソースを管理する際はUnitypackageとしてエクスポートした状態で各自の環境にインポートするという方法をとりました。

今後もしLFSを導入する流れになったら、その作業を行う前にきちんと調査や勉強会、運用方法の検討を行う必要があると思いました。

4.4. ブランチをもう少し工夫した方がいい気がした

中央リポジトリの管理はGitbucketとGit本体に関しては重大な問題は起きませんでしたが、作業者個々のリポジトリ管理の方法にはもう少し改善の余地があるように思いました。

例を挙げれば、個人のdevelopブランチにそのまま作業をコミットしてしまい、作業用のブランチが切られないという状況が結構あったように思います。(このあたりは個人のリポジトリ操作であるためある程度自由にやってもらってかまわないと思いますが...。)

作業用のブランチを切ると

  • 最初に考えたときの実行方針が難しいと判断した場合のリカバリをしやすい
    • ブランチを切っていればブランチを消してもう一度はやすだけで済む
    • git reset等でさかのぼらなくてもよい
  • 作業途中で別の修正等が入った場合、すぐにその作業に移ることができ、終わり次第すぐに復帰できる
    • ブランチを切っていれば、developから修正ブランチを新たにはやすだけで済む
    • 復帰の際はcheckoutのみで済む
    • 余計な作業結果を含むPRはレビューが非効率的になる

といった風に開発フローを柔軟にしたりやミスを防ぎやすくなると思います。今後はもう少し効率の良いGit運用ノウハウについて調査し、共有していきたいと思います。

4.5.レビューをもうすこしちゃんと

プルリクエストをマージする際、ガバガバなレビューを行い

  • 余計なディレクトリをマージしてしまったり
  • あるレビュワー的にはまずい変更をあるレビュワーが勝手にマージしてしまったり

等で余計な修正作業がはいってしまった場面がありました。これは複数人のレビューのApproveを受けて、初めてマージされるという機能がGithubにあるそうなので、次回の開発環境でこのような仕組みを用いることができたらぜひ使ってみたいと思います。

プルリクエストの必須レビューを有効にする

リポジトリの管理者は、必須レビューを施行し、プルリクエストのマージ前に特定の数の承認レビューが必要になるようにできます。
by プルリクエストの必須レビューを有効にする - GitHub ヘルプ

他にも規約としておそらく最低限のチェックリスト等をつくることはできると思いますので、導入を検討したいです。

4.6. 小ネタ

今回の開発で便利だなと感じたgitの機能としてaddコマンドの-pオプションがあります。

git add -p

同一のコミットに大量の変更があると、コミットメッセージのどこの内容がどのコード変更に対応してるのかを追うのが難しくなります。これを用いると「あ!w、コミット刻むのわすれてた!w」となっても、あとで変更を細かいコミットに刻むことができます。

これによってあとあと「ここからここのコミットをみればなに変更したかわかるから」といった報告が簡単で比較的低コストでできるようになりました。

詳細な使い方は 横着で神経質な私とあなたに贈るgit add -p - Qiita がわかりやすいです。

5. 来年に向けて

本格的な開発に入る前に、開発メンバー全員に簡単なGit + Gitbucket操作のチュートリアルを行ってもらいました。内容としては「clone、commit、add、push、pull」コマンドを使うものでした。しかしPull requestやfetch等の学習が漏れており、口頭で一部メンバーに慌てて学習を補完するというのをやったり、タスクチケットにコマンドを直接書き込む等を行いました。

これはさすがにスマートでないため、来年は今回漏れた部分も網羅できるような勉強会とチュートリアルを開発メンバーに行ってもらう予定です。

また他のwebサービス等の開発もバージョン管理システムを用いて行って行きたいです。その際にCD/CIツールの導入も行いたいです。


参考文献

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