20200314のGitに関する記事は5件です。

OSSで開発する時は真っ先にブランチを切ろう

まとめ

初めてのOSS参加だったんですが、ブランチを切り忘れた結果別イシューの開発ができなくなってしまいました。そこでforkしてきた自分のリポジトリだからいいだろうとgit push -f をしたら承認済みのPRまで消えてしまって焦ったという話です。push -fは使わないようにしよう。

背景

今東京都とCode for Japanが一体となって作っている新型コロナウィルス感染症対策サイトに自分も参加していました。

https://github.com/tokyo-metropolitan-gov/covid19

Code for Japanの活動に去年からちょくちょく参加していましたが、サービス設計やデータ整備の部分を多くやっていたのでgitを使った集団開発はかじったことがある程度、、でした。なのですがQiitaに素晴らしい記事が公開されていたので初OSS参加やってみようと思い立ちました。

OSS参加のための素晴らしい記事
https://qiita.com/FPC_COMMUNITY/items/b9cc072813dc2231b2b2#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB

無事に初PRも承認されて、意気揚々と別のイシューに取り掛かったんですがそこでちょっとした問題が発生しました。

起こったこと

ブランチを切らずにdevelopmentで開発をしてPRを投げた自分、2つ目のissueにどう取り組むんだ?という疑問に突き当たりました。

スクリーンショット 2020-03-14 17.34.43.png

このままdevelopmentにcommitしたら、そのコミットまでが1つ目のPRに乗ってしまいます。そこでようやく「集団作業の時は作業ごとにブランチを切れ!」という大原則を思い出しました。
本来はイシューを始める段階でブランチを切って開発して、そのブランチからPRを出すのが正解だったんですね。Developmentブランチは常にfork先の状態と一致させておく運用の方が直感的でわかりやすいです。

今からでも遅くはない、修正しようと思って行ったのが次の手順になります(結果面倒なことになったので真似しないでください)。

  1. ローカルブランチでIssue 1に取り組む前のコミットまで戻る
  2. ブランチを切ってnew-issue-1ブランチにIssue 1に関するコミットをcherry-pickを使って移動する
  3. 自分のリモートリポジトリのnew-issue-1ブランチにpushする
  4. developmentブランチに戻り、git reset --hard (コミット番号)でIssue 1に関するコミットログを消す
  5. (大戦犯)git push -f でリモートのdevelopmentブランチを元に戻す

スクリーンショット 2020-03-14 17.52.47.png

自分のリポジトリには自分しかコミットしないしforce-pushしていいだろ〜とか軽く考えていたんですが、、、

結果承認済みだったIssue 1のPRが自動で閉じてしまいました・・・

プルリクエストは個人のリモートのdevelopmentブランチからfork先のリモートのdevelopmentブランチに送られているので、個人のリモートのdevelopmentからログが消えたら自動でプルリクエストは閉じる仕様になっていたようです。「せっかく通ったはずのPRを勝手にcloseさせてしまったショック」に数分打ちひしがれていたのですが、事情を説明してすぐにnew-issue-1ブランチからPRを送り直しました。

集団開発の時は必ずローカルのブランチを切ってから作業しましょう!
後OSS参加楽しいので是非みなさんもやりましょう!

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

[WSL Debian] Gitのコマンドの入力補完を有効にする

概要

WSL版のDebian(以下,WSL-Debian)にて,Gitのコマンドの入力補完を有効にする.ただし,ここでのGitとは,WSL-Debianのaptを通してインストールしたものを示す.

「WSL-Debianのaptを通してインストールしたGit」とは

下のようなコマンドでインストールしたGitのことを示す.つまり,Git for Windowsは対象としない.

Install_git
sudo apt install git

動作確認した環境

動作を確認した環境は以下の通りである.

Environment
$ cat /etc/debian_version
9.12
$ uname -a
Linux DESKTOP-7IQQAG7 4.4.0-18362-Microsoft #476-Microsoft Fri Nov 01 16:53:00 PST 2019 x86_64 GNU/Linux
$ git --version
git version 2.11.0

結論

下に示すように,aptを通して,bash-completionをインストールする.

Install_bash-completion
sudo apt install bash-completion

なお,これを実行すると,aptをはじめとする他のコマンドの入力補完も有効となる.

結論に至った経緯

/usr/share/bash-completion/completions/の下に,Gitをはじめとするコマンドの入力補完のためのスクリプトがあるにもかかわらず,これがシェルに反映されないことを疑問に思い,試行錯誤してみた.

WSL-Debianは,初期設定において,bash-completionがインストールされていないため,補完スクリプトがあるにもかかわらず,これらが反映されないようである.

参考文献

bash-completionでserviceコマンドなどの補完を強化しよう

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

ソースコードのパッチを送るためのGmail (G Suite)・Thunderbirdの設定

English

GitHubでホストしていない古いプロジェクト(GNUとかGNUとか)を触っていると、コミットする手段がメールなことがしばしばあります。オープンソース活動にGmailをお使いの方は多いと思いますが、Gmailのwebメーラーでパッチを送ると、勝手にタブをスペースに変換するわ削除するわでまともに使えません。

patch collapsed via web Gmail

$ git apply < patch.txt
error: patch failed: gdb/ChangeLog:1
error: gdb/ChangeLog: patch does not apply
error: patch failed: gdb/darwin-nat.c:1985
error: gdb/darwin-nat.c: patch does not apply

そこでwebメーラーではなくメールクライアント (MUA; Mail User Agent) からGmailを使ってやる必要があります。

メーラーの選定

TL;DR: Muttに慣れている人はMuttで、それ以外の人にはThunderbirdをオススメします。

gitのパッチを送る場合に限ってはgit-send-email(1)を使うという手もあります。ググればやり方が沢山出てきます。Linux kernelにパッチを送る際の推奨手段でもあります。

この記事では cvs diffsvn diff、その他 unified diff (diff -u) 形式のパッチを送ることを想定します。

まずLinux kernelドキュメントgit-format-patch(1)に載っている全メーラーを調べてみることにしました。選定基準は:

  • オープンソース
  • 継続して開発されている。Gmailの仕様は頻繁に変更される(例えばパスワード認証はデフォルトで無効になったり)のですぐに対応できるソフトウェアが望ましいです。
  • パッチを送っている人が多い。エラーをググればすぐ出ると期待されるので。

ググった結果:

Search keywords GUI or TUI # results as of 2020/03/13
"git am" Mutt TUI 11,800
"git am" Thunderbird GUI 11,600
"git am" Alpine TUI 5,300
"git am" KMail GUI 1,650
"git am" Claws Mail GUI 2,270
"git am" TkRat GUI 252
"git am" Sylpheed GUI 262
"git am" Evolution (run only on Linux) GUI 11,900
"git am" outlook (non open source) GUI 6,690
"git am" apple mail (non open source) GUI 7,850
"git am" "apple mail" (non open source) GUI 101

まずMuttを試してみましたが、authentication failed みたいなエラーが出て、ググって解決しなかったのでやめました。Muttのスペシャリストになるのに時間を費やしたくない。

次にThunderbirdを試した結果サイコーでした。多くの人がパッチを送っているようだし、ググれば全部出る。

GmailのIMAPを有効にする

設定で Enable IMAP します。

enable IMAP in Gmail's Setting

Thunderbirdでアカウント追加

FileNewExisting Mail Account...

add Gmail's account on Thunderbird (1)

任意の名前とGmail (foo@gmail.com) か G Suite (foo@foo-organization.com) のメールアドレスを入力して Continue。今は Password は入力しなくてOKです。

add Gmail's account on Thunderbird (2)

Manual config をクリック。

add Gmail's account on Thunderbird (3)

AuthenticationOAuth2 になっていることを確認して Done

add Gmail's account on Thunderbird (4 Google OAuth)
add Gmail's account on Thunderbird (5 Google OAuth)

Google (G Suite) のパスワードを入力。

add Gmail's account on Thunderbird (6)

残念ながらエラーになりました(そのうち直ると思います)。

  • User name or password invalid
  • Configuration could not be verified ― is the user name or password wrong?

とりあえずパスワード認証することにします。

パスワード認証

Thunderbird の設定画面は開いたままにしておいて下さい

パスワード認証を行うためには less secure app access を有効にする必要があります。

G Suiteをお使いの場合(you@gmail.com でなく you@your-company.com でGmailをお使いの場合)G Suiteの管理者がこちらの設定を行う必要があります。

(G Suite) Allow users to manage their access to less secure apps

Less secure app access
settings
Allow less secure apps をONにします。アカウントは右上のアイコンで切り替えられます。

turn on: Allow less secure apps

Thunderbirdに戻り Normal password を選んで Done

add Gmail's account on Thunderbird (7)

これでメールが受信できるはずです ?

format=flowed を無効にする

しかしまだThunderbirdがパッチを壊しちゃいます。git-format-patch(1)に従い、

  • EditAccount SettingsComposition & AddressingCompose messages in HTML format のチェックを外す
  • EditPreferencesAdvancedConfig Editor...
    • mail.wrap_long_lines: false
    • mailnews.wraplength: 0
    • mailnews.send_plaintext_flowed: false

これでメールのヘッダーに format=flowed が付加されなくなります。

To: bar@gmail.com
From: Wataru Ashihara <foo@gmail.com>
Subject: test
Message-ID: <***@gmail.com>
Date: Mon, 9 Mar 2020 19:48:53 +0900
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101
 Thunderbird/60.9.0
MIME-Version: 1.0
Content-Type: text/plain; charset=utf-8; format=flowed
                                       ^^^^^^^^^^^^^^^ this removed!
Content-Language: en-US
Content-Transfer-Encoding: 7bit

body

パッチを壊さずに送信できるようになりました。

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

git(ギット)が一体何なのかがわからなくなってきた君へ

はじめに

本記事は共に開発を行う同僚や友人に向けて、gitおよびgit(hub)-flowに対する理解を深めるために用意した文書を公開したものです。筆者の個人的な思想や、厳密には正しくない、適切でないとされる表現が多分に含まれます。ご留意ください。

あなたの問題を解決する具体的なコマンドや導入実例などの参考データはなく、概念について深掘りした説明をしていますので、精神的、時間的に余裕のない方は読むのをお控えください。
また、gitの仕様や活用事例に関する解説(コミットとは、プッシュとは、ブランチとは、プルリクとは、CIとは...etc)については心のこもった秀逸な記事が星の数ほどありますので、是非そちらをご覧ください。

gitとは何者なのか

プロジェクトの開発を進めるうえで、プログラムコードの修正や素材の追加などの進捗があった際、”ファイル更新に事故が起こらないように 助ける ”ことを目的としたソフトウェアである。
平成の成熟期~衰退期から令和の黎明期にかけてのプログラム開発において、最適なスキーム、選択肢であるとされている。

gitが提供する管理システムは「バージョン管理」と呼ばれ、プロジェクト全体の「今の状態」をファイル単位で監視することにより、監視を始めてからのこれまでの瞬間を年表のように遡ることができる。
これにより、「1つ前の更新状態に巻き戻す」「特定の瞬間の更新内容をつまんで取り出す」「別の可能性を入れ込んだコピープロジェクトを平行して走らせる」といった柔軟な作業体制を実現する。1

gitの何が良いとされているのか

gitの良さは「プロジェクトの瞬間をファイル単位で管理・保存できること」である。しかし、それ自体には実のところ大した意義はない。気をつければファイルの破壊や消失は防げるし、時間をかければ壊れたものはまた生み出せる。ハードディスクの容量がないならば、何千、何万という差分をいちいち保存してもいられない。約束の期日に間に合わなかったとしても、邪悪な竜が復活して世界が3つに引き裂かれるわけではない。しかし、gitが生まれるまでの経緯には、gitが待ち望まれた救世主であるかのように讃えられる十二分な歴史があった。

バージョン管理の概念がなかった頃、コンピュータの中のファイルを共同作業で更新するという工程は阿鼻叫喚と疑心暗鬼の渦巻くカオスの世界であった。無秩序にいつの間にかファイルが更新され、道を歩けば作業が競合し、掴もうとした縄梯子は解け、時に踏み出そうとした足場が足をついた頃にはなくなっている事さえある。
要は、何かの手によって破壊される可能性がある不可逆変化の世界であった。2

gitはこれらの不可逆で実直で荘厳で真実で不条理な「諸行無常、盛者必衰の壊れる世界」にひとすじの光をもたらした秩序の道筋である。先行きはまばゆく、後ろへ引き返すことのできる天の川を我々人類はここに発明した。このような大袈裟な語彙を伴わずとも、多くのエンジニアはこの有用さを直感的に察知し、カオスな宇宙を星屑の道を辿って皆で真っ直ぐ歩めるその希望に心躍らせた。「もう足を踏み外して落ちなくていい」という安堵に身体を預けた。

gitの良さは「プロジェクトの瞬間をファイル単位で管理・保存できること」であるが、それは本質ではない。
「なかったものが生まれた」が正しいのだ。誰もが足を踏み外す危険から逃れ、統一された意識と共に前へ進んで、破壊や消失が起きてしまったものは遡って皆で歴史を改変し、障害にぶつかれば引き返して別の道をやり直すこともできる、そんな暖かい栄光へのルートを引いて示せるようになったのだ。

そしてここで言おう、「この光明の如きgitを導入すれば開発が安全かつ円滑に行えてプロジェクトが破壊されることはない、もう安心だ」という理解、認識は誤りだ。

gitをどのように使えば良いのか

上述したとおり、gitとは事故が起こらないように助ける目的で生み出されたツールである。事故が起こらないわけではない。どのように事故を防ぐのかと言えば、誰もがわかる道筋を引いてその道筋を歩めるよう誰かが導く必要がある。

それは宇宙を指せば天の川に例えられ、空では渡り鳥の航空路に、地上ではアリのフェロモンに、電車ではレールに例えることができる。gitとは混沌に秩序をもたらすものである。そして秩序とは、秩序であるが故にシステムとして管理・運営されなければならない。

gitを利用したバージョン管理による恩恵は、システムを企画し、構築し、管理・運営できることでしか得られない。壊れてもいいようにファイルのバックアップを取り続けるのが目的であれば、VS codeの拡張機能で十分に事が足りるのだ。gitを活用するには、その誘導役であるシステムのアドミニストレータ(管理者)が必要であり、そのアドミニストレータによって提供される仕組みは合理的で堅牢で合意がなされるものでなければならない。gitは秩序を作れるツールであるが、決して秩序をひとりでに作るロボットやインストーラーではない。

管理者が引いた線に皆が合意し、連れ立って歩くことによって初めて「おい、決めた道筋から外れてるぞ(戻ってこい)」という注意喚起を作業者同士で行えるようになる。これにより管理者が「できない作業者のミスを埋めて帳尻を合わせる」という管理体制から「作業者同士が互いのミスを認識して互いに埋め合う」という、よりランクの高い管理体制に移行しやすくなる。無論のこと、この管理体制は構築と維持が困難なものであり、それをさらに「助ける」目的で生まれたのがgit-flowないしgithub-flowといった”掟”にあたる概念である。

gitを導入したのち、管理者が独自に設けた「俺ルール」で運用を行おうとしてもなかなか合意は得られない。しかし、有識者同士で集まって決めた世界標準に等しい”掟”ならばどうだろうか。管理者はそれをルールとして提示する必要もなく採用だけ行い、作業者は採用された「gitの掟=git-flowやgithub-flow」を学べば良いだけである。この掟の登場によりgitの導入コストはグッと下げられたが、俺ルールにせよ世界標準にせよ、その掟が守られているかを監視・保守する必要があるのは変わらない。gitの導入によって「楽になった!安心だ!」と歓喜するのは作業者までであり、管理者はgitシステムという装置と向き合い続けることになるのだ。プロジェクトの安全性を高めるために定めた掟により、管理者はより厳しい秩序を保ち続けなければならなくなる。

つまり、「gitをどのように使えば良いのか」という問いに対しては「ボスの示した掟に従ってボスを助けてあげろ、ボスが迷っているなら掟を提案してやれ」という答えしか提示できない。秩序を秩序たらしめるためには、ボスは管理を行う方法を提示し、子分は管理される方法を把握し承諾する必要があるのだ。子分がいくら「git-flow守りましょうよw サイコーっすよw」とボスの無知をつついてみても、ボスの示す管理体制に共鳴していないことに幻滅されるのが関の山だ。逆にボスが「これよりgit-flowを施行する!野郎ども、続け!」と意気込んでも、クルーが頭に「?」を浮かべていてはせっかくの秩序は保たれない。秩序が保たれないなら、gitシステムは謳われている最高のパフォーマンスを発揮しない。

gitをどのように使うのかを決めるのは、作業者ではなく管理者だ。作業者は、管理者の定めた掟を受け入れて、その装置が最大速度で走り続けられるよう、装置を理解して管理者に協力してあげるのが栄光への道筋を繋ぎとめる唯一の策だ。また足場がなくなって、混沌の宇宙に落ちていくその無常を、二度と体験しないようにと願いながら。

覚えておくべきこと

  • gitはプロジェクトを更新ごとに丸ごと記録してくれるツール
  • プロジェクトの状態を巻き戻したり、違う機能が実装されたコピープロジェクトを作ったりできる
  • gitのおかげで開発現場の混乱がひとつ解消された、それは大きな躍進で大きな一歩だった
  • gitを使って安心安全な体制を実現するためにはその装置をずっと見ててくれる人が要る
  • 装置が機能するためのルールを個人が決めても浸透しないから、偉い人たちでgit-flow、github-flowっていうルールを決めた
  • gitの恩恵にあやかりたい作業者は管理者が決めてくれたルールを一緒に守ってあげよう。目指す道は同じだから

  1. 『STEINS;GATE』、『魔法少女まどか☆マギカ』、『ファンタシースターオンライン2』のEP1~EP3などに見られる”歴史改変モノ”の構図を取るストーリーはしばしばgitを活用した作業に例えられる。 

  2. "If anything can go wrong, it will."(「失敗する可能性のあるものは、失敗する。」) 

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

Gitコミット時のメールアドレスをブランチごとに自動で切り替える方法

モチベーション

Githubでcommitすると、コミッターのユーザー名とメールアドレスもコミットログに残って公開されてしまう。これを隠す方法。

githubはリポジトリ作成時に利用したメールアドレス以外からは、コミットを受け付けない。よって、コミットによってメールアドレスは実質公開されてしまう。

ただし、githubからnoreplyメールアドレスというものが割り当てられているので、それを利用してコミットすれば、リポジトリ製作者のメールアドレスでなくてもコミットを受け付けてもらえる。

git configでuser.emailを変更してしまうと、github以外での(ローカル作業での)コミッターのメールアドレスも変わってしまう。幸い、普段の開発ブランチと、github公開向けのブランチは分かれていて、かつ、git mergeせずにgit merge --squashなどでコミットしなおす形をとっている。よって、github向けのブランチでのコミット時だけnoreplyメールを使うようにしたい。

.gitconfigincludeIf記述を使えば、自動化を実現できる!

(注) .gitconfigincludeincludeIfを使う内容は多くの紹介記事が存在しますので、新しい話ではないです。includeIfonbranchとユーザー切り替えの記事はあまり見つけられなかったので敢えて投稿しました。忘備録ってことで許してください。

自動化しない方法(面倒だが設定は必要ない)

コマンド指定その1

git commit時のオプションで-cを指定する。このとき、gitとcommitの間に書く必要がある。
git -c user.name='foobar' -c user.email='foobar@example.com' commit -m 'message'

コマンド指定その2

git commitのオプションで--authorを使う。これはcommitの後に書くようにする。
git commit -m 'message' --author 'First M Family <author@example.com>'

.gitconfig のconditionIfで自動で切り替える方法(本丸)

まず、グローバルな.gitconfiguser.nameuser.emailが記載されているとする。ここで、条件に合わせてファイルをincludeする機能を使うことで、user.nameuser.emailをブランチやリポジトリごとに切り替えることができる。

ここでは、ブランチごとに切り替えることにする。想定として、普段のクローズドな開発ではクラウドストレージや社内サーバーでリモートリポジトリを運用し、そこにmasterブランチやdevelopブランチも紐づいているとする。Github公開用には、gh-masterブランチを作って、ローカルのgh-masterブランチを、github上のmasterブランチへpushする運用とする。例えば、以下のようなpush運用だ。
$ git push github gh-master:master

この場合に、クローズドなmaster,developブランチでは、プライベートメールアドレスでコミットし、gh-masterブランチではGithubのnoreplyメールアドレスでコミットしたい。そこで、conditionIfonbranch条件を使って、branch名がgh-masterの場合だけは、user.nameuser.emailに上書きする。

最初に、~/.gitconfigに次のような記述を行う。

[user]
    name = private your name
    email = yourname@private.jp
...
...
...
[includeIf "onbranch:gh-master"]
    path = ~/.github-noreply

さらに、~/.github-noreplyファイルを作成して、次のようにnoreplyのメールアドレスを書き込む
[user]
name = public your name
email = 12345678+username@users.noreply.github.com

セキュリティー的には、~/.github-noreplyファイルはgit管理しているディレクトリの外に置いておいた方がよいだろう。間違って公開しないように。ここでは.gitconfigと同じホームディレクトリに置いた。

実際に上手く設定できているなら次のようになる。

$ git checkout master
$ git config user.email
yourname@private.jp

$ git checkout gh-master
$ git config user.email
12345678+username@users.noreply.github.com

同様にgh-pagesなどもonbranchで設定してやると良さそう。

注意

gitのversionが2.13以降が必要1といわれていたり、2.23以降が必要2と言われていたりします。動かない時はversionを上げてみてください。実際Git for windowsの2.10では動かず、2.25にしたら動きました。

Reference

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