2018年04月03日

gccとccの違い

digital-388075_640.jpg

LinuxのC言語コンパイラでメジャーなgcc。

「GNU C Compiler」の略だと信じていたが、それは遠い昔の話。

もともと多言語を想定して設計されていて、「GNU C Compiler」と呼ばれていたときでも多くの言語に対応していた。

で、現在の標準パッケージには C、C++、Objective-C、Fortran、Javaなどのコンパイラやライブラリが含まれていて、「GNU Compiler Collection」の略だというのが正しい。

「ジーシーシー」としか口にしてなかったから知らなかったけど、たまたま調べてみて、あらびっくり。
でも、これを説明する事はもう無いだろうな。
GCC, the GNU Compiler Collection



で、話を戻して、C言語コンパイラに cc もある。

"g" が付くか付かないか。この違いはなんだろう?

gccは固有名詞で、ccはシステムに標準で付いてくるコンパイラのことらしい。
ただ、システムによっては gccにリンクを貼っていて、結局は同じものということもある。

Ubuntu16.04で確認してみた。
まずはパスを確認
$ which gcc
/usr/bin/gcc
$ which cc
/usr/bin/cc


詳しく見てみる
$ ls -l `which cc`
lrwxrwxrwx 1 root root 20 7月 3 2017 /usr/bin/cc -> /etc/alternatives/cc


$ sudo update-alternatives --config cc
リンクグループ cc に 1 つの alternative のみがあります (/usr/bin/cc が提供): /usr/bin/gcc
設定は行いません。


gccを参照していることが判った。

gccとccどちらを実行しても、同じgccの実行になるということ。

つまりは、ccは知らなくてもgccだけ知っていたら大丈夫。
すっきりした。


ラベル:ツール
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする

2017年09月05日

Apache2 で Basic認証 を設定

apache2 で Basic認証を設定する方法には
confに設定する方法と、.htaccessファイルを使う方法の2つの方法がある。
Basic認証(ベーシックにんしょう、Basic Authentication)とは、HTTPで定義される認証方式の一つ。基本認証と呼ばれることも。
Basic認証では、ユーザ名とパスワードの組みをコロン ":" でつなぎ、Base64でエンコードして送信する。このため、盗聴や改竄が簡単であるという欠点を持つが、ほぼ全てのWebサーバおよびブラウザで対応しているため、広く使われている。引用:Wikipedia


環境:
  • Ubuntu 16.04
  • Apache 2.4.18




ユーザーとパスワードの設定


どちらの方法でも認証のために、ユーザーとパスワードの設定は必要。先に作成しておく。


ユーザー管理ファイルを作成


管理ファイルを新規作成する場合、

$ sudo htpasswd -c ファイル名 ユーザー名

実行すると、パスワードの入力を求められるので2回入力する。

$ sudo htpasswd -c /etc/apache2/.htpasswd user1
New password:
Re-type new password:
Adding password for user user1


既に管理ファイルが存在していて、2回目以降のユーザー作成では、オプション -C を付けない。
$ sudo htpasswd /etc/apache2/.htpasswd user2
New password:
Re-type new password:
Adding password for user user2


ユーザー管理ファイルの置き場所はどこでもいいが、セキュリティ上、公開されていないディレクトリ上に作成すること。


パスワードの変更


パスワードを変更したい場合も、同様のコマンドで更新する。
$ sudo htpasswd /etc/apache2/.htpasswd user1
New password:
Re-type new password:
Updating password for user user1






ユーザーの削除


オプション -D を付ける。
$ sudo htpasswd -D /etc/apache2/.htpasswd user1
Deleting password for user user1





.htaccessファイルを使った認証方法


認証をかけたいディレクトリに .htaccess ファイルを置き、以下の内容を記述する。

AuthType Basic
AuthName "Please Enter Your ID and pass"
AuthUserFile /etc/apache2/.htpasswd
require valid-user


AuthType

認証方式を指定。 Basic認証の場合 Basic とする。

AuthName

認証画面に表示されるメッセージ。

AuthUserFile

作成したユーザー管理ファイルを指定。

require

アクセスを許可するユーザーやグループを指定。 valid-user の場合、ユーザー管理ファイルに含まれるすべてのユーザーを対象とする。


システムが .htaccess ファイルを見つけた時、このファイルの中で定義された設定を、既にこのディレクトリに対して定義されていた設定に対して上書きする必要がある。
これは apacheのディレクティブ設定で行う。

"/etc/apache2/sites-available/" に置いたconfファイルで設定する。
<Directory パス> 
  ~ 省略 ~
  AllowOverride AuthConfig ← None を変更する
  ~ 省略 ~
</Directory>

  • None :上書きを禁止
  • AuthConfig :認証に関する変更を許可
  • All :すべての設定の変更を許可


設定後、apacheを再起動する。

.htaccess ファイルを置いたディレクトリにアクセスする。
apache_basic01.png
設定した通り認証を求められるので、登録したユーザーとパスワードを入力すればいい。






confファイルで設定する方法


"/etc/apache2/sites-available/" に置いたapacheのディレクティブ設定で行う。

記述する内容は、.htaccess ファイル内に記述したものとほぼ同じ。
<Directory 認証を設定するディレクトリパス>
  AuthType Basic
  AuthName "Please Enter Your ID and pass"
  AuthUserFile /etc/apache2/.htpasswd
  require valid-user
</Directory>


設定後、apacheを再起動すれば、認証を設定するディレクトリに認証がかけられている。




まとめ


apache では .htaccessファイルの使用を推奨していません。
apacheでは認証用のディレクティブを書く方法が推奨され、.htaccess ファイルはサーバの設定ファイルを変更できない場合に使用すべきとしている。

理由としては、apacheが各ディレクトリで.htaccessファイルを探し、設定を書き換えるためサーバに余計な負荷をかけるというパフォーマンス上の問題や、.htaccessファイルは一般ユーザーが設置、編集できるのでセキュリティ上の問題があるため。
これらのことを理解したうえで、Basic認証を使い分けながら使用していく。


Ubuntu サーバの設定 Webサーバー
posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする

2017年08月28日

実践git

Git-Logo-1788C.png

公式サイト:https://git-scm.com/



インストール









1人でgitを使う


準備





基本的な作業



この流れの繰り返し。


リリース作業








複数人でgitを使う


準備






基本的な作業


リモートリポジトリからクローンして、ローカルリポジトリを準備すれば、後は1人でgitを使う流れと同じ。



他のメンバーと作業内容を共有







リリース作業


基本は 1人でgitを使う場合のリリース作業と同じ。





ブランチモデル








困ったときのtips


変更したファイルがたくさんある。ステージするのがたいへん。

  • $ git add .
    "."(ピリオド)を指定するとそのディレクトリ以下の階層すべての変更ファイルがステージの対象となる。

作業ツリー上に、gitで管理してほしくないファイルが存在している。


さっきコミットしたのに、追加を忘れたファイルがあった。


コミットしたコミットメッセージがいまいちだった。書き換えたい。


間違ってステージしてしまった。

  • ステージされているすべてのファイルをもとに戻す場合
    $ git reset HEAD
  • 特定のファイルだけ戻す場合
    $ git reset HEAD <対象ファイルパス>

間違ってコミットした。取り消したい。

  • 1つ前のコミット状態に戻す。ただし、作業ツリー、ステージングエリア上の変更は戻さない。コミットだけ無しにする。
    $ git reset --soft HEAD^

リセット実行したけど、実行前の状態に戻したい。


異なる目的の対応を一気にやってしまった。複数のファイルの変更点がある。分けてコミットしたい。

  • $ git add -p
    "-p" オプションをつけると、ステージする処理をインタラクティブに進める。
    変更ファイルが順に示されるので、コマンド入力でステージする・しないを決定する。コマンドの種類はいくつかあるが、ややこしい操作は無しにして次の操作だけ行えばいい。
    [y]ステージする、[n]ステージしない、[q]操作を中止する。

作業ツリー上の内容が中途半端でまだコミットできないのに、同じ作業ツリー上で、急遽、別の作業を行わないといけなくなった。


細目にコミットしたが、履歴を追うのが大変。まとまりある単位でのコミットにしておけば良かった。マージする前に整理したい。

  • git rebase -i で "squash" を指定してコミットをまとめる。

ブランチを切り替えるの忘れて、コミットしてしまった。

  • まず正しいブランチに切り替える
    $ git checkout <正しいブランチ名>
    コミットIDを使い、間違ったコミットを指定してチェリーピックする。
    $ git cherry-pick &ly;commitID>
    間違ってブランチに戻り、不要なコミットをリセットする。
    $ git checkout <間違ったブランチ名> && git reset --hard HEAD~

違うブランチを削除してしまった。

  • ローカルリポジトリの場合
    reflogで過去の作業から、ブランチ削除の前の状態を確認する。
    復活させたいブランチ名と確認した番号を使い、以下のコマンドを実行する。
    $ git branch <復活させたいブランチ名> HEAD@{確認した番号}
  • リモートリポジトリの場合
    すぐに他のメンバーに確認。リモートリポジトリを触って影響を受けないように連絡と、既に影響を受けてしまった人がいないか確認。
    そのうえで復活操作可能と判断できれば復活させる。すぐの操作が難しいとなればメンバー間で今後について相談する。

    復活手順:
    もしローカルリポジトリにも削除してしまったブランチがなければ、上記手順で復活させる。そのブランチをリモートリポジトリにプッシュする。ただし普通にはプッシュできないので、強制的にプッシュし復活させる。
    $ git push -f <リモートリポジトリ> <復活させるブランチ名>

リモートブランチは他のメンバーに影響を与える可能性が高い
焦って git push -f をしてはダメ。
メンバーに確認して、大丈夫だと確認が取れてから操作すること。

プッシュしたコミットが間違っていたので取り消したい。

  • 基本的にコミットを無かったことにするのはあきらめる。
    リモートブランチは他のメンバーに影響を与える可能性が高いので、コミット履歴を改変しないこと。
    git revert でコミットした歴史は残しつつ、内容だけ差し戻す。
  • もし他メンバーの誰にも影響が出ないことがわかったなら、例外的処置でリモートリポジトリを書き換える。
    まずローカルリポジトリでコミットをリセットする。
    $ git reset --hard HEAD^
    リセットした内容を強制的にプッシュする。
    $ git push -f <リモートリポジトリ> <ブランチ名>

スタッシュした内容を消してしまった。

間違って git stash drop したときや、git stash pop のあとに、うっかり git reset して大事なスタッシュを消してしまった場合。
  • "drop" や "pop" のスタッシュ操作したときに、
    例えば "Dropped refs/stash@{0} (13ce25271878e0763aaaefab44c0b2c52743df51)" と、SHA-1 が示される。これを使って復活させる。
    $ git stash apply <SHA-1>
  • もし、SHA-1 がわからない場合は、
    $ git fsck
    とすると、"dangling commit"(中間ファイルのようなもの)が列挙される。このどれかが消えたスタッシュ。
    上記操作で適用して地道に探してみる。

サーバーの入れ替えがあり、サーバーのアドレスが変わってしまった。


ローカルで1人で作業していたがチーム編成になり、今までの内容をメンバーに展開することになった。






gitの基礎


gitをインストール
gitサーバーのセットアップ
git ブランチについて
git 変更を一時的に退避 stash
git ブランチを合流するマージ
git ブランチを付け替える
git コミット履歴を変更する
git 変更をリセットする
git リモートでの操作
git ファイルの追跡
git リリース準備
git 変更をpatchファイルにする
git コンフリクトに対処する
git 失敗したときの復元


posted by Zorinos at 20:00| Comment(0) | Linux | 更新情報をチェックする

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 | 更新情報をチェックする
ブログランキング・にほんブログ村へ