Skip to content

Commit 1069060

Browse files
committed
Allow goto-ing a sha1 hash (#93)
A partial sha1 hash may now be provided to `stg goto`. The sha1 must unambiguously map to a patch within the current branch. Signed-off-by: Peter Grayson <[email protected]>
1 parent 1005bd9 commit 1069060

File tree

4 files changed

+42
-26
lines changed

4 files changed

+42
-26
lines changed

stgit/commands/common.py

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -136,17 +136,6 @@ def print_current_patch(stack):
136136
out.info('No patches applied')
137137

138138

139-
def get_patch_from_list(part_name, patch_list):
140-
candidates = [full for full in patch_list if part_name in full]
141-
if len(candidates) >= 2:
142-
out.info('Possible patches:\n %s' % '\n '.join(candidates))
143-
raise CmdException('Ambiguous patch name "%s"' % part_name)
144-
elif len(candidates) == 1:
145-
return candidates[0]
146-
else:
147-
return None
148-
149-
150139
def parse_patches(patch_args, patch_list, boundary=0, ordered=False):
151140
"""Parse patch_args list for patch names in patch_list.
152141

stgit/commands/goto.py

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
import re
2+
13
from stgit import argparse
2-
from stgit.commands.common import (
3-
CmdException,
4-
DirectoryHasRepository,
5-
get_patch_from_list,
6-
)
4+
from stgit.commands.common import CmdException, DirectoryHasRepository
75
from stgit.lib import transaction
6+
from stgit.out import out
87

98
__copyright__ = """
109
Copyright (C) 2006, Catalin Marinas <[email protected]>
@@ -38,26 +37,35 @@
3837
def func(parser, options, args):
3938
if len(args) != 1:
4039
parser.error('incorrect number of arguments')
41-
patch = args[0]
40+
name = args[0]
4241

4342
stack = directory.repository.current_stack
4443
iw = stack.repository.default_iw
4544
clean_iw = (not options.keep and iw) or None
4645
trans = transaction.StackTransaction(stack, 'goto', check_clean_iw=clean_iw)
4746

48-
if patch not in trans.all_patches:
49-
candidate = get_patch_from_list(patch, trans.all_patches)
50-
if candidate is None:
51-
raise CmdException('Patch "%s" does not exist' % patch)
52-
patch = candidate
47+
if name not in trans.all_patches:
48+
candidates = [pn for pn in trans.all_patches if name in pn]
49+
if len(candidates) == 1:
50+
name = candidates[0]
51+
elif len(candidates) > 1:
52+
out.info('Possible patches:\n %s' % '\n '.join(candidates))
53+
raise CmdException('Ambiguous patch name "%s"' % name)
54+
elif re.match('[0-9A-Fa-f]{4,40}$', name):
55+
sha1 = name
56+
name = stack.patches.name_from_sha1(sha1)
57+
if not name:
58+
raise CmdException('No patch associated with %s' % sha1)
59+
else:
60+
raise CmdException('Patch "%s" does not exist' % name)
5361

54-
if patch in trans.applied:
55-
to_pop = set(trans.applied[trans.applied.index(patch) + 1 :])
62+
if name in trans.applied:
63+
to_pop = set(trans.applied[trans.applied.index(name) + 1 :])
5664
popped_extra = trans.pop_patches(lambda pn: pn in to_pop)
5765
assert not popped_extra
58-
elif patch in trans.unapplied:
66+
elif name in trans.unapplied:
5967
try:
60-
to_push = trans.unapplied[: trans.unapplied.index(patch) + 1]
68+
to_push = trans.unapplied[: trans.unapplied.index(name) + 1]
6169
if options.merged:
6270
merged = set(trans.check_merged(to_push))
6371
else:

stgit/lib/stack.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,17 @@ def exists(self, name):
151151
def get(self, name):
152152
return self._patches[name]
153153

154+
def name_from_sha1(self, partial_sha1):
155+
patch_ref_prefix = _patches_ref_prefix(self._stack.name)
156+
for ref in self._stack.repository.refs:
157+
if ref.startswith(patch_ref_prefix):
158+
patch_name = ref[len(patch_ref_prefix) :]
159+
patch = self.get(patch_name)
160+
if patch.commit.sha1.startswith(partial_sha1.lower()):
161+
return patch_name
162+
else:
163+
return None
164+
154165
def is_name_valid(self, name):
155166
if '/' in name:
156167
# TODO slashes in patch names could be made to be okay

t/t1700-goto.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,14 @@ test_expect_success 'Goto a patch' '
3838
test "$(echo $(stg series --unapplied --noprefix))" = "p4 p5"
3939
'
4040

41+
test_expect_success 'Goto by partial sha1' '
42+
stg goto "$(echo $(stg id p5) | test_copy_bytes 10)" &&
43+
test "$(echo $(stg series --applied --noprefix))" = "p1 p2 p3 p4 p5" &&
44+
stg goto "$(echo $(stg id p3))" &&
45+
test "$(echo $(stg series --applied --noprefix))" = "p1 p2 p3" &&
46+
test "$(echo $(stg series --unapplied --noprefix))" = "p4 p5"
47+
'
48+
4149
test_expect_success 'Refuse to go to a hidden patch' '
4250
stg new h0 -m "hidden patch" &&
4351
stg hide h0 &&

0 commit comments

Comments
 (0)