* Re: [PATCH] Add a new lstat and fstat implementation based on Win32 API
From: Johannes Schindelin @ 2007-09-03 16:56 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: Johannes Sixt, Git Mailing List, Johannes Sixt
In-Reply-To: <46DC34A9.8020308@trolltech.com>
Hi,
On Mon, 3 Sep 2007, Marius Storm-Olsen wrote:
> I'll use the 4msysgit.git repo from now on. I assume it'll be ok if I
> +push to the teststat branch?
I should think so.
Ciao,
Dscho
^ permalink raw reply
* [PATCH 1/3] Export format_commit_message()
From: René Scharfe @ 2007-09-03 18:06 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
Drop the parameter "msg" of format_commit_message() (as it can be
inferred from the parameter "commit"), add a parameter "template"
in order to avoid accessing the static variable user_format
directly and export the result.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
commit.c | 9 +++++----
commit.h | 1 +
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/commit.c b/commit.c
index dc5a064..651e904 100644
--- a/commit.c
+++ b/commit.c
@@ -787,8 +787,8 @@ static void fill_person(struct interp *table, const char *msg, int len)
interp_set_entry(table, 6, show_date(date, tz, DATE_ISO8601));
}
-static long format_commit_message(const struct commit *commit,
- const char *msg, char **buf_p, unsigned long *space_p)
+long format_commit_message(const struct commit *commit, const void *template,
+ char **buf_p, unsigned long *space_p)
{
struct interp table[] = {
{ "%H" }, /* commit hash */
@@ -843,6 +843,7 @@ static long format_commit_message(const struct commit *commit,
char parents[1024];
int i;
enum { HEADER, SUBJECT, BODY } state;
+ const char *msg = commit->buffer;
if (ILEFT_RIGHT + 1 != ARRAY_SIZE(table))
die("invalid interp table!");
@@ -924,7 +925,7 @@ static long format_commit_message(const struct commit *commit,
char *buf = *buf_p;
unsigned long space = *space_p;
- space = interpolate(buf, space, user_format,
+ space = interpolate(buf, space, template,
table, ARRAY_SIZE(table));
if (!space)
break;
@@ -1165,7 +1166,7 @@ unsigned long pretty_print_commit(enum cmit_fmt fmt,
char *buf;
if (fmt == CMIT_FMT_USERFORMAT)
- return format_commit_message(commit, msg, buf_p, space_p);
+ return format_commit_message(commit, user_format, buf_p, space_p);
encoding = (git_log_output_encoding
? git_log_output_encoding
diff --git a/commit.h b/commit.h
index 467872e..a8d7661 100644
--- a/commit.h
+++ b/commit.h
@@ -61,6 +61,7 @@ enum cmit_fmt {
};
extern enum cmit_fmt get_commit_format(const char *arg);
+extern long format_commit_message(const struct commit *commit, const void *template, char **buf_p, unsigned long *space_p);
extern unsigned long pretty_print_commit(enum cmit_fmt fmt, const struct commit *, unsigned long len, char **buf_p, unsigned long *space_p, int abbrev, const char *subject, const char *after_subject, enum date_mode dmode);
/** Removes the first commit from a list sorted by date, and adds all
--
1.5.3
^ permalink raw reply related
* [PATCH 2/3] archive: specfile support (--pretty=format: in archive files)
From: René Scharfe @ 2007-09-03 18:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List, Michael Gernoth, Thomas Glanzmann
Add support for a new attribute, specfile. Files marked as being
specfiles are expanded by git-archive when they are written to an
archive. It has no effect on worktree files. The same placeholders
as those for the option --pretty=format: of git-log et al. can be
used.
The attribute is useful for creating auto-updating specfiles. It is
limited by the underlying function format_commit_message(), though.
E.g. currently there is no placeholder for git-describe like output,
and expanded specfiles can't contain NUL bytes. That can be fixed
in format_commit_message() later and will then benefit users of
git-log, too.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
Documentation/gitattributes.txt | 14 ++++++++++
archive-tar.c | 5 +++-
archive-zip.c | 5 +++-
archive.h | 3 ++
builtin-archive.c | 55 ++++++++++++++++++++++++++++++++++++++-
t/t5000-tar-tree.sh | 19 +++++++++++++
6 files changed, 98 insertions(+), 3 deletions(-)
This should already be sufficient for the use case which Michael and
Thomas described a while ago, viz. adding a commit ID file to
generated archives.
Why did it take me that long to come up with such a simple patch?
There was a vacation and a feature freeze in between, but above all
I was only recently able to convince myself (using ugly code) that
format_commit_message() can indeed be made to expand placeholders
to git-describe strings..
diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 46f9d59..47a621b 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -421,6 +421,20 @@ frotz unspecified
----------------------------------------------------------------
+Creating an archive
+~~~~~~~~~~~~~~~~~~~
+
+`specfile`
+^^^^^^^^^^
+
+If the attribute `specfile` is set for a file then git will expand
+several placeholders when adding this file to an archive. The
+expansion depends on the availability of a commit ID, i.e. if
+gitlink:git-archive[1] has been given a tree instead of a commit or a
+tag then no replacement will be done. The placeholders are the same
+as those for the option `--pretty=format:` of gitlink:git-log[1].
+
+
GIT
---
Part of the gitlink:git[7] suite
diff --git a/archive-tar.c b/archive-tar.c
index 66fe3e3..c0d95da 100644
--- a/archive-tar.c
+++ b/archive-tar.c
@@ -17,6 +17,7 @@ static unsigned long offset;
static time_t archive_time;
static int tar_umask = 002;
static int verbose;
+static const struct commit *commit;
/* writes out the whole block, but only if it is full */
static void write_if_needed(void)
@@ -285,7 +286,8 @@ static int write_tar_entry(const unsigned char *sha1,
buffer = NULL;
size = 0;
} else {
- buffer = convert_sha1_file(path.buf, sha1, mode, &type, &size);
+ buffer = sha1_file_to_archive(path.buf, sha1, mode, &type,
+ &size, commit);
if (!buffer)
die("cannot read %s", sha1_to_hex(sha1));
}
@@ -304,6 +306,7 @@ int write_tar_archive(struct archiver_args *args)
archive_time = args->time;
verbose = args->verbose;
+ commit = args->commit;
if (args->commit_sha1)
write_global_extended_header(args->commit_sha1);
diff --git a/archive-zip.c b/archive-zip.c
index 444e162..f63dff3 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -12,6 +12,7 @@
static int verbose;
static int zip_date;
static int zip_time;
+static const struct commit *commit;
static unsigned char *zip_dir;
static unsigned int zip_dir_size;
@@ -195,7 +196,8 @@ static int write_zip_entry(const unsigned char *sha1,
if (S_ISREG(mode) && zlib_compression_level != 0)
method = 8;
result = 0;
- buffer = convert_sha1_file(path, sha1, mode, &type, &size);
+ buffer = sha1_file_to_archive(path, sha1, mode, &type, &size,
+ commit);
if (!buffer)
die("cannot read %s", sha1_to_hex(sha1));
crc = crc32(crc, buffer, size);
@@ -316,6 +318,7 @@ int write_zip_archive(struct archiver_args *args)
zip_dir = xmalloc(ZIP_DIRECTORY_MIN_SIZE);
zip_dir_size = ZIP_DIRECTORY_MIN_SIZE;
verbose = args->verbose;
+ commit = args->commit;
if (args->base && plen > 0 && args->base[plen - 1] == '/') {
char *base = xstrdup(args->base);
diff --git a/archive.h b/archive.h
index 6838dc7..5791e65 100644
--- a/archive.h
+++ b/archive.h
@@ -8,6 +8,7 @@ struct archiver_args {
const char *base;
struct tree *tree;
const unsigned char *commit_sha1;
+ const struct commit *commit;
time_t time;
const char **pathspec;
unsigned int verbose : 1;
@@ -42,4 +43,6 @@ extern int write_tar_archive(struct archiver_args *);
extern int write_zip_archive(struct archiver_args *);
extern void *parse_extra_zip_args(int argc, const char **argv);
+extern void *sha1_file_to_archive(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size, const struct commit *commit);
+
#endif /* ARCHIVE_H */
diff --git a/builtin-archive.c b/builtin-archive.c
index 187491b..faccce3 100644
--- a/builtin-archive.c
+++ b/builtin-archive.c
@@ -10,6 +10,7 @@
#include "exec_cmd.h"
#include "pkt-line.h"
#include "sideband.h"
+#include "attr.h"
static const char archive_usage[] = \
"git-archive --format=<fmt> [--prefix=<prefix>/] [--verbose] [<extra>] <tree-ish> [path...]";
@@ -80,6 +81,57 @@ static int run_remote_archiver(const char *remote, int argc,
return !!rv;
}
+static void *convert_to_archive(const char *path,
+ const void *src, unsigned long *sizep,
+ const struct commit *commit)
+{
+ static struct git_attr *attr_specfile;
+ struct git_attr_check check[1];
+ char *interpolated = NULL;
+ unsigned long allocated = 0;
+
+ if (!commit)
+ return NULL;
+
+ if (!attr_specfile)
+ attr_specfile = git_attr("specfile", 8);
+
+ check[0].attr = attr_specfile;
+ if (git_checkattr(path, ARRAY_SIZE(check), check))
+ return NULL;
+ if (!ATTR_TRUE(check[0].value))
+ return NULL;
+
+ *sizep = format_commit_message(commit, src, &interpolated, &allocated);
+
+ return interpolated;
+}
+
+void *sha1_file_to_archive(const char *path, const unsigned char *sha1,
+ unsigned int mode, enum object_type *type,
+ unsigned long *size,
+ const struct commit *commit)
+{
+ void *buffer, *converted;
+
+ buffer = read_sha1_file(sha1, type, size);
+ if (buffer && S_ISREG(mode)) {
+ converted = convert_to_working_tree(path, buffer, size);
+ if (converted) {
+ free(buffer);
+ buffer = converted;
+ }
+
+ converted = convert_to_archive(path, buffer, size, commit);
+ if (converted) {
+ free(buffer);
+ buffer = converted;
+ }
+ }
+
+ return buffer;
+}
+
static int init_archiver(const char *name, struct archiver *ar)
{
int rv = -1, i;
@@ -109,7 +161,7 @@ void parse_treeish_arg(const char **argv, struct archiver_args *ar_args,
const unsigned char *commit_sha1;
time_t archive_time;
struct tree *tree;
- struct commit *commit;
+ const struct commit *commit;
unsigned char sha1[20];
if (get_sha1(name, sha1))
@@ -142,6 +194,7 @@ void parse_treeish_arg(const char **argv, struct archiver_args *ar_args,
}
ar_args->tree = tree;
ar_args->commit_sha1 = commit_sha1;
+ ar_args->commit = commit;
ar_args->time = archive_time;
}
diff --git a/t/t5000-tar-tree.sh b/t/t5000-tar-tree.sh
index 1a4c53a..3d5d01b 100755
--- a/t/t5000-tar-tree.sh
+++ b/t/t5000-tar-tree.sh
@@ -28,12 +28,15 @@ commit id embedding:
TAR=${TAR:-tar}
UNZIP=${UNZIP:-unzip}
+SPECFILEFORMAT=%H%n
+
test_expect_success \
'populate workdir' \
'mkdir a b c &&
echo simple textfile >a/a &&
mkdir a/bin &&
cp /bin/sh a/bin &&
+ printf "%s" "$SPECFILEFORMAT" >a/specfile &&
ln -s a a/l1 &&
(p=long_path_to_a_file && cd a &&
for depth in 1 2 3 4 5; do mkdir $p && cd $p; done &&
@@ -105,6 +108,22 @@ test_expect_success \
'diff -r a c/prefix/a'
test_expect_success \
+ 'create an archive with a specfile' \
+ 'echo specfile specfile >a/.gitattributes &&
+ git archive HEAD >f.tar &&
+ rm a/.gitattributes'
+
+test_expect_success \
+ 'extract specfile' \
+ '(mkdir f && cd f && $TAR xf -) <f.tar'
+
+test_expect_success \
+ 'validate specfile contents' \
+ 'git log --max-count=1 "--pretty=format:$SPECFILEFORMAT" HEAD \
+ >f/a/specfile.expected &&
+ diff f/a/specfile.expected f/a/specfile'
+
+test_expect_success \
'git archive --format=zip' \
'git archive --format=zip HEAD >d.zip'
--
1.5.3
^ permalink raw reply related
* [PATCH 3/3] Remove unused function convert_sha1_file()
From: René Scharfe @ 2007-09-03 18:08 UTC (permalink / raw)
To: Junio C Hamano; +Cc: Git Mailing List
convert_sha1_file() became unused by the previous patch -- remove it.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
---
cache.h | 1 -
convert.c | 15 ---------------
2 files changed, 0 insertions(+), 16 deletions(-)
diff --git a/cache.h b/cache.h
index 70abbd5..493983c 100644
--- a/cache.h
+++ b/cache.h
@@ -592,7 +592,6 @@ extern void trace_argv_printf(const char **argv, int count, const char *format,
/* convert.c */
extern char *convert_to_git(const char *path, const char *src, unsigned long *sizep);
extern char *convert_to_working_tree(const char *path, const char *src, unsigned long *sizep);
-extern void *convert_sha1_file(const char *path, const unsigned char *sha1, unsigned int mode, enum object_type *type, unsigned long *size);
/* diff.c */
extern int diff_auto_refresh_index;
diff --git a/convert.c b/convert.c
index 21908b1..d77c8eb 100644
--- a/convert.c
+++ b/convert.c
@@ -687,18 +687,3 @@ char *convert_to_working_tree(const char *path, const char *src, unsigned long *
return buf;
}
-
-void *convert_sha1_file(const char *path, const unsigned char *sha1,
- unsigned int mode, enum object_type *type,
- unsigned long *size)
-{
- void *buffer = read_sha1_file(sha1, type, size);
- if (S_ISREG(mode) && buffer) {
- void *converted = convert_to_working_tree(path, buffer, size);
- if (converted) {
- free(buffer);
- buffer = converted;
- }
- }
- return buffer;
-}
--
1.5.3
^ permalink raw reply related
* Re: [PATCH 1/3] Export format_commit_message()
From: Johannes Schindelin @ 2007-09-03 18:35 UTC (permalink / raw)
To: René Scharfe; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <46DC4D2C.8070109@lsrfire.ath.cx>
Hi,
On Mon, 3 Sep 2007, Ren? Scharfe wrote:
> -static long format_commit_message(const struct commit *commit,
> - const char *msg, char **buf_p, unsigned long *space_p)
> +long format_commit_message(const struct commit *commit, const void *template,
> + char **buf_p, unsigned long *space_p)
I am quite sure that this breaks compilation in C++.
Besides, "format" is so much more descriptive here IMHO. What is so wrong
with "format" for you?
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 2/3] archive: specfile support (--pretty=format: in archive files)
From: Johannes Schindelin @ 2007-09-03 18:40 UTC (permalink / raw)
To: René Scharfe
Cc: Junio C Hamano, Git Mailing List, Michael Gernoth,
Thomas Glanzmann
In-Reply-To: <46DC4D45.4030208@lsrfire.ath.cx>
Hi,
On Mon, 3 Sep 2007, Ren? Scharfe wrote:
> Add support for a new attribute, specfile. Files marked as being
> specfiles are expanded by git-archive when they are written to an
> archive. It has no effect on worktree files. The same placeholders
> as those for the option --pretty=format: of git-log et al. can be
> used.
I almost like this approach. Would it not be a little more useful if you
could mark the placeholders with something like "$Format: xyz %c$"?
Because then we could just shut up all those complainers that want to
insert some revision specific information into the files, without
affecting formats for printf().
Of course, the idea to keep the worktree unaffected is brilliant.
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH 1/3] Export format_commit_message()
From: René Scharfe @ 2007-09-03 18:44 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0709031934480.28586@racer.site>
Johannes Schindelin schrieb:
>> -static long format_commit_message(const struct commit *commit,
>> - const char *msg, char **buf_p, unsigned long *space_p)
>> +long format_commit_message(const struct commit *commit, const void *template,
>> + char **buf_p, unsigned long *space_p)
>
> I am quite sure that this breaks compilation in C++.
>
> Besides, "format" is so much more descriptive here IMHO. What is so wrong
> with "format" for you?
I have nothing against naming the parameter "format", actually. This
name simply didn't occur to me -- weird but true. :-]
René
^ permalink raw reply
* Re: confused about preserved permissions
From: Jan Hudec @ 2007-09-03 18:59 UTC (permalink / raw)
To: Benoit SIGOURE; +Cc: David Kastrup, git discussion list
In-Reply-To: <B38B8F2F-92B0-48F4-9093-54724FA862C2@lrde.epita.fr>
[-- Attachment #1: Type: text/plain, Size: 1419 bytes --]
On Thu, Aug 23, 2007 at 09:48:23 +0200, Benoit SIGOURE wrote:
> Hmm yes, that's right.
>
> Let's look at the problem from another point of view then: I want my
> *working tree* to be group readable even though my umask is 066. Would it
> be possible to add a local config option in the .git repo to tell git that
> it should create new file this way (exactly like core.sharedRepository but
> core.sharedWorkingCopy or whatever).
>
> WDYT?
You need to change umask not just for git, but for your editor and compiler
when you are working in the shared work tree as well, no? So what about
teaching your *shell* to change it as appropriate?
In zsh if you define a function chpwd, it will be called whenever you change
current working directory. If you define it as:
chpwd() {
# The / at the end is to make foo/* match path foo
case `pwd`/ in
/path/to/your/worktree/*) umask 002;;
*) umask 066;;
esac
}
would make any command (ie. git, editor and compiler/make/...) ran from the
shared worktree run with umask 002 (or whatever depending on permissions you
want there) and anything ran from anywhere else use your normal umask 066.
I don't use bash, but I am almost sure you can get a suitable hook there as
well. If nothing else I recall there is a way to run a function from prompt
expansion, which would do the trick.
--
Jan 'Bulb' Hudec <bulb@ucw.cz>
[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: [PATCH] Add a new lstat and fstat implementation based on Win32 API
From: Marius Storm-Olsen @ 2007-09-03 19:21 UTC (permalink / raw)
To: Johannes Schindelin, Johannes Sixt, Johannes Sixt; +Cc: Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0709031428080.28586@racer.site>
[-- Attachment #1: Type: text/plain, Size: 983 bytes --]
Johannes Schindelin wrote:
> To make it easier on others, I just uploaded it into the "teststat"
> branch on 4msysgit.git (subject to removal in a few days).
Ok, I've updated the patch in the 4msysgit.git repo, 'teststat' branch.
RFC, and please test.
The patch also incorporates some of Hannes local changes, with some
modifications. Hannes, does it look ok for you? You can add a tag to the
commit message if you'd like, and just +push it.
On Hannes' request (and to which I fully agree), I've gone back to the
old implementation of filetime_to_time_t(), since it was a bit 'nasty'.
(If we want to target CE in the future, it will quite possibly break)
http://repo.or.cz/w/git/mingw/4msysgit.git?a=commitdiff;h=f4f3fbddf6e0f16f66f94cedf66614e0e3643496
> First comment: it seems git_fstat() is not declared properly, so
> there are quite a few compiler warnings.
This is also fixed, of course.
Hope this is the final 'cut' :-)
Later!
--
.marius
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 187 bytes --]
^ permalink raw reply
* Re: [PATCH 2/3] archive: specfile support (--pretty=format: in archive files)
From: David Kastrup @ 2007-09-03 20:19 UTC (permalink / raw)
To: Johannes Schindelin
Cc: René Scharfe, Junio C Hamano, Git Mailing List,
Michael Gernoth, Thomas Glanzmann
In-Reply-To: <Pine.LNX.4.64.0709031935540.28586@racer.site>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> On Mon, 3 Sep 2007, Ren? Scharfe wrote:
>
>> Add support for a new attribute, specfile. Files marked as being
>> specfiles are expanded by git-archive when they are written to an
>> archive. It has no effect on worktree files. The same placeholders
>> as those for the option --pretty=format: of git-log et al. can be
>> used.
>
> I almost like this approach. Would it not be a little more useful if you
> could mark the placeholders with something like "$Format: xyz %c$"?
> Because then we could just shut up all those complainers that want to
> insert some revision specific information into the files, without
> affecting formats for printf().
>
> Of course, the idea to keep the worktree unaffected is brilliant.
I think a bit more layering would be helpful: when using git-svn, one
would want to have things like $Id$ and $Date$ expanded, so maybe
attribute specs like
somefile: expandmarkers="$Date: %aD$ $Id: ....$"
would be nice having. In the case of git-svn, I would expect them to
be generated from git-svn from the respective svn properties, so that
the user is not bothered with figuring out the awful $Id$ and whatever
strings.
--
David Kastrup, Kriemhildstr. 15, 44793 Bochum
^ permalink raw reply
* [StGit PATCH 0/2] Break Python 2.3 compatibility
From: Karl Hasselström @ 2007-09-03 21:48 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
In-Reply-To: <b0943d9e0709030136y4f1f241cge28fb9607ec559c1@mail.gmail.com>
On 2007-09-03 09:36:26 +0100, Catalin Marinas wrote:
> On 29/08/07, Karl Hasselström <kha@treskal.com> wrote:
>
> > Any chance we can drop Python 2.3 support any time soon, by the
> > way? I've confined all the ickyness to one place, but it would
> > still be good to get rid of it (not to mention being able to use
> > sets and generator expressions).
>
> Unless there is no objection, I'm actually OK with this. Feel free
> to break the 2.3 support from now on. I'll add a note stating the
> minimum versions for Python and GIT in the 0.14 release.
And here it is. We actually used sets in much fewer places than I
thought -- but then again, there are a number of places where we ought
to be using them but aren't.
--
Karl Hasselström, kha@treskal.com
www.treskal.com/kalle
^ permalink raw reply
* [StGit PATCH 1/2] Use subprocess.Popen to call git executables
From: Karl Hasselström @ 2007-09-03 21:48 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
In-Reply-To: <20070903214545.18057.79301.stgit@yoghurt>
Replace popen2.Popen3 and os.spawn* with the superior
subprocess.Popen. Now we can pass a modified environment to any
subprocess, redirect input and output as we please, and the shell is
no longer involved, meaning we don't have to worry about argument
quoting. (We could already do all of that, just not at the same time.)
This is a Python 2.4 library, so StGit now officially requires Python
2.4 or later.
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
stgit/run.py | 89 ++++++++++++++++++++++++++--------------------------------
1 files changed, 40 insertions(+), 49 deletions(-)
diff --git a/stgit/run.py b/stgit/run.py
index 94dd98e..29f8f71 100644
--- a/stgit/run.py
+++ b/stgit/run.py
@@ -17,12 +17,7 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
-# popen2 and os.spawn* suck. We should really use subprocess instead,
-# but that's only available in Python 2.4 and up, and we try our best
-# to stay Python 2.3 compatible.
-import popen2, os
-
-import datetime
+import datetime, os, subprocess
from stgit.out import *
@@ -48,11 +43,11 @@ class Run:
self.__good_retvals = [0]
self.__env = None
self.__indata = None
- def __log_start(self, cmd):
+ def __log_start(self):
if _log_mode == 'debug':
- out.start('Running subprocess %s' % cmd)
+ out.start('Running subprocess %s' % self.__cmd)
elif _log_mode == 'profile':
- out.start('Running subprocess %s' % cmd[0])
+ out.start('Running subprocess %s' % self.__cmd[0])
self.__starttime = datetime.datetime.now()
def __log_end(self, retcode):
if _log_mode == 'debug':
@@ -60,48 +55,41 @@ class Run:
elif _log_mode == 'profile':
duration = datetime.datetime.now() - self.__starttime
out.done('%1.3f s' % (duration.microseconds/1e6 + duration.seconds))
- def __run_io(self, cmd):
- """Run with captured IO. Note: arguments are parsed by the
- shell. We single-quote them, so don't use anything with single
- quotes in it."""
- if self.__env == None:
- ecmd = cmd
- else:
- ecmd = (['env'] + ['%s=%s' % (key, val)
- for key, val in self.__env.iteritems()]
- + cmd)
- self.__log_start(ecmd)
- p = popen2.Popen3(' '.join(["'%s'" % c for c in ecmd]), True)
- if self.__indata != None:
- p.tochild.write(self.__indata)
- p.tochild.close()
- outdata = p.fromchild.read()
- errdata = p.childerr.read()
- self.exitcode = p.wait() >> 8
- self.__log_end(self.exitcode)
+ def __check_exitcode(self):
if self.exitcode not in self.__good_retvals:
- raise self.exc('%s failed with code %d:\n%s'
- % (cmd[0], self.exitcode, errdata))
- if errdata:
- out.warn('call to %s succeeded, but generated a warning:' % cmd[0])
- out.err_raw(errdata)
+ raise self.exc('%s failed with code %d'
+ % (self.__cmd[0], self.exitcode))
+ def __run_io(self):
+ """Run with captured IO."""
+ self.__log_start()
+ try:
+ p = subprocess.Popen(self.__cmd, env = self.__env,
+ stdin = subprocess.PIPE,
+ stdout = subprocess.PIPE)
+ outdata, errdata = p.communicate(self.__indata)
+ self.exitcode = p.returncode
+ except OSError, e:
+ raise self.exc('%s failed: %s' % (self.__cmd[0], e))
+ self.__log_end(self.exitcode)
+ self.__check_exitcode()
return outdata
- def __run_noshell(self, cmd):
- """Run without captured IO. Note: arguments are not parsed by
- the shell."""
- assert self.__env == None
+ def __run_noio(self):
+ """Run without captured IO."""
assert self.__indata == None
- self.__log_start(cmd)
- self.exitcode = os.spawnvp(os.P_WAIT, cmd[0], cmd)
+ self.__log_start()
+ try:
+ p = subprocess.Popen(self.__cmd, env = self.__env)
+ self.exitcode = p.wait()
+ except OSError, e:
+ raise self.exc('%s failed: %s' % (self.__cmd[0], e))
self.__log_end(self.exitcode)
- if not self.exitcode in self.__good_retvals:
- raise self.exc('%s failed with code %d'
- % (cmd[0], self.exitcode))
+ self.__check_exitcode()
def returns(self, retvals):
self.__good_retvals = retvals
return self
def env(self, env):
- self.__env = env
+ self.__env = dict(os.environ)
+ self.__env.update(env)
return self
def raw_input(self, indata):
self.__indata = indata
@@ -110,15 +98,15 @@ class Run:
self.__indata = ''.join(['%s\n' % line for line in lines])
return self
def no_output(self):
- outdata = self.__run_io(self.__cmd)
+ outdata = self.__run_io()
if outdata:
raise self.exc, '%s produced output' % self.__cmd[0]
def discard_output(self):
- self.__run_io(self.__cmd)
+ self.__run_io()
def raw_output(self):
- return self.__run_io(self.__cmd)
+ return self.__run_io()
def output_lines(self):
- outdata = self.__run_io(self.__cmd)
+ outdata = self.__run_io()
if outdata.endswith('\n'):
outdata = outdata[:-1]
if outdata:
@@ -134,11 +122,14 @@ class Run:
% (self.__cmd[0], len(outlines)))
def run(self):
"""Just run, with no IO redirection."""
- self.__run_noshell(self.__cmd)
+ self.__run_noio()
def xargs(self, xargs):
"""Just run, with no IO redirection. The extra arguments are
appended to the command line a few at a time; the command is
run as many times as needed to consume them all."""
step = 100
+ basecmd = self.__cmd
for i in xrange(0, len(xargs), step):
- self.__run_noshell(self.__cmd + xargs[i:i+step])
+ self.__cmd = basecmd + xargs[i:i+step]
+ self.__run_noio()
+ self.__cmd = basecmd
^ permalink raw reply related
* [StGit PATCH 2/2] Use the builtin set() instead of sets.Set()
From: Karl Hasselström @ 2007-09-03 21:48 UTC (permalink / raw)
To: Catalin Marinas; +Cc: git
In-Reply-To: <20070903214545.18057.79301.stgit@yoghurt>
We can do that now that we're guaranteed to have Python 2.4 or later.
Signed-off-by: Karl Hasselström <kha@treskal.com>
---
stgit/git.py | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/stgit/git.py b/stgit/git.py
index 8857209..4b4c626 100644
--- a/stgit/git.py
+++ b/stgit/git.py
@@ -26,7 +26,6 @@ from stgit.utils import *
from stgit.out import *
from stgit.run import *
from stgit.config import config
-from sets import Set
# git exception class
class GitException(Exception):
@@ -959,10 +958,9 @@ def __remotes_from_dir(dir):
def remotes_list():
"""Return the list of remotes in the repository
"""
-
- return Set(__remotes_from_config()) | \
- Set(__remotes_from_dir('remotes')) | \
- Set(__remotes_from_dir('branches'))
+ return (set(__remotes_from_config())
+ | set(__remotes_from_dir('remotes'))
+ | set(__remotes_from_dir('branches')))
def remotes_local_branches(remote):
"""Returns the list of local branches fetched from given remote
^ permalink raw reply related
* Re: [PATCH 2/3] archive: specfile support (--pretty=format: in archive files)
From: Junio C Hamano @ 2007-09-03 23:53 UTC (permalink / raw)
To: René Scharfe; +Cc: Git Mailing List, Michael Gernoth, Thomas Glanzmann
In-Reply-To: <46DC4D45.4030208@lsrfire.ath.cx>
René Scharfe <rene.scharfe@lsrfire.ath.cx> writes:
> The attribute is useful for creating auto-updating specfiles. It is
> limited by the underlying function format_commit_message(), though.
> E.g. currently there is no placeholder for git-describe like output,
> and expanded specfiles can't contain NUL bytes. That can be fixed
> in format_commit_message() later and will then benefit users of
> git-log, too.
Interesting. I however wonder if "specfile" is a good name for
this attribute, although I admit I do not think of anything
better offhand.
> Why did it take me that long to come up with such a simple patch?
> There was a vacation and a feature freeze in between, but above all
> I was only recently able to convince myself (using ugly code) that
> format_commit_message() can indeed be made to expand placeholders
> to git-describe strings..
Thanks. Will take a look.
^ permalink raw reply
* Re: strbuf API
From: Miles Bader @ 2007-09-04 1:52 UTC (permalink / raw)
To: Johan Herland; +Cc: git
In-Reply-To: <20070903084610.GA21759@artemis.corp>
Pierre Habouzit <madcoder@debian.org> writes:
> For the record, I dislike the fact that bstring pullutes the b*
> namespace, whereas it should use bstr as a prefix everywhere, and some
> functions (like bstrcpy, that should definitely be named bstrdup) are
> really named the _wrong_ way
Yeah, I got the same impression. There's an odd "accumulated
haphazardly over time" feel to much of it.
[One thing I found especially weird is the way the "core" interface uses
lowercase names, but the "aux" interfaces all seem to use StUDlyCaPS...]
-Miles
--
Ich bin ein Virus. Mach' mit und kopiere mich in Deine .signature.
^ permalink raw reply
* Calculating tree nodes
From: Jon Smirl @ 2007-09-04 2:13 UTC (permalink / raw)
To: Git Mailing List
When I change a file it creates a new object with a new SHA. This new
SHA causes the tree node pointing to it to change. Changing the tree
node forces its parent to change and so on. Of course git batches all
of the changes together into a commit so that this ripple effect
doesn't happen for every file. But every commit causes a new root tree
node to be created, right?
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: [PATCH] Add a new lstat and fstat implementation based on Win32 API
From: Johannes Schindelin @ 2007-09-04 2:21 UTC (permalink / raw)
To: Marius Storm-Olsen; +Cc: Johannes Sixt, Johannes Sixt, Git Mailing List
In-Reply-To: <46DC5ED4.8050202@trolltech.com>
Hi,
On Mon, 3 Sep 2007, Marius Storm-Olsen wrote:
> Johannes Schindelin wrote:
> > To make it easier on others, I just uploaded it into the "teststat"
> > branch on 4msysgit.git (subject to removal in a few days).
>
> Ok, I've updated the patch in the 4msysgit.git repo, 'teststat' branch.
> RFC, and please test.
I'm too tired for more, but the first test which fails (consistently) is
t4200 here:
* FAIL 17: young records still live
test -f .git/rr-cache/08f6c39f296af7e0dd1b3b7d8bba18d0365f605f/preimage
&& test -f .git/rr-cache/4000000000000000000000000000000000000000/preimage
Ciao,
Dscho
^ permalink raw reply
* Re: Calculating tree nodes
From: Shawn O. Pearce @ 2007-09-04 2:51 UTC (permalink / raw)
To: Jon Smirl; +Cc: Git Mailing List
In-Reply-To: <9e4733910709031913q278cb9dbp441756afb28607c6@mail.gmail.com>
Jon Smirl <jonsmirl@gmail.com> wrote:
> When I change a file it creates a new object with a new SHA. This new
> SHA causes the tree node pointing to it to change. Changing the tree
> node forces its parent to change and so on. Of course git batches all
> of the changes together into a commit so that this ripple effect
> doesn't happen for every file. But every commit causes a new root tree
> node to be created, right?
Only if at least one file (or tree) differed. This may not be the
case if you do a merge with the ours merge strategy, but these are
very rare. So you can pretty much just say that yes, every commit
causes a new root tree to be created.
Usually the smallest number of objects created per commit is 3:
- the new commit
- the new root tree
- the new blob for a file in the root directory
The number increases as more files are modified or if they are in
subdirectories of the root.
--
Shawn.
^ permalink raw reply
* Re: [RFC] git-blame and git-gui blame wishlist
From: Shawn O. Pearce @ 2007-09-04 3:25 UTC (permalink / raw)
To: Jakub Narebski; +Cc: git, Junio Hamano, Linus Torvalds, Marco Costalba
In-Reply-To: <200709031240.04235.jnareb@gmail.com>
Jakub Narebski <jnareb@gmail.com> wrote:
> 1. In git-gui blame viewer you can click on shortened sha1 of a commit
...
> 2. Sometimes I'm interested only in part of a file. Thus I'd like
...
> 3. Sometimes when reviewing patches I do wonder: why the preimage looks
...
I've seen this list before... hmm, yea, I have, right here:
From: Jakub Narebski <jnareb@gmail.com>
To: git@vger.kernel.org
Subject: git-blame and blame GUI wishlist
Date: Mon, 6 Aug 2007 00:09:37 +0200
Message-Id: <200708060009.37595.jnareb@gmail.com>
;-)
To the extent that I can get around to it, it has been on my todo
list. But you have to keep in mind that my todo list for git is
very, very, very long and my time to work on it is quite limited
in comparsion.
I certainly would not mind if more folks helped out on git-gui by
contributing patches to it. :)
Unfortunately the survey results seem to indicate that not many of
our users know Tcl/Tk. Yea, it is a somewhat weird language, but
there's books and other documentation available for free through
a series tubes that Mr. Gore invented. Most programmers can pick
up Tcl. They just might want to hurt themselves afterwards...
--
Shawn.
^ permalink raw reply
* Re: Calculating tree nodes
From: Jon Smirl @ 2007-09-04 3:26 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: Git Mailing List
In-Reply-To: <20070904025153.GS18160@spearce.org>
Are tree objects really needed?
1) Make the path an attribute of the file object.
2) Commits are simply a list of all the objects that make up the commit.
Sort the SHAs in the commit and delta them.
This is something that has always bugged me about file systems. File
systems force hierarchical naming due to their directory structure.
There is no reason they have to work that way. Google is an example of
a giant file system that works just fine without hierarchical
directories. The full path should be just another attribute on the
file. If you want a hierarchical index into the file system you can
generate it by walking the files or using triggers. But you could also
delete the hierarchical directory and replace it with something else
like a full text index. Directories would become a computationally
generated cache, not a critical part of the file system. But this is a
git list so I shouldn't go too far off into file system design.
Git has picked up the hierarchical storage scheme since it was built
on a hierarchical file system. I don't this this is necessarily a good
thing moving forward.
If we really need tree objects they could become a new class of
computationally generated objects that could be deleted out of the
database at any time and recreated. For example if you think of the
file objects as being in a table, inserting a new row into this table
would compute new tree objects (an index).
Index is the key here, we may want other kinds of indexes in the
future. It was the mail about auto-generating the Maintainers list
that caused me to think about this. If file objects are a table with
triggers, building a hierarchical index for the Maintainers field
doesn't make sense.
These are just some initial thoughts on a different way to view the
data git is storing. Thinking about it as a database with fields and
indexes built via triggers may change the way we want to structure
things.
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: Calculating tree nodes
From: Johannes Schindelin @ 2007-09-04 3:40 UTC (permalink / raw)
To: Jon Smirl; +Cc: Shawn O. Pearce, Git Mailing List
In-Reply-To: <9e4733910709032026s7f94eed9h25d5165840cc38d2@mail.gmail.com>
Hi,
On Mon, 3 Sep 2007, Jon Smirl wrote:
> Are tree objects really needed?
Yes. For performance reasons, since a simple commit would kill you in any
reasonably sized repo.
Hth,
Dscho
^ permalink raw reply
* Re: Calculating tree nodes
From: Jon Smirl @ 2007-09-04 3:54 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Shawn O. Pearce, Git Mailing List
In-Reply-To: <Pine.LNX.4.64.0709040439070.28586@racer.site>
On 9/3/07, Johannes Schindelin <Johannes.Schindelin@gmx.de> wrote:
> Hi,
>
> On Mon, 3 Sep 2007, Jon Smirl wrote:
>
> > Are tree objects really needed?
>
> Yes. For performance reasons, since a simple commit would kill you in any
> reasonably sized repo.
That's not an obvious conclusion. A new commit is just a series of
edits to the previous commit. Start with the previous commit, edit it,
delta it and store it. Storing of the file objects is the same. Why
isn't this scheme fast than the current one?
>
> Hth,
> Dscho
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: Calculating tree nodes
From: David Tweed @ 2007-09-04 4:19 UTC (permalink / raw)
To: Jon Smirl; +Cc: Shawn O. Pearce, Git Mailing List
In-Reply-To: <9e4733910709032026s7f94eed9h25d5165840cc38d2@mail.gmail.com>
On 9/4/07, Jon Smirl <jonsmirl@gmail.com> wrote:
> Git has picked up the hierarchical storage scheme since it was built
> on a hierarchical file system.
FWIW my memory is that initial git used path-to-blob lists (as you're
describing but without delta-ing) and tree nodes were added after a
couple of weeks, the motivation _at the time_ being they were a
natural way to dramatically reduce the size of repos.
One of the nice things about tree nodes is that for doing a diff
between versions you can, to overwhelming probability, decide
equality/inequality of two arbitrarily deep and complicated subtrees
by comparing 40 characters, regardless of how remote and convoluted
their common ancestry. With delta chains don't you end up having to
trace back to a common "entry" in the history? (Of course, I don't
know how packs affect this - presumably there's some delta chasing to
get to the bare objects as well.)
--
cheers, dave tweed__________________________
david.tweed@gmail.com
Rm 124, School of Systems Engineering, University of Reading.
"we had no idea that when we added templates we were adding a Turing-
complete compile-time language." -- C++ standardisation committee
^ permalink raw reply
* Re: Calculating tree nodes
From: Martin Langhoff @ 2007-09-04 4:21 UTC (permalink / raw)
To: Jon Smirl; +Cc: Johannes Schindelin, Shawn O. Pearce, Git Mailing List
In-Reply-To: <9e4733910709032054y4407ce62o6b21935502bfacdb@mail.gmail.com>
On 9/4/07, Jon Smirl <jonsmirl@gmail.com> wrote:
> > Yes. For performance reasons, since a simple commit would kill you in any
> > reasonably sized repo.
>
> That's not an obvious conclusion. A new commit is just a series of
Hi Jon!
If you search the archives you'll find Linus explaining that the
initial git had all the directory structure in one single "tree"
object that held all the paths, not matter how deep. The problem with
that was taht every commit generated a huge new tree object, so he
switched to the current "nested trees" structure, which also has the
nice feature of speeding up diffs/merges if whole subtrees haven't
changed.
> edits to the previous commit. Start with the previous commit, edit it,
> delta it and store it. Storing of the file objects is the same. Why
> isn't this scheme fast than the current one?
I think you're a bit confused between 2 different things:
- git is _snapshot_ based, so every commit-tree-blob set is
completely independent. The "canonical" storage is each of those
gzipped in .git/objects
- however, for performance and on-disk-footprint, we delta them (very
efficiently I hear)
So if you ask the GIT APIs about a tree, you end up dealing with the
nested trees I describe. Similarly, if you ask for a blob, you get the
blob. But internally git _is_ delta-compressing them.
It's not compressing them immediately -- only when you run git gc. But
from an API perspective, you don't have to worry about that.
HTH
martin
^ permalink raw reply
* Re: Calculating tree nodes
From: Junio C Hamano @ 2007-09-04 4:28 UTC (permalink / raw)
To: Jon Smirl; +Cc: Johannes Schindelin, Shawn O. Pearce, Git Mailing List
In-Reply-To: <9e4733910709032054y4407ce62o6b21935502bfacdb@mail.gmail.com>
"Jon Smirl" <jonsmirl@gmail.com> writes:
>> Yes. For performance reasons, since a simple commit would kill you in any
>> reasonably sized repo.
>
> That's not an obvious conclusion. A new commit is just a series of
> edits to the previous commit. Start with the previous commit, edit it,
> delta it and store it. Storing of the file objects is the same. Why
> isn't this scheme fast than the current one?
I think you seem to be forgetting about tree comparison.
With a large project that has a reasonable directory structure
(i.e. not insanely narrow), a commit touches isolated subparts
of the whole tree. Think of an architecture specific patch to
the Linux kernel touching only include/asm-i386 and arch/i386
directories.
Being able to cull an entire subdirectory (e.g. drivers/ which
has 5700 files underneath) by only looking at the tree SHA-1 of
the containing tree is a _HUGE_ win.
And this is not just about two tree comparison. When you say:
git log v2.6.20 -- arch/i386/
what you are seeing is a simplified history that consists of
commits that touch only these paths. How would we determine if
a commit touch these paths efficiently? By comparing the "i386"
entry in tree objects for $commit^:arch and $commit:arch. You
do not have to look inside arch/i386/ trees to see if any of the
330 files in it is different. You just check a single SHA-1
pair.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox