检查被删除文件的历史记录

如果我在 Subversion 中删除了一个文件,我如何查看它的历史记录和内容?如果我尝试对一个不存在的文件执行 svn catsvn log操作,它会抱怨该文件不存在。

还有,如果我想要恢复文件,我是否应该返回 svn add

(我特别询问了 Subversion,但是我也想了解 Bazaar、 Mercurial 和 Git 是如何处理这个案例的。)

91576 次浏览

您需要指定一个修订版。

svn log -r <revision> <deleted file>

若要获取已删除文件的日志,请使用

svn log -r lastrevisionthefileexisted

如果要恢复文件并保持其版本历史记录,请使用

svn copy url/of/file@lastrevisionthefileexisted -r lastrevisionthefileexisted path/to/workingcopy/file

如果您只想要文件内容,但是没有版本控制(例如,为了快速检查) ,请使用

svn cat url/of/file@lastrevisionthefileexisted -r latrevisionthefileexisted > file

在任何情况下,不要使用’svn 上’得到一个删除的文件回来!

首先,找到文件被删除的版本号:

svn log -v > log.txt

然后在 log.txt (不是 SVN 专家,所以我不知道更好的方法)中找到

D <deleted file>

然后,就像在其他答案中一样,使用之前的修订重新生成文件。

Git 没什么特别的。如果您知道文件的名称,可以通过 log 查找删除该文件的更改:

git log -n 1 -- filename

然后,您可以使用该提交来获取删除之前存在的文件。

git checkout [last_revision]^ filename

例如:

dhcp-120:/tmp/slosh 587% ls -l slosh.tac
ls: slosh.tac: No such file or directory
dhcp-120:/tmp/slosh 588% git log -n 1 -- slosh.tac
commit 8d4a1f1a94e4aa37c1cb9d329a140d08eec1b587
Author: Dustin Sallings <dustin@spy.net>
Date:   Mon Dec 15 11:25:00 2008 -0800


Get rid of a .conf and replace it with .tac.
dhcp-120:/tmp/slosh 589% git checkout 8d4a1f^ slosh.tac
dhcp-120:/tmp/slosh 590% ll slosh.tac
-rw-------  1 dustin  wheel  822 Dec 30 12:52 slosh.tac

注意,这实际上并没有将文件放回修订控制中。它只是将处于最终状态的文件拖放到当前位置。然后你可以添加它,或者只是检查它,或者从那一点开始。

除了达斯汀的回答,如果你只是想检查内容,而不是检查出来,在他的例子中,你可以这样做:

$ git show 8d4a1f^:slosh.tac

将修订和修订中的路径分开,有效地要求在特定的修订中有一个特定的路径。

啊,因为我正在学习使用 Bazaar,这是我尝试的东西。没有成功,似乎你不能 对删除的文件进行日志记录和注释目前... :-(

试过:

> bzr log -r 3 Stuff/ErrorParser.hta
bzr: ERROR: Path does not have any revision history: Stuff/ErrorParser.hta

但奇怪的是(幸运的是)我能做到:

> bzr cat -r 3 Stuff/ErrorParser.hta

以及:

> bzr diff -r 2..3 Stuff/ErrorParser.hta

正如上面的错误所暗示的那样:

> bzr log -v | grep -B 1 ErrorParser

(根据需要调整 -B(--before-context)参数)。

当你想查看旧文件时,你真的应该知道以下两者的区别:

svn cat http://server/svn/project/file -r 1234

还有

svn cat http://server/svn/project/file@1234

第一个版本查看作为 http://server/svn/project/file提供的 现在路径,并检索该文件,如同它在修订版1234中那样。(因此,这种语法在文件删除后仍然有效)。

第二种语法获取版本1234中作为 http://server/svn/project/file提供的文件。因此,这种语法 是的适用于已删除的文件。

您甚至可以结合使用这些方法来检索一个文件,该文件在修订版2345中作为 http://server/svn/project/file提供,但其内容与修订版1234中的内容一样,具有:

svn cat http://server/svn/project/file@2345 -r 1234

只使用 GUI 的解决方案:

如果你知道文件的名字,但是 不知道上次的修订号甚至它的路径:

  1. 从 Repo Browser 对根目录执行“ Show log”操作
  2. 点击“全部显示”(在日志对话框的底部)
  3. 在 Filter 文本框中键入文件名(在日志对话框的顶部)

然后,这将只显示文件添加/修改/删除的那些修订

注意,如果文件是通过删除其父文件夹之一来删除的,那么日志中就不会有“已删除”的条目(因此 mjy 的解决方案不起作用)。在这种情况下,其在筛选日志中的最新条目将与其删除时的内容相对应。

如果您希望查看文件在重命名之前的历史记录,那么可以使用 这里有评论中提到的

git log --follow -- current_file_name

这张海报实际上问了3个问题:

  1. 如何查看 Subversion 中已删除文件的历史记录?
  2. 如何在 Subversion 中查看已删除文件的内容?
  3. 如何在 Subversion 中恢复已删除的文件?

我在这里看到的所有答案都是关于问题2和问题3的。

问题1的答案是:

svn log http://server/svn/project/file@1234

您仍然需要获取文件上次存在时的修订号,这里的其他人已经清楚地回答了这个问题。

使用以下命令:

svn log -v | awk '/^r[0-9]+/ { rev = $1; }; / D .*filename_escaped_for_regex/ { print rev" "$2; };'

这将列出所有的修订,曾经删除任何文件匹配的模式。 也就是说,如果您正在搜索文件 README,那么将找到并列出所有的 /src/README/src/README.first/some/deeply/hidden/directory/READMENOT

如果您的 文件名包含斜杠(路径)、点或其他特殊的正则表达式字符,不要忘记转义它们,以避免错误匹配或错误。

svn log -v | grep -B50 YourDeletedFileName

将得到路径和修订。在 git 中(也检查重命名) :

git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName

我想要一个答案,我自己。尝试下面的输出只从 svn log删除。

svn log --stop-on-copy --verbose [--limit <limit>] <repo Url> | \
awk '{ if ($0 ~ /^r[0-9]+/) rev = $0 }
{ if ($0 ~ /^ D /) { if (rev != "") { print rev; rev = "" }; print $0 } }'

这将通过 过滤日志输出。缓冲它找到的每个修订行,只有在找到删除记录时才输出它。每个修订只有一次输出,因此修订中的多个删除被组合在一起(与标准 svn log输出一样)。

可以指定 --limit以减少返回的记录数量。还可以根据需要删除 --stop-on-copy

我知道有人抱怨解析整个日志的效率有问题。我认为这是一个比 grep 和它的“撒大网”-B选项更好的解决方案。我不知道它是否更有效,但我不能想出一个替代 svn log。它与@Alexander Amelkin 的回答类似,但不需要具体的名称。这也是我的第一个 脚本,所以它可能是非常规的。

如果你不知道被删除的文件的路径,原来你可以在 svn log命令中找到它:

svn log --search <deleted_file_or_pattern> -v

这个命令可能会像没有搜索选项一样对服务器造成很大的影响,但是至少其他相关的资源(包括你的眼球)会稍微松一口气,因为它会告诉你该文件是在哪个版本中被删除的。然后,您可以遵循其他提示(主要使用相同的 svn log命令,但是已经在已定义的路径上)。

我编写了一个 php 脚本,将所有存储库的 svn 日志复制到 mysql 数据库中。现在,我可以对我的注释或文件名进行全文搜索。

您可以使用二进制搜索找到提供该文件的最后一个修订版。 我为此创建了一个简单的 /bin/bash脚本:

function svnFindLast(){
# The URL of the file to be found
local URL="$1"
# The SVN revision number which the file appears in (any rev where the file DOES exist)
local r="$2"
local R
for i in $(seq 1 "${#URL}")
do
echo "checkingURL:'${URL:0:$i}'" >&2
R="$(svn info --show-item revision "${URL:0:$i}" 2>/dev/null)"
echo "R=$R" >&2
[ -z "$R" ] || break
done
[ "$R" ] || {
echo "It seems '$URL' is not in a valid SVN repository!" >&2
return -1
}
while [ "$r" -ne "$R" -a "$(($r + 1))" -ne "$R" ]
do
T="$(($(($R + $r)) / 2))"
if svn log "${URL}@${T}" >/dev/null 2>&1
then
r="$T"
echo "r=$r" >&2
else
R="$T"
echo "R=$R" >&2
fi
done
echo "$r"
}

假设您的文件名为 ~/src/a/b/c/delete ted.file

cd ~/src/a/b/c  # to the directory where you do the svn rm or svn mv command
#cd ~/src   # if you forget the correct directory, just to the root of repository
svn log -v | grep -w -B 9 deleted.file | head  # head show first 10 lines

样本输出,发现它在 r90440

...
r90440 | user | 2017-02-03 11:55:09 +0800 (Fri, 03 Feb 2017) | 4 lines
Changed paths:
M /src/a/b/c/foo
M /src/a/b/c/bar
D /src/a/b/c/deleted.file

复制回以前的版本(90439 = 90440-1)

svn cp URL_of_deleted.file@90439 .