* Re: [PATCH 1/5] MSVC: Windows-native implementation for subset of Pthreads API
From: Johannes Sixt @ 2010-01-12 21:13 UTC (permalink / raw)
To: kusmabite; +Cc: Dmitry Potapov, msysgit, git, Andrzej K. Haczewski
In-Reply-To: <40aa078e1001080258n67e0711sf4733a99d512bf1@mail.gmail.com>
On Freitag, 8. Januar 2010, Erik Faye-Lund wrote:
> On Fri, Jan 8, 2010 at 4:32 AM, Dmitry Potapov <dpotapov@gmail.com> wrote:
> > AFAIK, Win32 API assumes that reading LONG is always atomic, so
> > the critical section is not really necesary here, but you need
> > to declare 'waiters' as 'volatile':
>
> "Simple reads and writes to properly-aligned 32-bit variables are
> atomic operations."
> http://msdn.microsoft.com/en-us/library/ms684122(VS.85).aspx
But then the next sentence is:
"However, access is not guaranteed to be synchronized. If two threads are
reading and writing from the same variable, you cannot determine if one
thread will perform its read operation before the other performs its write
operation."
This goes without saying, IOW, those Microsofties don't know what they write,
which makes the documentation a bit less trustworthy.
Nevertheless, I rewrote the code to use Interlocked* functions, and then read
the documentation again. InterlockedIncrement reads, for example:
"... This function is atomic with respect to calls to other interlocked
functions."
In particular, it doesn't say that it is atomic WRT reads such as we have
here:
> >> + /* we're done waiting, so make sure we decrease waiters count */
> >> + EnterCriticalSection(&cond->waiters_lock);
> >> + --cond->waiters;
> >> + LeaveCriticalSection(&cond->waiters_lock);
I've no assembly-fu, but I could imagine that it does not matter, but I really
would have confirmation from an x86 guru.
-- Hannes
^ permalink raw reply
* Re: [PATCH] grep: -L should show empty files
From: Sverre Rabbelier @ 2010-01-12 21:27 UTC (permalink / raw)
To: Junio C Hamano
Cc: git, Linus Torvalds, Miles Bader, Jeff King, Nguyen Thai Ngoc Duy
In-Reply-To: <7vvdf73eql.fsf_-_@alter.siamese.dyndns.org>
Heya,
On Tue, Jan 12, 2010 at 09:32, Junio C Hamano <gitster@pobox.com> wrote:
> This optimization doesn't matter too much in practice (a tracked empty
> file must be rare, or there is something wrong with your project);
How about python projects, where there's an __init__.py file
everywhere you turn your head? ;)
--
Cheers,
Sverre Rabbelier
^ permalink raw reply
* git-svn dcommit ignores --username if there are cached credentials
From: Michel Jouvin @ 2010-01-12 22:47 UTC (permalink / raw)
To: git
Hi,
I am new to Git and using 1.6.6. I'm very interested by using it to mirror SVN
repositories. But I am running into troubles with the way git-svn handles SVN
credentials.
For one SVN I use I have some cached credentials that have only very restricted
write access. With svn command, I am using --username for every commit and this
cached credential is just ignored: I'm asked for a password.
With git-svn, I use --username at init/fetch but during dcommit --username is
ignored becaused of the cached credential. I can see in SVN logs that the
cached credential (which doesn't have the right to commit the mods I made) has
been used instead of the one specified during fetch. If I removed the cached
credential, the username specified with --username is taken into account (I'm
asked a password for it and it works) and if I ommit the --username, the one
specified at fetch time is used.
IMO, looks like a bug... Thanks in advance for any comment.
Cheers,
Michel
^ permalink raw reply
* [PATCH v2] Threaded grep
From: Fredrik Kuivinen @ 2010-01-12 23:44 UTC (permalink / raw)
To: git
Cc: Linus Torvalds, Junio C Hamano, Miles Bader, Nguyen Thai Ngoc Duy,
Jeff King
This the second version of the threaded grep patch. It applies cleanly
on top of pu.
Two environment variables can be used to control the threading. If
NO_THREADS is set, then the old non-threaded code will be used.
THREADS can be set to an integer to specify the number of threads that
should be used. If neither NO_THREADS nor THREADS is set, 8 threads
are used.
The results below are best of five runs in the Linux repository on a
box with two cores.
git grep --no-ext-grep qwerty
4.38user 0.57system 0:02.69elapsed 183%CPU (0avgtext+0avgdata
0maxresident)k 0inputs+784outputs (0major+6206minor)pagefaults 0swaps
NO_THREADS=1 git grep --no-ext-grep qwerty
4.33user 0.48system 0:04.82elapsed 99%CPU (0avgtext+0avgdata
0maxresident)k 0inputs+784outputs (0major+3523minor)pagefaults 0swaps
And with a pattern with quite a few matches:
git grep --no-ext-grep function
6.28user 0.63system 0:03.97elapsed 173%CPU (0avgtext+0avgdata
0maxresident)k 0inputs+784outputs (0major+8101minor)pagefaults 0swaps
NO_THREADS=1 git grep --no-ext-grep function
6.21user 0.50system 0:06.71elapsed 100%CPU (0avgtext+0avgdata
0maxresident)k 0inputs+784outputs (0major+3523minor)pagefaults 0swaps
In either case we gain about 40% by the threading. More testing is, as
always, greatly appreciated.
The patch needs some further clean-ups before it can be considered for
application.
---
Major changes since v1:
* Buffer the output from the threads instead of waiting until the
result can be written to stdout.
* Limit the maximum number of pending work_items.
builtin-grep.c | 340 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
grep.c | 85 ++++++++++++--
grep.h | 6 +
strbuf.c | 19 ++-
strbuf.h | 1
5 files changed, 413 insertions(+), 38 deletions(-)
diff --git a/builtin-grep.c b/builtin-grep.c
index 59c4b12..ebeede9 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -15,6 +15,13 @@
#include "grep.h"
#include "quote.h"
+#ifdef THREADED_DELTA_SEARCH
+#include "thread-utils.h"
+#include <pthread.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#endif
+
#ifndef NO_EXTERNAL_GREP
#ifdef __unix__
#define NO_EXTERNAL_GREP 0
@@ -23,6 +30,262 @@
#endif
#endif
+static int use_threads = 1;
+
+#ifdef THREADED_DELTA_SEARCH
+
+static void* load_file(const char *filename, size_t *sz);
+
+enum work_type {WORK_BUF, WORK_FILE};
+
+/* We use one producer thread and number_of_threads consumer
+ threads. The producer adds struct work_items to 'todo' and the
+ consumers pick work items from the same array. */
+struct work_item
+{
+ enum work_type type;
+ char *name;
+
+ /* if type == WORK_BUF, then 'buf' points to a buffer of size
+ 'size' otherwise type == WORK_FILE and 'buf' is a nul
+ terminated filename. */
+ char *buf;
+ size_t size;
+ char done;
+ struct strbuf out;
+};
+
+/* Number of consumer threads. */
+static int number_of_threads;
+static pthread_t *threads;
+
+/* In the range [todo_done, todo_start) in 'todo' we have work_items
+ that have been or are processed by a consumer thread. We haven't
+ written the result for these to stdout yet.
+
+ The work_items in [todo_start, todo_end) are waiting to be picked
+ up by a consumer thread.
+
+ The ranges are modulo todo_alloc.
+*/
+static struct work_item *todo = NULL;
+static int todo_alloc = 0;
+static int todo_start = 0;
+static int todo_end = 0;
+static int todo_done = 0;
+
+/* Has all work items been added? */
+static int all_work_added = 0;
+
+/* This lock protects all the variables above. */
+static pthread_mutex_t grep_lock = PTHREAD_MUTEX_INITIALIZER;
+
+/* Signalled when a new work_item is added to todo. */
+static pthread_cond_t cond_add = PTHREAD_COND_INITIALIZER;
+
+/* Signalled when the result from one work_item is written to
+ stdout. */
+static pthread_cond_t cond_write = PTHREAD_COND_INITIALIZER;
+
+/* Signalled when we are finished with everything. */
+static pthread_cond_t cond_result = PTHREAD_COND_INITIALIZER;
+
+static void add_work(enum work_type type, char *name, char *buf, size_t size)
+{
+ pthread_mutex_lock(&grep_lock);
+
+ while ((todo_end+1) % todo_alloc == todo_done) {
+ pthread_cond_wait(&cond_write, &grep_lock);
+ }
+
+ todo[todo_end].type = type;
+ todo[todo_end].name = name;
+ todo[todo_end].buf = buf;
+ todo[todo_end].size = size;
+ todo[todo_end].done = 0;
+ strbuf_reset(&todo[todo_end].out);
+ todo_end = (todo_end + 1) % todo_alloc;
+
+ pthread_mutex_unlock(&grep_lock);
+ pthread_cond_signal(&cond_add);
+}
+
+static struct work_item* get_work()
+{
+ struct work_item* ret;
+
+ pthread_mutex_lock(&grep_lock);
+ while (todo_start == todo_end && !all_work_added) {
+ pthread_cond_wait(&cond_add, &grep_lock);
+ }
+
+ if (todo_start == todo_end && all_work_added) {
+ ret = NULL;
+ } else {
+ ret = &todo[todo_start];
+ todo_start = (todo_start + 1) % todo_alloc;
+ }
+ pthread_mutex_unlock(&grep_lock);
+ return ret;
+}
+
+/* This function takes ownership of 'name' and 'buf'. They will be
+ deallocated with free. */
+static int grep_buffer_async(struct grep_opt *opt, char *name, char *buf,
+ size_t size)
+{
+ add_work(WORK_BUF, name, buf, size);
+ return 0;
+}
+
+static int grep_file_async(struct grep_opt *opt, char *name,
+ const char *filename)
+{
+ add_work(WORK_FILE, name, (char*) filename, 0);
+ return 0;
+}
+
+static void work_done(struct work_item* w)
+{
+ int old_done;
+
+ pthread_mutex_lock(&grep_lock);
+ w->done = 1;
+ old_done = todo_done;
+ for(; todo[todo_done].done && todo_done != todo_start;
+ todo_done = (todo_done+1) % todo_alloc) {
+ w = &todo[todo_done];
+ write_or_die(1, w->out.buf, w->out.len);
+ if (w->type == WORK_BUF)
+ free(w->buf);
+
+ free(w->name);
+ }
+
+ if (old_done != todo_done)
+ pthread_cond_signal(&cond_write);
+
+ if (all_work_added && todo_done == todo_end)
+ pthread_cond_signal(&cond_result);
+
+ pthread_mutex_unlock(&grep_lock);
+}
+
+static void* run(void *arg)
+{
+ int hit = 0;
+ struct grep_opt *opt = arg;
+
+ while (1) {
+ struct work_item *w = get_work();
+ if (!w)
+ break;
+
+ opt->output_priv = w;
+ if (w->type == WORK_BUF) {
+ hit |= grep_buffer(opt, w->name, w->buf, w->size);
+ } else {
+ size_t sz;
+ void* data = load_file(w->buf, &sz);
+ if (data) {
+ hit |= grep_buffer(opt, w->name, data, sz);
+ free(data);
+ }
+ }
+
+ work_done(w);
+ }
+
+ return (void*) (intptr_t) hit;
+}
+
+static void strbuf_out(struct grep_opt *opt, const char *fmt, ...)
+{
+ struct work_item *w = opt->output_priv;
+ va_list ap;
+
+ va_start(ap, fmt);
+ strbuf_vaddf(&w->out, fmt, ap);
+ va_end(ap);
+}
+
+static void start_threads(struct grep_opt *opt)
+{
+ int i;
+
+ if (getenv("THREADS"))
+ number_of_threads = atoi(getenv("THREADS"));
+ else
+ number_of_threads = 8;
+
+ todo_alloc = 100;
+ todo = xmalloc(sizeof(struct work_item)*todo_alloc);
+ for (i = 0; i < todo_alloc; i++) {
+ strbuf_init(&todo[i].out, 0);
+ }
+
+ threads = xmalloc(sizeof(pthread_t)*number_of_threads);
+ for (i = 0; i < number_of_threads; i++) {
+ struct grep_opt *o = grep_opt_dup(opt);
+ o->show_hunk_mark = 1;
+ o->output = strbuf_out;
+ compile_grep_patterns(o);
+ int err = pthread_create(&threads[i], NULL, run, o);
+
+ if (err)
+ die("grep: failed to create thread: %s", strerror(err));
+ }
+}
+#endif /* THREADED_DELTA_SEARCH */
+
+#ifdef THREADED_DELTA_SEARCH
+static int wait_all()
+{
+ int hit = 0;
+ int i;
+
+ pthread_mutex_lock(&grep_lock);
+ all_work_added = 1;
+
+ /* Wait until all work is done. */
+ while (todo_done != todo_end)
+ pthread_cond_wait(&cond_result, &grep_lock);
+
+ /* Wake up all the consumer threads so they can see that there
+ is no more work to do. */
+ pthread_cond_broadcast(&cond_add);
+ pthread_mutex_unlock(&grep_lock);
+
+ for (i = 0; i < number_of_threads; i++) {
+ void *h;
+ pthread_join(threads[i], &h);
+ hit |= (int) (intptr_t) h;
+ }
+
+ return hit;
+}
+#else
+static int wait_all()
+{
+ return 0;
+}
+#endif
+
+static int grep_buffer_internal(struct grep_opt *opt, char *name, char *buf,
+ size_t size)
+{
+#ifdef THREADED_DELTA_SEARCH
+ if (use_threads)
+ return grep_buffer_async(opt, name, buf, size);
+#endif
+ {
+ int hit = grep_buffer(opt, name, buf, size);
+ free(name);
+ free(buf);
+ return hit;
+ }
+}
+
static char const * const grep_usage[] = {
"git grep [options] [-e] <pattern> [<rev>...] [[--] path...]",
NULL
@@ -169,21 +432,21 @@ static int grep_sha1(struct grep_opt *opt, const unsigned char *sha1, const char
if (opt->relative && opt->prefix_length) {
quote_path_relative(name + tree_name_len, -1, &pathbuf, opt->prefix);
strbuf_insert(&pathbuf, 0, name, tree_name_len);
- name = pathbuf.buf;
+ } else {
+ strbuf_addstr(&pathbuf, name);
}
- hit = grep_buffer(opt, name, data, size);
- strbuf_release(&pathbuf);
- free(data);
+
+ hit = grep_buffer_internal(opt, strbuf_detach(&pathbuf, NULL),
+ data, size);
+
return hit;
}
-static int grep_file(struct grep_opt *opt, const char *filename)
+static void* load_file(const char *filename, size_t *sz)
{
struct stat st;
+ char* data;
int i;
- char *data;
- size_t sz;
- struct strbuf buf = STRBUF_INIT;
if (lstat(filename, &st) < 0) {
err_ret:
@@ -195,24 +458,47 @@ static int grep_file(struct grep_opt *opt, const char *filename)
return 0; /* empty file -- no grep hit */
if (!S_ISREG(st.st_mode))
return 0;
- sz = xsize_t(st.st_size);
+ *sz = xsize_t(st.st_size);
i = open(filename, O_RDONLY);
if (i < 0)
goto err_ret;
- data = xmalloc(sz + 1);
- if (st.st_size != read_in_full(i, data, sz)) {
+ data = xmalloc(*sz + 1);
+ data[*sz] = 0;
+ if (st.st_size != read_in_full(i, data, *sz)) {
error("'%s': short read %s", filename, strerror(errno));
close(i);
free(data);
return 0;
}
close(i);
+ return data;
+}
+
+static int grep_file(struct grep_opt *opt, const char *filename)
+{
+ char *data;
+ size_t sz;
+ struct strbuf buf = STRBUF_INIT;
+ char *name;
+
if (opt->relative && opt->prefix_length)
- filename = quote_path_relative(filename, -1, &buf, opt->prefix);
- i = grep_buffer(opt, filename, data, sz);
- strbuf_release(&buf);
- free(data);
- return i;
+ quote_path_relative(filename, -1, &buf, opt->prefix);
+ else
+ strbuf_addstr(&buf, filename);
+ name = strbuf_detach(&buf, NULL);
+
+#ifdef THREADED_DELTA_SEARCH
+ if (use_threads) {
+ return grep_file_async(opt, name, filename);
+ } else
+#endif
+ {
+ data = load_file(filename, &sz);
+ if (!data)
+ return 0;
+
+ return grep_buffer_internal(opt, name, data, sz);
+ }
}
#if !NO_EXTERNAL_GREP
@@ -809,6 +1095,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_END()
};
+ use_threads = getenv("NO_THREADS") == NULL;
+
/*
* 'git grep -h', unlike 'git grep -h <pattern>', is a request
* to show usage information and exit.
@@ -862,6 +1150,17 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
opt.regflags |= REG_ICASE;
if ((opt.regflags != REG_NEWLINE) && opt.fixed)
die("cannot mix --fixed-strings and regexp");
+
+#ifdef THREADED_DELTA_SEARCH
+ if (!grep_threads_ok(&opt))
+ use_threads = 0;
+
+ if (use_threads)
+ start_threads(&opt);
+#else
+ use_threads = 0;
+#endif
+
compile_grep_patterns(&opt);
/* Check revs and then paths */
@@ -899,9 +1198,13 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
}
if (!list.nr) {
+ int hit;
if (!cached)
setup_work_tree();
- return !grep_cache(&opt, paths, cached, external_grep_allowed);
+ hit = grep_cache(&opt, paths, cached, external_grep_allowed);
+ if (use_threads)
+ hit |= wait_all();
+ return !hit;
}
if (cached)
@@ -913,6 +1216,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (grep_object(&opt, paths, real_obj, list.objects[i].name))
hit = 1;
}
+
+ if (use_threads)
+ hit |= wait_all();
free_grep_patterns(&opt);
return !hit;
}
diff --git a/grep.c b/grep.c
index 62723da..3dd3918 100644
--- a/grep.c
+++ b/grep.c
@@ -29,6 +29,28 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
p->next = NULL;
}
+struct grep_opt* grep_opt_dup(const struct grep_opt *opt)
+{
+ struct grep_pat *pat;
+ struct grep_opt *ret = xmalloc(sizeof(struct grep_opt));
+ *ret = *opt;
+
+ ret->pattern_list = NULL;
+ ret->pattern_tail = &ret->pattern_list;
+
+ for(pat = opt->pattern_list; pat != NULL; pat = pat->next)
+ {
+ if(pat->token == GREP_PATTERN_HEAD)
+ append_header_grep_pattern(ret, pat->field,
+ pat->pattern);
+ else
+ append_grep_pattern(ret, pat->pattern, pat->origin,
+ pat->no, pat->token);
+ }
+
+ return ret;
+}
+
static int is_fixed(const char *s)
{
while (*s && !is_regex_special(*s))
@@ -260,7 +282,7 @@ static int word_char(char ch)
static void show_name(struct grep_opt *opt, const char *name)
{
- printf("%s%c", name, opt->null_following_name ? '\0' : '\n');
+ opt->output(opt, "%s%c", name, opt->null_following_name ? '\0' : '\n');
}
@@ -501,20 +523,20 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
if (opt->pre_context || opt->post_context) {
if (opt->last_shown == 0) {
if (opt->show_hunk_mark)
- fputs("--\n", stdout);
+ opt->output(opt, "--\n");
else
opt->show_hunk_mark = 1;
} else if (lno > opt->last_shown + 1)
- fputs("--\n", stdout);
+ opt->output(opt, "--\n");
}
opt->last_shown = lno;
if (opt->null_following_name)
sign = '\0';
if (opt->pathname)
- printf("%s%c", name, sign);
+ opt->output(opt, "%s%c", name, sign);
if (opt->linenum)
- printf("%d%c", lno, sign);
+ opt->output(opt, "%d%c", lno, sign);
if (opt->color) {
regmatch_t match;
enum grep_context ctx = GREP_CONTEXT_BODY;
@@ -525,18 +547,19 @@ static void show_line(struct grep_opt *opt, char *bol, char *eol,
while (next_match(opt, bol, eol, ctx, &match, eflags)) {
if (match.rm_so == match.rm_eo)
break;
- printf("%.*s%s%.*s%s",
- (int)match.rm_so, bol,
- opt->color_match,
- (int)(match.rm_eo - match.rm_so), bol + match.rm_so,
- GIT_COLOR_RESET);
+ opt->output(opt, "%.*s%s%.*s%s",
+ (int)match.rm_so, bol,
+ opt->color_match,
+ (int)(match.rm_eo - match.rm_so),
+ bol + match.rm_so,
+ GIT_COLOR_RESET);
bol += match.rm_eo;
rest -= match.rm_eo;
eflags = REG_NOTBOL;
}
*eol = ch;
}
- printf("%.*s\n", rest, bol);
+ opt->output(opt, "%.*s\n", rest, bol);
}
static int match_funcname(struct grep_opt *opt, char *bol, char *eol)
@@ -674,6 +697,33 @@ static int look_ahead(struct grep_opt *opt,
return 0;
}
+int grep_threads_ok(const struct grep_opt *opt)
+{
+ /* If this condition is true, then we may use the attribute
+ machinery in grep_buffer_1. The attribute code is not
+ thread safe, so we disable the use of threads. */
+ if (opt->funcname && !opt->unmatch_name_only && !opt->status_only &&
+ !opt->name_only)
+ return 0;
+
+ /* If we are showing hunk marks, we should not do it for the
+ first match. The synchronization problem we get for this
+ constraint is not yet solved, so we disable threading in
+ this case. */
+ if (opt->pre_context || opt->post_context)
+ return 0;
+
+ return 1;
+}
+
+static void std_output(struct grep_opt *opt, const char* fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+}
+
static int grep_buffer_1(struct grep_opt *opt, const char *name,
char *buf, unsigned long size, int collect_hits)
{
@@ -689,6 +739,9 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
opt->last_shown = 0;
+ if (!opt->output)
+ opt->output = std_output;
+
if (buffer_is_binary(buf, size)) {
switch (opt->binary) {
case GREP_BINARY_DEFAULT:
@@ -761,7 +814,8 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
if (opt->status_only)
return 1;
if (binary_match_only) {
- printf("Binary file %s matches\n", name);
+ opt->output(opt,
+ "Binary file %s matches\n", name);
return 1;
}
if (opt->name_only) {
@@ -817,9 +871,10 @@ static int grep_buffer_1(struct grep_opt *opt, const char *name,
* which feels mostly useless but sometimes useful. Maybe
* make it another option? For now suppress them.
*/
- if (opt->count && count)
- printf("%s%c%u\n", name,
- opt->null_following_name ? '\0' : ':', count);
+ if (opt->count && count) {
+ opt->output(opt, "%s%c%u\n", name,
+ opt->null_following_name ? '\0' : ':', count);
+ }
return !!last_hit;
}
diff --git a/grep.h b/grep.h
index 75370f6..f5031c7 100644
--- a/grep.h
+++ b/grep.h
@@ -92,6 +92,9 @@ struct grep_opt {
unsigned last_shown;
int show_hunk_mark;
void *priv;
+
+ void (*output)(struct grep_opt*, const char*, ...);
+ void *output_priv;
};
extern void append_grep_pattern(struct grep_opt *opt, const char *pat, const char *origin, int no, enum grep_pat_token t);
@@ -100,4 +103,7 @@ extern void compile_grep_patterns(struct grep_opt *opt);
extern void free_grep_patterns(struct grep_opt *opt);
extern int grep_buffer(struct grep_opt *opt, const char *name, char *buf, unsigned long size);
+extern struct grep_opt* grep_opt_dup(const struct grep_opt *opt);
+extern int grep_threads_ok(const struct grep_opt *opt);
+
#endif
diff --git a/strbuf.c b/strbuf.c
index 4017476..a41f0ea 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -194,21 +194,28 @@ void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len)
void strbuf_addf(struct strbuf *sb, const char *fmt, ...)
{
- int len;
va_list ap;
+ va_start(ap, fmt);
+ strbuf_vaddf(sb, fmt, ap);
+ va_end(ap);
+}
+
+void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap)
+{
+ int len;
+ va_list ap2;
+
+ va_copy(ap2, ap);
if (!strbuf_avail(sb))
strbuf_grow(sb, 64);
- va_start(ap, fmt);
len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
- va_end(ap);
if (len < 0)
die("your vsnprintf is broken");
if (len > strbuf_avail(sb)) {
strbuf_grow(sb, len);
- va_start(ap, fmt);
- len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap);
- va_end(ap);
+ len = vsnprintf(sb->buf + sb->len, sb->alloc - sb->len, fmt, ap2);
+ va_end(ap2);
if (len > strbuf_avail(sb)) {
die("this should not happen, your snprintf is broken");
}
diff --git a/strbuf.h b/strbuf.h
index b37f06a..20129ad 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -118,6 +118,7 @@ extern size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
__attribute__((format (printf,2,3)))
extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...);
+extern void strbuf_vaddf(struct strbuf *sb, const char *fmt, va_list ap);
extern size_t strbuf_fread(struct strbuf *, size_t, FILE *);
/* XXX: if read fails, any partial read is undone */
^ permalink raw reply related
* Bug? git-svn clone dies with "fatal: ambiguous argument '...': unknown revision or path not in the working tree."
From: Eric Hanchrow @ 2010-01-12 23:58 UTC (permalink / raw)
To: git; +Cc: Eric Wong
I have been using git-svn happily for many months, updating git from
git://git.kernel.org/pub/scm/git/git.git every once in a while. I
just updated to c0eb604330e1288300d915f25868d1eed88d3038, and tried to
clone the same svn repo that I've been using for a long time:
$ git svn clone http://svn/repos/cozi/kits --stdlayout
It chugged along happily for a while, but then died like this:
fatal: ambiguous argument
'2d2df13977551168a54ffa9b706484242a58736a^..d038748d49a0de5802fe3c13f46d0e080d064290':
unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
rev-list 2d2df13977551168a54ffa9b706484242a58736a^..d038748d49a0de5802fe3c13f46d0e080d064290:
command returned error: 128
"git show 2d2df13977551168a54ffa9b706484242a58736a" shows that the
commit in question corresponds to a commit in svn that created an
empty directory:
15:56:46 [COZIGROUP\erich@ubuntu64-erich kits] (master)$ git show -w
2d2df13977551168a54ffa9b706484242a58736a
commit 2d2df13977551168a54ffa9b706484242a58736a
Author: cozigroup\erich <cozigroup\erich@1248e456-dc32-5a46-b6cc-76877e1dc968>
Date: Wed Jan 14 18:35:00 2009 +0000
This branch will hold work I've done to refactor the vcs backend
stuff, and add support for Mercurial.
git-svn-id: http://svn/repos/cozi/kits/branches/vcs-refactor@18735
1248e456-dc32-5a46-b6cc-76877e1dc968
15:41:01 [COZIGROUP\erich@ubuntu64-erich hmm]$ svn log --limit=1
-vr18735 http://svn/repos/cozi
------------------------------------------------------------------------
r18735 | cozigroup\erich | 2009-01-14 10:35:00 -0800 (Wed, 14 Jan
2009) | 2 lines
Changed paths:
A /kits/branches/vcs-refactor
This branch will hold work I've done to refactor the vcs backend
stuff, and add support for Mercurial.
If I recall correctly, that commit was a mistake: I'd forgotten that
the proper way to create a branch in svn is to copy the trunk, and not
to create an empty directory first.
Here I am creating that branch the proper way:
r18736 | cozigroup\erich | 2009-01-14 10:35:30 -0800 (Wed, 14 Jan
2009) | 2 lines
Changed paths:
D /kits/branches/vcs-refactor
D'oh. We branch by _copying_, not making empty directories :-|
------------------------------------------------------------------------
r18737 | cozigroup\erich | 2009-01-14 10:36:37 -0800 (Wed, 14 Jan
2009) | 2 lines
Changed paths:
A /kits/branches/vcs-refactor (from /kits/trunk:18671)
Refactoring the version-control stuff, and adding Mercurial support.
------------------------------------------------------------------------
15:56:51 [COZIGROUP\erich@ubuntu64-erich kits] (master)$ git show -w
d038748d49a0de5802fe3c13f46d0e080d064290
commit d038748d49a0de5802fe3c13f46d0e080d064290
Merge: 5108824 a370f0b
Author: cozigroup\erich <cozigroup\erich@1248e456-dc32-5a46-b6cc-76877e1dc968>
Date: Tue Jan 20 18:34:26 2009 +0000
Merged from trunk.
git-svn-id: http://svn/repos/cozi/kits/branches/vcs-refactor@18920
1248e456-dc32-5a46-b6cc-76877e1dc968
And here is (what might be) the first attempt to modify stuff in that directory:
15:52:52 [COZIGROUP\erich@ubuntu64-erich kits] (master)$ svn log
--limit=1 -vr18920 http://svn/repos/cozi
------------------------------------------------------------------------
r18920 | cozigroup\erich | 2009-01-20 10:34:26 -0800 (Tue, 20 Jan
2009) | 2 lines
Changed paths:
M /kits/branches/vcs-refactor
A /kits/branches/vcs-refactor/lib/CoziPlatform/cozi/resources.py
(from /kits/trunk/lib/CoziPlatform/cozi/resources.py:18919)
M /kits/branches/vcs-refactor/lib/CoziSecurity/cozi/authorize.py
M /kits/branches/vcs-refactor/lib/CoziSecurity/cozi/eguidtests.py
M /kits/branches/vcs-refactor/lib/CoziVaultRESTServices/cozi/screen_saver_api.py
M /kits/branches/vcs-refactor/lib/CoziVaultRESTServices/cozi/screen_saver_calendar_xml.tmpl
M /kits/branches/vcs-refactor/lib/CoziVaultRESTServices/cozi/web_client.py
Merged from trunk.
Anyway -- I suspect that my svn repos layout is ... er ... unusual,
and has hit some sorta edge case in git-svn. Is there some workaround
I can use, or is this a bug?
Thanks
^ permalink raw reply
* Lists for internal medicine, general practice, family practice
From: Alan home @ 2010-01-13 3:03 UTC (permalink / raw)
To: cargillmeats_centroamerica, lasse.turunen, oskar,
alexanderkai-lik.so, marketing
Please advise if you were still looking for lists of US doctors or dentists.
I have many different US medical lists, let me know what you need and I will get you some details, samples and discounted prices.
Please email me here instead: Rosario@choicemedicaldata.net (make sure to include a copy of this email in your reply)
Otherwise if you needed to have your email unlisted from our campaigns please send a request here: rembox@choicemedicaldata.net
^ permalink raw reply
* [PATCH] Add `commit.signoff` configuration variable.
From: Steven Drake @ 2010-01-13 3:36 UTC (permalink / raw)
To: git
Signed-off-by: Steven Drake <sdrake@xnet.co.nz>
---
Documentation/config.txt | 4 ++++
Documentation/git-commit.txt | 2 +-
builtin-commit.c | 4 ++++
3 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 23a965e..dd261cf 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -712,6 +712,10 @@ color.ui::
terminal. When more specific variables of color.* are set, they always
take precedence over this setting. Defaults to false.
+commit.signoff::
+ Add Signed-off-by line by the committer at the end of the commit
+ log message.
+
commit.template::
Specify a file to use as the template for new commit messages.
"{tilde}/" is expanded to the value of `$HOME` and "{tilde}user/" to the
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index c97c151..5a977b6 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -114,7 +114,7 @@ OPTIONS
-s::
--signoff::
Add Signed-off-by line by the committer at the end of the commit
- log message.
+ log message. This overrides the `commit.signoff` configuration variable.
-n::
--no-verify::
diff --git a/builtin-commit.c b/builtin-commit.c
index 3dfcd77..db90e7a 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -1093,6 +1093,10 @@ static int git_commit_config(const char *k, const char *v, void *cb)
if (!strcmp(k, "commit.template"))
return git_config_pathname(&template_file, k, v);
+ if (!strcmp(k, "commit.signoff")) {
+ signoff = git_config_bool(k, v);
+ return 0;
+ }
return git_status_config(k, v, s);
}
--
1.6.4
^ permalink raw reply related
* [PATCH] Add 'git commit --no-signoff' option.
From: Steven Drake @ 2010-01-13 3:36 UTC (permalink / raw)
To: git
Do not add a signed-off-by line. This overrides both the `--signoff`
option and the `commit.signoff` configuration variable.
Signed-off-by: Steven Drake <sdrake@xnet.co.nz>
---
Documentation/git-commit.txt | 4 ++++
builtin-commit.c | 5 ++++-
2 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt
index 5a977b6..2dfc989 100644
--- a/Documentation/git-commit.txt
+++ b/Documentation/git-commit.txt
@@ -116,6 +116,10 @@ OPTIONS
Add Signed-off-by line by the committer at the end of the commit
log message. This overrides the `commit.signoff` configuration variable.
+--no-signoff::
+ Do not add igned-off-by line. This overrides both the `--signoff`
+ option and the `commit.signoff` configuration variable.
+
-n::
--no-verify::
This option bypasses the pre-commit and commit-msg hooks.
diff --git a/builtin-commit.c b/builtin-commit.c
index db90e7a..f236068 100644
--- a/builtin-commit.c
+++ b/builtin-commit.c
@@ -51,7 +51,7 @@ static const char *logfile, *force_author;
static const char *template_file;
static char *edit_message, *use_message;
static char *author_name, *author_email, *author_date;
-static int all, edit_flag, also, interactive, only, amend, signoff;
+static int all, edit_flag, also, interactive, only, amend, signoff, no_signoff;
static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship;
static char *untracked_files_arg;
/*
@@ -103,6 +103,7 @@ static struct option builtin_commit_options[] = {
OPT_STRING('C', "reuse-message", &use_message, "COMMIT", "reuse message from specified commit"),
OPT_BOOLEAN(0, "reset-author", &renew_authorship, "the commit is authored by me now (used with -C-c/--amend)"),
OPT_BOOLEAN('s', "signoff", &signoff, "add Signed-off-by:"),
+ OPT_BOOLEAN(0, "no-signoff", &no_signoff, "Do not add Signed-off-by:"),
OPT_FILENAME('t', "template", &template_file, "use specified template file"),
OPT_BOOLEAN('e', "edit", &edit_flag, "force edit of commit"),
OPT_STRING(0, "cleanup", &cleanup_arg, "default", "how to strip spaces and #comments from message"),
@@ -797,6 +798,8 @@ static int parse_and_validate_options(int argc, const char *argv[],
if (force_author && renew_authorship)
die("Using both --reset-author and --author does not make sense");
+ signoff = no_signoff ? 0 : signoff;
+
if (logfile || message.len || use_message)
use_editor = 0;
if (edit_flag)
--
1.6.4
^ permalink raw reply related
* [PATCH 1/2] Add `init-db.templatedir` configuration variable.
From: Steven Drake @ 2010-01-13 4:19 UTC (permalink / raw)
To: git
Include `init.templatedir` as an alias for `init-db.templatedir`.
Signed-off-by: Steven Drake <sdrake@xnet.co.nz>
---
builtin-init-db.c | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/builtin-init-db.c b/builtin-init-db.c
index dd84cae..d56b3a4 100644
--- a/builtin-init-db.c
+++ b/builtin-init-db.c
@@ -20,6 +20,7 @@
static int init_is_bare_repository = 0;
static int init_shared_repository = -1;
+static const char *init_db_template_dir;
static void safe_create_dir(const char *dir, int share)
{
@@ -121,6 +122,8 @@ static void copy_templates(const char *template_dir)
if (!template_dir)
template_dir = getenv(TEMPLATE_DIR_ENVIRONMENT);
if (!template_dir)
+ template_dir = init_db_template_dir;
+ if (!template_dir)
template_dir = system_path(DEFAULT_GIT_TEMPLATE_DIR);
if (!template_dir[0])
return;
@@ -165,6 +168,15 @@ static void copy_templates(const char *template_dir)
closedir(dir);
}
+static int git_init_db_config(const char *k, const char *v, void *cb)
+{
+ /* we will accept "init-db.templatedir" or "init.templatedir" */
+ if (!strcmp(k, "init-db.templatedir") || !strcmp(k, "init.templatedir"))
+ return git_config_pathname(&init_db_template_dir, k, v);
+
+ return 0;
+}
+
static int create_default_files(const char *template_path)
{
const char *git_dir = get_git_dir();
@@ -190,6 +202,9 @@ static int create_default_files(const char *template_path)
safe_create_dir(git_path("refs/heads"), 1);
safe_create_dir(git_path("refs/tags"), 1);
+ /* Just look for `init-db.templatedir` */
+ git_config(git_init_db_config, NULL);
+
/* First copy the templates -- we might have the default
* config file there, in which case we would want to read
* from it after installing.
--
1.6.4
^ permalink raw reply related
* [PATCH 2/2] Add a "TEMPLATE DIRECTORY" section to git-init[1].
From: Steven Drake @ 2010-01-13 4:19 UTC (permalink / raw)
To: git
In-Reply-To: <04b754c8823368ec1459c16f4aa8890cc0de0204.1263356312.git.sdrake@xnet.co.nz>
Add references to it in config.txt and git-clone[1].
Signed-off-by: Steven Drake <sdrake@xnet.co.nz>
---
Documentation/config.txt | 4 ++++
Documentation/git-clone.txt | 3 +--
Documentation/git-init.txt | 29 +++++++++++++++++++++--------
3 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index dd261cf..b0369c4 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -1178,6 +1178,10 @@ imap::
The configuration variables in the 'imap' section are described
in linkgit:git-imap-send[1].
+init-db.templatedir::
+ Specify the directory from which templates will be copied.
+ (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
+
instaweb.browser::
Specify the program that will be used to browse your working
repository in gitweb. See linkgit:git-instaweb[1].
diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt
index 7ccd742..731b57e 100644
--- a/Documentation/git-clone.txt
+++ b/Documentation/git-clone.txt
@@ -143,8 +143,7 @@ objects from the source repository into a pack in the cloned repository.
--template=<template_directory>::
Specify the directory from which templates will be used;
- if unset the templates are taken from the installation
- defined default, typically `/usr/share/git-core/templates`.
+ (See the "TEMPLATE DIRECTORY" section of linkgit:git-init[1].)
--depth <depth>::
Create a 'shallow' clone with a history truncated to the
diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt
index f081b24..86b5766 100644
--- a/Documentation/git-init.txt
+++ b/Documentation/git-init.txt
@@ -28,14 +28,8 @@ current working directory.
--template=<template_directory>::
-Provide the directory from which templates will be used. The default template
-directory is `/usr/share/git-core/templates`.
-
-When specified, `<template_directory>` is used as the source of the template
-files rather than the default. The template files include some directory
-structure, some suggested "exclude patterns", and copies of non-executing
-"hook" files. The suggested patterns and hook files are all modifiable and
-extensible.
+Specify the directory from which templates will be used. (See the "TEMPLATE
+DIRECTORY" section below.)
--shared[={false|true|umask|group|all|world|everybody|0xxx}]::
@@ -106,6 +100,25 @@ of the repository, such as installing the default hooks and
setting the configuration variables. The old name is retained
for backward compatibility reasons.
+TEMPLATE DIRECTORY
+------------------
+
+The template directory contains files and directories that will be copied to
+the `$GIT_DIR` after it is created.
+
+The template directory used will (in order of preference):
+
+ - The argument given with the `--template` option.
+
+ - The contents of the `$GIT_TEMPLATE_DIR` environment variable.
+
+ - The `init-db.templatedir` configuration variable.
+
+ - The default template directory: `/usr/share/git-core/templates`.
+
+The default template directory includes some directory structure, some
+suggested "exclude patterns", and copies of non-executing "hook" files.
+The suggested patterns and hook files are all modifiable and extensible.
EXAMPLES
--------
--
1.6.4
^ permalink raw reply related
* Re: [PATCH] Add `commit.signoff` configuration variable.
From: Steven Drake @ 2010-01-13 4:36 UTC (permalink / raw)
To: git
In-Reply-To: <alpine.LNX.2.00.1001131635510.16395@vqena.qenxr.bet.am>
On Wed, 13 Jan 2010, Steven Drake wrote:
> Signed-off-by: Steven Drake <sdrake@xnet.co.nz>
I ment to make a note with that patch that the commit message Signed-off-by
was added using using the `commit.signoff` feature.
--
Steven
1: Linux - will work for fish.
2: The Linux penguin - looks stuffed to the brim with herring.
( make your own conclusions )
^ permalink raw reply
* Re: Bug? git-svn clone dies with "fatal: ambiguous argument '...': unknown revision or path not in the working tree."
From: Eric Wong @ 2010-01-13 5:29 UTC (permalink / raw)
To: Eric Hanchrow; +Cc: git, Sam Vilain, Andrew Myrick
In-Reply-To: <36366a981001121558v5324f2fbucf096e4c82402912@mail.gmail.com>
Eric Hanchrow <eric.hanchrow@gmail.com> wrote:
> I have been using git-svn happily for many months, updating git from
> git://git.kernel.org/pub/scm/git/git.git every once in a while. I
> just updated to c0eb604330e1288300d915f25868d1eed88d3038, and tried to
> clone the same svn repo that I've been using for a long time:
>
> $ git svn clone http://svn/repos/cozi/kits --stdlayout
>
> It chugged along happily for a while, but then died like this:
>
> fatal: ambiguous argument
> '2d2df13977551168a54ffa9b706484242a58736a^..d038748d49a0de5802fe3c13f46d0e080d064290':
Hi Eric,
I suspect you're hitting a bug with the newly-added mergeinfo support.
As we see below, d038748d49a0de5802fe3c13f46d0e080d064290 is a merge
commit. So I'll Cc Sam and Andrew on this since they know their way
around the mergeinfo stuff far better than I do and will hopefully have
some insight into things.
Since it's probably related to the new mergeinfo handling, reverting to
a version without it (1.6.5.7) might be the best way to go for now.
Thanks for the report!
> unknown revision or path not in the working tree.
> Use '--' to separate paths from revisions
> rev-list 2d2df13977551168a54ffa9b706484242a58736a^..d038748d49a0de5802fe3c13f46d0e080d064290:
> command returned error: 128
>
> "git show 2d2df13977551168a54ffa9b706484242a58736a" shows that the
> commit in question corresponds to a commit in svn that created an
> empty directory:
>
> 15:56:46 [COZIGROUP\erich@ubuntu64-erich kits] (master)$ git show -w
> 2d2df13977551168a54ffa9b706484242a58736a
> commit 2d2df13977551168a54ffa9b706484242a58736a
> Author: cozigroup\erich <cozigroup\erich@1248e456-dc32-5a46-b6cc-76877e1dc968>
> Date: Wed Jan 14 18:35:00 2009 +0000
>
> This branch will hold work I've done to refactor the vcs backend
> stuff, and add support for Mercurial.
>
>
> git-svn-id: http://svn/repos/cozi/kits/branches/vcs-refactor@18735
> 1248e456-dc32-5a46-b6cc-76877e1dc968
>
>
> 15:41:01 [COZIGROUP\erich@ubuntu64-erich hmm]$ svn log --limit=1
> -vr18735 http://svn/repos/cozi
> ------------------------------------------------------------------------
> r18735 | cozigroup\erich | 2009-01-14 10:35:00 -0800 (Wed, 14 Jan
> 2009) | 2 lines
> Changed paths:
> A /kits/branches/vcs-refactor
>
> This branch will hold work I've done to refactor the vcs backend
> stuff, and add support for Mercurial.
>
> If I recall correctly, that commit was a mistake: I'd forgotten that
> the proper way to create a branch in svn is to copy the trunk, and not
> to create an empty directory first.
>
> Here I am creating that branch the proper way:
>
> r18736 | cozigroup\erich | 2009-01-14 10:35:30 -0800 (Wed, 14 Jan
> 2009) | 2 lines
> Changed paths:
> D /kits/branches/vcs-refactor
>
> D'oh. We branch by _copying_, not making empty directories :-|
>
> ------------------------------------------------------------------------
> r18737 | cozigroup\erich | 2009-01-14 10:36:37 -0800 (Wed, 14 Jan
> 2009) | 2 lines
> Changed paths:
> A /kits/branches/vcs-refactor (from /kits/trunk:18671)
>
> Refactoring the version-control stuff, and adding Mercurial support.
>
> ------------------------------------------------------------------------
>
> 15:56:51 [COZIGROUP\erich@ubuntu64-erich kits] (master)$ git show -w
> d038748d49a0de5802fe3c13f46d0e080d064290
> commit d038748d49a0de5802fe3c13f46d0e080d064290
> Merge: 5108824 a370f0b
> Author: cozigroup\erich <cozigroup\erich@1248e456-dc32-5a46-b6cc-76877e1dc968>
> Date: Tue Jan 20 18:34:26 2009 +0000
>
> Merged from trunk.
>
>
> git-svn-id: http://svn/repos/cozi/kits/branches/vcs-refactor@18920
> 1248e456-dc32-5a46-b6cc-76877e1dc968
>
> And here is (what might be) the first attempt to modify stuff in that directory:
>
> 15:52:52 [COZIGROUP\erich@ubuntu64-erich kits] (master)$ svn log
> --limit=1 -vr18920 http://svn/repos/cozi
> ------------------------------------------------------------------------
> r18920 | cozigroup\erich | 2009-01-20 10:34:26 -0800 (Tue, 20 Jan
> 2009) | 2 lines
> Changed paths:
> M /kits/branches/vcs-refactor
> A /kits/branches/vcs-refactor/lib/CoziPlatform/cozi/resources.py
> (from /kits/trunk/lib/CoziPlatform/cozi/resources.py:18919)
> M /kits/branches/vcs-refactor/lib/CoziSecurity/cozi/authorize.py
> M /kits/branches/vcs-refactor/lib/CoziSecurity/cozi/eguidtests.py
> M /kits/branches/vcs-refactor/lib/CoziVaultRESTServices/cozi/screen_saver_api.py
> M /kits/branches/vcs-refactor/lib/CoziVaultRESTServices/cozi/screen_saver_calendar_xml.tmpl
> M /kits/branches/vcs-refactor/lib/CoziVaultRESTServices/cozi/web_client.py
>
> Merged from trunk.
>
>
> Anyway -- I suspect that my svn repos layout is ... er ... unusual,
> and has hit some sorta edge case in git-svn. Is there some workaround
> I can use, or is this a bug?
>
> Thanks
> --
^ permalink raw reply
* Re: git-svn dcommit ignores --username if there are cached credentials
From: Eric Wong @ 2010-01-13 5:41 UTC (permalink / raw)
To: Michel Jouvin; +Cc: git
In-Reply-To: <loom.20100112T233835-324@post.gmane.org>
Michel Jouvin <jouvin@lal.in2p3.fr> wrote:
> Hi,
>
> I am new to Git and using 1.6.6. I'm very interested by using it to mirror SVN
> repositories. But I am running into troubles with the way git-svn handles SVN
> credentials.
>
> For one SVN I use I have some cached credentials that have only very restricted
> write access. With svn command, I am using --username for every commit and this
> cached credential is just ignored: I'm asked for a password.
>
> With git-svn, I use --username at init/fetch but during dcommit --username is
> ignored becaused of the cached credential. I can see in SVN logs that the
> cached credential (which doesn't have the right to commit the mods I made) has
> been used instead of the one specified during fetch. If I removed the cached
> credential, the username specified with --username is taken into account (I'm
> asked a password for it and it works) and if I ommit the --username, the one
> specified at fetch time is used.
>
> IMO, looks like a bug... Thanks in advance for any comment.
Hi Michel,
I wonder if this is because we explicitly reread the config directory
when creating Git::SVN::Editor.
Does using --no-auth-cache work for you?
Otherwise, try pointing --config-dir= to an empty directory.
Or you can try this patch to force us to not reread the config_dir:
diff --git a/git-svn.perl b/git-svn.perl
index 650c9e5..280fd15 100755
--- a/git-svn.perl
+++ b/git-svn.perl
@@ -550,9 +550,6 @@ sub cmd_dcommit {
my %ed_opts = ( r => $last_rev,
log => get_commit_entry($d)->{log},
ra => Git::SVN::Ra->new($url),
- config => SVN::Core::config_get_config(
- $Git::SVN::Ra::config_dir
- ),
tree_a => "$d~1",
tree_b => $d,
editor_cb => sub {
We have a good reason to read config dirs there for getting auto-props,
though, so the above patch isn't going into git.git
--
Eric Wong
^ permalink raw reply related
* [PATCH 1/2] grep: rip out support for external grep
From: Junio C Hamano @ 2010-01-13 6:48 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds, Miles Bader, Jeff King, Nguyen Thai Ngoc Duy
In-Reply-To: <7v63774tfd.fsf@alter.siamese.dyndns.org>
We still allow people to pass --[no-]ext-grep on the command line,
but the option is ignored.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
Junio C Hamano <gitster@pobox.com> writes:
> Linus Torvalds <torvalds@linux-foundation.org> writes:
>
>> Ack. Works for me. And with that, I'd love for it to go in, and get rid of
>> the external grep.
> ...
> Before going forward, I found two small nits that should go to maint.
These nits out-of-way, we can now start doing this.
Makefile | 10 --
builtin-grep.c | 305 +------------------------------------------------------
t/t7002-grep.sh | 6 +-
3 files changed, 8 insertions(+), 313 deletions(-)
diff --git a/Makefile b/Makefile
index 4a1e5bc..a4b922e 100644
--- a/Makefile
+++ b/Makefile
@@ -185,10 +185,6 @@ all::
# is a simplified version of the merge sort used in glibc. This is
# recommended if Git triggers O(n^2) behavior in your platform's qsort().
#
-# Define NO_EXTERNAL_GREP if you don't want "git grep" to ever call
-# your external grep (e.g., if your system lacks grep, if its grep is
-# broken, or spawning external process is slower than built-in grep git has).
-#
# Define UNRELIABLE_FSTAT if your system's fstat does not return the same
# information on a not yet closed file that lstat would return for the same
# file after it was closed.
@@ -777,7 +773,6 @@ ifeq ($(uname_S),SunOS)
NO_MKDTEMP = YesPlease
NO_MKSTEMPS = YesPlease
NO_REGEX = YesPlease
- NO_EXTERNAL_GREP = YesPlease
THREADED_DELTA_SEARCH = YesPlease
ifeq ($(uname_R),5.7)
NEEDS_RESOLV = YesPlease
@@ -895,7 +890,6 @@ ifeq ($(uname_S),IRIX)
# NO_MMAP. If you suspect that your compiler is not affected by this
# issue, comment out the NO_MMAP statement.
NO_MMAP = YesPlease
- NO_EXTERNAL_GREP = UnfortunatelyYes
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH = /usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
@@ -915,7 +909,6 @@ ifeq ($(uname_S),IRIX64)
# NO_MMAP. If you suspect that your compiler is not affected by this
# issue, comment out the NO_MMAP statement.
NO_MMAP = YesPlease
- NO_EXTERNAL_GREP = UnfortunatelyYes
SNPRINTF_RETURNS_BOGUS = YesPlease
SHELL_PATH=/usr/gnu/bin/bash
NEEDS_LIBGEN = YesPlease
@@ -1322,9 +1315,6 @@ endif
ifdef DIR_HAS_BSD_GROUP_SEMANTICS
COMPAT_CFLAGS += -DDIR_HAS_BSD_GROUP_SEMANTICS
endif
-ifdef NO_EXTERNAL_GREP
- BASIC_CFLAGS += -DNO_EXTERNAL_GREP
-endif
ifdef UNRELIABLE_FSTAT
BASIC_CFLAGS += -DUNRELIABLE_FSTAT
endif
diff --git a/builtin-grep.c b/builtin-grep.c
index a5b6719..4adb971 100644
--- a/builtin-grep.c
+++ b/builtin-grep.c
@@ -15,14 +15,6 @@
#include "grep.h"
#include "quote.h"
-#ifndef NO_EXTERNAL_GREP
-#ifdef __unix__
-#define NO_EXTERNAL_GREP 0
-#else
-#define NO_EXTERNAL_GREP 1
-#endif
-#endif
-
static char const * const grep_usage[] = {
"git grep [options] [-e] <pattern> [<rev>...] [[--] path...]",
NULL
@@ -215,292 +207,12 @@ static int grep_file(struct grep_opt *opt, const char *filename)
return i;
}
-#if !NO_EXTERNAL_GREP
-static int exec_grep(int argc, const char **argv)
-{
- pid_t pid;
- int status;
-
- argv[argc] = NULL;
- pid = fork();
- if (pid < 0)
- return pid;
- if (!pid) {
- execvp("grep", (char **) argv);
- exit(255);
- }
- while (waitpid(pid, &status, 0) < 0) {
- if (errno == EINTR)
- continue;
- return -1;
- }
- if (WIFEXITED(status)) {
- if (!WEXITSTATUS(status))
- return 1;
- return 0;
- }
- return -1;
-}
-
-#define MAXARGS 1000
-#define ARGBUF 4096
-#define push_arg(a) do { \
- if (nr < MAXARGS) argv[nr++] = (a); \
- else die("maximum number of args exceeded"); \
- } while (0)
-
-/*
- * If you send a singleton filename to grep, it does not give
- * the name of the file. GNU grep has "-H" but we would want
- * that behaviour in a portable way.
- *
- * So we keep two pathnames in argv buffer unsent to grep in
- * the main loop if we need to do more than one grep.
- */
-static int flush_grep(struct grep_opt *opt,
- int argc, int arg0, const char **argv, int *kept)
-{
- int status;
- int count = argc - arg0;
- const char *kept_0 = NULL;
-
- if (count <= 2) {
- /*
- * Because we keep at least 2 paths in the call from
- * the main loop (i.e. kept != NULL), and MAXARGS is
- * far greater than 2, this usually is a call to
- * conclude the grep. However, the user could attempt
- * to overflow the argv buffer by giving too many
- * options to leave very small number of real
- * arguments even for the call in the main loop.
- */
- if (kept)
- die("insanely many options to grep");
-
- /*
- * If we have two or more paths, we do not have to do
- * anything special, but we need to push /dev/null to
- * get "-H" behaviour of GNU grep portably but when we
- * are not doing "-l" nor "-L" nor "-c".
- */
- if (count == 1 &&
- !opt->name_only &&
- !opt->unmatch_name_only &&
- !opt->count) {
- argv[argc++] = "/dev/null";
- argv[argc] = NULL;
- }
- }
-
- else if (kept) {
- /*
- * Called because we found many paths and haven't finished
- * iterating over the cache yet. We keep two paths
- * for the concluding call. argv[argc-2] and argv[argc-1]
- * has the last two paths, so save the first one away,
- * replace it with NULL while sending the list to grep,
- * and recover them after we are done.
- */
- *kept = 2;
- kept_0 = argv[argc-2];
- argv[argc-2] = NULL;
- argc -= 2;
- }
-
- if (opt->pre_context || opt->post_context) {
- /*
- * grep handles hunk marks between files, but we need to
- * do that ourselves between multiple calls.
- */
- if (opt->show_hunk_mark)
- write_or_die(1, "--\n", 3);
- else
- opt->show_hunk_mark = 1;
- }
-
- status = exec_grep(argc, argv);
-
- if (kept_0) {
- /*
- * Then recover them. Now the last arg is beyond the
- * terminating NULL which is at argc, and the second
- * from the last is what we saved away in kept_0
- */
- argv[arg0++] = kept_0;
- argv[arg0] = argv[argc+1];
- }
- return status;
-}
-
-static void grep_add_color(struct strbuf *sb, const char *escape_seq)
-{
- size_t orig_len = sb->len;
-
- while (*escape_seq) {
- if (*escape_seq == 'm')
- strbuf_addch(sb, ';');
- else if (*escape_seq != '\033' && *escape_seq != '[')
- strbuf_addch(sb, *escape_seq);
- escape_seq++;
- }
- if (sb->len > orig_len && sb->buf[sb->len - 1] == ';')
- strbuf_setlen(sb, sb->len - 1);
-}
-
-static int external_grep(struct grep_opt *opt, const char **paths, int cached)
-{
- int i, nr, argc, hit, len, status;
- const char *argv[MAXARGS+1];
- char randarg[ARGBUF];
- char *argptr = randarg;
- struct grep_pat *p;
-
- if (opt->extended || (opt->relative && opt->prefix_length))
- return -1;
- len = nr = 0;
- push_arg("grep");
- if (opt->fixed)
- push_arg("-F");
- if (opt->linenum)
- push_arg("-n");
- if (!opt->pathname)
- push_arg("-h");
- if (opt->regflags & REG_EXTENDED)
- push_arg("-E");
- if (opt->ignore_case)
- push_arg("-i");
- if (opt->binary == GREP_BINARY_NOMATCH)
- push_arg("-I");
- if (opt->word_regexp)
- push_arg("-w");
- if (opt->name_only)
- push_arg("-l");
- if (opt->unmatch_name_only)
- push_arg("-L");
- if (opt->null_following_name)
- /* in GNU grep git's "-z" translates to "-Z" */
- push_arg("-Z");
- if (opt->count)
- push_arg("-c");
- if (opt->post_context || opt->pre_context) {
- if (opt->post_context != opt->pre_context) {
- if (opt->pre_context) {
- push_arg("-B");
- len += snprintf(argptr, sizeof(randarg)-len,
- "%u", opt->pre_context) + 1;
- if (sizeof(randarg) <= len)
- die("maximum length of args exceeded");
- push_arg(argptr);
- argptr += len;
- }
- if (opt->post_context) {
- push_arg("-A");
- len += snprintf(argptr, sizeof(randarg)-len,
- "%u", opt->post_context) + 1;
- if (sizeof(randarg) <= len)
- die("maximum length of args exceeded");
- push_arg(argptr);
- argptr += len;
- }
- }
- else {
- push_arg("-C");
- len += snprintf(argptr, sizeof(randarg)-len,
- "%u", opt->post_context) + 1;
- if (sizeof(randarg) <= len)
- die("maximum length of args exceeded");
- push_arg(argptr);
- argptr += len;
- }
- }
- for (p = opt->pattern_list; p; p = p->next) {
- push_arg("-e");
- push_arg(p->pattern);
- }
- if (opt->color) {
- struct strbuf sb = STRBUF_INIT;
-
- grep_add_color(&sb, opt->color_match);
- setenv("GREP_COLOR", sb.buf, 1);
-
- strbuf_reset(&sb);
- strbuf_addstr(&sb, "mt=");
- grep_add_color(&sb, opt->color_match);
- strbuf_addstr(&sb, ":sl=:cx=:fn=:ln=:bn=:se=");
- setenv("GREP_COLORS", sb.buf, 1);
-
- strbuf_release(&sb);
-
- if (opt->color_external && strlen(opt->color_external) > 0)
- push_arg(opt->color_external);
- } else {
- unsetenv("GREP_COLOR");
- unsetenv("GREP_COLORS");
- }
- unsetenv("GREP_OPTIONS");
-
- hit = 0;
- argc = nr;
- for (i = 0; i < active_nr; i++) {
- struct cache_entry *ce = active_cache[i];
- char *name;
- int kept;
- if (!S_ISREG(ce->ce_mode))
- continue;
- if (!pathspec_matches(paths, ce->name, opt->max_depth))
- continue;
- name = ce->name;
- if (name[0] == '-') {
- int len = ce_namelen(ce);
- name = xmalloc(len + 3);
- memcpy(name, "./", 2);
- memcpy(name + 2, ce->name, len + 1);
- }
- argv[argc++] = name;
- if (MAXARGS <= argc) {
- status = flush_grep(opt, argc, nr, argv, &kept);
- if (0 < status)
- hit = 1;
- argc = nr + kept;
- }
- if (ce_stage(ce)) {
- do {
- i++;
- } while (i < active_nr &&
- !strcmp(ce->name, active_cache[i]->name));
- i--; /* compensate for loop control */
- }
- }
- if (argc > nr) {
- status = flush_grep(opt, argc, nr, argv, NULL);
- if (0 < status)
- hit = 1;
- }
- return hit;
-}
-#endif
-
-static int grep_cache(struct grep_opt *opt, const char **paths, int cached,
- int external_grep_allowed)
+static int grep_cache(struct grep_opt *opt, const char **paths, int cached)
{
int hit = 0;
int nr;
read_cache();
-#if !NO_EXTERNAL_GREP
- /*
- * Use the external "grep" command for the case where
- * we grep through the checked-out files. It tends to
- * be a lot more optimized
- */
- if (!cached && external_grep_allowed) {
- hit = external_grep(opt, paths, cached);
- if (hit >= 0)
- return hit;
- hit = 0;
- }
-#endif
-
for (nr = 0; nr < active_nr; nr++) {
struct cache_entry *ce = active_cache[nr];
if (!S_ISREG(ce->ce_mode))
@@ -697,8 +409,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
{
int hit = 0;
int cached = 0;
- int external_grep_allowed = 1;
int seen_dashdash = 0;
+ int external_grep_allowed__ignored;
struct grep_opt opt;
struct object_array list = { 0, 0, NULL };
const char **paths = NULL;
@@ -780,13 +492,8 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
OPT_BOOLEAN(0, "all-match", &opt.all_match,
"show only matches from files that match all patterns"),
OPT_GROUP(""),
-#if NO_EXTERNAL_GREP
- OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed,
- "allow calling of grep(1) (ignored by this build)"),
-#else
- OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed,
- "allow calling of grep(1) (default)"),
-#endif
+ OPT_BOOLEAN(0, "ext-grep", &external_grep_allowed__ignored,
+ "allow calling of grep(1) (ignored by this build)"),
{ OPTION_CALLBACK, 0, "help-all", &options, NULL, "show usage",
PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, help_callback },
OPT_END()
@@ -837,8 +544,6 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
argc--;
}
- if ((opt.color && !opt.color_external) || opt.funcname)
- external_grep_allowed = 0;
if (!opt.pattern_list)
die("no pattern given.");
if (!opt.fixed && opt.ignore_case)
@@ -884,7 +589,7 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
if (!list.nr) {
if (!cached)
setup_work_tree();
- return !grep_cache(&opt, paths, cached, external_grep_allowed);
+ return !grep_cache(&opt, paths, cached);
}
if (cached)
diff --git a/t/t7002-grep.sh b/t/t7002-grep.sh
index abd14bf..c369cdb 100755
--- a/t/t7002-grep.sh
+++ b/t/t7002-grep.sh
@@ -302,8 +302,8 @@ test_expect_success 'grep -C1, hunk mark between files' '
test_cmp expected actual
'
-test_expect_success 'grep -C1 --no-ext-grep, hunk mark between files' '
- git grep -C1 --no-ext-grep "^[yz]" >actual &&
+test_expect_success 'grep -C1 hunk mark between files' '
+ git grep -C1 "^[yz]" >actual &&
test_cmp expected actual
'
@@ -359,7 +359,7 @@ test_expect_success 'log grep (6)' '
test_expect_success 'grep with CE_VALID file' '
git update-index --assume-unchanged t/t &&
rm t/t &&
- test "$(git grep --no-ext-grep test)" = "t/t:test" &&
+ test "$(git grep test)" = "t/t:test" &&
git update-index --no-assume-unchanged t/t &&
git checkout t/t
'
--
1.6.6.292.ge84ea.dirty
^ permalink raw reply related
* [PATCH 2/2] grep: rip out pessimization to use fixmatch()
From: Junio C Hamano @ 2010-01-13 6:51 UTC (permalink / raw)
To: git; +Cc: Linus Torvalds, Miles Bader, Jeff King, Nguyen Thai Ngoc Duy
In-Reply-To: <7v63774tfd.fsf@alter.siamese.dyndns.org>
Even when running without the -F (--fixed-strings) option, we checked the
pattern and used fixmatch() codepath when it does not contain any regex
magic. Finding fixed strings with strstr() surely must be faster than
running the regular expression crud.
Not so. It turns out that on some libc implementations, using the
regcomp()/regexec() pair is a lot faster than running strstr() and
strcasestr() the fixmatch() codepath uses. Drop the optimization and use
the fixmatch() codepath only when the user explicitly asked for it with
the -F option.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
I first thought that this is somewhat questionable and we might want
an option --[no-]fixed-string-optimization to control it, but there
already is an option to do so with a shorter name, namely "-F".
grep.c | 9 +--------
1 files changed, 1 insertions(+), 8 deletions(-)
diff --git a/grep.c b/grep.c
index 62723da..8e1f7de 100644
--- a/grep.c
+++ b/grep.c
@@ -29,13 +29,6 @@ void append_grep_pattern(struct grep_opt *opt, const char *pat,
p->next = NULL;
}
-static int is_fixed(const char *s)
-{
- while (*s && !is_regex_special(*s))
- s++;
- return !*s;
-}
-
static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
{
int err;
@@ -43,7 +36,7 @@ static void compile_regexp(struct grep_pat *p, struct grep_opt *opt)
p->word_regexp = opt->word_regexp;
p->ignore_case = opt->ignore_case;
- if (opt->fixed || is_fixed(p->pattern))
+ if (opt->fixed)
p->fixed = 1;
if (opt->regflags & REG_ICASE)
p->fixed = 0;
--
1.6.6.292.ge84ea.dirty
^ permalink raw reply related
* Re: [PATCH v2 2/4] Documentation: warn prominently against merging with dirty trees
From: Junio C Hamano @ 2010-01-13 6:55 UTC (permalink / raw)
To: Jonathan Nieder; +Cc: Junio C Hamano, Thomas Rast, git
In-Reply-To: <20100111041318.GA9806@progeny.tock>
Jonathan Nieder <jrnieder@gmail.com> writes:
> | A merge is always between the current HEAD and one or more commits
> | (usually, branch head or tag), and the index file must match the tree of
> | HEAD commit (i.e. the contents of the last commit) when it starts out. In
> | other words, git diff --cached HEAD must report no changes. (One exception
> | is when the changed index entries are already in the same state that would
> | result from the merge anyway.)
>
> The potentially problematic scenario for "git reset --merge" is this
> last one, where a changed index entry is already in the same state
> that would result from the merge. Would a "git reset --merge" reset
> the changed contents away?
It will discard the change, the one you independently picked up, but the
change agreed with what was done by the the trash history that you are
cancelling merge with. You wouldn't miss losing the same change as in
that trash history.
^ permalink raw reply
* Re: [PATCH 2/3] strbuf: add strbuf_percentquote_buf
From: Junio C Hamano @ 2010-01-13 6:55 UTC (permalink / raw)
To: Jeff King; +Cc: Adam Megacz, git
In-Reply-To: <20100112154153.GB24957@coredump.intra.peff.net>
Jeff King <peff@peff.net> writes:
> +`strbuf_percentquote_buf`::
> +
> + Append the contents of one strbuf to another, quoting any
> + percent signs ("%") into double-percents ("%%") in the
> + destination. This is useful for literal data to be fed to either
> + strbuf_expand or to the *printf family of functions.
> +
> `strbuf_addf`::
>
> Add a formatted string to the buffer.
> diff --git a/strbuf.c b/strbuf.c
> index 6cbc1fc..b5183c6 100644
> --- a/strbuf.c
> +++ b/strbuf.c
> @@ -257,6 +257,16 @@ size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder,
> return 0;
> }
>
> +void strbuf_percentquote_buf(struct strbuf *dest, struct strbuf *src)
> +{
Just a style thing, but please call that "dst" to be consistent. You are
already dropping vowels from the other side to spell it "src".
I wondered if the function should be just 1-arg that always quotes
in-place instead, but your [PATCH 3/3] wants to have an appending
semantics from this function, so changing it to be a 1-arg "in-place
quoter" will force the caller to run strbuf_addbuf() on the result, which
is not nice.
Since tucking a p-quoted version of the same string to its original
doesn't make sense at all, perhaps this should:
(0) be renamed to have "append" somewhere in its name;
(1) mark the src side as const; and
(2) perhaps have assert(dst != src). The loop won't terminate when
called with src == dst, I think.
There seems to be only one other strbuf function that takes two strbufs in
the suite (strbuf_addbuf), and I think it is unsafe in a different way,
which is trivial to fix.
-- >8 --
Subject: [PATCH] strbuf_addbuf(): allow passing the same buf to dst and src
If sb and sb2 are the same (i.e. doubling the string), the underlying
strbuf_add() will make sb2->buf invalid by calling strbuf_grow(sb) at
the beginning and will read from the freed buffer.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
strbuf.h | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/strbuf.h b/strbuf.h
index fa07ecf..e272359 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -105,7 +105,13 @@ static inline void strbuf_addstr(struct strbuf *sb, const char *s) {
strbuf_add(sb, s, strlen(s));
}
static inline void strbuf_addbuf(struct strbuf *sb, const struct strbuf *sb2) {
- strbuf_add(sb, sb2->buf, sb2->len);
+ char *buf = sb2->buf;
+ int len = sb2->len;
+ if (sb->buf == sb2->buf) {
+ strbuf_grow(sb, len);
+ buf = sb->buf;
+ }
+ strbuf_add(sb, buf, len);
}
extern void strbuf_adddup(struct strbuf *sb, size_t pos, size_t len);
--
1.6.6.280.ge295b7.dirty
^ permalink raw reply related
* Re: Unable to get "pretty" URL aliases working
From: Junio C Hamano @ 2010-01-13 6:55 UTC (permalink / raw)
To: Adam Nielsen; +Cc: git
In-Reply-To: <4B4BB2DC.4090203@uq.edu.au>
Adam Nielsen <adam.nielsen@uq.edu.au> writes:
> What actually happens when you use the ssh:// style connection?
Be it ssh://host/full/path or host:/full/path or host:path/in/home, you
log in as whatver ssh identifies you as to the server, and start a
server-side git process over there.
With ssh://host/path notation, there is no way to specify any relative
path (i.e. "/path" part begins at root) so it will mean the same thing for
everybody (unless you are getting chrooted or something), while host:path
notation allows relative path which will be taken relative as where you
are, i.e. home directory of the user on the server.
^ permalink raw reply
* Re: [PATCHv2 1/3] lib-rebase: Provide clearer debugging info about what the editor did
From: Junio C Hamano @ 2010-01-13 6:55 UTC (permalink / raw)
To: Michael Haggerty; +Cc: git, Johannes.Schindelin
In-Reply-To: <a6ef19853c00263c2875026cb438ce46d3fcf950.1263310175.git.mhagger@alum.mit.edu>
Very nice; thanks.
^ permalink raw reply
* Re: [PATCH] remote-curl: Fix Accept header for smart HTTP connections
From: Junio C Hamano @ 2010-01-13 6:55 UTC (permalink / raw)
To: Shawn O. Pearce; +Cc: git
In-Reply-To: <20100112175404.GE1173@spearce.org>
Thanks.
^ permalink raw reply
* Re: [BUGFIX] Unbork remote helper execution
From: Junio C Hamano @ 2010-01-13 6:56 UTC (permalink / raw)
To: Johannes Sixt; +Cc: Ilari Liusvaara, git
In-Reply-To: <201001122053.29568.j6t@kdbg.org>
Thanks, both of you.
^ permalink raw reply
* Re: [PATCH] hg-to-git: fix COMMITTER type-o
From: Junio C Hamano @ 2010-01-13 6:56 UTC (permalink / raw)
To: Stelian Pop; +Cc: Bart Trojanowski, git
In-Reply-To: <20100112111651.GC3463@calypso>
Thanks both of you.
^ permalink raw reply
* Re: [PATCH] grep: -L should show empty files
From: Junio C Hamano @ 2010-01-13 6:56 UTC (permalink / raw)
To: Sverre Rabbelier
Cc: Junio C Hamano, git, Linus Torvalds, Miles Bader, Jeff King,
Nguyen Thai Ngoc Duy
In-Reply-To: <fabb9a1e1001121327s392f7311t2a7f11081ed70ff8@mail.gmail.com>
Sverre Rabbelier <srabbelier@gmail.com> writes:
> Heya,
>
> On Tue, Jan 12, 2010 at 09:32, Junio C Hamano <gitster@pobox.com> wrote:
>> This optimization doesn't matter too much in practice (a tracked empty
>> file must be rare, or there is something wrong with your project);
>
> How about python projects, where there's an __init__.py file
> everywhere you turn your head? ;)
It's Ok as the price we pay for producing correct result is to open those
empty files, read them, and look for matches which we will never find ;-)
^ permalink raw reply
* Re: [PATCH] lockfile: show absolute filename in unable_to_lock_message.
From: Junio C Hamano @ 2010-01-13 6:56 UTC (permalink / raw)
To: Matthieu Moy; +Cc: git, gitster
In-Reply-To: <1262876050-345-1-git-send-email-Matthieu.Moy@imag.fr>
Thanks.
^ permalink raw reply
* Re: [PATCH 16/18] blob.c: remove unused function
From: Junio C Hamano @ 2010-01-13 6:56 UTC (permalink / raw)
To: Daniel Barkalow; +Cc: git
In-Reply-To: <alpine.LNX.2.00.1001121128410.14365@iabervon.org>
Daniel Barkalow <barkalow@iabervon.org> writes:
> On Mon, 11 Jan 2010, Junio C Hamano wrote:
>
>> parse_blob() is not used anywhere since a510bfa (Mark blobs as parsed when
>> they're actually parsed, 2005-04-28).
>
> Perhaps it should be replaced with a comment that blobs are never parsed,
> because they don't need to be? We don't need the actual function, but I
> think it's worth having a note where the function would be.
I tend to agree.
Care to come up with a patch, with a real description of the reason _why_
they don't need to be parsed, please?
^ 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