<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Apple Geek &#187; developer</title>
	<atom:link href="http://theapplegeek.ru/archives/tag/developer/feed" rel="self" type="application/rss+xml" />
	<link>http://theapplegeek.ru</link>
	<description>Чему ты научился сегодня?</description>
	<lastBuildDate>Sun, 06 May 2012 15:19:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
<atom:link rel="hub" href="http://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="http://superfeedr.com/hubbub"/>		<item>
		<title>Работа с репозиториями git через ssh/SOCKS-прокси</title>
		<link>http://theapplegeek.ru/archives/5578</link>
		<comments>http://theapplegeek.ru/archives/5578#comments</comments>
		<pubDate>Fri, 12 Aug 2011 04:44:25 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Linux & PC]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=5578</guid>
		<description><![CDATA[<p>Представим типичную конфигурацию сети, когда рабочие станции не имеют прямого доступа в Интернет. И нужно на одной из этих станций (далее - Host) получить доступ к репозиторию git, находящемся в Интернет, например, на GitHub (забудем на мгновенье, что доступ возможен и <a href="http://progit.org/2010/03/04/smart-http.html">через транспорт http</a>).</p>]]></description>
			<content:encoded><![CDATA[<p>Представим типичную конфигурацию сети, когда рабочие станции не имеют прямого доступа в Интернет. И нужно на одной из этих станций (далее &#8211; Host) получить доступ к репозиторию git, находящемся в Интернет, например, на GitHub (забудем на мгновенье, что доступ возможен и <noindex><a rel="nofollow" href="http://progit.org/2010/03/04/smart-http.html" >через транспорт http</a></noindex>).</p>
<p><span id="more-5578"></span></p>
<p>При попытке сделать clone на <noindex><a rel="nofollow" href="http://ethanschoonover.com/solarized" >Solarized</a></noindex> (мне эта подборка цветовых схем очень нравится), получим предсказуемый ответ:</p>
<pre>
host$ git clone git://github.com/altercation/solarized.git
<small>Initialized empty Git repository in /home/ole/bin/solarized/.git/
github.com[0: 207.97.227.239]: errno=Connection refused
fatal: unable to connect a socket (Connection refused)</small>
</pre>
<p>Но, к счастью, в сети есть сервер (назову его Gate), у которого есть доступ в Интернет.</p>
<p>На &#8220;ущемлённом&#8221; компьютере Host убеждаюсь, что установлен Netcat:</p>
<pre>
host$ nc -h
<small>OpenBSD netcat (Debian patchlevel 1.89-3ubuntu2)</small>
</pre>
<p>Если нет, то ставлю его (netcat есть практически во всех Unix).</p>
<p>Ubuntu/Debian:</p>
<pre>
host$ sudo aptitude install netcat-openbsd
</pre>
<p>Mac OS X (Homebrew):</p>
<pre>
host$ brew install netcat
</pre>
<p>Создаю файл (192.168.1.1 &#8211; адрес Gate, подкорректируйте):</p>
<pre>
host$ mkdir -p ~/bin
host$ vim ~/bin/git-proxy-wrapper.sh
#!/bin/sh
nc -x <b>192.168.1.1</b>:1080 -X 5 $*

host$ chmod +x ~/bin/git-proxy-wrapper.sh
</pre>
<p>Выставляю переменную окружения GIT_PROXY_COMMAND (сначала в текущей сессии, а потом можно добавить команду в .bash_profile):</p>
<pre>
host$ export GIT_PROXY_COMMAND=~/bin/git-proxy-wrapper.sh
</pre>
<p>Перехожу к Gate. Запускаю ssh в режиме SOCKS-прокси, прохожу аутентификацию (-N &#8211; чтобы не входить в shell, -f &#8211; перейти в фоновый режим):</p>
<pre>
gate$ ssh -D 192.168.1.1:1080 -Nf localhost
<small>ole@localhost's password: *******</small>
</pre>
<p>На Host запускаю клонирование, всё работает:</p>
<pre>
host$ git clone git://github.com/altercation/solarized.git
<small>Initialized empty Git repository in /home/ole/tmp/solarized/.git/
remote: Counting objects: 1991, done.
remote: Compressing objects: 100% (1288/1288), done.
remote: Total 1991 (delta 656), reused 1909 (delta 583)
Receiving objects: 100% (1991/1991), 33.03 MiB | 4.14 MiB/s, done.
Resolving deltas: 100% (656/656), done.</small>
</pre>
<p>Доступ получен. Приятно. Описанный метод работает как на Linux, так на Mac.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/5578/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Извлечение файлов ресурсов из приложений iOS и декодирование изображений png</title>
		<link>http://theapplegeek.ru/archives/5298</link>
		<comments>http://theapplegeek.ru/archives/5298#comments</comments>
		<pubDate>Mon, 11 Apr 2011 06:51:41 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=5298</guid>
		<description><![CDATA[Если вам вдруг захотелось достать из приложения iOS понравившуюся картинку, то это хоть и не элементарно, но вполне возможно. Почему не элементарно? Потому что по крайней мере часть png-файлов невозможно просмотреть из-за особенностей адаптации их под видеопамять iPhone и iPad.]]></description>
			<content:encoded><![CDATA[<p>Если вам вдруг захотелось достать из приложения iOS понравившуюся картинку, то это хоть и не элементарно, но вполне возможно. Почему не элементарно? Потому что по крайней мере часть png-файлов невозможно просмотреть из-за особенностей адаптации их под видеопамять iPhone и iPad.</p>
<p><span id="more-5298"></span></p>
<p>С какой целью &#8211; неважно, но понадобилось мне посмотреть на файлы изображений png в одной программе для iOS. Пусть это будет&#8230; Да, Remote.</p>
<p>Добраться до файлов просто. Заходим в iTunes, находим программу, Secondary Click на ней и &#8220;Show in Finder&#8221;:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/01_ipng-thumb.png" height="149" width="233" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Копирую найденный ipa-файл в удобное место для дальнейших разборок:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/02_ipng-thumb.png" height="27" width="193" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Изменяю расширение .ipa на .zip:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/03_ipng-thumb.png" height="22" width="185" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>И открываю архив, что приводит к извлечению файлов:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/04_ipng-thumb.png" height="62" width="392" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Захожу в Payload, выбираю файл приложения, Secondary Click, &#8220;Show Package Content&#8221;:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/05_ipng-thumb.png" height="127" width="500" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Вижу все файлы, входящие в программу:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/06_ipng-thumb.png" height="275" width="187" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Но вот незадача &#8211; содержимое части png-файлов не отображается:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/07_ipng-thumb.png" height="271" width="390" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Причины описаны в статьях &#8220;<noindex><a rel="nofollow" href="http://modmyi.com/wiki/index.php/Iphone_PNG_images" >iPhone PNG images</a></noindex>&#8221; и &#8220;<noindex><a rel="nofollow" href="http://iphonedevelopment.blogspot.com/2008/10/iphone-optimized-pngs.html" >iPhone &#8220;Optimized&#8221; PNGs</a></noindex>&#8220;. Если коротко, то XCode при упаковке приложения под iOS адаптирует png под особенности организации видеопамяти iPhone и iPad, а именно меняет местами октеты красного и синего цветов и модифицирует альфа-канал, чтобы при загрузке не производить дополнительные вычисления.</p>
<p>Копирую эти файлы в свежесозданный каталог, иконки предпросмотра пусты:</p>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/08_ipng-thumb.png" height="315" width="500" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Говорю спасибо <noindex><a rel="nofollow" href="http://www.axelbrz.com.ar/" >Axel E. Brzostowski</a></noindex> за программу <noindex><a rel="nofollow" href="http://www.axelbrz.com.ar/?mod=iphone-png-images-normalizer" >iPhone PNG Images Normalizer</a></noindex>, написанную на Python. Я пробовал две другие программы, но они часть файлов не могли раскодировать.</p>
<p>Списываю архив и раскручиваю программу в ~/bin:</p>
<pre>
$ curl "http://www.axelbrz.com.ar/ipin1.0.zip" -o ~/Downloads/ipin1.0.zip
$ mkdir -p ~/bin
$ unzip ~/Downloads/ipin1.0.zip -d ~/bin/
</pre>
<p>Я копировал ранее файлы в ~/Downloads/Rev/images. Смотрю, что не так с файлами. Посмотрите на нереальный размер и битность:</p>
<pre>
$ cd ~/Downloads/Rev/images/
$ file Bar-itunes.audiobooks.png
<small>Bar-itunes.audiobooks.png: PNG image, 805314562 x 284378236, 0-bit grayscale,</small>
</pre>
<p>Натравливаю на файлы скрипт:</p>
<pre>
$ cd ~/Downloads/Rev/images/
$ python ~/bin/ipin.py
<small>-----------------------------------
 iPhone PNG Images Normalizer v1.0
-----------------------------------

[+] Searching PNG files... ok

 -  12 PNG files were found at this folder (and subfolders).

[?] Do you want to normalize all images (Y/N)? Y
0.00% ./Bar-itunes.audiobooks.png
8.33% ./Bar-itunes.audiobooks@2x.png
16.67% ./Bar-itunes.computers.png
25.00% ./Bar-itunes.computers@2x.png
33.33% ./Bar-itunes.genres.png
41.67% ./Bar-itunes.genres@2x.png
50.00% ./Bar-itunes.iTunesU.png
58.33% ./Bar-itunes.iTunesU@2x.png
66.67% ./Bar-itunes.movies.png
75.00% ./Bar-itunes.movies@2x.png
83.33% ./Bar-itunes.music.albums.png
91.67% ./Bar-itunes.music.albums@2x.png

[+] 12 PNG files were normalized.</small>
</pre>
<p>Файлы починились? Да, всё в порядке:</p>
<pre>
$ file Bar-itunes.audiobooks.png
<small>Bar-itunes.audiobooks.png: PNG image, 22 x 26, 8-bit/color RGBA, non-interlaced</small>
</pre>
<p style="clear: both"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2011/04/09_ipng-thumb.png" height="318" width="500" style=" text-align: center; display: block; margin: 0 auto 10px;"  alt="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" title="Извлечение файлов ресурсов из приложений iOS и декодирование изображений png" /></p>
<p>Наслаждаюсь очередной решённой задачей.</p>
<p>P.S. А иконку для статьи я взял из файла iTunesArtwork, добавив к нему расширение .png.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/5298/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Как прочитать архив SMS из резервной копии iPhone в iTunes</title>
		<link>http://theapplegeek.ru/archives/4741</link>
		<comments>http://theapplegeek.ru/archives/4741#comments</comments>
		<pubDate>Mon, 15 Nov 2010 06:05:32 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[iTunes]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=4741</guid>
		<description><![CDATA[Случайно наткнулся на статью &#8220;How to Access and Read the iPhone SMS Text Message Backup Files&#8220;, рассказывающую, как прочитать архив SMS с iPhone из резервной копии, которую делает iTunes. Сразу же замечу, что если вы параноидальны и не хотите, чтобы ваши SMS прочитали, то криптуйте свои бекапы (панель опций на закладке Summary вашего iPhone): Бекапы [...]]]></description>
			<content:encoded><![CDATA[<p>Случайно наткнулся на статью &#8220;<noindex><a rel="nofollow" href="http://osxdaily.com/2010/07/08/read-iphone-sms-backup/" >How to Access and Read the iPhone SMS Text Message Backup Files</a></noindex>&#8220;, рассказывающую, как прочитать архив SMS с iPhone из резервной копии, которую делает iTunes.</p>
<p>Сразу же замечу, что если вы параноидальны и не хотите, чтобы ваши SMS прочитали, то криптуйте свои бекапы (панель опций на закладке Summary вашего iPhone):</p>
<p style="clear: both"><noindex><a rel="nofollow" href="http://images.theapplegeek.ru/wp-content/uploads/2010/11/01_sms-full.png"  class="image-link"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2010/11/01_sms-thumb.png" height="190" width="397" style=" text-align: center; display: block; margin: 0 auto 10px;" /></a></noindex></p>
<p><span id="more-4741"></span></p>
<p>Бекапы iOS-устройств находятся в каталоге ~/Library/Application Support/MobileSync/Backup. Меня интересует список, отсортированный в порядке проведения бекапов, для этого использую &#8220;ls -lt&#8221;:</p>
<pre>
$ cd "~/Library/Application Support/MobileSync/Backup"
$ ls -lt
<small>drwxr-xr-x  6026 ctrld  staff  204884 Nov 12 16:34 09213b6660a22d13977258d480ced2a880ff8390
drwxr-xr-x  5633 ctrld  staff  191522 Oct 19 23:07 09213b6660a22d13977258d480ced2a880ff8390-20101019-230647</small>
</pre>
<p>Имя состоит из UDID устройства и времени формирования предыдущих копий.</p>
<p style="clear: both"><noindex><a rel="nofollow" href="http://images.theapplegeek.ru/wp-content/uploads/2010/11/02_sms-full.png"  class="image-link"><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2010/11/02_sms-thumb.png" height="121" width="500" style=" text-align: center; display: block; margin: 0 auto 10px;" /></a></noindex></p>
<p>Метод, приведённый в указанной выше <noindex><a rel="nofollow" href="http://osxdaily.com/2010/07/08/read-iphone-sms-backup/" >статье</a></noindex> не работает &#8211; файлы с расширением .mddata и .mdbackup в моём бекапе отсутствуют. Поэтому ищу почти наугад.</p>
<h3>Первый способ &#8211; поиск по известному фрагменту текста</h3>
<p>Я знаю, что мне приходил SMS из банка о снятии денег за программу из iTunes в пользу &#8220;ITUNES-USD&#8221;. Нахожу grep&#8217;ом файл, убеждаюсь, что это SQLite:</p>
<pre>
$ cd "~/Library/Application Support/MobileSync/Backup/"
$ cd 09213b6660a22d13977258d480ced2a880ff8390
$ grep ITUNES-USD *
<small>Binary file 3d0d7e5fb2ce288813306e4d4636395e047a3d28 matches</small>
$ file 3d0d7e5fb2ce288813306e4d4636395e047a3d28
<small>3d0d7e5fb2ce288813306e4d4636395e047a3d28: SQLite 3.x database</small>
</pre>
<h3>Второй способ &#8211; поиск по структуре базы</h3>
<p>Сделал скрипт 1.sh, который снимает схемы всех баз SQLite (в него нужно вставить ваши данные):</p>
<pre>
#!/bin/bash
UDID=09213b6660a22d13977258d480ced2a880ff8390

dir=~/Library/Application\ Support/MobileSync/Backup/$UDID
if [ -e "$dir" ]; then
	echo "Time: $(date)"
else
	echo "Directory $dir does not exists"
	exit
fi

cd "${dir}"
lst=$(file * | grep SQLite | awk -F : '{print $1}')

for l in ${lst}; do
	echo ${l}
	echo ".schema" | sqlite3 ${l}
done
echo "Time: $(date)"
</pre>
<p>Запускаю скрипт, записываю вывод в файл:</p>
<pre>
$ ./1.sh > 1.out
</pre>
<p>Ищу в результатах строку &#8220;CREATE TABLE message&#8221; &#8211; именно так определяется таблица с SMS. Нахожу нужный файл, у меня это 3d0d7e5fb2ce288813306e4d4636395e047a3d28.</p>
<h3>Вывод данных</h3>
<p>Копирую найденный файл в рабочий каталог</p>
<pre>
$ cp "~/Library/Application Support/MobileSync/Backup/09213b6660a22d13977258d480ced2a880ff8390/3d0d7e5fb2ce288813306e4d4636395e047a3d28" ~/sms.sqlite
</pre>
<p>Открываю, смотрю схему (несколько приёмов работы с SQLite я приводил в <a href="http://theapplegeek.ru/archives/3520" >статье по Mail.app</a>):</p>
<pre>
$ sqlite3 sms.sqlite
sqlite&gt; .schema
<small>CREATE TABLE _SqliteDatabaseProperties (key TEXT, value TEXT, UNIQUE(key));
CREATE TABLE group_member (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, address TEXT, country TEXT);
CREATE TABLE message (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, address TEXT, date INTEGER, text TEXT, flags INTEGER, replace INTEGER, svc_center TEXT, group_id INTEGER, association_id INTEGER, height INTEGER, UIFlags INTEGER, version INTEGER, subject TEXT, country TEXT, headers BLOB, recipients BLOB, read INTEGER);
CREATE TABLE msg_group (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, type INTEGER, newest_message INTEGER, unread_count INTEGER, hash INTEGER);
CREATE TABLE msg_pieces (ROWID INTEGER PRIMARY KEY AUTOINCREMENT, message_id INTEGER, data BLOB, part_id INTEGER, preview_part INTEGER, content_type TEXT, height INTEGER, version INTEGER, flags INTEGER, content_id TEXT, content_loc TEXT, headers BLOB);
...</small>
</pre>
<p>Делаю выборку из messages:</p>
<pre>
sqlite&gt; select * from message;
<small>...
2925|10060|1289398514|Parol: 11111111 www.privat24.ua -- Modem naprokat za 0 grn. v mesyats. Zakagi na privat24.ua i plati za Internet 60 ili 80 grn.|2|0||481|0|0|0|0||ua|||0
...</small>
</pre>
<p>Данные видны, а уже с ними можно работать.</p>
<p>Если вы ищете клиент под Mac OS X, то не смотрите на <noindex><a rel="nofollow" href="http://www.razorsql.com/" >RazorSQL</a></noindex> &#8211; такого кроссплатформенного уродца (да ещё и небесплатного) я давненько не встречал. Посмотрите <noindex><a rel="nofollow" href="http://stackoverflow.com/questions/100959/mac-sqlite-editor" >обсуждение</a></noindex> на StackOverflow и <noindex><a rel="nofollow" href="http://www.barefeetware.com/sqlite/compare/" >сравнительную таблицу</a></noindex> клиентов. Посоветовать ничего не могу, я их не смотрел, мне достаточно консоли.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/4741/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Работа с ветвями git</title>
		<link>http://theapplegeek.ru/archives/4547</link>
		<comments>http://theapplegeek.ru/archives/4547#comments</comments>
		<pubDate>Fri, 08 Oct 2010 15:09:18 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=4547</guid>
		<description><![CDATA[Недавно мне попалась на глаза статья о правильном использовании веток git при разработке приложений: &#8220;A successful Git branching model&#8220;. Я не профессиональный разработчик, и для меня это было откровением &#8211; все те мысли, к которым я пришёл сам или был на пути к ним, описаны системно и просто. Очень рекомендую ознакомиться. P.S. С этой заметки [...]]]></description>
			<content:encoded><![CDATA[<p>Недавно мне попалась на глаза статья о правильном использовании веток git при разработке приложений: &#8220;<noindex><a rel="nofollow" href="http://nvie.com/posts/a-successful-git-branching-model/" >A successful Git branching model</a></noindex>&#8220;. Я не профессиональный разработчик, и для меня это было откровением &#8211; все те мысли, к которым я пришёл сам или был на пути к ним, описаны системно и просто. Очень рекомендую ознакомиться.</p>
<p style="clear: both"><noindex><a rel="nofollow" href="http://nvie.com/posts/a-successful-git-branching-model/" ><img class="linked-to-original" src="http://images.theapplegeek.ru/wp-content/uploads/2010/10/Screen-shot-2009-12-24-at-11-thumb.32.1.png" height="570" width="427" style=" text-align: center; display: block; margin: 0 auto 10px;" /></a></noindex></p>
<p>P.S. С этой заметки ввожу отдельную категорию &#8220;Ссылки&#8221;, в которую будут попадать мои находки.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/4547/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Упрощение установки git с помощью Homebrew</title>
		<link>http://theapplegeek.ru/archives/4450</link>
		<comments>http://theapplegeek.ru/archives/4450#comments</comments>
		<pubDate>Mon, 13 Sep 2010 11:07:34 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=4450</guid>
		<description><![CDATA[Ранее я описывал установку git с помощью пакета git-osx-installer. Это нормальный способ, но если использовать менеджер пакетов Homebrew (а для меня это уже &#8220;must have&#8221;), то процесс можно упростить. Для начала нужно поставить XCode. Потом &#8211; выполняем действия, описанные в статье о Homebrew, но с небольшой добавкой. $ curl http://gist.github.com/gists/323731/download -o install_homebrew.tar.gz $ tar xvfz [...]]]></description>
			<content:encoded><![CDATA[<p>Ранее я описывал установку git с помощью <a href="http://theapplegeek.ru/archives/3464" >пакета git-osx-installer</a>. Это нормальный способ, но если использовать менеджер пакетов <a href="http://theapplegeek.ru/archives/3570" >Homebrew</a> (а для меня это уже &#8220;must have&#8221;), то процесс можно упростить.</p>
<p>Для начала нужно поставить <noindex><a rel="nofollow" href="http://developer.apple.com/technologies/xcode.html" >XCode</a></noindex>. Потом &#8211; выполняем действия, описанные в статье о <a href="http://theapplegeek.ru/archives/3570" >Homebrew</a>, но с небольшой добавкой.</p>
<pre>
$ curl http://gist.github.com/gists/323731/download -o install_homebrew.tar.gz
$ tar xvfz install_homebrew.tar.gz
x gist323731-3535cf3d066ed38db4e99d3f1f4a409fc07eda54/
x gist323731-3535cf3d066ed38db4e99d3f1f4a409fc07eda54/install_homebrew.rb
$ cd gist323731*
$ chmod +x install_homebrew.rb
$ ./install_homebrew.rb
</pre>
<p><span id="more-4450"></span></p>
<p>Добавка вот:</p>
<pre>
$ brew install git
</pre>
<p>Вуаля, дополнительный пакет git-osx-installer не нужен.</p>
<p>Остаётся прописать пути в .bashrc (я теперь для упрощения настройки делаю симлинк с .bashrc на .bash_profile):</p>
<pre>
$ vim ~/.bashrc
source /usr/local/etc/bash_completion.d/git-completion.bash

PATH="/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11/bin:/usr/local/bin:/usr/local/sbin"
export PATH

PS1='\[\033[0m\]\[\033[36m\]\A \[\033[0m\]\[\033[36m\][\[\033[0m\]\[\033[32m\]\u@\[\033[0m\]\[\033[37m\]\h\[\033[0m\]\[\033[36m\]][\[\033[1m\]\[\033[31m\]\w\[\033[0m\]\[\033[37m\]$(__git_ps1 " (%s)")\[\033[0m\]\[\033[36m\]\[\033[0m\]\[\033[36m\]]\[\033[0m\] '

$ ln -s ~/.bashrc ~/.bash_profile
</pre>
<p>И настроить git (можно воспользоваться <a href="http://theapplegeek.ru/archives/3464" >моим рецептом</a>).</p>
<p>Разве что можно расширить содержимое ~/.gitignore:</p>
<pre>
###
# .gitignore
# Mac OS X Finder and whatnot
.DS_Store
 
# XCode (and ancestors) per-user config (very noisy, and not relevant)
*.mode1
*.mode1v3
*.mode2v3
*.perspective
*.perspectivev3
*.pbxuser

# Generated files
VersionX-revision.h

# Textmate - if you build your xcode projects with it
*.tm_build_errors

# build products
build/
*.[oa]
 
# Other source repository archive directories (protects when importing)
.hg
.svn
CVS
 
# automatic backup files
*~.nib
*.swp
*~
*(Autosaved).rtfd/
Backup[ ]of[ ]*.pages/
Backup[ ]of[ ]*.key/
Backup[ ]of[ ]*.numbers/"
</pre>
<p>P.S. Поздравляю читателей <noindex><a rel="nofollow" href="http://ru.wikipedia.org/wiki/День_программиста" >с днём программиста</a></noindex>!</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/4450/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Книги для начинающих программистов под iOS</title>
		<link>http://theapplegeek.ru/archives/4146</link>
		<comments>http://theapplegeek.ru/archives/4146#comments</comments>
		<pubDate>Mon, 19 Jul 2010 13:27:33 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[iPad]]></category>
		<category><![CDATA[iPhone]]></category>
		<category><![CDATA[Mac]]></category>
		<category><![CDATA[books]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=4146</guid>
		<description><![CDATA[Профессионально я перестал занимался программированием лет десять назад (писал системы на разных языках, но предпочитал C и C++, как под DOS, так и под Windows), перейдя в область сетевого/системного администрирования. Конечно же, я продолжал писать, но уже на скриптовых языках Shell, Perl, немного TCL и Python. Год назад во время общения с разработчиком Blogo мне [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://images.theapplegeek.ru/wp-content/uploads/2010/07/01_loc-thumb1.png" height="224" align="right" width="170" style=" display: inline; float: right; margin: 0 0 10px 10px;" /></p>
<p>Профессионально я перестал занимался программированием лет десять назад (писал системы на разных языках, но предпочитал C и C++, как под DOS, так и под Windows), перейдя в область сетевого/системного администрирования. Конечно же, я продолжал писать, но уже на скриптовых языках Shell, Perl, немного TCL и Python.</p>
<p>Год назад во время общения с разработчиком Blogo мне снова захотелось &#8220;вернуться в семью&#8221;, и я начал присматриваться к программированию под Mac OS X. Ничего тогда толком не написал, но немного в Objective-C разобрался. Язык мне очень понравился, даже несмотря на лёгкое презрение к нему хардкорных программистов.</p>
<p>Потом у меня появилась идея нескольких приложений под iPhone и тут программирование более плотно вошло в мою жизнь. По основному роду деятельности у меня достаточно серьёзная занятость, поэтому приходится урывать для программирования время вечерами. Но хватит самооправданий &#8211; расскажу о тех книгах, по которым я учился и с которыми продолжаю работать (спасибо Артёму, который глядя на скриншоты программ чтения pdf под iPad задал мне вопрос о том, какие книги по программированию я бы мог порекомендовать).</p>
<p><span id="more-4146"></span></p>
<p>Итак, вот мой список. Сразу скажу &#8211; все книги я или купил в электронном виде, или получил доступ через <noindex><a rel="nofollow" href="http://my.safaribooksonline.com/" >SafariBooksOnline</a></noindex>.</p>
<p>Начальные знания по Objective-C я получил из двух книг:</p>
<ul>
<li>Mark Dalrymple, Scott Knaster. <noindex><a rel="nofollow" href="http://apress.com/book/view/9781430218159" >Learn Objective–C on the Mac</a></noindex></li>
<li>Stephen G. Kochan. <noindex><a rel="nofollow" href="http://my.safaribooksonline.com/9780321605559" >Programming in Objective-C 2.0</a></noindex> (2nd Edition). Скоро будет <noindex><a rel="nofollow" href="http://www.amazon.com/Programming-Objective-C-2-0-Developers-Library/dp/0321711394/ref=dp_ob_title_bk" >третья редакция</a></noindex> книги.</li>
</ul>
<p>По iOS мне очень помогли такие книги:</p>
<ul>
<li>Jeff LaMarche, David Mark. <noindex><a rel="nofollow" href="http://apress.com/book/view/9781430224594" >Beginning iPhone 3 Development: Exploring the iPhone SDK</a></noindex>.</li>
<li>Jeff LaMarche, David Mark. <noindex><a rel="nofollow" href="http://apress.com/book/view/9781430225058" >More iPhone 3 Development: Tackling iPhone SDK 3</a></noindex>. Если вы купите первую книгу, то на эту даётся скидка 50%.</li>
<li>Erica Sadun. <noindex><a rel="nofollow" href="http://my.safaribooksonline.com/9780321670168" >The iPhone Developer&#8217;s Cookbook 2nd Edition</a></noindex>. Книга на мой взгляд слишком много тянет с iPhone SDK 2.0, но некоторые рецепты можно посмотреть.</li>
<li>Toby Boudreaux. <noindex><a rel="nofollow" href="http://my.safaribooksonline.com/9780596805760" >Programming the iPhone User Experience</a></noindex>. Достойная книга, полистал и выборочно почитал, рекомендую.</li>
<li>Maher Ali. <noindex><a rel="nofollow" href="http://my.safaribooksonline.com/9780470683989" >iPhone SDK 3 Programming: Advanced Mobile Development for Apple iPhone and iPod touch</a></noindex>. Прочитал главу по Map Kit, книга понравилась.</li>
<li>Gary Bennett, Wolfgang Ante, Benjamin Jackson, Neil Mix, Steven Peterson, Matthew Rosenfeld, Michael Ash. <noindex><a rel="nofollow" href="http://apress.com/book/view/9781430223573" >iPhone Cool Projects</a></noindex>. Интересно почитать истории ведущих разработчиков с примерами кода.</li>
<li>Ben Britten Smith, Danton Chin, Arne de Vries, Claus Hoefele, Ben Kazez, Saul Mora, Leon Palm, Scott Penberthy, Charles Smith, David Smith, Joost van de Wijgerd. <noindex><a rel="nofollow" href="http://apress.com/book/view/9781430229223" >More iPhone Cool Projects</a></noindex>. Эту книгу ещё не смотрел.</li>
<li>James Bucanek. <noindex><a rel="nofollow" href="http://www.amazon.com/Professional-Xcode-Wrox-Programmer/dp/0470525223" >Professional Xcode 3</a></noindex>. Её я листал в виде образца под Amazon Kindle, стоит почитать для понимания XCode.</li>
</ul>
<p>Книги по системе контроля версий (я использую Git):</p>
<ul>
<li>Jon Loeliger. <noindex><a rel="nofollow" href="http://my.safaribooksonline.com/9780596158187" >Version Control with Git</a></noindex></li>
<li>Scott Chacon. <noindex><a rel="nofollow" href="http://progit.org/" >Pro Git</a></noindex>. Книга бесплатная.</li>
</ul>
<p>Буду благодарен за рекомендации книг по Objective-C, XCode, iOS и Mac OS X, которые используете вы.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/4146/feed</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Процесс ведения заметок с применением git</title>
		<link>http://theapplegeek.ru/archives/3864</link>
		<comments>http://theapplegeek.ru/archives/3864#comments</comments>
		<pubDate>Thu, 27 May 2010 10:28:14 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=3864</guid>
		<description><![CDATA[Меня в последнее время унесло в дебри, более близкие разработчикам и системным администраторам, чем обычным пользователям Mac&#8217;ов. Что поделаешь &#8211; что делаю, о том и пою. Буду стараться разбавить эту тематику материалами, интересными широкому кругу людей, но пока продолжу углубляться. Я в процессе работы делаю заметки и готовлю фрагменты конфигураций, записывая их в текстовые файлы [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://images.theapplegeek.ru/wp-content/uploads/2010/05/00_git-thumb11.png" height="106" align="right" width="143" style=" display: inline; float: right; margin: 0 0 10px 10px;" /></p>
<p>Меня в последнее время унесло в дебри, более близкие разработчикам и системным администраторам, чем обычным пользователям Mac&#8217;ов. Что поделаешь &#8211; что делаю, о том и пою. Буду стараться разбавить эту тематику материалами, интересными широкому кругу людей, но пока продолжу углубляться.</p>
<p>Я в процессе работы делаю заметки и готовлю фрагменты конфигураций, записывая их в текстовые файлы вида 20100527.txt &#8211; один файл на каждый день. Удобно то, что при необходимости можно посмотреть, что и как именно я делал. Увеличение продуктивности налицо, так как мне не приходится делать множество вещей с нуля.</p>
<p>При всём удобстве такого метода у него есть недостаток &#8211; отсутствие синхронизации. Мне приходится работать и за рабочей станцией, и за домашним компьютером, и за несколькими ноутбуками. И в каждом месте я делаю новые заметки и использую старые.</p>
<p><span id="more-3864"></span></p>
<p>Dropbox хорош, спора нет. Но это практически публичный сервис, и хранить там информацию, которую можно приравнять к конфиденциальной, сомнительное решение. Шифровать заметки можно сторонними утилитами, под Mac OS X удобно пользоваться зашифрованными образами SparseImageBundle, но кроме Mac&#8217;ов я использую и Windows, и Linux, и FreeBSD. <noindex><a rel="nofollow" href="http://www.truecrypt.org/" >TrueCrypt</a></noindex> кроссплатформенный, но я слыхал о случаях повреждения данных. Поэтому я не храню заметки в Dropbox.</p>
<p>Таскать с собой флешку &#8211; плохое решение. Не носить же её на цепочке на шее, а если хранить её в кармане джинсов, то можно надеть другие и потерять доступ к нужным данным. Кроме того я регулярно забывал вынять флешку из компьютера после окончания работы.</p>
<p>Хороший вариант &#8211; иметь сервер, к которому можно подключиться по ssh, и там в едином месте держать все заметки. Вопрос синхронизации снимается. Я работал в таком режиме года четыре. Но&#8230; Не всегда удобно работать с данными через vim в консоли, изредка хочется использовать тот же TextMate или gEdit/Linux. Да и бывают ситуации, когда Интернет недоступен, но данные нужны. Получаются заметки, сделанные в нескольких местах, и синхронизировать приходится их вручную, что неудобно.</p>
<p>Теперь я активно использую git (не сказал бы, что на продвинутом уровне, но стремлюсь к этому). И в процессе его изучения у меня возникла мысль применить его и для задачи ведения заметок.</p>
<p>Git на Mac&#8217;е <a href="http://theapplegeek.ru/archives/3464" >установлен</a>, приватный внешний репозиторий <a href="http://theapplegeek.ru/archives/3843" >тоже есть</a> (а если нет, то можно создать его бесплатно на сервисе <noindex><a rel="nofollow" href="http://www.assembla.com/" >Assembla</a></noindex> &#8211; спасибо hakka, или же платно на <noindex><a rel="nofollow" href="https://github.com/" >GitHub</a></noindex>). Самое время пользоваться простыми благами системы контроля версий.</p>
<p>Начнём с начала. Создадим каталог заметок (можно использовать существующий с наработанными данными) и инициализируем локальный репозиторий git:</p>
<pre>
$ mkdir ~/Documents/Notes
$ cd ~/Documents/Notes
$ touch Readme
$ git init
$ git add .
$ git commit -a -m "Initial commit"
</pre>
<p>Добавляем внешний репозиторий (процесс зависит от сервиса, для gitosis <a href="http://theapplegeek.ru/archives/3843" >я рассказывал</a>, как это делать):</p>
<pre>
$ git remote add origin gitosis@git.host.com:Notes.git
</pre>
<p>Записываем данные во внешний репозиторий:</p>
<pre>
$ git push origin master
</pre>
<p>Всё это я делал на ноутбуке ole-mac. Теперь я хочу начать работу с рабочей станции ole-linux. Захожу на неё и клонирую репозиторий (доступ должен быть предварительно организован, я это описывал для <a href="http://theapplegeek.ru/archives/3843" >gitosis</a>):</p>
<pre>
ole-linux$ cd ~/Documents
ole-linux$ git clone gitosis@git.host.com:Notes.git
</pre>
<p>Изменяю существующую заметку 20100526.txt и создаю новую 20100527.txt:</p>
<pre>
ole-linux$ cd ~/Documents/Notes
ole-linux$ date >> 20100526.txt
ole-linux$ echo "Hello from ole-linux" > 20100527.txt
</pre>
<p>Добавляю новую заметку в локальный репозиторий (иначе она не будет отслеживаться и не будет записана во внешний репозиторий):</p>
<pre>
ole-linux$ git add 20100527.txt
</pre>
<p>Можно также делать просто &#8211; добавлять все новые файлы одной командой:</p>
<pre>
ole-linux$ git add .
</pre>
<p>Делаю commit изменений:</p>
<pre>
ole-linux$ git commit -a -m "ole-linux, плановая работа"
</pre>
<p>Записываю изменения во внешний репозиторий:</p>
<pre>
ole-linux$ git push origin master
</pre>
<p>Возвращаюсь на ноутбук, списываю изменения:</p>
<pre>
ole-mac$ cd ~/Documents/Notes
ole-mac$ git pull origin master
</pre>
<p>Работаю с данными, вношу изменения, делаю commit:</p>
<pre>
ole-mac$ git add .
ole-mac$ git commit -a -m "ole-mac, новые заметки"
</pre>
<p>Передаю данные во внешний репозиторий:</p>
<pre>
ole-mac$ git push origin master
</pre>
<p>На всех рабочих местах у меня теперь есть доступ к нужным данным, при этом я могу следить за историей изменений.</p>
<p>Телодвижений много, но скоро это входит в привычку, особенно если git используется и для других задач. Главное в конце работы сделать commit/push, а при приходе на другое место &#8211; pull/push.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/3864/feed</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>autossh и доступ к внешним репозиториям git</title>
		<link>http://theapplegeek.ru/archives/3856</link>
		<comments>http://theapplegeek.ru/archives/3856#comments</comments>
		<pubDate>Tue, 25 May 2010 10:10:13 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=3856</guid>
		<description><![CDATA[Представим ситуацию &#8211; есть сервер, соединение с которым должно быть всегда активным, даже если в shell нет никакой активности. Или же должен постоянно работать туннель ssh. Обычный ssh при разрыве соединения не производит его переустановку (разве что можно посылать alive-пакеты, но это действует для активных сессий: ssh -o ServerAliveInterval=10 host.com). Вот, например, такую картину я [...]]]></description>
			<content:encoded><![CDATA[<p>Представим ситуацию &#8211; есть сервер, соединение с которым должно быть всегда активным, даже если в shell нет никакой активности. Или же должен постоянно работать <a href="http://theapplegeek.ru/archives/2285" >туннель ssh</a>. Обычный ssh при разрыве соединения не производит его переустановку (разве что можно посылать alive-пакеты, но это действует для активных сессий: ssh -o ServerAliveInterval=10 host.com).</p>
<p>Вот, например, такую картину я вижу постоянно при соединении со своим сервером, когда сессия неактивна долгое время:</p>
<pre>
$ ssh host.com
<small>Linux host.com 2.6.32.12-linode25 #1 SMP Wed Apr 28 19:25:11 UTC 2010 i686</small>

20:51 [ctrld@host][~]
17:14 [ctrld@host][~] Write failed: Broken pipe
</pre>
<p>Через какое-то время я получаю &#8220;Write failed: Broken pipe&#8221;. В данном случае переподключиться вручную просто, но всегда найдётся ситуация, когда это сделать гораздо труднее.</p>
<p><span id="more-3856"></span></p>
<p>Но есть полезная терминальная программа <noindex><a rel="nofollow" href="http://www.harding.motd.ca/autossh/" >autossh</a></noindex>. Она запускает ssh, производит мониторинг сессии и при необходимости её рестартует.</p>
<p>Устанавливаем autossh с помощью <a href="http://theapplegeek.ru/archives/3570" >Homebrew</a>:</p>
<pre>
$ brew update
$ brew install autossh
</pre>
<p>Ключи (если они необходимы) аналогичны ключам ssh, а особенности можно посмотреть в &#8220;man autossh&#8221;.</p>
<p>Теперь моя сессия с сервером держится до момента, когда я сам не выйду:</p>
<pre>
$ autossh host.com
<small>Linux host.com 2.6.32.12-linode25 #1 SMP Wed Apr 28 19:25:11 UTC 2010 i686</small>

10:03 [ctrld@host][~]
...
20:39 [ctrld@host][~] logout
</pre>
<p>На идею использования autossh меня натолкнуло обсуждение на <noindex><a rel="nofollow" href="http://stackoverflow.com/questions/1264262/connecting-to-gitosis-server-through-an-ssh-tunnel" >StackOverflow</a></noindex> по поводу организации доступа к внешним репозиториям git с хостов, которые не могут напрямую соединиться с ним по ssh.</p>
<p>Идея решения такова &#8211; в локальной сети должен быть хост dmz.host.com, имеющий возможность соединения по ssh с внешним репозиторием. Через этот хост строится туннель <a href="http://theapplegeek.ru/archives/2285" >ssh</a>:</p>
<pre>
internal.host.com$ autossh -M 20000 -f -N -L 2222:git.host.com:22 user@dmz.host.com
</pre>
<p>Затем на внутреннем хосте в <a href="http://theapplegeek.ru/archives/3729" >~/.ssh/config</a> описывается, что нужно ходить на репозитории через туннель:</p>
<pre>
Host git.host.com
        HostName localhost
        Port 2222
</pre>
<p>Уточню &#8211; я пока этот рецепт не использую и работоспособность не протестировал. Однако всё выглядит очень правдоподобно.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/3856/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Внешний репозиторий для git (gitosis/Ubuntu)</title>
		<link>http://theapplegeek.ru/archives/3843</link>
		<comments>http://theapplegeek.ru/archives/3843#comments</comments>
		<pubDate>Wed, 19 May 2010 09:28:15 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Linux & PC]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=3843</guid>
		<description><![CDATA[Git &#8211; это распределённая система контроля версий (Version Control System или же VCS). На первый взгляд может показаться, что её можно использовать только в применении к программированию, но это не совсем так. Да, заниматься программированием без какой-либо системы VCS &#8211; это признак низкой квалификации. Можно провести аналогию между таким программистом и системным администратором, не делающим [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://images.theapplegeek.ru/wp-content/uploads/2010/02/git_code_tshirt-p235397653474600864t5tr_1-thumb1.jpg" height="160" align="right" width="160" style=" display: inline; float: right; margin: 0 0 10px 10px;" /></p>
<p><a href="http://theapplegeek.ru/archives/3464" >Git</a> &#8211; это распределённая система контроля версий (Version Control System или же VCS). На первый взгляд может показаться, что её можно использовать только в применении к программированию, но это не совсем так.</p>
<p>Да, заниматься программированием без какой-либо системы VCS &#8211; это признак низкой квалификации. Можно провести аналогию между таким программистом и системным администратором, не делающим резервные копии своих серверов. Оба имеют работу только до первой потери данных.</p>
<p>Но применение VCS вообще и Git в частности гораздо шире, чем область программирования. Если что-то требует слежения за версионностью, то потенциально к нему можно использовать VCS. В качестве примера могу привести систему <noindex><a rel="nofollow" href="http://segfault.in/2010/03/keep-track-of-configuration-changes-using-etckeeper/" >etckeeper</a></noindex>, которая хранит в VCS (git, bazaar, mercurial, etc) изменения в конфигурационных файлах /etc.</p>
<p>При применении VCS нужно использовать здравый смысл &#8211; желательно не хранить в VCS часто изменяемые большие бинарные данные вроде видео.</p>
<p><span id="more-3843"></span></p>
<p>Для git очень желательно использовать внешний репозиторий (можно хранить данные в локальном репозитории, находящемся в каталоге с данными, но в случае выхода из строя диска никакая версионность не спасёт).</p>
<p>Я использовал для этого популярный сервис <noindex><a rel="nofollow" href="http://github.com/" >GitHub</a></noindex>. При всех достоинствах у него есть и недостатки. Если вы работаете над публичными проектами, то он бесплатен. Но если же вы хотите иметь приватный репозиторий, к которому не будет иметь доступ любой желающий, то за это уже <noindex><a rel="nofollow" href="http://github.com/plans" >нужно платить</a></noindex>. Самый дешёвый план Micro с 5 приватными репозиториями и не слишком большим дисковым пространством (сейчас на странице заказа не указывается размер, раньше вроде было порядка 600 MB) стоит $7 в месяц.</p>
<p>Деньги небольшие, но если по какой-то причине нужно хранить гораздо больше данных (например, web-сайт с файлами изображений), то придётся раскошелиться.</p>
<p>Решение есть. Можно организовать &#8220;self-hosted git repository&#8221; используя <noindex><a rel="nofollow" href="http://eagain.net/gitweb/?p=gitosis.git" >gitosis</a></noindex>.</p>
<p>Внешний репозиторий подразумевает запуск его на внешнем сервере. К сожалению, у меня нет сервера под Mac OS X, располагающемся на внешнем хостинге, поэтому я нарушу тематику блога и расскажу, как установить gitosis на Ubuntu Server 9.04. Если вам нужен именно Mac OS X, то посмотрите, например, статью &#8220;<noindex><a rel="nofollow" href="http://molind.habrahabr.ru/blog/58418/#habracut" >Разворачиваем сервер git на Mac OS X Leopard&#8221;.</a></noindex></p>
<p>Я проводил настройку, отталкиваясь от книги &#8220;<noindex><a rel="nofollow" href="http://progit.org/book/ch4-7.html" >Pro Git. Professional version control</a></noindex>&#8220;. Она бесплатна и рекомендована сервисом GitHub для ознакомления с git.</p>
<h3>Установка</h3>
<p>Итак, начинаем. Напоминаю &#8211; я использую Ubuntu Server 9.04, но процесс практически такой же и для других версий или дистрибутивов Debian (должен сказать, что на Debian Sid я не смог добавить первый публичный ключ через gitosis-init).</p>
<p>Обновляем пакеты и ставим нужные пакеты. python-setuptools поставил за компанию, достаточно было бы поставить просто gitosis.</p>
<pre>
$ sudo aptitude update
$ sudo aptitude install python-setuptools
$ sudo aptitude install gitosis
</pre>
<p>Первые настройки я буду производить с самого сервера, где стоит gitosis. Я делаю &#8220;sudo -s&#8221;, так как у меня были некоторые странности при добавлении первого ключа под обычным пользователем. Вместо /home/ctrld/.ssh/id_rsa.pub подставьте свой публичный ключ. Если вы его ещё не сгенерировали, то можете сделать это по инструкции под <noindex><a rel="nofollow" href="http://help.github.com/linux-key-setup/" >Linux</a></noindex> или <noindex><a rel="nofollow" href="http://help.github.com/mac-key-setup/" >Mac OS X</a></noindex>.</p>
<pre>
$ sudo -s
# sudo -H -u gitosis gitosis-init < /home/ctrld/.ssh/id_rsa.pub
<small>Initialized empty Git repository in /srv/gitosis/repositories/gitosis-admin.git/
Reinitialized existing Git repository in /srv/gitosis/repositories/gitosis-admin.git/</small>
</pre>
<p>Проверяем. Если получен &#8220;ERROR:gitosis.serve.main&#8221;, то всё в порядке:</p>
<pre>
$ ssh gitosis@git.host.com
<small>ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
Connection to git.host.com closed.</small>
</pre>
<h3>Настройка</h3>
<p>Перед началом работы с Git на клиентской стороне очень желательно настроить окружение. Об этом можно прочитать в моей статье &#8220;<a href="http://theapplegeek.ru/archives/3464" >Установка Git под Mac OS X</a>&#8220;.</p>
<p>Настройка заключается в клонировании системного репозитория gitosis-admin с настройками, их изменение, а затем возвращение их обратно.</p>
<pre>
$ mkdir ~/tmp
$ cd ~/tmp
$ git clone gitosis@git.host.com:gitosis-admin.git
$ cd gitosis-admin
</pre>
<p>Добавляем проект, например, Notes</p>
<pre>
$ vim gitosis.conf
[group writers]
writable = Notes
members = email@gmail.com
</pre>
<p>Я создал группу writers, куда будут иметь люди, работающие с проектом Notes.</p>
<p>Записываем изменения в конфигурации обратно на сервер.</p>
<pre>
$ git commit -am 'add project Notes and group writers'
$ git push
</pre>
<h3>Создание проекта</h3>
<pre>
$ mkdir ~/Notes
$ cd ~/Notes
$ git init
$ touch Readme
$ git add Readme
$ git commit -a -m "Initial commit"
</pre>
<p>Указание внешнего репозитория и push проекта в него:</p>
<pre>
$ git remote add origin gitosis@git.host.com:Notes.git
$ git push origin master
<small>Counting objects: 3, done.
Writing objects: 100% (3/3), 214 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
To gitosis@git.host.com:Notes.git
 * [new branch]      master -> master</small>
</pre>
<h3>Добавление пользователя</h3>
<p>Для добавления пользователя нужно внести изменения в системный репозиторий, а именно добавить публичный ключ и внести пользователя в gitosis.conf.</p>
<pre>
$ cd tmp/gitosis-admin/
$ git pull origin master
</pre>
<p>Я записал публичный ключ пользователя в файл ~ctrld/ole-desktop.pub. Добавляю его:</p>
<pre>
$ cp ~ctrld/ole-desktop.pub keydir/ole\@ole-desktop.host.com.pub
$ git add keydir/ole\@ole-desktop.host.com.pub
</pre>
<p>В gitosis имя пользователя определяется по имени файла в keydir, поэтому именование зависит от администратора. Я указал псевдо-email вида ole@ole-desktop.host.com.</p>
<p>Добавляем нового пользователя в группу (обратите внимание на то, что пользователи разделяются пробелами, а не запятыми):</p>
<pre>
$ vim gitosis.conf
[group writers]
writable = Notes
members = email@gmail.com <b>ole@ole-desktop.host.com</b>
</pre>
<p>Commit и push в удалённый репозиторий:</p>
<pre>
$ git commit -am 'add user ole@ole-desktop.host.com and assign him to project Notes'
$ git push origin master
</pre>
<p>Проверяем под видом нового пользователя с его компьютера:</p>
<pre>
$ ssh gitosis@git.host.com
<small>ERROR:gitosis.serve.main:Need SSH_ORIGINAL_COMMAND in environment.
Connection to git.host.com closed.</small>
</pre>
<p>Новый пользователь клонирует репозиторий и начинает работу с ним:</p>
<pre>
$ git clone gitosis@git.host.com:Notes.git
$ cd Notes
$ echo "Hello, I am ole@deskop" >> Readme
$ git status
#       modified:   Readme
$ git commit -a -m "ole@desktop changes"
$ git push origin master
</pre>
<p>На другой системе проверяем, внеслись ли изменения:</p>
<pre>
$ cd ~/Notes
$ git pull origin master
<small>...
Fast forward
 Readme |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)</small>
$ cat Readme
Hello, I am ole@deskop
</pre>
<p>Всё работает, можно пользоваться.</p>
<p>Для улучшения безопасности в конфигурации sshd можно разрешить только определённых пользователей, включая gitosis (имена тоже разделяются пробелами, а не запятыми):</p>
<pre>
$ vim /etc/ssh/sshd_config
AllowUsers ctrld gitosis
</pre>
<p>Если вы используете сервере sshd на нестандартном порту, то нужно прописать это в .ssh/config:</p>
<pre>
$ vim ~/.ssh/config
Host git.host.com
        Port 2222
</pre>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/3843/feed</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Установка MongoDB</title>
		<link>http://theapplegeek.ru/archives/3809</link>
		<comments>http://theapplegeek.ru/archives/3809#comments</comments>
		<pubDate>Fri, 14 May 2010 10:10:53 +0000</pubDate>
		<dc:creator>ctrld</dc:creator>
				<category><![CDATA[Mac]]></category>
		<category><![CDATA[developer]]></category>

		<guid isPermaLink="false">http://theapplegeek.ru/?p=3809</guid>
		<description><![CDATA[MongoDB&#8230; NoSQL&#8230; Для решения одной задачи я решил попробовать нереляционную базу данных. В production система будет работать на Debian, но для разработки и тестирования мне она нужна на ноутбуке. Сказано &#8211; сделано. Для установки подобного софта я использую HomeBrew. Обновляюсь: $ brew update Есть ли готовая формула для MongoDB? $ brew search mongo mongo mongodb [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://images.theapplegeek.ru/wp-content/uploads/2010/05/01_mongo-thumb1.png" height="50" align="right" width="150" style=" display: inline; float: right; margin: 0 0 10px 10px;" /></p>
<p><noindex><a rel="nofollow" href="http://www.mongodb.org/" >MongoDB</a></noindex>&#8230; <noindex><a rel="nofollow" href="http://en.wikipedia.org/wiki/NoSQL" >NoSQL</a></noindex>&#8230; Для решения одной задачи я решил попробовать нереляционную базу данных. В production система будет работать на Debian, но для разработки и тестирования мне она нужна на ноутбуке. Сказано &#8211; сделано.</p>
<p>Для установки подобного софта я использую <a href="http://theapplegeek.ru/archives/3570" >HomeBrew</a>.</p>
<p><span id="more-3809"></span></p>
<p>Обновляюсь:</p>
<pre>
$ brew update
</pre>
<p>Есть ли готовая формула для MongoDB?</p>
<pre>
$ brew search mongo
mongo	 mongodb

$ brew info mongodb
<small>mongodb 1.4.2-x86_64

http://www.mongodb.org/

Not installed

If this is your first install, automatically load on login with:
    cp /usr/local/Cellar/mongodb/1.4.2-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents
    launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist

If this is an upgrade and you already have the org.mongodb.mongod.plist loaded:
    launchctl unload -w ~/Library/LaunchAgents/org.mongodb.mongod.plist
    cp /usr/local/Cellar/mongodb/1.4.2-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents
    launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist

Or start it manually:
    mongod run --config /usr/local/Cellar/mongodb/1.4.2-x86_64/mongod.conf

http://github.com/ctrld/homebrew/commits//Library/Formula/mongodb.rb</small>
</pre>
<p>mongo &#8211; алиас для mongodb. 1.4.2 является <noindex><a rel="nofollow" href="http://www.mongodb.org/display/DOCS/Downloads" >последней продуктивной версией</a></noindex>, пакет Homebrew актуален.</p>
<p>Устанавливаю:</p>
<pre>
$ brew install mongodb
</pre>
<p>Обеспечиваю автозагрузку и стартую:</p>
<pre>
$ cp /usr/local/Cellar/mongodb/1.4.2-x86_64/org.mongodb.mongod.plist ~/Library/LaunchAgents
$ launchctl load -w ~/Library/LaunchAgents/org.mongodb.mongod.plist
</pre>
<p>Для проверки захожу в shell:</p>
<pre>
$ mongo
MongoDB shell version: 1.4.2
url: test
connecting to: test
type "help" for help
&gt;
</pre>
<p>Всё в порядке. Посмотреть азы работы можно в <noindex><a rel="nofollow" href="http://www.mongodb.org/display/DOCS/Tutorial" >Tutorial</a></noindex>, а для более плотного знакомства &#8211; почитать <noindex><a rel="nofollow" href="http://www.mongodb.org/display/DOCS/Books" >книги</a></noindex>.</p>
<h3>Клиентская часть</h3>
<p>Соединяться с MongoDB я буду из Python используя модуль <noindex><a rel="nofollow" href="http://api.mongodb.org/python/" >PyMongo</a></noindex>.</p>
<p>Для установки буду использовать <noindex><a rel="nofollow" href="http://pypi.python.org/pypi/pip" >pip</a></noindex>, хоть вполне можно ставить напрямую из easy_install:</p>
<pre>
$ easy_install pip
$ pip install pymongo
</pre>
<p>Описание PyMongo можно посмотреть в <noindex><a rel="nofollow" href="http://api.mongodb.org/python/tutorial.html" >Tutorial</a></noindex>. Также рекомендую взглянуть <noindex><a rel="nofollow" href="http://www.saltycrane.com/blog/2010/02/python-mongodb-notes/" >на пример записи логов Apache в MongoDB</a></noindex>.</p>
<p>А дальше &#8211; собственно программирование.</p>
]]></content:encoded>
			<wfw:commentRss>http://theapplegeek.ru/archives/3809/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

