如果我在Subversion中删除文件,我该如何查看它的历史和内容?如果我尝试对不存在的文件执行svn cat
或svn log
,则会抱怨该文件不存在。
另外,如果我想恢复该文件,我应该svn add
回来吗?
(我特意询问了Subversion,但我也想听听Bazaar,Mercurial和Git如何处理这个案例。)
答案 0 :(得分:144)
当你想查看旧文件时,你真的应该知道它们之间的区别:
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的文件。因此, DOES 语法可用于已删除的文件。
您甚至可以将这些方法组合在一起,以检索版本2345中可用的文件http://server/svn/project/file,但内容与1234中的内容一样:
svn cat http://server/svn/project/file@2345 -r 1234
答案 1 :(得分:89)
首先,找到文件被删除的修订号:
svn log -v > log.txt
然后查看log.txt(不是SVN大师,所以我不知道更好的方法)用于
的行D <deleted file>
并查看该修订版。然后,与其他答案一样,使用之前的版本重新生成文件。
答案 2 :(得分:77)
要获取已删除文件的日志,请使用
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 up'来删除已删除的文件!
答案 3 :(得分:27)
在git中没什么特别的。如果你知道文件的名称,你可以找到用日志删除它的更改:
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
请注意,这实际上并没有将文件放回版本控制中。它只是将文件以其最终状态存在于当前位置。然后,您可以添加它,或者只是检查它或其他任何东西。
答案 4 :(得分:14)
仅使用GUI的解决方案:
如果您知道该文件的名称,但不知道其最新修订号,甚至是其路径:
然后,这将仅显示添加/修改/删除文件的那些修订。 这是您的文件历史记录。
请注意,如果通过删除其中一个父文件夹来删除文件,则日志中不会有“已删除”条目(因此mjy的解决方案将无效)。在这种情况下,过滤日志中的最新条目将与删除时的内容相对应。
答案 5 :(得分:13)
svn log -v | grep -B50 YourDeletedFileName
将为您提供路径和修订。在git中(也检查重命名):
git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName
答案 6 :(得分:8)
除了达斯汀的回答,如果你只想检查内容,而不是检查出来,在他的例子中你可以这样做:
$ git show 8d4a1f^:slosh.tac
:分隔该修订版中的修订版和路径,有效地要求特定版本的特定路径。
答案 7 :(得分:8)
使用此命令:
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
。
如果文件名包含斜杠(路径),点或其他特殊正则表达式字符,请不要忘记将其转义以避免不匹配或错误。
答案 8 :(得分:5)
如果您不知道已删除文件的路径,那么您可以搜索以查看其他方面过于繁重的svn log
命令:
svn log --search <deleted_file_or_pattern> -v
该命令可能与没有搜索选项的情况一样严重打击服务器,但至少其余所涉及的资源(包括你的眼球)将会有所缓解,因为这将告诉你该文件的修订版本是删除。然后,您可以按照其他提示(主要使用相同的svn log
命令,但已经在定义的路径上)。
答案 9 :(得分:4)
啊,因为我正在学习使用Bazaar,这是我尝试过的。没有成功,看来你现在不能log and annotate removed files ......: - (
尝试:
> 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
)参数。
答案 10 :(得分:4)
海报实际上在这里问了3个问题:
我在这里看到的所有答案都是针对问题2和3。
问题1的答案是:
svn log http://server/svn/project/file@1234
您仍然需要获取该文件最后存在时的修订号,这在其他人可以清楚地回答。
答案 11 :(得分:1)
如果您想在重命名之前查看文件的历史记录,那么如a comment here中所述,您可以使用
git log --follow -- current_file_name
答案 12 :(得分:1)
我自己想要一个答案。请尝试以下操作,仅输出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 } }'
这会通过 awk 过滤日志输出。 awk 缓冲它找到的每个修订行,只有在找到删除记录时才输出它。每个修订版只输出一次,因此修订版中的多个删除操作被组合在一起(如标准svn log
输出中所示)。
您可以指定--limit
以减少返回的记录数量。您也可以根据需要删除--stop-on-copy
。
我知道有关于解析整个日志的效率的抱怨。我认为这是一个比grep更好的解决方案,它的“广泛网”-B
选项。我不知道它是否更有效率,但我想不出svn log
的替代方案。它类似于@Alexander Amelkin的答案,但不需要特定的名称。它也是我的第一个 awk 脚本,所以它可能是非常规的。
答案 13 :(得分:1)
您需要指定修订版。
svn log -r <revision> <deleted file>
答案 14 :(得分:0)
我编写了一个php脚本,将我所有存储库的svn日志复制到mysql数据库中。我现在可以对我的评论或文件名进行全文搜索。
答案 15 :(得分:0)
您可以找到使用二进制搜索提供文件的最新修订版。
我为此创建了一个简单的/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"
}
答案 16 :(得分:0)
假设您的文件名为〜/ src / a / b / c / deleted.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 .