カテゴリー「Linux」の5件の記事

【Git】 Gitリポジトリ構築(その2)

手始めに環境の確認を。

サーバ環境
OS:  ubuntu 10.04LTS Server
Git:  git vertion 1.7.0.4

クライアント環境
OS:  ubuntu 12.04LTS Desktop
Git:  git version 1.7.9.5

その他、Mac(OS X Lion)とWindowsからも使用予定。


  1. クライアント環境の準備
  2. ローカルリポジトリの作成
  3. ローカルリポジトリへのファイル登録・コミット
  4. ローカルリポジトリのファイル更新
  5. ローカルリポジトリのその他の操作
  6. サーバ環境の準備
  7. リモートリポジトリ(公開リポジトリ)の作成
  8. リモートリポジトリのアクセス方法
  9. ローカルリポジトリからリモートリポジトリへの変更公開
  10. リモートリポジトリからローカルリポジトリへの変更取り込み
  11. gitwebの立ち上げ

大体こんな順番ですかね。
その他の複雑な操作は追々...というか書籍とかWebとかマニュアルとかご参照ください。


1. クライアント環境の準備

$ sudo apt-get install git-core
$ git config --global user.name "名前"
$ git config --global user.email "メールアドレス"
$ git config --global color.ui "auto"

クライアント環境はこれ位で十分。
最後の一行はターミナルのカラー表示に関する設定です。
Gitのコマンドオプションはフルの場合が多いので(commitとかcheckoutとか)svnみたいに短縮形が使いたければ、それも設定してください。任意の名前が使えます。

$ git config --global alias.ci "commit"
$ git config --global alias.co "checkout"
$ git config --global alias.st "status"

これらの設定は~/.gitconfigに格納されるので、直接テキストエディタで変更してもOK。


2. ローカルリポジトリの作成

$ mkdir ~/git
$ cd ~/git
$ mkdir project
$ cd project
$ git init

Gitを使って複数のプロジェクトを管理するつもりなので、ワーク用のディレクトリを作成しその中に個別のプロジェクトディレクトリ(ローカルリポジトリ)を作ることにしました。最後の git init コマンドで、projectディレクトリがローカルリポジトリになります。


3. ローカルリポジトリへのファイル登録・コミット

$ touch README
$ git add README
$ git commit -m "コミットログ"

手始めに空っぽのREADMEファイルを作って、コミットしてみました。
Subversionと流れは同じです。addしてからcommitって感じですね。コミット時に-mオプションを省略すると適当なエディタを起動してコミットログを記入できるようになります。


4. ローカルリポジトリのファイル更新

$ vi README
(何か適当にテキストを記入してvi終了)
$ git add README
$ git commit -m "コミットログ"

ここでsvnとの違いが出てきます。
READMEは先程既にaddコマンドで登録したのに、なんでまた?と思いました。
実はGitでは作業領域とローカルリポジトリの間にステージという段階が入っているんですね。変更したファイルは一旦このステージにaddしてからリポジトリにcommitという手順になっているようです。これを一度にやるオプションもあります。

$ git commit -a -m "コミットログ"

このステージの使い方ですが、複数の理由から一気に沢山のファイルを変更した後、それぞれの理由に応じてコミットしたい時などに使えそうです。Subversionの場合はcommit対象のファイルを選択してcomitする必要がありましたが、ステージを使えば整理とコミットを明確に分けることができます。


5. ローカルリポジトリのその他の操作
$ git status (作業領域の状態表示)
$ git diff (ローカルリポジトリと作業領域の差分表示)
$ git log (ローカルリポジトリのコミットログ確認)
$ git log --graph --date-order -C -M (ローカルリポジトリのコミットログのツリー表示)
$ git branch "ブランチ名" (ブランチ切り替え、新規作成)
$ git branch (ローカルリポジトリのブランチ一覧表示)
$ git tag "タグ名" (ローカルリポジトリのタグ設定)
$ git tag (ローカルリポジトリのタグ一覧表示)
$ git checkout (ブランチ・タグの切り替え。svn switchと同等。)
$ git clone "リポジトリ名" (リポジトリのクローン化)
$ git push (ローカルリポジトリの変更をリモートリポジトリにアップロード)
$ git pull (リモートリポジトリの変更をローカルリポジトリにマージ)
$ git help (とりあえず困ったらこれ)

Gitではブランチの使い方が随分ダイナミックになっているようです。頻繁なマージを前提とした分散型の開発が主体になりますね。


6. サーバ環境の準備
ここからサーバ側での作業になります。

$ sudo apt-get install git-core
$ sudo apt-get install git-daemon-run
$ sudo apt-get install gitweb

ついでなんでgitwebパッケージもインストールしておきました。apache2とかの設定は完了している事が前提なので、その辺りご了承ください。あ、あとsshの公開鍵を登録して、パスワード認証をスキップしておくと色々と便利です。


7. リモートリポジトリ(公開リポジトリ)の作成
公開用のリモートリポジトリの作成方法は以下の2つがあります。

  • 既存のローカルリポジトリの公開
  • サーバ側で新規に公開リポジトリを作成

今回はローカルリポジトリを既に作っているので、これを公開するようにしましたが、一応両方のやりかたを載せておきます。

[ローカルリポジトリの公開](クライアント環境にsshログインできる必要があります)

$ sudo mkdir /git
$ sudo git clone --bare ユーザ名@クライアントIP:~/git/project /git/project.git
$ sudo chown -R gitdaemon:root /git

まず公開リポジトリの本体を格納するディレクトリを作成しました。
その後、--bareオプション付きのcloneコマンドで、クライアント環境にあるローカルリポジトリを公開リポジトリとして複製しています。この時、クライアント側にアクセスするのにsshを使っています。

[サーバ側で新規に公開リポジトリを作成]

$ sudo mkdir /git
$ sudo git init --bare /git/project.git
$ sudo chown -R gitdaemon:root /git

違いはクライアントのリポジトリをクローンしていたのをinitに変更しただけです。公開リポジトリの場合は --bare オプションが必要です。最後のアクセス権変更はgitプロトコルでアクセスした時にリポジトリに書き込めるようにするためです。ubuntuのgit-daemonはディフォルトではgitdaemonユーザ権限で起動するようなので。

最後にdaemonの設定をします。

$ sudo vi /etc/sv/git-daemon/run

最終行を以下のようにしてください。

/usr/lib/git-core/git-daemon --verbose --base-path=/git --export-all --enable=receive-pack

--base-pathは上記公開リポジトリを格納したディレクトリ名です。この設定では/git以下にある公開リポジトリ全てがこのデーモンでアクセスできます。--enable=receive-packというのはgitプロトコルで匿名アクセスでのアップロードを受け付けるための設定です。これが無いとgitプロトコルでのpushができません。

gitwebの設定は/etc/gitweb.confで行います。

$ sudo vi /etc/gitweb.conf

$projectroot = "/git"に変更するのを忘れないように。


7. リモートリポジトリのアクセス方法
クライアント環境からのリモートリポジトリ(公開リポジトリ)へのアクセスには以下の3種類があります。

  • gitプロトコル
  • ssh経由
  • webdav経由

一番手軽で高速なのがgitプロトコルでのアクセスです。ただし匿名アクセスになるので、セキュリティ面でもssh経由を推奨したいですね。今回は両方立ち上げましたけど。webdav経由は不要でしょう。クライアント環境でのそれぞれのアクセス方法は以下の通り。

[Gitプロトコル]

$ git clone git://サーバIP/project.git

[ssh経由]

$ git clone ユーザ名@サーバIP:/git/project.git

それぞれの指定したパスが異なる事に注意してください。


8. ローカルリポジトリからリモートリポジトリへの変更公開

$ git remote add origin git://サーバIP/project.git
$ git push --all

ま、大抵これで何とかなります。ローカルリポジトリの変更内容が全てリモートリポジトリに送信されます。remote addってのはリモートリポジトリのアクセス先(アクセス方法)をエイリアス化したような物です。originってのは特別なリモートリポジトリ名称で、git pushとかのコマンドでリモートリポジトリ名を指定しないとoriginが使われるようです。


9. リモートリポジトリからローカルリポジトリへの変更取り込み

$ git pull master

こっちもこれで大抵なんとかなるかな?originが既に設定されている事を前提としてます。masterというのはsvnで言う所のtrunkという解釈です。masterの代わりにブランチ名を指定すれば、任意のブランチにpullする事ができます。


10. gitwebの立ち上げ
もう設定はしちゃったんで、apache2のrestartさえしていれば、ブラウザで以下にアクセスできるはず。

http://サーバIP/gitweb/

これで/git以下の全公開リポジトリの参照がブラウザから行えます。
アクセス権の設定などはapache2の問題なので、それを参照してください。
設定するファイルは /etc/apache2/conf.d/gitweb です。


競合時のマージの話とか、肝心のブランチの話とかタグの事とか、もっと重要なバックアップを含めた運用方法の提案とか全く書いてないけど、まずは使ってみる事が肝心なので手順だけまとめておきました。後はやってみて、気が向いたら補足していくことにしますかな。

【Git】 Gitリポジトリ構築(その1)

もう10年近くになるかな?
ソフトウェアのバージョン管理にSubversionを使ってきました。その前は言わずもがなCVSで、さらにその前はRCS、会社ではSoftbenchCMやClearCaseなんかもありましたけど。

Subversionはディレクトリ管理も含んでいるので、ファイルの追加・削除・リネームなども追跡できて、かなり重宝してました。また基本的に低レベルのリポジトリ操作が不可能なので、ユーザが誤ってファイルやブランチを削除する事がない(削除されても逆マージで戻せる)という安全性もあって、作業に慣れない人を含む業務ベースで使う際にメリットがありました。

ただ不満が無いわけではありません。
Subversionの主な問題点を挙げると大体以下の通りかと。

  1. 集中型リポジトリなのでコミット時にサーバ接続が必要。
  2. DB型なので色んな意味でちょと重い。(初期のBerkleyDB使っていた時の話ですけど)
  3. ブランチ・タグがディレクトリと同義のため・・・(好みによる)
  4. リポジトリが肥大化する。(業務で使うとこれが深刻)
  5. バックアップに時間がかかる。(リポジトリが肥大化する事が根本原因です)
  6. 誤って行ったコミットを取り消せない。(パスワードとか暗号鍵とか入れちゃうと大変)

この辺りでしょうか。
はっきり言って、これらの問題点はSubversionの利点の裏返しでもあります。
とはいえ、サーバ接続していないとコミットできないという1番の問題だけは、集中型リポジトリの問題そのものなので解決しようがない。しかも昨今のクラウド環境やら、SOHOスタイルでは馴染まないのも事実ですね。

という事で、遅まきながらLinusさんがLinux Kernelのために開発したバージョン管理システム「Git」に移行する事としました。Git自体は2005年の発表された分散型バージョン管理システムで、個人でもグループでも使い勝手が良いかな?と思ったので、その検証もかねて自宅サーバに構築する事としたわけです。

Gitは上位リポジトリ(リモートリポジトリとも言う)にSubversionを使う事もできますが、今回は完全にGitに移行しています。Subversionで管理していたリポジトリも一部を移行してみました。

さて、手順については次の記事で。

【Linux】 安全なHDDのデータ消去方法

ubuntuでのHDDのデータ消去方法。
ご存知の通り、HDDはファイルを削除したりフォーマットしたりするだけではデータを削除する事はできない。そこで、アメリカの軍でも使用されているような乱数値を全面に3回以上記録するという方法で消去する必要があります。

WindowsだとHDDに物理的にアクセスする事ができないため、専用のソフトが必要になるのやけど、Linuxならshredというコマンドを使うことで簡単にできます。
ちなみにデバイスファイルに直接アクセスするのでroot権限が必要です。

まず消去対象のHDDがどのデバイスファイルにマップされているかを確認する。
dfやmount、dmesgコマンドなどで調べておきます。
次にshredコマンドを使ってデータを消去すると...

sudo shred -n 3 -v /dev/sdh

-nオプションは書き込みの回数を指定します。例では3回繰り返すという意味。-vはverboseモードを指定して途中経過などを表示します。最後は対象のHDDのデバイスファイルを指定します。ユーザ権限ではアクセスできないので、sudoを付けてroot権限で実行します。

とまぁ、この手の作業もLinuxなら楽やね。
最近、母親の古いノートPCを廃棄する必要があってデータ消去する必要があったので覚書しておきますだ。

P.S.
そういや、昔はddとかで適当なファイルやデータを上書きしてたなぁ。

【Linux Tips】 テキストファイルの一括置き換え/ファイル名の一括置き換え

久しぶりの覚書き。

perlを使った1ラインコマンドでのテキストファイルの一括置き換え方法

$ perl -p -w -i.bak -e "s/置換前文字列/置換後文字列/g" ファイル名

さらにfindを組み合わせ複数ファイルを一括処理する方法

以下のどちらでもOK。実は他にも色々と方法はある。

$ find . -name ファイル名パターン | xargs perl -p -w -i.bak -e "s/置換前文字列/置換後文字列/g"
$ find . -name ファイル名パターン -exec perl -p -w -i.bak -e "s/置換前文字列/置換後文字列/g" {} \;

もちろんperlの強力な正規表現が使えます。

ファイル名の一括置き換え方法

大量のファイルの拡張子を一気に変更とか、色々できまする。
通常は rename コマンドを使えば良いのだけど、CygwinとかMinGWではrenameが無いっぽい。
よって、シェルスクリプトと組み合わせて以下のようにすると良い。

$ find . -name ファイル名パターン | while read file; do mv $line `echo $file | sed -e 's/置換前文字列/置換後文字列/'`; done

う〜む、Linuxコマンドラインの世界は奥が深いですなぁ。


続きを読む "【Linux Tips】 テキストファイルの一括置き換え/ファイル名の一括置き換え" »

【Linux】 findコマンド

プログラム作ったり、写真を管理したりすると特定のディレクトリ以下について大量のファイル操作する事は結構あるわけです。
例えば・・・

  • 拡張子がbakのファイルを全て削除する
  • ファイル名にtestを含むファイルの数を数える
  • 拡張子jpgを全てpngに変更する(そんな事ないと思うけど
  • ディレクトリの一覧を表示する
  • .svnディレクトリ以外のファイルについて文字コードをUTF-8に変更する

等など。
実は、これ全部 find とその他のコマンドの組み合わせで実現できます。findは特定ディレクトリ以下の条件に当てはまるファイルやディレクトリを検索するコマンドです。めっちゃ便利やから良く使うねんけど。

基本的な使い方

find ディレクトリ
    指定ディレクトリ以下の全てのファイルとディレクトリを表示する
find ディレクトリ -type タイプ
    指定ディレクトリ以下の全てのタイプで指定したファイルorディレクトリを表示する
find ディレクトリ -name 名前
    指定ディレクトリ以下の全ての名前のファイルorディレクトリを表示する
find ディレクトリ -exec コマンド {} \;
    指定ディレクトリ以下の全てのファイルを引数にしてコマンドを実行する

凝った使い方

find . -name \.svn -type d -prune -or -type f -print
    カレントディレクトリ以下の.svnディレクトリ以外のディレクトリに含まれる全ファイルを表示する
find . -name \.svn -type d -exec rm -Rf {} \;
    カレントディレクトリ以下の全ての.svnディレクトリを削除する
    SubversionでチェックアウトしたディレクトリからSubversionの管理情報を削除する時に便利

findと組み合わせると便利なコマンド

grep
    ファイル内の文字列探索(-rコマンドでもできるけど、findの方が高度な検索が可能)
wc
    ファイルの情報を表示(行数とか単語数とか)
file
    ファイルの情報(キャラクタコードとか)を表示
mv/cp/rm
    ファイルのコピーやら移動やら削除やら
nkf
    ファイルの文字コードを変更
perl/sed
    ファイルの内容置き換え

かなり応用可能なコマンドですなぁ。