削除されたファイルの履歴を調べる


158

Subversionでファイルを削除した場合、その履歴と内容を確認するにはどうすればよいですか?実行しようとしsvn catたりsvn log、存在しないファイルに対して実行しようとすると、ファイルが存在しないというメッセージが表示されます。

また、ファイルを復活させたい場合は、svn add元に戻す必要がありますか?

(特にSubversionについて質問しましたが、Bazaar、Mercurial、およびGitがこのケースをどのように処理するかについても聞きたいです。)

回答:


85

削除されたファイルのログを取得するには、次を使用します

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」を使用しないでください!


2
ファイルを削除したリビジョンのリバースマージを実行して、ファイルを復活させることもできます。これは、SVNドキュメントで推奨されている手順です。「svn up」の使い方は、「やりたくない」ではなく、「やりたいことをやらない」ということです。
rmeador 2008

5
しかし、どうすればファイルの全履歴を確認できますか?
ベンジャミンピーターソン

71
シンプル:「-v」スイッチを使用して親フォルダのログを表示します。すべてのエントリについて、変更されたパスのリストが表示されます。先頭に「D」が付いているファイルと、削除したファイルの名前を見つけます。これは、ファイルが削除されたリビジョンです。
Stefan

7
これは削除されたファイルに対しては機能しないようです。これを試すと、次のエラーメッセージが表示されます。svncat [url] /trunk/include/syeka/poster_funk.incl.php -r 50> out.txt svn: '/ admintools /!svn / bc / 131 / trunk / include / syeka / poster_funk.incl.php 'パスが見つかりませんこのスレッドのさらに下にある@Bert Huijbenの応答を参照して、有効な解決策を見つけてください。
Keith Palmer Jr.

2
100,000コミットのリポジトリがある場合、「lastrevisionthefileexisted」は簡単には見つかりません。
Jon Watte

151

古いファイルを調べたいときは、次の違いを知っておく必要があります。

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

そして

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

最初のバージョンは、現在http:// server / svn / project / fileとして利用できるパスを調べます、リビジョン1234の場合と同じようにそのファイルを取得します(したがって、この構文はファイル削除後に機能しませ)。

2番目の構文は、http:// server / svn / project / fileとして利用可能だったファイルを取得しますリビジョンこの構文はそう1234でDOES削除されたファイルで作業を。

これらのメソッドを組み合わせて、リビジョン2345でhttp:// server / svn / project / fileとして利用できた が、1234と同じ内容のファイルを取得することもできます。

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

7
ああ、ありがとう!このスレッドの現在のトップレスポンスはこれについて言及していません。これはすばらしいことです。
Keith Palmer Jr.

絶対パスを使用しない限り、これはまだ失敗しました。ディレクトリが存在しない./local/fileときにローカルのsvnクライアントが解決できないときにエラーが発生した./localためです。これは、SVNの新しいバージョンでは問題にならない場合があります。
デリックライス

2
@DerrickRice:その場合、^表記は便利になります。これはリポジトリルートを参照するので、言うことができますsvn cat ^/local/file@REV(リポジトリルートとURLの間の距離によって異なります)。
musiphil

これは原則としてうまくいきます。フォルダの場合、私は以下を受け取ります:svn: E200009: Could not cat all targets because some targets are directories
Barney

これが最良の答えです。投票数も最高です。
フェリペアルバレス

94

まず、ファイルが削除されたリビジョン番号を見つけます。

svn log -v > log.txt

次に、log.txtを見て(SVNの第一人者ではないため、より良い方法がわかりません)、次の行を探します。

D <deleted file>

そしてそれがどのリビジョンだったかを見てください。次に、他の回答と同様に、以前のリビジョンを使用してファイルを復活させます。


22
svn log -v | grep D "file.name"
abatishchev 2008

18
質問に正しく回答した最初の人物であることの+1。削除前のリビジョンがわからない場合は、内容を確認できません。
セリン

8
@abatishchevこれにより、削除されたファイルのリストが取得されますが、リビジョン情報は破棄されるため、役に立ちません。また、多くの変更履歴を持つ大規模な/古いリポジトリを使用している場合も遅くなります。
11年

4
@abatishchevの改善により、すばらしい。tchen:-B50などの引数をgrepに使用して簡単に修正できます。私の答えを参照してください。
JonasByström9年

2
非常に大きい/古いリポジトリのsvn log -v出力を制限する別の良い方法は、-lオプションです。したがって、svn log -v -l 100 | grep D "file.name"
mindmatters 2013年

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

これは実際にはファイルをリビジョン管理に戻すわけではないことに注意してください。ファイルが最終的な状態で存在していたため、ファイルを現在の場所にドロップするだけです。その後、それを追加するか、単にそれを検査するか、その時点から何でもできます。


6
素晴らしい答え。唯一の問題は、svnに関する質問であることです。
JohnK

16

GUIのみを使用するソリューション:

ファイルの名前はわかっているが、最後のリビジョン番号またはパスさえわからない場合:

  1. リポジトリブラウザからルートで「ログを表示」を実行します
  2. [すべて表示]をクリックします(ログダイアログの下部)。
  3. (ログダイアログの上部にある)[フィルター]テキストボックスにファイル名を入力します。

これにより、ファイルが追加/変更/削除されたリビジョンのみが表示されます。これはファイルの履歴です。

親フォルダーの1つを削除することによってファイルが削除された場合、ログには「削除済み」エントリーが含まれないことに注意してください(したがって、mjyのソリューションは機能しません)。この場合、フィルタリングされたログの最新のエントリは、削除時のコンテンツに対応します。


ブルートフォースは必ずしもクソではありません。特に大きなリポジトリではありません。
JonasByström9年

UIのみのソリューションの場合は+1。コマンドラインはすばらしいですが、すべてが例外なく最良の答えとは限りません。特に、制御できない環境で作業している場合や、SVNにコマンドラインから簡単にアクセスできない場合。
ミール

上記の回答はTortoiseSVN GUIを対象としています。
Georg Muehlenberg、

13
svn log -v | grep -B50 YourDeletedFileName

パスとリビジョンを取得します。git(名前の変更もチェックします):

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

-B50は何をしますか?ここのヒントを使用すると、svn logとgrepを使用してファイルのリストを簡単に取得できますが、リビジョン番号が別の行に表示されているため、簡単に表示されないようです。私はB50のものを試してみましたが、それは私には驚くほどうまくいかなかったようです。
2015

他の誰かがこれを読んでいる場合に備えて、計算された行とその上の50行を出力します。
2015

8

ダスティンの答えに加えて、内容を調べたいだけでチェックアウトしたくない場合は、彼の例では次のようにすることができます。

$ git show 8d4a1f^:slosh.tac

:は、リビジョンとそのリビジョン内のパスを分離し、特定のリビジョンで特定のパスを要求します。


ああ、そうですね。私はそれを本当に、本当に難しい方法でやっていました。:)
ダスティン

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発見し、表示されます。

ファイル名にスラッシュ(パス)、ドット、またはその他の特殊な正規表現文字が含まれている場合は、それらをエスケープして、不一致やエラーを回避することを忘れないでください。


7

削除されたファイルへのパスがわからない場合は、そうでなければall-too-heavy コマンドで検索できることがわかりますsvn log

svn log --search <deleted_file_or_pattern> -v

コマンドはおそらく、検索オプションを使用しない場合と同じようにサーバーを叩きますが、少なくとも残りの関連リソース(眼球を含む)は、そのファイルが削除されたリビジョンを通知するので、少し安心します。次に、他のヒントに従います(主に同じsvn logコマンドを使用しますが、すでに定義済みのパス上にあります)。


svn log --search _test2.php -v... svn:無効なオプション:
search

5

ポスターは実際にここで3つの質問をしました:

  1. Subversionで削除されたファイルの履歴を確認するにはどうすればよいですか?
  2. Subversionで削除されたファイルの内容を確認するにはどうすればよいですか?
  3. Subversionで削除されたファイルを復活させる方法は?

ここにあるすべての回答は、質問2と3に対するものです。

質問1の答えは次のとおりです。

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

ファイルが最後に存在したときのリビジョン番号を取得する必要があります。この番号は、他のユーザーから明確に回答されています。


4

あ、バザールの使い方を学んでいるので、試してみました。成功しないと、現在、削除したファイルをログに記録して注釈を付けることができないようです... :-(

試した:

> 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)パラメータを調整します)。


1

リビジョンを指定する必要があります。

svn log -r <revision> <deleted file>

1
これはエラーになります。例:svn log -r 37428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java'パスが見つかりません
Jeremy

それはそのリビジョンで存在していたのですか?ファイルが実際に存在するリビジョンを指定する必要があります。
ジャックM.

-r37428と@ 37428をSVN URLに追加することの奇妙な違いについては、Bert Huijbenの回答を参照してください。
2011年


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は、見つかった各改訂行をバッファーに入れ、削除レコードが見つかった場合にのみ出力します。各リビジョンは1回だけ出力されるため、リビジョンの複数の削除は(標準svn log出力の場合と同様に)グループ化されます。

を指定して、--limit返されるレコードの量を減らすことができます。--stop-on-copy必要に応じて、を削除することもできます。

ログ全体の解析の効率について不満があることは知っています。これは、grepおよびその「ワイドネットをキャストする」-Bオプションよりも優れたソリューションだと思います。より効率的かどうかはわかりませんが、の代替案は考えられませんsvn log。@Alexander Amelkinの回答に似ていますが、特定の名前は必要ありません。これは私の最初のawkスクリプトでもあるので、型破りかもしれません。


1

ファイルの名前が〜/ 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 .

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"
}

-1

私はすべてのリポジトリのsvnログをmysqlデータベースにコピーするphpスクリプトを作成しました。コメントやファイル名を全文検索できるようになりました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.