How to create svn diff for a new file

2,830 views
Skip to first unread message

ms

unread,
Aug 12, 2010, 1:45:29 PM8/12/10
to reviewboard
Hi,

We use SVN for source control. I have a bunch of newly written code in
new java files that are not yet committed in subversion. I want to
review the code in these files using ReviewBoard, but I'm wondering
how to create diff for these files since they do not have a prior
version (these are brand new files).
SVN won't let me create a diff for these files since there is no
version of these files in SVN. I triesd to use GNU Diff to create a
diff file (using a blank file as previous version file), but that
doesn't load either in ReviewBoard.
Any ideas on how I can review these newly created uncommitted files
using ReviewBoard?

Thanks,
MS

Chris Clark

unread,
Aug 12, 2010, 3:07:46 PM8/12/10
to revie...@googlegroups.com

From memory I'm sure postreview does this for you (it has been a while
since I added a file in svn so I'm a little hazy).

Chris

Vesterbaek

unread,
Aug 12, 2010, 3:17:58 PM8/12/10
to reviewboard
post-review has the --revision-range argument, but this does not work
(as far as I remember - or rather, last time I checked this some while
ago), if you specify lower revision numbers than the initial. If you
want do put whole files up for review, you'd normally want something
ala:
svn diff -r 0:HEAD

but this yields:
svn: Unable to find repository location for '' in revision 0

To work around this, I've created a small python script 'post-review-
initial', which manually creates the diff and passes that to post-
review. You can pass a number of files or dirs as arguments. The files
must be added (not necessarily committed) to svn. Not really sure if
this is the best / most elegant solution, but it works :). Here goes

#
---------------------------------------------------------------------------------------
#!/usr/bin/python
import sys
import os
import os.path
import subprocess
from optparse import OptionParser

DUMMY_FILENAME = '__dummy_non_existing_file'
TMP_FILENAME = '__post_review_initial_tmp_file.diff'

def get_files(paths):
if not paths:
paths = ['.']
files = []
for p in paths:

if os.path.isdir(p):
dir = p
else:
dir = os.path.dirname(p)

_files = execute(['svn', 'list', '--recursive', p],
split_lines=True)
_files = [os.path.join(dir, file) for file in _files]
_files = [os.path.abspath(f) for f in _files]

for f in _files:
if os.path.isfile(f):
files.append(f)

# return sorted list of files. convert to set and back to list to
remove duplicates
return sort_and_remove_duplicates(files)


def sort_and_remove_duplicates(a):
if a:
a.sort()
last = a[-1]
for i in range(len(a)-2, -1, -1):
if last == a[i]:
del a[i]
else:
last = a[i]
return a


def create_file_diff(file):
diff = execute(['diff', '-u', '--new-file', DUMMY_FILENAME, file],
split_lines=True, ignore_errors=True)

if not diff:
return ''

info = execute(['svn', 'info', file], split_lines=True)
for l in info:
if l.lower().startswith('url'):
url = l.split(':',1)[1].strip()
if l.lower().startswith('repository root'):
repos_root = l.split(':',1)[1].strip()
if l.lower().startswith('revision'):
rev = l.split(':',1)[1].strip()
if not url or not repos_root or not rev:
raise Exception('Failed to get svn info for ' + file)

url = url.replace(repos_root, '')

diff.insert(0, 'Index: ' + url)
diff.insert(1,
'===================================================================')
diff[2] = '--- ' + url + '\t(revision 0)'
diff[3] = '+++ ' + url + '\t(revision %s)' % (rev)

return '\n'.join(diff)


def execute(command, env=None, split_lines=False, ignore_errors=False,
extra_ignore_errors=()):
if env:
env.update(os.environ)
else:
env = os.environ.copy()

env['LC_ALL'] = 'en_US.UTF-8'
env['LANGUAGE'] = 'en_US.UTF-8'

if sys.platform.startswith('win'):
p = subprocess.Popen(command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=False,
universal_newlines=True,
env=env)
else:
p = subprocess.Popen(command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=False,
close_fds=True,
universal_newlines=True,
env=env)
if split_lines:
data = [line.rstrip('\n') for line in p.stdout.readlines()]
else:
data = p.stdout.read()
rc = p.wait()
if rc and not ignore_errors and rc not in extra_ignore_errors:
raise Exception('Failed to execute command: %s\n%s' %
(command, data))

return data

def parse_options(args):
parser = OptionParser(usage='%prog [-n] [dir1/file1] [dir2/
file2] .... [post-review options]', version='%prog ' + '0.02')
parser.add_option('-n', '--output-diff', dest='output_diff_only',
action='store_true', default=False, help='outputs a diff to the
console and exits. Does not post')
# Add options after files to args list (used for post-review)
parser.disable_interspersed_args()
(options, args) = parser.parse_args(args)
return (options, args)

def main(args):
(options,args) = parse_options(args)

files_dirs = []
post_review_args = []
for a in args:
if a.startswith('-'):
post_review_args.append(a)
else:
files_dirs.append(a)

files = get_files(files_dirs)
diff = '\n'.join([create_file_diff(file) for file in files])

if options.output_diff_only:
print diff
else:
f = open(TMP_FILENAME, 'w')
f.write(diff)
f.close()
execute(['python', os.path.join(os.path.dirname(__file__), 'post-
review.py'), '--diff-filename='+TMP_FILENAME]+post_review_args)
# Cleanup
try:
os.unlink(TMP_FILENAME)
except:
pass

if __name__ == '__main__':
main(sys.argv[1:])
#
---------------------------------------------------------------------------------------

- Jeppe

Christian Hammond

unread,
Aug 13, 2010, 6:17:19 AM8/13/10
to revie...@googlegroups.com
In this case, post-review should actually work. post-review with Subversion shouid properly handle the case where you have new files that haven't been committed yet that you want to put up for review. We did this all the time with Review Board itself, before we switched over to Git.

Correct me if I'm wrong, but your script is useful when you want to put existing committed code as a whole up for review, right? Such as when you're doing a post-commit review for the first time of some code?

Christian

--
Christian Hammond - chi...@chipx86.com
Review Board - http://www.reviewboard.org
VMware, Inc. - http://www.vmware.com



--
Want to help the Review Board project? Donate today at http://www.reviewboard.org/donate/
Happy user? Let us know at http://www.reviewboard.org/users/
-~----------~----~----~----~------~----~------~--~---
To unsubscribe from this group, send email to reviewboard...@googlegroups.com
For more options, visit this group at http://groups.google.com/group/reviewboard?hl=en

Vesterbaek

unread,
Aug 15, 2010, 9:26:17 AM8/15/10
to reviewboard

> Correct me if I'm wrong, but your script is useful when you want to put
> existing committed code as a whole up for review, right? Such as when you're
> doing a post-commit review for the first time of some code?

Yup, correct. Having re-read the original question, I agree that if
you want to review new code that has just been added (but not
committed), post-review does the job. My script is for generating a
full review (diff with left side blank) of already checked in code.

- Jeppe

Manjit Singh

unread,
Aug 20, 2010, 4:39:39 PM8/20/10
to revie...@googlegroups.com
Your script did the job for me. This is exactly what I needed to do (I needed a full diff).
Thanks a lot.
-MS


 - Jeppe

Nathan Heijermans

unread,
Aug 20, 2010, 9:31:54 PM8/20/10
to revie...@googlegroups.com
It is indeed possible to use post-review to generate an appropriate diff following the post-commit review model. RBTools version 0.2.0 contains a fix that makes it possible to generate the initial review by passing "--revision-range 0:HEAD" to post-review. If you're stuck with an older version of RBTools, the appropriate changes can be found at http://reviews.reviewboard.org/r/1429/.

Cheers,
Nathan Heijermans

rv_saraswathi

unread,
May 22, 2012, 3:42:28 AM5/22/12
to revie...@googlegroups.com
Hi,

Sorry for replying to an old post. But I am having problems for uploading svn files, as described below:

- In my repository (SVN) there was a single svn add and commit (resulting in a revision #1683), for a huge set of files. 
- I am trying to help my team upload these files to RB, but cannot create a diff with this command below:
         post-review --revision-range 0:HEAD --output-diff --debug --disable-proxy

   which gives me the below error:

rvnath@rvnath:~/workpad/mohit/ResourceManager$ post-review --revision-range 0:HEAD --output-diff --debug --disable-proxy
>>> RBTools 0.4
>>> Home = /home/rvnath
>>> Disabling HTTP(s) proxy support
>>> HTTP GETting api/
>>> HTTP GETting http://172.19.2.226/reviews/api/info/
>>> Using the new web API
Failed to execute command: ['svn', 'diff', '--diff-cmd=diff', '-r', '0:HEAD']
["svn: Unable to find repository location for '' in revision 0\n"]

I downloaded and installed RBTools version 0.4, but still same problem.  Here is the version of my RBTools...

rvnath@rvnath:~/workpad/mohit/ResourceManager$ post-review --version
RBTools 0.4
rvnath@rvnath:~/workpad/mohit/ResourceManager$

I also tried with the script posted by Vester.  This also gives me errors, as below:

rvnath@rvnath:~/workpad/mohit/ResourceManager$ python ~/post-review-initial.py .
Traceback (most recent call last):
  File "/home/rvnath/post-review-initial.py", line 147, in <module>
    main(sys.argv[1:])
  File "/home/rvnath/post-review-initial.py", line 131, in main

    diff = '\n'.join([create_file_diff(file) for file in files])
  File "/home/rvnath/post-review-initial.py", line 69, in create_file_diff

    diff[3] = '+++ ' + url + '\t(revision %s)' % (rev)
IndexError: list assignment index out of range
rvnath@rvnath:~/workpad/mohit/ResourceManager$

What I really want is a simple way to upload a revision snapshot, instead of a diff.

Thanks for all the help in this regard..
rv


On Saturday, August 21, 2010 7:01:54 AM UTC+5:30, Nathan wrote:
It is indeed possible to use post-review to generate an appropriate diff following the post-commit review model. RBTools version 0.2.0 contains a fix that makes it possible to generate the initial review by passing "--revision-range 0:HEAD" to post-review. If you're stuck with an older version of RBTools, the appropriate changes can be found at http://reviews.reviewboard.org/r/1429/.

Cheers,
Nathan Heijermans

On Fri, Aug 20, 2010 at 4:39 PM, Manjit Singh <manjit...@gmail.com> wrote:
Your script did the job for me. This is exactly what I needed to do (I needed a full diff).
Thanks a lot.
-MS


On Sun, Aug 15, 2010 at 6:26 AM, Vesterbaek <veste...@gmail.com> wrote:

> Correct me if I'm wrong, but your script is useful when you want to put
> existing committed code as a whole up for review, right? Such as when you're
> doing a post-commit review for the first time of some code?

Yup, correct. Having re-read the original question, I agree that if
you want to review new code that has just been added (but not
committed), post-review does the job. My script is for generating a
full review (diff with left side blank) of already checked in code.

 - Jeppe

--
Want to help the Review Board project? Donate today at http://www.reviewboard.org/donate/
Happy user? Let us know at http://www.reviewboard.org/users/
-~----------~----~----~----~------~----~------~--~---
To unsubscribe from this group, send email to reviewboard+unsubscribe@googlegroups.com

For more options, visit this group at http://groups.google.com/group/reviewboard?hl=en

--
Want to help the Review Board project? Donate today at http://www.reviewboard.org/donate/
Happy user? Let us know at http://www.reviewboard.org/users/
-~----------~----~----~----~------~----~------~--~---
To unsubscribe from this group, send email to reviewboard+unsubscribe@googlegroups.com

Nathan Heijermans

unread,
Jun 2, 2012, 7:30:29 PM6/2/12
to revie...@googlegroups.com
rv,

I just noticed your question, and seem to recall running into a
similar problem. IIRC, post-review doesn't work the way you want with
a locally checked-out source tree, but works fine when adding a diff
directly from the Subversion server. Try running the command like this
instead::

post-review --revision-range 0:HEAD --output-diff URL_TO_SOURCE_TREE

Regards,
Nathan Heijermans
>>>> reviewboard...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/reviewboard?hl=en
>>>
>>>
>>> --
>>> Want to help the Review Board project? Donate today at
>>> http://www.reviewboard.org/donate/
>>> Happy user? Let us know at http://www.reviewboard.org/users/
>>> -~----------~----~----~----~------~----~------~--~---
>>> To unsubscribe from this group, send email to
>>> reviewboard...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/reviewboard?hl=en
>>
>>
> --
> Want to help the Review Board project? Donate today at
> http://www.reviewboard.org/donate/
> Happy user? Let us know at http://www.reviewboard.org/users/
> -~----------~----~----~----~------~----~------~--~---
> To unsubscribe from this group, send email to
> reviewboard...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages