[PATCH v2 1/5] config: accept value-less keys in configuration files

28 views
Skip to first unread message

Jacob Keller

unread,
Nov 28, 2017, 8:04:49ā€ÆPM11/28/17
to st...@googlegroups.com, Jacob Keller
If stg is run with a configuration file which has a key defined without
a value, the following exception is produced:

Traceback (most recent call last):
File "./stg", line 24, in <module>
from stgit.main import main
File "stgit/main.py", line 86, in <module>
cmd_list = stgit.commands.get_commands()
File "stgit/commands/__init__.py", line 61, in get_commands
for mod, m in _find_commands())
File "stgit/commands/__init__.py", line 60, in <genexpr>
return dict((text(getattr(m, 'name', mod)), (mod, _kinds[m.kind], m.help))
File "stgit/commands/__init__.py", line 45, in _find_commands
m = get_command(mod)
File "stgit/commands/__init__.py", line 29, in get_command
return __import__(__name__ + '.' + mod, globals(), locals(), ['*'])
File "stgit/commands/diff.py", line 48, in <module>
] + argparse.diff_opts_option()
File "stgit/argparse.py", line 208, in diff_opts_option
default = (config.get('stgit.diff-opts') or '').split(),
File "stgit/config.py", line 67, in get
self.load()
File "stgit/config.py", line 63, in load
key, value = line.split('\n', 1)
ValueError: need more than 1 value to unpack

Git considers this valid (as when parsing booleans, a key without
a value at all is considered as true), so we should not be producing an
exception.

To fix this, catch the ValueError, and use None as the value. This
should be fine, since looking up such a key produce None, which is the
expected behavior for get(), getall(), and getint().

We choose this route instead of simply leaving the key undefined, (which
would thus produce a KeyError exception upon lookup), as we will need to
distinguish this case separately in a following patch which adds
getbool() support.

Add a new test-case which highlights the issue.

Signed-off-by: Jacob Keller <jacob.e...@intel.com>
---
stgit/config.py | 6 +++++-
t/t6000-config.sh | 19 +++++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
create mode 100755 t/t6000-config.sh

diff --git a/stgit/config.py b/stgit/config.py
index e6134cc3c82d..99866020cc2b 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -59,7 +59,11 @@ class GitConfig(object):
lines = Run('git', 'config', '--null', '--list'
).discard_exitcode().output_lines('\0')
for line in lines:
- key, value = line.split('\n', 1)
+ try:
+ key, value = line.split('\n', 1)
+ except ValueError:
+ key = line
+ value = None
self.__cache.setdefault(key, []).append(value)

def get(self, name):
diff --git a/t/t6000-config.sh b/t/t6000-config.sh
new file mode 100755
index 000000000000..425991a6ee58
--- /dev/null
+++ b/t/t6000-config.sh
@@ -0,0 +1,19 @@
+#!/bin/sh
+#
+# Copyright (c) 2017 Intel Corporation
+#
+
+test_description='Simple configuration tests'
+
+. ./test-lib.sh
+
+# Note that it is not possible to use git-config to write such a value, but
+# they are expected to be interpret-able by git commands
+test_expect_success 'stg accepts keys without values' '
+ echo "[stgit]" >> .git/config &&
+ echo " aboolean" >> .git/config &&
+ stg init &&
+ stg status
+'
+
+test_done
--
2.15.0

Jacob Keller

unread,
Nov 28, 2017, 8:04:49ā€ÆPM11/28/17
to st...@googlegroups.com, Jacob Keller
Since I'm proposing a couple changes to refresh, as well as boolean
options which create non-textual conflicts between the patches, I
thought I'd send out all 5 patches as a single series. Otherwise, the
patches do not work properly by themselves (as they lack getbool()) or
they do not use getbool() but then are not updated when boolean changes
are handled.

Jacob Keller (5):
config: accept value-less keys in configuration files
config: parse booleans similar to git-config
refresh: allow configuring to refresh from index by default
stgit: ignore submodules when checking if working tree is clean
refresh: do not include submodules by default

stgit/commands/pull.py | 2 +-
stgit/commands/refresh.py | 55 ++++++++++++++++++++++++++++++++++++---
stgit/config.py | 60 ++++++++++++++++++++++++++++++++-----------
stgit/git.py | 2 +-
stgit/lib/git.py | 11 +++++++-
stgit/lib/transaction.py | 2 +-
t/t1200-push-modified.sh | 16 ++++++++++++
t/t5000-refresh-submodules.sh | 50 ++++++++++++++++++++++++++++++++++++
t/t6000-config.sh | 19 ++++++++++++++
9 files changed, 195 insertions(+), 22 deletions(-)
create mode 100755 t/t5000-refresh-submodules.sh
create mode 100755 t/t6000-config.sh

--
2.15.0

Jacob Keller

unread,
Nov 28, 2017, 8:04:50ā€ÆPM11/28/17
to st...@googlegroups.com, Jacob Keller
Currently, stgit has two "boolean" configuration values which we
support, "autoimerge" and "keepoptimized". However, we only support
"yes" and non-"yes" as valid values. (i.e. either the value is "yes" and
it is deemed true, or it is not "yes").

The standard for git config is to use the "--bool" parameter, which
interprets configuration values as boolean literals:

"yes", "on", "true" and any positive number are true
"no", "off", "false", zero, and the empty string are false

Additionally, a key defined without "= <value>" is taken as true.

Since this is the standard method for git, add a new getbool function
for the config module, which will parse values in this way.

We'll now use this getbool() method for each of these values, ensuring
that these boolean configurations are treated similar to proper git
configuration.

Note that we do not use get() directly in implementing getbool(). This
is because we need to distinguish the case of a defined key with an
undefined value to be True. Since get() converts KeyError exceptions
into None, we would not be able to distinguish the cases of an undefined
key (which should be False) with a key that has an undefined value
(which should be True).

I thought to add new tests for these, but since we don't directly expose
the config.py module, and I don't see an easy way to add tests for
python code explicitly

Signed-off-by: Jacob Keller <jacob.e...@intel.com>
---
stgit/commands/pull.py | 2 +-
stgit/config.py | 24 ++++++++++++++++++++++++
stgit/git.py | 2 +-
stgit/lib/transaction.py | 2 +-
4 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/stgit/commands/pull.py b/stgit/commands/pull.py
index 75a883444577..ed268eeb998b 100644
--- a/stgit/commands/pull.py
+++ b/stgit/commands/pull.py
@@ -114,7 +114,7 @@ def func(parser, options, args):
post_rebase(crt_series, applied, options.nopush, options.merged)

# maybe tidy up
- if config.get('stgit.keepoptimized') == 'yes':
+ if config.getbool('stgit.keepoptimized'):
git.repack()

print_crt_patch(crt_series)
diff --git a/stgit/config.py b/stgit/config.py
index 99866020cc2b..d2342cedd5c9 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -90,6 +90,30 @@ class GitConfig(object):
raise GitConfigException('Value for "%s" is not an integer: "%s"' %
(name, value))

+ def getbool(self, name):
+ """Report the canonicalized boolean value for a given key."""
+ # We cannot directly call get() because we need to use the KeyError in
+ # order to distinguish between the case of a key with an undefined
+ # value, and a completely undefined key. Git expects the former to be
+ # reported as "true".
+ self.load()
+ try:
+ value = self.__cache[name][-1]
+ except KeyError:
+ return None
+ if value is None:
+ # The key is defined, but the value is not, so treat it as true.
+ return True
+ elif value in ['yes', 'on', 'true']:
+ return True
+ elif value in ['no', 'off', 'false', '']:
+ return False
+ elif value.isdigit():
+ return bool(value)
+ else:
+ raise GitConfigException('Value for "%s" is not a booleain: "%s"' %
+ (name, value))
+
def getstartswith(self, name):
self.load()
return ((n, v[-1]) for (n, v) in self.__cache.items()
diff --git a/stgit/git.py b/stgit/git.py
index 826e81f399fb..92a26fc08409 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -607,7 +607,7 @@ def merge_recursive(base, head1, head2):
output = p.output_lines()
if p.exitcode:
# There were conflicts
- if config.get('stgit.autoimerge') == 'yes':
+ if config.getbool('stgit.autoimerge'):
mergetool()
else:
conflicts = [l for l in output if l.startswith('CONFLICT')]
diff --git a/stgit/lib/transaction.py b/stgit/lib/transaction.py
index a19796cb5859..1afa31782071 100644
--- a/stgit/lib/transaction.py
+++ b/stgit/lib/transaction.py
@@ -362,7 +362,7 @@ class StackTransaction(object):
self.__halt('Index/worktree dirty')
try:
interactive = (allow_interactive and
- config.get('stgit.autoimerge') == 'yes')
+ config.getbool('stgit.autoimerge'))
iw.merge(base, ours, theirs, interactive = interactive)
tree = iw.index.write_tree()
self.__current_tree = tree
--
2.15.0

Jacob Keller

unread,
Nov 28, 2017, 8:04:50ā€ÆPM11/28/17
to st...@googlegroups.com, Jacob Keller
Add a new stgit.refresh.index configuration variable which enables
--index by default. Add a new --no-index command line parameter to
override the configuration.

If --force or path_limiting are in effect, these now essentially
override configuration of stgit.refresh.index as they would otherwise be
incompatible. This is consistent with how git itself handles options and
configuration. Any command line parameters take precedence over the
configuration.

A user can also bypass index override by simply passing "." as the path
limiter, which is consistent with how git behaves.

This allows users who are used to interactive addition via git add -p to
more easily integrate with the stg refresh workflow (as otherwise they
must constantly type --index any time they refresh).

Signed-off-by: Jacob Keller <jacob.e...@intel.com>
---
stgit/commands/refresh.py | 17 +++++++++++++++++
stgit/config.py | 1 +
2 files changed, 18 insertions(+)

diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py
index f6c0bf371436..d17ccc2cf98b 100644
--- a/stgit/commands/refresh.py
+++ b/stgit/commands/refresh.py
@@ -6,6 +6,7 @@ from stgit import argparse, utils
from stgit.argparse import opt
from stgit.commands import common
from stgit.lib import git, transaction, edit
+from stgit.config import config, GitConfigException
from stgit.out import out

__copyright__ = """
@@ -37,6 +38,9 @@ Refresh will warn if the index is dirty, and require use of either the '--index'
or '--force' options to override this check. This is to prevent accidental full
refresh when only some changes were staged using git add interative mode.

+Users may optionally set stgit.refresh.index to yes in order to default to
+index-based refreshes.
+
You may optionally list one or more files or directories relative to
the current working directory; if you do, only matching files will be
updated.
@@ -61,6 +65,10 @@ options = [
short = 'Refresh from index instead of worktree', long = """
Instead of setting the patch top to the current contents of
the worktree, set it to the current contents of the index."""),
+ opt('', '--no-index', action = 'store_false', dest = 'index',
+ short = 'Force a refresh from worktree instead of index', long = """
+ Override previous --index or configuration values and force a refresh
+ from the worktree."""),
opt('-F', '--force', action = 'store_true',
short = 'Force refresh even if index is dirty', long = """
Instead of warning the user when some work has already been staged (such
@@ -245,6 +253,15 @@ def func(parser, options, args):
raise common.CmdException(
'You cannot --force a full refresh when using --index mode')

+ # If the user has not explicitly set the --index or --no-index parameters,
+ # we should lookup the default value from configuration. However, we do
+ # not want configuration to override any options on the command line.
+ # We want these options to infer --no-index, even if stgit.refresh.index
+ # is true. Otherwise, configuration could prevent --force or path limiting
+ # from working as expected.
+ if options.index is None and not path_limiting and not options.force:
+ options.index = config.getbool('stgit.refresh.index')
+
stack = directory.repository.current_stack
patch_name = get_patch(stack, options.patch)
paths = list_files(stack, patch_name, args, options.index, options.update)
diff --git a/stgit/config.py b/stgit/config.py
index d2342cedd5c9..5a88548abc51 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -39,6 +39,7 @@ class GitConfig(object):
'stgit.pull-policy': ['pull'],
'stgit.autoimerge': ['no'],
'stgit.keepoptimized': ['no'],
+ 'stgit.refresh.index': ['no'],
'stgit.shortnr': ['5'],
'stgit.pager': ['less'],
'stgit.alias.add': ['git add'],
--
2.15.0

Jacob Keller

unread,
Nov 28, 2017, 8:04:50ā€ÆPM11/28/17
to st...@googlegroups.com, Jacob Keller
If a patch contains a change to a submodule, and a user attempts to pop
and then push the patch from the queue, errors similar to the following
can occur:

$stg pop
Popped a-new-patch
No patch applied
$stg push
stg push: Worktree not clean. Use "refresh" or "reset --hard"

This error occurs because after popping the patch off the queue, the
submodule contents are not updated. This is due to the way that git
treats submodules and does not recursively check them out.

Later, once we go to push the patch back on, we check if the working
tree is clean, by using update-index. Since the submodule remained
checked out at the previous location, we now complain. Worse yet, the
two suggestions we've given do not help.

First, if the user tries to "reset --hard" to throw away these changes,
nothing happens. This, again, is because the submodule is not
automatically moved. Thus, the user can try running reset --hard as many
time as they like, and it will not resolve the problem.

Second, the user can use refresh. This is actually worse, because it
will superficially appear to resolve the problem. The refresh will
simply merge in this submodule pointer change into the previous patch on
the queue. Now, the user can continue with the push, which will notice
the submodule change was already part of the previous patch from the
queue and will essentially remove it from the original patch.

This is much worse now, we've accidentally moved the submodule change to
the wrong patch!

This issue and similar other issues exist due to the default way
submodules behave. We can fix all of them by telling "git update-index"
to ignore submodules. Doing so, now it will not consider submodules
which aren't checked out correctly as a problem for a dirty working
tree. This solves the problem, and makes stgit behave more how git
itself behaves with submodules by default.

Add a new test which demonstrates that popping and subsequently pushing
a patch that changes a submodule will now pass.

Signed-off-by: Jacob Keller <jacob.e...@intel.com>
---
stgit/lib/git.py | 2 +-
t/t1200-push-modified.sh | 16 ++++++++++++++++
2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index e9d9856d0522..82b7a900afb7 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -1086,7 +1086,7 @@ class IndexAndWorktree(RunWithEnvCwd):
def worktree_clean(self):
"""Check whether the worktree is clean relative to index."""
try:
- self.run(['git', 'update-index', '--refresh']).discard_output()
+ self.run(['git', 'update-index', '--ignore-submodules', '--refresh']).discard_output()
except RunException:
return False
else:
diff --git a/t/t1200-push-modified.sh b/t/t1200-push-modified.sh
index e04dac59680a..705e5463adbf 100755
--- a/t/t1200-push-modified.sh
+++ b/t/t1200-push-modified.sh
@@ -71,4 +71,20 @@ test_expect_success \
)
'

+test_expect_success \
+ 'pop then push a patch with a change to a submodule should not produce a conflict' '
+ (
+ cd bar &&
+ stg clone ../foo baz &&
+ stg new p3 -m p3 &&
+ git submodule add ../foo baz &&
+ stg refresh &&
+ (cd baz && git reset --hard HEAD^) &&
+ stg new p4 -m p4 &&
+ stg refresh &&
+ stg pop &&
+ stg push
+ )
+'
+
test_done
--
2.15.0

Jacob Keller

unread,
Nov 28, 2017, 8:04:50ā€ÆPM11/28/17
to st...@googlegroups.com, Jacob Keller
When refreshing patches, the default action is to include every path
which is changed relative to the current working directory. This common
workflow creates problems when one uses a submodule. Due to the nature
of submodules, under some workflows they can often be out-of-sync, such
as when working on new updates within a submodule.

Accidental refreshes which include the submodule changes often occur,
which leads to commits which unintentionally include changes to
submodule pointers. These commits likely cause submodules to point to
incorrect locations.

Since it is not easy to convince many developers to always use "refresh
--index", instead, modify the default refresh behavior.

Instead of including all files, now check to make sure that we exclude
submodule files.

We can do this by using git ls-tree to list the files and their modes.
To avoid re-running ls-tree many times, we'll use a compiled regex to
match lines that look like submodules, and extract their filename.

Add a new option to refresh "--submodules" which tells refresh to
include submodules regardless. Additionally, add a "--no-submodules" and
a stg.refresh.submodules configuration so that users may opt to configure
this behavior.

Since the number of users who use submodules is likely small, make this
the new default behavior.

Signed-off-by: Jacob Keller <jacob.e...@intel.com>
---
stgit/commands/refresh.py | 38 +++++++++++++++++++++++++++++---
stgit/config.py | 31 ++++++++++++++-------------
stgit/lib/git.py | 9 ++++++++
t/t5000-refresh-submodules.sh | 50 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 110 insertions(+), 18 deletions(-)
create mode 100755 t/t5000-refresh-submodules.sh

diff --git a/stgit/commands/refresh.py b/stgit/commands/refresh.py
index d17ccc2cf98b..223adadcf68a 100644
--- a/stgit/commands/refresh.py
+++ b/stgit/commands/refresh.py
@@ -45,6 +45,11 @@ You may optionally list one or more files or directories relative to
the current working directory; if you do, only matching files will be
updated.

+By default, stg refresh will ignore submodules when generating changes. This
+can be bypassed by passing --submodules, setting stg.refresh.submodules to
+yes, or adding a submodule change to the index and using --index to perform an
+index-based refresh.
+
Behind the scenes, stg refresh first creates a new temporary patch
with your updates, and then merges that patch into the patch you asked
to have refreshed. If you asked to refresh a patch other than the
@@ -79,7 +84,11 @@ options = [
opt('-e', '--edit', action = 'store_true',
short = 'Invoke an editor for the patch description'),
opt('-a', '--annotate', metavar = 'NOTE',
- short = 'Annotate the patch log entry')
+ short = 'Annotate the patch log entry'),
+ opt('-s', '--submodules', action = 'store_true',
+ short = 'Include submodules when refreshing patch contents'),
+ opt('', '--no-submodules', action = 'store_false', dest = 'submodules',
+ short = 'Exclude submodules when refreshing patch contents')
] + (argparse.message_options(save_template = False) +
argparse.hook_options() +
argparse.sign_options() + argparse.author_options())
@@ -99,7 +108,7 @@ def get_patch(stack, given_patch):
'Cannot refresh top patch, because no patches are applied')
return stack.patchorder.applied[-1]

-def list_files(stack, patch_name, args, index, update):
+def list_files(stack, patch_name, args, index, update, submodules):
"""Figure out which files to update."""
if index:
# --index: Don't update the index.
@@ -110,6 +119,15 @@ def list_files(stack, patch_name, args, index, update):
# --update: Restrict update to the paths that were already
# part of the patch.
paths &= stack.patches.get(patch_name).files()
+ else:
+ # Avoid including submodule files by default. This is to ensure that
+ # users in repositories with submodueles do not accidentally include
+ # submodule changes to patches just because they happen to have not
+ # run "git submodule update" prior to running stg refresh. We won't
+ # exclude them if we're explicitly told to include them, or if we're
+ # given explicit paths.
+ if not args and not submodules:
+ paths -= stack.repository.submodules(stack.head.data.tree)
return paths

def write_tree(stack, paths, temp_index):
@@ -253,6 +271,14 @@ def func(parser, options, args):
raise common.CmdException(
'You cannot --force a full refresh when using --index mode')

+ if options.update and options.submodules:
+ raise common.CmdException(
+ '--submodules is meaningless when only updating modified files')
+
+ if options.index and options.submodules:
+ raise common.CmdException(
+ '--submodules is meaningless when keeping the current index')
+
# If the user has not explicitly set the --index or --no-index parameters,
# we should lookup the default value from configuration. However, we do
# not want configuration to override any options on the command line.
@@ -262,9 +288,15 @@ def func(parser, options, args):
if options.index is None and not path_limiting and not options.force:
options.index = config.getbool('stgit.refresh.index')

+ # If submodules was not specified on the command line, infer a default
+ # from configuration. Similarly to index, do not infer a default if other
+ # command line options provided would already infer a false value.
+ if options.submodules is None and not options.index and not options.update:
+ options.submodules = config.getbool('stgit.refresh.submodules')
+
stack = directory.repository.current_stack
patch_name = get_patch(stack, options.patch)
- paths = list_files(stack, patch_name, args, options.index, options.update)
+ paths = list_files(stack, patch_name, args, options.index, options.update, options.submodules)

# Make sure there are no conflicts in the files we want to
# refresh.
diff --git a/stgit/config.py b/stgit/config.py
index 5a88548abc51..01d079b88b2a 100644
--- a/stgit/config.py
+++ b/stgit/config.py
@@ -32,21 +32,22 @@ class GitConfigException(StgException):

class GitConfig(object):
__defaults = {
- 'stgit.smtpserver': ['localhost:25'],
- 'stgit.smtpdelay': ['5'],
- 'stgit.pullcmd': ['git pull'],
- 'stgit.fetchcmd': ['git fetch'],
- 'stgit.pull-policy': ['pull'],
- 'stgit.autoimerge': ['no'],
- 'stgit.keepoptimized': ['no'],
- 'stgit.refresh.index': ['no'],
- 'stgit.shortnr': ['5'],
- 'stgit.pager': ['less'],
- 'stgit.alias.add': ['git add'],
- 'stgit.alias.rm': ['git rm'],
- 'stgit.alias.mv': ['git mv'],
- 'stgit.alias.resolved': ['git add'],
- 'stgit.alias.status': ['git status -s']
+ 'stgit.smtpserver': ['localhost:25'],
+ 'stgit.smtpdelay': ['5'],
+ 'stgit.pullcmd': ['git pull'],
+ 'stgit.fetchcmd': ['git fetch'],
+ 'stgit.pull-policy': ['pull'],
+ 'stgit.autoimerge': ['no'],
+ 'stgit.keepoptimized': ['no'],
+ 'stgit.refresh.index': ['no'],
+ 'stgit.refresh.submodules': ['no'],
+ 'stgit.shortnr': ['5'],
+ 'stgit.pager': ['less'],
+ 'stgit.alias.add': ['git add'],
+ 'stgit.alias.rm': ['git rm'],
+ 'stgit.alias.mv': ['git mv'],
+ 'stgit.alias.resolved': ['git add'],
+ 'stgit.alias.status': ['git status -s']
}

__cache = None
diff --git a/stgit/lib/git.py b/stgit/lib/git.py
index 82b7a900afb7..62b3377c7cc5 100644
--- a/stgit/lib/git.py
+++ b/stgit/lib/git.py
@@ -815,6 +815,15 @@ class Repository(RunWithEnv):
return None
finally:
index.delete()
+ def submodules(self, tree):
+ """Given a L{Tree}, return list of paths which are submodules."""
+ assert isinstance(tree, Tree)
+ # A simple regex to match submodule entries
+ regex = re.compile(r'160000 commit [0-9a-f]{40}\t(.*)$')
+ # First, use ls-tree to get all the trees and links
+ files = self.run(['git', 'ls-tree', '-d', '-r', '-z', tree.sha1]).output_lines('\0')
+ # Then extract the paths of any submodules
+ return set(m.group(1) for m in map(regex.match, files) if m)
def diff_tree(self, t1, t2, diff_opts, binary = True):
"""Given two L{Tree}s C{t1} and C{t2}, return the patch that takes
C{t1} to C{t2}.
diff --git a/t/t5000-refresh-submodules.sh b/t/t5000-refresh-submodules.sh
new file mode 100755
index 000000000000..9c8cbcb0b08a
--- /dev/null
+++ b/t/t5000-refresh-submodules.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+#
+# Copyright (c) 2017 Intel Corporation
+#
+
+test_description='Refresh with submodules'
+
+. ./test-lib.sh
+
+test_expect_success 'refresh with a submodule does not include by default' '
+ test_create_repo foo &&
+ git submodule add ./foo foo &&
+ git commit -m "submodule" &&
+ stg init &&
+ (
+ cd foo &&
+ touch file1 &&
+ git add file1 &&
+ git commit -m "change in submodule"
+ ) &&
+ stg new p1 -m p1 &&
+ stg refresh &&
+ [ "$(stg status)" == " M foo" ]
+'
+
+test_expect_success 'refresh includes non-submodule changes' '
+ touch file2 &&
+ git add file2 &&
+ stg refresh &&
+ [ "$(stg status)" == " M foo" ]
+'
+
+test_expect_success 'refresh with --submodules' '
+ stg refresh --submodules &&
+ [ "$(stg status)" == "" ]
+'
+
+test_expect_success 'refresh --no-submodules overrides config' '
+ stg undo && stg undo &&
+ git config stgit.refresh.submodules yes &&
+ stg refresh --no-submodules &&
+ [ "$(stg status)" == " M foo" ]
+'
+
+test_expect_success 'refresh with config' '
+ stg refresh &&
+ [ "$(stg status)" == "" ]

Jacob Keller

unread,
Jan 8, 2018, 12:12:37ā€ÆPM1/8/18
to StGit (Stacked Git)


On Tuesday, November 28, 2017 at 5:04:49 PM UTC-8, jacob.e.keller wrote:
Since I'm proposing a couple changes to refresh, as well as boolean
options which create non-textual conflicts between the patches, I
thought I'd send out all 5 patches as a single series. Otherwise, the
patches do not work properly by themselves (as they lack getbool()) or
they do not use getbool() but then are not updated when boolean changes
are handled.


Hi, this has been up since over a month ago, without comments.

Thanks,
JakeĀ 

Jacob Keller

unread,
Jan 18, 2018, 5:31:32ā€ÆPM1/18/18
to StGit (Stacked Git)
Another friendly ping post holidays.

Thanks,
Jake
Reply all
Reply to author
Forward
0 new messages