Git development
 help / color / mirror / Atom feed
* Re: Considering teaching plumbing to users harmful
From: Kevin Ballard @ 2008-07-17 21:10 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: Petr Baudis, David Kastrup, git
In-Reply-To: <200807172303.19339.jnareb@gmail.com>

On Jul 17, 2008, at 2:03 PM, Jakub Narebski wrote:

> Dnia czwartek 17. lipca 2008 22:40, Kevin Ballard napisał:
>> On Jul 17, 2008, at 1:26 PM, Petr Baudis wrote:
>>> On Thu, Jul 17, 2008 at 01:12:57PM -0700, Kevin Ballard wrote:
>
>>>> There is one facet of submodules that annoys me, because it
>>>> prevents me from using them as a replacement for svn:externals.
>>>> Namely, the submodule refers to a specific repository, but not
>>>> a path within that repository.  I work with svn repos that use
>>>> svn:externals to peg revisions (as is appropriate) but they all
>>>> refer to various paths within the other repositories, and the
>>>> only way I can deal with that is to throw symlinks everywhere.
>>>
>>> Actually, is this a big problem? Git can track symlinks and without
>>> adding support for overall partial checkouts, adding this would feel
>>> like too huge a hack to me.
>>>
>>> Also, when converting to a different VCS, it might be sensible to
>>> adjust
>>> your modules setup a bit as well - the requirement to include only
>>> particular subdirectory of a submodule sounds rather strange to me.
>>
>> The problem is right now I maintain a bunch of git-svn mirrors of
>> internal svn repos, but the company isn't willing to switch to git.
>> And we use subtree externals links to do things like pull in the
>> models from one rails app into another, or pull in various
>> subdirectories of the "support" repository.
>
> I think the correct solution would be to make 'models' separate
> repository... or create interim repository containing only changes
> to 'models', and having 'models' as its top directory.

That would require significantly more work to deal with than using  
symlinks like I described, since the company is not willing to adjust  
anything to help with my git usage (as I'm the only git user here).

-Kevin Ballard

-- 
Kevin Ballard
http://kevin.sb.org
kevin@sb.org
http://www.tildesoft.com

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Jakub Narebski @ 2008-07-17 21:03 UTC (permalink / raw)
  To: Kevin Ballard; +Cc: Petr Baudis, David Kastrup, git
In-Reply-To: <57BAA376-10A4-4E3F-BB8E-37B46E8C49D3@sb.org>

Dnia czwartek 17. lipca 2008 22:40, Kevin Ballard napisał:
> On Jul 17, 2008, at 1:26 PM, Petr Baudis wrote:
>> On Thu, Jul 17, 2008 at 01:12:57PM -0700, Kevin Ballard wrote:

>>> There is one facet of submodules that annoys me, because it  
>>> prevents me from using them as a replacement for svn:externals.
>>> Namely, the submodule refers to a specific repository, but not
>>> a path within that repository.  I work with svn repos that use
>>> svn:externals to peg revisions (as is appropriate) but they all
>>> refer to various paths within the other repositories, and the
>>> only way I can deal with that is to throw symlinks everywhere.
>>
>> Actually, is this a big problem? Git can track symlinks and without
>> adding support for overall partial checkouts, adding this would feel
>> like too huge a hack to me.
>>
>> Also, when converting to a different VCS, it might be sensible to  
>> adjust
>> your modules setup a bit as well - the requirement to include only
>> particular subdirectory of a submodule sounds rather strange to me.
> 
> The problem is right now I maintain a bunch of git-svn mirrors of  
> internal svn repos, but the company isn't willing to switch to git.  
> And we use subtree externals links to do things like pull in the  
> models from one rails app into another, or pull in various  
> subdirectories of the "support" repository.

I think the correct solution would be to make 'models' separate 
repository... or create interim repository containing only changes
to 'models', and having 'models' as its top directory.

-- 
Jakub Narebski
Poland

^ permalink raw reply

* [StGit PATCH] Fix uncommit status message
From: Karl Hasselström @ 2008-07-17 20:43 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git

It should say

  Uncommitting to 8561b089afbaed2651591e5a4574fdca451d82f2 (exclusive) ...

not

  Uncommitting to Commit<sha1: 8561b089afbaed2651591e5a4574fdca451d82f2, data: None> (exclusive) ...

(though arguably, the sha1 should be abbreviated as well).

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

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


diff --git a/stgit/commands/uncommit.py b/stgit/commands/uncommit.py
index eb39fcc..0f43b49 100644
--- a/stgit/commands/uncommit.py
+++ b/stgit/commands/uncommit.py
@@ -104,9 +104,9 @@ def func(parser, options, args):
             next_commit = get_parent(next_commit)
     else:
         if options.exclusive:
-            out.start('Uncommitting to %s (exclusive)' % to_commit)
+            out.start('Uncommitting to %s (exclusive)' % to_commit.sha1)
         else:
-            out.start('Uncommitting to %s' % to_commit)
+            out.start('Uncommitting to %s' % to_commit.sha1)
         while True:
             if next_commit == to_commit:
                 if not options.exclusive:

^ permalink raw reply related

* [StGit PATCH 5/5] Global performance logging
From: Karl Hasselström @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20080717204133.23407.34264.stgit@yoghurt>

Measure the time for the whole program, and how much of that was
subprocess calls.

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 stgit/main.py |   11 +++++++++--
 stgit/run.py  |   32 ++++++++++++++++++++++++++++----
 2 files changed, 37 insertions(+), 6 deletions(-)


diff --git a/stgit/main.py b/stgit/main.py
index aa1f8ef..64cff30 100644
--- a/stgit/main.py
+++ b/stgit/main.py
@@ -23,7 +23,7 @@ from optparse import OptionParser
 
 import stgit.commands
 from stgit.out import *
-from stgit import utils
+from stgit import run, utils
 
 #
 # The commands map
@@ -192,7 +192,7 @@ def print_help():
 #
 # The main function (command dispatcher)
 #
-def main():
+def _main():
     """The main function
     """
     global prog
@@ -293,3 +293,10 @@ def main():
         sys.exit(utils.STGIT_BUG_ERROR)
 
     sys.exit(ret or utils.STGIT_SUCCESS)
+
+def main():
+    run.start_logging()
+    try:
+        _main()
+    finally:
+        run.stop_logging()
diff --git a/stgit/run.py b/stgit/run.py
index befd3c1..e46836b 100644
--- a/stgit/run.py
+++ b/stgit/run.py
@@ -42,7 +42,27 @@ def get_log_mode(spec):
         f = out
     return (log_mode, f)
 
-(_log_mode, _logfile) = get_log_mode(os.environ.get('STGIT_SUBPROCESS_LOG', ''))
+def start_logging():
+    global _log_mode, _logfile, _log_starttime, _log_subproctime
+    (_log_mode, _logfile) = get_log_mode(
+        os.environ.get('STGIT_SUBPROCESS_LOG', ''))
+    _log_starttime = datetime.datetime.now()
+    _log_subproctime = 0.0
+
+def duration(t1, t2):
+    d = t2 - t1
+    return 86400*d.days + d.seconds + 1e-6*d.microseconds
+
+def stop_logging():
+    if _log_mode != 'profile':
+        return
+    ttime = duration(_log_starttime, datetime.datetime.now())
+    rtime = ttime - _log_subproctime
+    _logfile.info('Total time: %1.3f s' % ttime,
+                  'Time spent in subprocess calls: %1.3f s (%1.1f%%)'
+                  % (_log_subproctime, 100*_log_subproctime/ttime),
+                  'Remaining time: %1.3f s (%1.1f%%)'
+                  % (rtime, 100*rtime/ttime))
 
 class Run:
     exc = RunException
@@ -68,12 +88,16 @@ class Run:
             _logfile.start('Running subprocess %s' % self.__cmd)
             self.__starttime = datetime.datetime.now()
     def __log_end(self, retcode):
+        global _log_subproctime, _log_starttime
         if _log_mode == 'debug':
             _logfile.done('return code: %d' % retcode)
         elif _log_mode == 'profile':
-            duration = datetime.datetime.now() - self.__starttime
-            _logfile.done('%1.3f s' % (duration.microseconds/1e6
-                                       + duration.seconds))
+            n = datetime.datetime.now()
+            d = duration(self.__starttime, n)
+            _logfile.done('%1.3f s' % d)
+            _log_subproctime += d
+            _logfile.info('Time since program start: %1.3f s'
+                          % duration(_log_starttime, n))
     def __check_exitcode(self):
         if self.__good_retvals == None:
             return

^ permalink raw reply related

* [StGit PATCH 4/5] Log subprocess calls during performance testing
From: Karl Hasselström @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20080717204133.23407.34264.stgit@yoghurt>

Log each command's subprocess calls to a separate file.

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 perf/perftest.py |   12 ++++++++++--
 1 files changed, 10 insertions(+), 2 deletions(-)


diff --git a/perf/perftest.py b/perf/perftest.py
index 7072772..e5ed04b 100644
--- a/perf/perftest.py
+++ b/perf/perftest.py
@@ -1,4 +1,4 @@
-import datetime, subprocess, sys
+import datetime, os, os.path, subprocess, sys
 
 def duration(t1, t2):
     d = t2 - t1
@@ -8,8 +8,16 @@ class Run(object):
     def __init__(self):
         self.__cwd = None
         self.__log = []
+    def __logfile(self, cmd):
+        fn = os.path.join(os.getcwd(), '%04d.log' % len(self.__log))
+        f = open(fn, 'w')
+        f.write(' '.join(cmd) + '\n' + '-'*70 + '\n\n')
+        f.close()
+        return fn
     def __call__(self, *cmd, **args):
-        kwargs = { 'cwd': self.__cwd }
+        env = dict(os.environ)
+        env['STGIT_SUBPROCESS_LOG'] = 'profile:' + self.__logfile(cmd)
+        kwargs = { 'cwd': self.__cwd, 'env': env }
         if args.get('capture_stdout', False):
             kwargs['stdout'] = subprocess.PIPE
         start = datetime.datetime.now()

^ permalink raw reply related

* [StGit PATCH 3/5] Show full command in subprocess profiling
From: Karl Hasselström @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20080717204133.23407.34264.stgit@yoghurt>

Showing just the executable name isn't so useful now that it's always
"git".

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 stgit/run.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)


diff --git a/stgit/run.py b/stgit/run.py
index 9d50e43..befd3c1 100644
--- a/stgit/run.py
+++ b/stgit/run.py
@@ -65,7 +65,7 @@ class Run:
                     if k not in os.environ or os.environ[k] != self.__env[k]:
                         _logfile.info('%s: %s' % (k, self.__env[k]))
         elif _log_mode == 'profile':
-            _logfile.start('Running subprocess %s' % self.__cmd[0])
+            _logfile.start('Running subprocess %s' % self.__cmd)
             self.__starttime = datetime.datetime.now()
     def __log_end(self, retcode):
         if _log_mode == 'debug':

^ permalink raw reply related

* [StGit PATCH 2/5] Log subproces activity to a file
From: Karl Hasselström @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20080717204133.23407.34264.stgit@yoghurt>

If the user sets $STGIT_SUBPROCESS_LOG to a log mode followed by a
colon and a file name, append the log to that file instead of writing
it to stdout.

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 stgit/out.py |   11 +++++++----
 stgit/run.py |   35 +++++++++++++++++++++++------------
 2 files changed, 30 insertions(+), 16 deletions(-)


diff --git a/stgit/out.py b/stgit/out.py
index 485b830..753c176 100644
--- a/stgit/out.py
+++ b/stgit/out.py
@@ -20,7 +20,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 import sys, textwrap
 
 class MessagePrinter(object):
-    def __init__(self):
+    def __init__(self, file = None):
         class Output(object):
             def __init__(self, write, flush):
                 self.write = write
@@ -68,9 +68,12 @@ class MessagePrinter(object):
                 self.new_line()
                 self.write(string)
                 self.at_start_of_line = string.endswith('\n')
-        self.__stderr = Output(sys.stderr.write, sys.stderr.flush)
-        self.__stdout = Output(sys.stdout.write, sys.stdout.flush)
-        if sys.stdout.isatty():
+        if file:
+            self.__stdout = self.__stderr = Output(file.write, file.flush)
+        else:
+            self.__stdout = Output(sys.stdout.write, sys.stdout.flush)
+            self.__stderr = Output(sys.stdout.write, sys.stdout.flush)
+        if file or sys.stdout.isatty():
             self.__out = self.__stdout
             self.__err = self.__stdout
         else:
diff --git a/stgit/run.py b/stgit/run.py
index 0b79729..9d50e43 100644
--- a/stgit/run.py
+++ b/stgit/run.py
@@ -27,12 +27,22 @@ class RunException(StgException):
     subprocess."""
     pass
 
-_all_log_modes = ['debug', 'profile']
-_log_mode = os.environ.get('STGIT_SUBPROCESS_LOG', '')
-if _log_mode and not _log_mode in _all_log_modes:
-    out.warn(('Unknown log mode "%s" specified in $STGIT_SUBPROCESS_LOG.'
-              % _log_mode),
-             'Valid values are: %s' % ', '.join(_all_log_modes))
+def get_log_mode(spec):
+    if not ':' in spec:
+        spec += ':'
+    (log_mode, outfile) = spec.split(':', 1)
+    all_log_modes = ['debug', 'profile']
+    if log_mode and not log_mode in all_log_modes:
+        out.warn(('Unknown log mode "%s" specified in $STGIT_SUBPROCESS_LOG.'
+                  % log_mode),
+                 'Valid values are: %s' % ', '.join(all_log_modes))
+    if outfile:
+        f = MessagePrinter(open(outfile, 'a'))
+    else:
+        f = out
+    return (log_mode, f)
+
+(_log_mode, _logfile) = get_log_mode(os.environ.get('STGIT_SUBPROCESS_LOG', ''))
 
 class Run:
     exc = RunException
@@ -47,22 +57,23 @@ class Run:
         self.__discard_stderr = False
     def __log_start(self):
         if _log_mode == 'debug':
-            out.start('Running subprocess %s' % self.__cmd)
+            _logfile.start('Running subprocess %s' % self.__cmd)
             if self.__cwd != None:
-                out.info('cwd: %s' % self.__cwd)
+                _logfile.info('cwd: %s' % self.__cwd)
             if self.__env != None:
                 for k in sorted(self.__env.iterkeys()):
                     if k not in os.environ or os.environ[k] != self.__env[k]:
-                        out.info('%s: %s' % (k, self.__env[k]))
+                        _logfile.info('%s: %s' % (k, self.__env[k]))
         elif _log_mode == 'profile':
-            out.start('Running subprocess %s' % self.__cmd[0])
+            _logfile.start('Running subprocess %s' % self.__cmd[0])
             self.__starttime = datetime.datetime.now()
     def __log_end(self, retcode):
         if _log_mode == 'debug':
-            out.done('return code: %d' % retcode)
+            _logfile.done('return code: %d' % retcode)
         elif _log_mode == 'profile':
             duration = datetime.datetime.now() - self.__starttime
-            out.done('%1.3f s' % (duration.microseconds/1e6 + duration.seconds))
+            _logfile.done('%1.3f s' % (duration.microseconds/1e6
+                                       + duration.seconds))
     def __check_exitcode(self):
         if self.__good_retvals == None:
             return

^ permalink raw reply related

* [StGit PATCH 1/5] Add some performance testing scripts
From: Karl Hasselström @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git
In-Reply-To: <20080717204133.23407.34264.stgit@yoghurt>

find_patchbomb.py: Given a git repo, finds the longest linear sequence
  of commits. Useful for testing StGit on a real repository.

setup.sh: Creates two test repositories, one synthetic and one based
  on the Linux kernel repo, with strategically placed tags.

create_synthetic_repo.py: Helper script for setup.sh; it produces
  output that is to be fed to git fast-import.

perftest.py: Runs one of a (small) number of hard-coded performance
  tests against a copy of one of the repos created by setup.sh. The
  initial testcases all involve uncommitting a large number of patches
  and then rebasing them.

Signed-off-by: Karl Hasselström <kha@treskal.com>

---

 perf/.gitignore               |    2 +
 perf/create_synthetic_repo.py |   61 ++++++++++++++++++++++++++++
 perf/find_patchbomb.py        |   31 ++++++++++++++
 perf/perftest.py              |   88 +++++++++++++++++++++++++++++++++++++++++
 perf/setup.sh                 |   52 ++++++++++++++++++++++++
 5 files changed, 234 insertions(+), 0 deletions(-)
 create mode 100644 perf/.gitignore
 create mode 100644 perf/create_synthetic_repo.py
 create mode 100644 perf/find_patchbomb.py
 create mode 100644 perf/perftest.py
 create mode 100644 perf/setup.sh


diff --git a/perf/.gitignore b/perf/.gitignore
new file mode 100644
index 0000000..dfae110
--- /dev/null
+++ b/perf/.gitignore
@@ -0,0 +1,2 @@
+/*.orig
+/*.trash
diff --git a/perf/create_synthetic_repo.py b/perf/create_synthetic_repo.py
new file mode 100644
index 0000000..4d6ef6b
--- /dev/null
+++ b/perf/create_synthetic_repo.py
@@ -0,0 +1,61 @@
+next_mark = 1
+def get_mark():
+    global next_mark
+    next_mark += 1
+    return (next_mark - 1)
+
+def write_data(s):
+    print 'data %d' % len(s)
+    print s
+
+def write_blob(s):
+    print 'blob'
+    m = get_mark()
+    print 'mark :%d' % m
+    write_data(s)
+    return m
+
+def write_commit(branch, files, msg, parent = None):
+    print 'commit %s' % branch
+    m = get_mark()
+    print 'mark :%d' % m
+    auth = 'X Ample <xa@example.com> %d +0000' % (1000000000 + m)
+    print 'author %s' % auth
+    print 'committer %s' % auth
+    write_data(msg)
+    if parent != None:
+        print 'from :%d' % parent
+    for fn, fm in sorted(files.iteritems()):
+        print 'M 100644 :%d %s' % (fm, fn)
+    return m
+
+def set_ref(ref, mark):
+    print 'reset %s' % ref
+    print 'from :%d' % mark
+
+def stdblob(fn):
+    return ''.join('%d %s\n' % (x, fn) for x in xrange(10))
+
+def iter_paths():
+    for i in xrange(32):
+        for j in xrange(32):
+            for k in xrange(32):
+                yield '%02d/%02d/%02d' % (i, j, k)
+
+def setup():
+    def t(name): return 'refs/tags/%s' % name
+    files = dict((fn, write_blob(stdblob(fn))) for fn in iter_paths())
+    initial = write_commit(t('bomb-base'), files, 'Initial commit')
+    set_ref(t('bomb-top'), initial)
+    for fn in iter_paths():
+        write_commit(t('bomb-top'),
+                     { fn: write_blob(stdblob(fn) + 'Last line\n') },
+                     'Add last line to %s' % fn)
+    write_commit(t('add-file'), { 'woo-hoo.txt': write_blob('woo-hoo\n') },
+                 'Add a new file', parent = initial)
+    files = dict((fn, write_blob('First line\n' + stdblob(fn)))
+                 for fn in iter_paths())
+    write_commit(t('modify-all'), files, 'Add first line to all files',
+                 parent = initial)
+
+setup()
diff --git a/perf/find_patchbomb.py b/perf/find_patchbomb.py
new file mode 100644
index 0000000..69a78c7
--- /dev/null
+++ b/perf/find_patchbomb.py
@@ -0,0 +1,31 @@
+# Feed this with git rev-list HEAD --parents
+
+import sys
+
+parents = {}
+for line in sys.stdin.readlines():
+    commits = line.split()
+    parents[commits[0]] = commits[1:]
+
+sequence_num = {}
+stack = []
+for commit in parents.keys():
+    stack.append(commit)
+    while stack:
+        c = stack.pop()
+        if c in sequence_num:
+            continue
+        ps = parents[c]
+        if len(ps) == 1:
+            p = ps[0]
+            if p in sequence_num:
+                sequence_num[c] = 1 + sequence_num[p]
+            else:
+                stack.append(c)
+                stack.append(p)
+        else:
+            sequence_num[c] = 0
+
+(num, commit) = max((num, commit) for (commit, num)
+                    in sequence_num.iteritems())
+print '%s is a sequence of %d patches' % (commit, num)
diff --git a/perf/perftest.py b/perf/perftest.py
new file mode 100644
index 0000000..7072772
--- /dev/null
+++ b/perf/perftest.py
@@ -0,0 +1,88 @@
+import datetime, subprocess, sys
+
+def duration(t1, t2):
+    d = t2 - t1
+    return 86400*d.days + d.seconds + 1e-6*d.microseconds
+
+class Run(object):
+    def __init__(self):
+        self.__cwd = None
+        self.__log = []
+    def __call__(self, *cmd, **args):
+        kwargs = { 'cwd': self.__cwd }
+        if args.get('capture_stdout', False):
+            kwargs['stdout'] = subprocess.PIPE
+        start = datetime.datetime.now()
+        p = subprocess.Popen(cmd, **kwargs)
+        (out, err) = p.communicate()
+        stop = datetime.datetime.now()
+        self.__log.append((cmd, duration(start, stop)))
+        return out
+    def cd(self, dir):
+        self.__cwd = dir
+    def summary(self):
+        def pcmd(c): return ' '.join(c)
+        def ptime(t): return '%.3f' % t
+        (cs, times) = zip(*self.__log)
+        ttime = sum(times)
+        cl = max(len(pcmd(c)) for c in cs)
+        tl = max(len(ptime(t)) for t in list(times) + [ttime])
+        for (c, t) in self.__log:
+            print '%*s  %*s' % (tl, ptime(t), -cl, pcmd(c))
+        print '%*s' % (tl, ptime(ttime))
+
+perftests = {}
+perftestdesc = {}
+def perftest(desc, name = None):
+    def decorator(f):
+        def g():
+            r = Run()
+            f(r)
+            r.summary()
+        perftests[name or f.__name__] = g
+        perftestdesc[name or f.__name__] = desc
+        return g
+    return decorator
+
+def copy_testdir(dir):
+    tmp = dir + '.trash'
+    r = Run()
+    r('rsync', '-a', '--delete', dir + '.orig/', tmp)
+    return tmp
+
+def new_rebase(r, ref):
+    top = r('stg', 'top', capture_stdout = True)
+    r('stg', 'pop', '-a')
+    r('git', 'reset', '--hard', ref)
+    r('stg', 'goto', top.strip())
+
+def old_rebase(r, ref):
+    r('stg', 'rebase', ref)
+
+def def_rebasetest(rebase, dir, tag):
+    @perftest('%s rebase onto %s in %s' % (rebase, tag, dir),
+              'rebase-%srebase-%s-%s' % (rebase, tag, dir))
+    def rebasetest(r):
+        r.cd(copy_testdir(dir))
+        r('stg', 'init')
+        if dir == 'synt':
+            r('stg', 'uncommit', '-n', '500')
+        else:
+            r('stg', 'uncommit', '-x', '-t', 'bomb-base')
+        if rebase == 'new':
+            new_rebase(r, tag)
+        else:
+            old_rebase(r, tag)
+for rebase in ['old', 'new']:
+    for (dir, tag) in [('synt', 'add-file'),
+                       ('synt', 'modify-all'),
+                       ('linux', 'add-file')]:
+        def_rebasetest(rebase, dir, tag)
+
+args = sys.argv[1:]
+if len(args) == 0:
+    for (fun, desc) in sorted(perftestdesc.iteritems()):
+        print '%s: %s' % (fun, desc)
+else:
+    for test in args:
+        perftests[test]()
diff --git a/perf/setup.sh b/perf/setup.sh
new file mode 100644
index 0000000..b92ddfc
--- /dev/null
+++ b/perf/setup.sh
@@ -0,0 +1,52 @@
+krepo='git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git'
+
+get_linux() {
+    rm -rf linux.orig
+    git clone "$krepo" linux.orig
+}
+
+mod_linux() {
+    # Tag the top and base of a very long linear sequence of commits.
+    git tag bomb-top 85040bcb4643cba578839e953f25e2d1965d83d0
+    git tag bomb-base bomb-top~1470
+
+    # Add a file at the base of the linear sequence.
+    git checkout bomb-base
+    echo "woo-hoo" > woo-hoo.txt
+    git add woo-hoo.txt
+    git commit -m "Add a file"
+    git tag add-file
+
+    # Clean up and go to start position.
+    git gc
+    git update-ref refs/heads/master bomb-top
+    git checkout master
+}
+
+setup_linux () {
+    get_linux
+    ( cd linux.orig && mod_linux )
+}
+
+create_empty () {
+    dir="$1"
+    rm -rf $dir
+    mkdir $dir
+    ( cd $dir && git init )
+}
+
+fill_synthetic () {
+    python ../create_synthetic_repo.py | git fast-import
+    git gc --aggressive
+    git update-ref refs/heads/master bomb-top
+    git checkout master
+}
+
+setup_synthetic()
+{
+    create_empty synt.orig
+    ( cd synt.orig && fill_synthetic )
+}
+
+setup_linux
+setup_synthetic

^ permalink raw reply related

* [StGit PATCH 0/5] Performance testing tools
From: Karl Hasselström @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Catalin Marinas; +Cc: git

Here's the same scripts I posted earlier, but polished and extended.

---

Karl Hasselström (5):
      Global performance logging
      Log subprocess calls during performance testing
      Show full command in subprocess profiling
      Log subproces activity to a file
      Add some performance testing scripts


 perf/.gitignore               |    2 +
 perf/create_synthetic_repo.py |   61 ++++++++++++++++++++++++++
 perf/find_patchbomb.py        |   31 +++++++++++++
 perf/perftest.py              |   96 +++++++++++++++++++++++++++++++++++++++++
 perf/setup.sh                 |   52 ++++++++++++++++++++++
 stgit/main.py                 |   11 ++++-
 stgit/out.py                  |   11 +++--
 stgit/run.py                  |   61 +++++++++++++++++++++-----
 8 files changed, 306 insertions(+), 19 deletions(-)
 create mode 100644 perf/.gitignore
 create mode 100644 perf/create_synthetic_repo.py
 create mode 100644 perf/find_patchbomb.py
 create mode 100644 perf/perftest.py
 create mode 100644 perf/setup.sh

-- 
Karl Hasselström, kha@treskal.com
      www.treskal.com/kalle

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Kevin Ballard @ 2008-07-17 20:42 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: David Kastrup, git
In-Reply-To: <200807172234.19146.jnareb@gmail.com>

On Jul 17, 2008, at 1:34 PM, Jakub Narebski wrote:

> On Thu, 17 July 2008, Kevin Ballard wrote:
>> On Jul 17, 2008, at 1:04 PM, Jakub Narebski wrote:
>>
>>> Git submodules are roughly equivalent to svn:externals with peg
>>> revisions; I mean here that they refer not to some branch in some
>>> external repository, but to specific revision.  This is the only  
>>> sane
>>> design, as it assures that when checking out some historical  
>>> revision,
>>> the state that is checked out will be the same for everybody.
>>>
>>> Please take into account however that submodules are quite new
>>> feature, and while underlying engine is solid, interface (UI) needs
>>> some polishing (and use cases).
>>
>> There is one facet of submodules that annoys me, because it prevents
>> me from using them as a replacement for svn:externals. Namely, the
>> submodule refers to a specific repository, but not a path within that
>> repository. I work with svn repos that use svn:externals to peg
>> revisions (as is appropriate) but they all refer to various paths
>> within the other repositories, and the only way I can deal with that
>> is to throw symlinks everywhere.
>
> I don't quite understand.  At the lowest, "gitlink" level submodule
> entry is just having _commit_ object in place of directory.  And of
> course this commit object refers to top tree (top directory) in
> a subproject.
>
> If you have subproject B with the following file structure
>
>  B/foo
>  B/bar/baz
>
> and you have (super)project A, which contains B as subproject at path
> sub-b, and has some files itself, the directory sytucture would look
> like this:
>
>  A/quux
>  A/sub-b/foo
>  A/sub-b/bar/baz
>
>
> What you want, I guess, is some a bit weird for me mixture of  
> submodule
> and partial (subtree) checkout... and the latter is not implemented  
> yet
> (I say "yet" because there was some preliminary implementation of
> subtree checkout on git mailing list).

It seems you understand what I'm saying. The only way I can mimic it  
is to make the submodules actually live in some hidden directory .foo  
and then scatter symlinks everywhere.

-Kevin Ballard

-- 
Kevin Ballard
http://kevin.sb.org
kevin@sb.org
http://www.tildesoft.com

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Kevin Ballard @ 2008-07-17 20:40 UTC (permalink / raw)
  To: Petr Baudis; +Cc: Jakub Narebski, David Kastrup, git
In-Reply-To: <20080717202609.GA32184@machine.or.cz>

On Jul 17, 2008, at 1:26 PM, Petr Baudis wrote:

> On Thu, Jul 17, 2008 at 01:12:57PM -0700, Kevin Ballard wrote:
>> There is one facet of submodules that annoys me, because it  
>> prevents me
>> from using them as a replacement for svn:externals. Namely, the  
>> submodule
>> refers to a specific repository, but not a path within that  
>> repository. I
>> work with svn repos that use svn:externals to peg revisions (as is
>> appropriate) but they all refer to various paths within the other
>> repositories, and the only way I can deal with that is to throw  
>> symlinks
>> everywhere.
>
> Actually, is this a big problem? Git can track symlinks and without
> adding support for overall partial checkouts, adding this would feel
> like too huge a hack to me.
>
> Also, when converting to a different VCS, it might be sensible to  
> adjust
> your modules setup a bit as well - the requirement to include only
> particular subdirectory of a submodule sounds rather strange to me.

The problem is right now I maintain a bunch of git-svn mirrors of  
internal svn repos, but the company isn't willing to switch to git.  
And we use subtree externals links to do things like pull in the  
models from one rails app into another, or pull in various  
subdirectories of the "support" repository.

-Kevin Ballard

-- 
Kevin Ballard
http://kevin.sb.org
kevin@sb.org
http://www.tildesoft.com

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Jakub Narebski @ 2008-07-17 20:34 UTC (permalink / raw)
  To: Kevin Ballard; +Cc: David Kastrup, git
In-Reply-To: <38486DD8-B4D8-4AAC-9B5F-0A8035D894DD@sb.org>

On Thu, 17 July 2008, Kevin Ballard wrote:
> On Jul 17, 2008, at 1:04 PM, Jakub Narebski wrote:
> 
>> Git submodules are roughly equivalent to svn:externals with peg
>> revisions; I mean here that they refer not to some branch in some
>> external repository, but to specific revision.  This is the only sane
>> design, as it assures that when checking out some historical revision,
>> the state that is checked out will be the same for everybody.
>>
>> Please take into account however that submodules are quite new
>> feature, and while underlying engine is solid, interface (UI) needs
>> some polishing (and use cases).
> 
> There is one facet of submodules that annoys me, because it prevents  
> me from using them as a replacement for svn:externals. Namely, the  
> submodule refers to a specific repository, but not a path within that  
> repository. I work with svn repos that use svn:externals to peg  
> revisions (as is appropriate) but they all refer to various paths  
> within the other repositories, and the only way I can deal with that  
> is to throw symlinks everywhere.

I don't quite understand.  At the lowest, "gitlink" level submodule
entry is just having _commit_ object in place of directory.  And of
course this commit object refers to top tree (top directory) in
a subproject.

If you have subproject B with the following file structure

  B/foo
  B/bar/baz

and you have (super)project A, which contains B as subproject at path
sub-b, and has some files itself, the directory sytucture would look
like this:

  A/quux
  A/sub-b/foo
  A/sub-b/bar/baz


What you want, I guess, is some a bit weird for me mixture of submodule
and partial (subtree) checkout... and the latter is not implemented yet
(I say "yet" because there was some preliminary implementation of
subtree checkout on git mailing list).
-- 
Jakub Narebski
Poland

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Petr Baudis @ 2008-07-17 20:26 UTC (permalink / raw)
  To: Kevin Ballard; +Cc: Jakub Narebski, David Kastrup, git
In-Reply-To: <38486DD8-B4D8-4AAC-9B5F-0A8035D894DD@sb.org>

On Thu, Jul 17, 2008 at 01:12:57PM -0700, Kevin Ballard wrote:
> There is one facet of submodules that annoys me, because it prevents me 
> from using them as a replacement for svn:externals. Namely, the submodule 
> refers to a specific repository, but not a path within that repository. I 
> work with svn repos that use svn:externals to peg revisions (as is 
> appropriate) but they all refer to various paths within the other 
> repositories, and the only way I can deal with that is to throw symlinks 
> everywhere.

Actually, is this a big problem? Git can track symlinks and without
adding support for overall partial checkouts, adding this would feel
like too huge a hack to me.

Also, when converting to a different VCS, it might be sensible to adjust
your modules setup a bit as well - the requirement to include only
particular subdirectory of a submodule sounds rather strange to me.

-- 
				Petr "Pasky" Baudis
GNU, n. An animal of South Africa, which in its domesticated state
resembles a horse, a buffalo and a stag. In its wild condition it is
something like a thunderbolt, an earthquake and a cyclone. -- A. Pierce

^ permalink raw reply

* Re: [PATCH] Documentation/git-submodule.txt: Further clarify the description
From: Junio C Hamano @ 2008-07-17 20:24 UTC (permalink / raw)
  To: Petr Baudis; +Cc: gitster, git, Heikki Orsila
In-Reply-To: <20080717122911.32334.73465.stgit@localhost>

Petr Baudis <pasky@suse.cz> writes:

> This patch rewrites the general description yet again, first clarifying
> the high-level concept, mentioning the difference to remotes and using
> the subtree merge strategy, then getting to the details about tree
> entries and .gitmodules file.
>
> The patch also makes few smallar grammar fixups of the rest of the
> description and clarifies how does 'init' relate to 'update --init'.
>
> Cc: Heikki Orsila <shdl@zakalwe.fi>
> Signed-off-by: Petr Baudis <pasky@suse.cz>
> ---
>
>  Documentation/git-submodule.txt |   39 +++++++++++++++++++++++++++------------
>  1 files changed, 27 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
> index bb4e6fb..01d0d91 100644
> --- a/Documentation/git-submodule.txt
> +++ b/Documentation/git-submodule.txt
> @@ -18,24 +18,35 @@ SYNOPSIS
>  
>  DESCRIPTION
>  -----------
> +Submodules allow foreign repositories to be embedded within a dedicated
> +subdirectory of the source tree, always pointed at a particular commit.
> +They are not to be confused with remotes, which are meant mainly for branches
> +of the same project; submodules are meant for different projects you would like

Your lines are getting overlong to be easily quoted and commented...

> +....  In case you want to merge the project
> +histories, possibly make local modifications within the tree, but also do not
> +mind that your repository will bulk up with all the contents of the other
> +project, consider adding a remote for the other project and using the 'subtree'
> +merge strategy instead of setting up a submodule.

I'd suggest rephrasing "do not mind" to something a lot less nagative.
The user decides to merge because both histories *are* relevant and at
that point there is no _minding_ anymore.  If you want to have them, you
not only "do not mind to have" them but you positively "want" them.

On the other hand, a situation where you would want to use submodules is
when not necessarily all users of the superproject would want to have all
submodules cloned nor checked out.  This needs to be stressed with equal
weight as the above sentence in this "contrasting merged histories and
submodules" paragraph.  With that explained clearly upfront, it would
become easier for the readers to understand why you can choose not to even
update nor fetch submodules you are not interested in.

> +Submodules are composed from a special kind of tree entry (so-called `gitlink`)
> +in the main repository that refers to a particular commit object within

Do we have to say "special"?  Is a gitlink any more special than blob and
tree entries are?  It tends to be rarer, it came later, but I do not think
there is anything special from the end user's point of view.

>  checked out and at appropriate revision in your working tree. You can inspect
>  the current status of your submodules using the 'submodule' subcommand and get
> +an overview of the changes 'update' would perform using the 'summary'
> +subcommand.

Sorry, cannot parse the last three lines...

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Kevin Ballard @ 2008-07-17 20:15 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <86k5fk1ooq.fsf@lola.quinscape.zz>

On Jul 17, 2008, at 9:05 AM, David Kastrup wrote:

>> Distinguishing between branch part of directory name by _convention_
>> is design mistake; the fact that the tool doesn't help to ensure that
>> (a) tags lie on branch (b) tags _doesn't change_ is an example of  
>> this
>> stupidity.
>
> How much have you worked with Subversion so far?  I am doing quite a  
> bit
> of work with it, and the do-everything-via-copying paradigm does not  
> get
> in my hair.  It actually means that I have to remember fewer commands.
> And it is pretty easy to understand.

Sure, it's simpler, but the overhead in creating and using a branch is  
much larger. I have to extract the URL from the repository (since  
naturally I only have trunk checked out), issue a command to copy by  
URL, then issue an `svn switch` command, and then I have to remember  
that I have a switched repository. Switching between branches is a  
pain, especially if you have uncommitted work. There's a reason I  
never bothered to use branches when I used subversion.

-Kevin Ballard

-- 
Kevin Ballard
http://kevin.sb.org
kevin@sb.org
http://www.tildesoft.com

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Kevin Ballard @ 2008-07-17 20:12 UTC (permalink / raw)
  To: Jakub Narebski; +Cc: David Kastrup, git
In-Reply-To: <m3k5fks2et.fsf@localhost.localdomain>

On Jul 17, 2008, at 1:04 PM, Jakub Narebski wrote:

>> Granted, particularly concerning the external property. OTOH, it  
>> makes
>> the equivalent of git submodules rather cheap (and I actually still  
>> have
>> no idea how git submodules properly work and what implications they
>> have).
>
> Git submodules are roughly equivalent to svn:externals with peg
> revisions; I mean here that they refer not to some branch in some
> external repository, but to specific revision.  This is the only sane
> design, as it assures that when checking out some historical revision,
> the state that is checked out will be the same for everybody.
>
> Please take into account however that submodules are quite new
> feature, and while underlying engine is solid, interface (UI) needs
> some polishing (and use cases).

There is one facet of submodules that annoys me, because it prevents  
me from using them as a replacement for svn:externals. Namely, the  
submodule refers to a specific repository, but not a path within that  
repository. I work with svn repos that use svn:externals to peg  
revisions (as is appropriate) but they all refer to various paths  
within the other repositories, and the only way I can deal with that  
is to throw symlinks everywhere.

-Kevin Ballard

-- 
Kevin Ballard
http://kevin.sb.org
kevin@sb.org
http://www.tildesoft.com

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Jakub Narebski @ 2008-07-17 20:04 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <86k5fk1ooq.fsf@lola.quinscape.zz>

[I'm sorry about turning this subthread into Subversion vs. Git rant]

David Kastrup <dak@gnu.org> writes:
> Jakub Narebski <jnareb@gmail.com> writes:
>> David Kastrup <dak@gnu.org> writes:
>>> Daniel Barkalow <barkalow@iabervon.org> writes:

>>>> SVN branches are incredible confusing because they fail to
>>>> distinguish the directory structure of the project's source tree
>>>> from the arrangement of available latest versions.
>>> 
>>> That is because there _is_ no difference.  You just store different
>>> versions in different places.  What they are named is a convention,
>>> nothing more, nothing less.
>>
>> Branching by copying (!) and tagging by copying (!!!) is abuse
>> of the fact that copying in Subversion is cheap.
> 
> Uh, no.  A lot of work has been invested into ensuring that copying in
> Subversion in cheap _exactly_ because of the design decision to
> implement branching and tagging via copying.
> 
> It is not an accident that copying is cheap.

I guess that idea of implementing cheap tree copying and idea of
implementing branches and tags as "full-copies" went hand in hand.

My feeling is that it looks like designing around implementation,
instead of implementing design.

Implementing branches as copies, or in general as directory in
filesystem hierarchy is not that bad idea... provided that one
can flawlessly distinguish between branch and path in project,
can detect where branch name ends and in-project path begins
(perhaps with project/module name in the middle).

Neverheless designing around idea of graph of revisions is, IMVHO,
much superior design :-)
 
>> Distinguishing between branch part of directory name by _convention_
>> is design mistake; the fact that the tool doesn't help to ensure that
>> (a) tags lie on branch (b) tags _doesn't change_ is an example of this
>> stupidity.
> 
> How much have you worked with Subversion so far?  I am doing quite a bit
> of work with it, and the do-everything-via-copying paradigm does not get
> in my hair.  It actually means that I have to remember fewer commands.
> And it is pretty easy to understand.

If you know what you are doing, and have good established workflow...
I was talking there about possibility of mistake (either accident,
or invalid workflow) of either having tag which is not on a branch,
or changing the tag (treating it as branch).

Branches and tags _are_ different.  And should be, IMHO, treated
differently (well, up to a point) by SCM.

>>> Really, Subversion is rather simple to understand.  But it is not a
>>> DVCS.  Moving a history from one repository to another is not really
>>> feasible unless you are doing straight mirroring.
>>
>> Subversion is simple if you are limited to simple things; but the
>> same is true with Git.  I find for example the whole 'properties'
>> mechanism and its use seriously not simple.
> 
> Granted, particularly concerning the external property. OTOH, it makes
> the equivalent of git submodules rather cheap (and I actually still have
> no idea how git submodules properly work and what implications they
> have).

Git submodules are roughly equivalent to svn:externals with peg
revisions; I mean here that they refer not to some branch in some
external repository, but to specific revision.  This is the only sane
design, as it assures that when checking out some historical revision,
the state that is checked out will be the same for everybody.

Please take into account however that submodules are quite new
feature, and while underlying engine is solid, interface (UI) needs
some polishing (and use cases).

-- 
Jakub Narebski
Poland
ShadeHawk on #git

^ permalink raw reply

* Re: [PATCH] Documentation/git-merge.txt: Expand the How Merge Works  section
From: Junio C Hamano @ 2008-07-17 19:34 UTC (permalink / raw)
  To: Petr Baudis; +Cc: git
In-Reply-To: <20080717185451.GJ10151@machine.or.cz>

Petr Baudis <pasky@suse.cz> writes:

>   I'm not sure if I should resend the updated patch, or if you already
> included your comments yourself.

When I send my review comments out, I generally expect an updated version,
unless I explicitly say "will apply with tweaks, no need to resend".  I am
way too lazy to munge patches myself ;-) but more importantly, unlike
Linus, I am not perfect.  My comments are _not_ "I'll show you the right
way", but more often are "Here is what I think is better, but I may well
be wrong, in which case I want you to defend your position better so that
even I can understand why you are right".

>> > +So in the above two "failed merge" case, you do not have to
>> > +worry about loss of data --- you simply were not ready to do
>> > +a merge, so no merge happened at all.  You may want to finish
>> > +whatever you were in the middle of doing, and retry the same
>> > +pull after you are done and ready.
>> 
>> I am not sure what two cases we were describing.  It could be that this
>> paragraph was taken from a mailing list message responding to a question
>> (e.g. "I got this merge failure message and my tree is screwed up.  Please
>> help me get back to a good state, I am lost...") without copying the
>> original sample failure scenario.
>
>   Yes, I got confused by this too. I would perhaps simply drop this
> paragraph altogether.

I agree this does not belong to the same "advanced details" section that
talks about a theoretical corner case where the user:

 - has a perfect foresight,
 - applies (but not commits yet) a patch and stages the change,
 - keeps the working tree and the index dirty, and then
 - pulls from somewhere else in that dirty state,

knowing what will be merged has that exact same patch to trigger that
corner case logic (yes, I am strongly hinting to drop that description; it
is not even remotely interesting).

However, I think we may want to talk about "How to tell if your merge did
not even touch your index nor working tree" somewhere in the manual.
"When there are conflicts, these things happen" part talks about how to
resolve conflicts, but when merge refuses to avoid losing local changes,
the instruction in that part does not apply.

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Junio C Hamano @ 2008-07-17 19:10 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: J. Bruce Fields, git
In-Reply-To: <alpine.DEB.1.00.0807171940160.8986@racer>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

> On Thu, 17 Jul 2008, Junio C Hamano wrote:
>
>> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> 
>> >> Is there a way to commit the contents of a tarball without using 
>> >> plumbing?  I occasionally want to track an upstream that I know only 
>> >> as a series of tarballs, so I do something like:
>> >> 
>> >> 	cd repo/
>> >> 	git checkout upstream
>> >> 	rm -rf *
>> >> 	tar -xzvf ../new-version.tar.gz
>> >
>> > How about "git add -u" and "git add ."?
>> 
>> It would work only if new version never removes files.
>
> You made me doubt for a second there.  But "git add -u" updates the index 
> when a tracked files was deleted.  So after "rm -rf *", "git add -u" would 
> empty the index.

I thought everybody would react to my message like so after sending it ;-)
What I failed to say was that the main uneasiness about the above command
sequence Bruce or anybody would have felt would be that "rm -fr *" step,
which in itself look scary and does not remove .frotz that came from older
version.

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Daniel Barkalow @ 2008-07-17 19:00 UTC (permalink / raw)
  To: David Kastrup; +Cc: git
In-Reply-To: <861w1sn4id.fsf@lola.quinscape.zz>

On Thu, 17 Jul 2008, David Kastrup wrote:

> Daniel Barkalow <barkalow@iabervon.org> writes:
> 
> > You're simply wrong. A ref isn't a name for a commit (the point of
> > having a ref is that it doesn't persist in naming the same commit). A
> > commit isn't a blob. If you start telling people complicated and wrong
> > things, they're surely going to be confused.
> >
> > Git maintains history as a directed graph, with each commit pointing
> > back at its history. Refs are the what holds the newest commits that
> > nothing else points back to. If directed graphs aren't in your users'
> > experience, you can put it this way: git maintains history like
> > knitting, where each new stitch holds on to one or more previous
> > stitches, and refs are the knitting needles that hold the ends where
> > you're working (except that knitting is a lot wider than software
> > development). gitk --all even provides the diagram you want to explain
> > it.
> 
> Complicated and right things are not much less confusing...
> 
> > SVN branches are incredible confusing because they fail to distinguish
> > the directory structure of the project's source tree from the
> > arrangement of available latest versions.
> 
> That is because there _is_ no difference.  You just store different
> versions in different places.  What they are named is a convention,
> nothing more, nothing less.

No, there's a difference. When you get a tarball of a project that uses 
SVN, the root of the tarball isn't the root of the repository. It's the 
root of some directory within the repository. And if you ask for a tarball 
of some branch, it's from some different directory in the repository. 
Projects are not at all unaware that there are particular subdirectories 
in the repository structure which contain roots of versions, and above 
that, the directory structure doesn't refer to the structure of a project 
snapshot.

Because SVN lacks a vital concept (graph-structured history), it uses the 
same implementation for two qualitatively different concepts. This is 
extremely confusing, and much more confusing than having a clean 
separation between the two concepts like git does.

	-Daniel
*This .sig left intentionally blank*

^ permalink raw reply

* Re: [PATCH] Documentation/git-merge.txt: Expand the How Merge Works  section
From: Petr Baudis @ 2008-07-17 18:54 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7v3am8gytp.fsf@gitster.siamese.dyndns.org>

  Hi,

  I'm not sure if I should resend the updated patch, or if you already
included your comments yourself.

On Thu, Jul 17, 2008 at 11:17:22AM -0700, Junio C Hamano wrote:
> Petr Baudis <pasky@suse.cz> writes:
> > +* `HEAD` is already contained in the merged commit. This is the
> > +  most common case especially when involved through 'git pull':
> > +  you are tracking an upstream repository, committed no local
> > +  changes and now you want to update to a newer upstream revision.
> > +  So-called "fast-forward merge" is performed, simply repointing
> > +  your `HEAD` (and index) to the merged commit; no extra merge
> > +  commit is created.
> 
> I'd suggest rewording the last three lines:
> 
> 	Your `HEAD` (and the index) is updated to point the merged
							^ at
>         commit, without creating an extra merge commit.  This is
>         called "Fast-forward".

  Yes, that is better.

> > +Pre-flight requirements note
> > +~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > +In certain special cases, your index is
> > +allowed to be different from the tree of the `HEAD` commit.
> 
> Now this paragraph is moved far away from the original context that said
> "your index must be clean before you start your merge", you would need to
> re-introduce that in this sentenece:
> 
> 	... tree of the `HEAD` before you run 'git-merge'.

  Done.

  I have to admit that I didn't even carefully read the rest of this
subsection, but I agree that we might as well update it when moving it
around already.

> > +... Also, your index entries
> > +may have differences from your `HEAD` commit that match
> > +the result of a trivial merge (e.g. you received the same patch
> > +from an external source to produce the same result as what you are
> > +merging).  For example, if a path did not exist in the common
> > +ancestor and your head commit but exists in the tree you are
> > +merging into your repository, and if you already happen to have
> > +that path exactly in your index, the merge does not have to
> > +fail.
> 
> I originally wrote the above paragraph purely for completeness, but I
> wonder if this happens a lot in practice.  This is not something the user
> can easily anticipate anyway, so we might want to drop this.

  I think that we can expect only users that have real interest in these
details to read through this, so I would keep it for the completeness.

> > +So in the above two "failed merge" case, you do not have to
> > +worry about loss of data --- you simply were not ready to do
> > +a merge, so no merge happened at all.  You may want to finish
> > +whatever you were in the middle of doing, and retry the same
> > +pull after you are done and ready.
> 
> I am not sure what two cases we were describing.  It could be that this
> paragraph was taken from a mailing list message responding to a question
> (e.g. "I got this merge failure message and my tree is screwed up.  Please
> help me get back to a good state, I am lost...") without copying the
> original sample failure scenario.

  Yes, I got confused by this too. I would perhaps simply drop this
paragraph altogether.

-- 
				Petr "Pasky" Baudis
GNU, n. An animal of South Africa, which in its domesticated state
resembles a horse, a buffalo and a stag. In its wild condition it is
something like a thunderbolt, an earthquake and a cyclone. -- A. Pierce

^ permalink raw reply

* Re: Considering teaching plumbing to users harmful
From: Johannes Schindelin @ 2008-07-17 18:43 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: J. Bruce Fields, git
In-Reply-To: <7vtzeofjpi.fsf@gitster.siamese.dyndns.org>

Hi,

On Thu, 17 Jul 2008, Junio C Hamano wrote:

> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> 
> >> Is there a way to commit the contents of a tarball without using 
> >> plumbing?  I occasionally want to track an upstream that I know only 
> >> as a series of tarballs, so I do something like:
> >> 
> >> 	cd repo/
> >> 	git checkout upstream
> >> 	rm -rf *
> >> 	tar -xzvf ../new-version.tar.gz
> >
> > How about "git add -u" and "git add ."?
> 
> It would work only if new version never removes files.

You made me doubt for a second there.  But "git add -u" updates the index 
when a tracked files was deleted.  So after "rm -rf *", "git add -u" would 
empty the index.

AFAICT this has been a part of "git add -u" ever since dfdac5d(git-add -u: 
match the index with working tree.), i.e. ever since the "-u" option was 
added.

Ciao,
Dscho

^ permalink raw reply

* Re: [PATCH/rfc] git-svn.perl: workaround assertions in svn library 1.5.0
From: Dmitry Potapov @ 2008-07-17 18:37 UTC (permalink / raw)
  To: Gerrit Pape; +Cc: git, Eric Wong
In-Reply-To: <20080717140856.10213.qmail@c0f13986110104.315fe32.mid.smarden.org>

On Thu, Jul 17, 2008 at 6:08 PM, Gerrit Pape <pape@smarden.org> wrote:
>
> Hi, while this commit fixed the selftests, it unfortunately is a
> regression
>
>  http://thread.gmane.org/gmane.comp.version-control.git/87822/
>  http://bugs.debian.org/490400

This particular breakage is easy to fix:

diff --git a/git-svn.perl b/git-svn.perl
index 3750e47..a5a5b1b 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -1226,7 +1226,7 @@ sub linearize_history {

 sub find_file_type_and_diff_status {
        my ($path) = @_;
-       return ('dir', '') if $path eq '.';
+       return ('dir', '') if $path eq '';

        my $diff_output =
            command_oneline(qw(diff --cached --name-status --), $path) || "";

but it could be some other places in git-svn that may need correction too.

>
> I'm still not sure whether this is a git-svn problem, or actually a
> problem in subversion 1.5.0

Accordingly to SVN developers you do not use SVN API correctly,
therefore you got assert. So, the problem in git-svn.
http://svn.haxx.se/dev/archive-2008-01/0425.shtml

Dmitry

^ permalink raw reply related

* Re: Considering teaching plumbing to users harmful
From: Junio C Hamano @ 2008-07-17 18:29 UTC (permalink / raw)
  To: Johannes Schindelin; +Cc: J. Bruce Fields, git
In-Reply-To: <alpine.DEB.1.00.0807171915420.8986@racer>

Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:

>> Is there a way to commit the contents of a tarball without using
>> plumbing?  I occasionally want to track an upstream that I know only as
>> a series of tarballs, so I do something like:
>> 
>> 	cd repo/
>> 	git checkout upstream
>> 	rm -rf *
>> 	tar -xzvf ../new-version.tar.gz
>
> How about "git add -u" and "git add ."?

It would work only if new version never removes files.

^ permalink raw reply

* Re: [PATCH] Documentation/gitignore.txt: Clarify gitignore vs tracked files
From: Petr Baudis @ 2008-07-17 18:26 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git
In-Reply-To: <7vabgggyuc.fsf@gitster.siamese.dyndns.org>

  Hi,

On Thu, Jul 17, 2008 at 11:16:59AM -0700, Junio C Hamano wrote:
> I'd suggest dropping everything after ';'.

  I think the part after ';' is the main benefit of this patch,
actually. Without suggesting an alternative, the users are left puzzled
"so how do I do that?"

>  - If you want to keep local changes without ever checking in, you can do
>    so by making partial commits.

  Yes, that's a rather obvious solution but the user probably wants
something nicer than that if he starts looking already.

>  - You could mark these paths "assume unchanged".

  I really think this is worth mentioning in the gitignore manpage;
it is not _directly_ on-topic, but there is no other obvious place where
to teach users about it and all the interested people will check the
gitignore manpage first. Perhaps a small section at the end might be
acceptable? ;-)

-- 
				Petr "Pasky" Baudis
GNU, n. An animal of South Africa, which in its domesticated state
resembles a horse, a buffalo and a stag. In its wild condition it is
something like a thunderbolt, an earthquake and a cyclone. -- A. Pierce

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox