{"thread":{"id":"43400","subject":"[PATCH 3/3] Create a StgitObject class to factorise code for property handling.","startedAt":"2006-11-30T00:23:04Z","lastAt":"2006-12-05T22:02:22Z","messageCount":6,"participants":["Yann Dirson","Catalin Marinas"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"295386","messageId":"20061130002304.21981.67797.stgit@gandelf.nowhere.earth","threadId":"43400","inReplyTo":null,"subject":"[PATCH 0/3] Misc stgit patches","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2006-11-30T00:23:04Z","receivedAt":"2006-11-30T00:23:04Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"One of the following patches contains a pretty substantial change to stack.py to help\nadding new stored properties to a Series just like it is done for a Patch.  It was\nexpected to be the first in a series for storing branch parent information, but as you\nmay have read already, it's not for today :)\n\n-- \nYann Dirson    <ydirson@altern.org> |\nDebian-related: <dirson@debian.org> |   Support Debian GNU/Linux:\n                                    |  Freedom, Power, Stability, Gratis\n"},{"id":"298515","messageId":"20061130002717.21981.38049.stgit@gandelf.nowhere.earth","threadId":"43400","inReplyTo":"20061130002304.21981.67797.stgit@gandelf.nowhere.earth","subject":"[PATCH 1/3] Document some current bugs and add to the TODO list.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2006-11-30T00:27:17Z","receivedAt":"2006-11-30T00:27:17Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n TODO |   51 +++++++++++++++++++++++++++++++++++++++++++++++++++\n 1 files changed, 51 insertions(+), 0 deletions(-)\n\ndiff --git a/TODO b/TODO\nindex 6f7a132..ad02a0e 100644\n--- a/TODO\n+++ b/TODO\n@@ -26,3 +26,54 @@ The future, when time allows or if someone else does them:\n - patch synchronisation between between branches (as some people,\n   including me have the same patches based on different branches and\n   they have scripts for moving the changes in one to the others)\n+- numeric shortcuts for naming patches near top (eg. +1, -2)\n+- (config?) parameter for number of patches included by \"series -s\"\n+- refuse to \"stg init\" a branch known as remote (through .git/remotes/,\n+  .git/branches/ or any other info)\n+\n+Bugs:\n+\n+- cannot use \"stg refresh file\" after \"cg-rm file\"\n+- patch names with spaces are accepted by \"stg new\" but break \"stg series -d\"\n+- \"stg goto $(stg top)\" fails with unhandled exception\n+- at least \"commit is not robust wrt out-of-diskspace condition:\n+|deps$ stg commit\n+|error: git-checkout-index: unable to write file MANIFEST\n+|error: git-checkout-index: unable to write file META.yml\n+|error: git-checkout-index: unable to write file Makefile.PL\n+|error: git-checkout-index: unable to write file doc/README.dbk.xml\n+|error: git-checkout-index: unable to write file graph-includes\n+|error: git-checkout-index: unable to write file lib/graphincludes/params.pm\n+|fatal: unable to write new index file\n+|stg commit: git-read-tree failed (local changes maybe?)\n+|Committing 4 patches...\n+(luckily nothing was really committed)\n+\n+- cannot branch off arbitrary branch when current branch not under\n+stgit control:\n+|$ stg branch \n+|bar\n+|$ stg branch -c foo2 foo\n+|stg branch: Branch \"bar\" not initialised\n+\n+- patch created with empty description (\"stg new\" and quit editor\n+without saving) confuse \"series -d\":\n+|$ stg series -ds\n+|+ p5  | p5\n+|Traceback (most recent call last):\n+|  File \"/usr/bin/stg\", line 43, in ?\n+|    main()\n+|  File \"/var/lib/python-support/python2.4/stgit/main.py\", line 261, in main\n+|    command.func(parser, options, args)\n+|  File \"/var/lib/python-support/python2.4/stgit/commands/series.py\", line 107, in func\n+|    __print_patch(applied[-1], '> ', '0>', max_len, options)\n+|  File \"/var/lib/python-support/python2.4/stgit/commands/series.py\", line 63, in __print_patch\n+|    print prefix + patch.ljust(length) + '  | ' + __get_description(patch)\n+|  File \"/var/lib/python-support/python2.4/stgit/commands/series.py\", line 55, in __get_description\n+|    descr = p.get_description().strip()\n+|AttributeError: 'NoneType' object has no attribute 'strip'\n+|dwitch@gandelf:/export/work/yann/git/foo/a$ stg series\n+|+ p5\n+|> y\n+|$ cat .git/patches/master/patches/y/description\n"},{"id":"296908","messageId":"20061130002723.21981.11262.stgit@gandelf.nowhere.earth","threadId":"43400","inReplyTo":"20061130002304.21981.67797.stgit@gandelf.nowhere.earth","subject":"[PATCH 2/3] More config examples.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2006-11-30T00:27:23Z","receivedAt":"2006-11-30T00:27:23Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\n\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n examples/stgitrc |    1 +\n 1 files changed, 1 insertions(+), 0 deletions(-)\n\ndiff --git a/examples/stgitrc b/examples/stgitrc\nindex cc6e910..9ed2988 100644\n--- a/examples/stgitrc\n+++ b/examples/stgitrc\n@@ -32,6 +32,7 @@\n \n # this value overrides the default PAGER environment variable\n #pager: ~/share/stgit/contrib/diffcol.sh\n+#pager: filterdiff --annotate | colordiff | less -FRX\n \n # GIT pull command (should take the same arguments as git-pull)\n"},{"id":"294627","messageId":"20061130002728.21981.59782.stgit@gandelf.nowhere.earth","threadId":"43400","inReplyTo":"20061130002304.21981.67797.stgit@gandelf.nowhere.earth","subject":"[PATCH 3/3] Create a StgitObject class to factorise code for property handling.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2006-11-30T00:27:28Z","receivedAt":"2006-11-30T00:27:28Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"\nThis change makes it easier to add new stored fields to the Series object,\nwithout having to duplicate existing code from Patch.\n\nGeneric field accessors were taken from the Patch class.  Dir accessors\nwere added to avoid making the __dir attribute public, and were used\nto replace Series::__series_dir (that name was a bit redundant anyway).\nCreate_empty_field came as a natural addition to factorise more code.\n\nSigned-off-by: Yann Dirson <ydirson@altern.org>\n---\n\n stgit/stack.py |  198 +++++++++++++++++++++++++++++---------------------------\n 1 files changed, 103 insertions(+), 95 deletions(-)\n\ndiff --git a/stgit/stack.py b/stgit/stack.py\nindex 8fa3846..8cd632e 100644\n--- a/stgit/stack.py\n+++ b/stgit/stack.py\n@@ -119,27 +119,58 @@ def edit_file(series, line, comment, show_patch = True):\n # Classes\n #\n \n-class Patch:\n+class StgitObject:\n+    \"\"\"An object with stgit-like properties stored as files in a directory\n+    \"\"\"\n+    def _set_dir(self, dir):\n+        self.__dir = dir\n+    def dir(self):\n+        return self.__dir\n+\n+    def create_empty_field(self, name):\n+        print \"Creating '%s'\" % os.path.join(self.__dir, name)\n+        create_empty_file(os.path.join(self.__dir, name))\n+\n+    def _get_field(self, name, multiline = False):\n+        id_file = os.path.join(self.__dir, name)\n+        if os.path.isfile(id_file):\n+            line = read_string(id_file, multiline)\n+            if line == '':\n+                return None\n+            else:\n+                return line\n+        else:\n+            return None\n+\n+    def _set_field(self, name, value, multiline = False):\n+        fname = os.path.join(self.__dir, name)\n+        if value and value != '':\n+            write_string(fname, value, multiline)\n+        elif os.path.isfile(fname):\n+            os.remove(fname)\n+\n+    \n+class Patch(StgitObject):\n     \"\"\"Basic patch implementation\n     \"\"\"\n     def __init__(self, name, series_dir, refs_dir):\n         self.__series_dir = series_dir\n         self.__name = name\n-        self.__dir = os.path.join(self.__series_dir, self.__name)\n+        self._set_dir(os.path.join(self.__series_dir, self.__name))\n         self.__refs_dir = refs_dir\n         self.__top_ref_file = os.path.join(self.__refs_dir, self.__name)\n         self.__log_ref_file = os.path.join(self.__refs_dir,\n                                            self.__name + '.log')\n \n     def create(self):\n-        os.mkdir(self.__dir)\n-        create_empty_file(os.path.join(self.__dir, 'bottom'))\n-        create_empty_file(os.path.join(self.__dir, 'top'))\n+        os.mkdir(self.dir())\n+        self.create_empty_field('bottom')\n+        self.create_empty_field('top')\n \n     def delete(self):\n-        for f in os.listdir(self.__dir):\n-            os.remove(os.path.join(self.__dir, f))\n-        os.rmdir(self.__dir)\n+        for f in os.listdir(self.dir()):\n+            os.remove(os.path.join(self.dir(), f))\n+        os.rmdir(self.dir())\n         os.remove(self.__top_ref_file)\n         if os.path.exists(self.__log_ref_file):\n             os.remove(self.__log_ref_file)\n@@ -148,16 +179,16 @@ class Patch:\n         return self.__name\n \n     def rename(self, newname):\n-        olddir = self.__dir\n+        olddir = self.dir()\n         old_top_ref_file = self.__top_ref_file\n         old_log_ref_file = self.__log_ref_file\n         self.__name = newname\n-        self.__dir = os.path.join(self.__series_dir, self.__name)\n+        self._set_dir(os.path.join(self.__series_dir, self.__name))\n         self.__top_ref_file = os.path.join(self.__refs_dir, self.__name)\n         self.__log_ref_file = os.path.join(self.__refs_dir,\n                                            self.__name + '.log')\n \n-        os.rename(olddir, self.__dir)\n+        os.rename(olddir, self.dir())\n         os.rename(old_top_ref_file, self.__top_ref_file)\n         if os.path.exists(old_log_ref_file):\n             os.rename(old_log_ref_file, self.__log_ref_file)\n@@ -173,69 +204,51 @@ class Patch:\n         if top:\n             self.__update_top_ref(top)\n \n-    def __get_field(self, name, multiline = False):\n-        id_file = os.path.join(self.__dir, name)\n-        if os.path.isfile(id_file):\n-            line = read_string(id_file, multiline)\n-            if line == '':\n-                return None\n-            else:\n-                return line\n-        else:\n-            return None\n-\n-    def __set_field(self, name, value, multiline = False):\n-        fname = os.path.join(self.__dir, name)\n-        if value and value != '':\n-            write_string(fname, value, multiline)\n-        elif os.path.isfile(fname):\n-            os.remove(fname)\n-\n     def get_old_bottom(self):\n-        return self.__get_field('bottom.old')\n+        return self._get_field('bottom.old')\n \n     def get_bottom(self):\n-        return self.__get_field('bottom')\n+        return self._get_field('bottom')\n \n     def set_bottom(self, value, backup = False):\n         if backup:\n-            curr = self.__get_field('bottom')\n-            self.__set_field('bottom.old', curr)\n-        self.__set_field('bottom', value)\n+            curr = self._get_field('bottom')\n+            self._set_field('bottom.old', curr)\n+        self._set_field('bottom', value)\n \n     def get_old_top(self):\n-        return self.__get_field('top.old')\n+        return self._get_field('top.old')\n \n     def get_top(self):\n-        return self.__get_field('top')\n+        return self._get_field('top')\n \n     def set_top(self, value, backup = False):\n         if backup:\n-            curr = self.__get_field('top')\n-            self.__set_field('top.old', curr)\n-        self.__set_field('top', value)\n+            curr = self._get_field('top')\n+            self._set_field('top.old', curr)\n+        self._set_field('top', value)\n         self.__update_top_ref(value)\n \n     def restore_old_boundaries(self):\n-        bottom = self.__get_field('bottom.old')\n-        top = self.__get_field('top.old')\n+        bottom = self._get_field('bottom.old')\n+        top = self._get_field('top.old')\n \n         if top and bottom:\n-            self.__set_field('bottom', bottom)\n-            self.__set_field('top', top)\n+            self._set_field('bottom', bottom)\n+            self._set_field('top', top)\n             self.__update_top_ref(top)\n             return True\n         else:\n             return False\n \n     def get_description(self):\n-        return self.__get_field('description', True)\n+        return self._get_field('description', True)\n \n     def set_description(self, line):\n-        self.__set_field('description', line, True)\n+        self._set_field('description', line, True)\n \n     def get_authname(self):\n-        return self.__get_field('authname')\n+        return self._get_field('authname')\n \n     def set_authname(self, name):\n         if not name:\n@@ -243,10 +256,10 @@ class Patch:\n                 name = config.get('stgit', 'authname')\n             elif 'GIT_AUTHOR_NAME' in os.environ:\n                 name = os.environ['GIT_AUTHOR_NAME']\n-        self.__set_field('authname', name)\n+        self._set_field('authname', name)\n \n     def get_authemail(self):\n-        return self.__get_field('authemail')\n+        return self._get_field('authemail')\n \n     def set_authemail(self, address):\n         if not address:\n@@ -254,18 +267,18 @@ class Patch:\n                 address = config.get('stgit', 'authemail')\n             elif 'GIT_AUTHOR_EMAIL' in os.environ:\n                 address = os.environ['GIT_AUTHOR_EMAIL']\n-        self.__set_field('authemail', address)\n+        self._set_field('authemail', address)\n \n     def get_authdate(self):\n-        return self.__get_field('authdate')\n+        return self._get_field('authdate')\n \n     def set_authdate(self, date):\n         if not date and 'GIT_AUTHOR_DATE' in os.environ:\n             date = os.environ['GIT_AUTHOR_DATE']\n-        self.__set_field('authdate', date)\n+        self._set_field('authdate', date)\n \n     def get_commname(self):\n-        return self.__get_field('commname')\n+        return self._get_field('commname')\n \n     def set_commname(self, name):\n         if not name:\n@@ -273,10 +286,10 @@ class Patch:\n                 name = config.get('stgit', 'commname')\n             elif 'GIT_COMMITTER_NAME' in os.environ:\n                 name = os.environ['GIT_COMMITTER_NAME']\n-        self.__set_field('commname', name)\n+        self._set_field('commname', name)\n \n     def get_commemail(self):\n-        return self.__get_field('commemail')\n+        return self._get_field('commemail')\n \n     def set_commemail(self, address):\n         if not address:\n@@ -284,17 +297,17 @@ class Patch:\n                 address = config.get('stgit', 'commemail')\n             elif 'GIT_COMMITTER_EMAIL' in os.environ:\n                 address = os.environ['GIT_COMMITTER_EMAIL']\n-        self.__set_field('commemail', address)\n+        self._set_field('commemail', address)\n \n     def get_log(self):\n-        return self.__get_field('log')\n+        return self._get_field('log')\n \n     def set_log(self, value, backup = False):\n-        self.__set_field('log', value)\n+        self._set_field('log', value)\n         self.__update_log_ref(value)\n \n \n-class Series:\n+class Series(StgitObject):\n     \"\"\"Class including the operations on series\n     \"\"\"\n     def __init__(self, name = None):\n@@ -309,22 +322,21 @@ class Series:\n         except git.GitException, ex:\n             raise StackException, 'GIT tree not initialised: %s' % ex\n \n-        self.__series_dir = os.path.join(self.__base_dir, 'patches',\n-                                         self.__name)\n+        self._set_dir(os.path.join(self.__base_dir, 'patches', self.__name))\n         self.__refs_dir = os.path.join(self.__base_dir, 'refs', 'patches',\n                                        self.__name)\n         self.__base_file = os.path.join(self.__base_dir, 'refs', 'bases',\n                                         self.__name)\n \n-        self.__applied_file = os.path.join(self.__series_dir, 'applied')\n-        self.__unapplied_file = os.path.join(self.__series_dir, 'unapplied')\n-        self.__current_file = os.path.join(self.__series_dir, 'current')\n-        self.__descr_file = os.path.join(self.__series_dir, 'description')\n+        self.__applied_file = os.path.join(self.dir(), 'applied')\n+        self.__unapplied_file = os.path.join(self.dir(), 'unapplied')\n+        self.__current_file = os.path.join(self.dir(), 'current')\n+        self.__descr_file = os.path.join(self.dir(), 'description')\n \n         # where this series keeps its patches\n-        self.__patch_dir = os.path.join(self.__series_dir, 'patches')\n+        self.__patch_dir = os.path.join(self.dir(), 'patches')\n         if not os.path.isdir(self.__patch_dir):\n-            self.__patch_dir = self.__series_dir\n+            self.__patch_dir = self.dir()\n \n         # if no __refs_dir, create and populate it (upgrade old repositories)\n         if self.is_initialised() and not os.path.isdir(self.__refs_dir):\n@@ -333,7 +345,7 @@ class Series:\n                 self.get_patch(patch).update_top_ref()\n \n         # trash directory\n-        self.__trash_dir = os.path.join(self.__series_dir, 'trash')\n+        self.__trash_dir = os.path.join(self.dir(), 'trash')\n         if self.is_initialised() and not os.path.isdir(self.__trash_dir):\n             os.makedirs(self.__trash_dir)\n \n@@ -345,10 +357,7 @@ class Series:\n     def __set_current(self, name):\n         \"\"\"Sets the topmost patch\n         \"\"\"\n-        if name:\n-            write_string(self.__current_file, name)\n-        else:\n-            create_empty_file(self.__current_file)\n+        self._set_field('current', name)\n \n     def get_patch(self, name):\n         \"\"\"Return a Patch object for the given name\n@@ -366,10 +375,7 @@ class Series:\n     def get_current(self):\n         \"\"\"Return the name of the topmost patch, or None if there is\n         no such patch.\"\"\"\n-        if os.path.isfile(self.__current_file):\n-            name = read_string(self.__current_file)\n-        else:\n-            return None\n+        name = self._get_field('current')\n         if name == '':\n             return None\n         else:\n@@ -396,26 +402,26 @@ class Series:\n         return self.__base_file\n \n     def get_protected(self):\n-        return os.path.isfile(os.path.join(self.__series_dir, 'protected'))\n+        return os.path.isfile(os.path.join(self.dir(), 'protected'))\n \n     def protect(self):\n-        protect_file = os.path.join(self.__series_dir, 'protected')\n+        protect_file = os.path.join(self.dir(), 'protected')\n         if not os.path.isfile(protect_file):\n             create_empty_file(protect_file)\n \n     def unprotect(self):\n-        protect_file = os.path.join(self.__series_dir, 'protected')\n+        protect_file = os.path.join(self.dir(), 'protected')\n         if os.path.isfile(protect_file):\n             os.remove(protect_file)\n \n     def get_description(self):\n-        if os.path.isfile(self.__descr_file):\n-            return read_string(self.__descr_file)\n-        else:\n-            return ''\n+        return self._get_field('description')\n+\n+    def set_description(self, line):\n+        self._set_field('description', line)\n \n     def __patch_is_current(self, patch):\n-        return patch.get_name() == read_string(self.__current_file)\n+        return patch.get_name() == self.get_current()\n \n     def patch_applied(self, name):\n         \"\"\"Return true if the patch exists in the applied list\n@@ -481,10 +487,10 @@ class Series:\n \n         create_dirs(bases_dir)\n \n-        create_empty_file(self.__applied_file)\n-        create_empty_file(self.__unapplied_file)\n-        create_empty_file(self.__descr_file)\n-        os.makedirs(os.path.join(self.__series_dir, 'patches'))\n+        self.create_empty_field('applied')\n+        self.create_empty_field('unapplied')\n+        self.create_empty_field('description')\n+        os.makedirs(os.path.join(self.dir(), 'patches'))\n         os.makedirs(self.__refs_dir)\n         self.__begin_stack_check()\n \n@@ -493,15 +499,15 @@ class Series:\n         unconvert to place the patches in the same directory with\n         series control files\n         \"\"\"\n-        if self.__patch_dir == self.__series_dir:\n+        if self.__patch_dir == self.dir():\n             print 'Converting old-style to new-style...',\n             sys.stdout.flush()\n \n-            self.__patch_dir = os.path.join(self.__series_dir, 'patches')\n+            self.__patch_dir = os.path.join(self.dir(), 'patches')\n             os.makedirs(self.__patch_dir)\n \n             for p in self.get_applied() + self.get_unapplied():\n-                src = os.path.join(self.__series_dir, p)\n+                src = os.path.join(self.dir(), p)\n                 dest = os.path.join(self.__patch_dir, p)\n                 os.rename(src, dest)\n \n@@ -513,7 +519,7 @@ class Series:\n \n             for p in self.get_applied() + self.get_unapplied():\n                 src = os.path.join(self.__patch_dir, p)\n-                dest = os.path.join(self.__series_dir, p)\n+                dest = os.path.join(self.dir(), p)\n                 os.rename(src, dest)\n \n             if not os.listdir(self.__patch_dir):\n@@ -522,7 +528,7 @@ class Series:\n             else:\n                 print 'Patch directory %s is not empty.' % self.__name\n \n-            self.__patch_dir = self.__series_dir\n+            self.__patch_dir = self.dir()\n \n     def rename(self, to_name):\n         \"\"\"Renames a series\n@@ -536,7 +542,7 @@ class Series:\n \n         git.rename_branch(self.__name, to_name)\n \n-        if os.path.isdir(self.__series_dir):\n+        if os.path.isdir(self.dir()):\n             rename(os.path.join(self.__base_dir, 'patches'),\n                    self.__name, to_stack.__name)\n         if os.path.exists(self.__base_file):\n@@ -556,7 +562,7 @@ class Series:\n         new_series = Series(target_series)\n \n         # generate an artificial description file\n-        write_string(new_series.__descr_file, 'clone of \"%s\"' % self.__name)\n+        new_series.set_description('clone of \"%s\"' % self.__name)\n \n         # clone self's entire series as unapplied patches\n         patches = self.get_applied() + self.get_unapplied()\n@@ -590,6 +596,8 @@ class Series:\n                 os.remove(fname)\n             os.rmdir(self.__trash_dir)\n \n+            # FIXME: find a way to get rid of those manual removals\n+            # (move functionnality to StgitObject ?)\n             if os.path.exists(self.__applied_file):\n                 os.remove(self.__applied_file)\n             if os.path.exists(self.__unapplied_file):\n@@ -602,7 +610,7 @@ class Series:\n                 os.rmdir(self.__patch_dir)\n             else:\n                 print 'Patch directory %s is not empty.' % self.__name\n-            if not os.listdir(self.__series_dir):\n+            if not os.listdir(self.dir()):\n                 remove_dirs(os.path.join(self.__base_dir, 'patches'),\n                             self.__name)\n"},{"id":"295784","messageId":"b0943d9e0612050930t187e65c4g6a3c44ea1fefc940@mail.gmail.com","threadId":"43400","inReplyTo":"20061130002717.21981.38049.stgit@gandelf.nowhere.earth","subject":"Re: [PATCH 1/3] Document some current bugs and add to the TODO list.","fromName":"Catalin Marinas","fromEmail":"catalin.marinas@gmail.com","sentAt":"2006-12-05T17:30:56Z","receivedAt":"2006-12-05T17:30:56Z","isPatch":true,"sender":{"key":"catalin.marinas@gmail.com","avatar":null},"body":"Hi Yann,\n\nSee some comments below (I removed those which I am OK with or I fixed).\n\nOn 30/11/06, Yann Dirson <ydirson@altern.org> wrote:\n> +- numeric shortcuts for naming patches near top (eg. +1, -2)\n\nWe currently have the -n option for push and pop that accepts number.\nBecause of python, you can also, for example, push to the last but one\nwith \"push -n -1\" (similar for pop). Do you mean shortcuts for the\n\"goto\" command?\n\n> +- refuse to \"stg init\" a branch known as remote (through .git/remotes/,\n> +  .git/branches/ or any other info)\n\nI think it is up to the user not to do this. You would first need to\ncheck out such a branch anyway.\n\n> +- cannot use \"stg refresh file\" after \"cg-rm file\"\n\nIt seems to work for me. Can you send some log messages?\n\n> +- \"stg goto $(stg top)\" fails with unhandled exception\n\nIt works for me. What StGIT version do you use?\n\n> +- at least \"commit is not robust wrt out-of-diskspace condition:\n> +|deps$ stg commit\n> +|error: git-checkout-index: unable to write file MANIFEST\n> +|error: git-checkout-index: unable to write file META.yml\n> +|error: git-checkout-index: unable to write file Makefile.PL\n> +|error: git-checkout-index: unable to write file doc/README.dbk.xml\n> +|error: git-checkout-index: unable to write file graph-includes\n> +|error: git-checkout-index: unable to write file lib/graphincludes/params.pm\n> +|fatal: unable to write new index file\n> +|stg commit: git-read-tree failed (local changes maybe?)\n> +|Committing 4 patches...\n> +(luckily nothing was really committed)\n\nBut that's the correct behaviour, not to commit anything. The only\nproblem I see (and I fixed) is the \"Committing...\" message on stdout\nwithout flushing, causing it to appear afterwards. StGIT cannot know\nhow much space is needed by GIT to check this beforehand. It simply\nexits when a GIT command failed.\n\nThanks.\n\n-- \n"},{"id":"297657","messageId":"20061205220222.GA5320@nan92-1-81-57-214-146.fbx.proxad.net","threadId":"43400","inReplyTo":"b0943d9e0612050930t187e65c4g6a3c44ea1fefc940@mail.gmail.com","subject":"Re: [PATCH 1/3] Document some current bugs and add to the TODO list.","fromName":"Yann Dirson","fromEmail":"ydirson@altern.org","sentAt":"2006-12-05T22:02:22Z","receivedAt":"2006-12-05T22:02:22Z","isPatch":true,"sender":{"key":"ydirson@altern.org","avatar":"https://avatars.githubusercontent.com/u/1190950?v=4"},"body":"On Tue, Dec 05, 2006 at 05:30:56PM +0000, Catalin Marinas wrote:\n> On 30/11/06, Yann Dirson <ydirson@altern.org> wrote:\n> >+- numeric shortcuts for naming patches near top (eg. +1, -2)\n> \n> We currently have the -n option for push and pop that accepts number.\n> Because of python, you can also, for example, push to the last but one\n> with \"push -n -1\" (similar for pop). Do you mean shortcuts for the\n> \"goto\" command?\n\nI rather meant shortcuts for \"show\", \"fold --pick\", and possibly a\nhandful of others.\n\nWhile we're talking about shortcuts for goto, one that I regularly miss\nwould be something like \"goto BACK\", to allow for short excursions and\nquickly going back without having to worry on which exact patch I was\nbefore.  \"refresh --patch\" will make this less essential, but still\npossibly useful.\n\n\n> >+- refuse to \"stg init\" a branch known as remote (through .git/remotes/,\n> >+  .git/branches/ or any other info)\n> \n> I think it is up to the user not to do this.\n\nIt may not be obvious to a new user, so I'd think it would be useful to\nguard against things we know should not be done.\n\n\"git checkout\" being probably used as plumbing in several places should\nprobably not be taught to refuse switching to remote branches, so I'd\nthink porcelains should take care of this.\n\n\n> You would first need to check out such a branch anyway.\n\nSure.  Especially, the following should probably fail :)\n\n|stgit$ stg branch origin\n|Switching to branch \"origin\"... done\n\nMaybe it could be made to accept only to change to stgit-managed\nbranches ?\nAfter all, if we're switching to a non-stgit branch, we're probably\ngoing to use another set of tools anyway, so we can probably tell the\nuser to use git-checkout or cg-switch instead.\n\n\n> >+- cannot use \"stg refresh file\" after \"cg-rm file\"\n> \n> It seems to work for me. Can you send some log messages?\n\nI should have done that first, I cannot reproduce it any more.\n\n\n> >+- \"stg goto $(stg top)\" fails with unhandled exception\n> \n> It works for me. What StGIT version do you use?\n\nI got that error on 0.11 - and just checked that\n9b63cf56576bf219d26f490f3c011e937a5f7129 fixes exactly this problem\nalready.  Sorry, I should have checked on master first.\n\n\n> >+- at least \"commit is not robust wrt out-of-diskspace condition:\n> >+|deps$ stg commit\n> >+|error: git-checkout-index: unable to write file MANIFEST\n> >+|error: git-checkout-index: unable to write file META.yml\n> >+|error: git-checkout-index: unable to write file Makefile.PL\n> >+|error: git-checkout-index: unable to write file doc/README.dbk.xml\n> >+|error: git-checkout-index: unable to write file graph-includes\n> >+|error: git-checkout-index: unable to write file \n> >lib/graphincludes/params.pm\n> >+|fatal: unable to write new index file\n> >+|stg commit: git-read-tree failed (local changes maybe?)\n> >+|Committing 4 patches...\n> >+(luckily nothing was really committed)\n> \n> But that's the correct behaviour, not to commit anything.\n\nRight.\n\n> StGIT cannot know\n> how much space is needed by GIT to check this beforehand. It simply\n> exits when a GIT command failed.\n\nWhat I had in mind, is that when something fails midway, if we just exit\nwe may end up in an inconsistent state.  I have not taken the time to\ncheck about that, that's why I wanted it to appear in the TODO file.\nAgain, it was quite poorly worded, to say the least.\n\nBest regards,\n-- \n"}]}