* gitview: Fix DeprecationWarning
From: Aneesh Kumar @ 2006-02-24 8:32 UTC (permalink / raw)
To: Git Mailing List, Junio C Hamano
[-- Attachment #1: Type: text/plain, Size: 2 bytes --]
[-- Attachment #2: 0002-gitview-Fix-DeprecationWarning.txt --]
[-- Type: text/plain, Size: 743 bytes --]
Subject: gitview: Fix DeprecationWarning
DeprecationWarning: integer argument expected, got float
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@gmail.com>
---
contrib/gitview/gitview | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
1d34275e275b7450721033bf261ea29219934982
diff --git a/contrib/gitview/gitview b/contrib/gitview/gitview
index b04df74..4a6b448 100755
--- a/contrib/gitview/gitview
+++ b/contrib/gitview/gitview
@@ -154,7 +154,7 @@ class CellRendererGraph(gtk.GenericCellR
cols = self.node[0]
for start, end, colour in self.in_lines + self.out_lines:
- cols = max(cols, start, end)
+ cols = int(max(cols, start, end))
(column, colour, names) = self.node
names_len = 0
--
1.2.3.g2cf3-dirty
^ permalink raw reply related
* Re: [PATCH] New git-seek command with documentation and test.
From: H. Peter Anvin @ 2006-02-24 6:53 UTC (permalink / raw)
To: linux; +Cc: cworth, git
In-Reply-To: <20060224002915.17331.qmail@science.horizon.com>
linux@horizon.com wrote:
> The annoying thing about temporary branch names like "bisect" and "seek"
> is that:
> a) They clutter up the nae space available to the repository user.
> Users have to know that those are reserved names.
> b) If a repository is cloned while they're in use, they might get
> into a "remotes" file, with even more confusing results.
>
> This is somewhat heretical, but how about making a truly unnamed branch by
> having .git/HEAD *not* be a symlink, but rather hold a commit ID directly?
> It's already well established that files in the .git directory directly
> are strictly local to this working directory, so it seems a much better
> home for such temporary state.
>
It might be easier to just reserve part of the namespace, e.g. ".bisect"
and ".seek" instead.
-hpa
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Linus Torvalds @ 2006-02-24 6:43 UTC (permalink / raw)
To: Sam Vilain; +Cc: Junio C Hamano, git
In-Reply-To: <43FE1B9D.10403@vilain.net>
On Fri, 24 Feb 2006, Sam Vilain wrote:
>
> I like the term "Domain Specific Language" to refer to this sort of thing. It
> even hints at using the right kind of tools to achieve it, too :)
Just for fun, I wrote a first cut at a script engine for passing pipes
around.
It's designed so that the "fork+exec with a pipe" should be easily
replaced by "spawn with a socket" if that's what the target wants, but
it also has some rather strange syntax, so I'm in no way claiming that
this is a sane approach.
It was fun to write, though. You can already do some strange things with
it, like writing a script like this
set @ --since=2.months.ago Makefile
exec git-rev-parse --default HEAD $@
stdout arguments
exec git-rev-list $arguments
stdout revlist
exec git-diff-tree --pretty --stdin
stdin revlist
stdout diff-tree-output
exec less -S
stdin diff-tree-output
which kind of shows the idea (it sets the "@" variable by hand, because
the silly "git-script" thing doesn't set it itself).
I'm not sure this is worth pursuing (it really is a very strange kind of
script syntax), but it was amusing to do.
No docs - if you want to know how it works, you'll just have to read the
equally strange sources.
Linus
----
diff-tree 3e7dbcaae63278ccd413d93ecf9cba65a0d07021 (from d27d5b3c5b97ca30dfc5c448dc8cdae914131051)
Author: Linus Torvalds <torvalds@osdl.org>
Date: Thu Feb 23 22:06:12 2006 -0800
Add really strange script engine
diff --git a/Makefile b/Makefile
index 0c04882..247030b 100644
--- a/Makefile
+++ b/Makefile
@@ -164,7 +164,7 @@ PROGRAMS = \
git-upload-pack$X git-verify-pack$X git-write-tree$X \
git-update-ref$X git-symbolic-ref$X git-check-ref-format$X \
git-name-rev$X git-pack-redundant$X git-repo-config$X git-var$X \
- git-describe$X git-merge-tree$X
+ git-describe$X git-merge-tree$X git-script$X
# what 'all' will build and 'install' will install, in gitexecdir
ALL_PROGRAMS = $(PROGRAMS) $(SIMPLE_PROGRAMS) $(SCRIPTS)
@@ -204,7 +204,7 @@ LIB_OBJS = \
quote.o read-cache.o refs.o run-command.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
- fetch-clone.o \
+ fetch-clone.o execute.o \
$(DIFF_OBJS)
LIBS = $(LIB_FILE)
diff --git a/cache.h b/cache.h
index 5020f07..e4e66ce 100644
--- a/cache.h
+++ b/cache.h
@@ -352,4 +352,7 @@ extern int copy_fd(int ifd, int ofd);
extern int receive_unpack_pack(int fd[2], const char *me, int quiet);
extern int receive_keep_pack(int fd[2], const char *me, int quiet);
+/* script execution engine.. */
+extern int execute(const char *name, char *buf, unsigned int size);
+
#endif /* CACHE_H */
diff --git a/execute.c b/execute.c
new file mode 100644
index 0000000..abb6801
--- /dev/null
+++ b/execute.c
@@ -0,0 +1,622 @@
+/*
+ * Stupid git script execution engine
+ *
+ * Copyrigt (C) 2006, Linus Torvalds
+ *
+ * There's one rule here: only ever expand a single level of variables.
+ * In particular - we never expand as a string, and keep everything as
+ * a list of entries. Always.
+ *
+ * This avoids all issues with quoting etc, since it's never an issue.
+ * When we execute a program, we have a list of arguments, no quoting
+ * or string parsing involved.
+ */
+#include "cache.h"
+#include <sys/wait.h>
+
+enum vartype {
+ var_none,
+ var_fd,
+ var_array
+};
+
+struct argument {
+ enum vartype type;
+ int fd, members, allocs, error;
+ const char **array;
+};
+
+struct variable {
+ const char *name;
+ struct variable *next;
+ struct argument value;
+};
+
+struct cmd_struct {
+ const char *line;
+ unsigned int len;
+ struct cmd_struct *subcmd;
+ struct cmd_struct *next;
+};
+
+struct parse_buf {
+ const char *name;
+ const char *error;
+ char *prog;
+ unsigned int size;
+ unsigned int offset;
+ unsigned int line;
+ unsigned int linestart;
+};
+
+static struct variable *vars = NULL;
+static void run_program(struct cmd_struct *cmd);
+
+static int countline(struct parse_buf *buf)
+{
+ int count = 0;
+ unsigned offset;
+
+ for (offset = buf->offset; offset < buf->size; offset++) {
+ unsigned char c = buf->prog[offset];
+ switch (c) {
+ case '\n':
+ buf->line++;
+ /* fallthrough */
+ case '\r':
+ count = 0;
+ buf->offset = offset + 1;
+ buf->prog[offset] = 0;
+ continue;
+ case ' ':
+ count++;
+ continue;
+ case '\t':
+ count = (count + 8) & ~7;
+ continue;
+ default:
+ buf->linestart = offset;
+ return count;
+ }
+ }
+ buf->offset = offset;
+ return -2;
+}
+
+/*
+ * When this is called, we've already done the indentation check,
+ * and "buf->linestart" points to the actual start of the command.
+ */
+static struct cmd_struct *parse_one_line(struct parse_buf *buf)
+{
+ unsigned int offset;
+ struct cmd_struct *cmd = xmalloc(sizeof(*cmd));
+ memset(cmd, 0, sizeof(*cmd));
+
+ offset = buf->linestart;
+ cmd->line = buf->prog + offset;
+ for ( ; offset < buf->size; offset++) {
+ unsigned char c = buf->prog[offset];
+ switch (c) {
+ case '\n':
+ buf->prog[offset++] = 0;
+ buf->line++;
+ break;
+ default:
+ continue;
+ }
+ break;
+ }
+ buf->offset = offset;
+ return cmd;
+}
+
+static struct cmd_struct *parse(struct parse_buf *buf, int indent)
+{
+ struct cmd_struct *first = NULL, *last = NULL;
+
+ for (;;) {
+ struct cmd_struct *now;
+ int newindent = countline(buf);
+
+ if (newindent < indent)
+ break;
+ if (!first)
+ indent = newindent;
+ if (newindent > indent) {
+ struct cmd_struct *subcmd;
+ if (last->subcmd) {
+ buf->error = "bad indentation";
+ return NULL;
+ }
+ subcmd = parse(buf, newindent);
+ if (!subcmd)
+ return NULL;
+ last->subcmd = subcmd;
+ continue;
+ }
+ now = parse_one_line(buf);
+ if (!now)
+ return NULL;
+ if (last)
+ last->next = now;
+ else
+ first = now;
+ last = now;
+ }
+ return first;
+}
+
+static struct cmd_struct *exec_bad(struct cmd_struct *cmd, struct argument *arg)
+{
+ printf("unrecognized command: '%s'\n", cmd->line);
+ return NULL;
+}
+
+static struct cmd_struct *exec_echo(struct cmd_struct *cmd, struct argument *arg)
+{
+ int i;
+ for (i = 0; i < arg->members; i++)
+ printf("%s%c", arg->array[i], i == arg->members-1 ? '\n': ' ');
+ return cmd->next;
+}
+
+static struct variable *find_variable(const char *name)
+{
+ struct variable *var = vars;
+ while (var) {
+ if (!strcmp(var->name, name))
+ return var;
+ var = var->next;
+ }
+ return NULL;
+}
+
+static struct variable *create_variable(const char *name)
+{
+ struct variable *var = find_variable(name);
+
+ if (!var) {
+ var = xmalloc(sizeof(*var));
+ memset(var, 0, sizeof(*var));
+ var->name = name;
+ var->next = vars;
+ vars = var;
+ }
+ return var;
+}
+
+static struct cmd_struct *exec_set(struct cmd_struct *cmd, struct argument *arg)
+{
+ int count = arg->members;
+ struct variable *var;
+ const char *name;
+ unsigned size;
+
+ if (!count)
+ return cmd->next;
+ name = arg->array[0];
+ var = create_variable(arg->array[0]);
+
+ var->value.members = count-1;
+ size = count * sizeof(var->value.array[0]);
+ var->value.array = xmalloc(size);
+ memcpy(var->value.array, arg->array+1, size);
+
+ return cmd->next;
+}
+
+static void free_arg_list(struct argument *arg)
+{
+ /*
+ * We can't free the actual entries, since we re-use them
+ * on expansion. Right or wrong, that's how it is...
+ */
+ free(arg->array);
+}
+
+static void drop_variable(struct variable *var)
+{
+ free_arg_list(&var->value);
+ free(var);
+}
+
+static struct cmd_struct *exec_unset(struct cmd_struct *cmd, struct argument *arg)
+{
+ int i;
+
+ for (i = 0; i < arg->members; i++) {
+ const char *name = arg->array[i];
+ struct variable *var, **p = &vars;
+
+ while ((var = *p) != NULL) {
+ if (!strcmp(var->name, name)) {
+ *p = var->next;
+ drop_variable(var);
+ break;
+ }
+ p = &var->next;
+ }
+ }
+ return cmd->next;
+}
+
+static struct cmd_struct *exec_exit(struct cmd_struct *cmd, struct argument *arg)
+{
+ int value = 0;
+ if (arg->members)
+ value = atoi(arg->array[0]);
+ exit(value);
+}
+
+static struct cmd_struct *exec_else(struct cmd_struct *cmd, struct argument *arg)
+{
+ return cmd->next;
+}
+
+static struct cmd_struct *exec_if(struct cmd_struct *cmd, struct argument *arg)
+{
+ struct cmd_struct *pos, *neg;
+
+ pos = cmd->subcmd;
+ neg = cmd->next;
+ if (neg) {
+ if (!strncmp(neg->line, "else", 4))
+ neg = neg->subcmd;
+ else
+ neg = NULL;
+ }
+ if (!arg->members)
+ pos = neg;
+ run_program(pos);
+ return cmd->next;
+}
+
+static int match_cmd(const char *match, struct cmd_struct *cmd)
+{
+ int len = strlen(match), cmdlen = strlen(cmd->line);
+ if (cmdlen < len)
+ return 0;
+ if (cmdlen > len && !isspace(cmd->line[len]))
+ return 0;
+ return !memcmp(match, cmd->line, len);
+}
+
+static int set_input(int *redirect, const char *val)
+{
+ struct variable *var;
+
+ while (isspace(*val))
+ val++;
+ var = find_variable(val);
+ if (!var || var->value.type != var_fd)
+ die("bad 'fd' variable %s", val);
+
+ *redirect = var->value.fd;
+ var->value.fd = -1;
+ return 0;
+}
+
+static int set_output(int *redirect, const char *val)
+{
+ int fd[2];
+ struct variable *var;
+
+ while (isspace(*val))
+ val++;
+ var = create_variable(val);
+
+ if (pipe(fd) < 0)
+ die("unable to pipe");
+ var->value.type = var_fd;
+ var->value.fd = fd[0];
+ *redirect = fd[1];
+ return 0;
+}
+
+/*
+ * Only these routines should need to be ported to a "spawn()" interface
+ */
+static struct cmd_struct *exec_exec(struct cmd_struct *cmd, struct argument *arg)
+{
+ int redirect[3];
+ pid_t pid;
+ int nr = arg->members;
+ struct cmd_struct *io;
+
+ if (!nr) {
+ run_program(cmd->subcmd);
+ return cmd->next;
+ }
+
+ memset(redirect, 0, sizeof(redirect));
+ for (io = cmd->subcmd; io ; io = io->next) {
+ if (match_cmd("stdin", io)) {
+ set_input(redirect+0, io->line + 5);
+ continue;
+ }
+ if (match_cmd("stdout", io)) {
+ set_output(redirect+1, io->line + 6);
+ continue;
+ }
+ if (match_cmd("stderr", io)) {
+ set_output(redirect+2, io->line + 6);
+ continue;
+ }
+ }
+
+ /*
+ * HERE! Use spawn if necessary - the fd redirect table has been set up
+ */
+ pid = vfork();
+ if (pid < 0) {
+ error("vfork failed (%s)", strerror(errno));
+ return NULL;
+ }
+
+ if (!pid) {
+ int retval;
+ if (redirect[0]) {
+ dup2(redirect[0], 0);
+ close(redirect[0]);
+ }
+ if (redirect[1]) {
+ dup2(redirect[1], 1);
+ close(redirect[1]);
+ }
+ if (redirect[2]) {
+ dup2(redirect[2], 2);
+ close(redirect[2]);
+ }
+ retval = execvp(arg->array[0], (char *const*) arg->array);
+ exit(255);
+ }
+
+ if (redirect[0])
+ close(redirect[0]);
+ if (redirect[1])
+ close(redirect[1]);
+ if (redirect[2])
+ close(redirect[2]);
+
+ /*
+ * If we don't have anybody waiting for output,
+ * wait for it
+ */
+ if (!redirect[1]) {
+ int status;
+ while (waitpid(pid, &status, 0) < 0) {
+ if (errno == EINTR)
+ continue;
+ error("unable to wait for child (%s)", strerror(errno));
+ return NULL;
+ }
+ /* FIXME! Put exit status in a variable! */
+ }
+ run_program(cmd->subcmd);
+ return cmd->next;
+}
+
+static struct cmd_struct *exec_nop(struct cmd_struct *cmd, struct argument *arg)
+{
+ return cmd->next;
+}
+
+static const struct cmd_def {
+ const char *n;
+ int len;
+ struct cmd_struct *(*exec)(struct cmd_struct *, struct argument *);
+} cmds[] = {
+ { "bad", 0, exec_bad },
+ { "set", 3, exec_set },
+ { "unset", 5, exec_unset },
+ { "echo", 4, exec_echo },
+ { "exit", 4, exec_exit },
+ { "if", 2, exec_if },
+ { "else", 4, exec_else },
+ { "exec", 4, exec_exec },
+ { "stdin", 5, exec_nop },
+ { "stdout", 6, exec_nop },
+ { "stderr", 6, exec_nop },
+};
+
+static void add_argument(struct argument *arg, const char *n)
+{
+ int allocs = arg->allocs, members = arg->members;
+
+ if (members+1 >= allocs) {
+ allocs = (allocs * 3) / 2 + 32;
+ arg->array = xrealloc(arg->array, allocs*sizeof(arg->array[0]));
+ arg->allocs = allocs;
+ }
+ arg->array[members++] = n;
+ arg->array[members] = NULL;
+ arg->members = members;
+}
+
+static int get_word(const char *line, const char **res)
+{
+ int quoted = 0;
+ int offset = 0;
+ int stop = 0;
+ char *buf;
+
+ for (;;) {
+ unsigned char c = line[offset];
+ if (!c)
+ break;
+ offset++;
+ if (c == '\\') {
+ quoted ^= 1;
+ continue;
+ }
+ if (quoted) {
+ quoted = 0;
+ continue;
+ }
+ if (stop) {
+ if (c == stop)
+ stop = 0;
+ continue;
+ }
+ if (c == '\'' || c == '"') {
+ stop = c;
+ continue;
+ }
+ if (!isspace(c)) {
+ continue;
+ }
+ offset--;
+ break;
+ }
+ if (quoted || stop)
+ return -1;
+ buf = xmalloc(offset+1);
+ memcpy(buf, line, offset);
+ buf[offset] = 0;
+ *res = buf;
+ return offset;
+}
+
+static int expand_word(const char *line, struct argument *arg)
+{
+ const char *word;
+ int offset = get_word(line, &word);
+
+ if (offset > 0)
+ add_argument(arg, word);
+ return offset;
+}
+
+static void convert_fd_into_array(struct variable *var)
+{
+ int fd = var->value.fd;
+ char buffer[8192];
+ int len, offset, last;
+
+ var->value.fd = -1;
+ var->value.type = var_array;
+ len = 0;
+ for (;;) {
+ int ret = read(fd, buffer + len, sizeof(buffer) - len);
+ if (!ret)
+ break;
+ if (ret < 0) {
+ if (errno == EINTR)
+ continue;
+ break;
+ }
+ len += ret;
+ if (len >= sizeof(buffer))
+ break;
+ }
+
+ last = 0;
+ for (offset = 0; offset < len; offset++) {
+ unsigned char c = buffer[offset];
+ if (c == '\n') {
+ buffer[offset] = 0;
+ add_argument(&var->value, buffer+last);
+ last = offset+1;
+ continue;
+ }
+ }
+}
+
+static int expand_variable(const char *line, struct argument *arg)
+{
+ const char *word;
+ int offset = get_word(line+1, &word);
+
+ if (offset > 0) {
+ struct variable *var = find_variable(word);
+ offset++; /* The '$' character itself */
+ if (var) {
+ int i;
+ if (var->value.type == var_fd)
+ convert_fd_into_array(var);
+ for (i = 0; i < var->value.members; i++)
+ add_argument(arg, var->value.array[i]);
+ }
+ }
+ return offset;
+}
+
+static int expand_value(const char *line, struct argument *arg)
+{
+ unsigned char c = *line;
+
+ switch (c) {
+ case '$':
+ return expand_variable(line, arg);
+ default:
+ return expand_word(line, arg);
+ }
+}
+
+static struct argument *expand_line(const char *line)
+{
+ struct argument *arg;
+
+ arg = xmalloc(sizeof(*arg));
+ memset(arg, 0, sizeof(*arg));
+ arg->type = var_array;
+ for (;;) {
+ int n;
+ while (isspace(*line)) {
+ line++;
+ }
+ if (!*line)
+ break;
+ n = expand_value(line, arg);
+ if (n <= 0)
+ break;
+ line += n;
+ }
+ return arg;
+}
+
+static void run_program(struct cmd_struct *cmd)
+{
+ while (cmd) {
+ int i;
+ const struct cmd_def *run = cmds+0;
+ struct argument *arg = NULL;
+ int cmdlen = strlen(cmd->line);
+
+ for (i = 1; i < sizeof(cmds)/sizeof(cmds[0]); i++) {
+ const struct cmd_def *def = cmds + i;
+ int len = def->len;
+ if (len > cmdlen)
+ continue;
+ if (len < cmdlen && !isspace(cmd->line[len]))
+ continue;
+ if (memcmp(cmd->line, def->n, len))
+ continue;
+ run = def;
+ arg = expand_line(cmd->line + len);
+ break;
+ }
+ cmd = run->exec(cmd, arg);
+ }
+}
+
+int execute(const char *name, char *buf, unsigned int size)
+{
+ struct parse_buf p;
+ struct cmd_struct *program;
+
+ p.name = name;
+ p.prog = buf;
+ p.size = size;
+ p.offset = 0;
+ p.line = 1;
+ p.error = "empty program";
+
+ program = parse(&p, -1);
+ if (!program || p.offset != p.size)
+ die("parse error at %s:%d: %s", p.name, p.line, p.error);
+
+ run_program(program);
+ return 0;
+}
diff --git a/script.c b/script.c
new file mode 100644
index 0000000..ae85598
--- /dev/null
+++ b/script.c
@@ -0,0 +1,58 @@
+/*
+ * Silly git script language
+ *
+ * Copyright (C) 2006, Linus Torvalds
+ */
+#include "cache.h"
+
+static const char script_usage[] = "git-script <scriptfile>";
+
+int main(int argc, char **argv)
+{
+ int fd;
+ char *buf;
+ const char *filename;
+ unsigned int size, alloc;
+
+ fd = 0;
+ switch (argc) {
+ case 1:
+ filename = "stdin";
+ fd = dup(0);
+ close(0);
+ open("/dev/null", O_RDONLY);
+ break;
+ case 2:
+ filename = argv[1];
+ fd = open(filename, O_RDONLY);
+ if (fd < 0)
+ die("unable to open '%s': %s", filename, strerror(errno));
+ break;
+ default:
+ usage(script_usage);
+ }
+
+ buf = NULL;
+ alloc = 0;
+ size = 0;
+ for (;;) {
+ int nr;
+ if (size >= alloc) {
+ alloc = (alloc * 3) / 2 + 8192;
+ buf = xrealloc(buf, alloc);
+ }
+ nr = read(fd, buf + size, alloc - size);
+ if (!nr)
+ break;
+ if (nr < 0) {
+ if (errno == EAGAIN || errno == EINTR)
+ continue;
+ die("script read failed (%s)", strerror(errno));
+ }
+ size += nr;
+ }
+ close(fd);
+
+ execute(filename, buf, size);
+ return 0;
+}
^ permalink raw reply related
* Re: [PATCH] git-seek: Eliminate spurious warning. Fix errant reference to git-bisect in docs.
From: Junio C Hamano @ 2006-02-24 6:02 UTC (permalink / raw)
To: Carl Worth; +Cc: git
In-Reply-To: <87vev5r2m4.wl%cworth@cworth.org>
Carl Worth <cworth@cworth.org> writes:
>> I wonder if its a good idea to silently reset a branch named with a
>> short common word?
>
> It at least takes some care not to leave commits dangling when doing
> this, (the seek branch must at least be a subset of the current
> HEAD). I was pretty much following the lead of git-bisect here,
> (though "bisect" is definitely a touch longer and less common than
> "seek").
IIUC Cogito seems to use cg-seek-point or something long and
unusual like that...
^ permalink raw reply
* Re: FYI: git-am allows creation of empty commits.
From: Junio C Hamano @ 2006-02-24 5:56 UTC (permalink / raw)
To: Eric W. Biederman; +Cc: git
In-Reply-To: <m1slqahyxt.fsf@ebiederm.dsl.xmission.com>
ebiederm@xmission.com (Eric W. Biederman) writes:
> After fixing it up and doing all of my edits I occasionally forget
> the git-update-index step, before calling git-am --resolved. This
> proceeds along it's merry way and creates an empty commit.
Certainly a safty measure is missing here. Thanks for
noticing. How about something like this?
---
diff --git a/git-am.sh b/git-am.sh
index 85ecada..6730813 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -300,10 +300,16 @@ do
} >"$dotest/final-commit"
;;
*)
- case "$resolved,$interactive" in
- tt)
- # This is used only for interactive view option.
+ case "$resolved" in
+ t)
+ # This is used for interactive view option, but
+ # also we should see if the user really did
+ # something...
git-diff-index -p --cached HEAD >"$dotest/patch"
+ test -s "$dotest/patch" || {
+ echo "You said resolved, but there is no change in the index..."
+ stop_here $this
+ }
;;
esac
esac
^ permalink raw reply related
* Re: [PATCH] Convert open("-|") to qx{} calls
From: Rogan Dawes @ 2006-02-24 5:19 UTC (permalink / raw)
To: Alex Riesen; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <20060223211403.GB5827@steel.home>
Alex Riesen wrote:
> Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
>> Johannes> Now that our local Perl guru joined the discussion, may I ask what
>> Johannes> is, and what is not quoted when put inside qx{}?
>>
>> Nothing is quoted. Your string acts as if it was XXX in:
>>
>> sh -c 'XXX'
>>
>
> Not so for ActiveState. It'll just run the first non-whitespace word
> passing the rest of the line in its command-line.
> It's not even worse then to pass it all to cmd/command :)
>
Not true.
> type t
#!perl -w
print qx{echo joe & echo joe}."\n";
> perl t
joe
joe
>
If the shell was not interpreting the arguments, you would expect to get
1 line with:
joe & echo joe
on it.
> perl -v
This is perl, v5.8.7 built for MSWin32-x86-multi-thread
(with 7 registered patches, see perl -V for more detail)
Copyright 1987-2005, Larry Wall
Binary build 813 [148120] provided by ActiveState http://www.ActiveState.com
ActiveState is a division of Sophos.
Built Jun 6 2005 13:36:37
Perl may be copied only under the terms of either the Artistic License
or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'. If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Regards,
Rogan
^ permalink raw reply
* Re: [PATCH] New git-seek command with documentation and test.
From: linux @ 2006-02-24 1:23 UTC (permalink / raw)
To: Johannes.Schindelin, linux; +Cc: cworth, git
In-Reply-To: <Pine.LNX.4.63.0602240152490.32472@wbgn013.biozentrum.uni-wuerzburg.de>
> Not heretical. How do you intend to switch branches now?
Point .git/HEAD at the branch like usual.
.git/HEAD would not be a symref *only* when on the unnamed temporary
branch (which doesn't accept commits).
> And how do you intend to record the starting point of git-seek to
> which you want to return to?
Te same way it's done now for git-seek or git-bisect: by copying the
old HEAD to a temporary location like .git/head-name.
> All leads back to .git/HEAD pointing to a branch (or whatever
> you want to call it).
In the usual case, yes it should. Any time you want to be able to
develop on a branch, you need .git/HEAD pointing to a branch.
You only make it point to a commit directly is when exploring the
history with no intention of developing from it.
(Note that you can easily change your mind with a simple
"git checkout -b <branch>".)
> And BTW, .git/HEAD is no symlink these days, but a symref.
Yes, I'm sorry; I was just being lazy with my terminology.
^ permalink raw reply
* [PATCH] git-seek: Eliminate spurious warning. Fix errant reference to git-bisect in docs.
From: Carl Worth @ 2006-02-24 1:01 UTC (permalink / raw)
To: J. Bruce Fields; +Cc: Junio C Hamano, git, Linus Torvalds
In-Reply-To: <20060224001848.GB21094@fieldses.org>
[-- Attachment #1: Type: text/plain, Size: 2198 bytes --]
This fixed a bug that would cause "git seek" to mistakenly try to
checkout the seek branch just after deleting it. Of course, that would
never work, but fixing the bug does squelch the annoying error caused
by the bug.
Also fix an errant title of "git-bisect" in the git-seek documentation.
---
On Thu, 23 Feb 2006 19:18:48 -0500, "J. Bruce Fields" wrote:
> On Thu, Feb 23, 2006 at 12:31:25PM -0800, Carl Worth wrote:
> > +git-bisect(1)
> > +=============
>
> Oops.
Thanks.
> I wonder if its a good idea to silently reset a branch named with a
> short common word?
It at least takes some care not to leave commits dangling when doing
this, (the seek branch must at least be a subset of the current
HEAD). I was pretty much following the lead of git-bisect here,
(though "bisect" is definitely a touch longer and less common than
"seek").
If it would be preferred to hide such "internal" branch names behind
some unlikely symbol or such, that would obviously be easy to do.
As is, the seek branch is at least documented, and rather well
advertised in operation, (for example, returning with "git seek"
reported "Deleted branch seek.").
> These long usage texts with language duplicated from the man pages seem
> like they'd be asking for bit-rot, when an update happens in one place
> but not the other. I dunno.
Yeah, I don't know. Again, I was just imitating things I'd seen
elsewhere.
Documentation/git-seek.txt | 4 ++--
git-seek.sh | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
43f042982c26859b6b7f6055fc03dda8e89f4e70
diff --git a/Documentation/git-seek.txt b/Documentation/git-seek.txt
index cb5c13d..513dbc7 100644
--- a/Documentation/git-seek.txt
+++ b/Documentation/git-seek.txt
@@ -1,5 +1,5 @@
-git-bisect(1)
-=============
+git-seek(1)
+===========
NAME
----
diff --git a/git-seek.sh b/git-seek.sh
index 26f0b76..921c014 100644
--- a/git-seek.sh
+++ b/git-seek.sh
@@ -65,7 +65,7 @@ seek_reset() {
source
fi
git checkout "$source" &&
- (git branch -d seek || err=$? ; git checkout seek ; exit $err) &&
+ (git branch -d seek || (err=$? ; git checkout seek ; exit $err)) &&
rm -f "$GIT_DIR/head-name"
}
--
1.2.3.g2656-dirty
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply related
* Re: [PATCH] New git-seek command with documentation and test.
From: Johannes Schindelin @ 2006-02-24 0:54 UTC (permalink / raw)
To: linux; +Cc: cworth, git
In-Reply-To: <20060224002915.17331.qmail@science.horizon.com>
Hi,
On Fri, 23 Feb 2006, linux@horizon.com wrote:
> This is somewhat heretical, but how about making a truly unnamed branch by
> having .git/HEAD *not* be a symlink, but rather hold a commit ID directly?
Not heretical. How do you intend to switch branches now? And how do you
intend to record the starting point of git-seek to which you want to
return to? All leads back to .git/HEAD pointing to a branch (or whatever
you want to call it). And BTW, .git/HEAD is no symlink these days, but a
symref.
Hth,
Dscho
^ permalink raw reply
* Re: [PATCH] Add git-annotate, a tool for assigning blame.
From: Johannes Schindelin @ 2006-02-24 0:52 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Fredrik Kuivinen
In-Reply-To: <7vek1thaop.fsf@assigned-by-dhcp.cox.net>
Hi,
On Thu, 23 Feb 2006, Junio C Hamano wrote:
> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>
> >> > This could probably benefit a *LOT* from the libification project, I
> >> > think, though.
> >>
> >> Yes, perhaps. Some of the git-rev-list bits might simplify a couple of
> >> things.
> >
> > The major problem is probably not solved: What Linus calls a "stream
> > interface".
> >
> > I.e. if you pipe the output of git-rev-list to another program, you
> > *need* to execute the two semi-simultaneously. The "alternative" would be
> > to use buffers, which can get huge (and are sometimes not needed: think
> > git-whatchanged, which starts outputting before it's getting no more
> > input).
>
> You need a limited coroutine support, something like generator
> functions in Python ;-). In C, traditional way of doing it is
> to make your application specific function a callback of
> rev-list or whatever generator is, which is very unpleasant to
> code.
The most unpleasant aspect is that you usually need something like "this"
in C++: a pointer to an object (which you have to pass around all the
time). Without it you can not use the function in a nested way.
However, I can also see benefits of this when compared to the traditional
UNIX approach. It should be faster, for one, since you don't need to pass
data through pipes all the time. (This might be not as true for Linux as
for other OSes.)
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] New git-seek command with documentation and test.
From: linux @ 2006-02-24 0:29 UTC (permalink / raw)
To: cworth; +Cc: git
The annoying thing about temporary branch names like "bisect" and "seek"
is that:
a) They clutter up the nae space available to the repository user.
Users have to know that those are reserved names.
b) If a repository is cloned while they're in use, they might get
into a "remotes" file, with even more confusing results.
This is somewhat heretical, but how about making a truly unnamed branch by
having .git/HEAD *not* be a symlink, but rather hold a commit ID directly?
It's already well established that files in the .git directory directly
are strictly local to this working directory, so it seems a much better
home for such temporary state.
Admittedly, this requires more invasive edits (particularly adding a third
legitimate case to validate_symref()), but it seems to make more sense.
And be ultimately simpler than workarounds for the above problems.
Just loosen the rules from ".git/HEAD must be a symlink" to
".git/HEAD must be a symlink before you can check in".
Yes, I know it's radical. At least I'm not questioning the
power and efficacy of indulgences. :-)
^ permalink raw reply
* Re: [PATCH] New git-seek command with documentation and test.
From: J. Bruce Fields @ 2006-02-24 0:18 UTC (permalink / raw)
To: Carl Worth; +Cc: Junio C Hamano, git, Linus Torvalds
In-Reply-To: <87zmkhrf4y.wl%cworth@cworth.org>
On Thu, Feb 23, 2006 at 12:31:25PM -0800, Carl Worth wrote:
> --- /dev/null
> +++ b/Documentation/git-seek.txt
> @@ -0,0 +1,44 @@
> +git-bisect(1)
> +=============
Oops.
> +When given a <revision>, git-seek updates the files in the working
> +tree to the state of the given revision. It will do this by performing
> +a checkout of <revision> to a new branch named "seek", or by resetting
> +the seek branch if it already exists.
I wonder if its a good idea to silently reset a branch named with a
short common word?
> +LONG_USAGE='git-seek provides a temporary excursion through the revision history.
> +
> +When given a <revision>, git-seek updates the files in the working
> +tree to the state of the given revision. It will do this by performing
> +a checkout of <revision> to a new branch named "seek", or by resetting
> +the seek branch if it already exists.
These long usage texts with language duplicated from the man pages seem
like they'd be asking for bit-rot, when an update happens in one place
but not the other. I dunno.
--b.
^ permalink raw reply
* Re: [PATCH] Add git-annotate, a tool for assigning blame.
From: Junio C Hamano @ 2006-02-24 0:17 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, Fredrik Kuivinen
In-Reply-To: <Pine.LNX.4.63.0602240055080.31816@wbgn013.biozentrum.uni-wuerzburg.de>
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
>> > This could probably benefit a *LOT* from the libification project, I
>> > think, though.
>>
>> Yes, perhaps. Some of the git-rev-list bits might simplify a couple of
>> things.
>
> The major problem is probably not solved: What Linus calls a "stream
> interface".
>
> I.e. if you pipe the output of git-rev-list to another program, you
> *need* to execute the two semi-simultaneously. The "alternative" would be
> to use buffers, which can get huge (and are sometimes not needed: think
> git-whatchanged, which starts outputting before it's getting no more
> input).
You need a limited coroutine support, something like generator
functions in Python ;-). In C, traditional way of doing it is
to make your application specific function a callback of
rev-list or whatever generator is, which is very unpleasant to
code.
>> I have found some severe problems with the code I posted, in
>> particular it doesn't handle parallel development tracks at all. I am
>> working on fixing it, but it isn't finished yet.
>
> Looking forward to them!
Likewise.
^ permalink raw reply
* Re: [PATCH] Add git-annotate, a tool for assigning blame.
From: Johannes Schindelin @ 2006-02-24 0:00 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Ryan Anderson, Junio C Hamano, git
In-Reply-To: <20060223225547.GB8673@c165.ib.student.liu.se>
Hi,
On Thu, 23 Feb 2006, Fredrik Kuivinen wrote:
> On Thu, Feb 23, 2006 at 05:10:49PM -0500, Ryan Anderson wrote:
> > (Biased critique since I have the other tool in the tree, but still...)
> >
> > > + FILE* fout = fopen("/tmp/git-blame-tmp1", "w");
> >
> > Probably should be using something like mkstemp (mkstmp?) here, so if
> > someone is runnign things as root or with a malicous user around, things
> > don't collide.
> >
> > Hell, so on a multi-user machine this doesn't blow up on you.
>
> Yep, I know. The code is mostly a proof of concept. I didn't submit it
> for inclusion.
Ha ha, famous last words!
> > But, read down for a related comment.
> >
> > > + if(!fout)
> > > + die("fopen tmp1 failed: %s", strerror(errno));
> > > +
> > > + if(fwrite(info_c->buf, info_c->size, 1, fout) != 1)
> > > + die("fwrite 1 failed: %s", strerror(errno));
> > > + fclose(fout);
> > > +
> > > + fout = fopen("/tmp/git-blame-tmp2", "w");
> > > + if(!fout)
> > > + die("fopen tmp2 failed: %s", strerror(errno));
> > > +
> > > + if(fwrite(info_o->buf, info_o->size, 1, fout) != 1)
> > > + die("fwrite 2 failed: %s", strerror(errno));
> > > + fclose(fout);
> > > +
> > > + FILE* fin = popen("diff -u0 /tmp/git-blame-tmp1 /tmp/git-blame-tmp2", "r");
> > > + if(!fin)
> > > + die("popen failed: %s", strerror(errno));
> >
> > Can't git-diff-tree do this sufficiently, anyway? See my Perl script
> > for an example, you just need both commit IDs and both filenames and the
> > appropriate -M and you get the right results.
> >
> > (It's possible that's part of where the performance differences are,
> > though, not really sure at the moment.)
> >
>
> Yeah.. maybe. My first thought was to avoid forking and execing diff
> and use some C library for doing the diffing instead (libxdiff). But
> then I just wanted to get some code working and the simplest solution
> I could think of was to fork and exec diff.
git-diff-tree fork()s a diff. So, by fork()ing git-diff-tree you get two
fork()s (and no knife...).
> > I'm going to stop there for the moment, I'm not really confident in my
> > understanding of git-internals to say much more just yet.
> >
> > This could probably benefit a *LOT* from the libification project, I
> > think, though.
>
> Yes, perhaps. Some of the git-rev-list bits might simplify a couple of
> things.
The major problem is probably not solved: What Linus calls a "stream
interface".
I.e. if you pipe the output of git-rev-list to another program, you
*need* to execute the two semi-simultaneously. The "alternative" would be
to use buffers, which can get huge (and are sometimes not needed: think
git-whatchanged, which starts outputting before it's getting no more
input).
> I have found some severe problems with the code I posted, in
> particular it doesn't handle parallel development tracks at all. I am
> working on fixing it, but it isn't finished yet.
Looking forward to them!
Ciao,
Dscho
^ permalink raw reply
* Re: [PATCH] Add git-annotate, a tool for assigning blame.
From: Fredrik Kuivinen @ 2006-02-23 22:55 UTC (permalink / raw)
To: Ryan Anderson; +Cc: Fredrik Kuivinen, Junio C Hamano, git
In-Reply-To: <20060223221048.GA6423@mythryan2.michonline.com>
On Thu, Feb 23, 2006 at 05:10:49PM -0500, Ryan Anderson wrote:
> (Biased critique since I have the other tool in the tree, but still...)
>
> > + FILE* fout = fopen("/tmp/git-blame-tmp1", "w");
>
> Probably should be using something like mkstemp (mkstmp?) here, so if
> someone is runnign things as root or with a malicous user around, things
> don't collide.
>
> Hell, so on a multi-user machine this doesn't blow up on you.
Yep, I know. The code is mostly a proof of concept. I didn't submit it
for inclusion.
>
> But, read down for a related comment.
>
> > + if(!fout)
> > + die("fopen tmp1 failed: %s", strerror(errno));
> > +
> > + if(fwrite(info_c->buf, info_c->size, 1, fout) != 1)
> > + die("fwrite 1 failed: %s", strerror(errno));
> > + fclose(fout);
> > +
> > + fout = fopen("/tmp/git-blame-tmp2", "w");
> > + if(!fout)
> > + die("fopen tmp2 failed: %s", strerror(errno));
> > +
> > + if(fwrite(info_o->buf, info_o->size, 1, fout) != 1)
> > + die("fwrite 2 failed: %s", strerror(errno));
> > + fclose(fout);
> > +
> > + FILE* fin = popen("diff -u0 /tmp/git-blame-tmp1 /tmp/git-blame-tmp2", "r");
> > + if(!fin)
> > + die("popen failed: %s", strerror(errno));
>
> Can't git-diff-tree do this sufficiently, anyway? See my Perl script
> for an example, you just need both commit IDs and both filenames and the
> appropriate -M and you get the right results.
>
> (It's possible that's part of where the performance differences are,
> though, not really sure at the moment.)
>
Yeah.. maybe. My first thought was to avoid forking and execing diff
and use some C library for doing the diffing instead (libxdiff). But
then I just wanted to get some code working and the simplest solution
I could think of was to fork and exec diff.
> I'm going to stop there for the moment, I'm not really confident in my
> understanding of git-internals to say much more just yet.
>
> This could probably benefit a *LOT* from the libification project, I
> think, though.
Yes, perhaps. Some of the git-rev-list bits might simplify a couple of
things.
I have found some severe problems with the code I posted, in
particular it doesn't handle parallel development tracks at all. I am
working on fixing it, but it isn't finished yet.
Thanks for the comments.
- Fredrik
^ permalink raw reply
* Re: [PATCH] fix warning from pack-objects.c
From: Andreas Ericsson @ 2006-02-23 22:51 UTC (permalink / raw)
To: Luck, Tony; +Cc: git
In-Reply-To: <200602232242.k1NMgdAJ018406@agluck-lia64.sc.intel.com>
Luck, Tony wrote:
> When compiling on ia64 I get this warning (from gcc 3.4.3):
>
> gcc -o pack-objects.o -c -g -O2 -Wall -DSHA1_HEADER='<openssl/sha.h>' pack-objects.c
> pack-objects.c: In function `pack_revindex_ix':
> pack-objects.c:94: warning: cast from pointer to integer of different size
>
> A double cast (first to long, then to int) shuts gcc up, but is there
> a better way?
>
Make ui and i unsigned long and cast p to unsigned long (or perhaps
ptrdiff_t is preferred?). On 32-bit archs it's no difference, but 64-bit
archs can work with their native size. It's slightly faster (although I
expect the compiler takes care of that anyways).
I noticed this earlier on my shiny AMD FX2 64-bit. The tests run just
fine with my solution. I expect they will with yours as well.
> Signed-off-by: Tony Luck <tony.luck@intel.com>
>
> ---
>
> diff --git a/pack-objects.c b/pack-objects.c
> index 8f352aa..c985fab 100644
> --- a/pack-objects.c
> +++ b/pack-objects.c
> @@ -91,7 +91,7 @@ static int reused_delta = 0;
>
> static int pack_revindex_ix(struct packed_git *p)
> {
> - unsigned int ui = (unsigned int) p;
> + unsigned int ui = (unsigned int)(long)p;
> int i;
>
> ui = ui ^ (ui >> 16); /* defeat structure alignment */
> -
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
--
Andreas Ericsson andreas.ericsson@op5.se
OP5 AB www.op5.se
Tel: +46 8-230225 Fax: +46 8-230231
^ permalink raw reply
* [PATCH] fix warning from pack-objects.c
From: Luck, Tony @ 2006-02-23 22:42 UTC (permalink / raw)
To: git
When compiling on ia64 I get this warning (from gcc 3.4.3):
gcc -o pack-objects.o -c -g -O2 -Wall -DSHA1_HEADER='<openssl/sha.h>' pack-objects.c
pack-objects.c: In function `pack_revindex_ix':
pack-objects.c:94: warning: cast from pointer to integer of different size
A double cast (first to long, then to int) shuts gcc up, but is there
a better way?
Signed-off-by: Tony Luck <tony.luck@intel.com>
---
diff --git a/pack-objects.c b/pack-objects.c
index 8f352aa..c985fab 100644
--- a/pack-objects.c
+++ b/pack-objects.c
@@ -91,7 +91,7 @@ static int reused_delta = 0;
static int pack_revindex_ix(struct packed_git *p)
{
- unsigned int ui = (unsigned int) p;
+ unsigned int ui = (unsigned int)(long)p;
int i;
ui = ui ^ (ui >> 16); /* defeat structure alignment */
^ permalink raw reply related
* Re: [PATCH] Add git-annotate, a tool for assigning blame.
From: Ryan Anderson @ 2006-02-23 22:10 UTC (permalink / raw)
To: Fredrik Kuivinen; +Cc: Junio C Hamano, git
In-Reply-To: <20060220234054.GA7903@c165.ib.student.liu.se>
(Biased critique since I have the other tool in the tree, but still...)
On Tue, Feb 21, 2006 at 12:40:54AM +0100, Fredrik Kuivinen wrote:
> diff --git a/blame.c b/blame.c
> new file mode 100644
> index 0000000..d4a2fad
> --- /dev/null
> +++ b/blame.c
> @@ -0,0 +1,444 @@
> +#include <assert.h>
> +
> +#include "cache.h"
> +#include "refs.h"
> +#include "tag.h"
> +#include "commit.h"
> +#include "tree.h"
> +#include "blob.h"
> +#include "epoch.h"
> +#include "diff.h"
> +
> +#define DEBUG 0
> +
> +struct commit** blame_lines;
> +int num_blame_lines;
> +
> +struct util_info
> +{
> + int* line_map;
> + int num_lines;
> + unsigned char sha1[20]; /* blob sha, not commit! */
> + char* buf;
> + unsigned long size;
> +// const char* path;
> +};
> +
> +struct chunk
> +{
> + int off1, len1; // ---
> + int off2, len2; // +++
> +};
> +
> +struct patch
> +{
> + struct chunk* chunks;
> + int num;
> +};
> +
> +static void get_blob(struct commit* commit);
> +
> +int num_get_patch = 0;
> +int num_commits = 0;
> +
> +struct patch* get_patch(struct commit* commit, struct commit* other)
> +{
> + struct patch* ret = xmalloc(sizeof(struct patch));
> + ret->chunks = NULL;
> + ret->num = 0;
> +
> + struct util_info* info_c = (struct util_info*) commit->object.util;
> + struct util_info* info_o = (struct util_info*) other->object.util;
> +
> + if(!memcmp(info_c->sha1, info_o->sha1, 20))
> + return ret;
> +
> + get_blob(commit);
> + get_blob(other);
> +
> + FILE* fout = fopen("/tmp/git-blame-tmp1", "w");
Probably should be using something like mkstemp (mkstmp?) here, so if
someone is runnign things as root or with a malicous user around, things
don't collide.
Hell, so on a multi-user machine this doesn't blow up on you.
But, read down for a related comment.
> + if(!fout)
> + die("fopen tmp1 failed: %s", strerror(errno));
> +
> + if(fwrite(info_c->buf, info_c->size, 1, fout) != 1)
> + die("fwrite 1 failed: %s", strerror(errno));
> + fclose(fout);
> +
> + fout = fopen("/tmp/git-blame-tmp2", "w");
> + if(!fout)
> + die("fopen tmp2 failed: %s", strerror(errno));
> +
> + if(fwrite(info_o->buf, info_o->size, 1, fout) != 1)
> + die("fwrite 2 failed: %s", strerror(errno));
> + fclose(fout);
> +
> + FILE* fin = popen("diff -u0 /tmp/git-blame-tmp1 /tmp/git-blame-tmp2", "r");
> + if(!fin)
> + die("popen failed: %s", strerror(errno));
Can't git-diff-tree do this sufficiently, anyway? See my Perl script
for an example, you just need both commit IDs and both filenames and the
appropriate -M and you get the right results.
(It's possible that's part of where the performance differences are,
though, not really sure at the moment.)
I'm going to stop there for the moment, I'm not really confident in my
understanding of git-internals to say much more just yet.
This could probably benefit a *LOT* from the libification project, I
think, though.
--
Ryan Anderson
sometimes Pug Majere
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Alex Riesen @ 2006-02-23 21:43 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Andreas Ericsson, Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0602230911410.3771@g5.osdl.org>
Linus Torvalds, Thu, Feb 23, 2006 18:13:43 +0100:
> > Someday we'll have to start dropping features on Windows or restrict them
> > beyond their usefullness.
>
> One thing that would help a bit would be to avoid shell.
>
> There are many portable interpreters out there, and I don't mean perl. And
> writing a small "specialized for git" one isn't even that hard. In fact,
> most of the shell (and bash) hackery we do now would be unnecessary if we
> just made a small "git interpreter" that ran "git scripts".
>
> The fact that it would also help portability is just an added advantage.
>
I actually was dreaming about taking a vacation and rewrite at least
the most important scripts in C, but without cygwin. Implement the
needed subset of POSIX in compat/, workaround fork.
That'd help me to present git to my collegues without requiring them
to install cygwin, perl and python first. It is a real problem to
explain why a new tool is better than the old one if the problem start
right from installation, and it probably wont matter how bad the old
tool is (it is, they know that too, but it has windows, doors and a
mostly running man for busy-waiting cursor).
A gits own interpreter would be more than, of course.
^ permalink raw reply
* Re: [PATCH] Convert open("-|") to qx{} calls
From: Randal L. Schwartz @ 2006-02-23 21:15 UTC (permalink / raw)
To: Alex Riesen; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <20060223211403.GB5827@steel.home>
>>>>> "Alex" == Alex Riesen <raa.lkml@gmail.com> writes:
Alex> Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?
>>
>> Nothing is quoted. Your string acts as if it was XXX in:
>>
>> sh -c 'XXX'
>>
Alex> Not so for ActiveState. It'll just run the first non-whitespace word
Alex> passing the rest of the line in its command-line.
Alex> It's not even worse then to pass it all to cmd/command :)
Right. That's why I suggest (in a later message) that safe_qx merely
fall back to qx() on Activestate. Can't go much more wrong. :)
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* Re: [PATCH] Convert open("-|") to qx{} calls
From: Alex Riesen @ 2006-02-23 21:14 UTC (permalink / raw)
To: Randal L. Schwartz; +Cc: Johannes Schindelin, Junio C Hamano, git
In-Reply-To: <86lkw1g647.fsf@blue.stonehenge.com>
Randal L. Schwartz, Thu, Feb 23, 2006 21:41:44 +0100:
> Johannes> Now that our local Perl guru joined the discussion, may I ask what
> Johannes> is, and what is not quoted when put inside qx{}?
>
> Nothing is quoted. Your string acts as if it was XXX in:
>
> sh -c 'XXX'
>
Not so for ActiveState. It'll just run the first non-whitespace word
passing the rest of the line in its command-line.
It's not even worse then to pass it all to cmd/command :)
^ permalink raw reply
* Re: [PATCH] Convert open("-|") to qx{} calls
From: Randal L. Schwartz @ 2006-02-23 20:41 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Junio C Hamano, Alex Riesen, git
In-Reply-To: <Pine.LNX.4.63.0602232039160.30630@wbgn013.biozentrum.uni-wuerzburg.de>
>>>>> "Johannes" == Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
Johannes> Now that our local Perl guru joined the discussion, may I ask what
Johannes> is, and what is not quoted when put inside qx{}?
Nothing is quoted. Your string acts as if it was XXX in:
sh -c 'XXX'
so any quoting is entirely on your own. Thus, without the multi-arg exec in
my proposed replacement, you can get shell-ish interactions that can ruin your
day pretty bad.
Johannes> I had the
Johannes> impression that all arguments are quoted, except that variables are
Johannes> resolved first. Was that wrong? IOW does
Johannes> qx{bash $variable}
Johannes> quote the value of $variable, or not?
The Perl $variable is expanded to its current contents. But suppose the
contents are `date` (including the backquotes). That would mean that a shell
would execute a date command, and *its* output would then contribute further
to the command invocation.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<merlyn@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
^ permalink raw reply
* [PATCH] New git-seek command with documentation and test.
From: Carl Worth @ 2006-02-23 20:31 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Linus Torvalds
In-Reply-To: <7vu0b1pntl.fsf@assigned-by-dhcp.cox.net>
[-- Attachment #1: Type: text/plain, Size: 10708 bytes --]
Add git-seek which allows for temporary excursions through the
revision history. With "git seek <revision>" one gets a working tree
corresponding to <revision>. When done with the excursion "git seek"
returns back to the original branch from where the first seek began.
Signed-off-by: Carl Worth <cworth@cworth.org>
---
git-seek could be used as a new basis for git-bisect. This patch does
not do that, but even so, git-bisect and git-seek should play nicely
with each other, (in the sense that either will refuse to do anything
if .git/head-name already exists).
On Tue, 14 Feb 2006 14:39:34 -0800, Junio C Hamano wrote:
> Carl Worth <cworth@cworth.org> writes:
> > [arguments in favor of a new git-seek]
>
> I think this is a very valid point and I am happy to accept a
> workable proposal (does not have to be a working patch, but a
> general semantics that covers most of if not all the corner
> cases).
I had planned to just let this drop as my original need was some
historical exploration that I've already finished. But now I've found
a common use case in my everyday workflow that could benefit from
git-seek. Here it is:
I receive a bug-fix patch that updates a test case to demonstrate the
bug. I can apply both the fix and the test case and see it succeed.
But what I really want to do is first commit the test case, see it
fail, and only then commit the fix and see the test now succeed. I'd
also like the history to reflect that order. So what I do is:
$ git-am
$ git update-index test.c ; git commit -m "Update test"
$ git update-index buggy.c ; git commit -m "Fix bug"
At that point, without git-seek I can get by with:
$ git checkout -b tmp HEAD^
$ make check # to see failure
$ git checkout <branch_I_was_on_to_begin_with>
$ git branch -d tmp # easy to forget, but breaks the next time otherwise
$ make check # to see success
But what I'd really like to do, (and can with the attached patch), is:
$ git seek HEAD^
$ make check # to see failure
$ git seek
$ make check # to see success
This avoids me having to: 1) invent a throwaway name, 2) remember the
branch I started on, 3) remember to actually throwaway the temporary
branch.
I've documented git-seek quite carefully and added a test that tries
to cover every documented failure mode.
-Carl
.gitignore | 1
Documentation/git-seek.txt | 44 +++++++++++++++++++++
Makefile | 4 +-
git-seek.sh | 94 ++++++++++++++++++++++++++++++++++++++++++++
t/t3800-seek.sh | 82 ++++++++++++++++++++++++++++++++++++++
5 files changed, 223 insertions(+), 2 deletions(-)
create mode 100644 Documentation/git-seek.txt
create mode 100644 git-seek.sh
create mode 100755 t/t3800-seek.sh
2656ffb6e3fcbd9443c22b4675b13f23c031600e
diff --git a/.gitignore b/.gitignore
index 94f66d5..55484b0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -85,6 +85,7 @@ git-rev-list
git-rev-parse
git-revert
git-rm
+git-seek
git-send-email
git-send-pack
git-sh-setup
diff --git a/Documentation/git-seek.txt b/Documentation/git-seek.txt
new file mode 100644
index 0000000..cb5c13d
--- /dev/null
+++ b/Documentation/git-seek.txt
@@ -0,0 +1,44 @@
+git-bisect(1)
+=============
+
+NAME
+----
+git-seek - Provide a temporary excursion through the revision history.
+
+
+SYNOPSIS
+--------
+'git seek' [<revision>]
+
+DESCRIPTION
+-----------
+When given a <revision>, git-seek updates the files in the working
+tree to the state of the given revision. It will do this by performing
+a checkout of <revision> to a new branch named "seek", or by resetting
+the seek branch if it already exists.
+
+When run with with no <revision> argument, git-seek will return to the
+original branch from which the initial git-seek operation was
+performed, (this original branch name is saved in $GIT_DIR/head-name).
+
+git-seek refuses to do anything if the working tree or index are
+modified with respect to HEAD. If you want to carry modifications
+around, use git-checkout rather than git-seek.
+
+git-seek will also fail if GIT_DIR/head-name exists when a seek is not
+already in progress, or if a seek branch already exists that is not a
+subset of the current branch, (that is, if it has unmerged commits).
+
+Author
+------
+Written by Carl Worth <cworth@cworth.org>, based on git-bisect by
+Linus Torvalds <torvalds@osdl.org>
+
+Documentation
+-------------
+Documentation by Carl Worth and the git-list <git@vger.kernel.org>.
+
+GIT
+---
+Part of the gitlink:git[7] suite
+
diff --git a/Makefile b/Makefile
index 8e6bbce..f3383d8 100644
--- a/Makefile
+++ b/Makefile
@@ -120,8 +120,8 @@ SCRIPT_SH = \
git-merge-one-file.sh git-parse-remote.sh \
git-prune.sh git-pull.sh git-push.sh git-rebase.sh \
git-repack.sh git-request-pull.sh git-reset.sh \
- git-resolve.sh git-revert.sh git-rm.sh git-sh-setup.sh \
- git-tag.sh git-verify-tag.sh git-whatchanged.sh \
+ git-resolve.sh git-revert.sh git-rm.sh git-seek.sh \
+ git-sh-setup.sh git-tag.sh git-verify-tag.sh git-whatchanged.sh \
git-applymbox.sh git-applypatch.sh git-am.sh \
git-merge.sh git-merge-stupid.sh git-merge-octopus.sh \
git-merge-resolve.sh git-merge-ours.sh git-grep.sh \
diff --git a/git-seek.sh b/git-seek.sh
new file mode 100644
index 0000000..26f0b76
--- /dev/null
+++ b/git-seek.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+
+USAGE='[<revision>]'
+LONG_USAGE='git-seek provides a temporary excursion through the revision history.
+
+When given a <revision>, git-seek updates the files in the working
+tree to the state of the given revision. It will do this by performing
+a checkout of <revision> to a new branch named "seek", or by resetting
+the seek branch if it already exists.
+
+When run with with no <revision> argument, git-seek will return to the
+original branch from which the initial git-seek operation was
+performed, (this original branch name is saved in $GIT_DIR/head-name).
+
+git-seek refuses to do anything if the working tree or index are
+modified with respect to HEAD. If you want to carry modifications
+around, use git-checkout rather than git-seek.
+
+git-seek will also fail if GIT_DIR/head-name exists when a seek is not
+already in progress, or if a seek branch already exists that is not a
+subset of the current branch, (that is, if it has unmerged commits).'
+
+. git-sh-setup
+
+# Does $GIT_DIR/head-name contain the given revision
+# We use git-rev-parse to correctly resolve any aliases through references.
+head_name_contains() {
+ old_head=$(git-rev-parse $(cat "$GIT_DIR/head-name"))
+ new_head=$(git-rev-parse "$1")
+ [ "$old_head" = "$new_head" ]
+}
+
+seek_to() {
+ target="$1"
+ head=$(GIT_DIR="$GIT_DIR" git-symbolic-ref HEAD) ||
+ die "Bad HEAD - I need a symbolic ref"
+ case "$head" in
+ refs/heads/seek)
+ # An explicit seek to head-name is treated as a reset
+ if head_name_contains "$target"; then
+ seek_reset
+ else
+ git reset --hard $target
+ fi
+ ;;
+ refs/heads/*)
+ [ -s "$GIT_DIR/head-name" ] && die "Will not seek: $GIT_DIR/head-name is already in use"
+ echo "$head" | sed 's#^refs/heads/##' >"$GIT_DIR/head-name"
+ if git-rev-parse --verify seek >&/dev/null ; then
+ git-branch -d seek || exit
+ fi
+ git checkout -b seek $target
+ ;;
+ *)
+ die "Bad HEAD - strange symbolic ref"
+ ;;
+ esac
+}
+
+seek_reset() {
+ if [ -s "$GIT_DIR/head-name" ]; then
+ source=$(cat "$GIT_DIR/head-name") || exit
+ else
+ echo >&2 "No seek is in progress: returning to master."
+ source
+ fi
+ git checkout "$source" &&
+ (git branch -d seek || err=$? ; git checkout seek ; exit $err) &&
+ rm -f "$GIT_DIR/head-name"
+}
+
+head=$(git-rev-parse --verify HEAD) || die "You do not have a valid HEAD"
+
+files_dirty=$(git-diff-index --name-only $head) || exit
+index_dirty=$(git-diff-index --cached --name-only $head) || exit
+if [ "$files_dirty" -o "$index_dirty" ]; then
+ die "Will not seek from a dirty state:
+ ${index_dirty:+(dirty in index: $index_dirty)} ${files_dirty:+(dirty in working tree: $files_dirty)}
+You may want to commit these changes first or perhaps use git-checkout
+-m instead of git-seek."
+fi
+
+case "$#" in
+0)
+ seek_reset
+ ;;
+1)
+ seek_to "$1"
+ ;;
+*)
+ usage
+ ;;
+esac
+
diff --git a/t/t3800-seek.sh b/t/t3800-seek.sh
new file mode 100755
index 0000000..e5d8f90
--- /dev/null
+++ b/t/t3800-seek.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+#
+# Copyright (c) 2006 Carl D. Worth
+#
+
+test_description='Test of git-seek and all documented failure modes.'
+
+. ./test-lib.sh
+
+echo "first" > file
+git-add file && git-commit -m "add first revision of file"
+echo "second" > file
+git-commit -a -m "commit second revision"
+git tag second
+echo "third" > file
+git-commit -a -m "commit third revision"
+
+verify_revision() {
+ contents=$(cat file) && [ "$contents" = "$1" ]
+}
+
+test_expect_success \
+ 'Test of initial "git-seek <revision>"' \
+ 'git-seek HEAD~2 && verify_revision first'
+
+test_expect_success \
+ 'Test of "git-seek <revision>" during seek' \
+ 'git-seek second && verify_revision second'
+
+test_expect_success \
+ 'Test that "git-seek" returns to starting point and resets seek state' \
+ 'git-seek && verify_revision third &&
+ [ ! -f .git/refs/seek ] &&
+ [ ! -f .git/head-name ]'
+
+test_expect_success \
+ 'Test that "git-seek master" also resets seek state' \
+ 'git seek HEAD^1 &&
+ git seek master && verify_revision third &&
+ [ ! -f .git/refs/seek ] &&
+ [ ! -f .git/head-name ]'
+
+test_expect_success \
+ 'Test that "git-seek <revision>" which aliases to master also resets seek state' \
+ 'source=$(git-rev-parse HEAD) &&
+ git seek HEAD^1 &&
+ git seek $source && verify_revision third &&
+ [ ! -f .git/refs/seek ] &&
+ [ ! -f .git/head-name ]'
+
+echo modified > file
+test_expect_failure \
+ 'Test that git-seek fails with local file modification' \
+ 'git-seek HEAD^'
+git-reset --hard master
+
+echo modified > file
+git-update-index file
+test_expect_failure \
+ 'Test that git-seek fails with a modified index' \
+ 'git-seek HEAD^'
+git-reset --hard master
+
+echo master > .git/head-name
+test_expect_failure \
+ 'Test that git-seek fails when .git/head-name exists and not seeking' \
+ 'git-seek HEAD^'
+rm .git/head-name
+
+git-seek HEAD^
+echo new > new; git-add new; git-commit -m "Commit new file to seek branch"
+test_expect_failure \
+ 'Test that git-seek fails when there are unmerged commits on seek branch' \
+ 'git-seek'
+
+git checkout master
+git-pull . seek >&/dev/null
+test_expect_success \
+ 'Test that git-seek works again after merging in the seek branch' \
+ 'git-seek'
+
+test_done
--
1.2.3.g207a-dirty
[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply related
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Sam Vilain @ 2006-02-23 20:31 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0602231143290.3771@g5.osdl.org>
Linus Torvalds wrote:
>>>There are many portable interpreters out there, and I don't mean perl. And
>>>writing a small "specialized for git" one isn't even that hard. In fact,
>>>most of the shell (and bash) hackery we do now would be unnecessary if we
>>>just made a small "git interpreter" that ran "git scripts".
>>Before anybody mentions tcl ;-).
> Well, I was thinking more of the "embeddable" ones - things that are so
> small that they can be compiled with the project. Things like Lua.
[...]
> I was really thinking more of a simple shell-like script interpreter.
I like the term "Domain Specific Language" to refer to this sort of
thing. It even hints at using the right kind of tools to achieve it, too :)
Sam.
^ permalink raw reply
* Re: [PATCH] fmt-merge-msg: avoid open "-|" list form for Perl 5.6
From: Johannes Schindelin @ 2006-02-23 20:19 UTC (permalink / raw)
To: Linus Torvalds; +Cc: Junio C Hamano, git
In-Reply-To: <Pine.LNX.4.64.0602231151580.3771@g5.osdl.org>
Hi,
On Thu, 23 Feb 2006, Linus Torvalds wrote:
> On Thu, 23 Feb 2006, Johannes Schindelin wrote:
> > >
> > > Before anybody mentions tcl ;-).
> >
> > Darn, I had my suggestion sent out: Java ;-)
>
> I do see the smileys, but the fact is, "perl" is a hell of a lot more
> portable than either, if we want to talk executing processes and pipelines
> etc. But even perl is clearly not portable enough, and has tons of version
> skew.
>
> Java, afaik, has absolutely _zero_ support for creating a new process and
> piping its output to another one and doing things like safe argument
> expansion. Which is what almost all of the git scripts are all about.
You are right, but for the wrong reason. Java is actually a wonderful
thing to create new processes and talk between threads.
But Java is HUGE. No, it is rather HOOODGEEE.
And I don't know if something like Lua does any good. The problem is not
so much the language. It is the fork().
AFAIAC, cygwin is pretty good at hiding Windows behind sortofa POSIX
layer. <tongue-in-cheek>It hides it behind a POSIX layer *and* a
performance hit.</tongue-in-cheek>
I would rather like to see how all the fork()ing and |'ing can be done
with MinGW32.
Ciao,
Dscho
^ 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