获取已删除 git-svn 文件的 SVN URL

Get SVN URL of removed git-svn file

我想在 SVN 存储库的 子目录 上使用 git-svn 时尽可能早地跟踪已删除的文件。

  1. 使用 git log --full-history -- path/to/removed_file.py,我可以看到从文件移动到我使用 git-svn.
  2. 检出的子目录的时间开始的历史记录
  3. 我可以在 git-svn 提交消息后缀中看到哪个 SVN 修订版,所以我现在想使用 svn log <full_url>@revision 查看其余的历史记录。
  4. 我知道我可以使用 git svn info --url path/to/existing_file.py 来查看所需的完整 SVN url,但是 获取 SVN [=33] 的快速(理想情况下可编写脚本)方式是什么=] 不再存在于存储库中的文件?

对于git,在HEAD中删除一个文件foo/bar.py并不重要——只要你在历史中有它,你就可以查看过去的每一个版本

为了清楚具体,我将以 LLVM 项目中的 this git-svn repo 为例。在那里,文件 docs/todo.rst 已在 svn 修订版 308987 中删除,git 提交 fb572868… 并且在 master.

中不存在

让我们先初始化一个本地克隆。

$ git clone https://github.com/llvm-mirror/lnt && cd lnt
Cloning into 'lnt'...
...
$ git svn init https://llvm.org/svn/llvm-project/lnt/trunk
$ git update-ref refs/remotes/git-svn refs/remotes/origin/master
$ 
$ #-- ask svn info of anything to check setup and/or force laziness
$ git svn info --url README.md
Rebuilding .git/svn/refs/remotes/git-svn/.rev_map.91177308-0d34-0410-b5e6-96231b3b80d8 ...
r154126 = 3c3062527ac17b5fac440c55a3e1510d0ab8c9d9
r154135 = 82a95d29ac7d25c355fbd0898a44dc3e71a75fd8
...
r374687 = 446f9a3b651086e87684d643705273ef78045279
r374824 = 8c57bba3687ada10de5653ae46c537e957525bdb
Done rebuilding .git/svn/refs/remotes/git-svn/.rev_map.91177308-0d34-0410-b5e6-96231b3b80d8
https://llvm.org/svn/llvm-project/lnt/trunk/README.md

所以它按预期返回 README.md URL。现在让我们试试删除文件的情况:

$ git svn info --url docs/todo.rst
svn: 'docs/todo.rst' is not under version control

失败,正如你所说。 man git-svn 表示 info 目前不支持 -r/--revision 参数。

那好吧,让我们尝试模拟它的作用,首先是手工。

https://llvm.org/svn/llvm-project/lnt/trunk/README.md?r=374824 — 这是给定版本的给定文件的 URL。

我们消失的 docs/todo.rsthttps://llvm.org/svn/llvm-project/lnt/trunk/docs/todo.rst?p=308986 可用 注意减量:每个 git show fb572868 | grep git-svn-iddocs/todo.rst 已经 删除r308987 — 所以我们请求 r308986。

开始编写脚本...相当简单的工作。

git-svn-oldinfo () {
  relfname=""
  git log -n1 -- "$relfname" \
    | awk '/git-svn-id:/ {sub(/@/, " ", ); print }' \
    | { read baseurl rev; echo "${baseurl}/${relfname}?p=$((rev-1))"; }
}

#-- test:
$ git-svn-oldinfo docs/todo.rst
https://llvm.org/svn/llvm-project/lnt/trunk/docs/todo.rst?p=308986

Quick-n-dirty 但经过测试 — 欢迎您根据需要进行调整和扩展。


编辑

尽管 git log 是一个“瓷器”命令(即不是真正为脚本设计的),如果您要通过像 [=27 这样的 glob 查询,也很有可能从中解析出文件名=]:

git-svn-oldinfo-glob () {
  fileglob=""
  git log -n1 --stat --format=oneline -- "$fileglob" \
    | { read commit msg; \
        read fullname _remainder_dummy; \
        git cat-file -p $commit \
          | tail -n1 \
          | awk '/git-svn-id:/ {sub(/@/, " ", ); print }' \
          | { read baseurl rev; echo "${baseurl}/${fullname}?p=$((rev-1))"; } \
      }
}

#-- test:
$ git-svn-oldinfo-glob '**/todo.rst'
https://llvm.org/svn/llvm-project/lnt/trunk/docs/todo.rst?p=308986

对它持保留态度:如果 glob 匹配多个文件、non-removed 文件、名称中有空格的文件等,它可能会以搞笑的方式崩溃或输出垃圾。

一如既往,请查看 man git-log 并根据需要进行自定义。