add "stash" subcommand - fix #1
This commit is contained in:
parent
40775d6d72
commit
ce8b679910
13
README
13
README
@ -50,6 +50,19 @@ Implemented subcommands:
|
|||||||
- with --status, prepended '*' for those with svn:needs-lock set
|
- with --status, prepended '*' for those with svn:needs-lock set
|
||||||
externals
|
externals
|
||||||
- print a list of the externals in the repository
|
- print a list of the externals in the repository
|
||||||
|
stash [command]
|
||||||
|
- allow temporarily saving changes to the working copy without committing
|
||||||
|
- the stashes behaves as a "stack" where "save" pushes a new stash object
|
||||||
|
and "pop" pops the newest one from the top of the stack
|
||||||
|
commands:
|
||||||
|
save (default if not specified):
|
||||||
|
- save changes as a "stash" object and revert them from working copy
|
||||||
|
- this currently only works with changes to already-versioned files
|
||||||
|
list:
|
||||||
|
- show a list of all stash objects
|
||||||
|
pop:
|
||||||
|
- apply the stash object back to the working copy
|
||||||
|
- the stash object is removed if it was successfully applied
|
||||||
|
|
||||||
The following subcommands are executed using their native handler, but
|
The following subcommands are executed using their native handler, but
|
||||||
have their output simplified and/or colorized:
|
have their output simplified and/or colorized:
|
||||||
|
82
jsvn
82
jsvn
@ -52,6 +52,19 @@
|
|||||||
# - with --status, prepended '*' for those with svn:needs-lock set
|
# - with --status, prepended '*' for those with svn:needs-lock set
|
||||||
# externals
|
# externals
|
||||||
# - print a list of the externals in the repository
|
# - print a list of the externals in the repository
|
||||||
|
# stash [command]
|
||||||
|
# - allow temporarily saving changes to the working copy without committing
|
||||||
|
# - the stashes behaves as a "stack" where "save" pushes a new stash object
|
||||||
|
# and "pop" pops the newest one from the top of the stack
|
||||||
|
# commands:
|
||||||
|
# save (default if not specified):
|
||||||
|
# - save changes as a "stash" object and revert them from working copy
|
||||||
|
# - this currently only works with changes to already-versioned files
|
||||||
|
# list:
|
||||||
|
# - show a list of all stash objects
|
||||||
|
# pop:
|
||||||
|
# - apply the stash object back to the working copy
|
||||||
|
# - the stash object is removed if it was successfully applied
|
||||||
#
|
#
|
||||||
# The following subcommands are executed using their native handler, but
|
# The following subcommands are executed using their native handler, but
|
||||||
# have their output simplified and/or colorized:
|
# have their output simplified and/or colorized:
|
||||||
@ -265,6 +278,13 @@ def getSVNRoot(svn):
|
|||||||
return '/'.join(parts[:i])
|
return '/'.join(parts[:i])
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
def get_svn_wc_root(svn):
|
||||||
|
for line in Popen([svn, 'info'], stdout=PIPE).communicate()[0].split('\n'):
|
||||||
|
m = re.match(r'Working Copy Root Path: (.*)$', line)
|
||||||
|
if m is not None:
|
||||||
|
return m.group(1)
|
||||||
|
return ''
|
||||||
|
|
||||||
def getSVNRelPath(svn):
|
def getSVNRelPath(svn):
|
||||||
url = getSVNURL(svn)
|
url = getSVNURL(svn)
|
||||||
parts = url.split('/')
|
parts = url.split('/')
|
||||||
@ -373,6 +393,32 @@ def descendant_path(child, parent):
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def get_stashes_dir(svn):
|
||||||
|
stashes_dir = get_svn_wc_root(svn) + '/.svn/stashes'
|
||||||
|
if not os.path.isdir(stashes_dir):
|
||||||
|
os.mkdir(stashes_dir)
|
||||||
|
return stashes_dir
|
||||||
|
|
||||||
|
def get_stash_ids(svn):
|
||||||
|
stashes_dir = get_stashes_dir(svn)
|
||||||
|
stash_files = os.listdir(stashes_dir)
|
||||||
|
stash_ids = {}
|
||||||
|
for sf in stash_files:
|
||||||
|
m = re.match('stash\.(\d+)$', sf)
|
||||||
|
if m is not None:
|
||||||
|
stash_ids[int(m.group(1))] = 1
|
||||||
|
return sorted(stash_ids.keys())
|
||||||
|
|
||||||
|
def get_stash_fname(svn, idx):
|
||||||
|
return get_stashes_dir(svn) + '/stash.%d' % idx
|
||||||
|
|
||||||
|
def get_next_stash_idx(svn):
|
||||||
|
stash_ids = get_stash_ids(svn)
|
||||||
|
idx = 1
|
||||||
|
if len(stash_ids) > 0:
|
||||||
|
idx = stash_ids[-1] + 1
|
||||||
|
return idx
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
# Subcommand Handlers #
|
# Subcommand Handlers #
|
||||||
###########################################################################
|
###########################################################################
|
||||||
@ -745,6 +791,41 @@ def externals(argv, svn, out):
|
|||||||
out.write(line[8:])
|
out.write(line[8:])
|
||||||
return RET_OK
|
return RET_OK
|
||||||
|
|
||||||
|
def stash(argv, svn, out):
|
||||||
|
action = 'save'
|
||||||
|
if len(argv) >= 2:
|
||||||
|
if not argv[1].startswith('-'):
|
||||||
|
action = argv[1]
|
||||||
|
if action == 'save':
|
||||||
|
stash_idx = get_next_stash_idx(svn)
|
||||||
|
stash_fname = get_stash_fname(svn, stash_idx)
|
||||||
|
fh = open(stash_fname, 'w')
|
||||||
|
Popen([svn, 'diff'], stdout=fh).wait()
|
||||||
|
fh.close()
|
||||||
|
Popen([svn, 'revert', '--depth=infinity', get_svn_wc_root(svn)],
|
||||||
|
stdout=PIPE).wait()
|
||||||
|
out.write('Created stash %d\n' % stash_idx)
|
||||||
|
elif action == 'list':
|
||||||
|
stash_ids = get_stash_ids(svn)
|
||||||
|
for si in reversed(stash_ids):
|
||||||
|
out.write('%d\n' % si)
|
||||||
|
elif action == 'pop':
|
||||||
|
stash_ids = get_stash_ids(svn)
|
||||||
|
if len(stash_ids) > 0:
|
||||||
|
stash_idx = stash_ids[-1]
|
||||||
|
stash_fname = get_stash_fname(svn, stash_idx)
|
||||||
|
rc = Popen([svn, 'patch', stash_fname]).wait()
|
||||||
|
if rc == 0:
|
||||||
|
os.unlink(stash_fname)
|
||||||
|
out.write('Popped stash %d\n' % stash_idx)
|
||||||
|
else:
|
||||||
|
out.write('Error popping stash %d\n' % stash_idx)
|
||||||
|
else:
|
||||||
|
out.write('No stashes to pop\n')
|
||||||
|
else:
|
||||||
|
out.write('Unknown action "%s"\n' % action)
|
||||||
|
return RET_OK
|
||||||
|
|
||||||
def root(argv, svn, out):
|
def root(argv, svn, out):
|
||||||
out.write(getSVNRoot(svn) + '\n')
|
out.write(getSVNRoot(svn) + '\n')
|
||||||
return RET_OK
|
return RET_OK
|
||||||
@ -797,6 +878,7 @@ def main(argv):
|
|||||||
'binaries': binaries,
|
'binaries': binaries,
|
||||||
'lockable': lockable,
|
'lockable': lockable,
|
||||||
'status': status,
|
'status': status,
|
||||||
|
'stash': stash,
|
||||||
}
|
}
|
||||||
|
|
||||||
do_normal_exec = True
|
do_normal_exec = True
|
||||||
|
Loading…
x
Reference in New Issue
Block a user