<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Submodule on 終於明白 | tsungyi knows.</title><link>https://tsungyi.li/Blog/tags/submodule/</link><description>Recent content in Submodule on 終於明白 | tsungyi knows.</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Thu, 29 Oct 2026 10:55:56 +0800</lastBuildDate><atom:link href="https://tsungyi.li/Blog/tags/submodule/index.xml" rel="self" type="application/rss+xml"/><item><title>拆開 fzf 腳本：每支背後真正在跑的 Git 指令</title><link>https://tsungyi.li/Blog/posts/git-commands-behind-fzf-scripts/</link><pubDate>Thu, 29 Oct 2026 10:55:56 +0800</pubDate><guid>https://tsungyi.li/Blog/posts/git-commands-behind-fzf-scripts/</guid><description>&lt;h2 id="起因"&gt;起因&lt;/h2&gt;&#10;&lt;p&gt;&lt;a href="../interactive-git-cli-with-fzf/"&gt;上一篇&lt;/a&gt;講的是這些腳本怎麼設計。這篇反過來：把 fzf 那層剝掉，看每支腳本&lt;strong&gt;實際&lt;/strong&gt;在跑哪幾條 git 指令。&lt;/p&gt;&#10;&lt;p&gt;理由很實際。腳本不在手邊時（別人的機器、CI、container），你還是得自己打這些指令。而且拆的過程中，我挖出了兩個藏了很久的 bug。&lt;/p&gt;&#10;&lt;h2 id="共用底層"&gt;共用底層&lt;/h2&gt;&#10;&lt;p&gt;每支腳本開頭都是同一組檢查：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rev-parse --is-inside-work-tree &lt;span style="color:#75715e"&gt;# 不在 repo 裡就結束&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rev-parse --show-toplevel &lt;span style="color:#75715e"&gt;# cd 到 repo 根目錄&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;需要 &lt;code&gt;cd&lt;/code&gt; 到根目錄，是因為 &lt;code&gt;git status --short&lt;/code&gt; 和 &lt;code&gt;git diff --name-status&lt;/code&gt; 印出的路徑都是相對於 repo 根目錄。在子目錄裡直接拿去當 pathspec 用，就會對不上。&lt;/p&gt;&#10;&lt;p&gt;列分支用的是 &lt;code&gt;git branch --format&lt;/code&gt;，語法和 &lt;code&gt;git for-each-ref&lt;/code&gt; 一模一樣，連條件式都能寫：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch -l --format&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;%(refname:short) [%(objectname:short)] %(if)%(upstream)%(then)-&amp;gt; %(upstream:short)%(else)&amp;lt;no upstream&amp;gt;%(end)&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="gitbr查分支指向哪裡"&gt;gitbr：查分支指向哪裡&lt;/h2&gt;&#10;&lt;p&gt;&lt;code&gt;gitbr&lt;/code&gt; 的用途是：不 checkout 也能知道一條分支指向哪個 commit、有沒有追蹤 upstream，並把 short SHA 複製到剪貼簿。核心只有三條：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git branch --show-current &lt;span style="color:#75715e"&gt;# 目前分支名稱&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rev-parse &amp;lt;ref&amp;gt; &lt;span style="color:#75715e"&gt;# ref → SHA&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rev-parse --abbrev-ref &amp;lt;branch&amp;gt;@&lt;span style="color:#f92672"&gt;{&lt;/span&gt;upstream&lt;span style="color:#f92672"&gt;}&lt;/span&gt; &lt;span style="color:#75715e"&gt;# 追蹤的遠端分支&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;&amp;lt;branch&amp;gt;@{upstream}&lt;/code&gt;（縮寫 &lt;code&gt;@{u}&lt;/code&gt;）指的是 &lt;code&gt;branch.&amp;lt;name&amp;gt;.merge&lt;/code&gt; 設定的那條 remote-tracking branch。如果沒有設定，指令會失敗，所以腳本後面接了 &lt;code&gt;|| true&lt;/code&gt;。&lt;/p&gt;</description></item></channel></rss>