~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to shelf.py

  • Committer: Aaron Bentley
  • Date: 2005-10-29 21:29:55 UTC
  • mto: This revision was merged to the branch mainline in revision 263.
  • Revision ID: abentley@panoramicfeedback.com-20051029212955-132d343a64ac80bc
Switched to TreeDelta.has_changed

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#!/usr/bin/python
2
 
 
3
 
# Copyright (C) 2005 Michael Ellerman <michael@ellerman.id.au>
4
 
#
5
 
#    This program is free software; you can redistribute it and/or modify
6
 
#    it under the terms of the GNU General Public License as published by
7
 
#    the Free Software Foundation; either version 2 of the License, or
8
 
#    (at your option) any later version.
9
 
#
10
 
#    This program is distributed in the hope that it will be useful,
11
 
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
#    GNU General Public License for more details.
14
 
#
15
 
#    You should have received a copy of the GNU General Public License
16
 
#    along with this program; if not, write to the Free Software
17
 
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 
 
19
 
import patches
20
 
import os
21
 
import sys
22
 
import string
23
 
from bzrlib.commands import Command
24
 
 
25
 
def parse_args(args):
26
 
    if len(args) == 2 and args[1] == '--bzr-usage':
27
 
        print '\n'
28
 
        return True
29
 
    elif len(args) == 2 and args[1] == '--bzr-help':
30
 
        print 'Shelve a patch, you can get it back later with unshelve.'
31
 
        return True
32
 
    elif len(args) == 1:
33
 
        pass
34
 
    else:
35
 
        raise Exception("Don't understand args %s" % args)
36
 
 
37
 
    return False
38
 
 
39
 
def unshelve():
40
 
    root = run_bzr('root')[0].strip()
41
 
    shelf = os.path.join(root, '.bzr-shelf')
42
 
 
43
 
    if not os.path.exists(shelf):
44
 
        raise Exception("No shelf found in '%s'" % shelf)
45
 
 
46
 
    patch = open(shelf, 'r').read()
47
 
 
48
 
    print >>sys.stderr, "Reapplying shelved patches"
49
 
    pipe = os.popen('patch -d %s -s -p0' % root, 'w')
50
 
    pipe.write(patch)
51
 
    pipe.flush()
52
 
 
53
 
    if pipe.close() is not None:
54
 
        raise Exception("Failed running patch!")
55
 
 
56
 
    os.remove(shelf)
57
 
    print 'Diff status is now:'
58
 
    os.system('bzr diff | diffstat')
59
 
 
60
 
    return True
61
 
 
62
 
def shelve():
63
 
    diff_lines = run_bzr('diff')
64
 
    patch_list = patches.parse_patches(diff_lines.__iter__())
65
 
    to_shelve = prompt_user(patch_list)
66
 
 
67
 
    if len(to_shelve) == 0:
68
 
        print >>sys.stderr, 'Nothing to shelve'
69
 
        return True
70
 
 
71
 
    root = run_bzr('root')[0].strip()
72
 
    shelf = os.path.join(root, '.bzr-shelf')
73
 
    print >>sys.stderr, "Saving shelved patches to", shelf
74
 
    shelf = open(shelf, 'a')
75
 
 
76
 
    for patch in to_shelve:
77
 
        shelf.write(str(patch))
78
 
 
79
 
    shelf.flush()
80
 
    os.fsync(shelf.fileno())
81
 
    shelf.close()
82
 
 
83
 
    print >>sys.stderr, "Reverting shelved patches"
84
 
    pipe = os.popen('patch -d %s -sR -p0' % root, 'w')
85
 
    for patch in to_shelve:
86
 
       pipe.write(str(patch))
87
 
    pipe.flush()
88
 
 
89
 
    if pipe.close() is not None:
90
 
        raise Exception("Failed running patch!")
91
 
 
92
 
    print 'Diff status is now:'
93
 
    os.system('bzr diff | diffstat')
94
 
 
95
 
    return True
96
 
 
97
 
def run_bzr(args):
98
 
    if type(args) is str:
99
 
        args = [ args ]
100
 
    pipe = os.popen('bzr %s' % string.join(args, ' '), 'r')
101
 
    lines = pipe.readlines()
102
 
    if pipe.close() is not None:
103
 
        raise Exception("Failed running bzr")
104
 
    return lines
105
 
 
106
 
def prompt_user(patch_list):
107
 
    total = 0
108
 
    for patch in patch_list:
109
 
        total += len(patch.hunks)
110
 
 
111
 
    out = sys.stdout
112
 
    inp = sys.stdin
113
 
 
114
 
    to_shelve = []
115
 
    i = 1
116
 
    for patch in patch_list:
117
 
        if patch.oldname != patch.newname:
118
 
            name = "%s -> %s" % (patch.oldname, patch.newname)
119
 
        else:
120
 
            name = patch.oldname
121
 
 
122
 
        hunks = patch.hunks[:]
123
 
        for hunk in hunks:
124
 
            print name
125
 
            print hunk
126
 
            while True:
127
 
                out.write('Shelve this change? (%d of %d) [yn] ' % (i, total))
128
 
                line = inp.readline().strip().lower()
129
 
                if line == 'y' or line == 'yes':
130
 
                    break
131
 
                elif line == 'n' or line == 'no':
132
 
                    patch.hunks.remove(hunk)
133
 
                    break
134
 
 
135
 
            i += 1
136
 
 
137
 
        if len(patch.hunks) > 0:
138
 
            to_shelve.append(patch)
139
 
 
140
 
    return to_shelve
141
 
 
142
 
class cmd_shelve(Command):
143
 
    """Temporarily remove some changes from the current tree.
144
 
    Use 'unshelve' to restore these changes.
145
 
    """
146
 
 
147
 
    def run(self):
148
 
        return shelve()
149
 
 
150
 
class cmd_unshelve(Command):
151
 
    """Restore previously-shelved changes to the current tree.
152
 
    See also 'shelve'.
153
 
    """
154
 
    def run(self):
155
 
        return unshelve()