chiark / gitweb /
Implement a new patch identification scheme and id command
authorCatalin Marinas <catalin.marinas@gmail.com>
Thu, 21 Aug 2008 22:12:15 +0000 (23:12 +0100)
committerCatalin Marinas <catalin.marinas@gmail.com>
Thu, 21 Aug 2008 22:12:15 +0000 (23:12 +0100)
The new scheme allows '[<branch>:]<patch>' and '[<branch>:]{base}'
(the latter showing the base of a stack). You may append Git suffixes
like ^ and ^{...}.

Signed-off-by: Catalin Marinas <catalin.marinas@gmail.com>
stgit/commands/common.py
stgit/commands/id.py
stgit/lib/git.py
t/t0001-subdir-branches.sh
t/t1200-push-modified.sh
t/t1201-pull-trailing.sh
t/t2200-rebase.sh

index 029ec65fa6d3a56967bb85ba20d307f3a03a70bd..2994eb11a726da75f5e3d60e5b6d7c2289a88ee6 100644 (file)
@@ -28,6 +28,7 @@ from stgit.run import *
 from stgit import stack, git, basedir
 from stgit.config import config, file_extensions
 from stgit.lib import stack as libstack
 from stgit import stack, git, basedir
 from stgit.config import config, file_extensions
 from stgit.lib import stack as libstack
+from stgit.lib import git as libgit
 
 # Command exception class
 class CmdException(StgException):
 
 # Command exception class
 class CmdException(StgException):
@@ -116,6 +117,39 @@ def git_id(crt_series, rev):
 
     raise CmdException, 'Unknown patch or revision: %s' % rev
 
 
     raise CmdException, 'Unknown patch or revision: %s' % rev
 
+def git_commit(name, repository, branch = None):
+    """Return the a Commit object if 'name' is a patch name or Git commit.
+    The patch names allowed are in the form '<branch>:<patch>' and can
+    be followed by standard symbols used by git-rev-parse. If <patch>
+    is '{base}', it represents the bottom of the stack.
+    """
+    # Try a [branch:]patch name first
+    try:
+        branch, patch = name.split(':', 1)
+    except ValueError:
+        patch = name
+    if not branch:
+        branch = repository.current_branch_name
+
+    # The stack base
+    if patch.startswith('{base}'):
+        base_id = repository.get_stack(branch).base.sha1
+        return repository.rev_parse(base_id +
+                                    strip_prefix('{base}', patch))
+
+    # Other combination of branch and patch
+    try:
+        return repository.rev_parse('patches/%s/%s' % (branch, patch),
+                                    discard_stderr = True)
+    except libgit.RepositoryException:
+        pass
+
+    # Try a Git commit
+    try:
+        return repository.rev_parse(name, discard_stderr = True)
+    except libgit.RepositoryException:
+        raise CmdException('%s: Unknown patch or revision name' % name)
+
 def check_local_changes():
     if git.local_changes():
         raise CmdException('local changes in the tree. Use "refresh" or'
 def check_local_changes():
     if git.local_changes():
         raise CmdException('local changes in the tree. Use "refresh" or'
index 94b0229558b9cb471f0b8cd42442fd1bd1b16cb3..3819acc62b80aaf3a5ad13fd188bbaaefc679c5a 100644 (file)
@@ -15,28 +15,24 @@ along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-import sys, os
 from optparse import OptionParser, make_option
 
 from optparse import OptionParser, make_option
 
-from stgit.commands.common import *
-from stgit.utils import *
-from stgit.out import *
-from stgit import stack, git
-
+from stgit.out import out
+from stgit.commands import common
+from stgit.lib import stack
 
 help = 'print the GIT hash value of a StGIT reference'
 usage = """%prog [options] [id]
 
 
 help = 'print the GIT hash value of a StGIT reference'
 usage = """%prog [options] [id]
 
-Print the hash value of a GIT id (defaulting to HEAD). In addition to
-the standard GIT id's like heads and tags, this command also accepts
-'base[@<branch>]' and '[<patch>[@<branch>]][//[bottom | top]]'. If no
-'top' or 'bottom' are passed and <patch> is a valid patch name, 'top'
-will be used by default."""
-
-directory = DirectoryHasRepository()
-options = [make_option('-b', '--branch',
-                       help = 'use BRANCH instead of the default one')]
+Print the SHA1 value of a Git id (defaulting to HEAD). In addition to
+the standard Git id's like heads and tags, this command also accepts
+'[<branch>:]<patch>' and '[<branch>:]{base}' showing the id of a patch
+or the base of the stack. If no branch is specified, it defaults to the
+current one. The bottom of a patch is accessible with the
+'[<branch>:]<patch>^' format."""
 
 
+directory = common.DirectoryHasRepositoryLib()
+options = []
 
 def func(parser, options, args):
     """Show the applied patches
 
 def func(parser, options, args):
     """Show the applied patches
@@ -48,4 +44,4 @@ def func(parser, options, args):
     else:
         parser.error('incorrect number of arguments')
 
     else:
         parser.error('incorrect number of arguments')
 
-    out.stdout(git_id(crt_series, id_str))
+    out.stdout(common.git_commit(id_str, directory.repository).sha1)
index 3cafaec9afb569dabfccd1881cefee00c4350b47..c9d01192e135941439f8680ef243b052b2ee64ee 100644 (file)
@@ -572,11 +572,11 @@ class Repository(RunWithEnv):
     refs = property(lambda self: self.__refs)
     def cat_object(self, sha1):
         return self.run(['git', 'cat-file', '-p', sha1]).raw_output()
     refs = property(lambda self: self.__refs)
     def cat_object(self, sha1):
         return self.run(['git', 'cat-file', '-p', sha1]).raw_output()
-    def rev_parse(self, rev):
+    def rev_parse(self, rev, discard_stderr = False):
         try:
             return self.get_commit(self.run(
                     ['git', 'rev-parse', '%s^{commit}' % rev]
         try:
             return self.get_commit(self.run(
                     ['git', 'rev-parse', '%s^{commit}' % rev]
-                    ).output_one_line())
+                    ).discard_stderr(discard_stderr).output_one_line())
         except run.RunException:
             raise RepositoryException('%s: No such revision' % rev)
     def get_blob(self, sha1):
         except run.RunException:
             raise RepositoryException('%s: No such revision' % rev)
     def get_blob(self, sha1):
index 69c11a3e24dc7578adc62b04da77b4ae52f8df0a..3f7962ac13681b01aba91f923f24e9731345c1c6 100755 (executable)
@@ -18,25 +18,21 @@ test_expect_success 'Create a patch' \
    stg new foo -m "Add foo.txt" &&
    stg refresh'
 
    stg new foo -m "Add foo.txt" &&
    stg refresh'
 
-test_expect_success 'Old and new id with non-slashy branch' \
-  'stg id foo &&
-   stg id foo// &&
-   stg id foo/ &&
-   stg id foo//top &&
-   stg id foo/top &&
-   stg id foo@master &&
-   stg id foo@master//top &&
-   stg id foo@master/top'
+test_expect_success 'Try id with non-slashy branch' \
+  'stg id &&
+   stg id foo &&
+   stg id foo^ &&
+   stg id master:foo &&
+   stg id master:foo^'
 
 test_expect_success 'Clone branch to slashier name' \
   'stg branch --clone x/y/z'
 
 
 test_expect_success 'Clone branch to slashier name' \
   'stg branch --clone x/y/z'
 
-test_expect_success 'Try new form of id with slashy branch' \
+test_expect_success 'Try new id with slashy branch' \
   'stg id foo &&
   'stg id foo &&
-   stg id foo// &&
-   stg id foo//top &&
-   stg id foo@x/y/z &&
-   stg id foo@x/y/z//top'
+   stg id foo^ &&
+   stg id x/y/z:foo &&
+   stg id x/y/z:foo^'
 
 test_expect_success 'Try old id with slashy branch' '
    command_error stg id foo/ &&
 
 test_expect_success 'Try old id with slashy branch' '
    command_error stg id foo/ &&
index 6ebd0a1333dce2ad78e653c3616a697f7832c7c3..2edc76073c0ecf46b279fa25f5869a757191a300 100755 (executable)
@@ -36,7 +36,7 @@ test_expect_success \
     (
         cd foo &&
         GIT_DIR=../bar/.git git-format-patch --stdout \
     (
         cd foo &&
         GIT_DIR=../bar/.git git-format-patch --stdout \
-          $(cd ../bar && stg id base@master)..HEAD | git-am -3 -k
+          $(cd ../bar && stg id master:{base})..HEAD | git-am -3 -k
     )
 '
 
     )
 '
 
index 9d70fe02fcd499ae0c52602bb21a5af0ec18e47c..8a748737b4cab3b66ef3dffec18035645a8dd45d 100755 (executable)
@@ -30,7 +30,7 @@ test_expect_success \
     'Port those patches to orig tree' \
     '(cd foo &&
       GIT_DIR=../bar/.git git-format-patch --stdout \
     'Port those patches to orig tree' \
     '(cd foo &&
       GIT_DIR=../bar/.git git-format-patch --stdout \
-          $(cd ../bar && stg id base@master)..HEAD |
+          $(cd ../bar && stg id master:{base})..HEAD |
       git-am -3 -k
      )
     '
       git-am -3 -k
      )
     '
index a6f43bccd3f88239b5a8b50f051965b16e434e8e..256eaaa8d05f19fa6ee92dbbb67f86439c1ee6aa 100755 (executable)
@@ -27,7 +27,7 @@ test_expect_success \
        'Rebase to previous commit' \
        '
        stg rebase master~1 &&
        'Rebase to previous commit' \
        '
        stg rebase master~1 &&
-       test `stg id base@stack` = `git rev-parse master~1` &&
+       test `stg id stack:{base}` = `git rev-parse master~1` &&
        test `stg applied | wc -l` = 1
        '
 
        test `stg applied | wc -l` = 1
        '