<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6758697817819098194</id><updated>2024-09-23T01:55:18.847+01:00</updated><category term="Ruby/ Ruby on Rails"/><category term="Git"/><category term="Linux"/><category term="Processing"/><category term="English"/><category term="Essays and Reports"/><category term="Links"/><category term="Box2D.js"/><category term="Mac"/><category term="MySQL"/><category term="Sass"/><title type='text'>Engineer Flies エンジニアは空を飛ぶ</title><subtitle type='html'>Ruby, The Processing Language　などについてのブログ</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://engineerflies.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/-/Git'/><link rel='alternate' type='text/html' href='http://engineerflies.blogspot.com/search/label/Git'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/01700091790800160715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6758697817819098194.post-5630810552056953183</id><published>2013-08-08T04:28:00.000+01:00</published><updated>2013-08-08T04:29:18.607+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><title type='text'>現在のGitのブランチをzshのプロンプトに表示する</title><content type='html'>現在のGitのブランチをzshのプロンプトに表示するのがいろんなスクリプトがあると思いますが、個人的に&lt;a href=&quot;https://github.com/olivierverdier/zsh-git-prompt&quot;&gt;zsh-git-prompt&lt;/a&gt;を半年くらい使っていて何の不満も無かったのでお勧めしたいです。&lt;br /&gt;
&lt;a href=&#39;https://github.com/olivierverdier/zsh-git-prompt&#39;&gt;&lt;br /&gt;
&lt;img src=&#39;https://raw.github.com/olivierverdier/zsh-git-prompt/master/screenshot.png&#39; /&gt;&lt;br /&gt;
&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
現在のブランチとremoteとの差分を記号を使って表示してくれます。&lt;br /&gt;
表示される記号の詳細は&lt;a href=&quot;https://github.com/olivierverdier/zsh-git-prompt#prompt-structure&quot;&gt;こちら&lt;/a&gt;に表記されています。&lt;br /&gt;
&lt;br /&gt;
PROMTを設定することで設定済みの変数のうち何を表示するか設定できるようです。&lt;br /&gt;
PROMPT=&#39;%B%m%~%b$(git_super_status) %# &#39;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/5630810552056953183'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/5630810552056953183'/><link rel='alternate' type='text/html' href='http://engineerflies.blogspot.com/2013/08/gitzsh.html' title='現在のGitのブランチをzshのプロンプトに表示する'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/01700091790800160715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-6758697817819098194.post-9066536181608494871</id><published>2013-01-07T05:43:00.001+00:00</published><updated>2013-01-07T05:46:06.048+00:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><category scheme="http://www.blogger.com/atom/ns#" term="Linux"/><category scheme="http://www.blogger.com/atom/ns#" term="Ruby/ Ruby on Rails"/><title type='text'>CodeSchoolを試してみてる</title><content type='html'>最近いろいろなタイプのオンラインの学習サイトが乱立していることは皆さんもご存知のことと思います。&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&#39;http://jp.techcrunch.com/archives/201208215-ways-to-learn-code-from-the-comfort-of-your-own-browser/&#39;&gt;お手軽にプログラミングを学習したい人のための厳選5サイト&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
その中にはあまりにも一般化しすぎているものや、”やりたいことはあるけど使い勝手がいまいち。。”的なものなどあって、試してみるまでなかなかどれが良いか分かりません。そんな中周りの評判が良かったのと、自分で使った感じも良かったので&lt;a href=&#39;http://www.codeschool.com/&#39;&gt;CodeSchool&lt;/a&gt;を使い始めています。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;コードスクールの良さ&lt;/h2&gt;&lt;br /&gt;
コードスクールが良いのは、書きながら覚えていくことにラーニングのアプリケーションが特化しているので知識の吸収効率が良いこと、それから、&lt;a href=&#39;http://sass-lang.com/docs/yardoc/file.SASS_REFERENCE.html&#39;&gt;ながーーいリファレンス&lt;/a&gt;から必要な情報を抽出する手間を省いてくれていることなどです。&lt;br /&gt;
&lt;br /&gt;
Webのエンジニアリングの世界って分量的にカバーしておくべきが多いですよね？CodeSchoolは月＄５０と割高な感じなんですが、全ての技術に分厚い本を買って望む暇は無いけれど体系化した知識を付けてないと業務上の実践では不安というケースには有効です。&lt;br /&gt;
&lt;br /&gt;
コースは&lt;a href=&#39;http://www.codeschool.com/courses&#39;&gt;こんな感じ&lt;/a&gt;のがあります。今のところRuby on Rails界隈のスタックが多いけど、徐々に汎用的なコースが増えてきている感じがします。&lt;br /&gt;
&lt;br /&gt;
Git, Sass, CSS, Mobile, HTML5, Coffeescript, jQuery, iOSなんかのコースがあるのもうれしいですね。&lt;br /&gt;
- &lt;a href=&#39;http://www.codeschool.com/courses/tag/javascript&#39;&gt;Javascript&lt;/a&gt;&lt;br /&gt;
- &lt;a href=&#39;http://www.codeschool.com/courses/tag/design&#39;&gt;デザイン&lt;/a&gt;&lt;br /&gt;
- &lt;a href=&#39;http://www.codeschool.com/courses/tag/webtools&#39;&gt;Web tools&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;始めた理由&lt;/h2&gt;&lt;br /&gt;
- 以前iKnowを毎日やって成果が出たので感覚的にこういう感じのタイプの公文式みたいに繰り返しやって覚えるオンラインラーニングに慣れている&lt;br /&gt;
- 毎日２時間の学習時間は取れないけど、３０分なら取れる。週に一日２時間よりも、毎日３０分x５日の方が頭に定着する&lt;br /&gt;
- ＄５０は高いけど本の料金やWeb上のドキュメントとそれにかける時間を考えるとまあ良いかなと思える。仕事への投資と思えば安い。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
迷っている人は全てのコースの１個目のチャレンジは無料なのでものの試しにやってみることをお勧めします。ユーザ登録しておくとたまにディスカウントのメールが来るので良いですよ。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
以上、また一ヶ月後に使った感想を書くかも！&lt;br /&gt;
&lt;br /&gt;
</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/9066536181608494871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/9066536181608494871'/><link rel='alternate' type='text/html' href='http://engineerflies.blogspot.com/2013/01/codeschool.html' title='CodeSchoolを試してみてる'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/01700091790800160715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-6758697817819098194.post-6597009809719921101</id><published>2012-05-17T06:56:00.003+01:00</published><updated>2012-05-22T15:51:19.318+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><title type='text'>Git: (probably) Easiest way to reset your local master</title><content type='html'>I came across an easiest and laziest way to reset an origin/master in a local repository in &lt;a href=&#39;http://stackoverflow.com/questions/2665045/can-i-tell-git-pull-to-overwrite-instead-of-merge?answertab=votes#tab-top&#39;&gt;this answer in StackOverflow&lt;/a&gt;, which is to delete and checkout a master branch.&lt;br /&gt;</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/6597009809719921101'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/6597009809719921101'/><link rel='alternate' type='text/html' href='http://engineerflies.blogspot.com/2012/05/git-probably-easiest-way-to-reset-your.html' title='Git: (probably) Easiest way to reset your local master'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/01700091790800160715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author></entry><entry><id>tag:blogger.com,1999:blog-6758697817819098194.post-5855548907929864384</id><published>2010-03-11T17:44:00.035+00:00</published><updated>2013-07-04T07:29:29.138+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Git"/><title type='text'>Git入門 ゼロから始めるGitドリル</title><content type='html'>gitの勉強をしつつ取ったノートを記事化しました。一応これを読めばざっくりとした導入やSVNとの違いが分かってもらえるように書いたつもりです。svnを使った経験があることを前提に進めていきます。&lt;br /&gt;
&lt;br /&gt;
svnの場合、一つのレポジトリに対して認証のあるユーザが変更を報告していくユースケースをとっています。gitの場合は、個々のローカルマシンにリポジトリが分散されて配置され、お互いに変更を報告しあうユースケース。これはLinuxの伝統的なバザール方式の開発を想定しています。そのため例えばカフェや電車で開発したり、マスターはgithubやgitfarm（&lt;a href=&quot;http://git.wiki.kernel.org/index.php/GitHosting&quot;&gt;Git Hosting&lt;/a&gt;参照）にしておいて時々ローカルの変更を報告することも可能です。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;目次&lt;/h1&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#install&quot;&gt;インストール&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#basic_manupilation&quot;&gt;基本操作&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#init&quot;&gt;Gitリポジトリの作成&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#branch&quot;&gt;ブランチの作成。&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#tag&quot;&gt;タグ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#ignore&quot;&gt;ファイルを無視する&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#commit_index_workingtree&quot;&gt;索引の理解&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#reset&quot;&gt;取り消し&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#summary&quot;&gt;導入&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#hard_soft&quot;&gt;--hardと--softの違い&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#checkout_single_file&quot;&gt;一個のファイルの変更を取り消して最後のコミットの状態にする&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#reset_index&quot;&gt;コミット前の変更を取り消す&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#reset_commit&quot;&gt;間違ったコミットを無かったことにする&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#cancel_commit&quot;&gt;間違ったコミットを無かったことにするが、ファイルへの変更を残す&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#revert&quot;&gt;最後のコミットを取り消して指定したコミットの状態に戻す。そして、その取消しをコミットとして履歴に残す&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#collaboration&quot;&gt;共同作業 - ２人&lt;/a&gt;&lt;/li&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#stash&quot;&gt;自分の変更を隠す&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#remote&quot;&gt;リモートブランチ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#search_commit_from_log&quot;&gt;履歴の検索&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#collab_two_root&quot;&gt;共同作業 - 2人 + ルート&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#github&quot;&gt;githubを使う&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://draft.blogger.com/blogger.g?blogID=6758697817819098194#git_apache_basic_authentication&quot;&gt;Git + Apache + Basic認証&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;install&quot;&gt;インストール&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
インストール方法はOSに応じて行ってください。&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/ttaka_tmp/20110412/1302585640&quot;&gt;Mac&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://ubuntu-note.blog.so-net.ne.jp/2011-02-23&quot;&gt;Ubuntu&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;https://help.github.com/articles/set-up-git#platform-windows&quot;&gt;Windows&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;basic_manupilation&quot;&gt;基本操作&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;init&quot;&gt;Gitリポジトリの作成&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ mkdir ~/workspace/git
$ cd  ~/workspace/git

# 初期化
$ git init
$ ls .git
branches  config  description  HEAD  hooks  info  objects  refs
$ echo trial &amp;gt; test.txt

# 索引の追加
# 索引はコミットする前のステージのようなもの。
# 索引はgit add　によって繰り返し更新可能
# git add .はカレントディレクトリ以下のディレクトリ／ファイルを再帰的にスナップショットに追加します
$ git add .
# 削除したファイルを索引に追加する場合は -uが必要。例, git add -u path/to/files/no/longer/necessary 

# メッセージを指定してコミット
$ git commit -m &quot;initial commitment&quot;

# ブランチの一覧を表示
$ git branch
* master #=&amp;gt; masterというブランチは初期状態で作成されます
$ git log
commit e1bf45812b9eedb8aa578af3c0e87a96d84cf3b6
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 00:28:59 2010 +0000

initial commitment

&lt;/sin&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
場所を移動してもgitは動作します。レポジトリは作業ディレクトリと同じ場所にあります。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ mkdir trial
$ mv test.txt trial/
$ mv .git trial/
$ cd trial

# gitが動作している事を確認
$ git show #最後のコミット情報が表示される
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
こまめにコミットすることは個人で開発を進めている時にも非常に有効です。subversionと大きく違うところは個人でリポジトリを所有しているところです。マスターになるリポジトリにpush(後述)しない限り未試験のコードをローカルのリポジトリにコミットすることができます。例えば、複数の実装方法を思いついたときに現在の内容を一時的なソース保管庫としてリポジトリにコミットしておいて、ある方法が失敗したと思ったらすぐ元の位置に戻ればよいわけです。&lt;br /&gt;
&lt;br /&gt;
こまめなコミットによってローカルのlogが汚れるのが嫌な場合は、tag（後述）を使用したり、公開用のリポジトリをもう一つ用意することによって対処できます。Gitを採用するのならこのアドバンテージを利用すべきでしょう。折角subversionから切り替えるのなら気持ちも一緒に切り替えると使い方の幅も広がるのではないでしょうか。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;branch&quot;&gt;ブランチの作成&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH1cdyfzewbDFDNyAVeUAjCbbyNwjaLTwc5A_oXhnOIebuFja-rJ8DSVnkgTPWIEyFGd_-6ZWft5c4-T_tluwLEDg-AXHJWRmb1wqV5tUKyOuX54MYLhnYrepQepTMU3VDowZ4JGMQTVkf/s1600-h/branch_alone.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5450410029230218514&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH1cdyfzewbDFDNyAVeUAjCbbyNwjaLTwc5A_oXhnOIebuFja-rJ8DSVnkgTPWIEyFGd_-6ZWft5c4-T_tluwLEDg-AXHJWRmb1wqV5tUKyOuX54MYLhnYrepQepTMU3VDowZ4JGMQTVkf/s400/branch_alone.png&quot; style=&quot;cursor: hand; cursor: pointer; height: 182px; width: 356px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ git branch new 
$ git branch
*  master #=&amp;gt; *は現在どのブランチを参照しているかを示しています
new

# svnのcheckoutはリポジトリから最新を取得しますが、
# gitのcheckoutはブランチを切り替えてその最新を取得します。
$ git checkout new
Switched to branch &#39;new&#39;
$ git branch
master
* new
$ git checkout master

# ブランチの削除
$ git branch -d new
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
ブランチの作成(2)&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;# 新しくブランチを作成してチェックアウトします。= git branch new + git checkout new
$ git checkout -b new
$ echo &#39; of git&#39; &amp;gt;&amp;gt; test.txt

# 変更をリポジトリに報告
$ git add .

# 索引と最後のコミットを比較
$ git diff --cached
diff --git a/test.txt b/test.txt
index 10b4e1b..48215e2 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1,2 @@
trial
+ of git

# 今どんな状態？
$ git status
# On branch new # newブランチ上に
# Changes to be committed: # コミットすべき変更有り 
#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)
#
# modified:   test.txt #更新: test.txt
#
$ cat .git/COMMIT_EDITMSG 
modified test.txt
# Please enter the commit message for your changes. Lines starting
# with &#39;#&#39; will be ignored, and an empty message aborts the commit.
# On branch new
# Changes to be committed:
#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)
#
# modified:   test.txt
#

# -mオプションを省略するとgit diffと同様に
# commitによってどのような変更がなされるか#付きのコメント行で示される。
$ git commit
modified test.txt
# On branch new 
# Changes to be committed: 
#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage) #unstage（索引を空に）したい場合はgit rest HEADしてね
#
# modified:   test.txt 
#
&lt;/file&gt;&lt;/file&gt;&lt;/file&gt;&lt;/pre&gt;&lt;br /&gt;
svnのようにbranch用のディレクトリをこしらえる必要は無い。&lt;br /&gt;
gitではブランチを切り替えることで作業ディレクトリの状態を切り替えます。&lt;br /&gt;
&lt;br /&gt;
現在のブランチは.git/HEADで管理されています。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cat .git/HEAD
ref: refs/heads/new
$ cat .git/refs/heads/new
bdfb3c51bba2c6d60e7bc326ea686702849c21ab
$ git show
commit bdfb3c51bba2c6d60e7bc326ea686702849c21ab
$ cat test.txt
trial
of git
$ git checkout master
$ cat .git/HEAD
ref: refs/heads/master
$ cat test.txt
trial

# 作業ディレクトリにnewブランチの変更を引き込む
$ git pull . new
$ cat test.txt 
trial
of git
$ gitk
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;tag&quot;&gt;タグ&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ git tag v0.10.00

# タグの一覧表示
$ git tag -l
v0.10.00
vx.xx.xx
:
vx.xx.xx
# タグはいろんな箇所で使えます
$ git diff v0.10.00 ORIG_HEAD
# v0.10.0の位置に &quot;stable&quot; という名前の新しいブランチを作成
$ git branch stable v0.10.00 
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;ignore&quot;&gt;ファイルを無視する&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ mkdir bin
$ touch bin/gabage
$ git status
# On branch master
# Untracked files:
#   (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)
#
# bin/ =&amp;gt; binが追跡されてないのでgit addして と言ってる
nothing added to commit but untracked files present (use &quot;git add&quot; to track)

$ vi .gitignore
bin/*                                                                               */  
$ git status
# On branch master
# Untracked files:
#   (use &quot;git add &lt;file&gt;...&quot; to include in what will be committed)
#
# .gitignore =&amp;gt; .gitignoreもgitの管理対象
nothing added to commit but untracked files present (use &quot;git add&quot; to track)

$ git add .gitignore
$ git commit
Added new file .gitignore           
$ git status
# On branch master
nothing to commit (working directory clean)
&lt;/file&gt;&lt;/file&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;commit_index_workingtree&quot;&gt;索引の理解&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
コミット - Gitでは履歴内にある１点のことを指す。プロジェクトの全履歴は 相互に関連したコミットの集合により表現されています。git では&quot;コミット&quot;という言葉を 他のリビジョン管理システムが使用する &quot;リビジョン&quot; または &quot;バージョン&quot;と同じ意味で 使用することがあります。また、コミットオブジェクト の略称として使われることもあります。&lt;br /&gt;
&lt;br /&gt;
索引 - コミットしたいものの追跡を保つ為、git は &quot;索引(index)&quot; と呼ばれる 特別なエリア内にツリーの中身のスナップショットを保管しています。&lt;br /&gt;
&lt;br /&gt;
コミット[HEAD]&lt;br /&gt;
↑&lt;br /&gt;
↑ git commit&lt;br /&gt;
↑&lt;br /&gt;
索引[index]&lt;br /&gt;
↑&lt;br /&gt;
↑ git add&lt;br /&gt;
↑&lt;br /&gt;
作業ディレクトリ[working tree]&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ echo 1 &amp;gt; diff.txt
$ git add diff.txt
$ echo 2 &amp;gt; diff.txt

# 索引 と 最後のコミットを比較
$ git diff --cached
diff --git a/diff.txt b/diff.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/diff.txt
@@ -0,0 +1 @@
+1

# 作業ディレクトリ と 索引 を比較
$ git diff
diff --git a/diff.txt b/diff.txt
index d00491f..0cfbf08 100644
--- a/diff.txt
+++ b/diff.txt
@@ -1 +1 @@
-1
+2

# 作業ディレクトリ と 最後のコミット を比較
$ git diff HEAD
diff --git a/diff.txt b/diff.txt
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/diff.txt
@@ -0,0 +1 @@
+2
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;reset&quot;&gt;取り消し&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;a href=&quot;&quot; name=&quot;summary&quot;&gt;導入&lt;/a&gt;&lt;/h3&gt;一口に変更を元に戻すといってもシングルリポジトリなSVNと異なり以下にあげたようにいくつかの場面があります。これは索引やコミットそしてリモートなどの仕組み上の違いによるものです。&lt;br /&gt;
&lt;br /&gt;
- 一個のファイルの変更を取り消して最後のコミットの状態にする&lt;br /&gt;
git reset -- filename&lt;br /&gt;
&lt;br /&gt;
- 最後のコミットの内容に索引と作業ディレクトリを戻す&lt;br /&gt;
git reset --hard HEAD&lt;br /&gt;
&lt;br /&gt;
- 最後のコミットと索引と作業ディレクトリをその前のコミットに置き換える&lt;br /&gt;
git reset --hard ORIG_HEAD&lt;br /&gt;
&lt;br /&gt;
- 最後のコミットの後に、その前のコミットの状態をコミットする&lt;br /&gt;
git revert HEAD&lt;br /&gt;
&lt;br /&gt;
以下に違いを解説します。でもその前に --hardっていうオプションはなんなんでしょうか？--hardがあるなら--softもあるのか？&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;a href=&quot;&quot; name=&quot;hard_soft&quot;&gt;--hardと--softの違い&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ git reset -h
--mixed reset HEAD and index                
--soft  reset only HEAD                     
--hard  reset HEAD, index and working tree　
--merge reset HEAD, index and working tree
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;a href=&quot;&quot; name=&quot;checkout_single_file&quot;&gt;一個のファイルの変更を取り消して最後のコミットの状態にする&lt;/a&gt;&lt;/h3&gt;きっと一番よく使うのがこれ。コミットしていない変更がある場合は単にgit checkout filenameとしてもファイルの内容は最後のコミットの状態には戻らない。git reset --hardは作業ディレクトリ以下を全て最後のコミットの状態に戻してしまう。そんな時は &#39;--&#39;オプションをつけると一個のファイルだけを戻すことができる。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ &lt;b&gt;git checkout -- filename&lt;/b&gt;
&lt;/pre&gt;&lt;a href=&quot;http://norbauer.com/notebooks/code/notes/git-revert-reset-a-single-file&quot;&gt;参考&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
このコマンドで削除したファイルをリポジトリから復活するもできます。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ git status
# On branch master
# Changed but not updated:
#   (use &quot;git add/rm &lt;file&gt;...&quot; to update what will be committed)
#   &lt;b&gt;(use &quot;git checkout -- &lt;file&gt;...&quot; to discard changes in working directory)&lt;/file&gt;&lt;/b&gt;
#
# deleted:    rerun.txt

$ git checkout -- rerun.txt
$ ls
rerun.txt
&lt;/file&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;h3&gt;&lt;a href=&quot;&quot; name=&quot;reset_commit&quot;&gt;間違ったコミットを無かったことにする&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ touch abigmistake
$ git add .
$ git commit -m &#39;a big mistake&#39;
$ git log
commit b37c941bfe9364b681c8b760397b14e846b8fc7d
Author: suzukimilanpaak &lt;sin .wave808=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 19 17:05:55 2010 +0000

a big mistake

commit bdfb3c51bba2c6d60e7bc326ea686702849c21ab
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 01:08:36 2010 +0000

modified test.txt

$ &lt;b&gt;git reset --hard ORIG_HEAD&lt;/b&gt;

# 以下のように特定のタグを指定することもできる
$ git reset --hard v0.10.00

#&lt;b&gt;注意！： 作業ディレクトリの変更も削除されてしまう&lt;/b&gt;
$ ls
bin test.txt

$ git log
commit bdfb3c51bba2c6d60e7bc326ea686702849c21ab
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 01:08:36 2010 +0000

modified test.txt

commit e1bf45812b9eedb8aa578af3c0e87a96d84cf3b6
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 00:28:59 2010 +0000

initial commitment

&lt;/sin&gt;&lt;/sin&gt;&lt;/sin&gt;&lt;/sin&gt;&lt;/pre&gt;&lt;br /&gt;
注意! git reset --hard ORIG_HEADはリポジトリを直接変更します。誤ったコミットの履歴HEAD（この場合 &#39;a big mistake&#39;）を取り除きます。変更を取り消した履歴を残すことはありません。そのため他の作業者がそのコミットを既に取り寄せていた場合親族関係が崩れてしまい、他の作業者の変更がどこにも到達不可能になってしまうというケースが起こりうります。そのためgit reset --hard ORIG_HEADを行う場合は他の作業者に事前の確認が必要です。&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;br /&gt;
&lt;a href=&#39;&#39; name=&#39;cancel_commit&#39;&gt;間違ったコミットを無かったことにするが、ファイルへの変更をリセットしない&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
$ git reset --soft HEAD^&lt;br /&gt;
&lt;br /&gt;
コミットに含んで欲しくない変更があった場合や、タイポを後で見つけてしまった場合、新たな変更をコミットに含みたい場合などに便利&lt;br /&gt;
&lt;a href=&#39;http://stackoverflow.com/questions/927358/how-to-undo-the-last-git-commit&#39;&gt;参照&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;a href=&quot;&quot; name=&quot;revert&quot;&gt;最後のコミットを取り消して指定したコミットの状態に戻す。そして、その取消しをコミットとして履歴に残す&lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi07qmTUZ0gG3wx-mRxsEtXmd59suTfxTDIcuMqAMfEPKw1hs7-qRqtHSBeUbZ6DVGPqxPqJRvE7tUlg-_HfTIAFPRkEB03EcNkm8zhcUwXAEoW_gJegPUzIyxM6pvSv2WP1TyiOXYm8Y5Z/s1600-h/bob+edited+then+alice+edited.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5450409839901696514&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi07qmTUZ0gG3wx-mRxsEtXmd59suTfxTDIcuMqAMfEPKw1hs7-qRqtHSBeUbZ6DVGPqxPqJRvE7tUlg-_HfTIAFPRkEB03EcNkm8zhcUwXAEoW_gJegPUzIyxM6pvSv2WP1TyiOXYm8Y5Z/s400/bob+edited+then+alice+edited.png&quot; style=&quot;cursor: hand; cursor: pointer; height: 205px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
他の作業者がすでに間違ったコミットを取り寄せ済みの場合、間違ったコミットの変更を取り消すコミットを上書きする方法が望ましいようです。単に git revertに間違ったコミットへの参照を渡すことによって変更を取り消す新しいコミットが作成されます。 また、新しいコミットに対するコミットメッセージが促されます。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ echo foo &amp;gt; test.txt
$ git commit -am &#39;Modified test.txt&#39;
# HEADをORIG_HEADの内容に戻す。コミットも同時に行われます
$ &lt;b&gt;git revert HEAD&lt;/b&gt;

Revert &quot;Modified test.txt&quot;

This reverts commit 07abe15e79f4c1429fb1d22247723e29dc50293a.

# Please enter the commit message for your changes. Lines starting
# with &#39;#&#39; will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)
#
#       modified:   test.txt
#

$ git log
commit 42b30ec986d7fdb8d76c7a5b7c89f17114e8039c
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 01:45:28 2010 +0000

Revert &quot;Modified test.txt&quot;

This reverts commit 07abe15e79f4c1429fb1d22247723e29dc50293a.

commit 07abe15e79f4c1429fb1d22247723e29dc50293a
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 01:45:04 2010 +0000

Modified test.txt

#ここまでの変更をGUIで表示
$ gitk &amp;amp;
&lt;/sin&gt;&lt;/sin&gt;&lt;/file&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;&lt;a href=&quot;&quot; name=&quot;reset_index&quot;&gt;コミット前の変更を取り消す - git reset HEAD &lt;/a&gt;&lt;/h3&gt;&lt;br /&gt;
索引を空にする&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ touch abigmistake
$ git add .
$ git status
# On branch master
# Changes to be committed:
#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)　#unstageする場合はgit reset HEADしてね
#
# new file:   abigmistake
#
$ &lt;b&gt;git reset HEAD abigmistake&lt;/b&gt;

# 索引から履歴は削除されるがファイル自体は残っている
$ ls
abigmistake  test.txt

# もう一度索引に追加することもできます
$ git add abigmistake

$ git reset --hard HEAD
$ ls
test.txt
&lt;/file&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;collaboration&quot;&gt;共同作業 - ２人&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7QILT7CuPLHEwvJ2Vrr2T0POczbvgiiF6TJ_yxA1I_QOZI_c1JHNNzdWIlkk6v1JIMxwnsLob9pbU44EDgpemJ-AHPFJ3hbRy-tyXa9oItr3FQvuhPwcndvmdlRKehFMHvStOeVT5Vnnk/s1600-h/revert_modified_text.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; id=&quot;BLOGGER_PHOTO_ID_5450410106663023522&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7QILT7CuPLHEwvJ2Vrr2T0POczbvgiiF6TJ_yxA1I_QOZI_c1JHNNzdWIlkk6v1JIMxwnsLob9pbU44EDgpemJ-AHPFJ3hbRy-tyXa9oItr3FQvuhPwcndvmdlRKehFMHvStOeVT5Vnnk/s400/revert_modified_text.png&quot; style=&quot;cursor: hand; cursor: pointer; height: 205px; width: 400px;&quot; /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
準備&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;# aliceの署名情報を設定
$ git config --global user.name &quot;alice&quot;
$ git config --global user.email &quot;engineerflies+alice@gmail.com&quot;
$ cat ~/.gitconfig
[user]
name = alice
email = engineerflies+alice@gmail.com
$ cd ..
$ mkdir alice &amp;amp;&amp;amp; mv trial alice
$ git clone ./alice bob
bob$ cd bob
# bobの署名情報を設定(この場合同じユーザで書名情報を設定しているので~/.configを上書きする)
bob$ git config --global user.name &quot;bob&quot;
bob$ git config --global user.email &quot;engineerflies+bob@gmail.com&quot;

bob$ echo bob edited &amp;gt;test.txt
bob$ git commit -am &quot;bob edited&quot;
alice$ echo alice edited &amp;gt; test.txt
alice$ git add .

# bobのmasterブランチを現在のaliceのmasterブランチに取り寄せる
# 変更情報のみがリモート追跡用ブランチに格納されます。test.txtは変更されない
alice$ git fetch ../bob master
alice$ cat test.txt 
alice edited

# aliceのHEADとbobからpullしたFETCH_HEADの差異を表示
alice$ git diff HEAD..FETCH_HEAD
diff --git a/test.txt b/test.txt
index 48215e2..4cba843 100644
--- a/test.txt
+++ b/test.txt
@@ -1,2 +1 @@
-trial
- of git
+bob edited
alice$ cat .git/FETCH_HEAD 
b61671548ad431d9d865f0dd7eaeded68ec23711  branch &#39;master&#39; of ../bob
alice$ git merge FETCH_HEAD
Updating 7d62c24..b616715
error: Entry &#39;test.txt&#39; would be overwritten by merge. Cannot merge.

#このコミットはコンフリクトを起こさない（HEADと作業ディレクトリを比較しているから？）
alice$ git commit -am &quot;alice edited&quot;
alice$ git log
commit d04f56226dde3ac67839a5695ab6fb5644a34bc9
Author: bob &lt;engineerflies bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Thu Mar 18 13:21:13 2010 +0000

alice edited

commit 7d62c24953010a7628b29e891405e973b24a4239
Author: bob &lt;engineerflies bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Fri Mar 12 01:44:29 2010 +0000

ignore bin/
:
:

# 再度merge - コンフリクトを起こします
alice$ git merge FETCH_HEAD
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
Automatic merge failed; fix conflicts and then commit the result.
このようにマージは常に直前にコミットが済んでいることを想定して行われる様です。
dirtyな状態（現在のブランチにコミットされていない変更が作業ディレクトリ内に含まれていること）ではマージは行われません。

#コンフリクトを手動で回収します
alice$ vi test.txt
bob edited then alice edited

結果の表示
# bobが最後にpullしてから、aliceがbobの変更をpullするまでの変更を表示する
$ gitk HEAD..FETCH_HEAD
# aliceとbobのそれぞれの変更のうちお互いに&#39;到達不可能な&#39;変更を表示する
$ gitk HEAD...FETCH_HEAD

alice$ git commit -a
Merge branch &#39;master&#39; of ../bob #マージ用のログを自動生成してくれます

Conflicts: #コンフリクトが test.txtにあった
test.txt
#
#あなたはマージをコミットしている様です（とgitは認識しています）
# It looks like you may be committing a MERGE. 
#これが正しくなかったら、.git/MERGE_HEADを削除してからもう一回トライしてね
# If this is not correct, please remove the file 
#       .git/MERGE_HEAD
# and try again.
#

#以下はいつもコミット時に表示されるメッセージと同じ
# Please enter the commit message for your changes. Lines starting
# with &#39;#&#39; will be ignored, and an empty message aborts the commit.
# On branch master
# Changes to be committed:
#   (use &quot;git reset HEAD &lt;file&gt;...&quot; to unstage)
#
#       modified:   test.txt
#

#最後にaliceの変更をbobにも取り寄せておきます
#pull は fetch + mergeと等価です
bob$ git pull ../alice master
&lt;/file&gt;&lt;/engineerflies&gt;&lt;/engineerflies&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;stash&quot;&gt;自分の変更を隠す&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;bob$ echo love letter from canada &amp;gt;&amp;gt; testto.txt 
bob$ git commit -am &quot;love letter&quot;
alice$ echo affair in us&amp;gt;&amp;gt;test.txt 
alice$ git pull ../bob
# stash: 隠しもの
alice$ git stash save affair
# 隠しものを一覧する
alice$ git stash list
stash@{0}: On master: affair
alice$ git pull ../bob
alice$ vi test.txt 
love letter from canada
love letter from us
alice$ git commit -am &quot;in love&quot;
alice$ git stash clear
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;&lt;a href=&quot;&quot; name=&quot;remote&quot;&gt;リモートブランチ&lt;/a&gt;&lt;/h2&gt;&lt;br /&gt;
今までの作業でaliceがgit pull ../bobした場合はbobをリモートとして登録することなくbobの変更をaliceにマージしていた。bobとaliceの共同作業が恒久的に行われる場合はリモートブランチとしてbobを登録してしまった方が便利だ。この方法によってリモートにあるブランチをローカルのブランチであるかの様にマージができます。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;bob$ echo bob edited &amp;gt; test.txt 
bob$ git commit -am &quot;bob eidted&quot;
alice$ git remote add bob ~/workspace/git/bob
alice$ git branch -r
bob/master
alice$ cat .git/config 
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote &quot;bob&quot;]
url = /home/suzukimilanpaak/workspace/git/bob
fetch = +refs/heads/*:refs/remotes/bob/*                             


# 変更情報のみがリモート追跡用ブランチに格納されます。test.txtは変更されない */
alice$ git fetch bob

# 自分のmasterとbobのmasterを比較
# -p はpatchの略、patch提出用のログメッセージを出力してくれます
alice$ git log -p master..bob/master
commit 460f2c8928b7f1b1065766c6c2652f79001a054c
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Thu Mar 18 14:01:11 2010 +0000

bob eidted

# -pによって出力される変更ログ
diff --git a/test.txt b/test.txt
index 843ad85..4cba843 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1 @@
-love letter from canada
+bob edited
alice$ git merge master bob/master
Already up-to-date with ed79b27cc53885e29b2770a9f20d8fb2174e48b6
Trying simple merge with 460f2c8928b7f1b1065766c6c2652f79001a054c
Simple merge did not work, trying automatic merge.
Auto-merging test.txt
ERROR: content conflict in test.txt 
fatal: merge program failed
Automatic merge failed; fix conflicts and then commit the result.

# コンフリクトを解消します
alice$ vi test.txt
love letter from canada
love letter from us
bob edited
alice$ git commit -a
Merge branch &#39;master&#39;; commit &#39;bob/master&#39;

Conflicts:
test.txt

# bobのリポジトリはaliceをcloneして作られたためoriginにaliceのリポジトリが指定されている。
bob$ cat .git/config 
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote &quot;origin&quot;]
fetch = +refs/heads/*:refs/remotes/origin/*                                          */
url = /home/suzukimilanpaak/workspace/git/./alice
[branch &quot;master&quot;]
remote = origin
merge = refs/heads/master
bob$ git config -l
user.name=bob
user.email=sin.wave808+bob@gmail.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*                             */
remote.origin.url=/home/suzukimilanpaak/workspace/git/./alice
branch.master.remote=origin
branch.master.merge=refs/heads/master
bob$ git branch -r
origin/HEAD -&amp;gt; origin/master
origin/master
origin/new

# git pullで引数を省略すると remote &quot;origin&quot;に登録されている変更を取り寄せる
bob$ git pull

# ちゃんと変更されてる
bob$ cat test.txt 
love letter from canada
love letter from us
bob edited
&lt;/sin&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;search_commit_from_log&quot;&gt;履歴の検索&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
履歴の検索に強くなっておくと今後の作業に便利です。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ git log
commit 74f846a1bde25ef729b1742bfcd9fc693da1dbda

# ある時点のコミットの詳細を表示
# SHA1値の全てを指定する必要は無い
$ git show 74f846a1bde25ef
commit 74f846a1bde25ef729b1742bfcd9fc693da1dbda
Merge: 17b2308 a01e7b7
Author: suzukimilanpaak &lt;suzukimilanpaak none=&quot;&quot; sanfrancisco.=&quot;&quot;&gt;
Date:   Fri Mar 5 17:25:15 2010 +0000

tip of collaboration


$ git show HEAD^  # HEAD の親を表示
$ git show HEAD^^ # HEAD の祖父を表示
$ git show HEAD~4 # HEAD の４つ前を表示

# &quot;love&quot;を検索
$ git grep love
test.txt:love letter from canada
test.txt:love letter from us

# &quot;love&quot;をタグv0.00.00から検索
$ git grep love v0.10.00 #=&amp;gt; 何も見つからない
$ git log v0.10.00              # v0.10.00以降のコミット
$ git log --since=yesterday     # 昨日からのコミット
$ git log --since=&quot;3 hours ago&quot; # 3時間前からのコミット

# 最近２週間に &quot;drivers&quot; ディレクトリを修正したコミットでgitkで表示
$ gitk --since=&quot;2 weeks ago&quot; drivers/ 

# ファイル名を指定
$ git diff v0.10.00:test.txt HEAD:test.txt

# 変更したファイル名を検索
$ git log --stat|grep -A 5 haml
changed the view rendering engine html to haml.

app/views/feeds/new.html.haml |   48 ++++++++++++++++------------------------
1 files changed, 19 insertions(+), 29 deletions(-)
&lt;/suzukimilanpaak&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
差分の表示&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ git checkout -b a
$ echo a &amp;gt; a.txt
$ git commit -am &quot;a&quot;

# aにあってmasterにないコミットを表示
$ git log master..a
commit b090846acd519c2066a8975ed4c76de700d66fc3
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Thu Mar 18 14:44:04 2010 +0000

a

#masterにあってaにないコミットを表示 =&amp;gt; 何も表示されない
$ git log a..master
&lt;/sin&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;collab_two_root&quot;&gt;共同作業 - 2人 + ルート&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
今まではbobがaliceをoriginとして参照する方法で行って来ました。実際の開発ではルートとなるレポジトリを設けてアリスとボブがそれを参照する方が管理を行いやすいです。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;/opt$ mkdir git

# rootというリポジトリをaliceからコピーして生成します。
# この作業の前にaliceが開発の先端になっているべきであることに注意してください。
# bare&quot;裸の&quot;とは作業ファイルがなく、管理情報だけを持つリポジトリという意味
# sharedを付けると共用のユーザ権限がリポジトリに与えられます
/opt$ git clone --bare --shared ~/workspace/git/alice/ root
alice$ git remote rm bob

# -t: master ブランチをtrack&quot;追跡&quot;します
alice$ git remote add -t master origin /opt/git/root
alice$ git config -l
remote.origin.url=/opt/git/root
remote.origin.fetch=+refs/heads/master:refs/remotes/origin/master
# fetchがrefs/heads/masterを参照する様に設定されています
# -tオプションが指定されていない場合はrefs/heads/*が設定されます */

# 引数なしでpullをするとremotes/origin/masterから変更を取り寄せます
# git remote add に-tを使用したためです。
alice$ git pull

# これまでこの記事にそってリポジトリを作成してきた場合originはaliceを参照しているはずです
bob$ git config -l
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*                                 */
remote.origin.url=/home/suzukimilanpaak/workspace/git/./alice
bob$ git remote rm origin
bob$ git remote add -t master origin /opt/git/root
bob$ git pull


bob$ echo love from vancouver &amp;gt; test.txt
bob$ git commit -am &quot;love from vancouver&quot;
bob$ sudo git push origin master

alice$ echo love from san francisco &amp;gt; test.txt 
alice$ git commit -am &quot;love from san francisco&quot;
alice$ sudo git push origin master
To /opt/git/root
! [rejected]        master -&amp;gt; master (non-fast forward) 
error: failed to push some refs to &#39;/opt/git/root&#39;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
fast forwardじゃないというメッセージがでてpushが拒絶されます。&lt;br /&gt;
fast forward - 今行おうとしているコミットが既に他方のコミットに含まれている場合、gitは現在のブランチの先頭をマージされるブランチの先頭の位置に進め、新しいコミットは作成されません。これをfast forwardといいます。&lt;br /&gt;
&lt;br /&gt;
この場合、aliceの変更はbobが先に行った変更と衝突するため拒絶されています。別の言い方をすると、共有リポジトリを置いて開発を行う場合fast forwardでない限りpushを受け付けてもらえないようです。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;alice$ git pull
CONFLICT (content): Merge conflict in test.txt
alice$ vi test.txt
love from vancouver
love from san francisco
alice$ git commit -a
alice$ git push origin master
&lt;/pre&gt;&lt;br /&gt;
今度はpushを受け付けてもらえました&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;root$ git log
commit 40c4ded3df30d696a16552d928b3a46515cfb516
Merge: f180d66 a2bcc0d
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Thu Mar 18 17:00:51 2010 +0000

Merge branch &#39;master&#39; of /opt/git/root

Conflicts:
test.txt

commit f180d664d2943ccc83075e7dc1300f7dca999d72
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Thu Mar 18 16:40:37 2010 +0000

love from san francisco

commit a2bcc0d98f0e2c98d37df233aecb30caacb028f5
Author: bob &lt;sin .wave808=&quot;&quot; bob=&quot;&quot; gmail.com=&quot;&quot;&gt;
Date:   Thu Mar 18 16:39:49 2010 +0000

love from vancouver
&lt;/sin&gt;&lt;/sin&gt;&lt;/sin&gt;&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
- ３つ以上のマージ&lt;br /&gt;
http://www8.atwiki.jp/git_jp/pub/Documentation.ja/user-manual.html#merging-multiple-trees&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;github&quot;&gt;githubを使う&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
githubをマスターレポジトリとしてそこにローカルの変更をpushする環境を構築しましょう。まずはgithubでユーザアカウントを作成してください。githubでレポジトリを作成するとリポジトリのURLを教えてくれるのでそれを今まで通りgit remoteで登録します。そしてgithubにsshの公開鍵を渡し、ローカルの変更がうまく反映されるまでの流れを説明します。&lt;br /&gt;
&lt;br /&gt;
- こちらにアクセスしてください。http://github.com/repositories/new&lt;br /&gt;
- 必要事項を書き込みます&lt;br /&gt;
- ローカル環境のセットアップの説明が表示されます&lt;br /&gt;
&lt;br /&gt;
説明ページの手順にそって作業を進めていきます。&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ cd ~/.ssh
既存の鍵ペアがある場合はバックアップをとります
$ mkdir key_backup
$ cp id_rsa* key_backup
$ rm id_rsa*
鍵ペアを生成します
$ ssh-keygen -t rsa -C &quot;tekkub@gmail.com&quot;
&lt;/pre&gt;&lt;br /&gt;
鍵のファイル名はレポジトリごとに指定するのが後々管理しやすいです。ここではid_rsa_githubを指定しました。&lt;br /&gt;
&lt;br /&gt;
ホスト毎にsshが読み込む秘密鍵が分かるように以下の設定を~/.ssh/configに書き込みます。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ vi config
Host github.com
HostName github.com
User git
IdentityFile /home/suzukimilanpaak/.ssh/id_rsa_github
&lt;/pre&gt;&lt;br /&gt;
接続可能か試します。Permission denied (publickey).が表示されず、パスフレーズを求められれば上記の設定が成功しているはずです。&lt;br /&gt;
ssh -v git@github.com&lt;br /&gt;
&lt;br /&gt;
公開鍵をコピーします。改行が入らないようにxclipを使用します&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ sudo apt-get install xclip
$ cat ~/.ssh/id_rsa.pub | xclip -sel clip
xclipでクリップボードに公開鍵の内容が保存されているので、それを以下のページのKeyという項目に張り付けます
https://github.com/account#ssh_bucket
titleの項目は任意です。

~/workspace/git$ git clone alice snippets
~/workspace/git$ cd snippets
リポジトリのアドレスは作成したリポジトリのページからコピーしてください
snippets$ git remote add -t master origin git@github.com:yourusername/code-snippets.git
snippets$ git pull
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
READMEを作ってみましょう&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;snippets$ vi README
This repo is for my private use only. thank you
何だかgithubの意に反したことを言っていますが。。。

snippets$ git add .
snippets$ git commit -am &quot;added README&quot;
snippets$ git push origin master
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
- Network Graphを覗いてみましょう。今までの変更がグラフィカルに表示されているはずです。&lt;br /&gt;
http://github.com/yourusername/code-snippets/network&lt;br /&gt;
すばらしい&lt;br /&gt;
&lt;br /&gt;
このセクションを読んだあとに山形浩生さんが公開されているEric Raymondの&lt;a href=&quot;http://cruel.org/freeware/cathedral.html&quot;&gt;伽藍とバザールの日本語訳&lt;/a&gt;をご覧になられると良いかもしれません。このページの読者にはこれからオープンソースの開発に携わってみたいと思っている人も少なくないでしょう（私もその一人です）。githubの空気、ノリをつかむにはちょうど良い資材だと思います。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h1&gt;&lt;a href=&quot;&quot; name=&quot;git_apache_basic_authentication&quot;&gt;Git + Apache + Basic認証&lt;/a&gt;&lt;/h1&gt;&lt;br /&gt;
エンタープライズな開発の現場でもgitが使われるといいですね。Apacheと組み合わせて使う方法をご紹介します。svnと基本はあまり変わらないです。2009年末にapacheの連携を解消する&lt;a href=&quot;http://progit.org/2010/03/04/smart-http.html&quot;&gt;smart HTTP&lt;/a&gt;が発表されました。Git &amp;gt; v1.6.6、Apache 2.x という環境で恩恵をうけることができますが、下位互換がありますのでこの記事を書くに当たってそちらの構成を採用しました（これについては書き掛け）。&lt;br /&gt;
&lt;br /&gt;
Ubuntuでの設定をご説明します。まずはApacheが参照するリポジトリをDAV越しにローカルリポジトリが操作できるようにするところまで説明します。Smart HTTPについては後述します。&lt;br /&gt;
&lt;br /&gt;
認証方式について&lt;br /&gt;
&lt;a href=&quot;http://d.hatena.ne.jp/thinca/20081108/1226155897&quot;&gt;Gitは認証方式の指定ができません&lt;/a&gt;。そしてBasic認証を行おうとします。&lt;a href=&quot;http://github.com/rctay/git/commit/b8ac923010484908d8426cb8ded5ad7e8c21a7f6&quot;&gt;http.authanyで全てのHTTP認証方式に対応できるよう&lt;/a&gt;ですが都度で認証方式を決定するまでリトライするので重いようです。これではSmart HTTPを採用した意味がないので使用は避けた方がいいでしょう。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;# DocumentRootの場所を探します
$ grep -r DocumentRoot /etc/apache2/*                                               */
# DocumentRootに移動
$ cd /var/www
$ sudo mkdir dev.git
# 裸のgitリポジトリを作成します。apacheユーザでアクセスするので--sharedオプションは使用しません。
$ sudo git --bare init
$ git update-server-info

# apacheユーザを検索（apacheが動作している前提）
$ ps aux |grep apache
www-data  1862  0.0  0.0  40064    52 ?        S    09:10   0:00 /usr/sbin/apache2 -k start
$ sudo chown -R www-data:www-data dev.git
$ cd /etc/apache2
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
Ubuntuでapache2をapptitudeやapt-getからインストールした場合、/etc/apache2/mods-available/dav.loadがあるはずです。特に設定の変更は必要ありません。&lt;br /&gt;
&lt;br /&gt;
次に&lt;a href=&quot;http://httpd.apache.org/docs/2.0/ja/mod/mod_dav_fs.html&quot;&gt;DAVLockDBディレクティブ&lt;/a&gt;があるか確認します。ms_dav_fsはユーザの操作をロックするためにSDBMを使用します。そのためこのディレクティブによってデータベースファイルが指定されている必要があります。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ grep -r DAVLockDB mods-available/*                                            */
mods-available/dav_fs.conf:DAVLockDB /var/lock/apache2/DAVLock
モジュールを有効にします。
$ sudo a2enmod dav dav_fs
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
バーチャルホストの作成&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;$ sudo vi sites-available/git
NameVirtualHost *
&amp;lt;VirtualHost *&amp;gt;
ServerName &amp;lt;servername&amp;gt;
ServerAdmin a.hi.tech.hippie@@googlemail.com
DocumentRoot /var/www/dev.git
ErrorLog /var/log/apache2/error.dev.git.log

&amp;lt;Location /&amp;gt;
DAV on
AuthType Basic
AuthName &#39;developer&#39;
AuthUserFile /etc/apache2/.htbasic
Require valid-user
&amp;lt;/Location&amp;gt;
&amp;lt;/VirtualHost&amp;gt;

$ sudo vi /etc/hosts
127.0.0.1       &amp;lt;servername&amp;gt;
127.0.1.1       &amp;lt;servername&amp;gt;

$ htpasswd -c /etc/apache2/.htbasic &amp;lt;user&amp;gt;
$ /etc/init.d/apache2 restart
&lt;/pre&gt;&lt;br /&gt;
ブラウザでhttp://&amp;lt;servername&amp;gt;/にアクセスして認証が通るか確認してください。失敗した場合はErrorLogディレクティブで指定したログファイルを参照しながら修正してください。&lt;br /&gt;
&lt;br /&gt;
gitがapacheにアクセスできるように ~/.netrcファイルに次の記述をして作成してください。~/netrcはオーナーだけが読み書きできるように権限に600を設定してください。&lt;br /&gt;
&lt;pre class=&quot;init&quot; name=&quot;code&quot;&gt;machine &amp;lt;servername&amp;gt;
login &amp;lt;user&amp;gt;
password &amp;lt;password&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
それではApache上のリポジトリからローカル作業用のcloneを作りましょう。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;~/workspace/git$ git clone http://&amp;lt;servername&amp;gt;/ dev
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
もしこれが動作しない場合、curlを使って認証が通っているか確かめてみましょう。&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;curl --netrc --location -v http://&amp;lt;username&amp;gt;@&amp;lt;servername&amp;gt;/HEAD
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
初めてのプッシュ&lt;br /&gt;
&lt;pre class=&quot;prettyprint&quot;&gt;~/workspace/git/dev$ touch work?
~/workspace/git/dev$ git add .
~/workspace/git/dev$ git commit -m &quot;created work?&quot; 
# masterブランチの内容をoriginにpush
~/workspace/git/dev$ git push origin master
Fetching remote heads...
refs/
refs/tags/
refs/heads/
updating &#39;refs/heads/master&#39;
from 0000000000000000000000000000000000000000
to   bd4637936d5b8978b82ef06f8a8b6f75b716552f
sending 2 objects
done
Updating remote server info
&lt;/pre&gt;&lt;br /&gt;
うまくいかない場合はApacheのリポジトリの所有者やwriteの権限、それからgit update-server-infoを実施したか再チェックしてみてください。&lt;br /&gt;
&lt;br /&gt;
ここまででGit + Apache + Basic認証の設定は完了ですが、この構成で開発を続けていくときっとpushやfetchが遅いことに気づくと思います。それはGitがHTTP越しに動作するときにPackfile(Gitのストレージファイル)をまるごと転送しないといけないためです。Smart HTTPではupload-packとreceive-packというApache上で動くCGIを用意しており、それらがおあつらえのpackfileを作成し、一連のpostを行うようです。GETパラメータにSmart HTTPを実施するかどうかが渡されるため、対応していない場合単純に無視され旧バージョンの動作をします。この設定に関しては後日追記するつもりです。それまで&lt;a href=&quot;http://progit.org/2010/03/04/smart-http.html&quot;&gt;こちらの記事&lt;/a&gt;を参考にしてください。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
この文章で扱ってないこと&lt;br /&gt;
- ダンプ&lt;br /&gt;
&lt;br /&gt;
この文章は著者の理解が甘いため時々修正したり、書き足したりして縦に伸びていく予定です。ツッコミ、文の分かりづらいなどの指摘お待ちしております。&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.</content><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/5855548907929864384'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6758697817819098194/posts/default/5855548907929864384'/><link rel='alternate' type='text/html' href='http://engineerflies.blogspot.com/2010/03/git.html' title='Git入門 ゼロから始めるGitドリル'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/01700091790800160715</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhH1cdyfzewbDFDNyAVeUAjCbbyNwjaLTwc5A_oXhnOIebuFja-rJ8DSVnkgTPWIEyFGd_-6ZWft5c4-T_tluwLEDg-AXHJWRmb1wqV5tUKyOuX54MYLhnYrepQepTMU3VDowZ4JGMQTVkf/s72-c/branch_alone.png" height="72" width="72"/></entry></feed>