2017年08月08日

100均材料で 折りたたみできる撮影ボックスを作成

物を撮影するときに光源の位置で、
影が気になったり、反射が気になったり、周囲の映り込みが気になったり、
気になることが多すぎる。

簡易的なもので良いので撮影ボックスが欲しいなぁと常々思っていた。
常時、撮影に勤しむわけではないので、折りたたみできることは必須の要素。



値段も手ごろなので購入しようかなと思っていたところ、
結構、自作している人も多い。
欲しいサイズは小ぶりの撮影ボックスで、自作ならちょうどそれぐらいのサイズ感。
それなら100均で材料そろえて試してみよう。



材料


材料はセリアで購入。
  1. プラダン x 5枚
    box01.jpg
    プラダンと呼ばれる、プラスチック段ボール。カラーボックスのドアに使う目的に販売されているやつが手ごろなサイズで、クリアカラーだったのでちょうど良かった。

  2. 模造紙
    box02.jpg
    とりあえず白色の紙を準備したけど、布でも良いと思うし、色がついた紙とかをつかえば雰囲気がでると思う。

  3. 面ファスナー
    box03.jpg
    折りたためるように作るため、面の固定用に使う。
    どれぐらい使うのかわからなかったので4本分購入してみたけど、使ったのは1本だけだった。

  4. 両面テープ
    プラスチックに使えるやつ。
    家にあるものを使ったけど、プラスチックは不向きって書いてあった。けど、固定できたのでそのまま使っている。

  5. クリップ
    後から必要になった。とりあえず洗濯ばさみで代用した。

  6. その他
    • 瞬間接着剤があったほうがいい
    • カッター
    • 定規
    • カッター使うので、カッターマットまたは傷つかないようにする何か







製図


展開図


真ん中が底面、その上が背面。上面は絵の空きスペースの関係で下に描いた。
box04.jpg


グレーは面と面をくっつけるのりしろ部分。両面テープ等でかためる。
水色はプラダンを直角に当てる箇所。なのでプラダンの厚み3mm幅とっている。ここは瞬間接着剤でつけると良い。普通の接着剤でもいいが固定するのに苦労する。
黄色は前面のフラップになる。
紫は不要な部分。
赤線にカッターで切れ込みを入れ、折る。山折り(鎖線)、谷折り(破線)ある。カッターで切れ込みを入れる面に注意。



底面拡大図


底面を上から見た図。
底面はすべて谷折り。裏側からカットを入れ、内側に向けて折り込む。
折りたためるように2箇所カットし、コの字型にまげている。
裏側にカットを入れるので、作業するために裏側に向けたときには図面と左右逆になることに注意。
box05.jpg





左側面拡大図


上側が背面と接続。右側は底面と接続。
上部の山折り線は、折りたたむときに底面とぶつかる部分を避けるための折りたたみ。
下部のフラップ部分は、くみ上げたときに前面の空いた口を隠すように谷折り。
box06.jpg


右側面拡大図


左側面と対称。
box07.jpg





背面


左右ののりしろは側面との接続部分。山折りで後ろ側に折り込む。側面ののりしろと重なるのでクリップでとめる。
当初は、面ファスナーで引っ付けようと思ったが、思った以上に面ファスナーに厚みがあり、隙間が大きかったのでやめてクリップでとめることにした。
box08.jpg



上面


のりしろ部分は側面、背面を覆うように山折りで折り込む。
側面との接続部分は、面ファスナーでとめる。背面は覆うだけ。
box09.jpg




折りたたんだときの断面


ミリ単位でプラダンをカットしたり、折ったりする技術はないので絵にかいた餅なんだけど、目指す形はこんな断面。
box11.jpg





作業


まずはプラダン5枚を 370mm x 270mm のサイズにカット。
もともとが扉用なので取って部分になる丸い穴がある。そこまでがちょうど370mm。
box10.jpg

多少のずれは気にしない。
もともとミリ単位で正確にカットや折りまげができるわけではないので、正確にカットするという気持ちだけもって作業。

山折り・谷折りを考えて、切れ込み入れる面に注意する。

カッターで切れ込みを入れるときは、プラダンなので、一発で裁断することは無い。なので、あまり気を使わずカッターで切れ込みを入れる。切れ込みを入れたら丁寧に折り曲げる。
プラダンをミリ単位でカットしたり、きれいに折り曲げるのは難しいので、
だいたいの形で組み上げて、干渉する箇所があればカットして整えていく感じで組み上げる。


ピンぼけしてるけど、組み上げた状態。
box12.jpg
クリップがなかったので背面と側面の接続には洗濯ばさみを代用。


模造紙をセット。
模造紙は折って、背面に引っ掛けている。弧を描く感じで垂らすだけ。
bo13.jpg


上面を被せたら完成。
box14.jpg

上面と側面の接続部分は面ファスナーを使っている。
box15.jpg




折りたたみ


  1. 上面を外し、

  2. 左側面を折りたたむ。
    box16.jpg/li>
  3. 右側面を同じように折りたたむ。

  4. 背面を折りたたむ。
    box17.jpg
  5. 最後に上面をのせて、終了。
    box18.jpg


やはり、きっちりとは折りたためないが、邪魔にならないように片づけることが可能な大きさにはなるので十分。





使ってみた


まず撮影ボックス無しの場合、
box19.jpg
影が濃くでてるし、下地の映り込みがわかる。

撮影ボックス有りの場合、
box20.jpg
影が薄い。光源が右側にあるが、左側もきれいに映っている。
下地が白いので映込みが目立たない。






まとめ


撮影ボックスの効果がはっきりとわかって作成してよかった。
ライトは設置してないので、そこは必要に応じて用意することにする。
材料費も両面テープや、接着剤、クリップなどを買ったとしても1000円程度に収まるのでコスパは結構いいと思う。

もし撮影ボックスの設置スペースがあり、折りたたまなくてもいいのであれば、プラダンを適当なサイズにカットして、テープで貼り付けるだけで形になるので、それが一番簡単。


ラベル:自作 100均 カメラ DIY
posted by Zorinos at 20:00| Comment(0) | DIY | 更新情報をチェックする

2017年08月06日

git ブランチモデル git-flow

git のブランチは好きに使って効率よく作業すればいいのだが、好き勝手やり過ぎて効果的に使えなくなると意味がない。特にチームで使うとなると秩序が必要となる。また様々なチームを渡り歩いて作業するようなことになると、行く先々でルールが異なると、ローカルルールに従うことだけで苦労する。

こういった問題を解決するために「ブランチモデル」という管理法が提案されている。
メジャーなのが "git-flow" 。

"git-flow" という言葉は正確には Vincent Driessen 氏が提唱する
A successful Git branching model
(日本語訳 http://qiita.com/homhom44/items/9f13c646fa2619ae63d0)
というブランチモデルをサポートするツール(スクリプト)の名称を指しているが、ここでは「ブランチモデル」として整理する。





中央リポジトリ


git-flow02.png
まず中央リポジトリを準備し、各メンバーの作業はローカルリポジトリで作業する。
中央リポジトリは "origin" とする。リポジトリは自由に名前が付けれるが、gitを使ううえで馴染みが深い名称なので "origin" で統一する。
1人だけの作業であって中央リポジトリを準備し使うことにする。
(1人ならばネットワーク越しではなく、同一マシン上に準備しても良い)


各メンバーのローカルリポジトリを相互にリモートリポジトリとして追加して使っている。
これは、機能開発するうえで1人での単独開発だけではなく、機能の規模によりペアやチームを組んで機能開発にあたることがある。機能開発の途中段階において、中央リポジトリを使って共有するのではなく、各メンバー間でリモートリポジトリとして相互に指定して機能開発を進めることで、中央リポジトリに作業途中のコミットがあがることが避けられる。中央リポジトリはすっきりとした状態で保たれる。
(中央リポジトリ以外に、bareなリポジトリを準備できる場所を準備して、それをリモートリポジトリとして指定して共有して機能開発を進める。bareではないリポジトリを無理矢理に共有すると期待していない動作になるので注意)




定義されているブランチの種類


メインブランチ


git-flow01.png
中央リポジトリには、開発の最初から最後まで、恒久的に存在するブランチが2つ。
  • master
    "master" は gitブランチのデフォルトとしてのブランチ名だが、単にデフォルトだから使うのではなく、重要な役割をもつ名称として "master" が使われる。このブランチは常にリリース可能な安定版が反映される。
    "master" ブランチに直接コミットすることはなく、マージを行うだけのブランチとなる。
  • develop
    普段の開発ではこのブランチが更新される。開発の最新状態となるブランチ。プロジェクト開始時リポジトリを新規作成したときに、まず "master" ブランチから "develop" ブランチを切る。"master" ブランチ同様に、このブランチに直接コミットすることはない。






サポートブランチ


機能開発、不具合修正、リリース準備など、目的を達成するために作成されるブランチ。役割が終わると削除される。各メンバーのローカルリポジトリ上で主に作業されるブランチとなる。
それぞれのブランチには特定の目的があり、名称や、どのブランチから分岐し、どのブランチをマージ対象としなければならないかという厳格なルールがある。
(名称はブランチモデルとして絶対的な定義があるわけではない。自由度があり、プロジェクトごとに決めることができる。)




git-flow03.png
  • 機能ブランチ (feature branches) or トピックブランチ(topic branches)
    機能開発や不具合修正などほとんどの作業で使う。
    ブランチ元develop
    マージ先develop
    ブランチ名ルールfeature/?
    ブランチの存在期間機能ブランチは実装が継続している間は存在し続ける。実装が完了し "develop" ブランチにマージされるか、仕様ドロップで打ち切られるまで存在する。

    機能ブランチはメンバーのローカルリポジトリのみに存在し、中央リポジトリ "origin" には存在しない。

    機能ブランチを新たに作成するには、"develop" ブランチから分岐する。
    $ git checkout -b myfeature develop

    機能開発が完了したら "develop" ブランチへマージする。
    マージするときは --no-ff オプションを指定し、fast-­forwadマージが可能の場合であっても常にマージコミットを作成する。履歴に機能ブランチが存在したことの情報と、機能の追加のために行った作業をまとめて残しておける。
    $ git checkout develop   :"develop" ブランチへ切り替える
    $ git merge --no-ff feature/myapp :non-fast-forwardマージを指定

    機能開発が終了し、"develop" ブランチへマージしたら、役目を終えたブランチは削除する。
    $ git branch -d feature/myapp




git-flow04.png
  • リリースブランチ(release branches)
    製品をリリースするために使う。リリーステストで見つかった不具合修正や、リリースバージョンを付けたり、リリースのための関連作業を行う。
    ブランチ元develop
    マージ先develop と master
    ブランチ名ルールrelease/?
    ブランチの存在期間"develop" ブランチの状態が新しくリリースさせても良い状態になった時にブランチを切る。リリースが完全に出荷されるまでブランチは存在し続ける。

    リリースブランチを切り、リリース作業はそのブランチで専念することで、"develop" ブランチはリリースを気にすることなく作業を進めることができる。タイミング悪く、もし、今からのリリースに含まれない機能を "develop" ブランチへマージしようと思うのであれば、リリースブランチが切られるまで待ってからマージすること。

    リリースブランチを新たに作成するには、"develop" ブランチから分岐する。
    $ git checkout -b release/1.1 develop

    リリース作業中に見つかった不具合は、リリースブランチに対して適用する。
    これはリリース完了してから、まとめて "develop" ブランチへ反映するため。

    リリースできる状態になったら、"master" ブランチへマージし、タグも設定する。
    $ git checkout master   :"master" ブランチへ切り替える
    $ git merge --no-ff release/1.1 :non-fast-forwardマージを指定
    $ git tag -a 1.1 :注釈コメントも付ける

    リリースブランチで修正した内容を "develop" ブランチへも反映する。このときコンフリクトが起こる可能性が高いので注意してマージする。
    $ git checkout develop   :"develop" ブランチへ切り替える
    $ git merge --no-ff release/1.1 :non-fast-forwardマージを指定

    リリースが完了し、"master"・"develop" ブランチへのマージも完了したら、役目を終えたブランチは削除する。
    $ git branch -d release/1.1




git-flow05.png
  • Hotfixブランチ(hotfix branches)
    製品リリースした後で、重大な不具合が見つかり緊急対応が必要な場合に使う。次のリリースのためのブランチという意味でリリースブランチと似ているが、意図的に発生するものではない。
    ブランチ元master
    マージ先develop と master
    ブランチ名ルールhotfix/?
    ブランチの存在期間リリース後に重大な不具合が見つかり、緊急で対策を行いたい場合にブランチを切る。次のリリースが完全に出荷されるまでブランチは存在し続ける。

    "master" ブランチから分岐することで、"develop" ブランチの状況を気にせず、即座に緊急対応が可能。逆に担当者が緊急対応中でも他メンバーは "develop" ブランチで開発作業を継続できる。
    不具合修正とリリースバージョンを付け、その他リリースを行うための関連作業を行うという点で、リリースブランチと同じ。


    Hofixブランチは "master" ブランチから作成される。
    $ git checkout -b hotfix/1.2.1 master

    リリースできる状態になったら、"master" ブランチへマージし、タグも設定する。
    $ git checkout master   :"master" ブランチへ切り替える
    $ git merge --no-ff hotfix/1.2.1 :non-fast-forwardマージを指定
    $ git tag -a 1.2.1 :注釈コメントも付ける

    Hofixブランチで修正した内容を "develop" ブランチへも反映する。
    もし、このタイミングで進行中のリリースブランチがあれば、例外的にリリースブランチへマージする。これは、リリースブランチが完了すれば最終的に "develop" ブランチにも Hotfixブランチの不具合修正内容は反映されることになるから。ただしリリースブランチ完了まで待てない事情があれば、"develop" ブランチへマージしても問題はない。
    $ git checkout develop   :"develop" ブランチへ切り替える
    $ git merge --no-ff hotfix/1.2.1 :non-fast-forwardマージを指定

    リリースが完了し、"master"・"develop" ブランチへのマージも完了したら、役目を終えたブランチは削除する。
    $ git branch -d hotfix/1.2.1




git-flow06.png
  • (オプション)Supportブランチ(support branches)
    必須ではないが、旧バージョンをサポートし続けなければいけない場合に使う。旧バージョンの保守とリリースを行う。
    ブランチ元master
    マージ先develop
    ブランチ名ルールsupport/?
    ブランチの存在期間旧バージョンをサポートする必要が発生した場合にブランチを切る。以降はサポートが終了するまで、恒久的に存在する。



    Supportブランチは "master" ブランチからタグを指定し作成する。合わせて Supportブランチ用の Hotfixブランチを作成する。
    $ git checkout -b support/1.x 1.2  :Supportブランチを作成し切り替える
    $ git checkout -b hotfix/1.2.1

    Hotfixブランチで不具合修正を行い、リリースできる状態になったら、Supportブランチへマージし、タグも設定する。
    $ git checkout support/1.x   :Supportブランチへ切り替える
    $ git merge --no-ff hotfix/1.2.1 :non-fast-forwardマージを指定
    $ git tag -a 1.2.1 :注釈コメントも付ける

    旧バージョンのサポート用リリースが完了したら、役目を終えた Hotfixブランチは削除する。
    $ git branch -d hotfix/1.2.1


    混乱を避けるために、原則として、Supportブランチや、そこから分岐する Hotfixブランチを他のブランチへマージすることは避ける。

    最新リリースに対しても急ぎ不具合修正を反映する場合は、新たにHotfixブランチを作成する。
    $ git checkout -b hotfix/2.0.1 master

    (最新リリースに対して即時対応が必要なければ、"develop" ブランチから機能ブランチを分岐し、不具合修正として対応する。Hotfixブランチとは違うが対応の仕方は同じこと。)


    リリースできる状態になったら、"master" ブランチと "develop" ブランチへマージし、タグも設定する。
    $ git checkout master   :"master" ブランチへ切り替える
    $ git merge --no-ff hotfix/2.0.1 :non-fast-forwardマージを指定
    $ git tag -a 2.0.1 :注釈コメントも付ける
    $ git checkout develop :"develop" ブランチへ切り替える
    $ git merge --no-ff hotfix/2.0.1 :non-fast-forwardマージを指定

    リリースが完了したら、役目を終えたブランチは削除する。
    $ git branch -d hotfix/2.0.1








git-flow インストール


ここではマニュアルでインストールしてみる(nvie版)。
(git flow wiki:Installing git-flow manually

git-flow を github から clone する。リポジトリを用意する場所に移動してから実行。

$ cd ~/Downloads/gitflow
$ git clone --recursive git://github.com/nvie/gitflow.git



ツール(スクリプト)をインストール(コピー)する。
インストール先は、デフォルトは "/usr/local/bin"

$ sudo bash gitflow/contrib/gitflow-installer.sh

### gitflow no-make installer ###
Installing git-flow to /usr/local/bin
Using existing repo: gitflow
Submodules look up to date
'gitflow/git-flow' -> '/usr/local/bin/git-flow'
'gitflow/git-flow-init' -> '/usr/local/bin/git-flow-init'
'gitflow/git-flow-feature' -> '/usr/local/bin/git-flow-feature'
'gitflow/git-flow-hotfix' -> '/usr/local/bin/git-flow-hotfix'
'gitflow/git-flow-release' -> '/usr/local/bin/git-flow-release'
'gitflow/git-flow-support' -> '/usr/local/bin/git-flow-support'
'gitflow/git-flow-version' -> '/usr/local/bin/git-flow-version'
'gitflow/gitflow-common' -> '/usr/local/bin/gitflow-common'
'gitflow/gitflow-shFlags' -> '/usr/local/bin/gitflow-shFlags'




アンインストールする場合は、clone を実行したディレクトリから以下を実行する。

$ sudo bash gitflow/contrib/gitflow-installer.sh uninstall

### gitflow no-make installer ###
Uninstalling git-flow from /usr/local/bin
rm -vf /usr/local/bin/git-flow-init
'/usr/local/bin/git-flow-init' を削除しました
rm -vf /usr/local/bin/git-flow-feature
'/usr/local/bin/git-flow-feature' を削除しました
rm -vf /usr/local/bin/git-flow-hotfix
'/usr/local/bin/git-flow-hotfix' を削除しました
rm -vf /usr/local/bin/git-flow-release
'/usr/local/bin/git-flow-release' を削除しました
rm -vf /usr/local/bin/git-flow-support
'/usr/local/bin/git-flow-support' を削除しました
rm -vf /usr/local/bin/git-flow-version
'/usr/local/bin/git-flow-version' を削除しました
rm -vf /usr/local/bin/gitflow-common
'/usr/local/bin/gitflow-common' を削除しました
rm -vf /usr/local/bin/gitflow-shFlags
'/usr/local/bin/gitflow-shFlags' を削除しました
rm -vf /usr/local/bin/git-flow
'/usr/local/bin/git-flow' を削除しました






Ubuntuでは、apt管理から git-flow をインストールするとAVH版がインストールされる。

$ sudo apt-get install git-flow

基本は同じだが、こちらは機能が拡張されている。大は小を兼ねるの方針でAVH版を入れておけば問題ない。ここでは話が広がり過ぎるのでベースとなるnvie版を入れた。





git-flow を使ってみる


git コマンドの代わりに、git flow コマンドを使う。git コマンドもいつも通りに使える。git flow を使うことで、git-flow ルールを強制することができる。

リポジトリの初期化


各ブランチとタグの名称を指定するが、基本的にデフォルトのままでよいので、そのままEnterキーを押して進めれば良い。

$ git flow init

Initialized empty Git repository in ********************/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []



ブランチの状態を確認してみる。
$ git branch
* develop
master

"master" ブランチと "develop" ブランチが作成され、"develop" ブランチがチェックアウトされた状態となっている。


もし、初期化を修正したかったら、-f オプションを使う。

$ git flow init -f


これで再度初期設定が実行される。



中央リポジトリへ反映


中央リポジトリ となるリモートリポジトリを準備する。
ローカルリポジトリに、中央リポジトリ "origin" を設定して、プッシュする。

$ git remote add origin <リモートリポジトリのアドレス>
$ git push --all


ブランチの状態を確認してみる。
$ git branch -a
* develop
master
remotes/origin/develop
remotes/origin/master

リモート追跡ブランチも設定できた。




各メンバーの準備


中央リポジトリからクローンする。

$ git clone <リモートリポジトリのアドレス>


単にクローンしただけななおで、まだ "git-flow" の設定が紐づけられていない。
各メンバーのマシンにおいても初期設定を行う。これも git flow init でいける。注意するのは、プロジェクト内で用いるブランチ名はそろえておくこと。

$ git flow init

Initialized empty Git repository in ********************/.git/
No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []


追跡ブランチを確認してみる。
$ git branch -vv
* develop 9790466 [origin/develop] Initial commit
master 9790466 [origin/master] Initial commit

ローカルリポジトリの各ブランチにも、ちゃんと上流ブランチが設定されている。これで "git-flow" を使う準備ができた。


作業で使うブランチの種類は以下。
  • feature :機能ブランチ
  • release :リリースブランチ
  • hotfix :Hotfixブランチ
  • support :Supportブランチ

作業の開始


どのブランチでも基本的な流れは同じ。例として、機能ブランチを作成する。

$ git flow feature start app1

$ git branch
develop
* feature/app1
master

"feature/app1" ブランチが作成され、チェックアウトされた状態になった。


このブランチで作業を行う。
ブランチ操作は、通常のgitコマンドを使えばよい。



作業の終了


作業が終了したらマージする。git-flow に限ったことではないが、マージする前にスカッシュやリベースでコミットの内容を整理しておくと後から履歴を見返したときにわかり易くなるのでおススメ。

$ git flow feature finish app1


マージコミットメッセージを入力するエディタが起動するので、メッセージを入れる。

ブランチを確認してみる。
$ git branch
* develop
master

"feature/app1" ブランチが削除され、"develop" ブランチがチェックアウトされた状態になった。




develop ブランチを中央リポジトリへ反映


develop ブランチを更新したので、中央リポジトリへ反映する。

$ git push --all



基本的に、作業開始し、作業終了でマージし、中央リポジトリへプッシュするというのが流れ。
コンフリクトなど問題が発生した場合は、git-flow のスクリプトも止まるので、その場合は残りは手作業となる。git-flow のモデルを理解していないと問題対処後に何をすべきかがわからないので、ブランチモデルを知らなくても使えるというツールではないことに注意。






まとめ


"git-flow" で理解・管理しておけば多くの場面で、ブランチ管理の混乱は避けられ、途中参加したメンバーもスムーズに作業に集中できると思う。また "git-flow" と言っても、上で記述したブランチ以外にも、機能ブランチとは分けて、bugfixブランチを用意する場合もある。このシンプルな形で進めればいいのだけど、このモデルをベースにして、うまくやってくれ、ということだと思う。多少の足し引きがあっても、考え方が沿っていれば理解は早い。後はプロジェクト、チームに沿ったやり方を毎回、模索するしかないと思う。




gitをインストール
gitサーバーのセットアップ
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git リモートブランチを追加
git チェックアウトをもっと便利に使う
git プロジェクトの構成
git 変更をpatchファイルにする
git コンフリクトに対処する
git 失敗したときの復元
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする

2017年08月05日

git 失敗したときの復元

コミットしたけど間違っていたので無かったことにしたいと思えば git reset が使うことで履歴を変更できる。きれいさっぱり消して戻してくれる。
が、もしリセットする箇所を間違えたらどうなるのか?

このようなコミット履歴があった場合に、
$ git log --oneline
827142f modified2 a.txt b.txt
e379d74 modified a.txt b.txt
6c5004e modified a.txt d.txt
069d76c Add file :d.txt
4bfcd75 modified c.txt
3f062b7 modified b.txt
9925985 modified a.txt
d79bc0b Add files


間違ってコミットしたので、"HEAD^" で1つ前に戻ることにした。
$ git reset --hard HEAD^^
HEAD is now at 6c5004e modified a.txt d.txt

操作をミスで、"HEAD^^" で戻し過ぎてしまった!
reset --hard なのできれいに無くなってしまった!!
途方に暮れてしまう場面だが、gitにはこんなときでも復旧手段がある。




reflog(参照ログ)で復旧


$ git reflog


"reflog" はすべての変更を記録してくれている。
$ git reflog
6c5004e HEAD@{0}: reset: moving to HEAD^^
827142f HEAD@{1}: commit: modified2 a.txt b.txt
e379d74 HEAD@{2}: commit: modified a.txt b.txt
6c5004e HEAD@{3}: commit: modified a.txt d.txt
069d76c HEAD@{4}: commit: Add file :d.txt
4bfcd75 HEAD@{5}: commit: modified c.txt
3f062b7 HEAD@{6}: commit: modified b.txt
9925985 HEAD@{7}: commit: modified a.txt
d79bc0b HEAD@{8}: commit (initial): Add files


今回であれば git reset --hard HEAD^^ の前に戻れば復旧できるので、"HEAD@{1}" にリセットする。

$ git reset --hard HEAD@{1}


コミット履歴を確認してみる。
$ git log --oneline
827142f modified2 a.txt b.txt
e379d74 modified a.txt b.txt
6c5004e modified a.txt d.txt
069d76c Add file :d.txt
4bfcd75 modified c.txt
3f062b7 modified b.txt
9925985 modified a.txt
d79bc0b Add files

途方に暮れてしまう前の状態に巻き戻すことができている!


git reset だけではなく、git rebaseブランチの付け替えに失敗したときや、履歴の変更したときも使える。あとは、"detached HEAD" 状態に気づかずにコミットした後で、ブランチを切り替えた場合に、見えなくなってしまったコミットIDを探してチェリーピックすれば、失われたコミットをサルベージすることができる。




まとめ


作業ツリー上にしか存在していなかったデータなどはコミットしていなければ戻すことはできないが、直近の内容でコミットさえしてあれば、データがどこかに残っているので、目の前からデータが消えるようなことになってもリカバリできる。ただ、過去にさかのぼるのも限界があるので、間違いには早めに気づいて、気づいたらすぐに対処するのが良い。






gitをインストール
gitサーバーのセットアップ
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git リモートブランチを追加
git チェックアウトをもっと便利に使う
git プロジェクトの構成
git 変更をpatchファイルにする
git コンフリクトに対処する
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする

2017年08月03日

git コンフリクトに対処する

ブランチをマージした。
git_conflict01.png
$ git merge new_branch 
Auto-merging mystyle.css
CONFLICT (content): Merge conflict in mystyle.css
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
2つのファイルでコンフリクトが発生した。

コンフリクトした"index.html"ファイルの中身を見てみる。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>git確認</title>
</head>
<body>
<p>master branch</p>
<<<<<<< HEAD
<p>modified master</p>
=======
<p>new_branch</p>
>>>>>>> new_branch
</body>
</html>
gitでは現ブランチの内容と、マージするブランチの内容とでどちらを採用したらいいか判断がつかないときに、この操作を行った人にマージ対応を求めている状態がコンフリクト。


このときコンフリクトしたファイルの中には、コンフリクトした箇所がマーカーで示されている。
<<<<<<< HEAD
"現ブランチのコンフリクト部分"
=======
"マージするブランチのコンフリクト部分"
>>>>>>> マージするブランチ名

このマーカーで示された箇所を処理してあげないとコンフリクトは解消されない。
エディタを開き、このマーカー部分を修正して、再度コミットすればいい。




diffツール


GUIが使えるのであれば、コンフリクトを解消するときにGUIツールで作業したほうが直感的に作業できて便利。meld, KDiff3などいくつかツールがあるが、ここでは P4Merge というツールがあるので使ってみる。



インストール


ここからダウンロードする。

[DOWNLOAD] をクリックしする。
git_conflict02.jpg

OSを選んでダウンロードする。
git_conflict03.jpg

ユーザ登録の画面が表示される。登録しない場合はskipすることもできる。
git_conflict04.jpg

"p4v.tgz" ファイルがダウンロードされる。


ダウンロードが完了したら、ダウンロードしたファイルのディレクトリで展開する。
$ tar -xzvf p4v.tgz

展開されたディレクトリを移動し、シンボリックリンクを設定する。
$ sudo mv p4v-2017.2.1535556/ /opt/
sudo ln -s /opt/p4v-2017.2.1535556/bin/p4merge /usr/local/bin/p4merge




mergetoolに設定


configファイルに設定を行う。

$ git config --global merge.tool p4merge


マージツールを使う際のオプションも設定しておく。

$ git config --global mergetool.p4merge.cmd 'p4merge "$BASE" "$LOCAL" "$REMOTE" "$MERGED"'
$ git config --global mergetool.p4merge.trustExitCode false
$git config --global mergetool.p4merge.keepTemporaries false
$ git config --global mergetool.keepBackup false


"cmd" :p4mergeを実行する方法を指定
$BASE共通箇所の内容を保持する一時ファイルのパス
$LOCAL現ブランチの内容を保持する一時ファイルのパス
$REMOTEマージするブランチの内容を保持する一時ファイルのパス
$MERGEDマージ結果を書き出すファイル(コンフリクトしたファイル)

"trustExitCode" :p4mergeの終了コードでマージが成功したかどうかを判断できるのかどうか→"false" できないとした。
"keepTemporaries" :マージ作業の一時ファイルを残すのかどうか→"false" は自動的に削除される。
"keepBackup " :マージが完了したときに、バックアップファイル(*.orig)が残される→"false" は自動的に削除される。

"~/.gitconfig" ファイルに直接に記述してもいい。
.....

[merge]
tool = p4merge
[mergetool "p4merge"]
cmd = p4merge \"$BASE\" \"$LOCAL\" \"$REMOTE\" \"$MERGED\"
keepBackup = false
trustExitCode = false
keepTemporaries = false
[mergetool]
keepBackup = false




mergetoolを起動


コンフリクトした後、マージツールを起動する。

$ git mergertool


gitは "config" に設定された "merge.tool" を探し、起動する。
git_conflict05.jpg
"p4Merge" は4ペイン表示。
上部3つが左側から、"$LOCAL" "$BASE" "$REMOTE" と並び、下部が "$MERGED" となる。


下部のペインの左側にマーカーがあり、上部のペインにも同じマーカーが付けてある。
同じマーカーで "$LOCAL" "$BASE" "$REMOTE" を示しており、下部のマーカーをクリックすることでどの内容をマージで採用するかを決定できる。
複数の内容を有効としたければ、Shift + クリック することで複数採用することが可能。
git_conflict06.jpg

マージが完了すれば、保存終了する。
複数のコンフリクトがある場合、終了したら次のファイルのマージ処理が起動してくる。

2つのファイルのコンフリクトがあったので、2回ツールが起動し、マージ処理を行った。
$ git mergetool 
Merging:
index.html
mystyle.css

Normal merge conflict for 'index.html':
{local}: modified file
{remote}: modified file
QString::arg: 1 argument(s) missing in %1 - %2

Normal merge conflict for 'mystyle.css':
{local}: modified file
{remote}: modified file
QString::arg: 1 argument(s) missing in %1 - %2

"QString::arg: 1 argument(s) missing in %1 - %2" 良くわからないエラーがあるが、ツール起動に影響はないので放置している。。。

すべてマージが完了すれば、ステージして、コミットする。




まとめ


マージツールを使うと直感的に採用したい変更が決定しマージできるので、GUIを使っているのであればコンフリクトの解消にはぜひに使ったほうがいい。同じファイルに複数のコンフリクトがある場合や、ときにはgit側で共通部分の判別がつかず、大きなブロックで差分がでてしまうこともある。このような場合には、ツールで全体を見ながら修正できたほうが安心できる。






gitをインストール
gitサーバーのセットアップ
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git リモートブランチを追加
git チェックアウトをもっと便利に使う
git プロジェクトの構成
git 変更をpatchファイルにする
git 失敗したときの復元
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする

2017年08月02日

git 変更をpatchファイルにする

変更差分をpatchファイルにすることができる。

事前知識として、Linuxの patch はテキストファイルに差分を適用するコマンド。
パッチファイルを作成するコマンドは以下。

$ diff -u 変更前のファイル 変更後のファイル > パッチファイル名


-u オプションは unified diff形式で出力する指定。

例として、パッチファイルを作成して、そのパッチファイルの中身を見てみる。
$ diff -u a_old.txt a_new.txt > a.patch

$ cat a.patch
--- a_old.txt 2017-08-01 09:00:00.570393470 +0900
+++ a_new.txt 2017-08-01 09:30:00.841552217 +0900
@@ -1 +1,3 @@
aaa
+
+modified 1


パッチを適用するコマンドは以下。

$ patch -u 適用するファイル名 < パッチファイル名



パッチ適用前後を比較しながら、適用内容を確認してみる。
$ cat a.txt
aaa

$ patch a.txt < a.patch
patching file a.txt

$ cat a.txt
aaa

modified 1

変更差分のパッチが適用されたことがわかる。


もし適用するファイルを間違えていたら、パッチ適用を戻す(リバースパッチ)。
-R オプションを使うことで、新旧ファイルが反転しているものとして適用することで元に戻す。

$ patch -u -R 適用するファイル名 < パッチファイル名

$ patch -R a.txt < a.patch
patching file a.txt

$ cat a.txt
aaa

リバースパッチをあてることで元に戻った。





パッチファイルの作成


git diff の出力をパッチファイルとして保存すればいい。
例えば、特定ファイルの異なるコミットの差分のパッチファイルを作る場合、

$ git diff commitID1 commitID2 -- filepath > file.patch

試しに作成してみる。
$ git log --oneline
827142f modified2 a.txt b.txt
e379d74 modified a.txt b.txt
6c5004e modified a.txt d.txt
069d76c Add file :d.txt
4bfcd75 modified c.txt
3f062b7 modified b.txt
9925985 modified a.txt
d79bc0b Add files

$ git diff 069d76c 6c5004e -- p1/p2/d.txt
diff --git a/p1/p2/d.txt b/p1/p2/d.txt
index 1d60b70..c8b35f9 100644
--- a/p1/p2/d.txt
+++ b/p1/p2/d.txt

@@ -1 +1,3 @@
ddd
+
+patch 1:d.txt


$ git diff 069d76c 6c5004e -- p1/p2/d.txt > ~/Documents/test.patch

$ cat ~/Documents/test.patch
diff --git a/p1/p2/d.txt b/p1/p2/d.txt
index 1d60b70..c8b35f9 100644
--- a/p1/p2/d.txt
+++ b/p1/p2/d.txt
@@ -1 +1,3 @@
ddd
+
+patch 1:d.txt






パッチファイルの適用


作成したパッチファイルを適用するには git apply を使う。

$ git apply file.patch


git apply は全部適用するか、または一切適用しないかのどちらか。エラーが出るまで適用するとか中途半端なことはしない。
また、適用できるかあらかじめチェックすることができる。git apply --check を使い、適用できなければエラーがでる。適用可能であれば何も出力されない。
$ git apply --check test.patch
error: patch failed: p1/p2/d.txt:1
error: p1/p2/d.txt: patch does not apply

適用したら、ステージしてコミットすれば良い。



git操作で作成したパッチファイルは、Linuxコマンドの patch コマンドと互換性を持ち、git管理されていないファイルに対しても適用できる。

$ patch -p1 < test.patch

-p オプションは差分に記載されたファイル名から指定した個数分のパス指定を取り除く指定。"-p1" なので1個除く。
差分ファイルのパスの指定には、"a" "b" がついているのでこれを除くことで、patch コマンドと互換性が取れる。
--- a/p1/p2/d.txt
+++ b/p1/p2/d.txt






まとめ


パッチを使うことで、ファイル丸ごとの置き換えはしたくない差分対応とか、離れた環境にあるリポジトリへの適用や、git管理下にないファイルに変更差分を適用したい場合に使える。
変更差分は git diff の操作なので難しいことではない。
ちょっとした変更差分でも、手動でファイルに変化点を加えていくとヒューマンエラーが介入する可能性があり神経を使うので、自動的に作業できることは自動化してしまうほうが時間もかからないし、間違いが少ない。





gitをインストール
gitサーバーのセットアップ
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git リモートブランチを追加
git チェックアウトをもっと便利に使う
git プロジェクトの構成
git コンフリクトに対処する
git 失敗したときの復元
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする