<?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>「git」タグの記事一覧 - 工夫と趣向と分別と。</title>
	<atom:link href="https://d.akinori.org/tag/git/feed/" rel="self" type="application/rss+xml" />
	<link>https://d.akinori.org/tag/git/</link>
	<description>おもしろく生きたいね</description>
	<lastBuildDate>Mon, 28 Jan 2013 08:25:48 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.5.2</generator>
<atom:link rel="hub" href="https://pubsubhubbub.appspot.com"/><atom:link rel="hub" href="https://pubsubhubbub.superfeedr.com"/><atom:link rel="hub" href="https://websubhub.com/hub"/>	<item>
		<title>git mergetoolでEmacsのediff-merge-files-with-ancestorを呼び出す</title>
		<link>https://d.akinori.org/2012/07/23/git-mergetool%e3%81%a7emacs%e3%81%aeediff-merge-files-with-ancestor%e3%82%92%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%99/</link>
					<comments>https://d.akinori.org/2012/07/23/git-mergetool%e3%81%a7emacs%e3%81%aeediff-merge-files-with-ancestor%e3%82%92%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%99/#comments</comments>
		
		<dc:creator><![CDATA[Akinori]]></dc:creator>
		<pubDate>Mon, 23 Jul 2012 12:07:23 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[Emacs]]></category>
		<category><![CDATA[git]]></category>
		<guid isPermaLink="false">http://d.akinori.org/?p=2968</guid>

					<description><![CDATA[<p>git mergetoolに使えるツールとして、デフォルトで"emerge"というのが用意されており、Emacs使いはこれを使えばEmergeでマージが行えるわけだが、難点もある。ひとつは、新たなEmacsインスタンスを… <span class="read-more"><a href="https://d.akinori.org/2012/07/23/git-mergetool%e3%81%a7emacs%e3%81%aeediff-merge-files-with-ancestor%e3%82%92%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%99/">続きを読む &#187;</a></span></p>
<p>The post <a href="https://d.akinori.org/2012/07/23/git-mergetool%e3%81%a7emacs%e3%81%aeediff-merge-files-with-ancestor%e3%82%92%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%99/">git mergetoolでEmacsのediff-merge-files-with-ancestorを呼び出す</a> appeared first on <a href="https://d.akinori.org">工夫と趣向と分別と。</a>.</p>
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-yarpp-template-akinori'>
<!-- YARPP List -->

» 関連記事 «<ul>
<li><a href="https://d.akinori.org/2004/05/12/20040512p04/" rel="bookmark" title="tDiary &#8211; tdiary-mode-hook">tDiary &#8211; tdiary-mode-hook</a></li>
<li><a href="https://d.akinori.org/2004/12/25/20041225p02/" rel="bookmark" title="xyzzy / mcalc">xyzzy / mcalc</a></li>
<li><a href="https://d.akinori.org/2007/10/23/20071023p02/" rel="bookmark" title="vc-svk.elが遅い">vc-svk.elが遅い</a></li>
</ul>
</div>
]]></description>
										<content:encoded><![CDATA[<p><code>git mergetool</code>に使えるツールとして、デフォルトで<code>"emerge"</code>というのが用意されており、Emacs使いはこれを使えばEmergeでマージが行えるわけだが、難点もある。ひとつは、新たなEmacsインスタンスを起動してしまうということだ。起動に無駄な時間が掛かるし、マージにあたって既存のセッションで開いているファイルをその場で参照できないのは不便だろう。もっとも、これは<code>emacsclient</code>を使うようにして、Emergeの呼び出し方を少し直せば済む。もうひとつは、EmergeではなくよりモダンなEdiffを使いたいということだが、これは思ったほど簡単ではないのでわざわざこうして記事を書くことになった。</p>
<p>というのも、Emergeには<code>emerge-files-with-ancestor-command</code>という便利なものがあり、「マージが終わったらマージ結果を保存して即終了」ということが一発で出来てしまうのだが、Ediffの方にはそういうものがない。こいつはマージを終了してもろくに片付けもせず、全部ほったらかしという行儀の悪さだ。<br />
そういうわけで、まずはEdiffの<code>ediff-merge-{files,buffers}</code>が終わったら起動前のウィンドウ設定を復元するようにしてみる。これは比較的簡単。<em>[2013-01-23改訂:フックにappendフラグを指定]</em></p><pre class="urvanov-syntax-highlighter-plain-tag">(eval-after-load "ediff"
  '(progn
     ; save and restore window configuration
     (defvar my-ediff-saved-window-configuration nil "Saved window configuration for ediff")
     (defun my-ediff-save-window-configuration ()
       (setq my-ediff-saved-window-configuration (current-window-configuration)))
     (add-hook 'ediff-before-setup-hook 'my-ediff-save-window-configuration)
     (defun my-ediff-restore-window-configuration ()
       (set-window-configuration my-ediff-saved-window-configuration))
     (add-hook 'ediff-suspend-hook 'my-ediff-restore-window-configuration t)
     (add-hook 'ediff-quit-hook 'my-ediff-restore-window-configuration t)))</pre><p>次に、Ediffが新たに開いたファイルのバッファをマージ終了時に自動的に閉じる、および、マージ終了時に自動的にセーブしつつEmacsフレームを閉じる「バッチ版<code>ediff-merge-files-with-ancestor</code>」を加える。<em>[2013-01-23改訂:ediff-filesに影響を与えるなどおかしかったので大幅修正; 続きは<a href="https://github.com/knu/emacsc">GitHub</a>で]</em></p><pre class="urvanov-syntax-highlighter-plain-tag">(eval-after-load "ediff"
  '(progn
     ; batch mode (for use from git mergetool etc.)
     (ediff-defvar-local my-ediff-batch-mode-p nil "True if in batch mode")
     (ediff-defvar-local my-ediff-close-on-quit nil "True if the buffer should be closed on quit.")

     (defun my-ediff-batch-mode (&amp;optional mode)
       (ediff-with-current-buffer ediff-buffer-A
                                  (case mode
                                    (set
                                     (setq my-ediff-batch-mode-p t))
                                    (unset
                                     (prog1 my-ediff-batch-mode-p
                                       (setq my-ediff-batch-mode-p nil)))
                                    (t
                                     my-ediff-batch-mode-p))))

     (defadvice ediff-find-file (around
                                 mark-newly-opened-buffers
                                 (file-var buffer-name &amp;optional last-dir hooks-var)
                                 activate)
       (let* ((file (symbol-value file-var))
              (existing-p (and find-file-existing-other-name
                               (find-buffer-visiting file))))
         ad-do-it
         (or existing-p
             (ediff-with-current-buffer (symbol-value buffer-name)
                                        (setq my-ediff-close-on-quit t)))))

     (defun my-ediff-save-merge ()
       (if (my-ediff-batch-mode)
           (let ((file ediff-merge-store-file))
             (if file
                 (ediff-with-current-buffer ediff-buffer-C
                   (set-visited-file-name file t)
                   (save-buffer))))
         (ediff-maybe-save-and-delete-merge)))

     (remove-hook 'ediff-quit-merge-hook 'ediff-maybe-save-and-delete-merge)
     (add-hook 'ediff-quit-merge-hook 'my-ediff-save-merge)

     (defadvice ediff-cleanup-mess (around
                                    support-batch-mode
                                    ()
                                    activate)
       (let ((batch-p (my-ediff-batch-mode 'unset))
             (buffers (list ediff-buffer-A ediff-buffer-B ediff-ancestor-buffer))
             (buffer-C ediff-buffer-C))
         ad-do-it
         (dolist (buffer buffers)
           (ediff-with-current-buffer buffer
             (and my-ediff-close-on-quit (kill-buffer))))
         (when batch-p
           (ediff-kill-buffer-carefully buffer-C)
           (delete-frame))))

     (defun ediff-merge-files-with-ancestor-in-batch-mode
       (file-A file-B file-ancestor &amp;optional startup-hooks merge-buffer-file)
       (ediff-merge-files-with-ancestor
        file-A file-B file-ancestor
        (cons (function (lambda () (my-ediff-batch-mode 'set))) startup-hooks)
        merge-buffer-file))))

(autoload 'ediff-merge-files-with-ancestor-in-batch-mode "ediff")</pre><p>これで、<code>~/.gitconfig</code>にこんな風に書けば<code>git mergetool</code>で瞬時にEdiffが起動し、マージが済んだら<kbd>q</kbd>, <kbd>y</kbd>で即コマンドラインに帰ってくる。既存Emacsセッションにゴミバッファも残らない。</p><pre class="urvanov-syntax-highlighter-plain-tag">[merge]
	tool = ediff
[mergetool "ediff"]
	cmd = emacsclient -a \"\" -t -e \"(ediff-merge-files-with-ancestor-in-batch-mode \\\"$LOCAL\\\" \\\"$REMOTE\\\" \\\"$BASE\\\" nil \\\"$MERGED\\\")\"</pre><p>あとは、たとえばラッパースクリプトを用意して、「<code>&lt;&lt;&lt;&lt;&lt;&lt;&lt;</code>」などの行が残っていたらマージ失敗とするとか、好きに改良すると良い。</p>
<h3>参考記事</h3>
<ul>
<li><a href="http://stackoverflow.com/questions/1817370/using-ediff-as-git-mergetool">emacs &#8211; Using ediff as git mergetool &#8211; Stack Overflow</a></li>
</ul>
<p>The post <a href="https://d.akinori.org/2012/07/23/git-mergetool%e3%81%a7emacs%e3%81%aeediff-merge-files-with-ancestor%e3%82%92%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%99/">git mergetoolでEmacsのediff-merge-files-with-ancestorを呼び出す</a> appeared first on <a href="https://d.akinori.org">工夫と趣向と分別と。</a>.</p>
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-yarpp-template-akinori'>
<!-- YARPP List -->
<p>» 関連記事 «</p><ul>
<li><a href="https://d.akinori.org/2004/05/12/20040512p04/" rel="bookmark" title="tDiary &#8211; tdiary-mode-hook">tDiary &#8211; tdiary-mode-hook</a></li>
<li><a href="https://d.akinori.org/2004/12/25/20041225p02/" rel="bookmark" title="xyzzy / mcalc">xyzzy / mcalc</a></li>
<li><a href="https://d.akinori.org/2007/10/23/20071023p02/" rel="bookmark" title="vc-svk.elが遅い">vc-svk.elが遅い</a></li>
</ul>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://d.akinori.org/2012/07/23/git-mergetool%e3%81%a7emacs%e3%81%aeediff-merge-files-with-ancestor%e3%82%92%e5%91%bc%e3%81%b3%e5%87%ba%e3%81%99/feed/</wfw:commentRss>
			<slash:comments>237</slash:comments>
		
		
			</item>
		<item>
		<title>Gitを使っていて zsh: no matches found: HEAD^ などと言われない方法</title>
		<link>https://d.akinori.org/2012/01/23/git%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%84%e3%81%a6-zsh-no-matches-found-head-%e3%81%aa%e3%81%a9%e3%81%a8%e8%a8%80%e3%82%8f%e3%82%8c%e3%81%aa%e3%81%84%e6%96%b9%e6%b3%95/</link>
					<comments>https://d.akinori.org/2012/01/23/git%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%84%e3%81%a6-zsh-no-matches-found-head-%e3%81%aa%e3%81%a9%e3%81%a8%e8%a8%80%e3%82%8f%e3%82%8c%e3%81%aa%e3%81%84%e6%96%b9%e6%b3%95/#comments</comments>
		
		<dc:creator><![CDATA[Akinori]]></dc:creator>
		<pubDate>Mon, 23 Jan 2012 08:09:34 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[zsh]]></category>
		<guid isPermaLink="false">http://d.akinori.org/?p=2865</guid>

					<description><![CDATA[<p>Gitを使っていると、今のcommitなし！とgit reset --soft HEAD^したり、abc1234以降のコミットをパッチ化したい！とgit format-patch abc1234^したくなることがよくある… <span class="read-more"><a href="https://d.akinori.org/2012/01/23/git%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%84%e3%81%a6-zsh-no-matches-found-head-%e3%81%aa%e3%81%a9%e3%81%a8%e8%a8%80%e3%82%8f%e3%82%8c%e3%81%aa%e3%81%84%e6%96%b9%e6%b3%95/">続きを読む &#187;</a></span></p>
<p>The post <a href="https://d.akinori.org/2012/01/23/git%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%84%e3%81%a6-zsh-no-matches-found-head-%e3%81%aa%e3%81%a9%e3%81%a8%e8%a8%80%e3%82%8f%e3%82%8c%e3%81%aa%e3%81%84%e6%96%b9%e6%b3%95/">Gitを使っていて zsh: no matches found: HEAD^ などと言われない方法</a> appeared first on <a href="https://d.akinori.org">工夫と趣向と分別と。</a>.</p>
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-yarpp-template-akinori'>
<!-- YARPP List -->

» 関連記事 «<ul>
<li><a href="https://d.akinori.org/2004/01/24/20040124p01/" rel="bookmark" title="GNU screenのコマンドキー">GNU screenのコマンドキー</a></li>
<li><a href="https://d.akinori.org/2004/04/23/20040423p02/" rel="bookmark" title="zshのホスト名補完強化">zshのホスト名補完強化</a></li>
<li><a href="https://d.akinori.org/2007/01/17/20070117p02/" rel="bookmark" title="zshのglobal alias">zshのglobal alias</a></li>
</ul>
</div>
]]></description>
										<content:encoded><![CDATA[<p>Gitを使っていると、<em>今のcommitなし！</em>と<code>git reset --soft HEAD^</code>したり、<em><code>abc1234</code>以降のコミットをパッチ化したい！</em>と<code>git format-patch abc1234^</code>したくなることがよくあるわけだが、この<code>^</code>はzshの拡張グロブ有効化時（<code>setopt extended_glob</code>）はメタ文字として働くため、そのまま入力すると標記のエラーで怒られてしまう。<br />
いちいちエスケープするのは面倒だと思うのだが、ぐぐってみても正面から対処している人があまりいないようなので紹介しておくと、拙作の<a href="https://github.com/knu/zsh-git-escape-magic"><code>git-escape-magic</code></a>を使えば良い。リンク先のドキュメントの通り、ふつうに入力するだけで、いい感じに文脈を見て自動エスケープしてくれる。<br />
このように、zle（zshラインエディタ）をいじると結構おもしろいことができる。<br />
たとえば、3つ上のディレクトリを参照するために<code>../../..</code>などと打つのは指がつりそうな所作だが、カレントディレクトリが<code>.</code>で親ディレクトリが<code>..</code>であるならばn個上のディレクトリは(n-1)個の<code>.</code>の並びで表現できてもよさそうなものである。と、思ったなら、<a href="https://github.com/knu/zsh-manydots-magic"><code>manydots-magic</code></a>のような実装に至ることができる。<br />
もちろん正規表現、Gitのコミットの範囲指定、あるいはワンライナープログラム内で<code>...</code>という並びを使うこともあるので、引数の頭か<code>/</code>の直後でのみ動くようにしているほか、直後に<code>../..</code>の後には似つかわしくない文字が打たれたときは<code>...</code>に戻す工夫を加えた。また、指が滑って打ち過ぎたときに最後の<code>/..</code>をBSを3度も押して削るなどは面倒だから、<code>.</code>連打の後のBSは3文字分を削り直前の状態に戻るようにしてある。<br />
先ほどの<code>git-escape-magic</code>ともども、参考にした<code>url-quote-magic</code>では考慮外だったネストに対応しているので、いくつも併用できる。何かおもしろいものができたら、ぜひ公開してみてくれ。</p>
<p>The post <a href="https://d.akinori.org/2012/01/23/git%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%84%e3%81%a6-zsh-no-matches-found-head-%e3%81%aa%e3%81%a9%e3%81%a8%e8%a8%80%e3%82%8f%e3%82%8c%e3%81%aa%e3%81%84%e6%96%b9%e6%b3%95/">Gitを使っていて zsh: no matches found: HEAD^ などと言われない方法</a> appeared first on <a href="https://d.akinori.org">工夫と趣向と分別と。</a>.</p>
<div class='yarpp yarpp-related yarpp-related-rss yarpp-template-yarpp-template-akinori'>
<!-- YARPP List -->
<p>» 関連記事 «</p><ul>
<li><a href="https://d.akinori.org/2004/01/24/20040124p01/" rel="bookmark" title="GNU screenのコマンドキー">GNU screenのコマンドキー</a></li>
<li><a href="https://d.akinori.org/2004/04/23/20040423p02/" rel="bookmark" title="zshのホスト名補完強化">zshのホスト名補完強化</a></li>
<li><a href="https://d.akinori.org/2007/01/17/20070117p02/" rel="bookmark" title="zshのglobal alias">zshのglobal alias</a></li>
</ul>
</div>
]]></content:encoded>
					
					<wfw:commentRss>https://d.akinori.org/2012/01/23/git%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%a6%e3%81%84%e3%81%a6-zsh-no-matches-found-head-%e3%81%aa%e3%81%a9%e3%81%a8%e8%a8%80%e3%82%8f%e3%82%8c%e3%81%aa%e3%81%84%e6%96%b9%e6%b3%95/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
	</channel>
</rss>
