git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/7]
@ 2005-11-29 22:05 Chuck Lever
  2005-11-29 22:09 ` [PATCH 1/7] Make "stg export" save the base commit in the output directory Chuck Lever
                   ` (7 more replies)
  0 siblings, 8 replies; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:05 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

These are road-tested and ready for your review.

+ export-saves-base       | Make "stg export" save the base commit in the output directory
+ stg-in-subdirectories   | Use git-rev-parse to find the local GIT repository
+ fix-branch-description  | Align branch descriptions in output of "stg branch -l"
+ stg-series-description  | "stg series" option to show patch summary descriptions
+ stg-series-short        | Add facility to print short list of patches around 'top'
+ stg-branch-clone        | Add a "--clone" option to "stg branch"
> series-directory        | Use a separate directory for patches under each branch subdir

Before 0.8, you might also consider addressing the patch authorship issues
that come up when mailing out patches, as discussed on git@vger last week.

I've adjusted my patchmail.tmpl file as a workaround.

        -- Chuck Lever
--
corporate:    <cel at netapp dot com>
personal:     <chucklever at bigfoot dot com>

^ permalink raw reply	[flat|nested] 16+ messages in thread

* [PATCH 1/7] Make "stg export" save the base commit in the output directory
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-11-30 21:53   ` Catalin Marinas
  2005-11-29 22:09 ` [PATCH 2/7] Use git-rev-parse to find the local GIT repository Chuck Lever
                   ` (6 subsequent siblings)
  7 siblings, 1 reply; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

When trying to apply a series of diffs that was exported from an StGIT
series, it can be convenient to know exactly which base commit the
patches apply to.  Save that commit in a file patchdir/base.

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/commands/export.py |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/stgit/commands/export.py b/stgit/commands/export.py
index 0ef7d07..167a8d3 100644
--- a/stgit/commands/export.py
+++ b/stgit/commands/export.py
@@ -141,6 +141,10 @@ def func(parser, options, args):
             tmpl = file(patch_tmpl).read()
             break
 
+    # note the base commit for this series
+    write_string(os.path.join(dirname, 'base'), \
+                 crt_series.get_patch(patches[0]).get_bottom())
+
     patch_no = 1;
     for p in patches:
         pname = p

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 2/7] Use git-rev-parse to find the local GIT repository
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
  2005-11-29 22:09 ` [PATCH 1/7] Make "stg export" save the base commit in the output directory Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-11-29 22:09 ` [PATCH 3/7] Align branch descriptions in output of "stg branch -l" Chuck Lever
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

Use the latest git-rev-parse technology to allow some StGIT commands to
function correctly in subdirectories of the working directory.

Any command that relies on git-read-tree still doesn't work (changes to
GIT forthcoming).

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/commands/branch.py   |    2 +-
 stgit/commands/common.py   |    4 ++--
 stgit/commands/export.py   |    2 +-
 stgit/commands/mail.py     |    4 ++--
 stgit/commands/resolved.py |    4 ++--
 stgit/git.py               |   35 ++++++++++++++++++-----------------
 stgit/stack.py             |    9 +++++----
 7 files changed, 31 insertions(+), 29 deletions(-)

diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index 9bf6cdb..c3f7944 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -136,7 +136,7 @@ def func(parser, options, args):
         if len(args) != 0:
             parser.error('incorrect number of arguments')
 
-        branches = os.listdir(os.path.join(git.base_dir, 'refs', 'heads'))
+        branches = os.listdir(os.path.join(git.get_base_dir(), 'refs', 'heads'))
         branches.sort()
 
         print 'Available branches:'
diff --git a/stgit/commands/common.py b/stgit/commands/common.py
index e437111..8084cbd 100644
--- a/stgit/commands/common.py
+++ b/stgit/commands/common.py
@@ -96,7 +96,7 @@ def check_head_top_equal():
               '  are doing, use the "refresh -f" command'
 
 def check_conflicts():
-    if os.path.exists(os.path.join(git.base_dir, 'conflicts')):
+    if os.path.exists(os.path.join(git.get_base_dir(), 'conflicts')):
         raise CmdException, 'Unsolved conflicts. Please resolve them first'
 
 def print_crt_patch(branch = None):
@@ -130,7 +130,7 @@ def resolved_all(reset = None):
     if conflicts:
         for filename in conflicts:
             resolved(filename, reset)
-        os.remove(os.path.join(git.base_dir, 'conflicts'))
+        os.remove(os.path.join(git.get_base_dir(), 'conflicts'))
 
 def name_email(address):
     """Return a tuple consisting of the name and email parsed from a
diff --git a/stgit/commands/export.py b/stgit/commands/export.py
index 167a8d3..c93ab6e 100644
--- a/stgit/commands/export.py
+++ b/stgit/commands/export.py
@@ -132,7 +132,7 @@ def func(parser, options, args):
     else:
         patch_tmpl_list = []
 
-    patch_tmpl_list += [os.path.join(git.base_dir, 'patchexport.tmpl'),
+    patch_tmpl_list += [os.path.join(git.get_base_dir(), 'patchexport.tmpl'),
                         os.path.join(sys.prefix,
                                      'share/stgit/templates/patchexport.tmpl')]
     tmpl = ''
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 7cc18bc..b3b7b49 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -419,7 +419,7 @@ def func(parser, options, args):
         if options.cover:
             tfile_list = [options.cover]
         else:
-            tfile_list = [os.path.join(git.base_dir, 'covermail.tmpl'),
+            tfile_list = [os.path.join(git.get_base_dir(), 'covermail.tmpl'),
                           os.path.join(sys.prefix,
                                        'share/stgit/templates/covermail.tmpl')]
 
@@ -450,7 +450,7 @@ def func(parser, options, args):
     if options.template:
         tfile_list = [options.template]
     else:
-        tfile_list = [os.path.join(git.base_dir, 'patchmail.tmpl'),
+        tfile_list = [os.path.join(git.get_base_dir(), 'patchmail.tmpl'),
                       os.path.join(sys.prefix,
                                    'share/stgit/templates/patchmail.tmpl')]
     tmpl = None
diff --git a/stgit/commands/resolved.py b/stgit/commands/resolved.py
index d21ecc9..585c51b 100644
--- a/stgit/commands/resolved.py
+++ b/stgit/commands/resolved.py
@@ -65,8 +65,8 @@ def func(parser, options, args):
 
     # save or remove the conflicts file
     if conflicts == []:
-        os.remove(os.path.join(git.base_dir, 'conflicts'))
+        os.remove(os.path.join(git.get_base_dir(), 'conflicts'))
     else:
-        f = file(os.path.join(git.base_dir, 'conflicts'), 'w+')
+        f = file(os.path.join(git.get_base_dir(), 'conflicts'), 'w+')
         f.writelines([line + '\n' for line in conflicts])
         f.close()
diff --git a/stgit/git.py b/stgit/git.py
index b19f75f..2cedeaa 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -27,12 +27,6 @@ class GitException(Exception):
     pass
 
 
-# Different start-up variables read from the environment
-if 'GIT_DIR' in os.environ:
-    base_dir = os.environ['GIT_DIR']
-else:
-    base_dir = '.git'
-
 
 #
 # Classes
@@ -87,6 +81,15 @@ __commits = dict()
 #
 # Functions
 #
+
+def get_base_dir():
+    """Different start-up variables read from the environment
+    """
+    if 'GIT_DIR' in os.environ:
+        return os.environ['GIT_DIR']
+    else:
+        return _output_one_line('git-rev-parse --git-dir')
+
 def get_commit(id_hash):
     """Commit objects factory. Save/look-up them in the __commits
     dictionary
@@ -103,7 +106,7 @@ def get_commit(id_hash):
 def get_conflicts():
     """Return the list of file conflicts
     """
-    conflicts_file = os.path.join(base_dir, 'conflicts')
+    conflicts_file = os.path.join(get_base_dir(), 'conflicts')
     if os.path.isfile(conflicts_file):
         f = file(conflicts_file)
         names = [line.strip() for line in f.readlines()]
@@ -167,9 +170,6 @@ def __run(cmd, args=None):
         return r
     return 0
 
-def __check_base_dir():
-    return os.path.isdir(base_dir)
-
 def __tree_status(files = None, tree_id = 'HEAD', unknown = False,
                   noexclude = True):
     """Returns a list of pairs - [status, filename]
@@ -182,7 +182,7 @@ def __tree_status(files = None, tree_id 
 
     # unknown files
     if unknown:
-        exclude_file = os.path.join(base_dir, 'info', 'exclude')
+        exclude_file = os.path.join(get_base_dir(), 'info', 'exclude')
         base_exclude = ['--exclude=%s' % s for s in
                         ['*.[ao]', '*.pyc', '.*', '*~', '#*', 'TAGS', 'tags']]
         base_exclude.append('--exclude-per-directory=.gitignore')
@@ -296,8 +296,8 @@ def create_branch(new_branch, tree_id = 
     if tree_id:
         switch(tree_id)
 
-    if os.path.isfile(os.path.join(base_dir, 'MERGE_HEAD')):
-        os.remove(os.path.join(base_dir, 'MERGE_HEAD'))
+    if os.path.isfile(os.path.join(get_base_dir(), 'MERGE_HEAD')):
+        os.remove(os.path.join(get_base_dir(), 'MERGE_HEAD'))
 
 def switch_branch(name):
     """Switch to a git branch
@@ -316,8 +316,8 @@ def switch_branch(name):
         __head = tree_id
     set_head_file(new_head)
 
-    if os.path.isfile(os.path.join(base_dir, 'MERGE_HEAD')):
-        os.remove(os.path.join(base_dir, 'MERGE_HEAD'))
+    if os.path.isfile(os.path.join(get_base_dir(), 'MERGE_HEAD')):
+        os.remove(os.path.join(get_base_dir(), 'MERGE_HEAD'))
 
 def delete_branch(name):
     """Delete a git branch
@@ -325,7 +325,7 @@ def delete_branch(name):
     branch_head = os.path.join('refs', 'heads', name)
     if not branch_exists(branch_head):
         raise GitException, 'Branch "%s" does not exist' % name
-    os.remove(os.path.join(base_dir, branch_head))
+    os.remove(os.path.join(get_base_dir(), branch_head))
 
 def rename_branch(from_name, to_name):
     """Rename a git branch
@@ -339,7 +339,8 @@ def rename_branch(from_name, to_name):
 
     if get_head_file() == from_name:
         set_head_file(to_head)
-    os.rename(os.path.join(base_dir, from_head), os.path.join(base_dir, to_head))
+    os.rename(os.path.join(get_base_dir(), from_head), \
+              os.path.join(get_base_dir(), to_head))
 
 def add(names):
     """Add the files or recursively add the directory contents
diff --git a/stgit/stack.py b/stgit/stack.py
index 18b4c6e..dc7c19f 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -66,7 +66,7 @@ def __clean_comments(f):
 
 def edit_file(series, line, comment, show_patch = True):
     fname = '.stgit.msg'
-    tmpl = os.path.join(git.base_dir, 'patchdescr.tmpl')
+    tmpl = os.path.join(git.get_base_dir(), 'patchdescr.tmpl')
 
     f = file(fname, 'w+')
     if line:
@@ -263,9 +263,10 @@ class Series:
             self.__name = git.get_head_file()
 
         if self.__name:
-            self.__patch_dir = os.path.join(git.base_dir, 'patches',
+            base_dir = git.get_base_dir()
+            self.__patch_dir = os.path.join(base_dir, 'patches',
                                             self.__name)
-            self.__base_file = os.path.join(git.base_dir, 'refs', 'bases',
+            self.__base_file = os.path.join(base_dir, 'refs', 'bases',
                                             self.__name)
             self.__applied_file = os.path.join(self.__patch_dir, 'applied')
             self.__unapplied_file = os.path.join(self.__patch_dir, 'unapplied')
@@ -386,7 +387,7 @@ class Series:
     def init(self):
         """Initialises the stgit series
         """
-        bases_dir = os.path.join(git.base_dir, 'refs', 'bases')
+        bases_dir = os.path.join(git.get_base_dir(), 'refs', 'bases')
 
         if self.is_initialised():
             raise StackException, self.__patch_dir + ' already exists'

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 3/7] Align branch descriptions in output of "stg branch -l"
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
  2005-11-29 22:09 ` [PATCH 1/7] Make "stg export" save the base commit in the output directory Chuck Lever
  2005-11-29 22:09 ` [PATCH 2/7] Use git-rev-parse to find the local GIT repository Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-11-29 22:09 ` [PATCH 4/7] "stg series" option to show patch summary descriptions Chuck Lever
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

When printing branch descriptions, start descriptions in the same column.

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/commands/branch.py |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index c3f7944..ccf1f6b 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -63,7 +63,7 @@ options = [make_option('-c', '--create',
 def __is_current_branch(branch_name):
     return crt_series.get_branch() == branch_name
 
-def __print_branch(branch_name):
+def __print_branch(branch_name, length):
     initialized = ' '
     current = ' '
     protected = ' '
@@ -76,8 +76,8 @@ def __print_branch(branch_name):
         current = '>'
     if branch.get_protected():
         protected = 'p'
-    print '%s %s%s\t%s\t%s' % (current, initialized, protected, branch_name, \
-                               branch.get_description())
+    print current + ' ' + initialized + protected + '\t' + \
+          branch_name.ljust(length) + '  | ' + branch.get_description()
 
 def __delete_branch(doomed_name, force = False):
     doomed = stack.Series(doomed_name)
@@ -138,10 +138,11 @@ def func(parser, options, args):
 
         branches = os.listdir(os.path.join(git.get_base_dir(), 'refs', 'heads'))
         branches.sort()
+        max_len = max([len(i) for i in branches])
 
         print 'Available branches:'
         for i in branches:
-            __print_branch(i)
+            __print_branch(i, max_len)
         return
 
     elif options.protect:

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 4/7] "stg series" option to show patch summary descriptions
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
                   ` (2 preceding siblings ...)
  2005-11-29 22:09 ` [PATCH 3/7] Align branch descriptions in output of "stg branch -l" Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-11-29 22:09 ` [PATCH 5/7] Add facility to print short list of patches around 'top' Chuck Lever
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

Optionally show each patch's short description when listing a series.

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/commands/series.py |   48 +++++++++++++++++++++++++++++++---------------
 1 files changed, 32 insertions(+), 16 deletions(-)

diff --git a/stgit/commands/series.py b/stgit/commands/series.py
index 032b89e..a843307 100644
--- a/stgit/commands/series.py
+++ b/stgit/commands/series.py
@@ -33,12 +33,31 @@ prefixed with a '>'. Empty patches are p
 
 options = [make_option('-b', '--branch',
                        help = 'use BRANCH instead of the default one'),
+           make_option('-d', '--description',
+                       help = 'show a show description for each patch',
+                       action = 'store_true'),
            make_option('-e', '--empty',
                        help = 'check whether patches are empty '
                        '(much slower)',
                        action = 'store_true') ]
 
 
+def __get_description(patch):
+    """Extract and return a patch's short description
+    """
+    p = crt_series.get_patch(patch)
+    descr = p.get_description().strip()
+    descr_lines = descr.split('\n')
+    return descr_lines[0].rstrip()
+
+def __print_patch(patch, prefix, empty_prefix, length, options):
+    if options.empty and crt_series.empty_patch(patch):
+        prefix = empty_prefix
+    if options.description:
+        print prefix + patch.ljust(length) + '  | ' + __get_description(patch)
+    else:
+        print prefix + patch
+
 def func(parser, options, args):
     """Show the patch series
     """
@@ -46,21 +65,18 @@ def func(parser, options, args):
         parser.error('incorrect number of arguments')
 
     applied = crt_series.get_applied()
+    unapplied = crt_series.get_unapplied()
+    patches = applied + unapplied
+
+    max_len = 0
+    if len(patches) > 0:
+        max_len = max([len(i) for i in patches])
+
     if len(applied) > 0:
         for p in applied [0:-1]:
-            if options.empty and crt_series.empty_patch(p):
-                print '0', p
-            else:
-                print '+', p
-        p = applied[-1]
-
-        if options.empty and crt_series.empty_patch(p):
-            print '0>%s' % p
-        else:
-            print '> %s' % p
-
-    for p in crt_series.get_unapplied():
-        if options.empty and crt_series.empty_patch(p):
-            print '0', p
-        else:
-            print '-', p
+            __print_patch(p, '+ ', '0 ', max_len, options)
+
+        __print_patch(applied[-1], '> ', '0>', max_len, options)
+
+    for p in unapplied:
+        __print_patch(p, '- ', '0 ', max_len, options)

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 5/7] Add facility to print short list of patches around 'top'
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
                   ` (3 preceding siblings ...)
  2005-11-29 22:09 ` [PATCH 4/7] "stg series" option to show patch summary descriptions Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-11-29 22:09 ` [PATCH 6/7] Add a "--clone" option to "stg branch" Chuck Lever
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

When working in the middle of a very long series, I often find it useful
to have a list of the patches right around the current patch.  Add an
option to "stg series" called "--short" to provide this short list.

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/commands/series.py |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/stgit/commands/series.py b/stgit/commands/series.py
index a843307..ec1aaaf 100644
--- a/stgit/commands/series.py
+++ b/stgit/commands/series.py
@@ -39,6 +39,9 @@ options = [make_option('-b', '--branch',
            make_option('-e', '--empty',
                        help = 'check whether patches are empty '
                        '(much slower)',
+                       action = 'store_true'),
+           make_option('-s', '--short',
+                       help = 'list just the patches around the topmost patch',
                        action = 'store_true') ]
 
 
@@ -66,6 +69,13 @@ def func(parser, options, args):
 
     applied = crt_series.get_applied()
     unapplied = crt_series.get_unapplied()
+
+    if options.short:
+        if len(applied) > 5:
+            applied = applied[-6:]
+        if len(unapplied) > 5:
+            unapplied = unapplied[:5]
+
     patches = applied + unapplied
 
     max_len = 0

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 6/7] Add a "--clone" option to "stg branch"
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
                   ` (4 preceding siblings ...)
  2005-11-29 22:09 ` [PATCH 5/7] Add facility to print short list of patches around 'top' Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-12-01 21:05   ` Catalin Marinas
  2005-11-29 22:09 ` [PATCH 7/7] Use a separate directory for patches under each branch subdir Chuck Lever
  2005-11-30 22:27 ` [PATCH 0/7] Catalin Marinas
  7 siblings, 1 reply; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

Cloning a branch means creating a new branch and copying all of the
original branch's patches and its base to it.  Like creating a tag,
but this also preserves all the StGIT patches as well.

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/commands/branch.py |   28 +++++++++++++++++++++++++---
 stgit/stack.py           |   35 ++++++++++++++++++++++++++++++++++-
 2 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index ccf1f6b..5bc5e94 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -18,7 +18,7 @@ along with this program; if not, write t
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-import sys, os
+import sys, os, time
 from optparse import OptionParser, make_option
 
 from stgit.commands.common import *
@@ -29,10 +29,10 @@ from stgit import stack, git
 help = 'manage development branches'
 usage = """%prog [options] branch-name [commit-id]
 
-Create, list, switch between, rename, or delete development branches
+Create, clone, switch between, rename, or delete development branches
 within a git repository.  By default, a single branch called 'master'
 is always created in a new repository.  This subcommand allows you to
-manage several patch series in the same repository.
+manage several patch series in the same repository via GIT branches.
 
 When displaying the branches, the names can be prefixed with
 's' (StGIT managed) or 'p' (protected)."""
@@ -40,6 +40,9 @@ When displaying the branches, the names 
 options = [make_option('-c', '--create',
                        help = 'create a new development branch',
                        action = 'store_true'),
+           make_option('--clone',
+                       help = 'copy the contents of a branch',
+                       action = 'store_true'),
            make_option('--delete',
                        help = 'delete an existing development branch',
                        action = 'store_true'),
@@ -124,6 +127,25 @@ def func(parser, options, args):
         print 'Branch "%s" created.' % args[0]
         return
 
+    elif options.clone:
+
+        if len(args) == 0:
+            clone = crt_series.get_branch() + \
+                    time.strftime('-%C%y%m%d-%H%M%S')
+        elif len(args) == 1:
+            clone = args[0]
+        else:
+            parser.error('incorrect number of arguments')
+
+        check_local_changes()
+        check_conflicts()
+        check_head_top_equal()
+
+        print 'Cloning current branch to "%s"...' % clone
+        crt_series.clone(clone)
+        print 'done'
+        return
+
     elif options.delete:
 
         if len(args) != 1:
diff --git a/stgit/stack.py b/stgit/stack.py
index dc7c19f..2866121 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -18,7 +18,7 @@ along with this program; if not, write t
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
-import sys, os
+import sys, os, shutil
 
 from stgit.utils import *
 from stgit import git
@@ -420,6 +420,39 @@ class Series:
 
         self.__init__(to_name)
 
+    def clone(self, target_series):
+        """Clones a series
+        """
+        base = read_string(self.get_base_file())
+        git.create_branch(target_series, tree_id = base)
+        Series(target_series).init()
+
+        new_series = Series(target_series)
+
+        if os.path.exists(self.__descr_file):
+            shutil.copyfile(self.__descr_file, new_series.__descr_file)
+
+        for p in self.get_applied():
+            patch = self.get_patch(p)
+            new_series.new_patch(p, message = patch.get_description(),
+                                 can_edit = False, unapplied = True,
+                                 bottom = patch.get_bottom(),
+                                 top = patch.get_top(),
+                                 author_name = patch.get_authname(),
+                                 author_email = patch.get_authemail(),
+                                 author_date = patch.get_authdate())
+            modified = new_series.push_patch(p)
+
+        for p in self.get_unapplied():
+            patch = self.get_patch(p)
+            new_series.new_patch(p, message = patch.get_description(),
+                                 can_edit = False, unapplied = True,
+                                 bottom = patch.get_bottom(),
+                                 top = patch.get_top(),
+                                 author_name = patch.get_authname(),
+                                 author_email = patch.get_authemail(),
+                                 author_date = patch.get_authdate())
+
     def delete(self, force = False):
         """Deletes an stgit series
         """

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* [PATCH 7/7] Use a separate directory for patches under each branch subdir
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
                   ` (5 preceding siblings ...)
  2005-11-29 22:09 ` [PATCH 6/7] Add a "--clone" option to "stg branch" Chuck Lever
@ 2005-11-29 22:09 ` Chuck Lever
  2005-11-30 22:23   ` Catalin Marinas
  2005-11-30 22:27 ` [PATCH 0/7] Catalin Marinas
  7 siblings, 1 reply; 16+ messages in thread
From: Chuck Lever @ 2005-11-29 22:09 UTC (permalink / raw)
  To: catalin.marinas; +Cc: git

Currently you can't specify a patch name that matches the name of one of
the stgit special files under .git/patches/<branch-name>.  Let's use a
new subdirectory under .git/patches/<branch-name> to contain just the
patch directories to remove this limitation.

Signed-off-by: Chuck Lever <cel@netapp.com>
---

 stgit/stack.py |   24 +++++++++++++++---------
 1 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/stgit/stack.py b/stgit/stack.py
index 2866121..46b404c 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -264,14 +264,19 @@ class Series:
 
         if self.__name:
             base_dir = git.get_base_dir()
-            self.__patch_dir = os.path.join(base_dir, 'patches',
-                                            self.__name)
             self.__base_file = os.path.join(base_dir, 'refs', 'bases',
                                             self.__name)
-            self.__applied_file = os.path.join(self.__patch_dir, 'applied')
-            self.__unapplied_file = os.path.join(self.__patch_dir, 'unapplied')
-            self.__current_file = os.path.join(self.__patch_dir, 'current')
-            self.__descr_file = os.path.join(self.__patch_dir, 'description')
+            self.__series_dir = os.path.join(base_dir, 'patches',
+                                             self.__name)
+
+            self.__applied_file = os.path.join(self.__series_dir, 'applied')
+            self.__unapplied_file = os.path.join(self.__series_dir, 'unapplied')
+            self.__current_file = os.path.join(self.__series_dir, 'current')
+            self.__descr_file = os.path.join(self.__series_dir, 'description')
+
+            self.__patch_dir = os.path.join(self.__series_dir, 'patches')
+            if not os.path.isdir(self.__patch_dir):
+                self.__patch_dir = self.__series_dir
 
     def get_branch(self):
         """Return the branch name for the Series object
@@ -323,15 +328,15 @@ class Series:
         return self.__base_file
 
     def get_protected(self):
-        return os.path.isfile(os.path.join(self.__patch_dir, 'protected'))
+        return os.path.isfile(os.path.join(self.__series_dir, 'protected'))
 
     def protect(self):
-        protect_file = os.path.join(self.__patch_dir, 'protected')
+        protect_file = os.path.join(self.__series_dir, 'protected')
         if not os.path.isfile(protect_file):
             create_empty_file(protect_file)
 
     def unprotect(self):
-        protect_file = os.path.join(self.__patch_dir, 'protected')
+        protect_file = os.path.join(self.__series_dir, 'protected')
         if os.path.isfile(protect_file):
             os.remove(protect_file)
 
@@ -399,6 +404,7 @@ class Series:
         create_empty_file(self.__applied_file)
         create_empty_file(self.__unapplied_file)
         create_empty_file(self.__descr_file)
+        os.makedirs(os.path.join(self.__series_dir, 'patches'))
         self.__begin_stack_check()
 
     def rename(self, to_name):

^ permalink raw reply related	[flat|nested] 16+ messages in thread

* Re: [PATCH 1/7] Make "stg export" save the base commit in the output directory
  2005-11-29 22:09 ` [PATCH 1/7] Make "stg export" save the base commit in the output directory Chuck Lever
@ 2005-11-30 21:53   ` Catalin Marinas
  0 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2005-11-30 21:53 UTC (permalink / raw)
  To: Chuck Lever; +Cc: git

On 29/11/05, Chuck Lever <cel@netapp.com> wrote:
> When trying to apply a series of diffs that was exported from an StGIT
> series, it can be convenient to know exactly which base commit the
> patches apply to.  Save that commit in a file patchdir/base.

I would rather save it as a comment ('#' prefixed) in the series file.

--
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] Use a separate directory for patches under each branch subdir
  2005-11-29 22:09 ` [PATCH 7/7] Use a separate directory for patches under each branch subdir Chuck Lever
@ 2005-11-30 22:23   ` Catalin Marinas
  2005-11-30 22:28     ` Chuck Lever
  0 siblings, 1 reply; 16+ messages in thread
From: Catalin Marinas @ 2005-11-30 22:23 UTC (permalink / raw)
  To: Chuck Lever; +Cc: git

On 29/11/05, Chuck Lever <cel@netapp.com> wrote:
> Currently you can't specify a patch name that matches the name of one of
> the stgit special files under .git/patches/<branch-name>.  Let's use a
> new subdirectory under .git/patches/<branch-name> to contain just the
> patch directories to remove this limitation.

This patch doesn't fix the already created branches. It would be
useful to upgrade the branch structure automatically if the patches
directory is not found.

--
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 0/7]
  2005-11-29 22:05 [PATCH 0/7] Chuck Lever
                   ` (6 preceding siblings ...)
  2005-11-29 22:09 ` [PATCH 7/7] Use a separate directory for patches under each branch subdir Chuck Lever
@ 2005-11-30 22:27 ` Catalin Marinas
  7 siblings, 0 replies; 16+ messages in thread
From: Catalin Marinas @ 2005-11-30 22:27 UTC (permalink / raw)
  To: Chuck Lever; +Cc: git

On 29/11/05, Chuck Lever <cel@citi.umich.edu> wrote:
> + stg-in-subdirectories   | Use git-rev-parse to find the local GIT repository
> + fix-branch-description  | Align branch descriptions in output of "stg branch -l"
> + stg-series-description  | "stg series" option to show patch summary descriptions
> + stg-series-short        | Add facility to print short list of patches around 'top'

I applied the above patches.

> + stg-branch-clone        | Add a "--clone" option to "stg branch"

I'll comment on this tomorrow since I need to look at it in more
detail. One thing I would prefer is to be able to specify a name for
the newly cloned branch rather than generating one by default (which
can stay as well, as long as a 2nd argument with the name is not
given).

> Before 0.8, you might also consider addressing the patch authorship issues
> that come up when mailing out patches, as discussed on git@vger last week.

Yes, I will.

Thanks for the patches.

--
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] Use a separate directory for patches under each branch subdir
  2005-11-30 22:23   ` Catalin Marinas
@ 2005-11-30 22:28     ` Chuck Lever
  2005-11-30 22:32       ` Catalin Marinas
  0 siblings, 1 reply; 16+ messages in thread
From: Chuck Lever @ 2005-11-30 22:28 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 718 bytes --]

Catalin Marinas wrote:
> On 29/11/05, Chuck Lever <cel@netapp.com> wrote:
> 
>>Currently you can't specify a patch name that matches the name of one of
>>the stgit special files under .git/patches/<branch-name>.  Let's use a
>>new subdirectory under .git/patches/<branch-name> to contain just the
>>patch directories to remove this limitation.
> 
> 
> This patch doesn't fix the already created branches. It would be
> useful to upgrade the branch structure automatically if the patches
> directory is not found.

the reason i didn't do that is because i wanted to allow older versions 
of StGIT to continue to work on existing repositories.

what if i added a migration tool to allow a user to switch back and forth?

[-- Attachment #2: cel.vcf --]
[-- Type: text/x-vcard, Size: 439 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Charles
org:Network Appliance, Incorporated;Linux NFS Client Development
adr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA
email;internet:cel@citi.umich.edu
title:Member of Technical Staff
tel;work:+1 734 763 4415
tel;fax:+1 734 763 4434
tel;home:+1 734 668 1089
x-mozilla-html:FALSE
url:http://www.monkey.org/~cel/
version:2.1
end:vcard


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] Use a separate directory for patches under each branch subdir
  2005-11-30 22:28     ` Chuck Lever
@ 2005-11-30 22:32       ` Catalin Marinas
  2005-12-01  2:53         ` Chuck Lever
  0 siblings, 1 reply; 16+ messages in thread
From: Catalin Marinas @ 2005-11-30 22:32 UTC (permalink / raw)
  To: cel; +Cc: git

On 30/11/05, Chuck Lever <cel@citi.umich.edu> wrote:
> Catalin Marinas wrote:
> > This patch doesn't fix the already created branches. It would be
> > useful to upgrade the branch structure automatically if the patches
> > directory is not found.
>
> the reason i didn't do that is because i wanted to allow older versions
> of StGIT to continue to work on existing repositories.

You are right.

> what if i added a migration tool to allow a user to switch back and forth?

A separate stg command for this would be useful. Anyway since the
repository structure might change again in the future, I think it
would be better to have a version string saved somewhere in
.git/patches/version for reference.

--
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 7/7] Use a separate directory for patches under each branch subdir
  2005-11-30 22:32       ` Catalin Marinas
@ 2005-12-01  2:53         ` Chuck Lever
  0 siblings, 0 replies; 16+ messages in thread
From: Chuck Lever @ 2005-12-01  2:53 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 664 bytes --]

Catalin Marinas wrote:
> A separate stg command for this would be useful. Anyway since the
> repository structure might change again in the future, I think it
> would be better to have a version string saved somewhere in
> .git/patches/version for reference.

note that we have the same problem with .git/patches that this patch 
fixes in the .git/patches/<series> directories; namely, that if we add 
files in .git/patches, we can't have branches with the same names.

i was thinking of perhaps creating a .git/stgit subdirectory that might 
contain the config file, an stgit metadata version file, and perhaps any 
locally modified copies of the template files.

[-- Attachment #2: cel.vcf --]
[-- Type: text/x-vcard, Size: 439 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Charles
org:Network Appliance, Incorporated;Linux NFS Client Development
adr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA
email;internet:cel@citi.umich.edu
title:Member of Technical Staff
tel;work:+1 734 763-4415
tel;fax:+1 734 763 4434
tel;home:+1 734 668-1089
x-mozilla-html:FALSE
url:http://www.monkey.org/~cel/
version:2.1
end:vcard


^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] Add a "--clone" option to "stg branch"
  2005-11-29 22:09 ` [PATCH 6/7] Add a "--clone" option to "stg branch" Chuck Lever
@ 2005-12-01 21:05   ` Catalin Marinas
  2005-12-01 21:47     ` Chuck Lever
  0 siblings, 1 reply; 16+ messages in thread
From: Catalin Marinas @ 2005-12-01 21:05 UTC (permalink / raw)
  To: Chuck Lever; +Cc: git

On 29/11/05, Chuck Lever <cel@netapp.com> wrote:
> Cloning a branch means creating a new branch and copying all of the
> original branch's patches and its base to it.  Like creating a tag,
> but this also preserves all the StGIT patches as well.
[...]
> --- a/stgit/commands/branch.py
> +++ b/stgit/commands/branch.py
[...]
> +        print 'Cloning current branch to "%s"...' % clone

I would put a comma after this line and add sys.stdout.flush(). So
that 'done' is shown on the same line.

[...]
> --- a/stgit/stack.py
> +++ b/stgit/stack.py
[...]
> +    def clone(self, target_series):
> +        """Clones a series
> +        """

Wouldn't it be easier to do a recursive copy at the directory level
(.git/patches/<branch> into .git/patches/<clone> and
.git/refs/bases/<branch> into .git/refs/bases/<clone>)? Is there
anything that could go wrong if we do this?

--
Catalin

^ permalink raw reply	[flat|nested] 16+ messages in thread

* Re: [PATCH 6/7] Add a "--clone" option to "stg branch"
  2005-12-01 21:05   ` Catalin Marinas
@ 2005-12-01 21:47     ` Chuck Lever
  0 siblings, 0 replies; 16+ messages in thread
From: Chuck Lever @ 2005-12-01 21:47 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 2180 bytes --]

Catalin Marinas wrote:
> On 29/11/05, Chuck Lever <cel@netapp.com> wrote:
> 
>>Cloning a branch means creating a new branch and copying all of the
>>original branch's patches and its base to it.  Like creating a tag,
>>but this also preserves all the StGIT patches as well.
> 
> [...]
> 
>>--- a/stgit/commands/branch.py
>>+++ b/stgit/commands/branch.py
> 
> [...]
> 
>>+        print 'Cloning current branch to "%s"...' % clone
> 
> 
> I would put a comma after this line and add sys.stdout.flush(). So
> that 'done' is shown on the same line.

d'oh!  that's left over from when the Series.clone() method actually 
printed the name of each patch as it was cloning.  fixed.

> [...]
> 
>>--- a/stgit/stack.py
>>+++ b/stgit/stack.py
> 
> [...]
> 
>>+    def clone(self, target_series):
>>+        """Clones a series
>>+        """
> 
> 
> Wouldn't it be easier to do a recursive copy at the directory level
> (.git/patches/<branch> into .git/patches/<clone> and
> .git/refs/bases/<branch> into .git/refs/bases/<clone>)? Is there
> anything that could go wrong if we do this?

well, then you'd also clone any junk files that were left in there (for 
example, development notes).

also, by doing this a patch at a time, it gives the ability to hook in 
additional functionality in the future, in case we want to do something 
special to each newly cloned patch, like mechanically change the patch 
names, or automatically add some annotation, for example.

it also automatically converts an old-style branch (patches and series 
control files in same directory) to a new-style branch (patches in 
separate directory from series control files).

it follows the same basic pattern of logic as "stg pick".  cloning a 
branch is kind of like 'picking' all of it's patches into a new branch.

but finally (and most practically speaking), i hunted around for Python 
code to copy a directory hierarchy, and interestingly enough it looks 
about as complicated (or maybe more complicated) than the clone 
implementation i finally came up with, which is only about 30 lines.  i 
suppose we could just do a "os.system('cp -r yada yada')" but that's 
just lame  ;^)  and it only works on UNIX.

[-- Attachment #2: cel.vcf --]
[-- Type: text/x-vcard, Size: 445 bytes --]

begin:vcard
fn:Chuck Lever
n:Lever;Charles
org:Network Appliance, Incorporated;Open Source NFS Client Development
adr:535 West William Street, Suite 3100;;Center for Information Technology Integration;Ann Arbor;MI;48103-4943;USA
email;internet:cel@citi.umich.edu
title:Member of Technical Staff
tel;work:+1 734 763 4415
tel;fax:+1 734 763 4434
tel;home:+1 734 668 1089
x-mozilla-html:FALSE
url:http://www.monkey.org/~cel/
version:2.1
end:vcard


^ permalink raw reply	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2005-12-01 21:47 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-29 22:05 [PATCH 0/7] Chuck Lever
2005-11-29 22:09 ` [PATCH 1/7] Make "stg export" save the base commit in the output directory Chuck Lever
2005-11-30 21:53   ` Catalin Marinas
2005-11-29 22:09 ` [PATCH 2/7] Use git-rev-parse to find the local GIT repository Chuck Lever
2005-11-29 22:09 ` [PATCH 3/7] Align branch descriptions in output of "stg branch -l" Chuck Lever
2005-11-29 22:09 ` [PATCH 4/7] "stg series" option to show patch summary descriptions Chuck Lever
2005-11-29 22:09 ` [PATCH 5/7] Add facility to print short list of patches around 'top' Chuck Lever
2005-11-29 22:09 ` [PATCH 6/7] Add a "--clone" option to "stg branch" Chuck Lever
2005-12-01 21:05   ` Catalin Marinas
2005-12-01 21:47     ` Chuck Lever
2005-11-29 22:09 ` [PATCH 7/7] Use a separate directory for patches under each branch subdir Chuck Lever
2005-11-30 22:23   ` Catalin Marinas
2005-11-30 22:28     ` Chuck Lever
2005-11-30 22:32       ` Catalin Marinas
2005-12-01  2:53         ` Chuck Lever
2005-11-30 22:27 ` [PATCH 0/7] Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).