| #!/usr/bin/env python |
| # |
| # diff_tests.py: some basic diff tests |
| # |
| # Subversion is a tool for revision control. |
| # See http://subversion.tigris.org for more information. |
| # |
| # ==================================================================== |
| # Copyright (c) 2000-2007 CollabNet. All rights reserved. |
| # |
| # This software is licensed as described in the file COPYING, which |
| # you should have received as part of this distribution. The terms |
| # are also available at http://subversion.tigris.org/license-1.html. |
| # If newer versions of this license are posted there, you may use a |
| # newer version instead, at your option. |
| # |
| ###################################################################### |
| |
| # General modules |
| import sys, re, os, time |
| |
| # Our testing module |
| import svntest |
| |
| # (abbreviation) |
| Skip = svntest.testcase.Skip |
| XFail = svntest.testcase.XFail |
| Item = svntest.wc.StateItem |
| |
| |
| ###################################################################### |
| # Diff output checker |
| # |
| # Looks for the correct filenames and a suitable number of +/- lines |
| # depending on whether this is an addition, modification or deletion. |
| |
| def check_diff_output(diff_output, name, diff_type): |
| "check diff output" |
| |
| # On Windows, diffs still display / rather than \ in paths |
| if svntest.main.windows == 1: |
| name = name.replace('\\', '/') |
| i_re = re.compile('^Index:') |
| d_re = re.compile('^Index: (\\./)?' + name) |
| p_re = re.compile('^--- (\\./)?' + name) |
| add_re = re.compile('^\\+') |
| sub_re = re.compile('^-') |
| |
| i = 0 |
| while i < len(diff_output) - 4: |
| |
| # identify a possible diff |
| if (d_re.match(diff_output[i]) |
| and p_re.match(diff_output[i+2])): |
| |
| # count lines added and deleted |
| i += 4 |
| add_lines = 0 |
| sub_lines = 0 |
| while i < len(diff_output) and not i_re.match(diff_output[i]): |
| if add_re.match(diff_output[i][0]): |
| add_lines += 1 |
| if sub_re.match(diff_output[i][0]): |
| sub_lines += 1 |
| i += 1 |
| |
| #print "add:", add_lines |
| #print "sub:", sub_lines |
| # check if this looks like the right sort of diff |
| if add_lines > 0 and sub_lines == 0 and diff_type == 'A': |
| return 0 |
| if sub_lines > 0 and add_lines == 0 and diff_type == 'D': |
| return 0 |
| if add_lines > 0 and sub_lines > 0 and diff_type == 'M': |
| return 0 |
| |
| else: |
| i += 1 |
| |
| # no suitable diff found |
| return 1 |
| |
| def count_diff_output(diff_output): |
| "count the number of file diffs in the output" |
| |
| i_re = re.compile('Index:') |
| diff_count = 0 |
| i = 0 |
| while i < len(diff_output) - 4: |
| if i_re.match(diff_output[i]): |
| i += 4 |
| diff_count += 1 |
| else: |
| i += 1 |
| |
| return diff_count |
| |
| def verify_expected_output(diff_output, expected): |
| "verify given line exists in diff output" |
| for line in diff_output: |
| if line.find(expected) != -1: |
| break |
| else: |
| raise svntest.Failure |
| |
| def verify_excluded_output(diff_output, excluded): |
| "verify given line does not exist in diff output as diff line" |
| for line in diff_output: |
| if re.match("^(\\+|-)%s" % re.escape(excluded), line): |
| print 'Sought: %s' % excluded |
| print 'Found: %s' % line |
| raise svntest.Failure |
| |
| def extract_diff_path(line): |
| l2 = line[(line.find("(")+1):] |
| l3 = l2[0:(l2.find(")"))] |
| return l3 |
| |
| ###################################################################### |
| # diff on a repository subset and check the output |
| |
| def diff_check_repo_subset(wc_dir, repo_subset, check_fn, do_diff_r): |
| "diff and check for part of the repository" |
| |
| was_cwd = os.getcwd() |
| os.chdir(wc_dir) |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| repo_subset) |
| if check_fn(diff_output): |
| return 1 |
| |
| if do_diff_r: |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', 'HEAD', |
| repo_subset) |
| if check_fn(diff_output): |
| return 1 |
| |
| os.chdir(was_cwd) |
| |
| return 0 |
| |
| ###################################################################### |
| # Changes makers and change checkers |
| |
| def update_a_file(): |
| "update a file" |
| svntest.main.file_write(os.path.join('A', 'B', 'E', 'alpha'), "new atext") |
| # svntest.main.file_append(, "new atext") |
| return 0 |
| |
| def check_update_a_file(diff_output): |
| "check diff for update a file" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'B', 'E', 'alpha'), |
| 'M') |
| |
| def diff_check_update_a_file_repo_subset(wc_dir): |
| "diff and check update a file for a repository subset" |
| |
| repo_subset = os.path.join('A', 'B') |
| if diff_check_repo_subset(wc_dir, repo_subset, check_update_a_file, 1): |
| return 1 |
| |
| repo_subset = os.path.join('A', 'B', 'E', 'alpha') |
| if diff_check_repo_subset(wc_dir, repo_subset, check_update_a_file, 1): |
| return 1 |
| |
| return 0 |
| |
| |
| #---------------------------------------------------------------------- |
| |
| def add_a_file(): |
| "add a file" |
| svntest.main.file_append(os.path.join('A', 'B', 'E', 'theta'), "theta") |
| svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'E', 'theta')) |
| return 0 |
| |
| def check_add_a_file(diff_output): |
| "check diff for add a file" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'B', 'E', 'theta'), |
| 'A') |
| |
| def check_add_a_file_reverse(diff_output): |
| "check diff for add a file" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'B', 'E', 'theta'), |
| 'D') |
| |
| def diff_check_add_a_file_repo_subset(wc_dir): |
| "diff and check add a file for a repository subset" |
| |
| repo_subset = os.path.join('A', 'B') |
| if diff_check_repo_subset(wc_dir, repo_subset, check_add_a_file, 1): |
| return 1 |
| |
| repo_subset = os.path.join('A', 'B', 'E', 'theta') |
| ### TODO: diff -r HEAD doesn't work for added file |
| if diff_check_repo_subset(wc_dir, repo_subset, check_add_a_file, 0): |
| return 1 |
| |
| def update_added_file(): |
| svntest.main.file_append(os.path.join('A', 'B', 'E', 'theta'), "net ttext") |
| "update added file" |
| return 0 |
| |
| def check_update_added_file(diff_output): |
| "check diff for update of added file" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'B', 'E', 'theta'), |
| 'M') |
| |
| #---------------------------------------------------------------------- |
| |
| def add_a_file_in_a_subdir(): |
| "add a file in a subdir" |
| os.mkdir(os.path.join('A', 'B', 'T')) |
| svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'T')) |
| svntest.main.file_append(os.path.join('A', 'B', 'T', 'phi'), "phi") |
| svntest.main.run_svn(None, 'add', os.path.join('A', 'B', 'T', 'phi')) |
| return 0 |
| |
| def check_add_a_file_in_a_subdir(diff_output): |
| "check diff for add a file in a subdir" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'B', 'T', 'phi'), |
| 'A') |
| |
| def check_add_a_file_in_a_subdir_reverse(diff_output): |
| "check diff for add a file in a subdir" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'B', 'T', 'phi'), |
| 'D') |
| |
| def diff_check_add_a_file_in_a_subdir_repo_subset(wc_dir): |
| "diff and check add a file in a subdir for a repository subset" |
| |
| repo_subset = os.path.join('A', 'B', 'T') |
| ### TODO: diff -r HEAD doesn't work for added subdir |
| if diff_check_repo_subset(wc_dir, repo_subset, |
| check_add_a_file_in_a_subdir, 0): |
| return 1 |
| |
| repo_subset = os.path.join('A', 'B', 'T', 'phi') |
| ### TODO: diff -r HEAD doesn't work for added file in subdir |
| if diff_check_repo_subset(wc_dir, repo_subset, |
| check_add_a_file_in_a_subdir, 0): |
| return 1 |
| |
| #---------------------------------------------------------------------- |
| |
| def replace_a_file(): |
| "replace a file" |
| svntest.main.run_svn(None, 'rm', os.path.join('A', 'D', 'G', 'rho')) |
| svntest.main.file_append(os.path.join('A', 'D', 'G', 'rho'), "new rho") |
| svntest.main.run_svn(None, 'add', os.path.join('A', 'D', 'G', 'rho')) |
| return 0 |
| |
| def check_replace_a_file(diff_output): |
| "check diff for replace a file" |
| return check_diff_output(diff_output, |
| os.path.join('A', 'D', 'G', 'rho'), |
| 'M') |
| |
| #---------------------------------------------------------------------- |
| |
| def update_three_files(): |
| "update three files" |
| svntest.main.file_write(os.path.join('A', 'D', 'gamma'), "new gamma") |
| svntest.main.file_write(os.path.join('A', 'D', 'G', 'tau'), "new tau") |
| svntest.main.file_write(os.path.join('A', 'D', 'H', 'psi'), "new psi") |
| return 0 |
| |
| def check_update_three_files(diff_output): |
| "check update three files" |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'gamma'), |
| 'M'): |
| return 1 |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'G', 'tau'), |
| 'M'): |
| return 1 |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'H', 'psi'), |
| 'M'): |
| return 1 |
| return 0 |
| |
| |
| ###################################################################### |
| # make a change, check the diff, commit the change, check the diff |
| |
| def change_diff_commit_diff(wc_dir, revision, change_fn, check_fn): |
| "make a change, diff, commit, update and diff again" |
| |
| was_cwd = os.getcwd() |
| os.chdir(wc_dir) |
| |
| svntest.main.run_svn(None, |
| 'up', '-r', 'HEAD') |
| |
| change_fn() |
| |
| # diff without revision doesn't use an editor |
| diff_output, err_output = svntest.main.run_svn(None, 'diff') |
| if check_fn(diff_output): |
| raise svntest.Failure |
| |
| # diff with revision runs an editor |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', 'HEAD') |
| if check_fn(diff_output): |
| raise svntest.Failure |
| |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| svntest.main.run_svn(None, |
| 'up') |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', revision) |
| if check_fn(diff_output): |
| raise svntest.Failure |
| |
| os.chdir(was_cwd) |
| |
| ###################################################################### |
| # check the diff |
| |
| def just_diff(wc_dir, rev_check, check_fn): |
| "update and check that the given diff is seen" |
| |
| was_cwd = os.getcwd() |
| os.chdir(wc_dir) |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', rev_check) |
| if check_fn(diff_output): |
| raise svntest.Failure |
| os.chdir(was_cwd) |
| |
| ###################################################################### |
| # update, check the diff |
| |
| def update_diff(wc_dir, rev_up, rev_check, check_fn): |
| "update and check that the given diff is seen" |
| |
| was_cwd = os.getcwd() |
| os.chdir(wc_dir) |
| |
| svntest.main.run_svn(None, |
| 'up', '-r', rev_up) |
| |
| os.chdir(was_cwd) |
| |
| just_diff(wc_dir, rev_check, check_fn) |
| |
| ###################################################################### |
| # check a pure repository rev1:rev2 diff |
| |
| def repo_diff(wc_dir, rev1, rev2, check_fn): |
| "check that the given pure repository diff is seen" |
| |
| was_cwd = os.getcwd() |
| os.chdir(wc_dir) |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', |
| `rev2` + ':' + `rev1`) |
| if check_fn(diff_output): |
| raise svntest.Failure |
| |
| os.chdir(was_cwd) |
| |
| ###################################################################### |
| # Tests |
| # |
| |
| # test 1 |
| def diff_update_a_file(sbox): |
| "update a file" |
| |
| sbox.build() |
| |
| change_diff_commit_diff(sbox.wc_dir, 1, |
| update_a_file, |
| check_update_a_file) |
| |
| # test 2 |
| def diff_add_a_file(sbox): |
| "add a file" |
| |
| sbox.build() |
| |
| change_diff_commit_diff(sbox.wc_dir, 1, |
| add_a_file, |
| check_add_a_file) |
| |
| #test 3 |
| def diff_add_a_file_in_a_subdir(sbox): |
| "add a file in an added directory" |
| |
| sbox.build() |
| |
| change_diff_commit_diff(sbox.wc_dir, 1, |
| add_a_file_in_a_subdir, |
| check_add_a_file_in_a_subdir) |
| |
| # test 4 |
| def diff_replace_a_file(sbox): |
| "replace a file with a file" |
| |
| sbox.build() |
| |
| change_diff_commit_diff(sbox.wc_dir, 1, |
| replace_a_file, |
| check_replace_a_file) |
| |
| # test 5 |
| def diff_multiple_reverse(sbox): |
| "multiple revisions diff'd forwards and backwards" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| # rev 2 |
| change_diff_commit_diff(wc_dir, 1, |
| add_a_file, |
| check_add_a_file) |
| |
| #rev 3 |
| change_diff_commit_diff(wc_dir, 2, |
| add_a_file_in_a_subdir, |
| check_add_a_file_in_a_subdir) |
| |
| #rev 4 |
| change_diff_commit_diff(wc_dir, 3, |
| update_a_file, |
| check_update_a_file) |
| |
| # check diffs both ways |
| update_diff(wc_dir, 4, 1, check_update_a_file) |
| just_diff(wc_dir, 1, check_add_a_file_in_a_subdir) |
| just_diff(wc_dir, 1, check_add_a_file) |
| update_diff(wc_dir, 1, 4, check_update_a_file) |
| just_diff(wc_dir, 4, check_add_a_file_in_a_subdir_reverse) |
| just_diff(wc_dir, 4, check_add_a_file_reverse) |
| |
| # check pure repository diffs |
| repo_diff(wc_dir, 4, 1, check_update_a_file) |
| repo_diff(wc_dir, 4, 1, check_add_a_file_in_a_subdir) |
| repo_diff(wc_dir, 4, 1, check_add_a_file) |
| repo_diff(wc_dir, 1, 4, check_update_a_file) |
| # ### TODO: directory delete doesn't work yet |
| # repo_diff(wc_dir, 1, 4, check_add_a_file_in_a_subdir_reverse) |
| repo_diff(wc_dir, 1, 4, check_add_a_file_reverse) |
| |
| # test 6 |
| def diff_non_recursive(sbox): |
| "non-recursive behaviour" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| change_diff_commit_diff(wc_dir, 1, |
| update_three_files, |
| check_update_three_files) |
| |
| # The changes are in: ./A/D/gamma |
| # ./A/D/G/tau |
| # ./A/D/H/psi |
| # When checking D recursively there are three changes. When checking |
| # D non-recursively there is only one change. When checking G |
| # recursively, there is only one change even though D is the anchor |
| |
| # full diff has three changes |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1', |
| os.path.join(wc_dir, 'A', 'D')) |
| if count_diff_output(diff_output) != 3: |
| raise svntest.Failure |
| |
| # non-recursive has one change |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1', '-N', |
| os.path.join(wc_dir, 'A', 'D')) |
| if count_diff_output(diff_output) != 1: |
| raise svntest.Failure |
| |
| # diffing a directory doesn't pick up other diffs in the anchor |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1', |
| os.path.join(wc_dir, |
| 'A', 'D', 'G')) |
| if count_diff_output(diff_output) != 1: |
| raise svntest.Failure |
| |
| |
| # test 7 |
| def diff_repo_subset(sbox): |
| "diff only part of the repository" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| was_cwd = os.getcwd() |
| os.chdir(wc_dir) |
| |
| update_a_file() |
| add_a_file() |
| add_a_file_in_a_subdir() |
| |
| os.chdir(was_cwd) |
| |
| if diff_check_update_a_file_repo_subset(wc_dir): |
| raise svntest.Failure |
| |
| if diff_check_add_a_file_repo_subset(wc_dir): |
| raise svntest.Failure |
| |
| if diff_check_add_a_file_in_a_subdir_repo_subset(wc_dir): |
| raise svntest.Failure |
| |
| |
| # test 8 |
| def diff_non_version_controlled_file(sbox): |
| "non version controlled files" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| svntest.main.file_append(os.path.join(wc_dir, 'A', 'D', 'foo'), "a new file") |
| |
| diff_output, err_output = svntest.main.run_svn(1, 'diff', |
| os.path.join(wc_dir, |
| 'A', 'D', 'foo')) |
| |
| if count_diff_output(diff_output) != 0: raise svntest.Failure |
| |
| # At one point this would crash, so we would only get a 'Segmentation Fault' |
| # error message. The appropriate response is a few lines of errors. I wish |
| # there was a way to figure out if svn crashed, but all run_svn gives us is |
| # the output, so here we are... |
| for line in err_output: |
| if re.search("foo' is not under version control$", line): |
| break |
| else: |
| raise svntest.Failure |
| |
| # test 9 |
| def diff_pure_repository_update_a_file(sbox): |
| "pure repository diff update a file" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| os.chdir(wc_dir) |
| |
| # rev 2 |
| update_a_file() |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| |
| # rev 3 |
| add_a_file_in_a_subdir() |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| |
| # rev 4 |
| add_a_file() |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| |
| # rev 5 |
| update_added_file() |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| |
| svntest.main.run_svn(None, |
| 'up', '-r', '2') |
| |
| url = sbox.repo_url |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-c', '2', |
| url) |
| if check_update_a_file(diff_output): raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '1:2') |
| if check_update_a_file(diff_output): raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-c', '3', |
| url) |
| if check_add_a_file_in_a_subdir(diff_output): raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '2:3') |
| if check_add_a_file_in_a_subdir(diff_output): raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-c', '5', |
| url) |
| if check_update_added_file(diff_output): raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', '4:5') |
| if check_update_added_file(diff_output): raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', '-r', 'head') |
| if check_add_a_file_in_a_subdir_reverse(diff_output): raise svntest.Failure |
| |
| |
| # test 10 |
| def diff_only_property_change(sbox): |
| "diff when property was changed but text was not" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| expected_output = [ |
| "\n", |
| "Property changes on: iota\n", |
| "___________________________________________________________________\n", |
| "Name: svn:eol-style\n", |
| " + native\n", |
| "\n" ] |
| |
| expected_reverse_output = list(expected_output) |
| expected_reverse_output[4] = " - native\n" |
| |
| |
| os.chdir(sbox.wc_dir) |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'svn:eol-style', 'native', 'iota') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'empty-msg') |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-r', '1:2') |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-c', '2') |
| |
| svntest.actions.run_and_verify_svn(None, expected_reverse_output, [], |
| 'diff', '-r', '2:1') |
| |
| svntest.actions.run_and_verify_svn(None, expected_reverse_output, [], |
| 'diff', '-c', '-2') |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-r', '1') |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-r', 'PREV', 'iota') |
| |
| |
| |
| #---------------------------------------------------------------------- |
| # Regression test for issue #1019: make sure we don't try to display |
| # diffs when the file is marked as a binary type. This tests all 3 |
| # uses of 'svn diff': wc-wc, wc-repos, repos-repos. |
| |
| def dont_diff_binary_file(sbox): |
| "don't diff file marked as binary type" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| # Add a binary file to the project. |
| theta_contents = svntest.main.file_read( |
| os.path.join(sys.path[0], "theta.bin"), 'rb') |
| # Write PNG file data into 'A/theta'. |
| theta_path = os.path.join(wc_dir, 'A', 'theta') |
| svntest.main.file_write(theta_path, theta_contents, 'wb') |
| |
| svntest.main.run_svn(None, 'add', theta_path) |
| |
| # Created expected output tree for 'svn ci' |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/theta' : Item(verb='Adding (bin)'), |
| }) |
| |
| # Create expected status tree |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.add({ |
| 'A/theta' : Item(status=' ', wc_rev=2), |
| }) |
| |
| # Commit the new binary file, creating revision 2. |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| # Update the whole working copy to HEAD (rev 2) |
| expected_output = svntest.wc.State(wc_dir, {}) |
| |
| expected_disk = svntest.main.greek_state.copy() |
| expected_disk.add({ |
| 'A/theta' : Item(theta_contents, |
| props={'svn:mime-type' : 'application/octet-stream'}), |
| }) |
| |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
| expected_status.add({ |
| 'A/theta' : Item(status=' ', wc_rev=2), |
| }) |
| |
| svntest.actions.run_and_verify_update(wc_dir, |
| expected_output, |
| expected_disk, |
| expected_status, |
| None, None, None, None, None, |
| 1) # verify props, too. |
| |
| # Make a local mod to the binary file. |
| svntest.main.file_append(theta_path, "some extra junk") |
| |
| # First diff use-case: plain old 'svn diff wc' will display any |
| # local changes in the working copy. (diffing working |
| # vs. text-base) |
| |
| re_nodisplay = re.compile('^Cannot display:') |
| |
| stdout, stderr = svntest.main.run_svn(None, 'diff', wc_dir) |
| |
| for line in stdout: |
| if (re_nodisplay.match(line)): |
| break |
| else: |
| raise svntest.Failure |
| |
| # Second diff use-case: 'svn diff -r1 wc' compares the wc against a |
| # the first revision in the repository. |
| |
| stdout, stderr = svntest.main.run_svn(None, |
| 'diff', '-r', '1', wc_dir) |
| |
| for line in stdout: |
| if (re_nodisplay.match(line)): |
| break |
| else: |
| raise svntest.Failure |
| |
| # Now commit the local mod, creating rev 3. |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/theta' : Item(verb='Sending'), |
| }) |
| |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
| expected_status.add({ |
| 'A/theta' : Item(status=' ', wc_rev=3), |
| }) |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| # Third diff use-case: 'svn diff -r2:3 wc' will compare two |
| # repository trees. |
| |
| stdout, stderr = svntest.main.run_svn(None, |
| 'diff', '-r', '2:3', wc_dir) |
| |
| for line in stdout: |
| if (re_nodisplay.match(line)): |
| break |
| else: |
| raise svntest.Failure |
| |
| |
| def diff_nonextant_urls(sbox): |
| "svn diff errors against a non-existent URL" |
| |
| sbox.build(create_wc = False) |
| non_extant_url = sbox.repo_url + '/A/does_not_exist' |
| extant_url = sbox.repo_url + '/A/mu' |
| |
| diff_output, err_output = svntest.main.run_svn(1, |
| 'diff', |
| '--old', non_extant_url, |
| '--new', extant_url) |
| for line in err_output: |
| if re.search('was not found in the repository at revision', line): |
| break |
| else: |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(1, |
| 'diff', |
| '--old', extant_url, |
| '--new', non_extant_url) |
| for line in err_output: |
| if re.search('was not found in the repository at revision', line): |
| break |
| else: |
| raise svntest.Failure |
| |
| def diff_head_of_moved_file(sbox): |
| "diff against the head of a moved file" |
| |
| sbox.build() |
| mu_path = os.path.join(sbox.wc_dir, 'A', 'mu') |
| new_mu_path = mu_path + '.new' |
| |
| svntest.main.run_svn(None, 'mv', mu_path, new_mu_path) |
| |
| # Modify the file to ensure that the diff is non-empty. |
| svntest.main.file_append(new_mu_path, "\nActually, it's a new mu.") |
| |
| svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [], |
| 'diff', '-r', 'HEAD', new_mu_path) |
| |
| |
| |
| #---------------------------------------------------------------------- |
| # Regression test for issue #977: make 'svn diff -r BASE:N' compare a |
| # repository tree against the wc's text-bases, rather than the wc's |
| # working files. This is a long test, which checks many variations. |
| |
| def diff_base_to_repos(sbox): |
| "diff text-bases against repository" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| iota_path = os.path.join(sbox.wc_dir, 'iota') |
| newfile_path = os.path.join(sbox.wc_dir, 'A', 'D', 'newfile') |
| mu_path = os.path.join(sbox.wc_dir, 'A', 'mu') |
| |
| # Make changes to iota, commit r2, update to HEAD (r2). |
| svntest.main.file_append(iota_path, "some rev2 iota text.\n") |
| |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| }) |
| |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.tweak('iota', wc_rev=2) |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| expected_output = svntest.wc.State(wc_dir, {}) |
| expected_disk = svntest.main.greek_state.copy() |
| expected_disk.tweak('iota', |
| contents=\ |
| "This is the file 'iota'.\nsome rev2 iota text.\n") |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
| svntest.actions.run_and_verify_update(wc_dir, expected_output, |
| expected_disk, expected_status) |
| |
| # Now make another local mod to iota. |
| svntest.main.file_append(iota_path, "an iota local mod.\n") |
| |
| # If we run 'svn diff -r 1', we should see diffs that include *both* |
| # the rev2 changes and local mods. That's because the working files |
| # are being compared to the repository. |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r', '1', wc_dir) |
| |
| # Makes diff output look the same on all platforms. |
| def strip_eols(lines): |
| return [x.replace("\r", "").replace("\n", "") for x in lines] |
| |
| expected_output_lines = [ |
| "Index: svn-test-work/working_copies/diff_tests-14/iota\n", |
| "===================================================================\n", |
| "--- svn-test-work/working_copies/diff_tests-14/iota\t(revision 1)\n", |
| "+++ svn-test-work/working_copies/diff_tests-14/iota\t(working copy)\n", |
| "@@ -1 +1,3 @@\n", |
| " This is the file 'iota'.\n", |
| "+some rev2 iota text.\n", |
| "+an iota local mod.\n"] |
| |
| if strip_eols(diff_output) != strip_eols(expected_output_lines): |
| raise svntest.Failure |
| |
| # If we run 'svn diff -r BASE:1', we should see diffs that only show |
| # the rev2 changes and NOT the local mods. That's because the |
| # text-bases are being compared to the repository. |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', 'BASE:1', |
| wc_dir) |
| expected_output_lines = [ |
| "Index: svn-test-work/working_copies/diff_tests-14/iota\n", |
| "===================================================================\n", |
| "--- svn-test-work/working_copies/diff_tests-14/iota\t(working copy)\n", |
| "+++ svn-test-work/working_copies/diff_tests-14/iota\t(revision 1)\n", |
| "@@ -1,2 +1 @@\n", |
| " This is the file 'iota'.\n", |
| "-some rev2 iota text.\n"] |
| |
| if strip_eols(diff_output) != strip_eols(expected_output_lines): |
| raise svntest.Failure |
| |
| # But that's not all folks... no, no, we're just getting started |
| # here! There are so many other tests to do. |
| |
| # For example, we just ran 'svn diff -rBASE:1'. The output should |
| # look exactly the same as 'svn diff -r2:1'. (If you remove the |
| # header commentary) |
| diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', '2:1', |
| wc_dir) |
| |
| diff_output[2:4] = [] |
| diff_output2[2:4] = [] |
| |
| if (diff_output2 != diff_output): |
| raise svntest.Failure |
| |
| # and similarly, does 'svn diff -r1:2' == 'svn diff -r1:BASE' ? |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r', '1:2', wc_dir) |
| |
| diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r', '1:BASE', |
| wc_dir) |
| |
| diff_output[2:4] = [] |
| diff_output2[2:4] = [] |
| |
| if (diff_output2 != diff_output): |
| raise svntest.Failure |
| |
| # Now we schedule an addition and a deletion. |
| svntest.main.file_append(newfile_path, "Contents of newfile\n") |
| svntest.main.run_svn(None, 'add', newfile_path) |
| svntest.main.run_svn(None, 'rm', mu_path) |
| |
| expected_output = svntest.actions.get_virginal_state(wc_dir, 2) |
| expected_output.add({ |
| 'A/D/newfile' : Item(status='A ', wc_rev=0), |
| }) |
| expected_output.tweak('A/mu', status='D ') |
| expected_output.tweak('iota', status='M ') |
| svntest.actions.run_and_verify_status(wc_dir, expected_output) |
| |
| # once again, verify that -r1:2 and -r1:BASE look the same, as do |
| # -r2:1 and -rBASE:1. None of these diffs should mention the |
| # scheduled addition or deletion. |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| '1:2', wc_dir) |
| |
| diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| '1:BASE', wc_dir) |
| |
| diff_output3, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| '2:1', wc_dir) |
| |
| diff_output4, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| 'BASE:1', wc_dir) |
| |
| diff_output[2:4] = [] |
| diff_output2[2:4] = [] |
| diff_output3[2:4] = [] |
| diff_output4[2:4] = [] |
| |
| if (diff_output != diff_output2): |
| raise svntest.Failure |
| |
| if (diff_output3 != diff_output4): |
| raise svntest.Failure |
| |
| # Great! So far, so good. Now we commit our three changes (a local |
| # mod, an addition, a deletion) and update to HEAD (r3). |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| 'A/mu' : Item(verb='Deleting'), |
| 'A/D/newfile' : Item(verb='Adding') |
| }) |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
| expected_status.tweak('iota', wc_rev=3) |
| expected_status.remove('A/mu') |
| expected_status.add({ |
| 'A/D/newfile' : Item(status=' ', wc_rev=3), |
| }) |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| expected_output = svntest.wc.State(wc_dir, {}) |
| expected_disk = svntest.main.greek_state.copy() |
| expected_disk.tweak('iota', |
| contents="This is the file 'iota'.\n" + \ |
| "some rev2 iota text.\nan iota local mod.\n") |
| expected_disk.add({'A/D/newfile' : Item("Contents of newfile\n")}) |
| expected_disk.remove('A/mu') |
| |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 3) |
| expected_status.remove('A/mu') |
| expected_status.add({ |
| 'A/D/newfile' : Item(status=' ', wc_rev=3), |
| }) |
| svntest.actions.run_and_verify_update(wc_dir, expected_output, |
| expected_disk, expected_status) |
| |
| # Now 'svn diff -r3:2' should == 'svn diff -rBASE:2', showing the |
| # removal of changes to iota, the adding of mu, and deletion of newfile. |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| '3:2', wc_dir) |
| |
| diff_output2, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| 'BASE:2', wc_dir) |
| |
| # to do the comparison, remove all output lines starting with +++ or --- |
| re_infoline = re.compile('^(\+\+\+|---).*$') |
| list1 = [] |
| list2 = [] |
| |
| for line in diff_output: |
| if not re_infoline.match(line): |
| list1.append(line) |
| |
| for line in diff_output2: |
| if not re_infoline.match(line): |
| list2.append(line) |
| |
| if list1 != list2: |
| raise svntest.Failure |
| |
| |
| #---------------------------------------------------------------------- |
| # This is a simple regression test for issue #891, whereby ra_neon's |
| # REPORT request would fail, because the object no longer exists in HEAD. |
| |
| def diff_deleted_in_head(sbox): |
| "repos-repos diff on item deleted from HEAD" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| A_path = os.path.join(sbox.wc_dir, 'A') |
| mu_path = os.path.join(sbox.wc_dir, 'A', 'mu') |
| |
| # Make a change to mu, commit r2, update. |
| svntest.main.file_append(mu_path, "some rev2 mu text.\n") |
| |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/mu' : Item(verb='Sending'), |
| }) |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.tweak('A/mu', wc_rev=2) |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| expected_output = svntest.wc.State(wc_dir, {}) |
| expected_disk = svntest.main.greek_state.copy() |
| expected_disk.tweak('A/mu', |
| contents="This is the file 'mu'.\nsome rev2 mu text.\n") |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
| svntest.actions.run_and_verify_update(wc_dir, expected_output, |
| expected_disk, expected_status) |
| |
| # Now delete the whole directory 'A', and commit as r3. |
| svntest.main.run_svn(None, 'rm', A_path) |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A' : Item(verb='Deleting'), |
| }) |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 2) |
| expected_status.remove('A', 'A/B', 'A/B/E', 'A/B/E/beta', 'A/B/E/alpha', |
| 'A/B/F', 'A/B/lambda', 'A/D', 'A/D/G', 'A/D/G/rho', |
| 'A/D/G/pi', 'A/D/G/tau', 'A/D/H', 'A/D/H/psi', |
| 'A/D/H/omega', 'A/D/H/chi', 'A/D/gamma', 'A/mu', |
| 'A/C') |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| # Doing an 'svn diff -r1:2' on the URL of directory A should work, |
| # especially over the DAV layer. |
| the_url = sbox.repo_url + '/A' |
| diff_output = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r', |
| '1:2', the_url + "@2") |
| |
| |
| #---------------------------------------------------------------------- |
| def diff_targets(sbox): |
| "select diff targets" |
| |
| sbox.build() |
| os.chdir(sbox.wc_dir) |
| |
| update_a_file() |
| add_a_file() |
| |
| update_path = os.path.join('A', 'B', 'E', 'alpha') |
| add_path = os.path.join('A', 'B', 'E', 'theta') |
| parent_path = os.path.join('A', 'B', 'E') |
| update_url = sbox.repo_url + '/A/B/E/alpha' |
| parent_url = sbox.repo_url + '/A/B/E' |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| update_path, add_path) |
| if check_update_a_file(diff_output) or check_add_a_file(diff_output): |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| update_path) |
| if check_update_a_file(diff_output) or not check_add_a_file(diff_output): |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| '--old', parent_path, |
| 'alpha', 'theta') |
| if check_update_a_file(diff_output) or check_add_a_file(diff_output): |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| '--old', parent_path, |
| 'theta') |
| if not check_update_a_file(diff_output) or check_add_a_file(diff_output): |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| |
| diff_output, err_output = svntest.main.run_svn(1, |
| 'diff', '-r1:2', |
| update_path, add_path) |
| |
| regex = 'svn: Unable to find repository location for \'.*\'' |
| for line in err_output: |
| if re.match(regex, line): |
| break |
| else: |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(1, |
| 'diff', '-r1:2', |
| add_path) |
| for line in err_output: |
| if re.match(regex, line): |
| break |
| else: |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(1, |
| 'diff', '-r1:2', |
| '--old', parent_path, |
| 'alpha', 'theta') |
| regex = 'svn: \'.*\' was not found in the repository' |
| for line in err_output: |
| if re.match(regex, line): |
| break |
| else: |
| raise svntest.Failure |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r1:2', |
| '--old', parent_path, |
| 'alpha') |
| if check_update_a_file(diff_output) or not check_add_a_file(diff_output): |
| raise svntest.Failure |
| |
| |
| #---------------------------------------------------------------------- |
| def diff_branches(sbox): |
| "diff for branches" |
| |
| sbox.build() |
| |
| A_url = sbox.repo_url + '/A' |
| A2_url = sbox.repo_url + '/A2' |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'cp', '-m', 'log msg', |
| A_url, A2_url) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', sbox.wc_dir) |
| |
| A_alpha = os.path.join(sbox.wc_dir, 'A', 'B', 'E', 'alpha') |
| A2_alpha = os.path.join(sbox.wc_dir, 'A2', 'B', 'E', 'alpha') |
| |
| svntest.main.file_append(A_alpha, "\nfoo\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', sbox.wc_dir) |
| |
| svntest.main.file_append(A2_alpha, "\nbar\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', sbox.wc_dir) |
| |
| svntest.main.file_append(A_alpha, "zig\n") |
| |
| # Compare repository file on one branch against repository file on |
| # another branch |
| rel_path = os.path.join('B', 'E', 'alpha') |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '--old', A_url, |
| '--new', A2_url, |
| rel_path) |
| verify_expected_output(diff_output, "-foo") |
| verify_expected_output(diff_output, "+bar") |
| |
| # Same again but using whole branch |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '--old', A_url, |
| '--new', A2_url) |
| verify_expected_output(diff_output, "-foo") |
| verify_expected_output(diff_output, "+bar") |
| |
| # Compare two repository files on different branches |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| A_url + '/B/E/alpha', |
| A2_url + '/B/E/alpha') |
| verify_expected_output(diff_output, "-foo") |
| verify_expected_output(diff_output, "+bar") |
| |
| # Compare two versions of a file on a single branch |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| A_url + '/B/E/alpha@2', |
| A_url + '/B/E/alpha@3') |
| verify_expected_output(diff_output, "+foo") |
| |
| # Compare identical files on different branches |
| diff_output, err = svntest.actions.run_and_verify_svn( |
| None, [], [], |
| 'diff', A_url + '/B/E/alpha@2', A2_url + '/B/E/alpha@3') |
| |
| |
| #---------------------------------------------------------------------- |
| def diff_repos_and_wc(sbox): |
| "diff between repos URLs and WC paths" |
| |
| sbox.build() |
| |
| A_url = sbox.repo_url + '/A' |
| A2_url = sbox.repo_url + '/A2' |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'cp', '-m', 'log msg', |
| A_url, A2_url) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', sbox.wc_dir) |
| |
| A_alpha = os.path.join(sbox.wc_dir, 'A', 'B', 'E', 'alpha') |
| A2_alpha = os.path.join(sbox.wc_dir, 'A2', 'B', 'E', 'alpha') |
| |
| svntest.main.file_append(A_alpha, "\nfoo\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', sbox.wc_dir) |
| |
| svntest.main.file_append(A2_alpha, "\nbar\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', sbox.wc_dir) |
| |
| svntest.main.file_append(A_alpha, "zig\n") |
| |
| # Compare working file on one branch against repository file on |
| # another branch |
| A_path = os.path.join(sbox.wc_dir, 'A') |
| rel_path = os.path.join('B', 'E', 'alpha') |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '--old', A2_url, |
| '--new', A_path, |
| rel_path) |
| verify_expected_output(diff_output, "-bar") |
| verify_expected_output(diff_output, "+foo") |
| verify_expected_output(diff_output, "+zig") |
| |
| # Same again but using whole branch |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '--old', A2_url, |
| '--new', A_path) |
| verify_expected_output(diff_output, "-bar") |
| verify_expected_output(diff_output, "+foo") |
| verify_expected_output(diff_output, "+zig") |
| |
| #---------------------------------------------------------------------- |
| def diff_file_urls(sbox): |
| "diff between two file URLs (issue #1311)" |
| |
| sbox.build() |
| |
| iota_path = os.path.join(sbox.wc_dir, 'iota') |
| iota_url = sbox.repo_url + '/iota' |
| iota_copy_path = os.path.join(sbox.wc_dir, 'A', 'iota') |
| iota_copy_url = sbox.repo_url + '/A/iota' |
| iota_copy2_url = sbox.repo_url + '/A/iota2' |
| |
| # Put some different text into iota, and commit. |
| os.remove(iota_path) |
| svntest.main.file_append(iota_path, "foo\nbar\nsnafu\n") |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', iota_path) |
| |
| # Now, copy the file elsewhere, twice. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'cp', '-m', 'log msg', |
| iota_url, iota_copy_url) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'cp', '-m', 'log msg', |
| iota_url, iota_copy2_url) |
| |
| # Update (to get the copies) |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', sbox.wc_dir) |
| |
| # Now, make edits to one of the copies of iota, and commit. |
| os.remove(iota_copy_path) |
| svntest.main.file_append(iota_copy_path, "foo\nsnafu\nabcdefg\nopqrstuv\n") |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', iota_copy_path) |
| |
| # Finally, do a diff between the first and second copies of iota, |
| # and verify that we got the expected lines. And then do it in reverse! |
| out, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| iota_copy_url, iota_copy2_url) |
| |
| verify_expected_output(out, "+bar") |
| verify_expected_output(out, "-abcdefg") |
| verify_expected_output(out, "-opqrstuv") |
| |
| out, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| iota_copy2_url, iota_copy_url) |
| |
| verify_expected_output(out, "-bar") |
| verify_expected_output(out, "+abcdefg") |
| verify_expected_output(out, "+opqrstuv") |
| |
| #---------------------------------------------------------------------- |
| def diff_prop_change_local_edit(sbox): |
| "diff a property change plus a local edit" |
| |
| sbox.build() |
| |
| iota_path = os.path.join(sbox.wc_dir, 'iota') |
| iota_url = sbox.repo_url + '/iota' |
| |
| # Change a property on iota, and commit. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'pname', 'pvalue', iota_path) |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', iota_path) |
| |
| # Make local edits to iota. |
| svntest.main.file_append(iota_path, "\nMore text.\n") |
| |
| # diff r1:COMMITTED should show the property change but not the local edit. |
| out, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r1:COMMITTED', iota_path) |
| for line in out: |
| if line.find("+More text.") != -1: |
| raise svntest.Failure |
| verify_expected_output(out, " + pvalue") |
| |
| # diff r1:BASE should show the property change but not the local edit. |
| out, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r1:BASE', iota_path) |
| for line in out: |
| if line.find("+More text.") != -1: |
| raise svntest.Failure # fails at r7481 |
| verify_expected_output(out, " + pvalue") # fails at r7481 |
| |
| # diff r1:WC should show the local edit as well as the property change. |
| out, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', '-r1', iota_path) |
| verify_expected_output(out, "+More text.") # fails at r7481 |
| verify_expected_output(out, " + pvalue") |
| |
| #---------------------------------------------------------------------- |
| def check_for_omitted_prefix_in_path_component(sbox): |
| "check for omitted prefix in path component" |
| |
| sbox.build() |
| svntest.actions.do_sleep_for_timestamps() |
| |
| prefix_path = os.path.join(sbox.wc_dir, 'prefix_mydir') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'mkdir', prefix_path) |
| other_prefix_path = os.path.join(sbox.wc_dir, 'prefix_other') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'mkdir', other_prefix_path) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', sbox.wc_dir) |
| |
| |
| file_path = os.path.join(prefix_path, "test.txt") |
| svntest.main.file_write(file_path, "Hello\nThere\nIota\n") |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'add', file_path) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', sbox.wc_dir) |
| |
| |
| prefix_url = sbox.repo_url + "/prefix_mydir" |
| other_prefix_url = sbox.repo_url + "/prefix_other/mytag" |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'cp', '-m', 'log msg', prefix_url, |
| other_prefix_url) |
| |
| svntest.main.file_write(file_path, "Hello\nWorld\nIota\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg', prefix_path) |
| |
| out, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', prefix_url, |
| other_prefix_url) |
| |
| src = extract_diff_path(out[2]) |
| dest = extract_diff_path(out[3]) |
| |
| good_src = ".../prefix_mydir" |
| good_dest = ".../prefix_other/mytag" |
| |
| if ((src != good_src) or (dest != good_dest)): |
| print("src is '%s' instead of '%s' and dest is '%s' instead of '%s'" % |
| (src, good_src, dest, good_dest)) |
| raise svntest.Failure |
| |
| #---------------------------------------------------------------------- |
| def diff_renamed_file(sbox): |
| "diff a file that has been renamed" |
| |
| sbox.build() |
| |
| os.chdir(sbox.wc_dir) |
| |
| pi_path = os.path.join('A', 'D', 'G', 'pi') |
| pi2_path = os.path.join('A', 'D', 'pi2') |
| svntest.main.file_write(pi_path, "new pi") |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg') |
| |
| svntest.main.file_append(pi_path, "even more pi") |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg') |
| |
| svntest.main.run_svn(None, 'mv', pi_path, pi2_path) |
| |
| # Repos->WC diff of the file |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1', |
| pi2_path) |
| |
| if check_diff_output(diff_output, |
| pi2_path, |
| 'M') : |
| raise svntest.Failure |
| |
| svntest.main.file_append(pi2_path, "new pi") |
| |
| # Repos->WC of the directory |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1', |
| os.path.join('A', 'D')) |
| |
| if check_diff_output(diff_output, |
| pi_path, |
| 'D') : |
| raise svntest.Failure |
| |
| if check_diff_output(diff_output, |
| pi2_path, |
| 'M') : |
| raise svntest.Failure |
| |
| # WC->WC of the file |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| pi2_path) |
| if check_diff_output(diff_output, |
| pi2_path, |
| 'M') : |
| raise svntest.Failure |
| |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg') |
| |
| # Repos->WC diff of file after the rename. |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1', |
| pi2_path) |
| if check_diff_output(diff_output, |
| pi2_path, |
| 'M') : |
| raise svntest.Failure |
| |
| # Repos->repos diff after the rename. |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '2:3', |
| pi2_path) |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'pi'), |
| 'M') : |
| raise svntest.Failure |
| |
| #---------------------------------------------------------------------- |
| def diff_within_renamed_dir(sbox): |
| "diff a file within a renamed directory" |
| |
| sbox.build() |
| |
| os.chdir(sbox.wc_dir) |
| |
| svntest.main.run_svn(None, 'mv', os.path.join('A', 'D', 'G'), |
| os.path.join('A', 'D', 'I')) |
| # svntest.main.run_svn(None, 'ci', '-m', 'log_msg') |
| svntest.main.file_write(os.path.join('A', 'D', 'I', 'pi'), "new pi") |
| |
| # Check a repos->wc diff |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', |
| os.path.join('A', 'D', 'I', 'pi')) |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'I', 'pi'), |
| 'M') : |
| raise svntest.Failure |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg') |
| |
| # Check repos->wc after commit |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1', |
| os.path.join('A', 'D', 'I', 'pi')) |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'I', 'pi'), |
| 'M') : |
| raise svntest.Failure |
| |
| # Test the diff while within the moved directory |
| os.chdir(os.path.join('A','D','I')) |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1') |
| |
| if check_diff_output(diff_output, 'pi', 'M') : |
| raise svntest.Failure |
| |
| # Test a repos->repos diff while within the moved directory |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1:2') |
| |
| if check_diff_output(diff_output, 'pi', 'M') : |
| raise svntest.Failure |
| |
| #---------------------------------------------------------------------- |
| def diff_prop_on_named_dir(sbox): |
| "diff a prop change on a dir named explicitly" |
| |
| # Diff of a property change or addition should contain a "+" line. |
| # Diff of a property change or deletion should contain a "-" line. |
| # On a diff between repository revisions (not WC) of a dir named |
| # explicitly, the "-" line was missing. (For a file, and for a dir |
| # recursed into, the result was correct.) |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| os.chdir(sbox.wc_dir) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'p', 'v', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', '') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propdel', 'p', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', '') |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r2:3', 'A') |
| # Check that the result contains a "-" line. |
| verify_expected_output(diff_output, " - v") |
| |
| #---------------------------------------------------------------------- |
| def diff_keywords(sbox): |
| "ensure that diff won't show keywords" |
| |
| sbox.build() |
| |
| iota_path = os.path.join(sbox.wc_dir, 'iota') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ps', |
| 'svn:keywords', |
| 'Id Rev Date', |
| iota_path) |
| |
| fp = open(iota_path, 'w') |
| fp.write("$Date$\n") |
| fp.write("$Id$\n") |
| fp.write("$Rev$\n") |
| fp.write("$Date::%s$\n" % (' ' * 80)) |
| fp.write("$Id::%s$\n" % (' ' * 80)) |
| fp.write("$Rev::%s$\n" % (' ' * 80)) |
| fp.close() |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'keywords', sbox.wc_dir) |
| |
| svntest.main.file_append(iota_path, "bar\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'added bar', sbox.wc_dir) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', sbox.wc_dir) |
| |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r', 'prev:head', |
| sbox.wc_dir) |
| verify_expected_output(diff_output, "+bar") |
| verify_excluded_output(diff_output, "$Date:") |
| verify_excluded_output(diff_output, "$Rev:") |
| verify_excluded_output(diff_output, "$Id:") |
| |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r', 'head:prev', |
| sbox.wc_dir) |
| verify_expected_output(diff_output, "-bar") |
| verify_excluded_output(diff_output, "$Date:") |
| verify_excluded_output(diff_output, "$Rev:") |
| verify_excluded_output(diff_output, "$Id:") |
| |
| # Check fixed length keywords will show up |
| # when the length of keyword has changed |
| fp = open(iota_path, 'w') |
| fp.write("$Date$\n") |
| fp.write("$Id$\n") |
| fp.write("$Rev$\n") |
| fp.write("$Date::%s$\n" % (' ' * 79)) |
| fp.write("$Id::%s$\n" % (' ' * 79)) |
| fp.write("$Rev::%s$\n" % (' ' * 79)) |
| fp.close() |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'keywords 2', sbox.wc_dir) |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', sbox.wc_dir) |
| |
| diff_output, err = svntest.actions.run_and_verify_svn(None, None, [], |
| 'diff', |
| '-r', 'prev:head', |
| sbox.wc_dir) |
| # these should show up |
| verify_expected_output(diff_output, "+$Id:: ") |
| verify_expected_output(diff_output, "-$Id:: ") |
| verify_expected_output(diff_output, "-$Rev:: ") |
| verify_expected_output(diff_output, "+$Rev:: ") |
| verify_expected_output(diff_output, "-$Date:: ") |
| verify_expected_output(diff_output, "+$Date:: ") |
| # ... and these won't |
| verify_excluded_output(diff_output, "$Date: ") |
| verify_excluded_output(diff_output, "$Rev: ") |
| verify_excluded_output(diff_output, "$Id: ") |
| |
| |
| def diff_force(sbox): |
| "show diffs for binary files with --force" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| iota_path = os.path.join(wc_dir, 'iota') |
| |
| # Append a line to iota and make it binary. |
| svntest.main.file_append(iota_path, "new line") |
| svntest.main.run_svn(None, |
| 'propset', 'svn:mime-type', |
| 'application/octet-stream', iota_path) |
| |
| # Created expected output tree for 'svn ci' |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| }) |
| |
| # Create expected status tree |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.add({ |
| 'iota' : Item(status=' ', wc_rev=2), |
| }) |
| |
| # Commit iota, creating revision 2. |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| # Add another line, while keeping he file as binary. |
| svntest.main.file_append(iota_path, "another line") |
| |
| # Commit creating rev 3. |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| }) |
| |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.add({ |
| 'iota' : Item(status=' ', wc_rev=3), |
| }) |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, wc_dir) |
| |
| # Check that we get diff when the first, the second and both files are |
| # marked as binary. |
| |
| re_nodisplay = re.compile('^Cannot display:') |
| |
| stdout, stderr = svntest.main.run_svn(None, |
| 'diff', '-r1:2', iota_path, |
| '--force') |
| |
| for line in stdout: |
| if (re_nodisplay.match(line)): |
| raise svntest.Failure |
| |
| stdout, stderr = svntest.main.run_svn(None, |
| 'diff', '-r2:1', iota_path, |
| '--force') |
| |
| for line in stdout: |
| if (re_nodisplay.match(line)): |
| raise svntest.Failure |
| |
| stdout, stderr = svntest.main.run_svn(None, |
| 'diff', '-r2:3', iota_path, |
| '--force') |
| |
| for line in stdout: |
| if (re_nodisplay.match(line)): |
| raise svntest.Failure |
| |
| #---------------------------------------------------------------------- |
| # Regression test for issue #2333: Renaming a directory should produce |
| # deletion and addition diffs for each included file. |
| def diff_renamed_dir(sbox): |
| "diff a renamed directory" |
| |
| sbox.build() |
| |
| os.chdir(sbox.wc_dir) |
| |
| svntest.main.run_svn(None, 'mv', os.path.join('A', 'D', 'G'), |
| os.path.join('A', 'D', 'I')) |
| |
| # Check a repos->wc diff |
| diff_output, err_output = svntest.main.run_svn(None, 'diff', |
| os.path.join('A', 'D')) |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'G', 'pi'), |
| 'D') : |
| raise svntest.Failure |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'I', 'pi'), |
| 'A') : |
| raise svntest.Failure |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log msg') |
| |
| # Check repos->wc after commit |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1', |
| os.path.join('A', 'D')) |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'G', 'pi'), |
| 'D') : |
| raise svntest.Failure |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'I', 'pi'), |
| 'A') : |
| raise svntest.Failure |
| |
| # Test a repos->repos diff after commit |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1:2') |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'G', 'pi'), |
| 'D') : |
| raise svntest.Failure |
| if check_diff_output(diff_output, |
| os.path.join('A', 'D', 'I', 'pi'), |
| 'A') : |
| raise svntest.Failure |
| |
| # Test the diff while within the moved directory |
| os.chdir(os.path.join('A','D','I')) |
| |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1') |
| |
| if check_diff_output(diff_output, 'pi', 'A') : |
| raise svntest.Failure |
| |
| # Test a repos->repos diff while within the moved directory |
| diff_output, err_output = svntest.main.run_svn(None, |
| 'diff', '-r', '1:2') |
| |
| if check_diff_output(diff_output, 'pi', 'A') : |
| raise svntest.Failure |
| |
| |
| #---------------------------------------------------------------------- |
| def diff_property_changes_to_base(sbox): |
| "diff to BASE with local property mods" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| expected_output_r1_r2 = [ |
| "\n", |
| "Property changes on: A\n", |
| "___________________________________________________________________\n", |
| "Name: dirprop\n", |
| " + r2value\n", |
| "\n", |
| "\n", |
| "Property changes on: iota\n", |
| "___________________________________________________________________\n", |
| "Name: fileprop\n", |
| " + r2value\n", |
| "\n" ] |
| |
| expected_output_r2_r1 = list(expected_output_r1_r2) |
| expected_output_r2_r1[4] = " - r2value\n" |
| expected_output_r2_r1[10] = " - r2value\n" |
| |
| |
| os.chdir(sbox.wc_dir) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'fileprop', 'r2value', 'iota') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'dirprop', 'r2value', 'A') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'empty-msg') |
| |
| # Check that forward and reverse repos-repos diffs are as expected. |
| expected = svntest.verify.UnorderedOutput(expected_output_r1_r2) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', '1:2') |
| |
| expected = svntest.verify.UnorderedOutput(expected_output_r2_r1) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', '2:1') |
| |
| # Now check repos->WORKING, repos->BASE, and BASE->repos. |
| # (BASE is r1, and WORKING has no local mods, so this should produce |
| # the same output as above). |
| expected = svntest.verify.UnorderedOutput(expected_output_r1_r2) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', '1') |
| |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', '1:BASE') |
| |
| expected = svntest.verify.UnorderedOutput(expected_output_r2_r1) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', 'BASE:1') |
| |
| # Modify some properties. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'fileprop', 'workingvalue', 'iota') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'dirprop', 'workingvalue', 'A') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'fileprop', 'workingvalue', 'A/mu') |
| |
| # Check that the earlier diffs against BASE are unaffected by the |
| # presence of local mods. |
| expected = svntest.verify.UnorderedOutput(expected_output_r1_r2) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', '1:BASE') |
| |
| expected = svntest.verify.UnorderedOutput(expected_output_r2_r1) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', 'BASE:1') |
| |
| def diff_schedule_delete(sbox): |
| "scheduled deleted" |
| |
| sbox.build() |
| |
| expected_output_r2_working = [ |
| "Index: foo\n", |
| "===================================================================\n", |
| "--- foo\t(revision 2)\n", |
| "+++ foo\t(working copy)\n", |
| "@@ -1 +0,0 @@\n", |
| "-xxx\n" |
| ] |
| |
| expected_output_r2_base = [ |
| "Index: foo\n", |
| "===================================================================\n", |
| "--- foo\t(revision 2)\n", |
| "+++ foo\t(working copy)\n", |
| "@@ -1 +1,2 @@\n", |
| " xxx\n", |
| "+yyy\n" |
| ] |
| expected_output_base_r2 = [ |
| "Index: foo\n", |
| "===================================================================\n", |
| "--- foo\t(working copy)\n", |
| "+++ foo\t(revision 2)\n", |
| "@@ -1,2 +1 @@\n", |
| " xxx\n", |
| "-yyy\n" |
| ] |
| |
| expected_output_r1_base = [ |
| "Index: foo\n", |
| "===================================================================\n", |
| "--- foo\t(revision 0)\n", |
| "+++ foo\t(revision 3)\n", |
| "@@ -0,0 +1,2 @@\n", |
| "+xxx\n", |
| "+yyy\n" |
| ] |
| expected_output_base_r1 = [ |
| "Index: foo\n", |
| "===================================================================\n", |
| "--- foo\t(working copy)\n", |
| "+++ foo\t(revision 1)\n", |
| "@@ -1,2 +0,0 @@\n", |
| "-xxx\n", |
| "-yyy\n" |
| ] |
| expected_output_base_working = expected_output_base_r1[:] |
| expected_output_base_working[2] = "--- foo\t(revision 3)\n" |
| expected_output_base_working[3] = "+++ foo\t(working copy)\n" |
| |
| wc_dir = sbox.wc_dir |
| os.chdir(wc_dir) |
| |
| svntest.main.file_append('foo', "xxx\n") |
| svntest.main.run_svn(None, 'add', 'foo') |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg r2') |
| |
| svntest.main.file_append('foo', "yyy\n") |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg r3') |
| |
| # Update everyone's BASE to r3, and mark 'foo' as schedule-deleted. |
| svntest.main.run_svn(None, |
| 'up') |
| svntest.main.run_svn(None, 'rm', 'foo') |
| |
| # A file marked as schedule-delete should act as if were not present |
| # in WORKING, but diffs against BASE should remain unaffected. |
| |
| # 1. repos-wc diff: file not present in repos. |
| svntest.actions.run_and_verify_svn(None, [], [], |
| 'diff', '-r', '1') |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_base, [], |
| 'diff', '-r', '1:BASE') |
| svntest.actions.run_and_verify_svn(None, expected_output_base_r1, [], |
| 'diff', '-r', 'BASE:1') |
| |
| # 2. repos-wc diff: file present in repos. |
| svntest.actions.run_and_verify_svn(None, expected_output_r2_working, [], |
| 'diff', '-r', '2') |
| svntest.actions.run_and_verify_svn(None, expected_output_r2_base, [], |
| 'diff', '-r', '2:BASE') |
| svntest.actions.run_and_verify_svn(None, expected_output_base_r2, [], |
| 'diff', '-r', 'BASE:2') |
| |
| # 3. wc-wc diff. |
| svntest.actions.run_and_verify_svn(None, expected_output_base_working, [], |
| 'diff') |
| |
| #---------------------------------------------------------------------- |
| def diff_mime_type_changes(sbox): |
| "repos-wc diffs with local svn:mime-type prop mods" |
| |
| sbox.build() |
| |
| expected_output_r1_wc = [ |
| "Index: iota\n", |
| "===================================================================\n", |
| "--- iota\t(revision 1)\n", |
| "+++ iota\t(working copy)\n", |
| "@@ -1 +1,2 @@\n", |
| " This is the file 'iota'.\n", |
| "+revision 2 text.\n" ] |
| |
| expected_output_wc_r1 = [ |
| "Index: iota\n", |
| "===================================================================\n", |
| "--- iota\t(working copy)\n", |
| "+++ iota\t(revision 1)\n", |
| "@@ -1,2 +1 @@\n", |
| " This is the file 'iota'.\n", |
| "-revision 2 text.\n" ] |
| |
| |
| os.chdir(sbox.wc_dir) |
| |
| # Append some text to iota (r2). |
| svntest.main.file_append('iota', "revision 2 text.\n") |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| |
| # Check that forward and reverse repos-BASE diffs are as expected. |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_wc, [], |
| 'diff', '-r', '1:BASE') |
| |
| svntest.actions.run_and_verify_svn(None, expected_output_wc_r1, [], |
| 'diff', '-r', 'BASE:1') |
| |
| # Mark iota as a binary file in the working copy. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'svn:mime-type', |
| 'application/octet-stream', 'iota') |
| |
| # Check that the earlier diffs against BASE are unaffected by the |
| # presence of local svn:mime-type property mods. |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_wc, [], |
| 'diff', '-r', '1:BASE') |
| |
| svntest.actions.run_and_verify_svn(None, expected_output_wc_r1, [], |
| 'diff', '-r', 'BASE:1') |
| |
| # Commit the change (r3) (so that BASE has the binary MIME type), then |
| # mark iota as a text file again in the working copy. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propdel', 'svn:mime-type', 'iota') |
| |
| # Now diffs against BASE will fail, but diffs against WORKNG should be |
| # fine. |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_wc, [], |
| 'diff', '-r', '1') |
| |
| |
| #---------------------------------------------------------------------- |
| # Test a repos-WORKING diff, with different versions of the same property |
| # at repository, BASE, and WORKING. |
| def diff_prop_change_local_propmod(sbox): |
| "diff a property change plus a local prop edit" |
| |
| sbox.build() |
| |
| expected_output_r2_wc = [ |
| "\n", |
| "Property changes on: A\n", |
| "___________________________________________________________________\n", |
| "Name: dirprop\n", |
| " - r2value\n", |
| " + workingvalue\n", |
| "Name: newdirprop\n", |
| " + newworkingvalue\n", |
| "\n", |
| "\n", |
| "Property changes on: iota\n", |
| "___________________________________________________________________\n", |
| "Name: fileprop\n", |
| " - r2value\n", |
| " + workingvalue\n", |
| "Name: newfileprop\n", |
| " + newworkingvalue\n", |
| "\n" ] |
| |
| os.chdir(sbox.wc_dir) |
| |
| # Set a property on A/ and iota, and commit them (r2). |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'dirprop', |
| 'r2value', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'fileprop', |
| 'r2value', 'iota') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| |
| # Change the property values on A/ and iota, and commit them (r3). |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'dirprop', |
| 'r3value', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'fileprop', |
| 'r3value', 'iota') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| |
| # Finally, change the property values one last time. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'dirprop', |
| 'workingvalue', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'fileprop', |
| 'workingvalue', 'iota') |
| # And also add some properties that only exist in WORKING. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'newdirprop', |
| 'newworkingvalue', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'newfileprop', |
| 'newworkingvalue', 'iota') |
| |
| # Now, if we diff r2 to WORKING, we've got three property values |
| # to consider: r2value (in the repository), r3value (in BASE), and |
| # workingvalue (in WORKING). |
| # The diff should only show the r2->WORKING change. |
| # |
| # We also need to make sure that the 'new' (WORKING only) properties |
| # are included in the output, since they won't be listed in a simple |
| # BASE->r2 diff. |
| expected = svntest.verify.UnorderedOutput(expected_output_r2_wc) |
| svntest.actions.run_and_verify_svn(None, expected, [], |
| 'diff', '-r', '2') |
| |
| |
| #---------------------------------------------------------------------- |
| # repos->wc and BASE->repos diffs that add files or directories with |
| # properties should show the added properties. |
| def diff_repos_wc_add_with_props(sbox): |
| "repos-wc diff showing added entries with props" |
| |
| sbox.build() |
| |
| expected_output_r1_r3 = [ |
| "Index: foo\n", |
| "===================================================================\n", |
| "--- foo\t(revision 0)\n", |
| "+++ foo\t(revision 3)\n", |
| "@@ -0,0 +1 @@\n", |
| "+content\n", |
| "\n", |
| "Property changes on: foo\n", |
| "___________________________________________________________________\n", |
| "Name: propname\n", |
| " + propvalue\n", |
| "\n", |
| "\n", |
| "Property changes on: X\n", |
| "___________________________________________________________________\n", |
| "Name: propname\n", |
| " + propvalue\n", |
| "\n", |
| "Index: X/bar\n", |
| "===================================================================\n", |
| "--- X/bar\t(revision 0)\n", |
| "+++ X/bar\t(revision 3)\n", |
| "@@ -0,0 +1 @@\n", |
| "+content\n", |
| "\n", |
| "Property changes on: " + os.path.join('X', 'bar') + "\n", |
| "___________________________________________________________________\n", |
| "Name: propname\n", |
| " + propvalue\n", |
| "\n" ] |
| # The output from the BASE->repos diff is the same content, but in a |
| # different order. |
| expected_output_r1_r3_a = expected_output_r1_r3[:12] + \ |
| expected_output_r1_r3[18:] + expected_output_r1_r3[12:18] |
| |
| os.chdir(sbox.wc_dir) |
| |
| # Create directory X, file foo, and file X/bar, and commit them (r2). |
| os.makedirs('X') |
| svntest.main.file_append('foo', "content\n") |
| svntest.main.file_append(os.path.join('X', 'bar'), "content\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'add', 'X', 'foo') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| |
| # Set a property on all three items, and commit them (r3). |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', 'propname', |
| 'propvalue', 'X', 'foo', |
| os.path.join('X', 'bar')) |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| |
| # Now, if we diff r1 to WORKING or BASE, we should see the content |
| # addition for foo and X/bar, and property additions for all three. |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_r3, [], |
| 'diff', '-r', '1') |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_r3, [], |
| 'diff', '-r', '1:BASE') |
| |
| # Update the BASE and WORKING revisions to r1. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', '-r', '1') |
| |
| # If we diff BASE to r3, we should see the same output as above. |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_r3_a, [], |
| 'diff', '-r', 'BASE:3') |
| |
| |
| #---------------------------------------------------------------------- |
| # repos-wc diffs on a non-recursively checked out wc that would normally |
| # (if recursively checked out) include a directory that is not present in |
| # the repos version should not segfault. |
| def diff_nonrecursive_checkout_deleted_dir(sbox): |
| "nonrecursive diff + deleted directories" |
| sbox.build() |
| |
| url = sbox.repo_url |
| A_url = url + '/A' |
| A_prime_url = url + '/A_prime' |
| |
| svntest.main.run_svn(None, |
| 'cp', '-m', 'log msg', A_url, A_prime_url) |
| |
| svntest.main.run_svn(None, |
| 'mkdir', '-m', 'log msg', A_prime_url + '/Q') |
| |
| wc = sbox.add_wc_path('wc') |
| |
| svntest.main.run_svn(None, |
| 'co', '-N', A_prime_url, wc) |
| |
| os.chdir(wc) |
| |
| # We don't particular care about the output here, just that it doesn't |
| # segfault. |
| svntest.main.run_svn(None, |
| 'diff', '-r1') |
| |
| |
| #---------------------------------------------------------------------- |
| # repos->WORKING diffs that include directories with local mods that are |
| # not present in the repos version should work as expected (and not, for |
| # example, show an extraneous BASE->WORKING diff for the added directory |
| # after the repos->WORKING output). |
| def diff_repos_working_added_dir(sbox): |
| "repos->WORKING diff showing added modifed dir" |
| |
| sbox.build() |
| |
| expected_output_r1_BASE = [ |
| "Index: X/bar\n", |
| "===================================================================\n", |
| "--- X/bar\t(revision 0)\n", |
| "+++ X/bar\t(revision 2)\n", |
| "@@ -0,0 +1 @@\n", |
| "+content\n" ] |
| expected_output_r1_WORKING = [ |
| "Index: X/bar\n", |
| "===================================================================\n", |
| "--- X/bar\t(revision 0)\n", |
| "+++ X/bar\t(revision 2)\n", |
| "@@ -0,0 +1,2 @@\n", |
| "+content\n", |
| "+more content\n" ] |
| |
| os.chdir(sbox.wc_dir) |
| |
| # Create directory X and file X/bar, and commit them (r2). |
| os.makedirs('X') |
| svntest.main.file_append(os.path.join('X', 'bar'), "content\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'add', 'X') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', 'log_msg') |
| |
| # Make a local modification to X/bar. |
| svntest.main.file_append(os.path.join('X', 'bar'), "more content\n") |
| |
| # Now, if we diff r1 to WORKING or BASE, we should see the content |
| # addition for X/bar, and (for WORKING) the local modification. |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_BASE, [], |
| 'diff', '-r', '1:BASE') |
| svntest.actions.run_and_verify_svn(None, expected_output_r1_WORKING, [], |
| 'diff', '-r', '1') |
| |
| |
| #---------------------------------------------------------------------- |
| # A base->repos diff of a moved file used to output an all-lines-deleted diff |
| def diff_base_repos_moved(sbox): |
| "base->repos diff of moved file" |
| |
| sbox.build() |
| |
| os.chdir(sbox.wc_dir) |
| |
| oldfile = 'iota' |
| newfile = 'kappa' |
| |
| # Move, modify and commit a file |
| svntest.main.run_svn(None, 'mv', oldfile, newfile) |
| svntest.main.file_write(newfile, "new content\n") |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', '') |
| |
| # Check that a base->repos diff shows deleted and added lines. |
| # It's not clear whether we expect a file-change diff or |
| # a file-delete plus file-add. The former is currently produced if we |
| # explicitly request a diff of the file itself, and the latter if we |
| # request a tree diff which just happens to contain the file. |
| out, err = svntest.actions.run_and_verify_svn(None, |
| svntest.verify.AnyOutput, [], |
| 'diff', '-rBASE:1', newfile) |
| if check_diff_output(out, newfile, 'M'): |
| raise svntest.Failure |
| |
| # Diff should recognise that the item's name has changed, and mention both |
| # the current and the old name in parentheses, in the right order. |
| if (out[2][:3] != '---' or out[2].find('kappa)') == -1 or |
| out[3][:3] != '+++' or out[3].find('iota)') == -1): |
| raise svntest.Failure |
| |
| |
| #---------------------------------------------------------------------- |
| # A diff of an added file within an added directory should work, and |
| # shouldn't produce an error. |
| def diff_added_subtree(sbox): |
| "wc->repos diff of added subtree" |
| |
| sbox.build() |
| |
| os.chdir(sbox.wc_dir) |
| |
| # Roll the wc back to r0 (i.e. an empty wc). |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', '-r0') |
| |
| # We shouldn't get any errors when we request a diff showing the |
| # addition of the greek tree. The diff contains additions of files |
| # and directories with parents that don't currently exist in the wc, |
| # which is what we're testing here. |
| svntest.actions.run_and_verify_svn(None, svntest.verify.AnyOutput, [], |
| 'diff', '-r', 'BASE:1') |
| |
| #---------------------------------------------------------------------- |
| def basic_diff_summarize(sbox): |
| "basic diff summarize" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| # A content modification. |
| svntest.main.file_append(os.path.join(wc_dir, "A", "mu"), "New mu content") |
| |
| # A prop modification. |
| svntest.main.run_svn(None, |
| "propset", "prop", "val", |
| os.path.join(wc_dir, 'iota')) |
| |
| # Both content and prop mods. |
| tau_path = os.path.join(wc_dir, "A", "D", "G", "tau") |
| svntest.main.file_append(tau_path, "tautau") |
| svntest.main.run_svn(None, |
| "propset", "prop", "val", tau_path) |
| |
| # A file addition. |
| newfile_path = os.path.join(wc_dir, 'newfile') |
| svntest.main.file_append(newfile_path, 'newfile') |
| svntest.main.run_svn(None, 'add', newfile_path) |
| |
| # A file deletion. |
| svntest.main.run_svn(None, "delete", os.path.join(wc_dir, 'A', 'B', |
| 'lambda')) |
| |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/mu': Item(verb='Sending'), |
| 'iota': Item(verb='Sending'), |
| 'newfile': Item(verb='Adding'), |
| 'A/D/G/tau': Item(verb='Sending'), |
| 'A/B/lambda': Item(verb='Deleting'), |
| }) |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.add({ |
| 'newfile': Item(status=' ', wc_rev=2), |
| }) |
| expected_status.tweak("A/mu", "iota", "A/D/G/tau", 'newfile', wc_rev=2) |
| expected_status.remove("A/B/lambda") |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, |
| wc_dir) |
| |
| # Get the differences between two versions of a file. |
| expected_diff = svntest.wc.State(wc_dir, { |
| 'iota': Item(status=' M'), |
| }) |
| svntest.actions.run_and_verify_diff_summarize(expected_diff, None, |
| None, None, None, None, |
| os.path.join(wc_dir, 'iota'), |
| '-c2') |
| |
| # Get the differences between two versions of an entire directory. |
| expected_diff = svntest.wc.State(wc_dir, { |
| 'A/mu': Item(status='M '), |
| 'iota': Item(status=' M'), |
| 'A/D/G/tau': Item(status='MM'), |
| 'newfile': Item(status='A '), |
| 'A/B/lambda': Item(status='D '), |
| }) |
| svntest.actions.run_and_verify_diff_summarize(expected_diff, None, |
| None, None, None, None, |
| wc_dir, '-r1:2') |
| |
| def diff_weird_author(sbox): |
| "diff with svn:author that has < in it" |
| |
| sbox.build() |
| |
| svntest.actions.enable_revprop_changes(sbox.repo_dir) |
| |
| svntest.main.file_write(os.path.join(sbox.wc_dir, 'A', 'mu'), |
| "new content\n") |
| |
| expected_output = svntest.wc.State(sbox.wc_dir, { |
| 'A/mu': Item(verb='Sending'), |
| }) |
| |
| expected_status = svntest.actions.get_virginal_state(sbox.wc_dir, 1) |
| expected_status.tweak("A/mu", wc_rev=2) |
| |
| svntest.actions.run_and_verify_commit(sbox.wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, |
| sbox.wc_dir) |
| |
| svntest.main.run_svn(None, |
| "propset", "--revprop", "-r", "2", "svn:author", |
| "J. Random <jrandom@example.com>", sbox.repo_url) |
| |
| svntest.actions.run_and_verify_svn(None, |
| ["J. Random <jrandom@example.com>\n"], |
| [], |
| "pget", "--revprop", "-r" "2", |
| "svn:author", sbox.repo_url) |
| |
| expected_output = [ |
| "Index: A/mu\n", |
| "===================================================================\n", |
| "--- A/mu\t(revision 1)\n", |
| "+++ A/mu\t(revision 2)\n", |
| "@@ -1 +1 @@\n", |
| "-This is the file 'mu'.\n", |
| "+new content\n" |
| ] |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-r1:2', sbox.repo_url) |
| |
| # test for issue 2121, use -x -w option for ignoring whitespace during diff |
| def diff_ignore_whitespace(sbox): |
| "ignore whitespace when diffing" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| file_name = "iota" |
| file_path = os.path.join(wc_dir, file_name) |
| |
| svntest.main.file_write(file_path, |
| "Aa\n" |
| "Bb\n" |
| "Cc\n") |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| }) |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| None, None, None, None, |
| None, None, wc_dir) |
| |
| # only whitespace changes, should return no changes |
| svntest.main.file_write(file_path, |
| " A a \n" |
| " B b \n" |
| " C c \n") |
| |
| svntest.actions.run_and_verify_svn(None, [], [], |
| 'diff', '-x', '-w', file_path) |
| |
| # some changes + whitespace |
| svntest.main.file_write(file_path, |
| " A a \n" |
| "Xxxx X\n" |
| " Bb b \n" |
| " C c \n") |
| expected_output = [ |
| "Index: svn-test-work/working_copies/diff_tests-39/iota\n", |
| "===================================================================\n", |
| "--- svn-test-work/working_copies/diff_tests-39/iota\t(revision 2)\n", |
| "+++ svn-test-work/working_copies/diff_tests-39/iota\t(working copy)\n", |
| "@@ -1,3 +1,4 @@\n", |
| " Aa\n", |
| "-Bb\n", |
| "+Xxxx X\n", |
| "+ Bb b \n", |
| " Cc\n" ] |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-x', '-w', file_path) |
| |
| def diff_ignore_eolstyle(sbox): |
| "ignore eol styles when diffing" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| file_name = "iota" |
| file_path = os.path.join(wc_dir, file_name) |
| |
| svntest.main.file_write(file_path, |
| "Aa\n" |
| "Bb\n" |
| "Cc\n") |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| }) |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| None, None, None, None, |
| None, None, wc_dir) |
| |
| # commit only eol changes |
| svntest.main.file_write(file_path, |
| "Aa\r" |
| "Bb\r" |
| "Cc") |
| |
| expected_output = [ |
| "Index: svn-test-work/working_copies/diff_tests-40/iota\n", |
| "===================================================================\n", |
| "--- svn-test-work/working_copies/diff_tests-40/iota\t(revision 2)\n", |
| "+++ svn-test-work/working_copies/diff_tests-40/iota\t(working copy)\n", |
| "@@ -1,3 +1,3 @@\n", |
| " Aa\n", |
| " Bb\n", |
| "-Cc\n", |
| "+Cc\n", |
| "\ No newline at end of file\n" ] |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-x', '--ignore-eol-style', |
| file_path) |
| |
| # test for issue 2600, diff revision of a file in a renamed folder |
| def diff_in_renamed_folder(sbox): |
| "diff a revision of a file in a renamed folder" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| C_path = os.path.join(wc_dir, "A", "C") |
| D_path = os.path.join(wc_dir, "A", "D") |
| kappa_path = os.path.join(D_path, "C", "kappa") |
| |
| # add a new file to a renamed (moved in this case) folder. |
| svntest.main.run_svn(None, 'mv', C_path, D_path) |
| |
| svntest.main.file_append(kappa_path, "this is file kappa.\n") |
| svntest.main.run_svn(None, 'add', kappa_path) |
| |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/C' : Item(verb='Deleting'), |
| 'A/D/C' : Item(verb='Adding'), |
| 'A/D/C/kappa' : Item(verb='Adding'), |
| }) |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| None, None, None, None, |
| None, None, wc_dir) |
| |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/D/C/kappa' : Item(verb='Sending'), |
| }) |
| |
| # modify the file two times so we have something to diff. |
| for i in range(3, 5): |
| svntest.main.file_append(kappa_path, str(i) + "\n") |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| None, None, None, None, |
| None, None, wc_dir) |
| |
| expected_output = [ |
| "Index: svn-test-work/working_copies/diff_tests-41/A/D/C/kappa\n", |
| "===================================================================\n", |
| "--- svn-test-work/working_copies/diff_tests-41/A/D/C/kappa\t(revision 3)\n", |
| "+++ svn-test-work/working_copies/diff_tests-41/A/D/C/kappa\t(revision 4)\n", |
| "@@ -1,2 +1,3 @@\n", |
| " this is file kappa.\n", |
| " 3\n", |
| "+4\n" |
| ] |
| |
| svntest.actions.run_and_verify_svn(None, expected_output, [], |
| 'diff', '-r3:4', kappa_path) |
| |
| def diff_with_depth(sbox): |
| "test diffs at various depths" |
| |
| sbox.build() |
| |
| diff = [ |
| "\n", |
| "Property changes on: .\n", |
| "___________________________________________________________________\n", |
| "Name: foo1\n", |
| " + bar1\n", |
| "\n", |
| "\n", |
| "Property changes on: iota\n", |
| "___________________________________________________________________\n", |
| "Name: foo2\n", |
| " + bar2\n", |
| "\n", |
| "\n", |
| "Property changes on: A\n", |
| "___________________________________________________________________\n", |
| "Name: foo3\n", |
| " + bar3\n", |
| "\n", |
| "\n", |
| "Property changes on: " + os.path.join('A', 'B') + "\n", |
| "___________________________________________________________________\n", |
| "Name: foo4\n", |
| " + bar4\n", |
| "\n" ] |
| |
| expected_empty = svntest.verify.UnorderedOutput(diff[:6]) |
| expected_files = svntest.verify.UnorderedOutput(diff[:12]) |
| expected_immediates = svntest.verify.UnorderedOutput(diff[:18]) |
| expected_infinity = svntest.verify.UnorderedOutput(diff[:]) |
| |
| os.chdir(sbox.wc_dir) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo1', 'bar1', '.') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo2', 'bar2', 'iota') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo3', 'bar3', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo4', 'bar4', os.path.join('A', 'B')) |
| |
| # Test wc-wc diff. |
| svntest.actions.run_and_verify_svn(None, expected_empty, [], |
| 'diff', '--depth', 'empty') |
| svntest.actions.run_and_verify_svn(None, expected_files, [], |
| 'diff', '--depth', 'files') |
| svntest.actions.run_and_verify_svn(None, expected_immediates, [], |
| 'diff', '--depth', 'immediates') |
| svntest.actions.run_and_verify_svn(None, expected_infinity, [], |
| 'diff', '--depth', 'infinity') |
| |
| # Commit the changes. |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'ci', '-m', '') |
| |
| # Test repos-repos diff. Reuse the expected outputs from above. |
| svntest.actions.run_and_verify_svn(None, expected_empty, [], |
| 'diff', '-c2', '--depth', 'empty') |
| svntest.actions.run_and_verify_svn(None, expected_files, [], |
| 'diff', '-c2', '--depth', 'files') |
| svntest.actions.run_and_verify_svn(None, expected_immediates, [], |
| 'diff', '-c2', '--depth', 'immediates') |
| svntest.actions.run_and_verify_svn(None, expected_infinity, [], |
| 'diff', '-c2', '--depth', 'infinity') |
| |
| diff_wc_repos = [ |
| "\n", |
| "Property changes on: .\n", |
| "___________________________________________________________________\n", |
| "Name: foo1\n", |
| " - bar1\n", |
| " + baz1\n", |
| "\n", |
| "\n", |
| "Property changes on: iota\n", |
| "___________________________________________________________________\n", |
| "Name: foo2\n", |
| " - bar2\n", |
| " + baz2\n", |
| "\n", |
| "\n", |
| "Index: iota\n", |
| "===================================================================\n", |
| "--- iota\t(revision 2)\n", |
| "+++ iota\t(working copy)\n", |
| "@@ -1 +1,2 @@\n", |
| " This is the file 'iota'.\n", |
| "+new text\n", |
| "Property changes on: A\n", |
| "___________________________________________________________________\n", |
| "Name: foo3\n", |
| " - bar3\n", |
| " + baz3\n", |
| "\n", |
| "\n", |
| "Property changes on: " + os.path.join('A', 'B') + "\n", |
| "___________________________________________________________________\n", |
| "Name: foo4\n", |
| " - bar4\n", |
| " + baz4\n", |
| "\n", |
| "Index: A/mu\n", |
| "===================================================================\n", |
| "--- A/mu\t(revision 1)\n", |
| "+++ A/mu\t(working copy)\n", |
| "@@ -1 +1,2 @@\n", |
| " This is the file 'mu'.\n", |
| "+new text\n" ] |
| |
| expected_empty = svntest.verify.UnorderedOutput(diff_wc_repos[:7]) |
| expected_files = svntest.verify.UnorderedOutput(diff_wc_repos[1:22]) |
| expected_immediates = svntest.verify.UnorderedOutput(diff_wc_repos[1:29]) |
| expected_infinity = svntest.verify.UnorderedOutput(diff_wc_repos[:]) |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'up', '-r1') |
| |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo1', 'baz1', '.') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo2', 'baz2', 'iota') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo3', 'baz3', 'A') |
| svntest.actions.run_and_verify_svn(None, None, [], |
| 'propset', |
| 'foo4', 'baz4', os.path.join('A', 'B')) |
| svntest.main.file_append(os.path.join('A', 'mu'), "new text\n") |
| svntest.main.file_append('iota', "new text\n") |
| |
| # Test wc-repos diff. |
| svntest.actions.run_and_verify_svn(None, expected_empty, [], |
| 'diff', '-rHEAD', '--depth', 'empty') |
| svntest.actions.run_and_verify_svn(None, expected_files, [], |
| 'diff', '-rHEAD', '--depth', 'files') |
| svntest.actions.run_and_verify_svn(None, expected_immediates, [], |
| 'diff', '-rHEAD', '--depth', 'immediates') |
| svntest.actions.run_and_verify_svn(None, expected_infinity, [], |
| 'diff', '-rHEAD', '--depth', 'infinity') |
| |
| # test for issue 2920: ignore eol-style on empty lines |
| def diff_ignore_eolstyle_empty_lines(sbox): |
| "ignore eol styles when diffing empty lines" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| file_name = "iota" |
| file_path = os.path.join(wc_dir, file_name) |
| |
| svntest.main.file_write(file_path, |
| "Aa\n" |
| "\n" |
| "Bb\n" |
| "\n" |
| "Cc\n") |
| expected_output = svntest.wc.State(wc_dir, { |
| 'iota' : Item(verb='Sending'), |
| }) |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| None, None, None, None, |
| None, None, wc_dir) |
| |
| # sleep to guarantee timestamp change |
| time.sleep(1) |
| |
| # commit only eol changes |
| svntest.main.file_write(file_path, |
| "Aa\012" |
| "\012" |
| "Bb\r" |
| "\r" |
| "Cc\012", |
| mode="wb") |
| |
| svntest.actions.run_and_verify_svn(None, [], [], |
| 'diff', '-x', '--ignore-eol-style', |
| file_path) |
| |
| def diff_backward_repos_wc_copy(sbox): |
| "backward repos->wc diff with copied file" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| os.chdir(wc_dir) |
| |
| # copy a file |
| mu_path = os.path.join('A', 'mu') |
| mucp_path = os.path.join('A', 'mucopy') |
| svntest.main.run_svn(None, 'cp', mu_path, mucp_path) |
| |
| # commit r2 and update back to r1 |
| svntest.main.run_svn(None, |
| 'ci', '-m', 'log msg') |
| svntest.main.run_svn(None, 'up', '-r1') |
| |
| # diff r2 against working copy |
| diff_repos_wc = [ |
| "Index: A/mucopy\n", |
| "===================================================================\n", |
| "--- A/mucopy\t(revision 2)\n", |
| "+++ A/mucopy\t(working copy)\n", |
| "@@ -1 +0,0 @@\n", |
| "-This is the file 'mu'.\n", |
| ] |
| |
| svntest.actions.run_and_verify_svn(None, diff_repos_wc, [], |
| 'diff', '-r' , '2') |
| |
| #---------------------------------------------------------------------- |
| |
| def diff_summarize_xml(sbox): |
| "xml diff summarize" |
| |
| sbox.build() |
| wc_dir = sbox.wc_dir |
| |
| # A content modification. |
| svntest.main.file_append(os.path.join(wc_dir, "A", "mu"), "New mu content") |
| |
| # A prop modification. |
| svntest.main.run_svn(None, |
| "propset", "prop", "val", |
| os.path.join(wc_dir, 'iota')) |
| |
| # Both content and prop mods. |
| tau_path = os.path.join(wc_dir, "A", "D", "G", "tau") |
| svntest.main.file_append(tau_path, "tautau") |
| svntest.main.run_svn(None, |
| "propset", "prop", "val", tau_path) |
| |
| # A file addition. |
| newfile_path = os.path.join(wc_dir, 'newfile') |
| svntest.main.file_append(newfile_path, 'newfile') |
| svntest.main.run_svn(None, 'add', newfile_path) |
| |
| # A file deletion. |
| svntest.main.run_svn(None, "delete", os.path.join(wc_dir, 'A', 'B', |
| 'lambda')) |
| |
| # A directory addition |
| svntest.main.run_svn(None, "mkdir", os.path.join(wc_dir, 'newdir')) |
| |
| expected_output = svntest.wc.State(wc_dir, { |
| 'A/mu': Item(verb='Sending'), |
| 'iota': Item(verb='Sending'), |
| 'newfile': Item(verb='Adding'), |
| 'A/D/G/tau': Item(verb='Sending'), |
| 'A/B/lambda': Item(verb='Deleting'), |
| 'newdir': Item(verb='Adding'), |
| }) |
| expected_status = svntest.actions.get_virginal_state(wc_dir, 1) |
| expected_status.add({ |
| 'newfile': Item(status=' ', wc_rev=2), |
| 'newdir': Item(status=' ', wc_rev=2), |
| }) |
| expected_status.tweak("A/mu", "iota", "A/D/G/tau", "newfile", "newdir", |
| wc_rev=2) |
| expected_status.remove("A/B/lambda") |
| |
| svntest.actions.run_and_verify_commit(wc_dir, expected_output, |
| expected_status, None, |
| None, None, None, None, |
| wc_dir) |
| |
| # 1) Test --xml without --summarize |
| svntest.actions.run_and_verify_svn( |
| None, None, ".*--xml' option only valid with '--summarize' option", |
| 'diff', wc_dir, '--xml') |
| |
| # 2) Test --xml on invalid revision |
| svntest.actions.run_and_verify_diff_summarize_xml( |
| ".*No such revision 5555555", |
| None, wc_dir, None, None, None, '-r0:5555555', wc_dir) |
| |
| # 3) Test working copy summarize |
| svntest.actions.run_and_verify_diff_summarize_xml( |
| ".*Summarizing diff can only compare repository to repository", |
| None, wc_dir, None, None, wc_dir) |
| |
| # 4) Test --summarize --xml on -c2 |
| paths = ['iota',] |
| items = ['none',] |
| kinds = ['file',] |
| props = ['modified',] |
| |
| svntest.actions.run_and_verify_diff_summarize_xml( |
| [], wc_dir, paths, items, props, kinds, '-c2', |
| os.path.join(wc_dir, 'iota')) |
| |
| # 5) Test --summarize --xml on -r1:2 |
| paths = ['A/mu', 'iota', 'A/D/G/tau', 'newfile', 'A/B/lambda', |
| 'newdir',] |
| items = ['modified', 'none', 'modified', 'added', 'deleted', 'added',] |
| kinds = ['file','file','file','file','file', 'dir',] |
| props = ['none', 'modified', 'modified', 'none', 'none', 'none',] |
| |
| svntest.actions.run_and_verify_diff_summarize_xml( |
| [], wc_dir, paths, items, props, kinds, '-r1:2', wc_dir) |
| |
| # 6) Same as test #5 but ran against a URL instead of a WC path |
| paths = ['A/mu', 'iota', 'A/D/G/tau', 'newfile', 'A/B/lambda', |
| 'newdir',] |
| items = ['modified', 'none', 'modified', 'added', 'deleted', 'added',] |
| kinds = ['file','file','file','file','file', 'dir',] |
| props = ['none', 'modified', 'modified', 'none', 'none', 'none',] |
| |
| svntest.actions.run_and_verify_diff_summarize_xml( |
| [], sbox.repo_url, paths, items, props, kinds, '-r1:2', sbox.repo_url) |
| |
| ######################################################################## |
| #Run the tests |
| |
| |
| # list all tests here, starting with None: |
| test_list = [ None, |
| diff_update_a_file, |
| diff_add_a_file, |
| diff_add_a_file_in_a_subdir, |
| diff_replace_a_file, |
| diff_multiple_reverse, |
| diff_non_recursive, |
| diff_repo_subset, |
| diff_non_version_controlled_file, |
| diff_pure_repository_update_a_file, |
| diff_only_property_change, |
| dont_diff_binary_file, |
| diff_nonextant_urls, |
| diff_head_of_moved_file, |
| diff_base_to_repos, |
| diff_deleted_in_head, |
| diff_targets, |
| diff_branches, |
| diff_repos_and_wc, |
| diff_file_urls, |
| diff_prop_change_local_edit, |
| check_for_omitted_prefix_in_path_component, |
| diff_renamed_file, |
| diff_within_renamed_dir, |
| diff_prop_on_named_dir, |
| diff_keywords, |
| diff_force, |
| diff_schedule_delete, |
| XFail(diff_renamed_dir), |
| diff_property_changes_to_base, |
| diff_mime_type_changes, |
| diff_prop_change_local_propmod, |
| diff_repos_wc_add_with_props, |
| diff_nonrecursive_checkout_deleted_dir, |
| diff_repos_working_added_dir, |
| diff_base_repos_moved, |
| diff_added_subtree, |
| basic_diff_summarize, |
| diff_weird_author, |
| diff_ignore_whitespace, |
| diff_ignore_eolstyle, |
| diff_in_renamed_folder, |
| diff_with_depth, |
| diff_ignore_eolstyle_empty_lines, |
| diff_backward_repos_wc_copy, |
| diff_summarize_xml, |
| ] |
| |
| if __name__ == '__main__': |
| svntest.main.run_tests(test_list) |
| # NOTREACHED |
| |
| |
| ### End of file. |