* [PATCH 0/7] StGIT, remotes, and parent
@ 2007-01-29 23:05 Yann Dirson
2007-01-29 23:05 ` [PATCH 1/7] Make stgit.config use git-repo-config Yann Dirson
` (6 more replies)
0 siblings, 7 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
This new series should bring the first 5 patches into sufficiently
reasonable shape, so I'm presenting them for inclusion. The last 2
ones are still there for context only.
This new revision of the series brings:
- Better use of stgit.config in subsequent patches, notably deported
the remaining call to repo-config into stgit.config:
config.sections_matching(regexp)
- Caching in stgit.config. I implemented this as on-demand caching,
initially because it was straightforward, but it turns out that
sections_matching() naturally fits in this model, and i'm not sure how
we could have implemented this in the pre-caching model.
- The usual bunch of misc cleanups.
Best regards,
--
Yann Dirson <ydirson@altern.org> |
Debian-related: <dirson@debian.org> | Support Debian GNU/Linux:
| Freedom, Power, Stability, Gratis
http://ydirson.free.fr/ | Check <http://www.debian.org/>
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/7] Make stgit.config use git-repo-config.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-29 23:05 ` [PATCH 2/7] Add caching to the new config class Yann Dirson
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
This is an initial implementation without any sort of caching. If we
want that, we could do it with this new API. We could even just
simply generalize the use of ConfigOption instead.
I just copypasted __run from stgit.git to avoid too much work, but
it's definitely something to cleanup.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/commands/common.py | 5 +
stgit/commands/mail.py | 36 +++-------
stgit/commands/pull.py | 9 +-
stgit/commands/refresh.py | 2 -
stgit/config.py | 166 +++++++++++++++++++++++----------------------
stgit/git.py | 10 +--
stgit/gitmergeonefile.py | 7 +-
stgit/stack.py | 5 +
8 files changed, 113 insertions(+), 127 deletions(-)
diff --git a/stgit/commands/common.py b/stgit/commands/common.py
index 2e57824..432edce 100644
--- a/stgit/commands/common.py
+++ b/stgit/commands/common.py
@@ -311,9 +311,10 @@ def address_or_alias(addr_str):
if addr.find('@') >= 0:
# it's an e-mail address
return addr
- if config.has_option('mail "alias"', addr):
+ alias = config.get('mail.alias.'+addr)
+ if alias:
# it's an alias
- return config.get('mail "alias"', addr)
+ return alias
raise CmdException, 'unknown e-mail alias: %s' % addr
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 6f61b83..7f20f13 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -129,9 +129,8 @@ def __get_sender():
"""Return the 'authname <authemail>' string as read from the
configuration file
"""
- if config.has_option('stgit', 'sender'):
- sender = config.get('stgit', 'sender')
- else:
+ sender=config.get('stgit.sender')
+ if not sender:
try:
sender = str(git.user())
except git.GitException:
@@ -207,10 +206,7 @@ def __build_address_headers(msg, options, extra_cc = []):
cc_addr = ''
bcc_addr = ''
- if config.has_option('stgit', 'autobcc'):
- autobcc = config.get('stgit', 'autobcc')
- else:
- autobcc = ''
+ autobcc = config.get('stgit.autobcc') or ''
if options.to:
to_addr = ', '.join(options.to)
@@ -283,8 +279,9 @@ def __edit_message(msg):
f.close()
# the editor
- if config.has_option('stgit', 'editor'):
- editor = config.get('stgit', 'editor')
+ editor = config.get('stgit.editor')
+ if editor:
+ pass
elif 'EDITOR' in os.environ:
editor = os.environ['EDITOR']
else:
@@ -469,14 +466,7 @@ def func(parser, options, args):
"""Send the patches by e-mail using the patchmail.tmpl file as
a template
"""
- smtpserver = config.get('stgit', 'smtpserver')
-
- smtpuser = None
- smtppassword = None
- if config.has_option('stgit', 'smtpuser'):
- smtpuser = config.get('stgit', 'smtpuser')
- if config.has_option('stgit', 'smtppassword'):
- smtppassword = config.get('stgit', 'smtppassword')
+ smtpserver = config.get('stgit.smtpserver')
applied = crt_series.get_applied()
@@ -488,11 +478,8 @@ def func(parser, options, args):
else:
raise CmdException, 'Incorrect options. Unknown patches to send'
- if options.smtp_password:
- smtppassword = options.smtp_password
-
- if options.smtp_user:
- smtpuser = options.smtp_user
+ smtppassword = options.smtp_password or config.get('stgit.smtppassword')
+ smtpuser = options.smtp_user or config.get('stgit.smtpuser')
if (smtppassword and not smtpuser):
raise CmdException, 'SMTP password supplied, username needed'
@@ -508,10 +495,7 @@ def func(parser, options, args):
else:
ref_id = options.refid
- if options.sleep != None:
- sleep = options.sleep
- else:
- sleep = config.getint('stgit', 'smtpdelay')
+ sleep = options.sleep or config.getint('stgit.smtpdelay')
# send the cover message (if any)
if options.cover or options.edit_cover:
diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py
index 7c5db22..e47858a 100644
--- a/stgit/commands/pull.py
+++ b/stgit/commands/pull.py
@@ -53,11 +53,7 @@ def func(parser, options, args):
if len(args) >= 1:
repository = args[0]
else:
- section = 'branch "%s"' % git.get_head_file()
- if config.has_option(section, 'remote'):
- repository = config.get(section, 'remote')
- else:
- repository = 'origin'
+ repository = config.get('branch.%s.remote' % git.get_head_file()) or 'origin'
refspec = None
if len(args) == 2:
@@ -88,8 +84,7 @@ def func(parser, options, args):
push_patches(applied, options.merged)
# maybe tidy up
- repack = config.get('stgit', 'keepoptimized')
- if repack == 'yes':
+ if config.get('stgit.keepoptimized') == 'yes':
git.repack()
print_crt_patch()
diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py
index 0efe1df..7a9bf7d 100644
--- a/stgit/commands/refresh.py
+++ b/stgit/commands/refresh.py
@@ -77,7 +77,7 @@ options = [make_option('-f', '--force',
def func(parser, options, args):
- autoresolved = config.get('stgit', 'autoresolved')
+ autoresolved = config.get('stgit.autoresolved')
if autoresolved != 'yes':
check_conflicts()
diff --git a/stgit/config.py b/stgit/config.py
index a6afbfd..d42754b 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -18,91 +18,97 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
-import os, ConfigParser
-from StringIO import StringIO
+import os, re
from stgit import basedir
-config = ConfigParser.RawConfigParser()
-
-def git_config(filename):
- """Open a git config file and convert it to be understood by
- Python."""
- try:
- f = file(filename)
- cont = False
- lines = []
- for line in f:
- line = line.strip()
-
- if cont:
- # continued line, add a space at the beginning
- line = ' ' + line
-
- if line and line[-1] == '\\':
- line = line[:-1].rstrip()
- cont = True
- else:
- line = line + '\n'
- cont = False
-
- lines.append(line)
-
- f.close()
- cfg_str = ''.join(lines)
- except IOError:
- cfg_str = ''
-
- strio = StringIO(cfg_str)
- strio.name = filename
-
- return strio
+class GitConfigException(Exception):
+ pass
+
+class GitConfig:
+ __defaults={
+ 'stgit.autoresolved': 'no',
+ 'stgit.smtpserver': 'localhost:25',
+ 'stgit.smtpdelay': '5',
+ 'stgit.pullcmd': 'git-pull',
+ 'stgit.merger': 'diff3 -L current -L ancestor -L patched -m -E ' \
+ '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"',
+ 'stgit.autoimerge': 'no',
+ 'stgit.keeporig': 'yes',
+ 'stgit.keepoptimized': 'no',
+ 'stgit.extensions': '.ancestor .current .patched',
+ 'stgit.shortnr': '5'
+ }
+
+ def __run(self, cmd, args=None):
+ """__run: runs cmd using spawnvp.
+
+ Runs cmd using spawnvp. The shell is avoided so it won't mess up
+ our arguments. If args is very large, the command is run multiple
+ times; args is split xargs style: cmd is passed on each
+ invocation. Unlike xargs, returns immediately if any non-zero
+ return code is received.
+ """
+
+ args_l=cmd.split()
+ if args is None:
+ args = []
+ for i in range(0, len(args)+1, 100):
+ r=os.spawnvp(os.P_WAIT, args_l[0], args_l + args[i:min(i+100, len(args))])
+ if r:
+ return r
+ return 0
+
+ def get(self, name):
+ stream = os.popen('git repo-config --get %s' % name, 'r')
+ value = stream.readline().strip()
+ stream.close()
+ if len(value) > 0:
+ return value
+ elif (self.__defaults.has_key(name)):
+ return self.__defaults[name]
+ else:
+ return None
+
+ def getall(self, name):
+ stream = os.popen('git repo-config --get-all %s' % name, 'r')
+ values = [line.strip() for line in stream]
+ stream.close()
+ return values
+
+ def getint(self, name):
+ value = self.get(name)
+ if value.isdigit():
+ return int(value)
+ else:
+ raise GitConfigException, 'Value for "%s" is not an integer: "%s"' % (name, value)
+
+ def set(self, name, value):
+ self.__run('git-repo-config', [name, value])
+
+ def sections_matching(self, regexp):
+ """Takes a regexp with a single group, matches it against all
+ config variables, and returns a list whose members are the
+ group contents, for all variable names matching the regexp.
+ """
+ result = []
+ stream = os.popen('git repo-config --get-regexp "^%s$"' % regexp, 'r')
+ for line in stream:
+ m = re.match('^%s ' % regexp, line)
+ if m:
+ result.append(m.group(1))
+ stream.close()
+ return result
+
+config=GitConfig()
def config_setup():
global config
- # Set the defaults
- config.add_section('stgit')
- config.set('stgit', 'autoresolved', 'no')
- config.set('stgit', 'smtpserver', 'localhost:25')
- config.set('stgit', 'smtpdelay', '5')
- config.set('stgit', 'pullcmd', 'git-pull')
- config.set('stgit', 'merger',
- 'diff3 -L current -L ancestor -L patched -m -E ' \
- '"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"')
- config.set('stgit', 'autoimerge', 'no')
- config.set('stgit', 'keeporig', 'yes')
- config.set('stgit', 'keepoptimized', 'no')
- config.set('stgit', 'extensions', '.ancestor .current .patched')
- config.set('stgit', 'shortnr', '5')
-
- # Read the configuration files (if any) and override the default settings
- # stgitrc are read for backward compatibility
- config.read('/etc/stgitrc')
- config.read(os.path.expanduser('~/.stgitrc'))
- config.read(os.path.join(basedir.get(), 'stgitrc'))
-
- # GIT configuration files can have a [stgit] section
- try:
- global_config = os.environ['GIT_CONFIG']
- except KeyError:
- global_config = os.path.expanduser('~/.gitconfig')
- try:
- local_config = os.environ['GIT_CONFIG_LOCAL']
- except KeyError:
- local_config = os.path.join(basedir.get(), 'config')
- config.readfp(git_config(global_config))
- config.readfp(git_config(local_config))
-
# Set the PAGER environment to the config value (if any)
- if config.has_option('stgit', 'pager'):
- os.environ['PAGER'] = config.get('stgit', 'pager')
-
- # [gitmergeonefile] section is deprecated. In case it exists copy the
- # options/values to the [stgit] one
- if config.has_section('gitmergeonefile'):
- for option, value in config.items('gitmergeonefile'):
- config.set('stgit', option, value)
-
+ pager = config.get('stgit.pager')
+ if pager:
+ os.environ['PAGER'] = pager
+ # FIXME: handle EDITOR the same way ?
class ConfigOption:
"""Delayed cached reading of a configuration option.
@@ -114,7 +120,7 @@ class ConfigOption:
def __str__(self):
if not self.__value:
- self.__value = config.get(self.__section, self.__option)
+ self.__value = config.get(self.__section + '.' + self.__option)
return self.__value
@@ -127,7 +133,7 @@ def file_extensions():
global __extensions
if not __extensions:
- cfg_ext = config.get('stgit', 'extensions').split()
+ cfg_ext = config.get('stgit.extensions').split()
if len(cfg_ext) != 3:
raise CmdException, '"extensions" configuration error'
diff --git a/stgit/git.py b/stgit/git.py
index 7d99338..249080e 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -449,10 +449,10 @@ def user():
"""
global __user
if not __user:
- if config.has_option('user', 'name') \
- and config.has_option('user', 'email'):
- __user = Person(config.get('user', 'name'),
- config.get('user', 'email'))
+ name=config.get('user.name')
+ email=config.get('user.email')
+ if name and email:
+ __user = Person(name, email)
else:
raise GitException, 'unknown user details'
return __user;
@@ -818,7 +818,7 @@ def pull(repository = 'origin', refspec = None):
if refspec:
args.append(refspec)
- if __run(config.get('stgit', 'pullcmd'), args) != 0:
+ if __run(config.get('stgit.pullcmd'), args) != 0:
raise GitException, 'Failed "git-pull %s"' % repository
def repack():
diff --git a/stgit/gitmergeonefile.py b/stgit/gitmergeonefile.py
index 587c8c4..b9d02aa 100644
--- a/stgit/gitmergeonefile.py
+++ b/stgit/gitmergeonefile.py
@@ -102,9 +102,8 @@ def interactive_merge(filename):
"""Run the interactive merger on the given file. Note that the
index should not have any conflicts.
"""
- try:
- imerger = config.get('stgit', 'imerger')
- except Exception, err:
+ imerger = config.get('stgit.imerger')
+ if not imerger:
raise GitMergeException, 'Configuration error: %s' % err
extensions = file_extensions()
@@ -185,7 +184,7 @@ def merge(orig_hash, file1_hash, file2_hash,
os.system('git-update-index --cacheinfo %s %s %s'
% (file1_mode, file1_hash, path))
- if config.get('stgit', 'autoimerge') == 'yes':
+ if config.get('stgit.autoimerge') == 'yes':
print >> sys.stderr, \
'Trying the interactive merge'
try:
diff --git a/stgit/stack.py b/stgit/stack.py
index 5237084..6281f36 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -92,8 +92,9 @@ def edit_file(series, line, comment, show_patch = True):
f.close()
# the editor
- if config.has_option('stgit', 'editor'):
- editor = config.get('stgit', 'editor')
+ editor = config.get('stgit.editor')
+ if editor:
+ pass
elif 'EDITOR' in os.environ:
editor = os.environ['EDITOR']
else:
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/7] Add caching to the new config class.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
2007-01-29 23:05 ` [PATCH 1/7] Make stgit.config use git-repo-config Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-29 23:05 ` [PATCH 3/7] Move identification of parent branch's remote def up into stack class Yann Dirson
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/config.py | 19 ++++++++++++++++---
1 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/stgit/config.py b/stgit/config.py
index d42754b..901f600 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -39,6 +39,8 @@ class GitConfig:
'stgit.shortnr': '5'
}
+ __cache={}
+
def __run(self, cmd, args=None):
"""__run: runs cmd using spawnvp.
@@ -59,20 +61,31 @@ class GitConfig:
return 0
def get(self, name):
+ if self.__cache.has_key(name):
+ return self.__cache[name]
+
stream = os.popen('git repo-config --get %s' % name, 'r')
value = stream.readline().strip()
stream.close()
if len(value) > 0:
- return value
+ pass
elif (self.__defaults.has_key(name)):
- return self.__defaults[name]
+ value = self.__defaults[name]
else:
- return None
+ value = None
+
+ self.__cache[name] = value
+ return value
def getall(self, name):
+ if self.__cache.has_key(name):
+ return self.__cache[name]
+
stream = os.popen('git repo-config --get-all %s' % name, 'r')
values = [line.strip() for line in stream]
stream.close()
+
+ self.__cache[name] = values
return values
def getint(self, name):
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/7] Move identification of parent branch's remote def up into stack class.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
2007-01-29 23:05 ` [PATCH 1/7] Make stgit.config use git-repo-config Yann Dirson
2007-01-29 23:05 ` [PATCH 2/7] Add caching to the new config class Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-29 23:05 ` [PATCH 4/7] Allows extraction of information about remotes Yann Dirson
` (3 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
Also adds the __set_parent_remote() counterpart method, but only
private since it is expected to be called only through set_parent, to
be introduced in subsequent patch.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/commands/pull.py | 2 +-
stgit/stack.py | 6 ++++++
2 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py
index e47858a..0608fb6 100644
--- a/stgit/commands/pull.py
+++ b/stgit/commands/pull.py
@@ -53,7 +53,7 @@ def func(parser, options, args):
if len(args) >= 1:
repository = args[0]
else:
- repository = config.get('branch.%s.remote' % git.get_head_file()) or 'origin'
+ repository = crt_series.get_parent_remote()
refspec = None
if len(args) == 2:
diff --git a/stgit/stack.py b/stgit/stack.py
index 6281f36..947b416 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -407,6 +407,12 @@ class Series(StgitObject):
def set_description(self, line):
self._set_field('description', line)
+ def get_parent_remote(self):
+ return config.get('branch.%s.remote' % self.__name) or 'origin'
+
+ def __set_parent_remote(self, remote):
+ value = config.set('branch.%s.remote' % self.__name, remote)
+
def __patch_is_current(self, patch):
return patch.get_name() == self.get_current()
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/7] Allows extraction of information about remotes.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
` (2 preceding siblings ...)
2007-01-29 23:05 ` [PATCH 3/7] Move identification of parent branch's remote def up into stack class Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-29 23:05 ` [PATCH 5/7] Basic support for keeping a ref to the parent branch Yann Dirson
` (2 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
We want to know the list of declared remotes, the local branches they
hold, and which remotes holds a given branch. All this regardless of
where the information is stored.
If there are any git-1.5 remotes declared in .git/config, we suppose
you know what you're doing and they will take precedence on any
pre-1.5 remotes.
This does not use git-remote for now, since it is 1.5 material not
released yet, does not support legacy branches/ remotes, and does not
allow yet to query all of the information we need.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/git.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 68 insertions(+), 0 deletions(-)
diff --git a/stgit/git.py b/stgit/git.py
index 249080e..038aaac 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -881,3 +881,71 @@ def modifying_revs(files, base_rev):
revs = [line.strip() for line in _output_lines(cmd + files)]
return revs
+
+
+def refspec_localpart(refspec):
+ m = re.match('^[^:]*:([^:]*)$', refspec)
+ if m:
+ return m.group(1)
+ else:
+ raise GitException, 'Cannot parse refspec "%s"' % line
+
+def refspec_remotepart(refspec):
+ m = re.match('^([^:]*):[^:]*$', refspec)
+ if m:
+ return m.group(1)
+ else:
+ raise GitException, 'Cannot parse refspec "%s"' % line
+
+
+def __remotes_from_config():
+ return config.sections_matching(r'remote\.(.*)\.url')
+
+def __remotes_from_dir(dir):
+ return os.listdir(os.path.join(basedir.get(), dir))
+
+def remotes_list():
+ """Return the list of remotes in the repository
+ """
+
+ return set(__remotes_from_config()) | \
+ set(__remotes_from_dir('remotes')) | \
+ set(__remotes_from_dir('branches'))
+
+def remotes_local_branches(remote):
+ """Returns the list of local branches fetched from given remote
+ """
+
+ branches = []
+ if remote in __remotes_from_config():
+ for line in config.getall('remote.%s.fetch' % remote):
+ branches.append(refspec_localpart(line))
+ elif remote in __remotes_from_dir('remotes'):
+ stream = open(os.path.join(basedir.get(), 'remotes', remote), 'r')
+ for line in stream:
+ # Only consider Pull lines
+ m = re.match('^Pull: (.*)\n$', line)
+ branches.append(refspec_localpart(m.group(1)))
+ stream.close()
+ elif remote in __remotes_from_dir('branches'):
+ # old-style branches only declare one branch
+ branches.append('refs/heads/'+remote);
+ else:
+ raise GitException, 'Unknown remote "%s"' % remote
+
+ return branches
+
+def identify_remote(branchname):
+ """Return the name for the remote to pull the given branchname
+ from, or None if we believe it is a local branch.
+ """
+
+ for remote in remotes_list():
+ if branchname in remotes_local_branches(remote):
+ return remote
+
+ # FIXME: in the case of local branch we should maybe set remote to
+ # "." but are we even sure it is the only case left ?
+
+ # if we get here we've found nothing
+ return None
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/7] Basic support for keeping a ref to the parent branch.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
` (3 preceding siblings ...)
2007-01-29 23:05 ` [PATCH 4/7] Allows extraction of information about remotes Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-29 23:05 ` [PATCH 6/7] Have 'stg branch --create' record parent information Yann Dirson
2007-01-29 23:05 ` [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull Yann Dirson
6 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
This adds a framework to handle the parent branch of a stack, in
addition to the parent remote, and to set them when creating a stack.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
TODO | 2 --
stgit/stack.py | 24 +++++++++++++++++++++++-
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/TODO b/TODO
index 549bc9d..884b831 100644
--- a/TODO
+++ b/TODO
@@ -20,8 +20,6 @@ The future, when time allows or if someone else does them:
- multiple heads in a patch - useful for forking a patch,
synchronising with other patches (diff format or in other
repositories)
-- "pull" argument should default to a sane value, "origin" is wrong in
- many cases
- commit directly to a patch which is not top
- patch synchronisation between between branches (as some people,
including me have the same patches based on different branches and
diff --git a/stgit/stack.py b/stgit/stack.py
index 947b416..9640eb5 100644
--- a/stgit/stack.py
+++ b/stgit/stack.py
@@ -413,6 +413,26 @@ class Series(StgitObject):
def __set_parent_remote(self, remote):
value = config.set('branch.%s.remote' % self.__name, remote)
+ def get_parent_branch(self):
+ value = config.get('branch.%s.merge' % self.__name)
+ if value:
+ return value
+ elif rev_parse('heads/origin'):
+ return 'heads/origin'
+ else:
+ raise StackException, 'Cannot find a parent branch for "%s"' % self.__name
+
+ def __set_parent_branch(self, name):
+ config.set('branch.%s.merge' % self.__name, name)
+
+ def set_parent(self, remote, localbranch):
+ if localbranch:
+ self.__set_parent_branch(localbranch)
+ if remote:
+ self.__set_parent_remote(remote)
+ elif remote:
+ raise StackException, 'Remote "%s" without a branch cannot be used as parent' % remote
+
def __patch_is_current(self, patch):
return patch.get_name() == self.get_current()
@@ -466,7 +486,7 @@ class Series(StgitObject):
"""
return os.path.isdir(self.__patch_dir)
- def init(self, create_at=False):
+ def init(self, create_at=False, parent_remote=None, parent_branch=None):
"""Initialises the stgit series
"""
bases_dir = os.path.join(self.__base_dir, 'refs', 'bases')
@@ -483,6 +503,8 @@ class Series(StgitObject):
os.makedirs(self.__patch_dir)
+ self.set_parent(parent_remote, parent_branch)
+
create_dirs(bases_dir)
self.create_empty_field('applied')
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/7] Have 'stg branch --create' record parent information.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
` (4 preceding siblings ...)
2007-01-29 23:05 ` [PATCH 5/7] Basic support for keeping a ref to the parent branch Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-29 23:05 ` [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull Yann Dirson
6 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/commands/branch.py | 37 ++++++++++++++++++++++++++++++++++---
1 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/stgit/commands/branch.py b/stgit/commands/branch.py
index d348409..f074d47 100644
--- a/stgit/commands/branch.py
+++ b/stgit/commands/branch.py
@@ -123,10 +123,41 @@ def func(parser, options, args):
check_head_top_equal()
tree_id = None
- if len(args) == 2:
+ if len(args) >= 2:
+ try:
+ if git.rev_parse(args[1]) == git.rev_parse('refs/heads/' + args[1]):
+ # we are for sure refering to a branch
+ parentbranch = 'refs/heads/' + args[1]
+ print 'Recording "%s" as parent branch.' % parentbranch
+ elif git.rev_parse(args[1]) and re.search('/', args[1]):
+ # FIXME: should the test be more strict ?
+ parentbranch = args[1]
+ else:
+ # Note: this includes refs to StGIT patches
+ print 'Don\'t know how to determine parent branch from "%s".' % args[1]
+ parentbranch = None
+ except git.GitException:
+ # should use a more specific exception to catch only non-git refs ?
+ print 'Don\'t know how to determine parent branch from "%s".' % args[1]
+ parentbranch = None
+
tree_id = git_id(args[1])
-
- stack.Series(args[0]).init(create_at = tree_id)
+ else:
+ # branch stack off current branch
+ parentbranch = git.get_head_file()
+
+ if parentbranch:
+ parentremote = git.identify_remote(parentbranch)
+ if parentremote:
+ print 'Using "%s" remote to pull parent from.' % parentremote
+ else:
+ print 'Not identified a remote to pull parent from.'
+ else:
+ parentremote = None
+
+ stack.Series(args[0]).init(create_at = tree_id,
+ parent_remote = parentremote,
+ parent_branch = parentbranch)
print 'Branch "%s" created.' % args[0]
return
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull.
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
` (5 preceding siblings ...)
2007-01-29 23:05 ` [PATCH 6/7] Have 'stg branch --create' record parent information Yann Dirson
@ 2007-01-29 23:05 ` Yann Dirson
2007-01-31 23:44 ` Catalin Marinas
6 siblings, 1 reply; 10+ messages in thread
From: Yann Dirson @ 2007-01-29 23:05 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
We introduce a new pull-does-rebase setting, as companion to pullcmd.
This allows to use both pullcmd's that need a rebase (like git-fetch)
and pullcmd's that do not (like git-pull).
To be able to rebase, we rely on parent information being available
for the stack.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
examples/gitconfig | 8 +++++++-
stgit/config.py | 3 ++-
stgit/git.py | 15 ++++++++++-----
3 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/examples/gitconfig b/examples/gitconfig
index ee68d07..60f6e85 100644
--- a/examples/gitconfig
+++ b/examples/gitconfig
@@ -33,8 +33,14 @@
#pager = ~/share/stgit/contrib/diffcol.sh
#pager = filterdiff --annotate | colordiff | less -FRX
- # GIT pull command (should take the same arguments as git-pull)
+ # GIT pull command (should take the same arguments as
+ # git-fetch or git-pull). By default:
+ #pullcmd = git-fetch
+ #pull-does-rebase = yes
+ # Alternative (old behaviour), less intuitive but maybe useful
+ # for some workflows:
#pullcmd = git-pull
+ #pull-does-rebase = no
# The three-way merge tool. Note that the 'output' file contains the
# same data as 'branch1'. This is useful for tools that do not take an
diff --git a/stgit/config.py b/stgit/config.py
index 901f600..48b4e2d 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -29,7 +29,8 @@ class GitConfig:
'stgit.autoresolved': 'no',
'stgit.smtpserver': 'localhost:25',
'stgit.smtpdelay': '5',
- 'stgit.pullcmd': 'git-pull',
+ 'stgit.pullcmd': 'git-fetch',
+ 'stgit.pull-does-rebase': 'yes',
'stgit.merger': 'diff3 -L current -L ancestor -L patched -m -E ' \
'"%(branch1)s" "%(ancestor)s" "%(branch2)s" > "%(output)s"',
'stgit.autoimerge': 'no',
diff --git a/stgit/git.py b/stgit/git.py
index 038aaac..e30b959 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -808,18 +808,23 @@ def reset(files = None, tree_id = None, check_out = True):
__set_head(tree_id)
def pull(repository = 'origin', refspec = None):
- """Pull changes from the remote repository. At the moment, just
- use the 'git-pull' command
+ """Pull changes from the remote repository. Uses 'git-fetch'
+ and moves the stack base.
"""
- # 'git-pull' updates the HEAD
+ # we update the HEAD
__clear_head_cache()
args = [repository]
if refspec:
args.append(refspec)
- if __run(config.get('stgit.pullcmd'), args) != 0:
- raise GitException, 'Failed "git-pull %s"' % repository
+ command = config.get('stgit.pullcmd')
+ if __run(command, args) != 0:
+ raise GitException, 'Failed "%s %s"' % (command, repository)
+
+ if (config.get('stgit.pull-does-rebase')):
+ # FIXME!
+ reset(tree_id = rev_parse(repository))
def repack():
"""Repack all objects into a single pack
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull.
2007-01-29 23:05 ` [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull Yann Dirson
@ 2007-01-31 23:44 ` Catalin Marinas
2007-02-01 18:47 ` Yann Dirson
0 siblings, 1 reply; 10+ messages in thread
From: Catalin Marinas @ 2007-01-31 23:44 UTC (permalink / raw)
To: Yann Dirson; +Cc: git
On 29/01/07, Yann Dirson <ydirson@altern.org> wrote:
> We introduce a new pull-does-rebase setting, as companion to pullcmd.
> This allows to use both pullcmd's that need a rebase (like git-fetch)
> and pullcmd's that do not (like git-pull).
Thanks for the patches. I applied all of them but I have a question on this one:
> + if (config.get('stgit.pull-does-rebase')):
> + # FIXME!
> + reset(tree_id = rev_parse(repository))
Why the "FIXME" here? The alternative is switch() and it might be safer.
--
Catalin
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull.
2007-01-31 23:44 ` Catalin Marinas
@ 2007-02-01 18:47 ` Yann Dirson
0 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-02-01 18:47 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
On Wed, Jan 31, 2007 at 11:44:07PM +0000, Catalin Marinas wrote:
> On 29/01/07, Yann Dirson <ydirson@altern.org> wrote:
> >We introduce a new pull-does-rebase setting, as companion to pullcmd.
> >This allows to use both pullcmd's that need a rebase (like git-fetch)
> >and pullcmd's that do not (like git-pull).
>
> Thanks for the patches. I applied all of them but I have a question on this
> one:
>
> >+ if (config.get('stgit.pull-does-rebase')):
> >+ # FIXME!
> >+ reset(tree_id = rev_parse(repository))
>
> Why the "FIXME" here? The alternative is switch() and it might be safer.
The last 2 patches, including the one with this FIXME, will need some
work.
In this case, we should reset to the parent branch. It currently just
works because traditionnaly we use refs/heads/origin from remote
"origin", and "rev-parse origin" resolves to that branch.
Best regards,
--
Yann
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2007-02-01 18:48 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-01-29 23:05 [PATCH 0/7] StGIT, remotes, and parent Yann Dirson
2007-01-29 23:05 ` [PATCH 1/7] Make stgit.config use git-repo-config Yann Dirson
2007-01-29 23:05 ` [PATCH 2/7] Add caching to the new config class Yann Dirson
2007-01-29 23:05 ` [PATCH 3/7] Move identification of parent branch's remote def up into stack class Yann Dirson
2007-01-29 23:05 ` [PATCH 4/7] Allows extraction of information about remotes Yann Dirson
2007-01-29 23:05 ` [PATCH 5/7] Basic support for keeping a ref to the parent branch Yann Dirson
2007-01-29 23:05 ` [PATCH 6/7] Have 'stg branch --create' record parent information Yann Dirson
2007-01-29 23:05 ` [PATCH 7/7] Make 'stg pull' use git-fetch and not git-pull Yann Dirson
2007-01-31 23:44 ` Catalin Marinas
2007-02-01 18:47 ` Yann Dirson
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).