examining history of deleted file
Asked Answered
D

17

171

If I delete a file in Subversion, how can I look at it's history and contents? If I try to do svn cat or svn log on a nonexistent file, it complains that the file doesn't exist.

Also, if I wanted to resurrect the file, should I just svn add it back?

(I asked specifically about Subversion, but I'd also like to hear about how Bazaar, Mercurial, and Git handle this case, too.)

Dateless answered 30/12, 2008 at 20:5 Comment(0)
C
86

To get the log of a deleted file, use

svn log -r lastrevisionthefileexisted

If you want to resurrect the file and keep its version history, use

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

If you just want the file content but unversioned (e.g., for a quick inspection), use

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

In any case, DO NOT use 'svn up' to get a deleted file back!

Carport answered 30/12, 2008 at 20:13 Comment(7)
You can also ressurrect the file by doing a reverse merge of the revision in which you deleted it. This is the procedure recommended in the SVN docs. As for using "svn up", it's not so much a matter of "don't do it" as it is "it will not do what you want it to do".Silsby
How can I see the file's whole history, though?Dateless
I'd edit the answer if I could, but since I can't, the way to get the whole log is to use a revision range of the form 1:lastrevisionfileexisted (or perhaps it starts at zero... can't remember)Silsby
Simple: show the log for a parent folder with the '-v' switch: you'll get for every entry a list of changed paths. Find the one with a 'D' in front and the name of your deleted file. That's the revision where the file got deleted.Carport
This doesn't seem to work for deleted files. If I try this, I get this error message: svn cat [url]/trunk/include/syeka/poster_funk.incl.php -r 50 > out.txt svn: '/admintools/!svn/bc/131/trunk/include/syeka/poster_funk.incl.php' path not found See @Bert Huijben's response further down this thread for a working solution.Dunigan
If I have a repo with 100,000 commits, "lastrevisionthefileexisted" is not easy to find!Goldplate
If you know the name of the file, or part of it, but don't remember when you deleted it you could use this quick script I threw together a few years back: github.com/inquam/svn-find-deleted-fileFulgurous
W
158

When you want to look at old files you really should know the difference between:

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

and

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

The first version looks at the path that is now available as http://server/svn/project/file and retrieves that file as it was in revision 1234. (So this syntax does not work after a file delete).

The second syntax gets the file that was available as http://server/svn/project/file in revision 1234. So this syntax DOES work on deleted files.

You can even combine these methods to retrieve a file that was available in revision 2345 as http://server/svn/project/file but with the contents as it had in 1234 with:

svn cat http://server/svn/project/file@2345 -r 1234
Wryneck answered 13/2, 2009 at 21:18 Comment(7)
Gah, thanks! The current top response in this thread does not mention this, this is great!Dunigan
This still failed for me unless I used absolute paths, since my local svn client was giving an error when unable to resolve ./local/file when the ./local directory did not exist. This might not be a problem for newer versions of SVN.Yanez
@DerrickRice: In that case, the ^ notation comes handy: it refers to the repository root, so you can say svn cat ^/local/file@REV (depending on the distance between the repository root and URL).Monoclinous
This works great in principle. For folders I receive the following: svn: E200009: Could not cat all targets because some targets are directoriesPosada
This is the best answer. Has the highest votes, too.Sheepshead
This is the answer you are looking for. Not sure how the accepted answer achieved that many votes or got accepted because it doesn't work as far as I can tell.Greatcoat
for rev in {900..600}; do if svn cat server/repo/file.ext@$rev > /dev/null 2>&1; then echo "Last seen at revision: $rev"; break; fi; doneNitza
S
100

First, find the revision number where the file got deleted:

svn log -v > log.txt

Then look in log.txt (not an SVN guru, so I don't know a better way) for a line with

D <deleted file>

and see which revision that was. Then, as in the other answers, resurrect the file using the previous revision.

Scudder answered 30/12, 2008 at 20:17 Comment(5)
svn log -v | grep D "file.name"Viafore
+1 for being the first person to correctly answer the question. You can't look at the contents if you don't know the revision before it was deleted.Pure
@Viafore this obtains the list of deleted files, but discards the revision info, so it's not useful. Also it's slow if you're working with a large/old repository with much change history.Obtuse
Good, great with @abatishchev's improvement. tchen: easily fixed using a -B50 or so argument to grep, see my answer.Allomorphism
Another good way to limit the svn log -v output for very large/old repositories is the -l option. So you could use svn log -v -l 100 | grep D "file.name"Cheesecloth
C
86

To get the log of a deleted file, use

svn log -r lastrevisionthefileexisted

If you want to resurrect the file and keep its version history, use

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

If you just want the file content but unversioned (e.g., for a quick inspection), use

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

In any case, DO NOT use 'svn up' to get a deleted file back!

Carport answered 30/12, 2008 at 20:13 Comment(7)
You can also ressurrect the file by doing a reverse merge of the revision in which you deleted it. This is the procedure recommended in the SVN docs. As for using "svn up", it's not so much a matter of "don't do it" as it is "it will not do what you want it to do".Silsby
How can I see the file's whole history, though?Dateless
I'd edit the answer if I could, but since I can't, the way to get the whole log is to use a revision range of the form 1:lastrevisionfileexisted (or perhaps it starts at zero... can't remember)Silsby
Simple: show the log for a parent folder with the '-v' switch: you'll get for every entry a list of changed paths. Find the one with a 'D' in front and the name of your deleted file. That's the revision where the file got deleted.Carport
This doesn't seem to work for deleted files. If I try this, I get this error message: svn cat [url]/trunk/include/syeka/poster_funk.incl.php -r 50 > out.txt svn: '/admintools/!svn/bc/131/trunk/include/syeka/poster_funk.incl.php' path not found See @Bert Huijben's response further down this thread for a working solution.Dunigan
If I have a repo with 100,000 commits, "lastrevisionthefileexisted" is not easy to find!Goldplate
If you know the name of the file, or part of it, but don't remember when you deleted it you could use this quick script I threw together a few years back: github.com/inquam/svn-find-deleted-fileFulgurous
C
23

It's nothing particularly special in git. If you know the name of the file, you can find out the change that removed it with log:

git log -n 1 -- filename

Then you can use that commit to get the file as it existed before the deletion.

git checkout [last_revision]^ filename

Example:

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 <[email protected]>
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

Note that this does not actually put the file back in revision control. It simply drops the file as it existed in its final state into the current location. You can then add it or just inspect it or whatever from that point.

Cabalist answered 30/12, 2008 at 20:56 Comment(4)
Wonderful answer. Only problem is that the question is about svn!Elfish
As the post makes no attempt to answer the original question which is explicitly about Subversion, consider downvoting it in order to give it a chance to be removed.Hobby
As the original question has this comment downvoting is not fair: "(I asked specifically about Subversion, but I'd also like to hear about how Bazaar, Mercurial, and Git handle this case, too.)"Fluted
@Fluted Stack Exchange principle: Answer the question asked in the title, then you can provide supplementary info. People coming here looking for subversion info are going to be frustrated by an off-topic answer.Freedwoman
E
17

A solution using only the GUI:

If you know the name of the file, but don't know its last revision number or even its path:

  1. From Repo Browser do a "Show log" on the root
  2. Hit "Show All" (at the bottom of the log dialog)
  3. Type the filename into the Filter textbox (at the top of the log dialog)

This will then show only those revisions where the file was added/modified/deleted. This is your history of the file.

Note that if the file was deleted by deleting one of its parent folders, it won't have a 'deleted' entry in the log (and so mjy's solution won't work). In this case, its most recent entry in the filtered log will correspond to its contents at deletion.

Elegance answered 29/11, 2010 at 5:8 Comment(3)
Brute force is not always the shit. Especially not on big repos.Allomorphism
+1 for a UI only solution. Command line is great, and all, but it's not always the best answer without exception. Especially when you're working in an environment you don't control, and don't have easy command line access to SVN.Undershoot
Please note that the above answer is meant for the TortoiseSVN GUI.Bedpost
C
14
svn log -v | grep -B50 YourDeletedFileName

Will get you the path and revision. In git (also checks for renames):

git log --diff-filter=DR --name-only | grep -B50 YourDeletedFileName
Ciracirca answered 6/9, 2012 at 7:27 Comment(2)
What does the -B50 do? I can get a list of files using svn log and grep quite easily using the tips here, but I can't seem to get the revision numbers displayed at all easily, being as they are displayed on a different line. I tried the B50 thing and it didn't seem to work that amazingly for me.Sturgeon
It outputs the mathced line and the 50 lines above that in case anybody else is reading this.Sturgeon
I
10

If you don't know the path to the deleted file, turns out you can search for it in the otherwise all-too-heavy svn log command:

svn log --search <deleted_file_or_pattern> -v

The command is probably hammering the server just as much as it would without the search option, but at least the rest of involved resources (including your eyeballs) would be kinda relieved, since that will tell you in which revision that file was deleted. Then, you can follow the other tips (mainly using the same svn log command, but already on a defined path).

Intellect answered 26/11, 2014 at 12:26 Comment(1)
svn log --search _test2.php -v ... svn: invalid option: --search ... :(Sewer
U
9

In addition to Dustin's answer, if you just want to examine the contents, and not check it out, in his example you can do:

$ git show 8d4a1f^:slosh.tac

the : separates a revision and a path in that revision, effectively asking for a specific path at a specific revision.

Ulises answered 30/12, 2008 at 22:22 Comment(1)
Ah, very true. I used to do that the really, really hard way. :)Cabalist
L
9

Use this command:

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

This will list all revisions that ever deleted any files matching the pattern. That is, if you're searching for file README, then all of /src/README, /src/README.first, and /some/deeply/hidden/directory/READMENOT will be found and listed.

If your filename contains slashes (path), dots, or other special regex characters, don't forget to escape them to avoid mismatching or errors.

Luciferous answered 23/3, 2012 at 10:19 Comment(0)
B
5

The poster has actually asked 3 questions here:

  1. How do I look at the history of a deleted file in Subversion?
  2. How do I look at the contents of a deleted file in Subversion?
  3. How do I resurrect a deleted file in Subversion?

All the answers I see here are for questions 2 and 3.

The answer to question 1 is:

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

You still need to get the revision number for when the file last existed, which is clearly answered by others here.

Bootery answered 7/11, 2011 at 16:8 Comment(0)
F
4

Ah, since I am learning to use Bazaar, it is something I tried. Without success, it appears you cannot log and annotate removed files currently... :-(

Tried:

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

but curiously (and fortunately) I can do:

> bzr cat -r 3 Stuff/ErrorParser.hta

and:

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

and as suggested in the bug above:

> bzr log -v | grep -B 1 ErrorParser

(adjust -B (--before-context) parameter as needed).

Fetiparous answered 12/2, 2009 at 16:55 Comment(0)
H
2

Assume your file was named as ~/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

sample output, found it at 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

copy it back to previous version(90439=90440-1)

svn cp URL_of_deleted.file@90439 .
Hygrostat answered 17/3, 2017 at 2:22 Comment(0)
H
1

You would need to specify a revision.

svn log -r <revision> <deleted file>
Honewort answered 30/12, 2008 at 20:9 Comment(3)
This gives an error. Example: svn log -r 37428 svn.example.com/deletedfile.java svn: '/!svn/bc/98571/deletedfile.java' path not foundRhianna
Are you sure it existed at that revision? You have to specify a revision where the file actually existed.Honewort
See the answer by Bert Huijben for the weird different between -r37428 and adding @37428 to the SVN URL.Urinate
G
1

If you're wanting to look at the history of a file prior to it being renamed, then as mentioned in a comment here you can use

git log --follow -- current_file_name
Gandzha answered 1/12, 2010 at 5:7 Comment(0)
T
1

I wanted an answer, myself. Try the following to output only deletes from 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 } }'

This filters the log output through awk. awk buffers each revision line it finds, outputting it only when a delete record is found. Each revision is only output once, so multiple deletes in a revision are grouped together (as in standard svn log output).

You can specify a --limit to reduce the amount of records returned. You may also remove the --stop-on-copy, as needed.

I know there are complaints about the efficiency of parsing the whole log. I think this is a better solution than grep and its "cast a wide net" -B option. I don't know if it is more efficient, but I can't think of an alternative to svn log. It's similar to @Alexander Amelkin's answer, but doesn't need a specific name. It's also my first awk script, so it might be unconventional.

Timepleaser answered 8/1, 2013 at 16:42 Comment(0)
D
0

You can find the last revision which provides the file using binary search. I have created a simple /bin/bash script for this:

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"
}
Duckbill answered 4/1, 2017 at 13:34 Comment(0)
S
-1

I wrote a php script that copies the svn log of all my repositories into a mysql database. I can now do full text searches on my comments or names of files.

Sewer answered 26/3, 2015 at 17:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.