Answers:
要获取已删除文件的日志,请使用
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”找回已删除的文件!
当您想查看旧文件时,您确实应该知道以下两者之间的区别:
svn cat http://server/svn/project/file -r 1234
和
svn cat http://server/svn/project/file@1234
第一个版本着眼于为路径,现在可作为HTTP://服务器/ SVN /项目/文件和检索文件,因为它是在修订1234(所以这个语法确实不删除文件后工作)。
第二个语法获取可用的文件HTTP://服务器/ SVN /项目/文件在修订1234所以这句法DOES上删除的文件的工作。
您甚至可以结合使用这些方法来检索版本2345中作为http:// server / svn / project / file提供 但其内容与1234中相同的文件,其中包括:
svn cat http://server/svn/project/file@2345 -r 1234
./local/file
当./local
目录不存在时无法解析时,本地svn客户端会给出错误。对于较新版本的SVN,这可能不是问题。
^
符号很方便:它指向存储库根目录,因此您可以说svn cat ^/local/file@REV
(取决于存储库根目录和URL之间的距离)。
svn: E200009: Could not cat all targets because some targets are directories
首先,找到删除文件的版本号:
svn log -v > log.txt
然后在log.txt中查找(不是SVN专家,所以我不知道更好的方法)
D <deleted file>
看看那是哪个版本。然后,与其他答案一样,使用先前的版本恢复文件。
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
请注意,这实际上并未将文件放回修订控制中。它只是将文件以其最终状态存在时拖放到当前位置。然后,您可以添加它,或者只是检查它,或者从那时开始进行任何检查。
仅使用GUI的解决方案:
如果您知道文件的名称,但不知道其上一个修订号甚至路径:
然后,将仅显示添加/修改/删除文件的那些修订。这是您的文件历史记录。
请注意,如果通过删除其父文件夹之一删除了该文件,则该文件在日志中将没有“已删除”条目(因此mjy的解决方案将不起作用)。在这种情况下,其在过滤日志中的最新条目将对应于其删除时的内容。
使用以下命令:
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
:
svn log --search <deleted_file_or_pattern> -v
该命令可能会像不使用搜索选项时一样重击服务器,但是至少可以缓解所涉及的其余资源(包括您的眼球),因为这将告诉您该文件的修订版本。然后,您可以遵循其他技巧(主要使用相同的svn log
命令,但是已经在定义的路径上)。
svn log --search _test2.php -v
... svn:无效选项:--search ... :(
啊,因为我正在学习使用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 log -r <revision> <deleted file>
我自己想要一个答案。尝试以下操作以仅输出的删除内容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
输出中一样)。
您可以指定a --limit
以减少返回的记录量。您也可以删除--stop-on-copy
根据需要。
我知道有人抱怨解析整个日志的效率。我认为,这比grep及其“广泛应用” -B
选项更好。我不知道它是否更有效,但我无法想到的替代方法svn log
。它类似于@Alexander Amelkin的答案,但不需要特定的名称。这也是我的第一个awk脚本,因此可能是非常规的。
假设您的文件名为〜/ 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 .
您可以使用二进制搜索找到提供文件的最新修订。我/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"
}