git で特定の2つのフォルダーを使ってる履歴のみ残して、後は消す

フォルダー一つだけなら git filter-branch --subdirectory-filter が使えるが、複数の場合はそうもいかない。 複数のフォルダーだけを残すために、Lua スクリプトをさくっと書いた。

function getgitlog(files)
    local fd = io.popen("git log " .. table.concat(files," ") )
    local commit = {}
    if fd then
        for line in fd:lines() do
            if string.match(line,"^commit ") then
                commit[ #commit + 1 ] = string.sub(line,8)
                print( commit[ #commit ])
            end
        end
        fd:close()
    end
    return commit
end


local commit = getgitlog( {"argf","seek"} )
local all = getgitlog( {} )
local first = all[ #all ]

os.execute("git checkout " .. first)
os.execute("git branch tmp")
os.execute("git checkout tmp")
for i=#commit,1,-1 do
    os.execute("git cherry-pick "..commit[i])
end

自分の都合だけで作ったので、下記のような制限がある。

  • 1回限りの利用なので、残すフォルダー「argf」「seek」は決め打ち
  • argf , seek フォルダーに関わっている commit だけをcherry-pick するという方式なので、厳密には argf , seek だけを抽出するわけではない
  • 最初の commit だけは argf , seek フォルダーに関わってなくとも残ってしまう(あとで revert した)
  • git filter-branch --subdirectory-filter みたいに、フォルダーの解消まではしない(二つフォルダーがあるから実際無理)。
  • フォルダー名に空白が含まれると多分誤動作

これを使って公開したのが、先に公開した seek コマンドだったりする。