/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/patch.py

  • Committer: Michael Ellerman
  • Date: 2006-03-09 00:24:48 UTC
  • mto: (1610.1.8 bzr.mbp.integration)
  • mto: This revision was merged to the branch mainline in revision 1616.
  • Revision ID: michael@ellerman.id.au-20060309002448-70cce15e3d605130
Make the "ignore line" in the commit message editor the "right" width, so
that if you make your message that wide it won't wrap in bzr log output.
Just as a visual aid.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import errno
 
2
import os
 
3
from subprocess import Popen, PIPE
 
4
 
 
5
from bzrlib.errors import NoDiff3
 
6
"""
 
7
Diff and patch functionality
 
8
"""
 
9
__docformat__ = "restructuredtext"
 
10
 
 
11
def write_to_cmd(args, input=""):
 
12
    if os.name != 'nt':
 
13
        process = Popen(args, bufsize=len(input), stdin=PIPE, stdout=PIPE,
 
14
                        stderr=PIPE, close_fds=True)
 
15
    else:
 
16
        process = Popen(args, bufsize=len(input), stdin=PIPE, stdout=PIPE,
 
17
                        stderr=PIPE)
 
18
 
 
19
    stdout, stderr = process.communicate(input)
 
20
    status = process.wait()
 
21
    if status < 0:
 
22
        raise Exception("%s killed by signal %i" (args[0], -status))
 
23
    return stdout, stderr, status
 
24
    
 
25
 
 
26
def patch(patch_contents, filename, output_filename=None, reverse=False):
 
27
    """Apply a patch to a file, to produce another output file.  This is should
 
28
    be suitable for our limited purposes.
 
29
 
 
30
    :param patch_contents: The contents of the patch to apply
 
31
    :type patch_contents: str
 
32
    :param filename: the name of the file to apply the patch to
 
33
    :type filename: str
 
34
    :param output_filename: The filename to produce.  If None, file is \
 
35
    modified in-place
 
36
    :type output_filename: str or NoneType
 
37
    :param reverse: If true, apply the patch in reverse
 
38
    :type reverse: bool
 
39
    :return: 0 on success, 1 if some hunks failed
 
40
    """
 
41
    args = ["patch", "-f", "-s", "--posix", "--binary"]
 
42
    if reverse:
 
43
        args.append("--reverse")
 
44
    if output_filename is not None:
 
45
        args.extend(("-o", output_filename))
 
46
    args.append(filename)
 
47
    stdout, stderr, status = write_to_cmd(args, patch_contents)
 
48
    return status 
 
49
 
 
50
 
 
51
def diff3(out_file, mine_path, older_path, yours_path):
 
52
    def add_label(args, label):
 
53
        args.extend(("-L", label))
 
54
    args = ['diff3', "-E", "--merge"]
 
55
    add_label(args, "TREE")
 
56
    add_label(args, "ANCESTOR")
 
57
    add_label(args, "MERGE-SOURCE")
 
58
    args.extend((mine_path, older_path, yours_path))
 
59
    try:
 
60
        output, stderr, status = write_to_cmd(args)
 
61
    except OSError, e:
 
62
        if e.errno == errno.ENOENT:
 
63
            raise NoDiff3
 
64
        else:
 
65
            raise
 
66
    if status not in (0, 1):
 
67
        raise Exception(stderr)
 
68
    file(out_file, "wb").write(output)
 
69
    return status