OLD | NEW |
---|---|
1 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """SCM-specific utility classes.""" | 5 """SCM-specific utility classes.""" |
6 | 6 |
7 import os | 7 import os |
8 import re | 8 import re |
9 import shutil | 9 import shutil |
10 import subprocess | 10 import subprocess |
(...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
543 empty string is also returned. | 543 empty string is also returned. |
544 """ | 544 """ |
545 output = SVN.Capture(["propget", property_name, file]) | 545 output = SVN.Capture(["propget", property_name, file]) |
546 if (output.startswith("svn: ") and | 546 if (output.startswith("svn: ") and |
547 output.endswith("is not under version control")): | 547 output.endswith("is not under version control")): |
548 return "" | 548 return "" |
549 else: | 549 else: |
550 return output | 550 return output |
551 | 551 |
552 @staticmethod | 552 @staticmethod |
553 def DiffItem(filename, full_move=False): | 553 def DiffItem(filename, full_move=False, revision=None): |
554 """Diffs a single file. | 554 """Diffs a single file. |
555 | 555 |
556 Be sure to be in the appropriate directory before calling to have the | 556 Be sure to be in the appropriate directory before calling to have the |
557 expected relative path. | 557 expected relative path. |
558 full_move means that move or copy operations should completely recreate the | 558 full_move means that move or copy operations should completely recreate the |
559 files, usually in the prospect to apply the patch for a try job.""" | 559 files, usually in the prospect to apply the patch for a try job.""" |
560 # Use svn info output instead of os.path.isdir because the latter fails | 560 # Use svn info output instead of os.path.isdir because the latter fails |
561 # when the file is deleted. | 561 # when the file is deleted. |
562 if SVN.CaptureInfo(filename).get("Node Kind") == "directory": | 562 if SVN.CaptureInfo(filename).get("Node Kind") == "directory": |
563 return None | 563 return None |
564 # If the user specified a custom diff command in their svn config file, | 564 # If the user specified a custom diff command in their svn config file, |
565 # then it'll be used when we do svn diff, which we don't want to happen | 565 # then it'll be used when we do svn diff, which we don't want to happen |
566 # since we want the unified diff. Using --diff-cmd=diff doesn't always | 566 # since we want the unified diff. Using --diff-cmd=diff doesn't always |
567 # work, since they can have another diff executable in their path that | 567 # work, since they can have another diff executable in their path that |
568 # gives different line endings. So we use a bogus temp directory as the | 568 # gives different line endings. So we use a bogus temp directory as the |
569 # config directory, which gets around these problems. | 569 # config directory, which gets around these problems. |
570 bogus_dir = tempfile.mkdtemp() | 570 bogus_dir = tempfile.mkdtemp() |
571 try: | 571 try: |
572 # Grabs the diff data. | 572 # Grabs the diff data. |
573 data = SVN.Capture(["diff", "--config-dir", bogus_dir, filename], None) | 573 command = ["diff", "--config-dir", bogus_dir, filename] |
574 if revision is not None: | |
bradn
2010/01/07 01:50:13
if not revision:
| |
575 command.extend(['--revision', revision]) | |
576 data = SVN.Capture(command, None) | |
574 if data: | 577 if data: |
575 pass | 578 pass |
576 elif SVN.IsMoved(filename): | 579 elif SVN.IsMoved(filename): |
577 if full_move: | 580 if full_move: |
578 file_content = gclient_utils.FileRead(filename, 'rb') | 581 file_content = gclient_utils.FileRead(filename, 'rb') |
579 # Prepend '+' to every lines. | 582 # Prepend '+' to every lines. |
580 file_content = ['+' + i for i in file_content.splitlines(True)] | 583 file_content = ['+' + i for i in file_content.splitlines(True)] |
581 nb_lines = len(file_content) | 584 nb_lines = len(file_content) |
582 # We need to use / since patch on unix will fail otherwise. | 585 # We need to use / since patch on unix will fail otherwise. |
583 filename = filename.replace('\\', '/') | 586 filename = filename.replace('\\', '/') |
584 data = "Index: %s\n" % filename | 587 data = "Index: %s\n" % filename |
585 data += '=' * 67 + '\n' | 588 data += '=' * 67 + '\n' |
586 # Note: Should we use /dev/null instead? | 589 # Note: Should we use /dev/null instead? |
587 data += "--- %s\n" % filename | 590 data += "--- %s\n" % filename |
588 data += "+++ %s\n" % filename | 591 data += "+++ %s\n" % filename |
589 data += "@@ -0,0 +1,%d @@\n" % nb_lines | 592 data += "@@ -0,0 +1,%d @@\n" % nb_lines |
590 data += ''.join(file_content) | 593 data += ''.join(file_content) |
591 else: | 594 else: |
592 # svn diff on a mv/cp'd file outputs nothing. | 595 # svn diff on a mv/cp'd file outputs nothing. |
593 # We put in an empty Index entry so upload.py knows about them. | 596 # We put in an empty Index entry so upload.py knows about them. |
594 data = "Index: %s\n" % filename | 597 data = "Index: %s\n" % filename |
595 else: | 598 else: |
596 # The file is not modified anymore. It should be removed from the set. | 599 # The file is not modified anymore. It should be removed from the set. |
597 pass | 600 pass |
598 finally: | 601 finally: |
599 shutil.rmtree(bogus_dir) | 602 shutil.rmtree(bogus_dir) |
600 return data | 603 return data |
601 | 604 |
602 @staticmethod | 605 @staticmethod |
603 def GenerateDiff(filenames, root=None, full_move=False): | 606 def GenerateDiff(filenames, root=None, full_move=False, revision=None): |
604 """Returns a string containing the diff for the given file list. | 607 """Returns a string containing the diff for the given file list. |
605 | 608 |
606 The files in the list should either be absolute paths or relative to the | 609 The files in the list should either be absolute paths or relative to the |
607 given root. If no root directory is provided, the repository root will be | 610 given root. If no root directory is provided, the repository root will be |
608 used. | 611 used. |
609 The diff will always use relative paths. | 612 The diff will always use relative paths. |
610 """ | 613 """ |
611 previous_cwd = os.getcwd() | 614 previous_cwd = os.getcwd() |
612 root = os.path.join(root or SVN.GetCheckoutRoot(previous_cwd), '') | 615 root = os.path.join(root or SVN.GetCheckoutRoot(previous_cwd), '') |
613 def RelativePath(path, root): | 616 def RelativePath(path, root): |
614 """We must use relative paths.""" | 617 """We must use relative paths.""" |
615 if path.startswith(root): | 618 if path.startswith(root): |
616 return path[len(root):] | 619 return path[len(root):] |
617 return path | 620 return path |
618 try: | 621 try: |
619 os.chdir(root) | 622 os.chdir(root) |
620 diff = "".join(filter(None, | 623 diff = "".join(filter(None, |
621 [SVN.DiffItem(RelativePath(f, root), | 624 [SVN.DiffItem(RelativePath(f, root, revision), |
622 full_move=full_move) | 625 full_move=full_move) |
623 for f in filenames])) | 626 for f in filenames])) |
624 finally: | 627 finally: |
625 os.chdir(previous_cwd) | 628 os.chdir(previous_cwd) |
626 return diff | 629 return diff |
627 | 630 |
628 | 631 |
629 @staticmethod | 632 @staticmethod |
630 def GetEmail(repo_root): | 633 def GetEmail(repo_root): |
631 """Retrieves the svn account which we assume is an email address.""" | 634 """Retrieves the svn account which we assume is an email address.""" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
693 if not cur_dir_repo_root: | 696 if not cur_dir_repo_root: |
694 return None | 697 return None |
695 | 698 |
696 while True: | 699 while True: |
697 parent = os.path.dirname(directory) | 700 parent = os.path.dirname(directory) |
698 if (SVN.CaptureInfo(parent, print_error=False).get( | 701 if (SVN.CaptureInfo(parent, print_error=False).get( |
699 "Repository Root") != cur_dir_repo_root): | 702 "Repository Root") != cur_dir_repo_root): |
700 break | 703 break |
701 directory = parent | 704 directory = parent |
702 return directory | 705 return directory |
OLD | NEW |