* [PATCH 2/4] Call external commands without a shell where possible.
2007-05-31 22:34 [StGIT PATCH 0/4] Rename detection, take 2 Yann Dirson
2007-05-31 22:34 ` [PATCH 1/4] Add 2 new contrib scripts Yann Dirson
@ 2007-05-31 22:34 ` Yann Dirson
2007-05-31 22:34 ` [PATCH 3/4] Make diff flags handling more modular Yann Dirson
2007-05-31 22:34 ` [PATCH 4/4] Add new --diff-opts/-O flag to diff- and status-related commands Yann Dirson
3 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-05-31 22:34 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
On my dev box it consistently improves performance when timing the
full testsuite:
before:
user 2m22.509s
sys 0m50.695s
user 2m23.565s
sys 0m49.399s
user 2m23.497s
sys 0m49.675s
after:
user 2m20.261s
sys 0m45.687s
user 2m21.485s
sys 0m46.427s
user 2m20.581s
sys 0m45.367s
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/git.py | 42 +++++++++++++++++++++---------------------
1 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/stgit/git.py b/stgit/git.py
index 845c712..5cdc8cd 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -74,7 +74,7 @@ class Commit:
def __init__(self, id_hash):
self.__id_hash = id_hash
- lines = _output_lines('git-cat-file commit %s' % id_hash)
+ lines = _output_lines(['git-cat-file', 'commit', id_hash])
for i in range(len(lines)):
line = lines[i]
if line == '\n':
@@ -102,8 +102,8 @@ class Commit:
return None
def get_parents(self):
- return _output_lines('git-rev-list --parents --max-count=1 %s'
- % self.__id_hash)[0].split()[1:]
+ return _output_lines(['git-rev-list', '--parents', '--max-count=1',
+ self.__id_hash])[0].split()[1:]
def get_author(self):
return self.__author
@@ -285,7 +285,7 @@ def get_head_file():
"""Returns the name of the file pointed to by the HEAD link
"""
return strip_prefix('refs/heads/',
- _output_one_line('git-symbolic-ref HEAD'))
+ _output_one_line(['git-symbolic-ref', 'HEAD']))
def set_head_file(ref):
"""Resets HEAD to point to a new ref
@@ -617,27 +617,27 @@ def commit(message, files = None, parents = None, allowempty = False,
must_switch = True
# write the index to repository
if tree_id == None:
- tree_id = _output_one_line('git-write-tree')
+ tree_id = _output_one_line(['git-write-tree'])
else:
must_switch = False
# the commit
- cmd = ''
+ cmd = ['env']
if author_name:
- cmd += 'GIT_AUTHOR_NAME="%s" ' % author_name
+ cmd += ['GIT_AUTHOR_NAME=%s' % author_name]
if author_email:
- cmd += 'GIT_AUTHOR_EMAIL="%s" ' % author_email
+ cmd += ['GIT_AUTHOR_EMAIL=%s' % author_email]
if author_date:
- cmd += 'GIT_AUTHOR_DATE="%s" ' % author_date
+ cmd += ['GIT_AUTHOR_DATE=%s' % author_date]
if committer_name:
- cmd += 'GIT_COMMITTER_NAME="%s" ' % committer_name
+ cmd += ['GIT_COMMITTER_NAME=%s' % committer_name]
if committer_email:
- cmd += 'GIT_COMMITTER_EMAIL="%s" ' % committer_email
- cmd += 'git-commit-tree %s' % tree_id
+ cmd += ['GIT_COMMITTER_EMAIL=%s' % committer_email]
+ cmd += ['git-commit-tree', tree_id]
# get the parents
for p in parents:
- cmd += ' -p %s' % p
+ cmd += ['-p', p]
commit_id = _output_one_line(cmd, message)
if must_switch:
@@ -652,9 +652,9 @@ def apply_diff(rev1, rev2, check_index = True, files = None):
the pushing would fall back to the three-way merge.
"""
if check_index:
- index_opt = '--index'
+ index_opt = ['--index']
else:
- index_opt = ''
+ index_opt = []
if not files:
files = []
@@ -662,7 +662,7 @@ def apply_diff(rev1, rev2, check_index = True, files = None):
diff_str = diff(files, rev1, rev2)
if diff_str:
try:
- _input_str('git-apply %s' % index_opt, diff_str)
+ _input_str(['git-apply'] + index_opt, diff_str)
except GitException:
return False
@@ -680,7 +680,7 @@ def merge(base, head1, head2, recursive = False):
# general when pushing or picking patches)
try:
# use _output() to mask the verbose prints of the tool
- _output('git-merge-recursive %s -- %s %s' % (base, head1, head2))
+ _output(['git-merge-recursive', base, '--', head1, head2])
except GitException, ex:
err_output = str(ex)
pass
@@ -696,7 +696,7 @@ def merge(base, head1, head2, recursive = False):
files = {}
stages_re = re.compile('^([0-7]+) ([0-9a-f]{40}) ([1-3])\t(.*)$', re.S)
- for line in _output('git-ls-files --unmerged --stage -z').split('\0'):
+ for line in _output(['git-ls-files', '--unmerged', '--stage', '-z']).split('\0'):
if not line:
continue
@@ -818,7 +818,7 @@ def files(rev1, rev2):
"""
result = ''
- for line in _output_lines('git-diff-tree -r %s %s' % (rev1, rev2)):
+ for line in _output_lines(['git-diff-tree', '-r', rev1, rev2]):
result += '%s %s\n' % tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
return result.rstrip()
@@ -828,7 +828,7 @@ def barefiles(rev1, rev2):
"""
result = ''
- for line in _output_lines('git-diff-tree -r %s %s' % (rev1, rev2)):
+ for line in _output_lines(['git-diff-tree', '-r', rev1, rev2]):
result += '%s\n' % line.rstrip().split(' ',4)[-1].split('\t',1)[-1]
return result.rstrip()
@@ -947,7 +947,7 @@ def apply_patch(filename = None, diff = None, base = None,
refresh_index()
try:
- _input_str('git-apply --index', diff)
+ _input_str(['git-apply', '--index'], diff)
except GitException:
if base:
switch(orig_head)
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/4] Make diff flags handling more modular.
2007-05-31 22:34 [StGIT PATCH 0/4] Rename detection, take 2 Yann Dirson
2007-05-31 22:34 ` [PATCH 1/4] Add 2 new contrib scripts Yann Dirson
2007-05-31 22:34 ` [PATCH 2/4] Call external commands without a shell where possible Yann Dirson
@ 2007-05-31 22:34 ` Yann Dirson
2007-05-31 22:34 ` [PATCH 4/4] Add new --diff-opts/-O flag to diff- and status-related commands Yann Dirson
3 siblings, 0 replies; 10+ messages in thread
From: Yann Dirson @ 2007-05-31 22:34 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/commands/diff.py | 7 ++++++-
stgit/commands/export.py | 8 +++++++-
stgit/commands/mail.py | 7 ++++++-
stgit/git.py | 12 ++++--------
4 files changed, 23 insertions(+), 11 deletions(-)
diff --git a/stgit/commands/diff.py b/stgit/commands/diff.py
index f56cbeb..b66c75b 100644
--- a/stgit/commands/diff.py
+++ b/stgit/commands/diff.py
@@ -79,10 +79,15 @@ def func(parser, options, args):
rev1 = 'HEAD'
rev2 = None
+ if options.binary:
+ diff_flags = [ '--binary' ]
+ else:
+ diff_flags = []
+
if options.stat:
out.stdout_raw(git.diffstat(args, git_id(rev1), git_id(rev2)) + '\n')
else:
diff_str = git.diff(args, git_id(rev1), git_id(rev2),
- binary = options.binary)
+ diff_flags = diff_flags )
if diff_str:
pager(diff_str)
diff --git a/stgit/commands/export.py b/stgit/commands/export.py
index cafcbe3..d6b36a9 100644
--- a/stgit/commands/export.py
+++ b/stgit/commands/export.py
@@ -87,6 +87,11 @@ def func(parser, options, args):
os.makedirs(dirname)
series = file(os.path.join(dirname, 'series'), 'w+')
+ if options.binary:
+ diff_flags = [ '--binary' ]
+ else:
+ diff_flags = []
+
applied = crt_series.get_applied()
if len(args) != 0:
patches = parse_patches(args, applied)
@@ -175,7 +180,8 @@ def func(parser, options, args):
# write the diff
git.diff(rev1 = patch.get_bottom(),
rev2 = patch.get_top(),
- out_fd = f, binary = options.binary)
+ out_fd = f,
+ diff_flags = diff_flags )
if not options.stdout:
f.close()
patch_no += 1
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index b95014c..7113cff 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -377,6 +377,11 @@ def __build_message(tmpl, patch, patch_nr, total_nr, msg_id, ref_id, options):
else:
prefix_str = ''
+ if options.binary:
+ diff_flags = [ '--binary' ]
+ else:
+ diff_flags = []
+
total_nr_str = str(total_nr)
patch_nr_str = str(patch_nr).zfill(len(total_nr_str))
if total_nr > 1:
@@ -394,7 +399,7 @@ def __build_message(tmpl, patch, patch_nr, total_nr, msg_id, ref_id, options):
'endofheaders': '',
'diff': git.diff(rev1 = git_id('%s//bottom' % patch),
rev2 = git_id('%s//top' % patch),
- binary = options.binary),
+ diff_flags = diff_flags ),
'diffstat': git.diffstat(rev1 = git_id('%s//bottom'%patch),
rev2 = git_id('%s//top' % patch)),
# for backward template compatibility
diff --git a/stgit/git.py b/stgit/git.py
index 5cdc8cd..7358fae 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -770,27 +770,23 @@ def status(files = None, modified = False, new = False, deleted = False,
out.stdout('%s' % fs[1])
def diff(files = None, rev1 = 'HEAD', rev2 = None, out_fd = None,
- binary = False):
+ diff_flags = []):
"""Show the diff between rev1 and rev2
"""
if not files:
files = []
- args = []
- if binary:
- args.append('--binary')
-
if rev1 and rev2:
- diff_str = _output(['git-diff-tree', '-p'] + args
+ diff_str = _output(['git-diff-tree', '-p'] + diff_flags
+ [rev1, rev2, '--'] + files)
elif rev1 or rev2:
refresh_index()
if rev2:
diff_str = _output(['git-diff-index', '-p', '-R']
- + args + [rev2, '--'] + files)
+ + diff_flags + [rev2, '--'] + files)
else:
diff_str = _output(['git-diff-index', '-p']
- + args + [rev1, '--'] + files)
+ + diff_flags + [rev1, '--'] + files)
else:
diff_str = ''
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/4] Add new --diff-opts/-O flag to diff- and status-related commands.
2007-05-31 22:34 [StGIT PATCH 0/4] Rename detection, take 2 Yann Dirson
` (2 preceding siblings ...)
2007-05-31 22:34 ` [PATCH 3/4] Make diff flags handling more modular Yann Dirson
@ 2007-05-31 22:34 ` Yann Dirson
2007-06-04 22:15 ` Catalin Marinas
3 siblings, 1 reply; 10+ messages in thread
From: Yann Dirson @ 2007-05-31 22:34 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
This new flag allows to pass arbitrary flags to the git-diff calls
underlying several StGIT commands. It can be used to pass flags
affecting both diff- and status-generating commands (eg. -M or -C), or
flags only affecting diff-generating ones (eg. --color, --binary).
It supercedes --binary for commands where it was allowed,
'-O --binary' is now available for the same functionality.
Signed-off-by: Yann Dirson <ydirson@altern.org>
---
stgit/commands/diff.py | 9 ++++-----
stgit/commands/export.py | 9 ++++-----
stgit/commands/files.py | 9 ++++++++-
stgit/commands/mail.py | 9 ++++-----
stgit/commands/show.py | 11 +++++++++--
stgit/commands/status.py | 10 +++++++++-
stgit/git.py | 21 ++++++++++++---------
7 files changed, 50 insertions(+), 28 deletions(-)
diff --git a/stgit/commands/diff.py b/stgit/commands/diff.py
index b66c75b..f8b19f8 100644
--- a/stgit/commands/diff.py
+++ b/stgit/commands/diff.py
@@ -44,9 +44,8 @@ shows the specified patch (defaulting to the current one)."""
options = [make_option('-r', '--range',
metavar = 'rev1[..[rev2]]', dest = 'revs',
help = 'show the diff between revisions'),
- make_option('--binary',
- help = 'output a diff even for binary files',
- action = 'store_true'),
+ make_option('-O', '--diff-opts',
+ help = 'options to pass to git-diff'),
make_option('-s', '--stat',
help = 'show the stat instead of the diff',
action = 'store_true')]
@@ -79,8 +78,8 @@ def func(parser, options, args):
rev1 = 'HEAD'
rev2 = None
- if options.binary:
- diff_flags = [ '--binary' ]
+ if options.diff_opts:
+ diff_flags = options.diff_opts.split()
else:
diff_flags = []
diff --git a/stgit/commands/export.py b/stgit/commands/export.py
index d6b36a9..35851bc 100644
--- a/stgit/commands/export.py
+++ b/stgit/commands/export.py
@@ -62,9 +62,8 @@ options = [make_option('-d', '--dir',
help = 'Use FILE as a template'),
make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
- make_option('--binary',
- help = 'output a diff even for binary files',
- action = 'store_true'),
+ make_option('-O', '--diff-opts',
+ help = 'options to pass to git-diff'),
make_option('-s', '--stdout',
help = 'dump the patches to the standard output',
action = 'store_true')]
@@ -87,8 +86,8 @@ def func(parser, options, args):
os.makedirs(dirname)
series = file(os.path.join(dirname, 'series'), 'w+')
- if options.binary:
- diff_flags = [ '--binary' ]
+ if options.diff_opts:
+ diff_flags = options.diff_opts.split()
else:
diff_flags = []
diff --git a/stgit/commands/files.py b/stgit/commands/files.py
index 59893d8..659a82b 100644
--- a/stgit/commands/files.py
+++ b/stgit/commands/files.py
@@ -38,6 +38,8 @@ options = [make_option('-s', '--stat',
action = 'store_true'),
make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
+ make_option('-O', '--diff-opts',
+ help = 'options to pass to git-diff'),
make_option('--bare',
help = 'bare file names (useful for scripting)',
action = 'store_true')]
@@ -61,4 +63,9 @@ def func(parser, options, args):
elif options.bare:
out.stdout_raw(git.barefiles(rev1, rev2) + '\n')
else:
- out.stdout_raw(git.files(rev1, rev2) + '\n')
+ if options.diff_opts:
+ diff_flags = options.diff_opts.split()
+ else:
+ diff_flags = []
+
+ out.stdout_raw(git.files(rev1, rev2, diff_flags = diff_flags) + '\n')
diff --git a/stgit/commands/mail.py b/stgit/commands/mail.py
index 7113cff..cec1828 100644
--- a/stgit/commands/mail.py
+++ b/stgit/commands/mail.py
@@ -120,9 +120,8 @@ options = [make_option('-a', '--all',
help = 'username for SMTP authentication'),
make_option('-b', '--branch',
help = 'use BRANCH instead of the default one'),
- make_option('--binary',
- help = 'output a diff even for binary files',
- action = 'store_true'),
+ make_option('-O', '--diff-opts',
+ help = 'options to pass to git-diff'),
make_option('-m', '--mbox',
help = 'generate an mbox file instead of sending',
action = 'store_true')]
@@ -377,8 +376,8 @@ def __build_message(tmpl, patch, patch_nr, total_nr, msg_id, ref_id, options):
else:
prefix_str = ''
- if options.binary:
- diff_flags = [ '--binary' ]
+ if options.diff_opts:
+ diff_flags = options.diff_opts.split()
else:
diff_flags = []
diff --git a/stgit/commands/show.py b/stgit/commands/show.py
index a270efd..ea4c874 100644
--- a/stgit/commands/show.py
+++ b/stgit/commands/show.py
@@ -35,7 +35,9 @@ options = [make_option('-a', '--applied',
action = 'store_true'),
make_option('-u', '--unapplied',
help = 'show the unapplied patches',
- action = 'store_true')]
+ action = 'store_true'),
+ make_option('-O', '--diff-opts',
+ help = 'options to pass to git-diff')]
def func(parser, options, args):
@@ -58,8 +60,13 @@ def func(parser, options, args):
else:
patches = parse_patches(args, applied + unapplied, len(applied))
+ if options.diff_opts:
+ diff_flags = options.diff_opts.split()
+ else:
+ diff_flags = []
+
commit_ids = [git_id(patch) for patch in patches]
- commit_str = '\n'.join([git.pretty_commit(commit_id)
+ commit_str = '\n'.join([git.pretty_commit(commit_id, diff_flags=diff_flags)
for commit_id in commit_ids])
if commit_str:
pager(commit_str)
diff --git a/stgit/commands/status.py b/stgit/commands/status.py
index b8f0623..156552b 100644
--- a/stgit/commands/status.py
+++ b/stgit/commands/status.py
@@ -58,6 +58,8 @@ options = [make_option('-m', '--modified',
make_option('-x', '--noexclude',
help = 'do not exclude any files from listing',
action = 'store_true'),
+ make_option('-O', '--diff-opts',
+ help = 'options to pass to git-diff'),
make_option('--reset',
help = 'reset the current tree changes',
action = 'store_true')]
@@ -75,5 +77,11 @@ def func(parser, options, args):
resolved_all()
git.reset()
else:
+ if options.diff_opts:
+ diff_flags = options.diff_opts.split()
+ else:
+ diff_flags = []
+
git.status(args, options.modified, options.new, options.deleted,
- options.conflict, options.unknown, options.noexclude)
+ options.conflict, options.unknown, options.noexclude,
+ diff_flags = diff_flags)
diff --git a/stgit/git.py b/stgit/git.py
index 7358fae..4bc41aa 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -217,7 +217,7 @@ def __run(cmd, args=None):
return 0
def __tree_status(files = None, tree_id = 'HEAD', unknown = False,
- noexclude = True, verbose = False):
+ noexclude = True, verbose = False, diff_flags = []):
"""Returns a list of pairs - [status, filename]
"""
if verbose:
@@ -254,7 +254,8 @@ def __tree_status(files = None, tree_id = 'HEAD', unknown = False,
cache_files += [('C', filename) for filename in conflicts]
# the rest
- for line in _output_lines(['git-diff-index', tree_id, '--'] + files):
+ for line in _output_lines(['git-diff-index'] + diff_flags +
+ [ tree_id, '--'] + files):
fs = tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
if fs[1] not in conflicts:
cache_files.append(fs)
@@ -737,13 +738,15 @@ def merge(base, head1, head2, recursive = False):
raise GitException, 'GIT index merging failed (possible conflicts)'
def status(files = None, modified = False, new = False, deleted = False,
- conflict = False, unknown = False, noexclude = False):
+ conflict = False, unknown = False, noexclude = False,
+ diff_flags = []):
"""Show the tree status
"""
if not files:
files = []
- cache_files = __tree_status(files, unknown = True, noexclude = noexclude)
+ cache_files = __tree_status(files, unknown = True, noexclude = noexclude,
+ diff_flags = diff_flags)
all = not (modified or new or deleted or conflict or unknown)
if not all:
@@ -809,12 +812,12 @@ def diffstat(files = None, rev1 = 'HEAD', rev2 = None):
raise GitException, 'git.diffstat failed'
return diff_str
-def files(rev1, rev2):
+def files(rev1, rev2, diff_flags = []):
"""Return the files modified between rev1 and rev2
"""
result = ''
- for line in _output_lines(['git-diff-tree', '-r', rev1, rev2]):
+ for line in _output_lines(['git-diff-tree'] + diff_flags + ['-r', rev1, rev2]):
result += '%s %s\n' % tuple(line.rstrip().split(' ',4)[-1].split('\t',1))
return result.rstrip()
@@ -829,11 +832,11 @@ def barefiles(rev1, rev2):
return result.rstrip()
-def pretty_commit(commit_id = 'HEAD'):
+def pretty_commit(commit_id = 'HEAD', diff_flags = []):
"""Return a given commit (log + diff)
"""
- return _output(['git-diff-tree', '--cc', '--always', '--pretty', '-r',
- commit_id])
+ return _output(['git-diff-tree'] + diff_flags +
+ ['--cc', '--always', '--pretty', '-r', commit_id])
def checkout(files = None, tree_id = None, force = False):
"""Check out the given or all files
^ permalink raw reply related [flat|nested] 10+ messages in thread